blob: be3bc276c181f82eb1b7f32875c3a10e5254c81a [file] [log] [blame]
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +02001package main
2
3import (
4 "errors"
5 "flag"
6 "fmt"
7 "strings"
8 "time"
9
10 "source.monogon.dev/cloud/equinix/wrapngo"
11 "source.monogon.dev/cloud/shepherd/manager"
12)
13
14var (
15 NoSuchKey = errors.New("no such key")
16)
17
18// providerConfig contains configuration options used by both the Initializer and
19// Provisioner components of the Shepherd. In CLI scenarios, RegisterFlags should
20// be called to configure this struct from CLI flags. Otherwise, this structure
21// should be explicitly configured, as the default values are not valid.
22type providerConfig struct {
23 // ProjectId is the Equinix project UUID used by the manager. See Equinix API
24 // documentation for details. Must be set.
25 ProjectId string
26
27 // KeyLabel specifies the ID to use when handling the Equinix-registered SSH
28 // key used to authenticate to newly created servers. Must be set.
29 KeyLabel string
30
31 // DevicePrefix applied to all devices (machines) created by the Provisioner,
32 // and used by the Provisioner to identify machines which it managed.
33 // Must be set.
34 DevicePrefix string
35
36 // OS defines the operating system new devices are created with. Its format
37 // is specified by Equinix API.
38 OS string
39
40 // UseProjectKeys defines if the provisioner adds all ssh keys defined inside
41 // the used project to every new machine. This is only used for debug purposes.
42 UseProjectKeys bool
43
44 // RebootWaitSeconds defines how many seconds to sleep after a reboot call
45 // to ensure a reboot actually happened.
46 RebootWaitSeconds int
47
48 // ReservationCacheTimeout defines how after which time the reservations should be
49 // refreshed.
50 ReservationCacheTimeout time.Duration
51}
52
53func (pc *providerConfig) check() error {
54 if pc.ProjectId == "" {
55 return fmt.Errorf("-equinix_project_id must be set")
56 }
57 if pc.KeyLabel == "" {
58 return fmt.Errorf("-equinix_ssh_key_label must be set")
59 }
60 if pc.DevicePrefix == "" {
61 return fmt.Errorf("-equinix_device_prefix must be set")
62 }
63
64 // These variables are _very_ important to configure correctly, otherwise someone
65 // running this locally with prod creds will actually destroy production
66 // data.
67 if strings.Contains(pc.KeyLabel, "FIXME") {
68 return fmt.Errorf("refusing to run with -equinix_ssh_key_label %q, please set it to something unique", pc.KeyLabel)
69 }
70 if strings.Contains(pc.DevicePrefix, "FIXME") {
71 return fmt.Errorf("refusing to run with -equinix_device_prefix %q, please set it to something unique", pc.DevicePrefix)
72 }
73
74 return nil
75}
76
77func (pc *providerConfig) RegisterFlags() {
78 flag.StringVar(&pc.ProjectId, "equinix_project_id", "", "Equinix project ID where resources will be managed")
79 flag.StringVar(&pc.KeyLabel, "equinix_ssh_key_label", "shepherd-FIXME", "Label used to identify managed SSH key in Equinix project")
80 flag.StringVar(&pc.DevicePrefix, "equinix_device_prefix", "shepherd-FIXME-", "Prefix applied to all devices (machines) in Equinix project, used to identify managed machines")
81 flag.StringVar(&pc.OS, "equinix_os", "ubuntu_20_04", "OS that provisioner will deploy on Equinix machines. Not the target OS for cluster customers.")
82 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.")
83 flag.IntVar(&pc.RebootWaitSeconds, "equinix_reboot_wait_seconds", 30, "How many seconds to sleep to ensure a reboot happend")
84 flag.DurationVar(&pc.ReservationCacheTimeout, "equinix_reservation_cache_timeout", time.Minute*15, "Reservation cache validity timeo")
85}
86
87func (pc *providerConfig) New(sshKey *manager.SSHKey, api wrapngo.Client) (*equinixProvider, error) {
88 if err := pc.check(); err != nil {
89 return nil, err
90 }
91
92 return &equinixProvider{
93 config: pc,
94 sshKey: sshKey,
95 api: api,
96 }, nil
97}