blob: aeaab4653c73b743a94aa66c27cb920df8c17d60 [file] [log] [blame]
// Copyright The Monogon Project Authors.
// SPDX-License-Identifier: Apache-2.0
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
}
// Availability defines the availability state according to the provider.
// See the different states for more information.
type Availability int
const (
// AvailabilityUndefined is used as a placeholder to prevent that the default
// value can create any type of bad behaviour.
AvailabilityUndefined Availability = iota
// AvailabilityPossiblyUsed 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.
AvailabilityPossiblyUsed
// AvailabilityKnownUnused 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.
AvailabilityKnownUnused
// AvailabilityKnownUsed 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.
AvailabilityKnownUsed
)
func (a Availability) String() string {
switch a {
case AvailabilityUndefined:
return "Undefined"
case AvailabilityKnownUnused:
return "KnownUnused"
case AvailabilityKnownUsed:
return "KnownUsed"
case AvailabilityPossiblyUsed:
return "PossiblyUsed"
default:
return fmt.Sprintf("<invalid value %d>", a)
}
}
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
// Availability returns the availability of the machine.
Availability() Availability
// Failed should return true if the machine is in a failed state and
// should be ignored if there are inconsistencies between the provider
// and BMDB.
Failed() bool
}
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
}