cloud: split shepherd up
Change-Id: I8e386d9eaaf17543743e1e8a37a8d71426910d59
Reviewed-on: https://review.monogon.dev/c/monogon/+/2213
Reviewed-by: Serge Bazanski <serge@monogon.tech>
Tested-by: Jenkins CI
diff --git a/cloud/shepherd/provider/equinix/provider_config.go b/cloud/shepherd/provider/equinix/provider_config.go
new file mode 100644
index 0000000..be3bc27
--- /dev/null
+++ b/cloud/shepherd/provider/equinix/provider_config.go
@@ -0,0 +1,97 @@
+package main
+
+import (
+ "errors"
+ "flag"
+ "fmt"
+ "strings"
+ "time"
+
+ "source.monogon.dev/cloud/equinix/wrapngo"
+ "source.monogon.dev/cloud/shepherd/manager"
+)
+
+var (
+ NoSuchKey = errors.New("no such key")
+)
+
+// providerConfig contains configuration options used by both the Initializer and
+// Provisioner components of the Shepherd. In CLI scenarios, RegisterFlags should
+// be called to configure this struct from CLI flags. Otherwise, this structure
+// should be explicitly configured, as the default values are not valid.
+type providerConfig struct {
+ // ProjectId is the Equinix project UUID used by the manager. See Equinix API
+ // documentation for details. Must be set.
+ ProjectId string
+
+ // KeyLabel specifies the ID to use when handling the Equinix-registered SSH
+ // key used to authenticate to newly created servers. Must be set.
+ KeyLabel string
+
+ // DevicePrefix applied to all devices (machines) created by the Provisioner,
+ // and used by the Provisioner to identify machines which it managed.
+ // Must be set.
+ DevicePrefix string
+
+ // OS defines the operating system new devices are created with. Its format
+ // is specified by Equinix API.
+ OS string
+
+ // UseProjectKeys defines if the provisioner adds all ssh keys defined inside
+ // the used project to every new machine. This is only used for debug purposes.
+ UseProjectKeys bool
+
+ // RebootWaitSeconds defines how many seconds to sleep after a reboot call
+ // to ensure a reboot actually happened.
+ RebootWaitSeconds int
+
+ // ReservationCacheTimeout defines how after which time the reservations should be
+ // refreshed.
+ ReservationCacheTimeout time.Duration
+}
+
+func (pc *providerConfig) check() error {
+ if pc.ProjectId == "" {
+ return fmt.Errorf("-equinix_project_id must be set")
+ }
+ if pc.KeyLabel == "" {
+ return fmt.Errorf("-equinix_ssh_key_label must be set")
+ }
+ if pc.DevicePrefix == "" {
+ return fmt.Errorf("-equinix_device_prefix must be set")
+ }
+
+ // These variables are _very_ important to configure correctly, otherwise someone
+ // running this locally with prod creds will actually destroy production
+ // data.
+ if strings.Contains(pc.KeyLabel, "FIXME") {
+ return fmt.Errorf("refusing to run with -equinix_ssh_key_label %q, please set it to something unique", pc.KeyLabel)
+ }
+ if strings.Contains(pc.DevicePrefix, "FIXME") {
+ return fmt.Errorf("refusing to run with -equinix_device_prefix %q, please set it to something unique", pc.DevicePrefix)
+ }
+
+ return nil
+}
+
+func (pc *providerConfig) RegisterFlags() {
+ flag.StringVar(&pc.ProjectId, "equinix_project_id", "", "Equinix project ID where resources will be managed")
+ flag.StringVar(&pc.KeyLabel, "equinix_ssh_key_label", "shepherd-FIXME", "Label used to identify managed SSH key in Equinix project")
+ flag.StringVar(&pc.DevicePrefix, "equinix_device_prefix", "shepherd-FIXME-", "Prefix applied to all devices (machines) in Equinix project, used to identify managed machines")
+ flag.StringVar(&pc.OS, "equinix_os", "ubuntu_20_04", "OS that provisioner will deploy on Equinix machines. Not the target OS for cluster customers.")
+ flag.BoolVar(&pc.UseProjectKeys, "equinix_use_project_keys", false, "Add all Equinix project keys to newly provisioned machines, not just the provisioner's managed key. Debug/development only.")
+ flag.IntVar(&pc.RebootWaitSeconds, "equinix_reboot_wait_seconds", 30, "How many seconds to sleep to ensure a reboot happend")
+ flag.DurationVar(&pc.ReservationCacheTimeout, "equinix_reservation_cache_timeout", time.Minute*15, "Reservation cache validity timeo")
+}
+
+func (pc *providerConfig) New(sshKey *manager.SSHKey, api wrapngo.Client) (*equinixProvider, error) {
+ if err := pc.check(); err != nil {
+ return nil, err
+ }
+
+ return &equinixProvider{
+ config: pc,
+ sshKey: sshKey,
+ api: api,
+ }, nil
+}