kubernetes

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 43 Imported by: 0

Documentation

Overview

Package kubernetes is the Kubernetes adapter: it reads the cluster the agent runs in through the typed clientset, with the agent's ServiceAccount, and returns product types only. No client-go type leaves this package.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrExecUnavailable = errors.New("exec unavailable: the client has no cluster configuration")
	ErrExecClosed      = errors.New("exec stream closed; process exit is not established")
	ErrExecIdle        = errors.New("exec input idle timeout")
	ErrExecLifetime    = errors.New("exec absolute timeout")
	ErrExecSetup       = errors.New("exec stream setup timed out")
)
View Source
var ErrIdentityConflict = errors.New("the identity Secret changed under this agent; another agent may share this identity")

ErrIdentityConflict is a Secret that changed under this agent twice running, or that holds another endpoint's identity: the sign of two agents sharing one identity, which this store exists to prevent. The caller stops.

Functions

func OwnNamespace

func OwnNamespace() (string, error)

OwnNamespace is the namespace the agent's pod runs in.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

func InCluster

func InCluster() (*Client, error)

InCluster reads the cluster the agent's pod runs in, as its ServiceAccount.

func New

func New(cfg *rest.Config) (*Client, error)

New reads the cluster cfg names.

func NewFromClientset

func NewFromClientset(cs k8s.Interface) *Client

NewFromClientset is for tests: cs is usually k8s.io/client-go/kubernetes/fake.

func (*Client) ApplyWorkload

func (c *Client) ApplyWorkload(parent context.Context, req protocol.WorkloadApply, started func()) protocol.DeploymentResult

ApplyWorkload writes req.Spec's image, command, args, env and cpu and memory of each named container, and replicas and paused, onto the object read fresh, then waits for a Deployment's rollout within req.Deadline. The precondition, after an access review for patch (forbidden) and the namespace's Pod Security level (pod_security, as a deploy), refuses a managed object (application_managed), one at another resourceVersion than the read or without a named container (conflict), one whose read is not whole (configuration_unreported: an apply would drop what it did not show), a Secret reference the object does not already carry (secret_ref_refused) and replicas that delete claims, as a scale (pvc_retention). The write is a strategic merge patch of only the changed paths (see bind), so fields the form does not carry, those it carries unchanged and those this client's types do not know keep their exact bytes. It carries the read's resourceVersion, so a concurrent write is the API server's 409, reported conflict. A StatefulSet's or DaemonSet's rollout, and a paused Deployment's, is not waited for: rollout is skipped. started is called once, before the write. A create frame runs createWorkload instead.

func (*Client) Deploy

func (c *Client) Deploy(parent context.Context, req protocol.DeploymentRequest, started func()) protocol.DeploymentResult

Deploy applies each service's objects and waits for its rollout. First every service's precondition: the agent's own grant (a SelfSubjectAccessReview for create deployments in the namespace, forbidden when denied), the namespace's Pod Security level (pod_security unless it enforces baseline or restricted), then each planned object read by name, refused name_taken when one exists without this instance's label, and each claim, refused claim_immutable when this instance's differs from the plan. Then per service create (Service, missing claims, ConfigMap, Secret, Deployment, each updated when it exists and is owned, created otherwise; one conflict is re-read and retried; a refused write is forbidden without the verb, admission_denied with it) and start (the rollout, polled until available, a failure the cluster reports, or the deadline: rollout_timeout; then prune, or restore after a rollout_timeout). The first step that is not a success ends the run and every later step is skipped. started is called once, before the first write.

func (*Client) Facts

func (c *Client) Facts(ctx context.Context) map[string]string

Facts is the enrollment report for a cluster: what an approver compares with the cluster they meant to enroll. A fact the agent cannot read is "unknown", never left out.

func (*Client) Inspect

Inspect reads the Deployment a validation watches and the pods its selector (immutable, unlike its labels) selects, within callBudget: a Get and one List, both verbs the manifest already grants. A Deployment that is gone answers Missing; one recreated under the name answers with its own UID. More than MaxWorkloadPods pods is an error (unavailable), never a cut list: one leaving out every baseline pod would read as a recreate, and a restarted pod left out would hide it.

func (*Client) Logs

func (c *Client) Logs(ctx context.Context, req protocol.LogRequest, sink func([]byte) error) error

