Documentation
¶
Overview ¶
Package domain holds the Controller's core types and the rules of the state machines in docs/design.md. It performs no I/O: the store persists these types and the API exposes them.
Index ¶
- Constants
- Variables
- func AcceptsPlacements(admin NodeAdminState, conn NodeConnectionState) bool
- func Authorize(principal Principal, grants []Grant, perm Permission, res Resource) bool
- func CanBeMember(template string) bool
- func CheckChosenNode(n Candidate, r Resources) error
- func CheckDesiredStateChange(p ServerPhase, to DesiredServerState) error
- func EffectiveAccess(user User, grants []Grant, restrict []Permission) (Principal, []Grant)
- func FreePort(r PortRange, used map[int]bool) (int, error)
- func HasPressure(conditions []Condition) bool
- func Parse[T Enum](s string) (T, error)
- func TemplateLoadsPlugins(template string) bool
- func ValidateCommand(c string) error
- func ValidateHost(h string) error
- func ValidateInitialProperties(p map[string]string) error
- func ValidateParts(parts []DataPart) error
- type APIToken
- type ActorKind
- type AgentEvent
- type Artifact
- type ArtifactRef
- type ArtifactSource
- type AuditEvent
- type Backup
- type BackupPlugin
- type BackupState
- type BackupTrigger
- type BuiltinRole
- type Candidate
- type Condition
- type ConditionReason
- type ConditionSource
- type Convergence
- type DataPart
- type DesiredServerState
- type Destination
- type DestinationKind
- type Enum
- type Event
- type EventSource
- type FileEntry
- type FileKind
- type Grant
- type Network
- type Node
- type NodeAdminState
- type NodeCertificate
- type NodeConnectionState
- type NodeStatus
- type OperationError
- type Outcome
- type Permission
- type PermissionInfo
- type PermissionSummary
- type PlannedPlugin
- type PluginArtifact
- type PluginArtifactRef
- type PluginCompatibility
- type PluginJar
- type PluginJars
- type PluginPlan
- type PluginRef
- type PluginSource
- type PluginTarget
- type PluginVersionInfo
- type Port
- type PortProtocol
- type PortRange
- type Principal
- type Resource
- type ResourceAmounts
- type Resources
- type RestartPolicy
- type Role
- type RoleAssignment
- type RolePatch
- type RuntimeState
- type S3Config
- type Schedule
- type ScheduleAction
- type Scope
- type ScopeKind
- type ScopedPermissions
- type Server
- type ServerPhase
- type ServerPlugin
- type ServerStatus
- type ServerSummary
- type Session
- type Software
- type Team
- type User
- type UserPatch
- type Visibility
- type Workflow
- type WorkflowKind
- type WorkflowState
- type WorkloadKind
Constants ¶
const ( // SessionIdleTimeout ends a session nobody has used for this long. SessionIdleTimeout = 12 * time.Hour // SessionLifetime ends every session this long after sign-in. SessionLifetime = 7 * 24 * time.Hour // PasswordResetLifetime is how long a reset link stays valid. PasswordResetLifetime = 24 * time.Hour )
const ( MaxNetworkNameLength = 64 MaxNetworkDescriptionLength = 500 )
MaxNetworkNameLength bounds a network's name; descriptions get more.
const EnrollmentTokenLifetime = time.Hour
EnrollmentTokenLifetime is how long an enrollment token stays valid.
const PluginDenylistedCondition = "plugin-denylisted"
PluginDenylistedCondition is the ID of the Controller condition naming a server's denylisted plugin versions.
const SoftwareChangeCondition = "software-change"
SoftwareChangeCondition is the ID of the Controller condition a failed software version change leaves on a server.
const UploadPluginPrefix = "upload:"
UploadPluginPrefix starts the plugin ID of an uploaded jar, followed by the name its plugin.yml declares.
Variables ¶
var ( // ErrInvalidEnrollmentToken covers every reason an enrollment token is // refused (unknown, wrong secret, expired, used), so a caller learns // nothing about which. ErrInvalidEnrollmentToken = errors.New("invalid enrollment token") // ErrNodeEnrolled is returned when enrolling, or issuing a token for, a // Node that already holds a certificate. ErrNodeEnrolled = errors.New("the Node is already enrolled") )
var ( // ErrNodeNotConnected is returned for operations on a server whose // Node has no live session. ErrNodeNotConnected = errors.New("the server's Node is not connected") // ErrNodeTimeout is returned when a Node does not answer in time. ErrNodeTimeout = errors.New("the server's Node did not answer in time") )
var ( // ErrLastGlobalAdmin is returned when a change would leave no enabled // global administrator, locking everyone out of identity management. ErrLastGlobalAdmin = errors.New("the last enabled global administrator cannot be disabled, demoted or deleted") // ErrBuiltinRole is returned when a built-in role would be changed. ErrBuiltinRole = errors.New("built-in roles cannot be changed or deleted") // ErrTeamOwnsServers is returned when deleting a team that still owns // servers; every server must have an owning team. ErrTeamOwnsServers = errors.New("the team still owns servers") )
var ( // ErrNetworkNotSetUp is returned before the network has a profile. ErrNetworkNotSetUp = errors.New("the network is not set up yet") // ErrProxyExists is returned when the network already has its proxy. ErrProxyExists = errors.New("the network already has a proxy") // ErrInvalidNetwork wraps a network setting that is not valid. ErrInvalidNetwork = errors.New("invalid network setting") // ErrNotMemberTemplate is returned when a server whose software // cannot accept forwarded players is put in the network. ErrNotMemberTemplate = errors.New("only Paper, Purpur and Folia servers can be reached through the network; Vanilla servers are joined directly") )
var ( // ErrPluginsUnsupported is returned for templates that cannot load // plugins (Vanilla). ErrPluginsUnsupported = errors.New("this server's software does not load plugins") // ErrPluginWrongPlatform is returned for a version built for another // platform (e.g. Velocity); force does not override it. ErrPluginWrongPlatform = errors.New("the plugin version is not built for this server's software") // ErrPluginIncompatible is returned for a version not marked for the // server's Minecraft version; force installs it anyway. ErrPluginIncompatible = errors.New("the plugin version is not marked compatible with this server's Minecraft version") // ErrPluginDependencyMissing is returned when a required dependency is // not in the catalog; force installs without it. ErrPluginDependencyMissing = errors.New("a required dependency is not in the catalog") // ErrPluginInstalled is returned when installing a plugin the server // already has. ErrPluginInstalled = errors.New("the plugin is already installed on this server") // ErrPluginRequired is returned when removing a plugin another // installed plugin requires. ErrPluginRequired = errors.New("another installed plugin requires this plugin") // ErrPluginVersionUnknown is returned for a version the catalog does // not have. ErrPluginVersionUnknown = errors.New("the catalog has no such plugin version") )
var DefaultGamePorts = PortRange{First: 25565, Last: 25664}
DefaultGamePorts is where game ports are assigned from.
var ErrBackupNewerSoftware = errors.New("the backup was made with a newer Minecraft version than the server runs; change the server's software first")
ErrBackupNewerSoftware refuses restoring data written by newer Minecraft than the server runs: Minecraft cannot load downgraded worlds.
var ErrBackupNotRestorable = errors.New("only a completed backup can be restored")
ErrBackupNotRestorable refuses a backup that did not succeed.
var ErrInsufficientCapacity = errors.New("no Node has enough unreserved CPU and memory for this server")
ErrInsufficientCapacity is returned when no Node, or not the chosen one, has enough unreserved CPU and memory for a server.
var ErrInvalidMove = errors.New("the server cannot move there")
ErrInvalidMove refuses moving a server where it cannot go.
var ErrInvalidTransition = errors.New("invalid state transition")
ErrInvalidTransition is returned when a state change is not allowed by the state machines in docs/design.md.
var ErrNodeHasServers = errors.New("servers are still assigned to the Node")
ErrNodeHasServers is returned when deleting a Node that servers are still assigned to.
ErrNodeUnavailable is returned when placing a server on a Node that does not accept new servers.
var ErrPhaseBusy = errors.New("another workflow is running for this server")
ErrPhaseBusy is returned when a user action arrives while another workflow is running for the server.
var ErrPortConflict = errors.New("the host port is already used on this Node")
ErrPortConflict is returned when a host port is already used by another server on the same Node, or no port in the range is free.
var ErrServerNotRunning = errors.New("the server is not running")
ErrServerNotRunning is returned for actions that need a running server.
var InitialPropertyKeys = map[string]func(string) bool{ "difficulty": oneOf("peaceful", "easy", "normal", "hard"), "gamemode": oneOf("survival", "creative", "adventure", "spectator"), "pvp": oneOf("true", "false"), "hardcore": oneOf("true", "false"), "view-distance": intIn(2, 32), "simulation-distance": intIn(2, 32), "max-players": intIn(1, 10000), "motd": func(v string) bool { return len(v) <= 256 && !strings.ContainsFunc(v, isControl) }, "level-seed": func(v string) bool { return len(v) <= 64 && !strings.ContainsFunc(v, isControl) }, "white-list": oneOf("true", "false"), "spawn-protection": intIn(0, 1000), }
InitialPropertyKeys are the server.properties settings a new server can start with. Everything else is left to the server's defaults and its Settings afterwards; settings Shardkeep manages are never here.
var MemberTemplates = []string{"paper", "purpur", "folia"}
MemberTemplates are the templates that can be network members: they accept Velocity's modern forwarding without mods.
Functions ¶
func AcceptsPlacements ¶
func AcceptsPlacements(admin NodeAdminState, conn NodeConnectionState) bool
AcceptsPlacements reports whether new servers may be placed on a Node.
func Authorize ¶
func Authorize(principal Principal, grants []Grant, perm Permission, res Resource) bool
Authorize decides whether principal may use perm on res, given every grant in effect for the principal.
func CanBeMember ¶ added in v1.19.0
CanBeMember reports whether servers of template can join the network.
func CheckChosenNode ¶ added in v1.9.0
CheckChosenNode checks a Node an operator chose explicitly: it must be ENABLED and have room. Its health is not required, so an operator can place a server on a Node that is briefly unreachable.
func CheckDesiredStateChange ¶
func CheckDesiredStateChange(p ServerPhase, to DesiredServerState) error
CheckDesiredStateChange validates a user setting desired state to while the server is in phase p. User actions are rejected outside READY, except that a FAILED server may be deleted.
func EffectiveAccess ¶ added in v1.3.0
func EffectiveAccess(user User, grants []Grant, restrict []Permission) (Principal, []Grant)
EffectiveAccess returns the principal and grants to authorize a request with. Without a restriction (restrict is nil) that is the user's own access. A restricted API token gets the intersection of the user's grants and its permissions, and never the global-admin bypass: a restricted token of an administrator holds its permissions at global scope and nothing more, so it cannot manage users, teams or roles.
func HasPressure ¶
HasPressure reports whether any condition is a Node pressure condition.
func TemplateLoadsPlugins ¶ added in v1.14.0
TemplateLoadsPlugins reports whether servers of a template can have plugins.
func ValidateCommand ¶ added in v1.18.0
ValidateCommand checks a console command: one line of at most 256 characters, without control characters.
func ValidateHost ¶ added in v1.19.0
ValidateHost checks a host players or Nodes connect to: an IP address or a DNS name, without a scheme or port.
func ValidateInitialProperties ¶ added in v1.19.0
ValidateInitialProperties checks a new server's starting settings.
func ValidateParts ¶ added in v1.18.0
ValidateParts checks a clone's parts: at least one, each known, none twice.
Types ¶
type APIToken ¶ added in v1.3.0
type APIToken struct {
ID uuid.UUID
UserID uuid.UUID
Name string
DisplayPrefix string
// Permissions restricts the token to a subset of its user's
// permissions; nil means everything the user may do.
Permissions []Permission
ExpiresAt *time.Time
LastUsedAt *time.Time
CreatedAt time.Time
RevokedAt *time.Time
}
APIToken lets automation act as a user. Only the hash of its secret is stored.
type AgentEvent ¶
type AgentEvent struct {
Seq int64
OccurredAt time.Time
// ServerID is nil for Node-level events.
ServerID *uuid.UUID
Kind string
Data json.RawMessage
}
AgentEvent is a change the Agent recorded locally and replays to the Controller, identified by its per-Node sequence number.
type Artifact ¶ added in v1.11.0
type Artifact struct {
ID uuid.UUID
Template string
Version string
Build string
JavaVersion int
SHA256 []byte
Size int64
Source ArtifactSource
Verified bool
CreatedBy *uuid.UUID
CreatedAt time.Time
}
Artifact is a server jar in the Controller's cache.
func (Artifact) Ref ¶ added in v1.11.0
func (a Artifact) Ref() ArtifactRef
Ref returns what a server spec carries about a.
type ArtifactRef ¶ added in v1.11.0
ArtifactRef is what a server spec carries about its artifact.
type ArtifactSource ¶ added in v1.11.0
type ArtifactSource string
ArtifactSource says where an artifact came from.
const ( // ArtifactUpstream was downloaded from the software's publisher and // checked against its published checksum. ArtifactUpstream ArtifactSource = "UPSTREAM" // ArtifactUpload was uploaded by an administrator and is unverified. ArtifactUpload ArtifactSource = "UPLOAD" )
type AuditEvent ¶
type AuditEvent struct {
ID int64
OccurredAt time.Time
ActorKind ActorKind
// ActorUserID is set for user and API-token actors.
ActorUserID *uuid.UUID
// Action is a dotted name such as "server.start".
Action string
TargetKind string
TargetID string
Outcome Outcome
Details json.RawMessage
}
AuditEvent records an action a person or the system took. Audit events are immutable and never hold secrets or IP addresses.
type Backup ¶ added in v1.18.0
type Backup struct {
ID uuid.UUID
ServerID uuid.UUID
DestinationID uuid.UUID
// NodeID took the backup; a Node-directory backup is stored there.
NodeID uuid.UUID
ScheduleID *uuid.UUID
Trigger BackupTrigger
State BackupState
ObjectKey string
SizeBytes int64
SHA256 []byte
Software Software
Plugins []BackupPlugin
Error string
RequestedBy *uuid.UUID
StartedAt time.Time
FinishedAt *time.Time
}
Backup is a backup record. Records outlive their servers.
type BackupPlugin ¶ added in v1.18.0
type BackupPlugin struct {
PluginID string `json:"pluginId"`
CatalogVersionID string `json:"catalogVersionId,omitempty"`
Name string `json:"name"`
Version string `json:"version"`
}
BackupPlugin is a managed plugin a server had when it was backed up.
type BackupState ¶ added in v1.18.0
type BackupState string
BackupState is where a backup stands.
const ( BackupRunning BackupState = "RUNNING" BackupSucceeded BackupState = "SUCCEEDED" BackupFailed BackupState = "FAILED" )
type BackupTrigger ¶ added in v1.18.0
type BackupTrigger string
BackupTrigger is why a backup was taken.
const ( TriggerManual BackupTrigger = "MANUAL" TriggerSchedule BackupTrigger = "SCHEDULE" TriggerBeforeRestore BackupTrigger = "BEFORE_RESTORE" )
type BuiltinRole ¶
type BuiltinRole struct {
Name string
Description string
Permissions []Permission
}
BuiltinRole is a role seeded by the database migrations. Built-in roles can be assigned but not edited or deleted.
func BuiltinRoles ¶
func BuiltinRoles() []BuiltinRole
BuiltinRoles returns the seeded roles. Each one includes the previous.
type Candidate ¶ added in v1.9.0
type Candidate struct {
ID uuid.UUID
Name string
AdminState NodeAdminState
Connection NodeConnectionState
Allocatable ResourceAmounts
// Reserved is the sum of the reservations of every server on the Node,
// whatever its state: resources are reserved, not observed.
Reserved Resources
}
Candidate is a Node as placement sees it.
func Place ¶ added in v1.9.0
Place chooses a Node for a server needing r. Only Nodes that accept placements (ENABLED and HEALTHY) and have room are considered; among them the one with the most free memory wins, then the most free CPU, then the name, which spreads servers across Nodes.
type Condition ¶
type Condition struct {
// ID is unique per Node or server and stable while the condition is
// active. Agent conditions use the Agent's ID.
ID string
Source ConditionSource
Reason ConditionReason
Message string
Since time.Time
}
Condition explains why observed state differs from desired state, or why a Node is under pressure. Discrepancies are conditions, never extra states.
type ConditionReason ¶
type ConditionReason string
ConditionReason is the machine-readable cause of a Condition. Values match the shardkeep.agent.v1 ConditionReason names without their prefix, plus the reasons only the Controller sets.
const ( // Node conditions reported by the Agent. Any of them makes the Node // DEGRADED. ReasonDiskPressure ConditionReason = "DISK_PRESSURE" ReasonMemoryPressure ConditionReason = "MEMORY_PRESSURE" // Server conditions reported by the Agent. ReasonNodeSafetyDiskPressure ConditionReason = "NODE_SAFETY_DISK_PRESSURE" ReasonCrashLoop ConditionReason = "CRASH_LOOP" ReasonSpecInvalid ConditionReason = "SPEC_INVALID" ReasonTemplateUnknown ConditionReason = "TEMPLATE_UNKNOWN" ReasonArtifactHashMismatch ConditionReason = "ARTIFACT_HASH_MISMATCH" ReasonPortConflict ConditionReason = "PORT_CONFLICT" ReasonInsufficientResources ConditionReason = "INSUFFICIENT_RESOURCES" ReasonEULANotAccepted ConditionReason = "EULA_NOT_ACCEPTED" ReasonRestartPending ConditionReason = "RESTART_PENDING" ReasonNetworkSettings ConditionReason = "NETWORK_SETTINGS" // ReasonMissing is set by the Controller on a server it expects on a // Node that does not report it. ReasonMissing ConditionReason = "MISSING" // ReasonOrphanedServer is set by the Controller on a Node that reports a // server the Controller does not know. There is no server record to hold // it, so it is a Node condition naming the orphan in its message. ReasonOrphanedServer ConditionReason = "ORPHANED_SERVER" // ReasonPluginDenylisted is set by the Controller on a server with an // installed plugin version the catalog's denylist names. ReasonPluginDenylisted ConditionReason = "PLUGIN_DENYLISTED" // ReasonWorkflowFailed is set by the Controller on a server whose // restore or clone failed; it stays stopped until restored again. ReasonWorkflowFailed ConditionReason = "WORKFLOW_FAILED" )
func (ConditionReason) IsPressure ¶
func (r ConditionReason) IsPressure() bool
IsPressure reports whether r is a Node pressure condition.
func (ConditionReason) RequiresAcknowledgement ¶
func (r ConditionReason) RequiresAcknowledgement() bool
RequiresAcknowledgement reports whether a server stopped for this reason stays stopped until an administrator acknowledges the condition. Safety overrides win over desired state until then.
func (ConditionReason) Valid ¶
func (r ConditionReason) Valid() bool
Valid reports whether r is a known reason.
type ConditionSource ¶
type ConditionSource string
ConditionSource says who raised a condition.
const ( SourceAgent ConditionSource = "AGENT" SourceController ConditionSource = "CONTROLLER" )
func (ConditionSource) Valid ¶
func (s ConditionSource) Valid() bool
Valid reports whether s is a known source.
type Convergence ¶
type Convergence string
Convergence summarises how observed state relates to desired state.
const ( Converged Convergence = "CONVERGED" InProgress Convergence = "IN_PROGRESS" Discrepancy Convergence = "DISCREPANCY" // Unknown is shown while the Node is UNREACHABLE, keeping the last // reported state. It is derived when read, never stored. Unknown Convergence = "UNKNOWN" )
func ServerConvergence ¶
func ServerConvergence(desired DesiredServerState, observed RuntimeState, removed, nodeReachable bool) Convergence
ServerConvergence compares desired and observed state. observed is the zero RuntimeState until the Agent first reports; removed is true once the Agent confirmed cleanup after DELETED. A Discrepancy must carry a condition.
type DataPart ¶ added in v1.18.0
type DataPart string
DataPart is a part of a server's data, for cloning.
const ( PartWorld DataPart = "WORLD" PartPlayerData DataPart = "PLAYER_DATA" PartProperties DataPart = "PROPERTIES" PartConfig DataPart = "CONFIG" PartPluginConfig DataPart = "PLUGIN_CONFIG" PartPlayerLists DataPart = "PLAYER_LISTS" // PartSchedules copies schedules in the database, not data. PartSchedules DataPart = "SCHEDULES" )
type DesiredServerState ¶
type DesiredServerState string
DesiredServerState is the user-set target for a server.
const ( DesiredRunning DesiredServerState = "RUNNING" DesiredStopped DesiredServerState = "STOPPED" // DesiredDeleted asks the Agent to remove the server. The Controller // removes the record once the Agent confirms cleanup. DesiredDeleted DesiredServerState = "DELETED" )
func (DesiredServerState) Valid ¶
func (s DesiredServerState) Valid() bool
Valid reports whether s is a known desired state.
type Destination ¶ added in v1.18.0
type Destination struct {
ID uuid.UUID
Name string
Kind DestinationKind
Subdirectory string
S3 S3Config
AgeRecipient string
AgeIdentity string
CreatedBy *uuid.UUID
CreatedAt time.Time
UpdatedAt time.Time
}
Destination is where backups are stored. AgeIdentity is a secret: it decrypts every backup stored there.
func (Destination) Validate ¶ added in v1.18.0
func (d Destination) Validate() error
Validate checks a destination's settings (not its keys).
type DestinationKind ¶ added in v1.18.0
type DestinationKind string
DestinationKind is where a destination stores backups.
const ( // DestinationNodeDirectory stores backups in a directory below each // Agent's backup directory, on every Node separately. DestinationNodeDirectory DestinationKind = "NODE_DIRECTORY" // DestinationS3 stores backups in an S3-compatible bucket. DestinationS3 DestinationKind = "S3" )
type Enum ¶
Enum is implemented by the string-backed enums in this package. Their values are the strings stored in the database and shown in the API.
type Event ¶ added in v1.5.0
type Event struct {
ID int64
OccurredAt time.Time
Source EventSource
NodeID *uuid.UUID
ServerID *uuid.UUID
Kind string
Data json.RawMessage
}
Event is one entry in the state history.
type EventSource ¶ added in v1.5.0
type EventSource string
EventSource says who recorded a history event.
const ( EventFromAgent EventSource = "AGENT" EventFromController EventSource = "CONTROLLER" )
type FileKind ¶ added in v1.12.0
type FileKind string
FileKind is the type of an entry in a server's files.
type Grant ¶
type Grant struct {
RoleID uuid.UUID
Permissions []Permission
Scope Scope
}
Grant is one role assignment in effect for a user, held directly or through a team: the role's permissions at the assignment's scope.
type Network ¶ added in v1.19.0
type Network struct {
Name string
Description string
// HasLogo is true when a logo was uploaded.
HasLogo bool
// Address is the host name or IP address players connect to, and Port
// the port (25565 by default).
Address string
Port int
// LobbyServerIDs are the members players are sent to when they join,
// tried in order.
LobbyServerIDs []uuid.UUID
UpdatedAt time.Time
}
Network is the one network a Controller manages: what it is called and how players reach it. Its servers, teams and Nodes are not owned by it.
func (Network) JoinAddress ¶ added in v1.19.0
JoinAddress is what players type: the address, with the port when it is not Minecraft's default.
type Node ¶
type Node struct {
ID uuid.UUID
Name string
AdminState NodeAdminState
CreatedAt time.Time
Status NodeStatus
Conditions []Condition
// Reserved is the CPU and memory reserved by the servers on the Node.
Reserved Resources
// Address is where other Nodes reach the Node's published ports, as
// an administrator set it; empty to use Status.ObservedAddress.
Address string
}
Node is a machine running an Agent. AdminState is desired state; Status and Conditions are observed.
func (Node) ReachAddress ¶ added in v1.19.0
ReachAddress is where other Nodes reach the Node's published ports.
type NodeAdminState ¶
type NodeAdminState string
NodeAdminState is the administrator-set state of a Node (desired state).
const ( // NodeEnabled is normal operation. NodeEnabled NodeAdminState = "ENABLED" // NodeDisabled is cordoned: no new placements, existing servers keep // running and stay managed. NodeDisabled NodeAdminState = "DISABLED" // NodeRevoked means the certificate is revoked. It is terminal. NodeRevoked NodeAdminState = "REVOKED" )
func (NodeAdminState) TransitionTo ¶
func (s NodeAdminState) TransitionTo(to NodeAdminState) error
TransitionTo validates a change from s to the admin state to. Staying in the same state is not a transition.
func (NodeAdminState) Valid ¶
func (s NodeAdminState) Valid() bool
Valid reports whether s is a known admin state.
type NodeCertificate ¶ added in v1.6.0
type NodeCertificate struct {
Serial string
NodeID uuid.UUID
Fingerprint string
NotBefore time.Time
NotAfter time.Time
RevokedAt *time.Time
}
NodeCertificate is a certificate the CA issued to a Node.
type NodeConnectionState ¶
type NodeConnectionState string
NodeConnectionState is derived from the Agent's connection and reports (observed state).
const ( // NodeAwaitingEnrollment means a token was issued but no Agent has // connected yet. NodeAwaitingEnrollment NodeConnectionState = "AWAITING_ENROLLMENT" // NodeHealthy means connected, heartbeats on time and no pressure // conditions. NodeHealthy NodeConnectionState = "HEALTHY" // NodeDegraded means connected but reporting a pressure condition. NodeDegraded NodeConnectionState = "DEGRADED" // NodeUnreachable means the heartbeat timeout passed. Its servers are // assumed still running and shown as unknown. NodeUnreachable NodeConnectionState = "UNREACHABLE" )
func ConnectionStateFor ¶
func ConnectionStateFor(hasPressure bool) NodeConnectionState
ConnectionStateFor returns the state of a connected Node given whether it reports any pressure condition.
func (NodeConnectionState) TransitionTo ¶
func (s NodeConnectionState) TransitionTo(to NodeConnectionState) error
TransitionTo validates a change from s to the connection state to, following the Node state table in docs/design.md.
func (NodeConnectionState) Valid ¶
func (s NodeConnectionState) Valid() bool
Valid reports whether s is a known connection state.
type NodeStatus ¶
type NodeStatus struct {
ConnectionState NodeConnectionState
AgentVersion string
Hostname string
OS string
Arch string
RuntimeName string
RuntimeVersion string
Allocatable ResourceAmounts
Usage ResourceAmounts
LastHeartbeatAt *time.Time
ConnectedAt *time.Time
// ObservedAddress is the IP address the Node's Agent last connected
// from.
ObservedAddress string
}
NodeStatus is what the Controller observes about a Node.
type OperationError ¶ added in v1.12.0
OperationError is an Agent's refusal of an operation on a server, with the protocol's code (INVALID_PATH, NOT_FOUND, NOT_RUNNING, READ_ONLY, TOO_LARGE, CONFLICT, UNAVAILABLE, INVALID_ARGUMENT or INTERNAL).
func (*OperationError) Error ¶ added in v1.12.0
func (e *OperationError) Error() string
type Permission ¶
type Permission string
Permission is an action on an area, named "<area>.<action>".
const ( PermServersRead Permission = "servers.read" PermServersCreate Permission = "servers.create" PermServersStart Permission = "servers.start" PermServersStop Permission = "servers.stop" PermServersDelete Permission = "servers.delete" // PermServersConsole shows the live console, which carries player // names and IP addresses. PermServersConsole Permission = "servers.console" // PermServersCommand sends console commands and restarts servers. PermServersCommand Permission = "servers.command" // PermServersUpdate changes a server's resources and settings. PermServersUpdate Permission = "servers.update" PermFilesRead Permission = "files.read" PermFilesWrite Permission = "files.write" PermFilesDelete Permission = "files.delete" PermPluginsRead Permission = "plugins.read" PermPluginsInstall Permission = "plugins.install" PermPluginsUpdate Permission = "plugins.update" PermPluginsDelete Permission = "plugins.delete" PermNodesRead Permission = "nodes.read" PermNodesManage Permission = "nodes.manage" PermBackupsRead Permission = "backups.read" PermBackupsCreate Permission = "backups.create" PermBackupsRestore Permission = "backups.restore" )
func AllPermissions ¶
func AllPermissions() []Permission
AllPermissions returns every permission, in catalog order.
func (Permission) Area ¶
func (p Permission) Area() string
Area returns the part before the dot, e.g. "servers".
func (Permission) Valid ¶
func (p Permission) Valid() bool
Valid reports whether p is in the permission catalog.
type PermissionInfo ¶ added in v1.4.0
type PermissionInfo struct {
Name Permission
Description string
}
PermissionInfo describes a permission in the catalog.
type PermissionSummary ¶ added in v1.17.0
type PermissionSummary struct {
GlobalAdmin bool
Global []Permission
Teams []ScopedPermissions
Servers []ScopedPermissions
}
PermissionSummary is everything a principal may do, by scope: what holds everywhere, on each team's servers and on single servers. A team or server lists only what Global does not already hold, and Node permissions appear only in Global, where alone they take effect. Allows on a summary decides exactly as Authorize does on the grants it came from.
func SummarizePermissions ¶ added in v1.17.0
func SummarizePermissions(principal Principal, grants []Grant) PermissionSummary
SummarizePermissions merges the grants in effect for principal by scope. Permissions come in catalog order; teams and servers in ID order.
func (PermissionSummary) Allows ¶ added in v1.17.0
func (s PermissionSummary) Allows(perm Permission, res Resource) bool
Allows reports whether the summary allows perm on res.
type PlannedPlugin ¶ added in v1.14.0
type PlannedPlugin struct {
Version PluginVersionInfo
Confirmed bool
// Dependency is true for plugins pulled in by another one.
Dependency bool
}
PlannedPlugin is one plugin version an install or update will put on a server.
type PluginArtifact ¶ added in v1.14.0
type PluginArtifact struct {
ID uuid.UUID
PluginID string
Version string
// CatalogVersionID is empty for uploads.
CatalogVersionID string
FileName string
SHA256 []byte
Size int64
Source ArtifactSource
Verified bool
CreatedBy *uuid.UUID
CreatedAt time.Time
}
PluginArtifact is a plugin jar in the Controller's artifact cache.
func (PluginArtifact) Ref ¶ added in v1.14.0
func (a PluginArtifact) Ref() PluginArtifactRef
Ref returns what a server spec carries about a.
type PluginArtifactRef ¶ added in v1.14.0
PluginArtifactRef is what a server spec carries about a plugin jar.
type PluginCompatibility ¶ added in v1.14.0
type PluginCompatibility int
PluginCompatibility is how well a plugin version fits a server.
const ( // PluginWrongPlatform: built for software the server does not run. PluginWrongPlatform PluginCompatibility = iota // PluginVersionUnconfirmed: the right platform, but the server's // Minecraft version is not among those listed. PluginVersionUnconfirmed // PluginCompatible: the right platform and Minecraft version. PluginCompatible )
Compatibility levels.
func CheckPluginCompatibility ¶ added in v1.14.0
func CheckPluginCompatibility(template, gameVersion string, platforms, gameVersions []string) PluginCompatibility
CheckPluginCompatibility compares what a plugin version declares with a server's template and Minecraft version.
type PluginJar ¶ added in v1.14.0
type PluginJar struct {
FileName string
Size int64
// PluginName and PluginVersion are what its plugin.yml declares;
// empty when it has none.
PluginName string
PluginVersion string
}
PluginJar is a plugin jar an Agent found in a server's volume.
type PluginJars ¶ added in v1.14.0
PluginJars lists a server's plugin jars: those users placed in plugins/ and those Shardkeep manages (named by SHA-256).
type PluginPlan ¶ added in v1.14.0
type PluginPlan struct {
Plugins []PlannedPlugin
// Missing names required dependencies that are not in the catalog
// (only with force; otherwise planning fails).
Missing []string
}
PluginPlan is the outcome of planning an install or update: the root first, then the dependencies it brings.
func PlanPlugin ¶ added in v1.14.0
func PlanPlugin(t PluginTarget, rootID, versionID string, force, update bool, versions func(pluginID string) ([]PluginVersionInfo, error)) (PluginPlan, error)
PlanPlugin chooses what to install for one plugin: the given version or, when versionID is empty, the newest compatible one, plus every required dependency that is not installed yet (each at its newest compatible version). With force, versions not marked for the server's Minecraft version are accepted (unconfirmed) and missing dependencies are reported instead of refused; a wrong platform is never accepted. update allows the root to be installed already. versions returns a plugin's catalog versions, newest first.
type PluginRef ¶ added in v1.14.0
type PluginRef struct {
PluginID string
Artifact PluginArtifactRef
}
PluginRef is one plugin in a server spec.
type PluginSource ¶ added in v1.14.0
type PluginSource string
PluginSource says where an installed plugin came from.
const ( PluginFromCatalog PluginSource = "CATALOG" PluginFromUpload PluginSource = "UPLOAD" )
Plugin sources.
type PluginTarget ¶ added in v1.14.0
type PluginTarget struct {
Template string
// GameVersion is the server's Minecraft version.
GameVersion string
// Installed holds the catalog plugin IDs already on the server.
Installed map[string]bool
}
PluginTarget is the server a plan is for.
type PluginVersionInfo ¶ added in v1.14.0
type PluginVersionInfo struct {
PluginID string
Name string
VersionID string
Version string
Platforms []string
GameVersions []string
// Requires lists required dependencies that are in the catalog.
Requires []string
// MissingRequired names required dependencies that are not.
MissingRequired []string
}
PluginVersionInfo is what the catalog says about one plugin version.
func NewestCompatible ¶ added in v1.14.0
func NewestCompatible(template, gameVersion string, vs []PluginVersionInfo) (PluginVersionInfo, bool)
NewestCompatible returns the newest version in vs that is compatible with the server, if any.
type Port ¶
type Port struct {
Name string
HostPort int
Protocol PortProtocol
}
Port publishes a server port on its Node.
type PortProtocol ¶
type PortProtocol string
PortProtocol is the transport protocol of a published port.
const ( ProtocolTCP PortProtocol = "TCP" ProtocolUDP PortProtocol = "UDP" )
func (PortProtocol) Valid ¶
func (p PortProtocol) Valid() bool
Valid reports whether p is a known protocol.
type PortRange ¶ added in v1.9.0
type PortRange struct{ First, Last int }
PortRange is an inclusive range of host ports.
type Principal ¶
type Principal struct {
UserID uuid.UUID
// GlobalAdmin bypasses resource permissions.
GlobalAdmin bool
// Disabled users are denied everything.
Disabled bool
}
Principal is the user an authorization decision is about.
type Resource ¶
Resource is what an action targets. For a server, TeamID is its owning team and ServerID its ID; when creating a server, ServerID is uuid.Nil and TeamID is the team that will own it. Node actions use the zero Resource.
type ResourceAmounts ¶
type ResourceAmounts struct {
// CPUMillis is CPU in thousandths of a core.
CPUMillis int64
MemoryBytes int64
DiskBytes int64
}
ResourceAmounts is an amount of CPU, memory and disk: a Node's allocatable capacity or current usage.
type Resources ¶
type Resources struct {
// CPUMillis is CPU in thousandths of a core (4 vCPU = 4000).
CPUMillis int64
MemoryBytes int64
}
Resources is a server's reservation, held even while it is idle and enforced by the Agent as runtime limits.
type RestartPolicy ¶
type RestartPolicy struct {
// MaxRestarts within Window; zero disables automatic restarts.
MaxRestarts int
Window time.Duration
}
RestartPolicy bounds automatic restarts after a crash.
func DefaultRestartPolicy ¶
func DefaultRestartPolicy() RestartPolicy
DefaultRestartPolicy is 3 restarts in 10 minutes.
func (RestartPolicy) Validate ¶
func (p RestartPolicy) Validate() error
Validate checks the policy is usable.
type Role ¶ added in v1.4.0
type Role struct {
ID uuid.UUID
Name string
Description string
// Builtin roles are seeded by migrations and cannot be changed.
Builtin bool
Permissions []Permission
CreatedAt time.Time
}
Role is a named set of permissions.
type RoleAssignment ¶ added in v1.4.0
type RoleAssignment struct {
ID uuid.UUID
RoleID uuid.UUID
UserID *uuid.UUID
TeamID *uuid.UUID
Scope Scope
CreatedAt time.Time
}
RoleAssignment gives a role to a user or a team (exactly one) at a scope.
type RolePatch ¶ added in v1.4.0
type RolePatch struct {
Name *string
Description *string
Permissions *[]Permission
}
RolePatch changes a custom role. Nil fields stay as they are; Permissions, when set, replaces the whole set.
type RuntimeState ¶
type RuntimeState string
RuntimeState is the server process state the Agent reports. It is observed only: the Controller records whatever the Agent reports and never rejects it. The zero value means no report has arrived yet.
const ( RuntimeStopped RuntimeState = "STOPPED" RuntimeStarting RuntimeState = "STARTING" // RuntimeRunning means the status ping on the game port answers. RuntimeRunning RuntimeState = "RUNNING" RuntimeStopping RuntimeState = "STOPPING" RuntimeCrashed RuntimeState = "CRASHED" )
func (RuntimeState) Valid ¶
func (s RuntimeState) Valid() bool
Valid reports whether s is a known runtime state.
type S3Config ¶ added in v1.18.0
type S3Config struct {
Endpoint string
Bucket string
Region string
Prefix string
AccessKeyID string
SecretAccessKey string
// CAPEM adds certificates to trust for a self-signed endpoint.
CAPEM string
}
S3Config is an S3-compatible bucket. SecretAccessKey is a secret.
type Schedule ¶ added in v1.18.0
type Schedule struct {
ID uuid.UUID
ServerID uuid.UUID
Cron string
TimeZone string
Action ScheduleAction
DestinationID *uuid.UUID
KeepLast int
KeepDays int
Command string
Enabled bool
CreatedBy *uuid.UUID
CreatedAt time.Time
UpdatedAt time.Time
}
Schedule is a recurring job the server's Agent runs.
type ScheduleAction ¶ added in v1.18.0
type ScheduleAction string
ScheduleAction is what a schedule does.
const ( ScheduleBackup ScheduleAction = "BACKUP" ScheduleRestart ScheduleAction = "RESTART" ScheduleCommand ScheduleAction = "COMMAND" )
type Scope ¶
Scope is where a role assignment applies. TeamID is set only for ScopeTeam, ServerID only for ScopeServer.
type ScopedPermissions ¶ added in v1.17.0
type ScopedPermissions struct {
ID uuid.UUID
Permissions []Permission
}
ScopedPermissions are the permissions held on one team's servers or on one server.
type Server ¶
type Server struct {
ID uuid.UUID
Name string
TeamID uuid.UUID
// NodeID is nil until placement assigns a Node.
NodeID *uuid.UUID
Kind WorkloadKind
DesiredState DesiredServerState
Generation int64
Phase ServerPhase
Software Software
Resources Resources
RestartPolicy RestartPolicy
Ports []Port
// AcknowledgedConditionIDs lists conditions an administrator
// acknowledged, so a safety-stopped server may restart.
AcknowledgedConditionIDs []string
EULAAcceptedAt *time.Time
CreatedAt time.Time
// Artifact is the exact software the server runs; nil until
// provisioning resolves it.
Artifact *ArtifactRef
// RestartCount grows with each restart request.
RestartCount int64
// InNetwork is true for a network member: players reach it through
// the proxy.
InNetwork bool
// InitialProperties are server.properties values for its first start.
InitialProperties map[string]string
}
Server is a logical Minecraft workload, never a container. Every field is desired state written by the Controller; observed state is ServerStatus.
type ServerPhase ¶
type ServerPhase string
ServerPhase is the workflow the Controller is running for a server. Only one workflow runs per server at a time.
const ( PhaseProvisioning ServerPhase = "PROVISIONING" PhaseReady ServerPhase = "READY" PhaseMigrating ServerPhase = "MIGRATING" PhaseRestoring ServerPhase = "RESTORING" PhaseUpdating ServerPhase = "UPDATING" PhaseDeleting ServerPhase = "DELETING" // PhaseFailed means a workflow could not finish; the reason is kept as a // condition. PhaseFailed ServerPhase = "FAILED" )
func (ServerPhase) TransitionTo ¶
func (p ServerPhase) TransitionTo(to ServerPhase) error
TransitionTo validates a change from phase p to phase to, following the phase table in docs/design.md. DELETING ends with the record removed, so it has no outgoing transition.
func (ServerPhase) Valid ¶
func (p ServerPhase) Valid() bool
Valid reports whether p is a known phase.
type ServerPlugin ¶ added in v1.14.0
type ServerPlugin struct {
// ID identifies the installation (catalog IDs contain slashes).
ID uuid.UUID
ServerID uuid.UUID
Source PluginSource
// PluginID is the catalog ID, or UploadPluginPrefix plus the name.
PluginID string
Name string
Version string
// CatalogVersionID is empty for uploads.
CatalogVersionID string
// Platforms and GameVersions are what the catalog said about this
// version when it was installed, so compatibility can be checked again
// after the catalog drops it. Empty for uploads.
Platforms []string
GameVersions []string
// Requires lists the catalog plugin IDs this version needs.
Requires []string
Artifact PluginArtifactRef
// Verified is false for uploads: nothing vouches for them.
Verified bool
// CompatibilityConfirmed is false when it was installed with force.
CompatibilityConfirmed bool
// Dependency is true when it was installed because another plugin
// requires it.
Dependency bool
InstalledBy *uuid.UUID
InstalledAt time.Time
UpdatedAt time.Time
}
ServerPlugin is a plugin Shardkeep manages on a server: part of the server's desired state.
type ServerStatus ¶
type ServerStatus struct {
// RuntimeState is empty until the Agent first reports.
RuntimeState RuntimeState
AppliedGeneration int64
Removed bool
Usage ResourceAmounts
ObservedAt *time.Time
Conditions []Condition
}
ServerStatus is a server's observed state, written only from Agent reports.
type ServerSummary ¶ added in v1.5.0
type ServerSummary struct {
ID uuid.UUID
Name string
Kind WorkloadKind
InNetwork bool
TeamID uuid.UUID
NodeID *uuid.UUID
DesiredState DesiredServerState
Generation int64
Phase ServerPhase
// RuntimeState is empty until the Agent first reports.
RuntimeState RuntimeState
Removed bool
// NodeConnection is empty when no Node is assigned.
NodeConnection NodeConnectionState
// Software, Resources, GamePort (0 when unassigned) and the number of
// conditions, for lists.
Software Software
Resources Resources
GamePort int
ConditionCount int
}
ServerSummary is what a server list shows: identity, desired and observed state, and the Node's connection state for deriving convergence.
func (ServerSummary) Convergence ¶ added in v1.5.0
func (s ServerSummary) Convergence() Convergence
Convergence derives the summary's convergence. A server with no Node, or on a reachable Node, is judged on its reports; on an unreachable Node it is unknown.
type Session ¶ added in v1.3.0
type Session struct {
ID uuid.UUID
UserID uuid.UUID
CreatedAt time.Time
LastSeenAt time.Time
ExpiresAt time.Time
}
Session is a signed-in browser. Only the hash of its token is stored.
type User ¶
type User struct {
ID uuid.UUID
Username string
Email string
DisplayName string
GlobalAdmin bool
// PasswordChangeRequired limits the user to changing their password
// until they do.
PasswordChangeRequired bool
DisabledAt *time.Time
CreatedAt time.Time
}
User is a person who signs in to Shardkeep.
type UserPatch ¶ added in v1.4.0
UserPatch changes a user. Nil fields stay as they are.
func (UserPatch) RemovesGlobalAdmin ¶ added in v1.4.0
RemovesGlobalAdmin reports whether applying p to u takes away an enabled global administrator.
type Visibility ¶ added in v1.5.0
type Visibility struct {
// All is true when every server is included.
All bool
TeamIDs []uuid.UUID
ServerIDs []uuid.UUID
}
Visibility is the set of servers a principal may use one permission on, in a form a database query can filter by.
func VisibleServers ¶ added in v1.5.0
func VisibleServers(principal Principal, grants []Grant, perm Permission) Visibility
VisibleServers returns the servers principal may use perm on. It agrees with Authorize: a server is included exactly when Authorize allows perm on it.
func (Visibility) Includes ¶ added in v1.5.0
func (v Visibility) Includes(res Resource) bool
Includes reports whether v covers res.
type Workflow ¶ added in v1.18.0
type Workflow struct {
ID uuid.UUID
Kind WorkflowKind
ServerID uuid.UUID
BackupID *uuid.UUID
SourceServerID *uuid.UUID
FromNodeID *uuid.UUID
ToNodeID *uuid.UUID
Parts []DataPart
SafetyBackupID *uuid.UUID
// StartAfter starts the server once the workflow succeeds.
StartAfter bool
// PreviousPort is a migration's game port on the old Node.
PreviousPort *int
State WorkflowState
Step string
Error string
CreatedBy *uuid.UUID
CreatedAt time.Time
UpdatedAt time.Time
}
Workflow moves data into a server: a restore, a migration or a clone.
type WorkflowKind ¶ added in v1.18.0
type WorkflowKind string
WorkflowKind is what a workflow does to a server's data.
const ( WorkflowRestore WorkflowKind = "RESTORE" WorkflowRestoreAsNew WorkflowKind = "RESTORE_AS_NEW" WorkflowMigrate WorkflowKind = "MIGRATE" WorkflowClone WorkflowKind = "CLONE" )
type WorkflowState ¶ added in v1.18.0
type WorkflowState string
WorkflowState is where a workflow stands.
const ( WorkflowRunning WorkflowState = "RUNNING" WorkflowSucceeded WorkflowState = "SUCCEEDED" WorkflowFailed WorkflowState = "FAILED" )
type WorkloadKind ¶
type WorkloadKind string
WorkloadKind selects how the Agent runs a server.
const ( // WorkloadMinecraftServer is a Minecraft game server. WorkloadMinecraftServer WorkloadKind = "MINECRAFT_SERVER" // WorkloadVelocityProxy is the network's Velocity proxy. WorkloadVelocityProxy WorkloadKind = "VELOCITY_PROXY" )
func (WorkloadKind) Valid ¶
func (k WorkloadKind) Valid() bool
Valid reports whether k is a known workload kind.