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