Documentation
¶
Overview ¶
Package protocol holds the wire-level helpers shared by the control plane and the agent: signed-message preimages (docs/agent-protocol.md section 2) and key fingerprints.
Index ¶
- Constants
- Variables
- func AdmitLongWait(ctx context.Context) bool
- func AgentNonce(q url.Values) ([]byte, error)
- func AuthPreimage(endpointID string, nonce []byte, serverHost string, version int) []byte
- func CapabilitiesFit(runtime string, capabilities []string) bool
- func ChallengePreimage(nonce, agentNonce []byte, serverHost, instanceFingerprint string) []byte
- func CheckRuntimeShape(runtime string, s *Snapshot) error
- func Clamp(s *Snapshot)
- func CleanText(s string, max int) string
- func ClusterHealth(active bool, s *Snapshot) string
- func ExecRefusal(err error) string
- func Fingerprint(publicKey []byte) string
- func IsExecRefusal(reason string) bool
- func IsImageAction(action string) bool
- func KubernetesNames(project string, services []string) map[string]string
- func NamespaceNetwork(name string) bool
- func Preimage(context string, fields ...[]byte) []byte
- func RawFingerprint(publicKey []byte) []byte
- func RunDeployment(raw json.RawMessage, target WorkloadRef) (*appsv1.Deployment, error)
- func Shrink(s *Snapshot) []byte
- func SplitImageReference(s string) (name, tag string)
- func StorageSizeBytes(s string) (int64, bool)
- func UnmarshalHelloBounded(data []byte, h *Hello) error
- func UnmarshalSnapshotBounded(data []byte, s *Snapshot) error
- func ValidClusterIP(s string) bool
- func ValidConfigurationEnvName(name string) bool
- func ValidContainerHexID(s string) bool
- func ValidContainerID(s string) bool
- func ValidDNSLabel(s string) bool
- func ValidDNSSubdomain(s string) bool
- func ValidDeploymentID(id string) bool
- func ValidExecID(id string) bool
- func ValidImageReference(s string) bool
- func ValidLabelValue(s string) bool
- func ValidRequestID(id string) bool
- func ValidServiceName(s string) bool
- func ValidStorageClass(s string) bool
- func VerifyAuth(publicKey []byte, endpointID string, nonce []byte, serverHost string, ...) bool
- func VerifyEnrollment(publicKey, token, proof []byte) bool
- func VerifyRotation(currentKey, currentRawFingerprint, newKey, signature []byte) bool
- func WithLongWait(ctx context.Context, admit func() bool) context.Context
- type Auth
- type Challenge
- type Claim
- type Command
- type ConfigurationCancel
- type ConfigurationOpen
- type ConfigurationResult
- type Container
- type ContainerConfiguration
- type ContainerInspection
- type DeploymentIdentity
- type DeploymentRequest
- type DeploymentResult
- type DeploymentService
- type DeploymentStep
- type Device
- type Engine
- type EnvEntry
- type Envelope
- type ExecClose
- type ExecData
- type ExecOpen
- type ExecResize
- type ExecSpec
- type ExecStatus
- type ExecStream
- type Expectation
- type ExplicitService
- type FieldError
- type Healthcheck
- type Hello
- type Image
- type ImagePlatform
- type ImagePull
- type InspectionCancel
- type InspectionOpen
- type InspectionResult
- type InspectionTarget
- type KubernetesClaim
- type KubernetesInventory
- type KubernetesMount
- type KubernetesTarget
- type LogCancel
- type LogChunk
- type LogClose
- type LogConfig
- type LogRequest
- type Metrics
- type Mount
- type MountCounts
- type Network
- type NetworkAttachment
- type NetworkAttachmentSpec
- type Node
- type Pod
- type PodContainer
- type PodStatus
- type PodTarget
- type Port
- type RegistryAuth
- type RemovalRequest
- type RemovalTarget
- type Resources
- type Result
- type Rotate
- type Rotated
- type Sample
- type Service
- type Snapshot
- type StorageClass
- type TerminalSize
- type Volume
- type Workload
- type WorkloadApply
- type WorkloadCondition
- type WorkloadConfiguration
- type WorkloadContainer
- type WorkloadEnv
- type WorkloadRef
- type WorkloadResources
- type WorkloadStatus
Constants ¶
const ( TypeConfigurationOpen = "configuration.open" TypeConfigurationResult = "configuration.result" TypeConfigurationCancel = "configuration.cancel" CapabilityContainerConfigure = "container.configure" // ConfigurationLifetime is the longest grant a configuration.open may carry. The alias below // shares InspectionOpen.ValidateFor, which enforces InspectionLifetime; the server issues // Expires = min(context deadline, now + ConfigurationLifetime) and the agent enforces this // bound with ValidateWithin. ConfigurationLifetime = 20 * time.Second MaxConfigurationFrameBytes = 320 << 10 MaxArgv, MaxArgvEntryBytes = 64, 4096 MaxListEntries, MaxListEntryBytes = 32, 1024 MaxConfigurationNetworks = 16 // the brief's MaxNetworks; that name is the inventory's 200 MaxLogOptions = 16 // Configuration carries full label values; inventory keeps its display bound. MaxConfigurationLabelValueBytes = 4096 // MountTmpfs is a configuration-only mount kind; inventory reports tmpfs as "other". MountTmpfs = "tmpfs" )
const ( TypeDeploymentApply = "deployment.apply" TypeDeploymentResult = "deployment.result" CapabilityDeploymentApply = "deployment.apply" CapabilityDeploymentPull = "deployment.pull" // the agent runs a service's Pull step MaxDeploymentRequestBytes = 320 << 10 MaxDeploymentRequestBytesLegacy = 192 << 10 // an agent without CapabilityDeploymentPull MaxDeploymentResultBytes = 160 << 10 DeploymentLifetime = 15 * time.Minute MaxDeploymentServices = 100 MaxDeploymentEnvEntries = 128 MaxDeploymentEnvValueBytes = 16 << 10 MaxDeploymentEnvBytes = 64 << 10 MaxDeploymentPorts = 64 MaxDeploymentStepDetailBytes = 256 MaxRegistryAuthHosts = 16 MaxRegistryAuthSecretBytes = 4096 MaxDeploymentVolumes = 64 MaxMountPathBytes = 4096 StepPrecondition = "precondition" StepImage = "image" StepPull = "pull" StepVolume = "volume" StepStop = "stop" StepRename = "rename" StepCreate = "create" StepStart = "start" StepRemove = "remove" StepRecheck = "recheck" // re-inspects the old container at the start of its replacement StepRollback = "rollback" // restores the replaced container after a failed start; also reports a failed create, rename or stop undo, or a run's container left unsettled StepApply = "apply" // a workload apply's update of the object StepRollout = "rollout" // a workload apply's wait for the rollout // ExplicitProject and ExplicitRevision are the fixed identity of a direct (edit or run) frame. ExplicitProject = "direct" ExplicitRevision = 1 OutcomeSkipped = "skipped" TypeDeploymentRemove = "deployment.remove" CapabilityDeploymentRemove = "deployment.remove" MaxRemovalTargets = 100 // three steps each fit a result's MaxDeploymentResultSteps // MaxClockSkew bounds the difference between the server's clock when it built a frame and // the agent's when it reads one, and between an inventory's observed and received times. MaxClockSkew = 5 * time.Minute // MaxDeploymentResultSteps is eight steps per service (precondition, image or pull, // recheck, rename, create, stop, start, remove), one per volume and one rollback: only the // service whose step ended the run rolls back. A ninth step per service would // break the MaxDeploymentResultBytes proof. MaxDeploymentResultSteps = 8*MaxDeploymentServices + MaxDeploymentVolumes + 1 )
Deployment frames carry one plan to the agent and one result back. The request holds resolved environment values: it exists only in memory on both sides and is never logged. See docs/agent-protocol.md, Deployment apply.
const ( ResultStepFailed = "step_failed" // a step did not succeed; the steps say which ResultClockSkew = "clock_skew" // issued_at is more than MaxClockSkew from the agent's clock ResultInvalidRequest = "invalid_request" // the frame failed Validate ResultWrongEndpoint = "wrong_endpoint" // the frame names another endpoint ResultBusy = "busy" // the agent is already applying a deployment ResultRestarted = "restarted" // the agent restarted after replacement began ResultUnreadable = "unreadable" // the runtime returned a result the agent could not validate // CodeLegacy is the server's reading of a result from an agent built before codes, for a // step or a result; no agent emits it. CodeLegacy = "legacy" )
Outcome codes: the closed vocabulary a denied or failed step, and a result that did not succeed, report in. A step's Detail is its code's parameter, never a sentence. See docs/agent-protocol.md, Outcome codes.
const ( MaxExecChunkBytes = 32 << 10 MaxExecArgs = 64 MaxExecArgumentBytes = 8 << 10 MaxExecDimension = 512 ExecIdleTimeout = 15 * time.Minute ExecAbsoluteTimeout = 8 * time.Hour )
Runtime exec bounds implement docs/agent-protocol.md section 7. Wire grants and stream admission remain control-plane/agent responsibilities, not runtime policy.
const ( TypeExecOpen = "exec.open" TypeExecReady = "exec.ready" TypeExecInput = "exec.input" TypeExecOutput = "exec.output" TypeExecResize = "exec.resize" TypeExecCancel = "exec.cancel" TypeExecClose = "exec.close" MaxExecStreamsPerEndpoint = 4 ExecGrantLifetime = time.Minute MaxExecFrameBytes = 64 << 10 )
Exec grants travel only over the authenticated agent socket. Connection is the handshake nonce, so a grant from an old socket cannot start a second process.
const ( TypeInspectionOpen = "inspection.open" TypeInspectionResult = "inspection.result" TypeInspectionCancel = "inspection.cancel" InspectionLifetime = 25 * time.Second MaxInspectionFrameBytes = 32 << 10 MaxInspectionsPerEndpoint = 2 CapabilityContainerInspect = "container.inspect" // CapabilityContainerInspectVerdict marks an agent whose inspections carry the unsupported // codes and configuration_verified; plans need it, the inspection dialog does not. CapabilityContainerInspectVerdict = "container.inspect.verdict" // CapabilityContainerInspectHealth marks an agent whose inspections carry health and // restart_count; health validation needs it. CapabilityContainerInspectHealth = "container.inspect.health" // MaxRestartCount bounds a reported restart count. MaxRestartCount = 1_000_000 MaxUnsupported = 40 )
const ( MaxContainers = 1000 MaxImages = 1000 MaxNetworks = 200 MaxVolumes = 500 MaxLabels = 32 MaxLabelBytes = 256 // MaxSnapshotBytes is the one limit both sides enforce on the serialized snapshot: the // agent shrinks to it before sending, the server refuses past it. MaxSnapshotBytes = 1 << 20 MaxNameBytes = 255 MaxImageRefBytes = 512 MaxStatusBytes = 128 )
Product inventory types. Runtime SDK shapes never leave their adapter; these are the bounded summaries the control plane stores (docs/application-schema.md, retention-policy.md). Container environment is deliberately absent: it is where secrets live.
const ( MountVolume = "volume" MountBind = "bind" MountOther = "other" // inventory only: tmpfs, npipe and anything else the runtime reports )
const ( RuntimeDocker = "docker" RuntimeKubernetes = "kubernetes" )
Runtimes an endpoint can have. The endpoint row fixes one at enrollment; nothing changes it.
const ( CapabilityKubernetesInventory = "kubernetes.inventory" CapabilityPodLogs = "pod.logs" )
Kubernetes capabilities. A cluster agent advertises these and nothing else; a Docker agent never advertises them (CapabilitiesFit).
const ( MaxNodes = 500 MaxNamespaces = 500 MaxWorkloads = 2000 MaxPods = 2000 MaxServices = 2000 MaxClaims = 1000 MaxPodContainers = 32 MaxWorkloadImages = 32 MaxNodeRoles = 16 MaxServicePorts = 32 MaxKubeNameBytes = 253 MaxKubeImageBytes = 1 << 10 MaxKubeShortBytes = 64 )
Cluster inventory bounds. Lists are cut at their cap and named in Truncated; nested lists are cut silently by Clamp, except a pod's containers, which also mark "pods".
const ( HealthHealthy = "healthy" HealthDegraded = "degraded" HealthUnknown = "unknown" )
Cluster health, derived on read from the stored inventory.
const ( MaxKubernetesClaims = 16 // per request MaxKubernetesMounts = 8 // per service MaxStorageClasses = 100 AccessReadWriteOnce = "ReadWriteOnce" // DetailRetained is the detail of a removal's skipped volume step: the claim was kept. DetailRetained = "retained" )
Claims a cluster deployment mounts: a PersistentVolumeClaim per chosen named volume, created once and never updated or deleted by the agent. See docs/agent-protocol.md, Claims.
const ( CapabilityKubernetesDeploy = "kubernetes.deploy" CapabilityKubernetesClaims = "kubernetes.claims" CapabilityKubernetesServiceIPs = "kubernetes.service_ips" CapabilityKubernetesRemove = "kubernetes.remove" )
Cluster deployment capabilities. A cluster agent advertises them when it can apply and remove an application's objects; it never advertises deployment.pull, because the kubelet pulls. kubernetes.claims says it applies KubernetesTarget.Claims and service volumes: an agent without it decodes a frame leniently and would run the pod with no claim.
const ( // CapabilityKubernetesWorkloads marks a cluster agent that runs the workload and pod // actions, reads a workload's configuration and applies it. CapabilityKubernetesWorkloads = "kubernetes.workloads" // CapabilityKubernetesWorkloadsRun marks a cluster agent whose workload apply honours // Create: agents from before it advertise kubernetes.workloads and refuse a run. CapabilityKubernetesWorkloadsRun = "kubernetes.workloads.run" CapabilityKubernetesManifestsRun = "kubernetes.manifests.run" // CapabilityPodExec marks a cluster agent that opens an exec session in a pod container. CapabilityPodExec = "pod.exec" TypeWorkloadApply = "workload.apply" MaxWorkloadApplyBytes = 128 << 10 // WorkloadApplyService is the one service a workload apply's DeploymentResult names. WorkloadApplyService = "workload" MaxWorkloadReplicas = 1000 MaxWorkloadContainers = 16 MaxWorkloadEnv = 128 // per container MaxQuantityBytes = 32 MaxResourceVersionBytes = 64 MaxWorkloadEnvFrom = MaxListEntries MaxWorkloadUnsupported = 16 )
Cluster workload operations: commands on workloads and pods, the configuration read of a workload's pod template, its apply, and pod exec.
const ( WorkloadDeployment = "deployment" WorkloadStatefulSet = "statefulset" WorkloadDaemonSet = "daemonset" WorkloadPod = "pod" )
Kinds a WorkloadRef names, lower-case as they travel.
const ( TypeLogOpen = "log.open" // server → agent: start reading one container's log TypeLogChunk = "log.chunk" // agent → server: the next piece of it TypeLogClose = "log.close" // agent → server: this stream is over, and why TypeLogCancel = "log.cancel" // server → agent: the reader went away, stop reading )
Log frame types. A log stream is a conversation inside the one socket: the server opens it, the agent sends chunks until it ends or is cancelled, and either side can end it.
const ( // MaxLogChunkBytes is one chunk on the wire. Small enough that a slow reader costs little // to hold and that a chunk fits well inside the control-frame limit. MaxLogChunkBytes = 32 << 10 // MaxLogFrameBytes bounds a log chunk frame. It is larger than the control-frame limit // because JSON escaping can multiply a byte by six, and a log carries whatever the // application printed; the log text inside it is still bounded by MaxLogChunkBytes. MaxLogFrameBytes = 256 << 10 // MaxLogLines and MaxLogBytes bound one request: whichever comes first ends it, and the // answer says it was truncated rather than pretending it was the whole log. MaxLogLines = 10000 MaxLogBytes = 4 << 20 // MaxLogTail is the most history one request may ask the runtime for. MaxLogTail = MaxLogLines // MaxLogStreamsPerEndpoint is how many log streams one endpoint serves at once. Both // sides read it from here: if the agent's limit were the lower of the two it would be the // real ceiling, and the control plane's per-reader split -- which exists so that members // holding nothing but container.logs cannot deny an administrator the logs of a host -- // would hand out places the agent then refuses. MaxLogStreamsPerEndpoint = 4 // LogFollowBuffer is what one following stream may hold for a reader that is not keeping // up. Past it, bytes are dropped and the gap is reported: a reader watching a chatty // container must not be able to grow the control plane's memory without limit. LogFollowBuffer = 1 << 20 )
Log bounds, from docs/retention-policy.md. Log bodies are never stored, so these bound memory and work rather than disk: what an operator asked for must not be able to cost the control plane or the agent more than this, however much the container has written.
const ( TypeChallenge = "challenge" TypeAuth = "auth" TypeHello = "hello" TypeHeartbeat = "heartbeat" TypeInventory = "inventory" TypeInventoryRefresh = "inventory.refresh" TypeMetrics = "metrics" TypeApproved = "enrollment.approved" TypeRotate = "identity.rotate" // agent → server: a new key signed by the current one TypeRotated = "identity.rotated" // server → agent: the operator acknowledged that key TypeCommand = "command" // server → agent: do one thing to one named resource TypeResult = "result" // agent → server: what became of it TypeError = "error" )
Frame types used by the connection lifecycle.
const ( OutcomeSucceeded = "succeeded" OutcomeFailed = "failed" OutcomeDenied = "denied" // the agent refused: wrong tenant, unmet precondition OutcomeTimedOut = "timed_out" // the deadline passed before the runtime answered OutcomeUnknown = "unknown" // the socket went before a result came back )
Command outcomes. Every dispatched command ends in exactly one of these, and the set is closed: an outcome the server has not heard is Unknown, never a missing row.
const ( ActionStart = "container.start" ActionStop = "container.stop" ActionRestart = "container.restart" ActionRemove = "container.remove" // Image actions name a reference rather than a container, and travel in Reference. ActionImagePull = "image.pull" ActionImageRemove = "image.remove" // Cluster actions name a WorkloadRef ("<namespace>/<kind>/<name>") in Reference. ActionWorkloadRestart = "workload.restart" ActionWorkloadScale = "workload.scale" // Expects.Replicas is the new count ActionWorkloadDelete = "workload.delete" ActionPodDelete = "pod.delete" )
Container actions on a container that already exists. Removal is here because it travels the same path as the others, but it is not one of them: it carries a different permission and a confirmation the server checks against its own state before any frame is built.
const ( CloseRevoked = "identity_revoked" CloseDuplicate = "duplicate_connection" CloseIncompatible = "incompatible_version" CloseRejected = "enrollment_rejected" CloseShutdown = "server_shutdown" CloseTimeout = "heartbeat_timeout" CloseProtocol = "protocol_error" CloseKeyRetired = "key_retired" // switch to the acknowledged key CloseKeyPending = "key_pending_review" // keep using the approved key )
Close reasons the server sends in the WebSocket close frame.
const ( ContextEnroll = "kyyard-agent-enroll-v1" ContextAuth = "kyyard-agent-auth-v1" ContextRotate = "kyyard-agent-rotate-v1" // ContextServer is signed by the control plane's instance key, never by an agent key. ContextServer = "kyyard-server-challenge-v2" TokenSize = 32 )
const ( // CapabilityKubernetesInspect marks a cluster agent that answers a WorkloadRef inspection; // health validation of a cluster needs it. CapabilityKubernetesInspect = "kubernetes.inspect" // MaxWorkloadConditions bounds a status's conditions; MaxWorkloadPods its pods. MaxWorkloadConditions = 8 MaxWorkloadPods = MaxPodContainers * 4 )
Kubernetes inspection: the inspection frames carry a Deployment target and its status. See agent-protocol.md, Container inspection.
const AgentNonceParam = "agent_nonce"
AgentNonceParam is the dial query parameter carrying the agent's fresh nonce, unpadded base64url, so the server's proof covers a value the server could not have seen before.
const CapabilityInventoryRefresh = "inventory.refresh"
CapabilityInventoryRefresh supports an on-demand report on either runtime.
const KindDeployment = "Deployment"
KindDeployment is the one object kind a Kubernetes identity names.
const MaxImageReferenceBytes = 512
MaxImageReferenceBytes bounds a reference. Docker's own limit is far larger, but a reference becomes part of a URL addressed to the host's root-equivalent socket, and nothing legitimate comes close to this.
const MaxInspectionEntries = 64
const MaxKubeObjectName = 63
MaxKubeObjectName bounds a Deployment's and a Service's name: a DNS-1123 label.
const MaxMetricsBytes = 64 << 10
MaxMetricsBytes matches the server's control-payload limit. Metrics are shrunk on the agent before they enter the wire, so a large but valid container set cannot reconnect-loop.
const MaxMounts = 32
MaxMounts bounds a container's reported mounts and a deployed service's mounts alike.
const MaxNetworkAttachments = 32
MaxNetworkAttachments bounds a container's reported networks and attachments alike.
const MaxResultDetailBytes = 4 << 10
MaxResultDetailBytes bounds the text an agent may attach to a result.
const MaxSamples = 1000
MaxSamples bounds one metrics frame; the adapter reports running containers only.
const Version = 1
Version is the protocol major version both sides negotiate in hello.
Variables ¶
var ( // ErrExecForbidden: the agent's own grant lacks the exec (create pods/exec). ErrExecForbidden = errors.New("forbidden") // ErrExecPodSecurity: the pod's namespace does not enforce Pod Security baseline or // restricted, or the pod itself does not meet baseline. ErrExecPodSecurity = errors.New("pod_security") )
A runtime refuses an exec start with one of these fixed errors when the operator can act on the cause. The agent sends its text as the exec.close reason, and the server passes exactly these through to the browser; every other start failure keeps a fixed generic reason.
var ConfigurationOnlyCodes = []string{"volumes_from", "volume_driver", "mount_options", "ulimits", "sysctls", "device_requests", "pid_mode", "ipc_mode", "userns_mode", "cgroup_parent", "group_add", "links", "runtime", "anonymous_volume"}
ConfigurationOnlyCodes are the UnsupportedCodes naming settings an ExplicitService cannot express: a configuration read lists them, and an explicit recreate of a container that has any is refused.
var ErrClockSkew = errors.New("clock skew exceeds 5 minutes")
ErrClockSkew is a frame whose issue time is more than MaxClockSkew from the reader's clock.
var ErrSnapshotShape = errors.New("the snapshot does not match the endpoint's runtime")
ErrSnapshotShape is a snapshot whose lists do not match the endpoint's runtime.
var HealthStates = map[string]bool{"none": true, "starting": true, "healthy": true, "unhealthy": true}
HealthStates is the closed vocabulary of Container.Health and ContainerInspection.Health.
var UnsupportedCodes = []string{"mount_type", "anonymous_volume", "volumes_from", "volume_driver", "mount_options", "tmpfs", "auto_remove", "read_only_rootfs", "privileged", "capabilities", "security_opt", "devices", "pid_mode", "ipc_mode", "user", "runtime", "resource_limits", "ulimits", "sysctls", "device_requests", "init", "userns_mode", "cgroup_parent", "group_add", "extra_hosts", "dns", "links", "network", "image_config", "k8s_volume", "k8s_host_ip", "k8s_restart", "k8s_name", "k8s_namespace", "k8s_volume_shared", "k8s_name_taken", "k8s_service_renamed"}
UnsupportedCodes is the closed vocabulary of ContainerInspection.Unsupported, in the order the Docker adapter reports them, then the k8s_ codes a plan for a Kubernetes endpoint refuses. Each is configuration the target runtime cannot take from the definition.
var WorkloadUnsupportedCodes = []string{"env_field_ref", "resources_extended", "containers_truncated", "env_truncated", "argv_truncated", "env_from_truncated"}
WorkloadUnsupportedCodes names what a workload read carries that an apply would drop.
Functions ¶
func AdmitLongWait ¶
AdmitLongWait asks for room for one; false means refuse the action rather than wait. Without an admission in ctx the wait is admitted.
func AgentNonce ¶
AgentNonce reads the agent's nonce from the dial query: nil when absent, an error unless it is exactly one value decoding to 32 bytes.
func AuthPreimage ¶
AuthPreimage binds the signature to this endpoint, this nonce, the host the agent dialed and the version it speaks, so a capture cannot be replayed elsewhere or later.
func CapabilitiesFit ¶
CapabilitiesFit reports whether a hello's capabilities belong to the endpoint's runtime: apart from runtime-neutral inventory refresh, a cluster names cluster capabilities and a Docker agent names none of them.
func ChallengePreimage ¶
ChallengePreimage binds the instance key's signature to both nonces, the host the agent dialed and the fingerprint it pins, so a signature cannot be replayed for another socket, a later handshake or another name.
func CheckRuntimeShape ¶
CheckRuntimeShape holds a Kubernetes endpoint to a cluster inventory and no Docker lists, and a Docker endpoint to no cluster inventory.
func Clamp ¶
func Clamp(s *Snapshot)
Clamp rewrites a snapshot so it conforms to the declared schema by construction: list caps, string bounds, label caps and text safety, whatever the sender did. Truncated lists are named.
func CleanText ¶
CleanText makes agent-supplied text safe to show next to other text: control characters, line and paragraph separators and bidi controls are removed, and the result is cut on a rune boundary at max bytes. The server applies it to every string it stores; the adapter applies it before sending so honest agents never trip the limits.
func ClusterHealth ¶
ClusterHealth is degraded when a reported node is not Ready, healthy when every node is reported and Ready, and unknown when the endpoint is not active, has no cluster inventory, reports no node, or reports only part of its nodes.
func ExecRefusal ¶
ExecRefusal is err's fixed close reason, or "" when err is not one of the fixed refusals.
func Fingerprint ¶
Fingerprint identifies a public key: hex SHA-256 of its raw bytes.
func IsExecRefusal ¶
IsExecRefusal reports whether reason is a fixed refusal's close reason.
func IsImageAction ¶
IsImageAction reports whether an action names an image rather than a container.
func KubernetesNames ¶
KubernetesNames maps each service to the name of its Deployment and Service: <project>-<service> lower-cased, '_' and '.' read as '-', prefixed "ky-" when it would not start with a letter (a Service name must). A name longer than 63 characters, or one two services share, is cut and suffixed with six hex characters of a digest of project and service, so every name is distinct.
func NamespaceNetwork ¶
NamespaceNetwork reports a name that is a network namespace mode rather than a network: the host's, or another container's. Only network_mode may name one; an attachment may not.
func Preimage ¶
Preimage is the context string and every field, each as a 4-byte big-endian length followed by the bytes, so a signature under one context can never verify under another or split differently. The prefix is total for any field a message can carry.
func RawFingerprint ¶
RawFingerprint is the 32-byte digest the rotation preimage carries; Fingerprint is its hex.
func RunDeployment ¶
func RunDeployment(raw json.RawMessage, target WorkloadRef) (*appsv1.Deployment, error)
RunDeployment decodes an exact new Deployment, retaining native selectors, ports, probes, volume references and security settings. Namespace Pod Security remains the admission gate. Identity/service-account fields are constrained because this is a namespace-scoped run.
func Shrink ¶
Shrink drops labels, then mounts (marking each container's list truncated), then the tails of the largest lists, until the serialized snapshot fits MaxSnapshotBytes, naming what it dropped. It returns the final encoding.
func SplitImageReference ¶
SplitImageReference separates a reference into the image name and the tag or digest that pins it to one image. An empty tag means the reference named neither, which is not a thing this product sends to a runtime: the Engine API reads an empty tag as "every tag in the repository", so "pull nginx" would fetch the whole repository onto the host.
func StorageSizeBytes ¶
StorageSizeBytes reads a claim size: a whole number of Mi, Gi or Ti from 1Mi to 16Ti, the one quantity form KyYard writes. ok is false for anything else.
func UnmarshalHelloBounded ¶
UnmarshalHelloBounded limits capability count and total decoded text before the caller hands it to the store.
func UnmarshalSnapshotBounded ¶
UnmarshalSnapshotBounded decodes list fields one element at a time. A byte cap alone is not enough: a small JSON object can expand into a much larger Go value.
func ValidClusterIP ¶
ValidClusterIP checks a canonical unicast address. The Kubernetes API server owns service-range and allocation checks; neither inventory nor a local pool is authoritative.
func ValidConfigurationEnvName ¶
ValidConfigurationEnvName is the name rule Validate applies to a container's environment.
func ValidContainerHexID ¶
ValidContainerHexID reports whether s is a full 64-hex container ID, not a name.
func ValidContainerID ¶
ValidContainerID reports whether s can name a container.
func ValidDNSLabel ¶
ValidDNSLabel is RFC 1123 label syntax as Kubernetes applies it: namespaces, containers.
func ValidDNSSubdomain ¶
ValidDNSSubdomain is RFC 1123 subdomain syntax as Kubernetes applies it: pod names.
func ValidDeploymentID ¶
ValidDeploymentID is the grammar Validate requires of Deployment: a lowercase UUID. A frame failing this cannot be attributed to any deployment and so cannot be answered at all.
func ValidExecID ¶
ValidExecID constrains daemon-returned identifiers before they enter another API path.
func ValidImageReference ¶
ValidImageReference reports whether s can name an image. Both the control plane and the agent check it: the agent is the last thing between a request body and the socket, and the repository's rule is that neither check may be the only one.
func ValidLabelValue ¶
ValidLabelValue is Kubernetes label value syntax: at most 63 characters, alphanumeric at both ends, '-', '_' and '.' between.
func ValidRequestID ¶
ValidRequestID is the grammar of a frame's request_id, the audit correlation ID: the API's 32 hex characters or the store's UUID fallback, safe to log.
func ValidServiceName ¶
ValidServiceName is the grammar of a service name on the wire: a cluster agent reads it back from its objects' labels.
func ValidStorageClass ¶
ValidStorageClass is "" (the cluster default) or a DNS-1123 subdomain.
func VerifyAuth ¶
func VerifyEnrollment ¶
VerifyEnrollment checks the agent's proof of possession over the raw token.
func VerifyRotation ¶
VerifyRotation checks that the current key signed the new one under the rotation context.
Types ¶
type Auth ¶
type Auth struct {
EndpointID string `json:"endpoint_id"`
Fingerprint string `json:"fingerprint"` // which of the endpoint's keys signed
Version int `json:"version"`
Signature []byte `json:"signature"`
}
Auth is the agent's reply, signed under ContextAuth by its endpoint key.
type Challenge ¶
type Challenge struct {
Nonce []byte `json:"nonce"`
InstanceFingerprint string `json:"instance_fingerprint"`
Versions []int `json:"versions"`
InstanceKey []byte `json:"instance_key,omitempty"`
Signature []byte `json:"signature,omitempty"`
}
Challenge is the server's first frame: a fresh nonce and its pinned identity, proven by the instance key's signature (SignChallenge). Servers before the proof, and any server answering a dial without an agent nonce, omit both fields.
func SignChallenge ¶
func SignChallenge(instance ed25519.PrivateKey, nonce, agentNonce []byte, serverHost string) Challenge
SignChallenge is the server's challenge for nonce, signed by its instance key over the agent's nonce.
type Claim ¶
type Claim struct {
Namespace string `json:"namespace"`
Name string `json:"name"`
Phase string `json:"phase"`
StorageClass string `json:"storage_class"`
Capacity string `json:"capacity"`
}
Claim is a PersistentVolumeClaim.
type Command ¶
type Command struct {
ID string `json:"id"`
RequestID string `json:"request_id"`
Org string `json:"org"`
Env string `json:"env"`
Endpoint string `json:"endpoint"`
Deadline time.Time `json:"deadline"`
Action string `json:"action"`
Container string `json:"container,omitempty"`
// Reference is the image an image action names, in Docker's own reference grammar. A
// command names a container or a reference, never both.
Reference string `json:"reference,omitempty"`
Capability string `json:"capability,omitempty"`
// Expects is what the actor saw when they asked. Docker has no universal resource
// version, so this is operation-specific identity the agent re-checks immediately before
// acting: the same container, in the state the decision was made about.
Expects Expectation `json:"expects"`
}
Command is one instruction for one endpoint. ID is a ULID minted by the server and is the dedupe key: an agent that has already run this ID returns its stored result rather than acting twice. RequestID is the audit correlation ID, so an agent's logs join the audit trail. The actor is never sent; who asked is recorded server-side only.
type ConfigurationCancel ¶
type ConfigurationCancel = InspectionCancel
ConfigurationOpen and ConfigurationCancel carry the inspection grant shape: request, endpoint, actor, connection nonce, expiry and immutable target.
type ConfigurationOpen ¶
type ConfigurationOpen = InspectionOpen
ConfigurationOpen and ConfigurationCancel carry the inspection grant shape: request, endpoint, actor, connection nonce, expiry and immutable target.
type ConfigurationResult ¶
type ConfigurationResult struct {
Request string `json:"request"`
Status string `json:"status"`
Result *ContainerConfiguration `json:"result,omitempty"`
Workload *WorkloadConfiguration `json:"workload,omitempty"`
}
ConfigurationResult answers a ConfigurationOpen. Status is ok, unavailable or busy; only ok carries an answer, a Result for a container or a Workload for a cluster object, and never runtime error text.
func (ConfigurationResult) Validate ¶
func (r ConfigurationResult) Validate() error
Validate checks the frame's shape; a present Result or Workload is validated against the grant's target by the caller with its own Validate.
type Container ¶
type Container struct {
ID string `json:"id"`
Name string `json:"name"`
Image string `json:"image"`
ImageID string `json:"image_id"`
State string `json:"state"` // created, running, paused, restarting, exited, dead
Status string `json:"status"` // human text from the runtime, bounded
CreatedAt time.Time `json:"created_at"`
// StartedAt is zero when the container is not running or the agent could not read it in
// budget; the UI derives uptime from it and never parses Status.
StartedAt time.Time `json:"started_at,omitzero"`
Health string `json:"health,omitempty"` // HealthStates, "" when not reported
RestartPolicy string `json:"restart_policy,omitempty"`
Ports []Port `json:"ports"`
Labels map[string]string `json:"labels"`
Networks []string `json:"networks"`
// NetworkAttachments repeats Networks with addresses; nil from an agent older than it.
NetworkAttachments []NetworkAttachment `json:"network_attachments,omitempty"`
// Managed is the Compose project label when present; ownership arrives with M6.
ComposeProject string `json:"compose_project,omitempty"`
// Mounts is nil when the agent did not report them (older than mounts), empty when there
// are none; MountsTruncated says entries past MaxMounts were dropped.
Mounts []Mount `json:"mounts"`
MountsTruncated bool `json:"mounts_truncated,omitempty"`
}
func (*Container) UnmarshalJSON ¶
UnmarshalJSON caps mounts and network attachments while decoding, like the snapshot's own lists.
type ContainerConfiguration ¶
type ContainerConfiguration struct {
Target InspectionTarget `json:"target"`
ObservedAt time.Time `json:"observed_at"`
Name string `json:"name"`
Image ImagePull `json:"image"`
ImageID string `json:"image_id"`
Command []string `json:"command"`
Entrypoint []string `json:"entrypoint"`
User string `json:"user"`
WorkingDir string `json:"working_dir"`
Hostname string `json:"hostname"`
Env []EnvEntry `json:"env"`
// Labels are cleaned (CleanText) by the agent before sending; Validate refuses any that are not.
Labels map[string]string `json:"labels"`
Restart string `json:"restart"`
RestartRetries int `json:"restart_retries"`
Ports []Port `json:"ports"` // Host 0 is exposed but unpublished
Mounts []Mount `json:"mounts"`
NetworkMode string `json:"network_mode"`
Networks []NetworkAttachmentSpec `json:"networks"`
Resources Resources `json:"resources"`
Healthcheck *Healthcheck `json:"healthcheck,omitempty"`
Privileged bool `json:"privileged"`
ReadOnlyRootfs bool `json:"read_only_rootfs"`
Init bool `json:"init"`
TTY bool `json:"tty"`
StdinOpen bool `json:"stdin_open"`
CapAdd []string `json:"cap_add"`
CapDrop []string `json:"cap_drop"`
SecurityOpt []string `json:"security_opt"`
ExtraHosts []string `json:"extra_hosts"`
DNS []string `json:"dns"`
Devices []Device `json:"devices"`
Log LogConfig `json:"log"`
StopSignal string `json:"stop_signal"`
StopTimeout *int `json:"stop_timeout,omitempty"`
Unsupported []string `json:"unsupported"`
}
ContainerConfiguration is the editable configuration of one container, read for the edit form. Unlike ContainerInspection it carries values (env, labels, argv). Unsupported names configuration the agent cannot express in a service spec.
func (*ContainerConfiguration) Validate ¶
func (c *ContainerConfiguration) Validate(target InspectionTarget, now time.Time) error
Validate bounds an untrusted agent's configuration before it reaches an HTTP response.
type ContainerInspection ¶
type ContainerInspection struct {
Target InspectionTarget `json:"target"`
ObservedAt time.Time `json:"observed_at"`
State string `json:"state"`
// Health is Docker's State.Health.Status, "none" without a healthcheck; RestartCount is the
// runtime's restart count. Both are set exactly when the agent advertises
// CapabilityContainerInspectHealth. The healthcheck's command and log never enter this type.
Health string `json:"health"`
RestartCount int `json:"restart_count"`
ImagePlatform ImagePlatform `json:"image_platform"`
RestartPolicy string `json:"restart_policy"`
RestartRetries int `json:"restart_retries"`
Ports []Port `json:"ports"`
Mounts MountCounts `json:"mounts"`
NetworkMode string `json:"network_mode"`
NetworkCount int `json:"network_count"`
Privileged bool `json:"privileged"`
ReadOnlyRootFS bool `json:"read_only_rootfs"`
AutoRemove bool `json:"auto_remove"`
Unsupported []string `json:"unsupported"`
ConfigurationVerified bool `json:"configuration_verified"`
// Workload is a cluster agent's answer, set exactly for a Kubernetes target; every Docker
// field is then empty.
Workload *WorkloadStatus `json:"workload,omitempty"`
}
ContainerInspection is an allowlisted observation, not a recreation spec. Counts omit mount paths/network names. Environment, labels, argv, healthcheck commands, raw configuration and hashes of those values never enter this type. Unsupported names, as codes from UnsupportedCodes, configuration a recreate from the definition would drop; ConfigurationVerified is true exactly when it is empty.
func (ContainerInspection) Validate ¶
func (r ContainerInspection) Validate(target InspectionTarget, now time.Time, health bool) error
Validate bounds an untrusted agent result before it reaches an HTTP response. The target's shape decides the runtime: a Workload target takes a WorkloadStatus answer and nothing else. For a container, health says the answering agent advertised CapabilityContainerInspectHealth: health and restart_count are then required and bounded, and otherwise absent.
type DeploymentIdentity ¶
type DeploymentIdentity struct {
Service string `json:"service"`
ContainerID string `json:"container_id"`
ImageID string `json:"image_id"`
CreatedUnix int64 `json:"created_unix"`
ImageDigest string `json:"image_digest,omitempty"`
Kind string `json:"kind,omitempty"`
Namespace string `json:"namespace,omitempty"`
Name string `json:"name,omitempty"`
UID string `json:"uid,omitempty"`
Generation int64 `json:"generation,omitempty"`
}
DeploymentIdentity is what a service now runs as: a Docker container, or on a cluster (Kind set) the Deployment's namespace, name, UID and generation. ImageDigest is the pulled repository digest, always set for a Deployment.
type DeploymentRequest ¶
type DeploymentRequest struct {
Deployment string `json:"deployment"`
// RequestID is the plan's audit correlation ID; the agent logs and echoes it.
RequestID string `json:"request_id"`
Endpoint string `json:"endpoint"`
Project string `json:"project"`
Revision int `json:"revision"`
// IssuedAt is the server's clock when it built the frame; Deadline is measured from it too.
IssuedAt time.Time `json:"issued_at"`
Deadline time.Time `json:"deadline"`
Services []DeploymentService `json:"services"`
// Registries holds a credential per registry host some service pulls from; never logged.
Registries map[string]RegistryAuth `json:"registries,omitempty"`
// Volumes are the named volumes the agent ensures before any replacement, each one some
// service mounts.
Volumes []string `json:"volumes,omitempty"`
// Kubernetes is set exactly for a cluster endpoint: the namespace and labels of its objects.
Kubernetes *KubernetesTarget `json:"kubernetes,omitempty"`
// Explicit is set when the operator saw and kept every setting: each service then carries
// its Explicit configuration and the adapter inherits nothing from the replaced container.
Explicit bool `json:"explicit,omitempty"`
}
func (DeploymentRequest) Validate ¶
func (r DeploymentRequest) Validate(now time.Time) error
Validate refuses anything the adapter would have to guess about. Every bound here is a wire bound as well: PR B rejects a frame that fails it before touching the runtime.
func (DeploymentRequest) ValidateFor ¶
func (r DeploymentRequest) ValidateFor(runtime string, now time.Time) error
ValidateFor is Validate holding the frame to the agent's runtime: a Kubernetes target exactly when the runtime is kubernetes.
type DeploymentResult ¶
type DeploymentResult struct {
Deployment string `json:"deployment"`
// RequestID echoes the frame's request_id; empty only from a binary built before it.
RequestID string `json:"request_id"`
Outcome string `json:"outcome"`
// Code is a result code, set exactly when Outcome is not succeeded.
Code string `json:"code"`
Steps []DeploymentStep `json:"steps"`
Services []DeploymentIdentity `json:"services"`
}
func (DeploymentResult) Validate ¶
func (r DeploymentResult) Validate() error
type DeploymentService ¶
type DeploymentService struct {
Name string `json:"name"`
ContainerName string `json:"container_name"`
ImageID string `json:"image_id"`
Replaces InspectionTarget `json:"replaces"`
Restart string `json:"restart"`
Ports []Port `json:"ports"`
Env map[string]string `json:"env"`
// Pull, when set, has the agent pull the image first; ImageID is then empty.
Pull *ImagePull `json:"pull,omitempty"`
// Mounts are MountVolume or MountBind only; a bind must already be on the replaced container.
// Always sent: a nil list is invalid.
Mounts []Mount `json:"mounts"`
// SecretKeys are the Env keys backed by a secret reference, sorted; Kubernetes only. The
// agent puts them in the service's Secret and the rest in its ConfigMap.
SecretKeys []string `json:"secret_keys,omitempty"`
// Volumes mount the request's claims; Kubernetes only.
Volumes []KubernetesMount `json:"volumes,omitempty"`
// ClusterIP requests a static internal Service address; Kubernetes only.
ClusterIP string `json:"cluster_ip,omitempty"`
// Explicit is the full configuration of an explicit request; nil otherwise.
Explicit *ExplicitService `json:"explicit,omitempty"`
}
type DeploymentStep ¶
type DeploymentStep struct {
Service string `json:"service"`
Step string `json:"step"`
Outcome string `json:"outcome"`
// Code is a step code, set exactly when Outcome is denied, failed, timed_out or unknown.
Code string `json:"code"`
// Detail is Code's parameter: empty, unsupported codes, a container ID or a status.
Detail string `json:"detail"`
}
type Engine ¶
type Engine struct {
Runtime string `json:"runtime"`
Version string `json:"version"`
APIVersion string `json:"api_version"`
OS string `json:"os"`
Arch string `json:"arch"`
Kernel string `json:"kernel"`
CPUs int `json:"cpus"`
MemoryBytes int64 `json:"memory_bytes"`
Hostname string `json:"hostname"`
}
type Envelope ¶
type Envelope struct {
V int `json:"v"`
Type string `json:"type"`
ID string `json:"id,omitempty"`
RequestID string `json:"request_id,omitempty"`
Org string `json:"org,omitempty"`
Env string `json:"env,omitempty"`
Endpoint string `json:"endpoint,omitempty"`
Deadline *time.Time `json:"deadline,omitempty"`
Payload json.RawMessage `json:"payload,omitempty"`
}
Envelope is one frame (docs/agent-protocol.md section 4). Payload is decoded by Type.
type ExecData ¶
Data uses JSON base64 encoding to preserve arbitrary PTY bytes, including UTF-8 split across reads. The decoded chunk limit applies in both directions.
type ExecOpen ¶
type ExecResize ¶
type ExecResize struct {
Stream string `json:"stream"`
Size TerminalSize `json:"size"`
}
type ExecSpec ¶
type ExecSpec struct {
Container string `json:"container"`
ImageID string `json:"image_id"`
User string `json:"user"`
Argv []string `json:"argv"`
Pod *PodTarget `json:"pod,omitempty"`
}
ExecSpec carries the exact target approved by the caller: a Docker container and image with an explicit user, or a pod container pinned by the pod's UID. Argv is passed directly to the runtime: no adapter parses a command line or inserts a shell.
func (ExecSpec) ValidateFor ¶
ValidateFor is Validate holding the target to the runtime: a pod exactly on a cluster.
type ExecStatus ¶
ExitCode is absent until Docker confirms that the process is no longer running.
type ExecStream ¶
type ExecStream struct {
Stream string `json:"stream"`
}
type Expectation ¶
type Expectation struct {
ImageDigest string `json:"image_digest,omitempty"`
State string `json:"state,omitempty"`
// Replicas is a scale's target count, 0..MaxWorkloadReplicas.
Replicas *int32 `json:"replicas,omitempty"`
}
Expectation is the precondition a command is contingent on. An empty field is not checked, so a caller says only what its decision actually depended on.
type ExplicitService ¶
type ExplicitService struct {
Command []string `json:"command"`
Entrypoint []string `json:"entrypoint"`
User string `json:"user"`
WorkingDir string `json:"working_dir"`
Hostname string `json:"hostname"`
Labels map[string]string `json:"labels"` // sent as-is; no Compose labels added
NetworkMode string `json:"network_mode"`
Networks []NetworkAttachmentSpec `json:"networks"`
Resources Resources `json:"resources"`
Healthcheck *Healthcheck `json:"healthcheck,omitempty"`
Privileged bool `json:"privileged"`
ReadOnlyRootfs bool `json:"read_only_rootfs"`
Init bool `json:"init"`
TTY bool `json:"tty"`
StdinOpen bool `json:"stdin_open"`
CapAdd []string `json:"cap_add"`
CapDrop []string `json:"cap_drop"`
SecurityOpt []string `json:"security_opt"`
ExtraHosts []string `json:"extra_hosts"`
DNS []string `json:"dns"`
Devices []Device `json:"devices"`
Log LogConfig `json:"log"`
StopSignal string `json:"stop_signal"`
StopTimeout *int `json:"stop_timeout,omitempty"`
RestartRetries int `json:"restart_retries"`
AcknowledgedBinds []string `json:"acknowledged_binds"` // host paths the operator confirmed
}
ExplicitService is every setting of one container that a direct edit or run sets. Replaces may be zero (a run).
type FieldError ¶
type FieldError struct{ Field, Message string }
FieldError is a refused configuration; Field names what was refused.
func (*FieldError) Error ¶
func (e *FieldError) Error() string
type Healthcheck ¶
type Hello ¶
type Hello struct {
State string `json:"state,omitempty"`
HeartbeatSeconds int `json:"heartbeat_seconds,omitempty"`
Capabilities []string `json:"capabilities,omitempty"`
AgentVersion string `json:"agent_version,omitempty"`
}
Hello is exchanged after authentication. The server's copy states the endpoint state and the heartbeat it expects; the agent's copy states what it can do.
type ImagePlatform ¶
type ImagePull ¶
type ImagePull struct {
Reference string `json:"reference"`
Digest string `json:"digest"`
Tag string `json:"tag,omitempty"`
}
ImagePull names an image by host, repository and the digest it must resolve to. Tag, when set, is the service's tag reference (same host and repository) the pulled image is tagged with, so the host's tag follows the update; empty for a digest-pinned spec reference.
type InspectionCancel ¶
type InspectionCancel struct {
Request string `json:"request"`
}
type InspectionOpen ¶
type InspectionOpen struct {
Request string `json:"request"`
Endpoint string `json:"endpoint"`
Actor string `json:"actor"`
Connection []byte `json:"connection"`
Expires time.Time `json:"expires"`
Target InspectionTarget `json:"target"`
}
func (InspectionOpen) ValidateFor ¶
func (r InspectionOpen) ValidateFor(now time.Time, runtime string) error
ValidateFor checks a grant for an agent of the runtime, with the inspection lifetime.
func (InspectionOpen) ValidateWithin ¶
ValidateWithin is ValidateFor for a frame with its own grant lifetime.
type InspectionResult ¶
type InspectionResult struct {
Request string `json:"request"`
Status string `json:"status"` // ok, unavailable or busy; never runtime error text.
Result *ContainerInspection `json:"result,omitempty"`
}
type InspectionTarget ¶
type InspectionTarget struct {
ContainerID string `json:"container_id"`
ImageID string `json:"image_id"`
CreatedUnix int64 `json:"created_unix"`
Workload WorkloadRef `json:"workload,omitzero"`
}
InspectionTarget pins the identity already authorized by the caller. Docker inventory exposes creation time in whole seconds. See application-schema.md, Runtime inspection foundation. This is not a wire grant or deployment approval. A Kubernetes target names a Deployment (Workload) and no container.
func (InspectionTarget) Validate ¶
func (t InspectionTarget) Validate() error
Validate holds a target to the Docker shape.
func (InspectionTarget) ValidateFor ¶
func (t InspectionTarget) ValidateFor(runtime string) error
ValidateFor holds a target to the one shape the runtime reads: a container for Docker, a Deployment for Kubernetes.
type KubernetesClaim ¶
type KubernetesClaim struct {
Name string `json:"name"`
StorageClass string `json:"storage_class"`
Size string `json:"size"`
AccessMode string `json:"access_mode"`
}
KubernetesClaim is one PersistentVolumeClaim of the instance: its name, the StorageClass ("" is the cluster default), the requested size and the access mode.
type KubernetesInventory ¶
type KubernetesInventory struct {
Nodes []Node `json:"nodes"`
Namespaces []string `json:"namespaces"`
Workloads []Workload `json:"workloads"`
Pods []Pod `json:"pods"`
Services []Service `json:"services"`
Claims []Claim `json:"claims"`
// StorageClasses are what a migration's volume choices pick from.
StorageClasses []StorageClass `json:"storage_classes"`
}
KubernetesInventory is what a cluster agent reports in place of the Docker lists.
type KubernetesMount ¶
type KubernetesMount struct {
Claim string `json:"claim"`
MountPath string `json:"mount_path"`
ReadOnly bool `json:"read_only,omitempty"`
}
KubernetesMount mounts a claim the request names at MountPath.
type KubernetesTarget ¶
type KubernetesTarget struct {
Namespace string `json:"namespace"`
ApplicationID string `json:"application_id"`
InstanceID string `json:"instance_id"`
SpecDigest string `json:"spec_digest"`
// Claims are the PersistentVolumeClaims an apply ensures; a removal carries none.
Claims []KubernetesClaim `json:"claims,omitempty"`
}
KubernetesTarget is where a cluster agent applies or removes an instance's objects, and what it labels and annotates them with. A request carries it exactly when the endpoint's runtime is kubernetes (ValidateFor).
func (KubernetesTarget) Validate ¶
func (k KubernetesTarget) Validate() error
type LogCancel ¶
type LogCancel struct {
Stream string `json:"stream"`
}
LogCancel stops a stream the reader has abandoned.
type LogChunk ¶
type LogChunk struct {
Stream string `json:"stream"`
Data string `json:"data"`
Dropped int64 `json:"dropped,omitempty"`
}
LogChunk is log text as the container wrote it. Dropped is what an older agent lost before it when its queue was full; the control plane still reports it as a gap. The current agent waits instead of dropping and never sets it.
type LogClose ¶
type LogClose struct {
Stream string `json:"stream"`
Reason string `json:"reason"`
// Failed says the stream ended because something went wrong rather than because the log
// ended or the reader left, so the reader can tell an empty log from a broken one.
Failed bool `json:"failed,omitempty"`
}
LogClose ends a stream. Reason is short and operator-facing.
type LogRequest ¶
type LogRequest struct {
Stream string `json:"stream"`
Container string `json:"container"`
Pod *PodTarget `json:"pod,omitempty"`
Tail int `json:"tail"`
Since time.Time `json:"since,omitempty"`
Timestamps bool `json:"timestamps"`
Follow bool `json:"follow"`
}
LogRequest opens one stream. Container is the ID the control plane resolved, never a name: a name is a label the runtime reassigns, and a stream must not follow it to another container mid-read. A Kubernetes endpoint is asked for a Pod instead (ValidateFor).
func (LogRequest) ValidateFor ¶
func (r LogRequest) ValidateFor(runtime string) error
ValidateFor holds a log request to the one target the runtime reads: a container ID for Docker, a pod for Kubernetes, never both.
type Metrics ¶
Metrics is a bounded observation of running containers taken at one instant.
func ShrinkMetrics ¶
ShrinkMetrics keeps the largest prefix that fits the wire limit. The server applies the same limit, and a prefix search avoids repeatedly marshaling one sample at a time.
type Mount ¶
type Mount struct {
Kind string `json:"kind"`
Source string `json:"source"`
Target string `json:"target"`
ReadOnly bool `json:"read_only,omitempty"`
}
Mount is a volume (Source is its name) or a bind (Source is the host path) at Target.
type MountCounts ¶
type NetworkAttachment ¶
type NetworkAttachment struct {
Name string `json:"name"`
IP string `json:"ip,omitempty"` // IPv4, "" when none
IP6 string `json:"ip6,omitempty"` // global IPv6, "" when none
}
NetworkAttachment is one network a container is joined to, with its addresses on it.
type NetworkAttachmentSpec ¶
type NetworkAttachmentSpec struct {
Name string `json:"name"`
Aliases []string `json:"aliases,omitempty"`
IP string `json:"ip,omitempty"`
}
NetworkAttachmentSpec is a network to join; IP is the static address, "" when dynamic.
type Pod ¶
type Pod struct {
Namespace string `json:"namespace"`
Name string `json:"name"`
UID string `json:"uid,omitempty"`
Phase string `json:"phase"`
Node string `json:"node"`
OwnerKind string `json:"owner_kind"`
OwnerName string `json:"owner_name"`
StartedAt time.Time `json:"started_at"`
Containers []PodContainer `json:"containers"`
// contains filtered or unexported fields
}
Pod carries its Kubernetes phase and its controller: a Deployment's pod names the Deployment, not the ReplicaSet between them.
func (*Pod) UnmarshalJSON ¶
UnmarshalJSON caps a pod's containers while decoding: of the nested lists it is the one a small document can expand into a large value.
type PodContainer ¶
type PodContainer struct {
Name string `json:"name"`
Image string `json:"image"`
ImageID string `json:"image_id"`
State string `json:"state"`
Reason string `json:"reason"`
Ready bool `json:"ready"`
RestartCount int32 `json:"restart_count"`
}
PodContainer State is running, waiting or terminated; Reason is the runtime's word for why.
type PodStatus ¶
type PodStatus struct {
Name string `json:"name"`
UID string `json:"uid"`
Phase string `json:"phase"`
Containers []PodContainer `json:"containers"`
}
PodStatus is one pod of the Deployment. Its containers carry no image: the judge reads state, reason, readiness and restarts only, and the answer must fit MaxInspectionFrameBytes.
type PodTarget ¶
type PodTarget struct {
Namespace string `json:"namespace"`
Name string `json:"name"`
Container string `json:"container,omitempty"`
UID string `json:"uid,omitempty"`
}
PodTarget names one pod and, optionally, one of its containers and the pod's UID. An empty Container asks the agent to take the pod's only container; it refuses when there are several. An exec names both (ExecSpec.Validate).
type RegistryAuth ¶
type RemovalRequest ¶
type RemovalRequest struct {
Deployment string `json:"deployment"`
RequestID string `json:"request_id"`
Endpoint string `json:"endpoint"`
Project string `json:"project"`
IssuedAt time.Time `json:"issued_at"`
Deadline time.Time `json:"deadline"`
Containers []RemovalTarget `json:"containers"`
// Kubernetes is set exactly for a cluster endpoint; Containers is then empty and Services
// names every service whose objects the agent deletes.
Kubernetes *KubernetesTarget `json:"kubernetes,omitempty"`
Services []string `json:"services,omitempty"`
}
RemovalRequest stops and deletes every adopted container of an application being removed, each identified by the same pinned target an inspection or replacement would use rather than a name a daemon restart could reassign.
func (RemovalRequest) ValidateFor ¶
func (r RemovalRequest) ValidateFor(runtime string, now time.Time) error
ValidateFor is RemovalRequest.Validate holding the frame to the agent's runtime.
type RemovalTarget ¶
type RemovalTarget struct {
Service string `json:"service"`
Target InspectionTarget `json:"target"`
}
type Result ¶
type Result struct {
ID string `json:"id"`
Outcome string `json:"outcome"`
Detail string `json:"detail,omitempty"`
}
Result is what became of a command. Detail is bounded: an agent cannot make the control plane store an arbitrary amount of text by failing loudly.
type Rotated ¶
Rotated names the key that now authenticates (server → agent) or was recorded (ack of Rotate).
type Sample ¶
type Sample struct {
ContainerID string `json:"container_id"`
CPUPercent float64 `json:"cpu_percent"`
MemoryBytes int64 `json:"memory_bytes"`
MemoryLimit int64 `json:"memory_limit"`
RxBytes int64 `json:"rx_bytes"`
TxBytes int64 `json:"tx_bytes"`
Pids int64 `json:"pids"`
RestartCount int64 `json:"restart_count"`
}
Sample is one container's usage at ObservedAt. CPUPercent is the share of one core over the interval since the previous sample (100 = one core busy); the first sample after a restart has no interval and reports -1, which the UI shows as "no data" rather than zero. RestartCount is the runtime's own counter for the container, cumulative since it was created, so a rising series across samples is a container restarting. It is -1 when the runtime did not answer, which is not the same as a container that has never restarted.
type Snapshot ¶
type Snapshot struct {
Generation uint64 `json:"generation"`
ObservedAt time.Time `json:"observed_at"`
Engine Engine `json:"engine"`
Containers []Container `json:"containers"`
Images []Image `json:"images"`
Networks []Network `json:"networks"`
Volumes []Volume `json:"volumes"`
// Kubernetes is a cluster agent's inventory; nil from a Docker agent (CheckRuntimeShape).
Kubernetes *KubernetesInventory `json:"kubernetes,omitempty"`
// Truncated names the lists that hit their cap; the UI shows the gap.
Truncated []string `json:"truncated,omitempty"`
}
type StorageClass ¶
StorageClass is a cluster StorageClass as the inventory reports it; Default is the is-default-class annotation.
type TerminalSize ¶
func (TerminalSize) Validate ¶
func (s TerminalSize) Validate() error
type Volume ¶
type Volume struct {
Name string `json:"name"`
Driver string `json:"driver"`
Mountpoint string `json:"mountpoint"`
CreatedAt time.Time `json:"created_at"`
// Plain is a local volume without driver options, so no host path backs it; false from an
// agent too old to say.
Plain bool `json:"plain,omitempty"`
}
type Workload ¶
type Workload struct {
Kind string `json:"kind"`
Namespace string `json:"namespace"`
Name string `json:"name"`
Desired int32 `json:"desired"`
Ready int32 `json:"ready"`
Updated int32 `json:"updated"`
Images []string `json:"images"`
Paused bool `json:"paused"`
// Application and Instance are the KyYard labels of a workload KyYard deployed, else empty.
Application string `json:"application,omitempty"`
Instance string `json:"instance,omitempty"`
}
Workload is a Deployment, StatefulSet or DaemonSet.
type WorkloadApply ¶
type WorkloadApply struct {
Request string `json:"request"`
Endpoint string `json:"endpoint"`
IssuedAt time.Time `json:"issued_at"`
Deadline time.Time `json:"deadline"`
Target WorkloadRef `json:"target"`
ResourceVersion string `json:"resource_version"`
Spec WorkloadConfiguration `json:"spec"`
Create bool `json:"create,omitempty"`
}
WorkloadApply sets a workload's pod template (image, command, args, env, resources) and replicas and paused from Spec, on the object at ResourceVersion only. With Create it instead creates a Deployment that must not exist, from containers, replicas and strategy only, with no ResourceVersion. It is answered by a DeploymentResult whose Deployment is Request and whose one service is WorkloadApplyService.
type WorkloadCondition ¶
type WorkloadConfiguration ¶
type WorkloadConfiguration struct {
RunManifest json.RawMessage `json:"run_manifest,omitempty"`
Target WorkloadRef `json:"target"`
ObservedAt time.Time `json:"observed_at"`
ResourceVersion string `json:"resource_version"`
Replicas *int32 `json:"replicas,omitempty"`
Paused bool `json:"paused"`
Strategy string `json:"strategy"`
Containers []WorkloadContainer `json:"containers"`
InitContainers []WorkloadContainer `json:"init_containers"`
EnvFrom []string `json:"env_from"`
Managed bool `json:"managed"`
Unsupported []string `json:"unsupported"`
}
WorkloadConfiguration is the editable pod template of a Deployment, StatefulSet or DaemonSet. Replicas is nil exactly for a DaemonSet; Paused is a Deployment's only. EnvFrom entries are "secret/<name>" or "configmap/<name>". Managed is a workload KyYard deployed, edited through its application. Unsupported names, from WorkloadUnsupportedCodes, what an apply would drop.
func (*WorkloadConfiguration) Validate ¶
func (c *WorkloadConfiguration) Validate(target WorkloadRef, now time.Time) error
Validate bounds an untrusted agent's read before it reaches an HTTP response.
type WorkloadContainer ¶
type WorkloadContainer struct {
Name string `json:"name"`
Image string `json:"image"`
ImageID string `json:"image_id"`
Command []string `json:"command"`
Args []string `json:"args"`
Env []WorkloadEnv `json:"env"`
Resources WorkloadResources `json:"resources"`
}
WorkloadContainer is one container of a pod template. ImageID is what a running pod reports, "" when none does.
type WorkloadEnv ¶
type WorkloadEnv struct {
Name string `json:"name"`
Value string `json:"value"`
SecretRef string `json:"secret_ref,omitempty"`
ConfigMapRef string `json:"config_map_ref,omitempty"`
}
WorkloadEnv is a literal Value or a reference ("<name>/<key>") to a Secret or ConfigMap key, never both: a referenced value is never read.
type WorkloadRef ¶
type WorkloadRef struct {
Namespace string `json:"namespace"`
Kind string `json:"kind,omitempty"`
Name string `json:"name"`
UID string `json:"uid,omitempty"`
}
WorkloadRef has two shapes. An inspection names a Deployment by UID and no Kind (valid); a configuration read, an apply or a command names an object by Kind and no UID (validObject, ParseWorkloadRef).
func ParseWorkloadRef ¶
func ParseWorkloadRef(reference string) (WorkloadRef, error)
ParseWorkloadRef reads "<namespace>/<kind>/<name>", the form a command's Reference carries.
func (WorkloadRef) String ¶
func (r WorkloadRef) String() string
type WorkloadResources ¶
type WorkloadResources struct {
CPURequest string `json:"cpu_request"`
CPULimit string `json:"cpu_limit"`
MemoryRequest string `json:"memory_request"`
MemoryLimit string `json:"memory_limit"`
}
WorkloadResources are Kubernetes quantity strings, "" when unset.
type WorkloadStatus ¶
type WorkloadStatus struct {
UID string `json:"uid"`
Generation int64 `json:"generation"`
ObservedGeneration int64 `json:"observed_generation"`
Desired int32 `json:"desired"`
Updated int32 `json:"updated"`
Ready int32 `json:"ready"`
Available int32 `json:"available"`
Conditions []WorkloadCondition `json:"conditions"`
Pods []PodStatus `json:"pods"`
Missing bool `json:"missing"`
}
WorkloadStatus is a Deployment's rollout state and its pods. Missing: the Deployment is gone, and nothing else is set. A UID other than the target's is a Deployment recreated under the name.