| package shepherd |
| |
| import ( |
| "context" |
| "fmt" |
| "net/netip" |
| |
| "source.monogon.dev/cloud/bmaas/bmdb" |
| "source.monogon.dev/cloud/bmaas/bmdb/model" |
| ) |
| |
| var ErrMachineNotFound = fmt.Errorf("machine not found") |
| var ErrNotImplemented = fmt.Errorf("not implemented") |
| |
| // ProviderID is an opaque unique identifier for a machine within a single |
| // provider instance. It is generated by the Provider and usually the same |
| // as the ID of the machine within the system that the Provider managed. |
| // The Shepherd (and BMaaS in general) requires these IDs to be unique |
| // within a provider and stable. |
| type ProviderID string |
| |
| const InvalidProviderID ProviderID = "invalid" |
| |
| // IsValid reports whether the ProviderID is valid. |
| func (p ProviderID) IsValid() bool { |
| return p != InvalidProviderID |
| } |
| |
| // State defines in which state the machine is. |
| // See the different states for more information. |
| type State int |
| |
| const ( |
| // StateUndefined is used as a placeholder to prevent that the default |
| // value can create any type of bad behaviour. |
| StateUndefined State = iota |
| // StatePossiblyUsed defines the state where a machine is possibly used, |
| // this is a state for use in stateless providers where the shepherd has |
| // to check against the bmdb if Machine.ID is already provisioned or not. |
| // These machines must have a valid ID and Addr. |
| StatePossiblyUsed |
| // StateKnownUnused defines the state where a machine is know to be free, |
| // e.g. a hardware reservation at equinix. These machines may not have an |
| // ID or Addr. |
| StateKnownUnused |
| // StateKnownUsed defines the state where a machine is known to be used, |
| // e.g. a deployed machine that is in use. These machines must have a |
| // valid ID and Addr. |
| StateKnownUsed |
| ) |
| |
| func (s State) String() string { |
| switch s { |
| case StateUndefined: |
| return "Undefined" |
| case StateKnownUnused: |
| return "KnownUnused" |
| case StateKnownUsed: |
| return "KnownUsed" |
| case StatePossiblyUsed: |
| return "PossiblyUsed" |
| default: |
| return fmt.Sprintf("<invalid value %d>", s) |
| } |
| } |
| |
| type Machine interface { |
| // ID returns the provider id, see ProviderID for more information. |
| ID() ProviderID |
| // Addr returns the machines ip address that is reachable from the |
| // shepherd. It is used to connect to the machine via SSH to execute |
| // all takeover tasks, etc. |
| Addr() netip.Addr |
| // State returns the state in which the machine is |
| State() State |
| } |
| |
| type CreateMachineRequest struct { |
| // UnusedMachine resembles a machine to use as deployment target. |
| UnusedMachine Machine |
| } |
| |
| // Provider is the interface that is used to abstract the interaction between |
| // the shepherd and machine providers like Equinix. All methods inside this |
| // interface must not be called concurrently. |
| type Provider interface { |
| // ListMachines returns all existing machines for a provider. Machines |
| // that are still in the state of being created by CreateMachine should |
| // not be returned. |
| ListMachines(context.Context) ([]Machine, error) |
| |
| // GetMachine returns an existing machine for a provider. Machines |
| // that are still in the state of being created by CreateMachine should |
| // not be returned. If a there are no machines found after these filters |
| // an error should be returned. |
| GetMachine(context.Context, ProviderID) (Machine, error) |
| |
| // CreateMachine creates a new machine with the given parameters and |
| // returns the created instance. The provider is required to create the |
| // entry into the machine table and MachineProvided tag. If there are no |
| // more machines avaiable, an error should be returned. |
| CreateMachine(context.Context, *bmdb.Session, CreateMachineRequest) (Machine, error) |
| |
| // Type returns the value that represents this provider inside the database. |
| Type() model.Provider |
| } |
| |
| type Recoverer interface { |
| Provider |
| |
| // RebootMachine tries to bring a machine back from the dead by e.g. rebooting |
| RebootMachine(context.Context, ProviderID) error |
| |
| // ReinstallMachine should reinstall the given machine and if the provider |
| // does not support reinstallation, the function should return an error |
| // stating this. If reinstalled, the installed tag should be updated to |
| // allow the reconcile loop to restart the takeover process. |
| ReinstallMachine(context.Context, ProviderID) error |
| } |