blob: e9b9289b21d37ae956fd310558a8c0fbd91aac15 [file] [log] [blame]
Serge Bazanskicaa12082023-02-16 14:54:04 +01001package main
2
3import (
4 "context"
5 "flag"
6 "fmt"
7 "os"
8 "strings"
9
10 "k8s.io/klog"
11
12 "source.monogon.dev/cloud/bmaas/bmdb"
Serge Bazanski77628312023-02-15 23:33:22 +010013 "source.monogon.dev/cloud/bmaas/bmdb/webug"
Serge Bazanskicaa12082023-02-16 14:54:04 +010014 "source.monogon.dev/cloud/lib/component"
15 "source.monogon.dev/cloud/shepherd/equinix/manager"
16 "source.monogon.dev/cloud/shepherd/equinix/wrapngo"
17 clicontext "source.monogon.dev/metropolis/cli/pkg/context"
18)
19
20type Config struct {
21 Component component.ComponentConfig
22 BMDB bmdb.BMDB
23
24 SharedConfig manager.SharedConfig
Serge Bazanskicaa12082023-02-16 14:54:04 +010025 ProvisionerConfig manager.ProvisionerConfig
26 InitializerConfig manager.InitializerConfig
Serge Bazanski77628312023-02-15 23:33:22 +010027 WebugConfig webug.Config
Serge Bazanskicaa12082023-02-16 14:54:04 +010028 API wrapngo.Opts
29}
30
31// TODO(q3k): factor this out to BMDB library?
32func runtimeInfo() string {
33 hostname, _ := os.Hostname()
34 if hostname == "" {
35 hostname = "UNKNOWN"
36 }
37 return fmt.Sprintf("host %s", hostname)
38}
39
40func (c *Config) RegisterFlags() {
41 c.Component.RegisterFlags("shepherd")
42 c.BMDB.ComponentName = "shepherd-equinix"
43 c.BMDB.RuntimeInfo = runtimeInfo()
44 c.BMDB.Database.RegisterFlags("bmdb")
45
46 c.SharedConfig.RegisterFlags("")
Serge Bazanskicaa12082023-02-16 14:54:04 +010047 c.ProvisionerConfig.RegisterFlags()
48 c.InitializerConfig.RegisterFlags()
Serge Bazanski77628312023-02-15 23:33:22 +010049 c.WebugConfig.RegisterFlags()
Serge Bazanskicaa12082023-02-16 14:54:04 +010050 c.API.RegisterFlags()
51}
52
53func main() {
54 c := &Config{}
55 c.RegisterFlags()
56 flag.Parse()
57
58 ctx := clicontext.WithInterrupt(context.Background())
59
60 if c.API.APIKey == "" || c.API.User == "" {
61 klog.Exitf("-equinix_api_username and -equinix_api_key must be set")
62 }
63 api := wrapngo.New(&c.API)
64
65 // These variables are _very_ important to configure correctly, otherwise someone
66 // running this locally with prod creds will actually destroy production
67 // data.
68 if strings.Contains(c.SharedConfig.KeyLabel, "FIXME") {
69 klog.Exitf("refusing to run with -equinix_ssh_key_label %q, please set it to something unique", c.SharedConfig.KeyLabel)
70 }
71 if strings.Contains(c.SharedConfig.DevicePrefix, "FIXME") {
72 klog.Exitf("refusing to run with -equinix_device_prefix %q, please set it to something unique", c.SharedConfig.DevicePrefix)
73 }
74
75 klog.Infof("Ensuring our SSH key is configured...")
76 if err := c.SharedConfig.SSHEquinixEnsure(ctx, api); err != nil {
77 klog.Exitf("Ensuring SSH key failed: %v", err)
78 }
79
80 provisioner, err := c.ProvisionerConfig.New(api, &c.SharedConfig)
81 if err != nil {
82 klog.Exitf("%v", err)
83 }
84
Serge Bazanski86a714d2023-04-17 15:54:21 +020085 initializer, err := manager.NewInitializer(api, c.InitializerConfig, &c.SharedConfig)
Serge Bazanskicaa12082023-02-16 14:54:04 +010086 if err != nil {
87 klog.Exitf("%v", err)
88 }
89
90 conn, err := c.BMDB.Open(true)
91 if err != nil {
92 klog.Exitf("Failed to open BMDB connection: %v", err)
93 }
Serge Bazanski77628312023-02-15 23:33:22 +010094
Serge Bazanskicaa12082023-02-16 14:54:04 +010095 go func() {
96 err = provisioner.Run(ctx, conn)
97 if err != nil {
98 klog.Exit(err)
99 }
100 }()
101 go func() {
Serge Bazanski86a714d2023-04-17 15:54:21 +0200102 err = manager.RunControlLoop(ctx, conn, initializer)
Serge Bazanskicaa12082023-02-16 14:54:04 +0100103 if err != nil {
104 klog.Exit(err)
105 }
106 }()
Serge Bazanski77628312023-02-15 23:33:22 +0100107 go func() {
108 if err := c.WebugConfig.Start(ctx, conn); err != nil && err != ctx.Err() {
109 klog.Exitf("Failed to start webug: %v", err)
110 }
111 }()
Serge Bazanskicaa12082023-02-16 14:54:04 +0100112
113 <-ctx.Done()
114}