blob: 3504eb7b7aec69ca579ace6de42276e7546e607a [file] [log] [blame]
Tim Windelschmidtb6308cd2023-10-10 21:19:03 +02001package shepherd
2
3import (
4 "context"
5 "fmt"
6 "net/netip"
7
8 "source.monogon.dev/cloud/bmaas/bmdb"
9 "source.monogon.dev/cloud/bmaas/bmdb/model"
10)
11
12var ErrMachineNotFound = fmt.Errorf("machine not found")
13var ErrNotImplemented = fmt.Errorf("not implemented")
14
15// ProviderID is an opaque unique identifier for a machine within a single
16// provider instance. It is generated by the Provider and usually the same
17// as the ID of the machine within the system that the Provider managed.
18// The Shepherd (and BMaaS in general) requires these IDs to be unique
19// within a provider and stable.
20type ProviderID string
21
22const InvalidProviderID ProviderID = "invalid"
23
24// IsValid reports whether the ProviderID is valid.
25func (p ProviderID) IsValid() bool {
26 return p != InvalidProviderID
27}
28
29// State defines in which state the machine is.
30// See the different states for more information.
31type State int
32
33const (
34 // StateUndefined is used as a placeholder to prevent that the default
35 // value can create any type of bad behaviour.
36 StateUndefined State = iota
37 // StatePossiblyUsed defines the state where a machine is possibly used,
38 // this is a state for use in stateless providers where the shepherd has
39 // to check against the bmdb if Machine.ID is already provisioned or not.
40 // These machines must have a valid ID and Addr.
41 StatePossiblyUsed
42 // StateKnownUnused defines the state where a machine is know to be free,
43 // e.g. a hardware reservation at equinix. These machines may not have an
44 // ID or Addr.
45 StateKnownUnused
46 // StateKnownUsed defines the state where a machine is known to be used,
47 // e.g. a deployed machine that is in use. These machines must have a
48 // valid ID and Addr.
49 StateKnownUsed
50)
51
52func (s State) String() string {
53 switch s {
54 case StateUndefined:
55 return "Undefined"
56 case StateKnownUnused:
57 return "KnownUnused"
58 case StateKnownUsed:
59 return "KnownUsed"
60 case StatePossiblyUsed:
61 return "PossiblyUsed"
62 default:
63 return fmt.Sprintf("<invalid value %d>", s)
64 }
65}
66
67type Machine interface {
68 // ID returns the provider id, see ProviderID for more information.
69 ID() ProviderID
70 // Addr returns the machines ip address that is reachable from the
71 // shepherd. It is used to connect to the machine via SSH to execute
72 // all takeover tasks, etc.
73 Addr() netip.Addr
74 // State returns the state in which the machine is
75 State() State
76}
77
78type CreateMachineRequest struct {
79 // UnusedMachine resembles a machine to use as deployment target.
80 UnusedMachine Machine
81}
82
83// Provider is the interface that is used to abstract the interaction between
84// the shepherd and machine providers like Equinix. All methods inside this
85// interface must not be called concurrently.
86type Provider interface {
87 // ListMachines returns all existing machines for a provider. Machines
88 // that are still in the state of being created by CreateMachine should
89 // not be returned.
90 ListMachines(context.Context) ([]Machine, error)
91
92 // GetMachine returns an existing machine for a provider. Machines
93 // that are still in the state of being created by CreateMachine should
94 // not be returned. If a there are no machines found after these filters
95 // an error should be returned.
96 GetMachine(context.Context, ProviderID) (Machine, error)
97
98 // CreateMachine creates a new machine with the given parameters and
99 // returns the created instance. The provider is required to create the
100 // entry into the machine table and MachineProvided tag. If there are no
101 // more machines avaiable, an error should be returned.
102 CreateMachine(context.Context, *bmdb.Session, CreateMachineRequest) (Machine, error)
103
104 // Type returns the value that represents this provider inside the database.
105 Type() model.Provider
106}
107
108type Recoverer interface {
109 Provider
110
111 // RebootMachine tries to bring a machine back from the dead by e.g. rebooting
112 RebootMachine(context.Context, ProviderID) error
113
114 // ReinstallMachine should reinstall the given machine and if the provider
115 // does not support reinstallation, the function should return an error
116 // stating this. If reinstalled, the installed tag should be updated to
117 // allow the reconcile loop to restart the takeover process.
118 ReinstallMachine(context.Context, ProviderID) error
119}