Logs streams one pod container's log to sink, at most protocol.MaxLogLines lines or protocol.MaxLogBytes bytes, whichever comes first. The container comes from the pod spec: an unnamed one is the pod's only container, and a pod with several is refused rather than guessed at.

func (*Client) OpenExec

func (c *Client) OpenExec(ctx context.Context, spec protocol.ExecSpec) (client.ExecSession, error)

OpenExec attaches a TTY to spec.Pod's container, running spec.Argv, once the pod read back has the same UID, is Running and has that container, its namespace enforces Pod Security baseline or restricted and the pod itself meets baseline (protocol.ErrExecPodSecurity), and an access review allows create pods/exec on it (protocol.ErrExecForbidden). See protocol §7.

func (*Client) Operate

func (c *Client) Operate(ctx context.Context, cmd protocol.Command) (outcome, detail string)

Operate runs one workload or pod action named by Reference ("<namespace>/<kind>/<name>"), after a SelfSubjectAccessReview for its verb: an agent whose manifest lacks the grant answers denied forbidden. Restart stamps the pod template's restartedAt annotation, scale sets spec.replicas to Expects.Replicas (0..MaxWorkloadReplicas; a DaemonSet has none) at the read's resourceVersion and refuses to scale a StatefulSet below its replicas when that deletes the excess replicas' claims (whenScaled: Delete, pvc_retention), delete removes the object read just before, by its UID (a workload also by its resourceVersion), with Background propagation, unless it is labelled managed-by kyyard (application_managed) or is a StatefulSet whose claims go with it (whenDeleted: Delete, pvc_retention). The granted namespaces are the server's check; here the access review is the boundary.

func (*Client) ReadWorkload

ReadWorkload reads a Deployment's, StatefulSet's or DaemonSet's editable pod template within callBudget. Secret and ConfigMap env are named by reference ("<name>/<key>") and never read. Unsupported names what an apply would drop: env from another source (env_field_ref), env or argv past the protocol's bounds (env_truncated, argv_truncated). Containers past MaxWorkloadContainers, envFrom past MaxWorkloadEnvFrom and resources other than cpu and memory are left out of the read but never touched by an apply, so they are not unsupported.

func (*Client) Remove

func (c *Client) Remove(parent context.Context, req protocol.RemovalRequest, started func()) protocol.DeploymentResult

Remove deletes the instance's objects: the Deployments, Services and ConfigMaps in the namespace carrying its instance label, and each named service's Secret when it carries the label too. An object without it is never touched. The first service's precondition does the reads; each service then has a remove step, skipped when nothing of it is left. Deletes are foreground, so a Deployment's pods go with it. The instance's claims are kept: each is a skipped volume step, detail retained, under the service that mounts it.

func (*Client) Snapshot

func (c *Client) Snapshot(ctx context.Context) (*protocol.Snapshot, error)

Snapshot reads the cluster's inventory, every list at once so a slow API server costs the slowest list rather than the sum. A list the ServiceAccount cannot read is reported empty and named in Truncated, so one forbidden verb does not blank the whole endpoint; the error return is only ever nil.

type SecretIdentityStore

type SecretIdentityStore struct {
	// contains filtered or unexported fields
}

SecretIdentityStore keeps the identity in a Secret in the agent's own namespace, so a restarted pod comes back as the same endpoint instead of enrolling again. It writes against the Secret it last read or wrote, so a second agent's write since then is a conflict.

func NewSecretIdentityStore

func NewSecretIdentityStore(c *Client, namespace, name string) (*SecretIdentityStore, error)

func (*SecretIdentityStore) Load

func (s *SecretIdentityStore) Load() (*client.Identity, error)

func (*SecretIdentityStore) Save

Save updates the Secret as last seen, creating it only when it was absent. On a conflict it re-reads once: a Secret holding another endpoint or a later generation is ErrIdentityConflict, anything else is retried once, and a second conflict is ErrIdentityConflict. A Secret holding another endpoint's identity is never overwritten.

Directories

Path Synopsis
Package manifest renders the file an administrator applies to enroll a Kubernetes cluster.
Package manifest renders the file an administrator applies to enroll a Kubernetes cluster.
Package render turns one deployment request into the Kubernetes objects a cluster agent applies: per service a Deployment, a Service, a ConfigMap and a Secret, labelled as KyYard's.
Package render turns one deployment request into the Kubernetes objects a cluster agent applies: per service a Deployment, a Service, a ConfigMap and a Secret, labelled as KyYard's.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL