blob: 38735db8617431125ee62bb052f0bddb07e97f70 [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
Tim Windelschmidt44cacd62023-06-12 23:54:45 +020010 "k8s.io/klog/v2"
Serge Bazanskicaa12082023-02-16 14:54:04 +010011
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 Bazanskiae004682023-04-18 13:28:48 +020027 RecovererConfig manager.RecovererConfig
Serge Bazanskiafd3cf82023-04-19 17:43:46 +020028 UpdaterConfig manager.UpdaterConfig
Serge Bazanski77628312023-02-15 23:33:22 +010029 WebugConfig webug.Config
Serge Bazanskicaa12082023-02-16 14:54:04 +010030 API wrapngo.Opts
31}
32
33// TODO(q3k): factor this out to BMDB library?
34func runtimeInfo() string {
35 hostname, _ := os.Hostname()
36 if hostname == "" {
37 hostname = "UNKNOWN"
38 }
39 return fmt.Sprintf("host %s", hostname)
40}
41
42func (c *Config) RegisterFlags() {
43 c.Component.RegisterFlags("shepherd")
44 c.BMDB.ComponentName = "shepherd-equinix"
45 c.BMDB.RuntimeInfo = runtimeInfo()
46 c.BMDB.Database.RegisterFlags("bmdb")
47
48 c.SharedConfig.RegisterFlags("")
Serge Bazanskicaa12082023-02-16 14:54:04 +010049 c.ProvisionerConfig.RegisterFlags()
50 c.InitializerConfig.RegisterFlags()
Serge Bazanskiae004682023-04-18 13:28:48 +020051 c.RecovererConfig.RegisterFlags()
Serge Bazanskiafd3cf82023-04-19 17:43:46 +020052 c.UpdaterConfig.RegisterFlags()
Serge Bazanski77628312023-02-15 23:33:22 +010053 c.WebugConfig.RegisterFlags()
Serge Bazanskicaa12082023-02-16 14:54:04 +010054 c.API.RegisterFlags()
55}
56
57func main() {
58 c := &Config{}
59 c.RegisterFlags()
60 flag.Parse()
Tim Windelschmidt44cacd62023-06-12 23:54:45 +020061 if flag.NArg() > 0 {
62 klog.Exitf("unexpected positional arguments: %v", flag.Args())
63 }
Serge Bazanskicaa12082023-02-16 14:54:04 +010064
Serge Bazanskic50f6942023-04-24 18:27:22 +020065 registry := c.Component.PrometheusRegistry()
66 c.BMDB.EnableMetrics(registry)
67
Serge Bazanskicaa12082023-02-16 14:54:04 +010068 ctx := clicontext.WithInterrupt(context.Background())
Serge Bazanskifbda89e2023-04-24 17:43:58 +020069 c.Component.StartPrometheus(ctx)
Serge Bazanskicaa12082023-02-16 14:54:04 +010070
71 if c.API.APIKey == "" || c.API.User == "" {
72 klog.Exitf("-equinix_api_username and -equinix_api_key must be set")
73 }
Serge Bazanskidea7cd02023-04-26 13:58:17 +020074 c.API.MetricsRegistry = registry
Serge Bazanskicaa12082023-02-16 14:54:04 +010075 api := wrapngo.New(&c.API)
76
77 // These variables are _very_ important to configure correctly, otherwise someone
78 // running this locally with prod creds will actually destroy production
79 // data.
80 if strings.Contains(c.SharedConfig.KeyLabel, "FIXME") {
81 klog.Exitf("refusing to run with -equinix_ssh_key_label %q, please set it to something unique", c.SharedConfig.KeyLabel)
82 }
83 if strings.Contains(c.SharedConfig.DevicePrefix, "FIXME") {
84 klog.Exitf("refusing to run with -equinix_device_prefix %q, please set it to something unique", c.SharedConfig.DevicePrefix)
85 }
86
87 klog.Infof("Ensuring our SSH key is configured...")
88 if err := c.SharedConfig.SSHEquinixEnsure(ctx, api); err != nil {
89 klog.Exitf("Ensuring SSH key failed: %v", err)
90 }
91
92 provisioner, err := c.ProvisionerConfig.New(api, &c.SharedConfig)
93 if err != nil {
94 klog.Exitf("%v", err)
95 }
96
Serge Bazanski86a714d2023-04-17 15:54:21 +020097 initializer, err := manager.NewInitializer(api, c.InitializerConfig, &c.SharedConfig)
Serge Bazanskicaa12082023-02-16 14:54:04 +010098 if err != nil {
99 klog.Exitf("%v", err)
100 }
101
Serge Bazanskiae004682023-04-18 13:28:48 +0200102 recoverer, err := manager.NewRecoverer(api, c.RecovererConfig)
103 if err != nil {
104 klog.Exitf("%v", err)
105 }
106
Serge Bazanskiafd3cf82023-04-19 17:43:46 +0200107 updater, err := c.UpdaterConfig.New(api)
108 if err != nil {
109 klog.Exitf("%v", err)
110 }
111
Serge Bazanskicaa12082023-02-16 14:54:04 +0100112 conn, err := c.BMDB.Open(true)
113 if err != nil {
114 klog.Exitf("Failed to open BMDB connection: %v", err)
115 }
Serge Bazanski77628312023-02-15 23:33:22 +0100116
Serge Bazanskicaa12082023-02-16 14:54:04 +0100117 go func() {
118 err = provisioner.Run(ctx, conn)
119 if err != nil {
120 klog.Exit(err)
121 }
122 }()
123 go func() {
Serge Bazanski86a714d2023-04-17 15:54:21 +0200124 err = manager.RunControlLoop(ctx, conn, initializer)
Serge Bazanskicaa12082023-02-16 14:54:04 +0100125 if err != nil {
126 klog.Exit(err)
127 }
128 }()
Serge Bazanski77628312023-02-15 23:33:22 +0100129 go func() {
Serge Bazanskiae004682023-04-18 13:28:48 +0200130 err = manager.RunControlLoop(ctx, conn, recoverer)
131 if err != nil {
132 klog.Exit(err)
133 }
134 }()
135 go func() {
Serge Bazanskiafd3cf82023-04-19 17:43:46 +0200136 err = updater.Run(ctx, conn)
137 if err != nil {
138 klog.Exit(err)
139 }
140 }()
141 go func() {
Serge Bazanski77628312023-02-15 23:33:22 +0100142 if err := c.WebugConfig.Start(ctx, conn); err != nil && err != ctx.Err() {
143 klog.Exitf("Failed to start webug: %v", err)
144 }
145 }()
Serge Bazanskicaa12082023-02-16 14:54:04 +0100146
147 <-ctx.Done()
148}