Documentation
¶
Overview ¶
Package node manages Docker host (server) records and their reachability.
Index ¶
- Constants
- Variables
- func AppAlias(app *models.Application) string
- func CanaryAlias(app *models.Application) string
- func NewAppAlias(token string, appID uint) string
- func SetAppNetwork(name string)
- type NodeInput
- type NodeLimitError
- type Service
- func (s *Service) AdoptGateway(id uint, container, image, configYAML string) (*models.Server, error)
- func (s *Service) Authenticate(token string) (*models.Server, error)
- func (s *Service) AuthenticateProvider(slug, token string) (*models.Server, error)
- func (s *Service) Bootstrap(ctx context.Context, endpoint string)
- func (s *Service) CreateNode(in NodeInput) (*models.Server, string, error)
- func (s *Service) DeleteNode(id uint) error
- func (s *Service) FindBySwarmNodeID(swarmNodeID string) (*models.Server, error)
- func (s *Service) GatewayRedisPassword(id uint) (string, error)
- func (s *Service) GatewayToken(id uint) (string, error)
- func (s *Service) Get(id uint) (*models.Server, error)
- func (s *Service) IDByUID(uid string) (uint, error)
- func (s *Service) LearnEndpoint(id uint, ip, hostname string)
- func (s *Service) LearnSwarmNodeID(id uint, swarmNodeID string)
- func (s *Service) List(ctx context.Context) ([]models.Server, error)
- func (s *Service) MarkConnected(id uint, agentVersion string)
- func (s *Service) MarkDisconnected(id uint)
- func (s *Service) MarkGatewayDeployed(id uint)
- func (s *Service) NameBySwarmNodeID(swarmNodeID string) string
- func (s *Service) Placeable(serverID uint) error
- func (s *Service) RegenerateToken(id uint) (string, error)
- func (s *Service) RegisterClusterNode(swarmNodeID, hostname string) (*models.Server, error)
- func (s *Service) ReleaseGateway(id uint) (*models.Server, error)
- func (s *Service) SetCordoned(id uint, cordoned bool) error
- func (s *Service) SetGatewayConfig(id uint, config string) (*models.Server, error)
- func (s *Service) SetGatewayImage(id uint, image string) (*models.Server, error)
- func (s *Service) SetGatewayUpdate(id uint, p *models.GatewayUpdateProgress) error
- func (s *Service) SetNodeLimit(fn func() int)
- func (s *Service) SetSwarmNodeID(id uint, swarmNodeID string) error
- func (s *Service) UpdateNode(id uint, in NodeInput) (*models.Server, error)
- func (s *Service) WorkloadImpact(id uint) (apps int64, databases int64, err error)
Constants ¶
const IngressOverlay = "miabi-ingress"
IngressOverlay is the single shared, attachable Swarm overlay the central Goma gateway joins to reach every clustered app's service VIP for public (north- south) ingress. Cluster (service) apps attach to it in addition to their per-workspace east-west overlay. Because it carries only gateway↔VIP traffic (each service registers just its globally-unique upstream alias here, not its tenant-scoped name), east-west isolation between workspaces is unaffected.
Variables ¶
var ( ErrNodeNotFound = errors.New("node not found") ErrNameRequired = errors.New("node name is required") ErrLocalNode = errors.New("the local node cannot be modified this way") ErrBadToken = errors.New("invalid agent token") ErrNodeCordoned = errors.New("node is cordoned and cannot accept new placements") // ErrConnectivityAckRequired is returned when an update changes the node's // reachability settings without the caller acknowledging the impact. ErrConnectivityAckRequired = &connectivityAckError{} )
var AppNetwork = "miabi"
AppNetwork is the shared Docker network Goma Gateway and managed app containers join (the proxy gateway network). Configurable via MIABI_PROXY_NETWORK; set once at startup with SetAppNetwork.
Functions ¶
func AppAlias ¶
func AppAlias(app *models.Application) string
AppAlias is the stable network DNS alias for an application's active container, used as the reverse-proxy upstream so it survives redeploys. It is the app's stored Alias ("mb-app-<token>-<id>"); legacy apps with no stored alias fall back to "mb-app-<id>".
func CanaryAlias ¶
func CanaryAlias(app *models.Application) string
CanaryAlias is the network DNS alias for an application's canary container, run alongside the stable release during a canary deployment. Only the stable release answers AppAlias, so the proxy can split weighted traffic between the two distinct aliases.
func NewAppAlias ¶
NewAppAlias builds a fresh stable alias for a newly created app.
func SetAppNetwork ¶
func SetAppNetwork(name string)
SetAppNetwork overrides the gateway network name (call once at startup, before Bootstrap or any deploy).
Types ¶
type NodeInput ¶
type NodeInput struct {
Name string
Address string
PublicIP string
PublicHostname string
Connectivity models.ServerConnectivity
AccessMode models.ServerAccessMode
// DockerEndpoint is the host for non-agent modes (unix://… / tcp://host:2376).
DockerEndpoint string
TLSCACert string // api, optional (PEM)
TLSCert string // api, optional (PEM)
TLSKey string // api, optional (PEM; stored encrypted)
// Acknowledge confirms the caller accepts that a reachability change may
// briefly interrupt the workloads running on the node. Required whenever the
// update actually changes connectivity/access mode/endpoint/address/TLS.
Acknowledge bool
}
NodeInput is the create/update payload for a remote node. The TLS key is plaintext on input and encrypted at rest.
type NodeLimitError ¶
type NodeLimitError struct{ Limit int }
NodeLimitError is returned when registering a node would exceed the edition's node cap. It exposes a stable Code() and a curated Message() so the API envelope surfaces NODE_LIMIT_REACHED with an upgrade-oriented message rather than the generic status word.
func (*NodeLimitError) Code ¶
func (e *NodeLimitError) Code() string
func (*NodeLimitError) Error ¶
func (e *NodeLimitError) Error() string
func (*NodeLimitError) Message ¶
func (e *NodeLimitError) Message() string
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func NewService ¶
func NewService(repo *repositories.ServerRepository, dockerClient docker.Client) *Service
func (*Service) AdoptGateway ¶
func (s *Service) AdoptGateway(id uint, container, image, configYAML string) (*models.Server, error)
AdoptGateway tracks a pre-existing gateway container as this node's gateway (import). It records the container name + image, optionally copies the gateway's existing config into the node's stored config, switches the node to edge-gateway connectivity, and stamps the deploy time — without recreating anything, so the running gateway is untouched.
func (*Service) Authenticate ¶
Authenticate resolves the node an agent token belongs to (constant-time-ish via hash lookup).
func (*Service) AuthenticateProvider ¶
AuthenticateProvider resolves the node a Goma HTTP-provider request belongs to, accepting either the agent join token or the node's gateway token. The slug in the URL must match the resolved node.
func (*Service) Bootstrap ¶
Bootstrap registers the local node, pings the daemon to set its status, and ensures the managed Docker network exists. Non-fatal: logs and continues if Docker is unreachable so the API can still serve.
func (*Service) CreateNode ¶
CreateNode registers a remote node. For agent mode it returns a one-time join token (only its hash is stored); other modes return an empty token.
func (*Service) DeleteNode ¶
DeleteNode removes a remote node record.
func (*Service) FindBySwarmNodeID ¶ added in v1.3.0
FindBySwarmNodeID resolves the node backing a swarm node id.
func (*Service) GatewayRedisPassword ¶
GatewayRedisPassword returns the per-node edge-gateway Redis password (decrypted), minting and persisting one (encrypted) on first use. Stable across redeploys so the gateway and its Redis keep matching credentials.
func (*Service) GatewayToken ¶
GatewayToken returns the node's edge-gateway provider token (decrypted), minting and persisting one (encrypted) on first use. Unlike the join token it is recoverable, so the gateway can be (re)deployed on demand.
func (*Service) LearnEndpoint ¶
LearnEndpoint fills a node's public IP and/or hostname discovered from its agent connection, so an admin doesn't have to know them when adding the node: ip is the agent's source address as seen by the control plane, hostname is self-reported (X-Agent-Hostname). Non-destructive — it only fills fields the admin left blank, so an explicit value is never overwritten. Only a routable public IP is adopted (a private/NAT/loopback source would be misleading).
func (*Service) LearnSwarmNodeID ¶ added in v1.3.0
LearnSwarmNodeID records the swarm node id the agent read from its own Docker engine at connect (X-Agent-Swarm-Node-ID).
This is how a Miabi node gets mapped to its swarm node in every case, not just the one where Miabi did the joining. The control plane can only fill SwarmNodeID itself when it ran the `swarm join` (see cluster.JoinNode); a host joined with `docker swarm join`, or one that was already a member when Miabi met it, stayed unmapped forever. That is not cosmetic — an unmapped node cannot be resolved from a service's task, which is precisely what makes a replica's logs and metrics unreachable. The node is the authority on which node it is, so let it say.
Unlike LearnEndpoint this OVERWRITES: a node can leave one swarm and join another, and its own report is always more current than ours. An empty value is ignored rather than treated as "left the swarm" — an older agent sends nothing at all, and we must not wipe a good id because of it. The leave paths clear it explicitly (cluster.LeaveNode).
func (*Service) MarkConnected ¶
MarkConnected records that a node's agent connected.
func (*Service) MarkDisconnected ¶
MarkDisconnected records that a node's agent dropped.
func (*Service) MarkGatewayDeployed ¶
MarkGatewayDeployed stamps the node's last successful gateway deploy time and clears any imported-gateway tracking (a fresh install supersedes an import).
func (*Service) NameBySwarmNodeID ¶
NameBySwarmNodeID resolves a swarm node id to a node's Miabi display name, so a cluster app's real replica placement can be shown by name. Returns "" when no node record carries that swarm id (the caller then falls back to a short id).
func (*Service) Placeable ¶
Placeable validates that a node can accept a new resource (app/db/volume). The local node (0) is always placeable; a remote node must exist and not be cordoned. (Reachability is enforced separately when the operation runs.)
func (*Service) RegenerateToken ¶
RegenerateToken issues a fresh join token for a node, invalidating the old one.
func (*Service) RegisterClusterNode ¶ added in v1.3.0
RegisterClusterNode creates the record for a swarm worker that registered itself through the global agent service.
The caller (cluster.AuthenticateAgent) has already verified the swarm node id is a member of THIS swarm, so this is not an open registration endpoint — the machine is one the swarm already trusts.
The node is marked AutoJoined: the cluster brought it in, an admin did not. It has no join token of its own (it authenticates with the cluster token), and it defaults to port-forward connectivity like any other node — which in cluster mode is moot, since ingress reaches it over the overlay.
func (*Service) ReleaseGateway ¶
ReleaseGateway stops tracking an imported gateway without touching the container (the inverse of AdoptGateway).
func (*Service) SetCordoned ¶
SetCordoned toggles a node's drain flag (no new placements when cordoned).
func (*Service) SetGatewayConfig ¶
SetGatewayConfig stores a node's custom edge-gateway config (empty resets to the rendered default). Returns the updated node.
func (*Service) SetGatewayImage ¶
SetGatewayImage stores a node's edge-gateway image override (empty resets to the resolved default). Returns the updated node.
func (*Service) SetGatewayUpdate ¶
func (s *Service) SetGatewayUpdate(id uint, p *models.GatewayUpdateProgress) error
SetGatewayUpdate persists the node's in-flight gateway update progress (nil clears it). Used by the safe-update flow so progress survives a reconnect.
func (*Service) SetNodeLimit ¶
SetNodeLimit wires the resolved edition node cap (manager + remotes). The closure is re-evaluated on every node registration so a license install or lapse takes effect without a restart. A nil closure or a negative return means unlimited.
func (*Service) SetSwarmNodeID ¶
SetSwarmNodeID records (or clears) the Docker Swarm node ID a node maps to, so the Nodes page can correlate it to `docker node ls`. Idempotent: a no-op when the value is unchanged, to avoid write churn on every cluster refresh.
func (*Service) UpdateNode ¶
UpdateNode edits a remote node's reachability settings. Credential fields are only replaced when non-empty (so an unchanged form keeps existing secrets).