cluster

package
v0.29.0 Latest Latest
Warning

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

Go to latest
Published: Oct 2, 2026 License: Apache-2.0 Imports: 29 Imported by: 0

Documentation

Overview

Package cluster defines the API types for a cluster configuration.

Index

Constants

View Source
const (
	// FirewallActionAllow lets matching traffic through.
	FirewallActionAllow = "allow"
	// FirewallActionDeny drops matching traffic without a reply.
	FirewallActionDeny = "deny"
	// FirewallActionReject refuses matching traffic with an ICMP error.
	FirewallActionReject = "reject"

	// FirewallDirectionIn matches traffic arriving at the node.
	FirewallDirectionIn = "in"
	// FirewallDirectionOut matches traffic leaving the node.
	FirewallDirectionOut = "out"
	// FirewallDirectionForward matches traffic routed through the node, from one
	// zone or interface to another.
	FirewallDirectionForward = "forward"
)
View Source
const (
	// RoleController marks a host as a control-plane node.
	RoleController = "controller"
	// RoleControllerWorker marks a host as both a control-plane node and a worker node.
	RoleControllerWorker = "controller+worker"
	// RoleSingle marks a host as a single-node cluster: both control plane and worker on one host.
	RoleSingle = "single"
	// RoleWorker marks a host as a worker node.
	RoleWorker = "worker"
	// RoleError is a sentinel value returned when a role or service lookup fails.
	RoleError = "error"
)
View Source
const AgeHeader = "-----BEGIN AGE ENCRYPTED FILE-----"

AgeHeader marks a value in a cluster configuration as armored age ciphertext, the alternative to Ansible Vault. Cargoship decrypts such a value at apply time with an age identity rather than a password.

The string is written out rather than taken from filippo.io/age/armor so that this package, which defines the API types every other package loads a configuration into, stays free of crypto dependencies. TestAgeHeaderMatchesArmorHeader pins the two together.

View Source
const VaultHeader = "$ANSIBLE_VAULT"

VaultHeader marks a value in a cluster configuration as Ansible Vault ciphertext produced by `ansible-vault encrypt_string`. Cargoship decrypts such a value at apply time, so anything that inspects the plaintext has to wait until then.

Variables

View Source
var ErrCommandFailed = errors.New("command failed")

ErrCommandFailed is returned when a command fails

View Source
var ErrNotConnected = errors.New("host is not connected")

ErrNotConnected is returned by host operations that need a live connection on a host that has never been set up or connected.

Functions

func IsAgeEncrypted

func IsAgeEncrypted(value string) bool

IsAgeEncrypted reports whether value is age ciphertext rather than a plain value.

func IsEncrypted

func IsEncrypted(value string) bool

IsEncrypted reports whether value is ciphertext in either of the formats cargoship decrypts.

A configuration can hold both: the two headers tell them apart, so nothing has to be told which format a document uses, and a document part-way through a migration between them applies the same as one that is not.

func IsVaultEncrypted

func IsVaultEncrypted(value string) bool

IsVaultEncrypted reports whether value is Ansible Vault ciphertext rather than a plain value.

func ParseConcurrency

func ParseConcurrency(value string, total int) (int, error)

ParseConcurrency parses a concurrency spec (a fixed count like "1", or a percentage like "25%") against total, the number of hosts in the batch being sized. A fixed count is used as-is; 0 or empty means unlimited. A percentage is scaled against total, rounded up, and clamped to a minimum of 1 so a low percentage never collapses to 0, which would otherwise be indistinguishable from "unlimited".

func ValidateRegistries

func ValidateRegistries(registries []ZarfClusterRegistries) error

ValidateRegistries validates every registry entry, and rejects a set of entries that would quietly lose part of itself on the way to an engine configuration file.

Two entries naming the same registry collide on the mirror they define for it, and two entries resolving to the same host -- which several registries proxied through one mirror legitimately do -- collide on the credentials and TLS settings written for that host. In both cases the last entry wins and the earlier one silently does nothing, so the conflict is reported here instead. Entries that resolve to the same host with identical settings are left alone: there is nothing to lose between them.

Types

type HostServices

type HostServices interface {
	ServiceIsRunning(ctx context.Context, name string) bool
	StartService(ctx context.Context, name string) error
	StopService(ctx context.Context, name string) error
	RestartService(ctx context.Context, name string) error
	EnableService(ctx context.Context, name string) error
}

HostServices is the init system surface a host exposes. A real host satisfies it through its rig connection; SetServices substitutes another implementation, which is how the distro modules and phases are exercised without a machine to run against.

type ZarfCluster

type ZarfCluster struct {
	// APIVersion identifies the API group and version of this configuration document.
	APIVersion string `json:"apiVersion,omitempty" jsonschema:"enum=zarf.dev/v1alpha1"`
	// Kind identifies the document type. The value must be ZarfCluster.
	Kind v1alpha1.ZarfDistroKind `json:"kind" jsonschema:"enum=ZarfCluster"`
	// Metadata holds identifying information for the cluster.
	Metadata ZarfClusterMetadata `json:"metadata"`
	// Spec holds the configuration and hosts for the cluster.
	Spec ZarfClusterSpec `json:"spec"`
	// RuntimeMetadata stores data gathered while the phases run.
	RuntimeMetadata ZarfRuntimeMeta `json:"-"`
}

ZarfCluster is the root object of a cluster configuration document.

type ZarfClusterAgeEncryption

type ZarfClusterAgeEncryption struct {
	// Recipients lists the age public keys cargoship encrypted to, in the order they were given. An SSH key keeps its authorized_keys comment, since that is the part that says whose key it is.
	Recipients []string `json:"recipients,omitempty"`
	// LastModified is when cargoship last rewrote the credentials in this document, in RFC 3339.
	LastModified string `json:"lastModified,omitempty" jsonschema:"format=date-time"`
}

ZarfClusterAgeEncryption records the age recipients a document's credentials were encrypted to.

It is advisory. Nothing verifies it, and nothing can: an age header carries no recipient identifier, which is the property that keeps ciphertext from revealing who can read it. Editing this list therefore changes what the file claims and not a byte of what it holds -- cargoship compares it against the recipients you name and says so when the two differ, and never encrypts to a key that came out of it.

type ZarfClusterConfig

type ZarfClusterConfig struct {
	// LoadBalancer is the hostname clients use to reach the cluster control plane.
	LoadBalancer string `json:"loadbalancer" jsonschema:"format=hostname"`
	// Registries lists the container registries the cluster uses.
	Registries []ZarfClusterRegistries `json:"registries,omitempty"`
	// Profiles maps a profile name to host and engine overrides that a host can select.
	Profiles map[string]ZarfClusterProfiles `json:"profiles,omitempty"`
	// Values overrides the values the distro package was built with. It is the same
	// nested structure the package ships, addressed by the same dotted paths, and it
	// must still satisfy the package's values schema. Keys the package does not
	// define are kept, so a cluster can carry values a later package version reads.
	Values map[string]any `json:"values,omitempty"`
}

ZarfClusterConfig holds cluster-wide configuration.

type ZarfClusterEncryption

type ZarfClusterEncryption struct {
	// Age records the age recipients this document's credentials were encrypted to. Nothing verifies this list and nothing can: an age header carries no recipient identifier, so editing it changes what the file claims and not a byte of what it holds.
	Age *ZarfClusterAgeEncryption `json:"age,omitempty"`
}

ZarfClusterEncryption records how the credentials in a document were encrypted.

There is a section per format rather than one flat list, so that a document holding both Ansible Vault and age credentials has somewhere to say so later. Only age needs a record today: a vaulted value is read with the one password the operator already has to supply by name.

type ZarfClusterFiles

type ZarfClusterFiles struct {
	// Name identifies the file in the cluster configuration.
	Name string `json:"name"`
	// Source is the local path or URL cargoship reads the file from.
	Source string `json:"src,omitempty"`
	// Destination is the path on the host where cargoship writes the file.
	Destination string `json:"dst,omitempty"`
	// DestinationDirectory is the directory on the host where cargoship writes the file.
	DestinationDirectory string `json:"dstDir,omitempty"`
	// Permission sets the file mode cargoship applies on the host.
	Permission string `json:"perm,omitempty"`
	// User identifies the file owner on the host.
	User string `json:"user,omitempty" jsonschema:"example=root"`
	// Group identifies the file group on the host.
	Group string `json:"group,omitempty" jsonschema:"example=root"`
	// Data holds inline content for the file, as an alternative to Source.
	Data string `json:"data,omitempty"`
}

ZarfClusterFiles defines a file to write to a host.

type ZarfClusterMetadata

type ZarfClusterMetadata struct {
	// Name sets the cluster name. If you allow cargoship to update the kubeconfig, cargoship uses this name there.
	Name string `json:"name" jsonschema:"pattern=^[a-z0-9][a-z0-9\\-]*$"`
	// Encryption records how the credentials in this document were encrypted. Cargoship writes it and never reads it back as key material, because an age header names no recipient: this records what was done, not a fact anything can check against the ciphertext beside it.
	Encryption *ZarfClusterEncryption `json:"encryption,omitempty"`
}

ZarfClusterMetadata holds identifying information for a cluster.

type ZarfClusterProfiles

type ZarfClusterProfiles struct {
	// Host holds the configuration overrides applied to a host that selects this profile.
	Host ZarfHostConfig `json:"host,omitempty"`
	// Engine holds the node label and taint overrides applied to a host that selects this profile.
	Engine ZarfHostEngine `json:"engine,omitempty"`
	// Concurrency limits how many hosts using this profile cargoship processes at once, e.g.
	// draining, upgrading, initializing, or uninstalling. It accepts a fixed count ("1") or a
	// percentage of the hosts sharing this profile ("25%"). Empty falls back to the phase's
	// default concurrency.
	Concurrency string `` /* 136-byte string literal not displayed */
}

ZarfClusterProfiles holds the host and engine overrides for one profile.

func (ZarfClusterProfiles) ResolveConcurrency

func (p ZarfClusterProfiles) ResolveConcurrency(total int, fallback string) (int, error)

ResolveConcurrency returns the batch size cargoship should use for total hosts sharing this profile. A fixed count is used as-is. A percentage (e.g. "25%") is scaled against total, rounded up, and clamped to a minimum of 1 so a low percentage never collapses to 0, which would otherwise be indistinguishable from "unlimited". An empty Concurrency falls back to fallback, parsed the same way against total.

type ZarfClusterRegistrieName

type ZarfClusterRegistrieName string

ZarfClusterRegistrieName is the registry name in ZarfClusterRegistries. It's a named type (rather than a bare string) solely so it can implement JSONSchemaExtend below and suggest common registries in the generated schema; the config file is not restricted to those.

func (ZarfClusterRegistrieName) JSONSchemaExtend

func (ZarfClusterRegistrieName) JSONSchemaExtend(s *jsonschema.Schema)

JSONSchemaExtend adds CommonRegistries to the schema as examples, so editors can suggest them for this string field without restricting it to just those values.

type ZarfClusterRegistries

type ZarfClusterRegistries struct {
	// Name identifies the registry. With a proxy it is the registry pulls are redirected away
	// from; without one it is the registry the credentials authenticate to.
	Name ZarfClusterRegistrieName `json:"name"`
	// Authentication holds the credentials for the registry.
	Authentication ZarfClusterRegistryAuth `json:"auth,omitempty"`
	// Proxy holds the pull redirect settings for the registry. Omit it to configure credentials
	// or TLS for the registry without redirecting pulls away from it.
	Proxy *ZarfClusterRegistryProxy `json:"proxy,omitempty"`
	// TLS configures TLS verification and certificates for the registry endpoint.
	TLS *ZarfClusterRegistryTLS `json:"tls,omitempty"`
}

ZarfClusterRegistries holds the credentials and pull proxy for one container registry. The proxy and the credentials are independent: an entry with both redirects pulls to a mirror and authenticates to that mirror, while an entry with credentials alone authenticates a direct pull from the registry itself. Upstream Kubernetes keeps the two in separate files entirely -- mirrors in containerd's hosts.toml, which holds no credentials, and credentials in a node docker config -- so an entry must be able to carry either one on its own.

func (ZarfClusterRegistries) ConfigHost

func (r ZarfClusterRegistries) ConfigHost() string

ConfigHost returns the host this registry's credentials and TLS settings belong to: the mirror when pulls are redirected to one, and the registry itself when they are not. The proxy address may carry a scheme and a path -- "https://mirror.example.com:5000/v2" -- but an engine matches its per-registry configuration on the host alone, so the host is what comes back here.

func (ZarfClusterRegistries) MirrorEndpoint

func (r ZarfClusterRegistries) MirrorEndpoint() string

MirrorEndpoint returns the proxy address as an engine mirror endpoint: the configured URL, completed to https when it was given without a scheme, since that is both what a registry serves by default and what the engine would otherwise have to guess at. It is empty when the registry has no proxy.

func (ZarfClusterRegistries) ProxyURL

func (r ZarfClusterRegistries) ProxyURL() string

ProxyURL returns the address pulls for this registry are redirected to, or an empty string when the registry has no proxy and is pulled from directly. Proxy is a pointer -- so that a proxy left out of a document is distinguishable from one written out empty, and so that omitempty applies to it at all, which encoding/json does not do for a struct value -- and this saves every caller a nil check to ask the only question most of them have.

func (ZarfClusterRegistries) Validate

func (r ZarfClusterRegistries) Validate() error

Validate returns an error when the registry entry configures nothing. An entry has to carry a proxy, credentials, or TLS settings to have any effect, and one that carries none of them is more likely a mistyped document than an intentional no-op.

type ZarfClusterRegistryAuth

type ZarfClusterRegistryAuth struct {
	// Username is the login name for the remote registry.
	Username string `` /* 132-byte string literal not displayed */
	// Password is the login secret for the remote registry.
	Password string `` /* 133-byte string literal not displayed */
	// Token authenticates to the remote registry instead of a username and password.
	Token string `` /* 133-byte string literal not displayed */
}

ZarfClusterRegistryAuth holds the credentials for a container registry. Username, Password, and Token may each be given in plaintext, or encrypted in either of the two formats cargoship reads: an Ansible Vault string (the output of `ansible-vault encrypt_string`, starting with "$ANSIBLE_VAULT"), or armored age ciphertext (starting with "-----BEGIN AGE ENCRYPTED FILE-----"). Cargoship decrypts either at apply time, using the vault password given via --vault-password-file or the age identity given via --age-identity-file.

func (ZarfClusterRegistryAuth) Validate

Validate returns an error when the credentials cannot be used as given. name identifies the registry in the error.

type ZarfClusterRegistryProxy

type ZarfClusterRegistryProxy struct {
	// URL is the registry address the engine pulls from instead of the original registry.
	URL string `json:"url"`
	// Rewrite maps a regex pattern to a replacement, transforming the image name (not the tag)
	// before it is pulled from this mirror. See https://docs.rke2.io/install/private_registry#rewrites
	Rewrite map[string]string `json:"rewrite,omitempty"`
}

ZarfClusterRegistryProxy redirects pulls for a registry to a different URL.

func (*ZarfClusterRegistryProxy) Validate

Validate returns an error when the proxy settings cannot be applied. A nil receiver is valid: a registry may be configured without redirecting pulls away from it. name identifies the registry in the error.

type ZarfClusterRegistryTLS

type ZarfClusterRegistryTLS struct {
	// CA is the PEM-encoded CA certificate used to verify the registry certificate. Cargoship
	// writes it to a file on each host and points the engine at that path, so the certificate
	// travels with the cluster configuration instead of having to be distributed separately.
	// Use CAFile instead when the certificate is already on the hosts. It may also be given as
	// an Ansible Vault-encrypted string, which cargoship decrypts at apply time.
	CA string `json:"ca,omitempty"`
	// CAFile is the path on the host to the CA bundle used to verify the registry certificate.
	CAFile string `json:"caFile,omitempty"`
	// CertFile is the path on the host to the client certificate used to authenticate to the registry.
	CertFile string `json:"certFile,omitempty"`
	// KeyFile is the path on the host to the client private key used to authenticate to the registry.
	KeyFile string `json:"keyFile,omitempty"`
	// InsecureSkipVerify disables TLS certificate verification.
	InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"`
}

ZarfClusterRegistryTLS holds the TLS connection settings for a container registry. The field names are cargoship's own, in the camelCase the rest of this file uses; distrocfg maps them onto whatever spelling each engine's registry configuration expects.

func (*ZarfClusterRegistryTLS) Validate

Validate returns an error when the TLS settings cannot be applied. A nil receiver is valid: TLS is optional. name identifies the registry in the error.

type ZarfClusterSpec

type ZarfClusterSpec struct {
	// Config holds the cluster-wide configuration.
	Config ZarfClusterConfig `json:"config"`
	// Hosts lists the hosts that make up the cluster.
	Hosts ZarfHosts `json:"hosts" jsonschema:"minItems=1"`
}

ZarfClusterSpec holds the configuration and hosts for a cluster.

type ZarfFirewallConfig

type ZarfFirewallConfig struct {
	// Rules lists the firewall rules cargoship applies to the node.
	Rules []ZarfFirewallRule `json:"rules,omitempty"`
}

ZarfFirewallConfig is the backend-neutral firewall configuration for a node. Cargoship renders these rules onto whichever firewall backend the node runs, so a single inventory can target firewalld, ufw, and nftables hosts alike.

func (*ZarfFirewallConfig) Merge

func (c *ZarfFirewallConfig) Merge(update ZarfFirewallConfig)

Merge adds every rule from update that c does not already define, matching rules by Key. A host that names a rule the same as its profile does keeps its own; every other profile rule is added. Unlike the rest of ZarfHostConfig, firewall rules union rather than replace, so a host can add one rule of its own without giving up the baseline its profile sets.

func (ZarfFirewallConfig) Validate

func (c ZarfFirewallConfig) Validate() error

Validate returns an error when any rule in the config is unusable.

type ZarfFirewallPolicyConfig

type ZarfFirewallPolicyConfig struct {
	// XMLName sets the element name cargoship uses when it marshals this policy to firewalld XML.
	XMLName xml.Name `xml:"policy" json:"-"`
	// Short is a human-readable description of the policy.
	Short string `xml:"short,omitempty" json:"-"`
	// Target is the action taken on traffic that matches the policy.
	Target string `xml:"target,attr,omitempty" json:"target" jsonschema:"enum=CONTINUE,enum=ACCEPT,enum=REJECT,enum=DROP"`
	// Ingress is the zone the policy allows traffic from.
	Ingress ZarfFirewallZone `xml:"ingress-zone"`
	// Egress is the zone the policy allows traffic to.
	Egress ZarfFirewallZone `xml:"egress-zone"`
	// Ports lists the ports this policy allows.
	Ports []ZarfFirewallPort `xml:"port,omitempty" json:"ports,omitempty"`
}

ZarfFirewallPolicyConfig configures a firewalld policy that opens ports from one zone to another.

type ZarfFirewallPort

type ZarfFirewallPort struct {
	// Protocol is the type of allowed traffic.
	Protocol string `xml:"protocol,attr" json:"protocol" jsonschema:"enum=tcp,enum=udp,enum=sctp,enum=dccp"`
	// Port is the port number, or port range, cargoship opens.
	Port string `xml:"port,attr" json:"port" jsonschema:"oneof_type=string;integer"`
}

ZarfFirewallPort defines a port allowed through the firewalld policy.

type ZarfFirewallRule

type ZarfFirewallRule struct {
	// Name identifies the rule. Cargoship uses it to name the artifacts it writes on the
	// node, so it must be unique within a host. Cargoship generates one when it is empty.
	Name string `json:"name,omitempty" jsonschema:"example=allow-metrics"`
	// Action is what cargoship does with traffic that matches the rule.
	Action string `json:"action" jsonschema:"required,enum=allow,enum=deny,enum=reject"`
	// Direction selects which traffic the rule matches. It defaults to in.
	Direction string `json:"direction,omitempty" jsonschema:"enum=in,enum=out,enum=forward,default=in"`
	// Source is the address or CIDR the traffic comes from.
	Source string `json:"source,omitempty" jsonschema:"example=10.0.0.0/8"`
	// Destination is the address or CIDR the traffic goes to.
	Destination string `json:"destination,omitempty" jsonschema:"example=10.42.0.0/16"`
	// Ingress names where forward traffic enters. It is a zone on firewalld hosts and an
	// interface on ufw hosts. It applies to forward rules only.
	Ingress string `json:"ingress,omitempty" jsonschema:"example=public"`
	// Egress names where forward traffic leaves. It is a zone on firewalld hosts and an
	// interface on ufw hosts. It applies to forward rules only.
	Egress string `json:"egress,omitempty" jsonschema:"example=trusted"`
	// Port is the port number, or inclusive port range, the rule matches.
	Port string `json:"port,omitempty" jsonschema:"oneof_type=string;integer,example=6443,example=30000-32767"`
	// Protocol is the type of traffic the rule matches.
	Protocol string `json:"protocol,omitempty" jsonschema:"enum=tcp,enum=udp,enum=sctp,enum=dccp"`
}

ZarfFirewallRule is a single backend-neutral firewall rule. Every field except Action is optional; an omitted match field means "any". Backends translate a rule into their own dialect, so not every combination is expressible everywhere -- see the firewall package.

func (ZarfFirewallRule) Key

func (r ZarfFirewallRule) Key() string

Key returns the rule's Name, or a stable name derived from the rule's fields when Name is empty. Backends use it to name the files and comments that tie an applied rule back to this configuration.

func (ZarfFirewallRule) NormalizedAction

func (r ZarfFirewallRule) NormalizedAction() string

NormalizedAction returns the rule's action, lowercased.

func (ZarfFirewallRule) NormalizedDirection

func (r ZarfFirewallRule) NormalizedDirection() string

NormalizedDirection returns the rule's direction, lowercased, defaulting to in.

func (ZarfFirewallRule) NormalizedProtocol

func (r ZarfFirewallRule) NormalizedProtocol() string

NormalizedProtocol returns the rule's protocol, lowercased.

func (ZarfFirewallRule) Validate

func (r ZarfFirewallRule) Validate() error

Validate returns an error when the rule cannot be applied by any backend.

type ZarfFirewallZone

type ZarfFirewallZone struct {
	// Name identifies the firewalld zone.
	Name string `xml:"name,attr" jsonschema:"example=trusted,example=public"`
}

ZarfFirewallZone is the name of either the ingress or egress zone for a policy.

type ZarfHost

type ZarfHost struct {
	// ClientWithConfig embeds rig's client type. It gives ZarfHost multi-protocol connectivity to a remote host.
	rig.ClientWithConfig `json:",inline"`

	// Environment maps environment variables cargoship sets on the host.
	Environment map[string]string `json:"environment,omitempty"`
	// Files lists files cargoship uploads to the host.
	Files []ZarfClusterFiles `json:"files,omitempty"`
	// Hostname overrides the discovered name of the node.
	Hostname string `json:"hostname,omitempty"`
	// PrivateAddress overrides the discovered private address of the node.
	PrivateAddress string `json:"privateAddress,omitempty"`
	// PrivateInterface overrides the discovered private interface of the node.
	PrivateInterface string `json:"privateInterface,omitempty"`
	// Profile selects a profile by name from the cluster config's Profiles map.
	Profile string `json:"profile,omitempty"`
	// Role sets the node role when cargoship adds this host to the cluster. It must be controller or worker.
	Role string `json:"role" jsonschema:"required,enum=controller,enum=worker"`
	// Host holds the host-level configuration overrides for this node.
	Host ZarfHostConfig `json:"host,omitempty"`
	// Engine holds the node label and taint overrides for this node.
	Engine ZarfHostEngine `json:"engine,omitempty"`
	// Configurer is the per-host operations implementation cargoship uses to manage this host.
	Configurer os.Configurer `json:"-"`
	// OSRelease caches the detected (or fallback-resolved) OS release for this host.
	OSRelease *rigos.Release `json:"-"`
	// Metadata holds values cargoship discovers about this host at runtime.
	Metadata ZarfHostMetadata `json:"-"`
	// contains filtered or unexported fields
}

ZarfHost is a remote connection to a node

func (*ZarfHost) Address

func (h *ZarfHost) Address() string

Address returns the address rig is connected to for this host, or the empty string for a host that has not gone through Setup or Connect yet.

The promoted rig.Client.Address panics on a host in that state: ClientWithConfig defers creating its embedded *Client until Setup or Connect runs, so a host built directly (as tests do, or as a host removed from the config and never dialed this run) has a nil Client, and Address dereferences it unconditionally.

func (*ZarfHost) Arch

func (h *ZarfHost) Arch() (string, error)

Arch returns the host architecture, caching the result in metadata

func (*ZarfHost) CheckHTTPStatus

func (h *ZarfHost) CheckHTTPStatus(ctx context.Context, url string, expected ...int) error

CheckHTTPStatus requests url and returns an error if the response status is not one of expected.

func (*ZarfHost) Connect

func (h *ZarfHost) Connect(ctx context.Context) error

Connect establishes the connection to the host, injecting cargoship's configured logger so that rig's internal logging is routed through the same logger as the rest of the run. rig v2 has no global logger setter; the logger is injected per-client via rig.WithLogger, which is only honored at client construction (the first Connect call) or via ClientWithConfig.Connect's own options -- see riglogger.RigLogger.

func (*ZarfHost) DeleteFile

func (h *ZarfHost) DeleteFile(path string) error

DeleteFile removes a file from the host. Always runs with privilege escalation.

func (*ZarfHost) Dir

func (h *ZarfHost) Dir(path string) (string, error)

Dir returns the directory name for the given path using the remote filesystem.

func (*ZarfHost) EnableService

func (h *ZarfHost) EnableService(ctx context.Context, name string) error

EnableService enables the named service on the host.

func (*ZarfHost) Exec

func (h *ZarfHost) Exec(command string, opts ...cmd.ExecOption) error

Exec runs a command on the host. It shadows the promoted rig client method so that an unconnected host returns an error rather than panicking.

func (*ZarfHost) ExecOutput

func (h *ZarfHost) ExecOutput(command string, opts ...cmd.ExecOption) (string, error)

ExecOutput runs a command on the host and returns its output. It shadows the promoted rig client method so that an unconnected host returns an error rather than panicking.

func (*ZarfHost) FS

func (h *ZarfHost) FS() remotefs.FS

FS returns the host's filesystem. It shadows the promoted rig client method so that a host with a substituted filesystem uses that one, and an unconnected host returns a filesystem that fails rather than one that panics.

func (*ZarfHost) FileChanged

func (h *ZarfHost) FileChanged(lpath, rpath string) bool

FileChanged compares the local file at lpath to the remote file at rpath by sha256 checksum. It returns true if the checksums differ or if either checksum cannot be computed.

func (*ZarfHost) FileExist

func (h *ZarfHost) FileExist(path string) bool

FileExist returns true if path exists on the host. Always runs with privilege escalation, matching the behavior of the v0.x Configurer.FileExist implementation this replaces.

func (*ZarfHost) IsController

func (h *ZarfHost) IsController() bool

IsController returns true for the controller, controller+worker, and single roles.

func (*ZarfHost) KubeRole

func (h *ZarfHost) KubeRole() string

KubeRole returns the Kubernetes role for this host. It maps controller+worker and single to controller.

func (*ZarfHost) OSKind

func (h *ZarfHost) OSKind() (string, error)

OSKind returns the host OS kind via the resolved configurer.

func (*ZarfHost) ReadFile

func (h *ZarfHost) ReadFile(path string) (string, error)

ReadFile returns the contents of path on the host, or an error if the file does not exist. Always runs with privilege escalation.

func (*ZarfHost) ResolveConfigurer

func (h *ZarfHost) ResolveConfigurer() error

ResolveConfigurer detects the host OS version and assigns the matching configurer to Configurer.

func (*ZarfHost) RestartService

func (h *ZarfHost) RestartService(ctx context.Context, name string) error

RestartService restarts the named service on the host.

func (*ZarfHost) ServiceIsRunning

func (h *ZarfHost) ServiceIsRunning(ctx context.Context, name string) bool

ServiceIsRunning returns true if the named service is running on the host.

func (*ZarfHost) ServiceName

func (h *ZarfHost) ServiceName() string

ServiceName returns the name of the distro service that runs on this host.

func (*ZarfHost) SetFS

func (h *ZarfHost) SetFS(fs remotefs.FS)

SetFS substitutes the filesystem this host's file operations act through, in place of the one its rig connection provides.

func (*ZarfHost) SetServices

func (h *ZarfHost) SetServices(services HostServices)

SetServices substitutes the init system this host's service operations act through, in place of the one its rig connection provides.

func (*ZarfHost) StartService

func (h *ZarfHost) StartService(ctx context.Context, name string) error

StartService starts the named service on the host.

func (*ZarfHost) Stat

func (h *ZarfHost) Stat(path string) (fs.FileInfo, error)

Stat returns file information for path on the host. Always runs with privilege escalation, matching the rest of this host's file operations.

func (*ZarfHost) StopService

func (h *ZarfHost) StopService(ctx context.Context, name string) error

StopService stops the named service on the host.

func (*ZarfHost) String

func (h *ZarfHost) String() string

String returns the connection string. Safe to call before Connect.

func (*ZarfHost) SudoExec

func (h *ZarfHost) SudoExec(command string, opts ...cmd.ExecOption) error

SudoExec runs a command on the host with privilege escalation. Like Exec, it returns an error rather than panicking on a host that was never connected.

func (*ZarfHost) SudoExecOutput

func (h *ZarfHost) SudoExecOutput(command string, opts ...cmd.ExecOption) (string, error)

SudoExecOutput runs a command on the host with privilege escalation and returns its output. Like ExecOutput, it returns an error rather than panicking on a host that was never connected.

func (*ZarfHost) Touch

func (h *ZarfHost) Touch(path string, modTime time.Time) error

Touch updates file modification timestamps, creating the file if needed. Always runs with privilege escalation.

func (*ZarfHost) UnmarshalYAML

func (h *ZarfHost) UnmarshalYAML(unmarshal func(any) error) error

UnmarshalYAML decodes a host document into both ZarfHost's own fields and the embedded rig client's connection configuration.

rig.ClientWithConfig implements UnmarshalYAML itself, and since it is embedded anonymously that method is promoted onto *ZarfHost. Left alone, goccy/go-yaml would treat *ZarfHost as an InterfaceUnmarshaler and call the promoted method for the whole host document -- which decodes only ClientWithConfig's own fields and silently leaves every field ZarfHost declares (Hostname, Role, Profile, ...) zeroed. Decoding into a shadow type with no embedded ClientWithConfig avoids triggering that promoted method, and a second explicit decode through ClientWithConfig's own UnmarshalYAML fills in the connection config the same way it always did.

func (*ZarfHost) WriteFile

func (h *ZarfHost) WriteFile(path string, data string, permissions string) error

WriteFile writes data to path on the host. Do not use this for large files. Always runs with privilege escalation.

type ZarfHostConfig

type ZarfHostConfig struct {
	// Firewall holds the backend-neutral firewall rules cargoship renders onto whichever
	// firewall the node runs, firewalld, ufw, or nftables.
	Firewall ZarfFirewallConfig `json:"firewall,omitempty"`
	// Policy maps a policy name to a firewalld policy that allows traffic from one interface to another.
	// It is firewalld-only; prefer forward rules under `firewall.rules` for new configuration.
	Policy map[string]ZarfFirewallPolicyConfig `json:"policy,omitempty"`
	// Ports lists the ports and protocols cargoship opens on the node.
	Ports []ZarfHostPort `json:"ports,omitempty" xml:"port"`
}

ZarfHostConfig defines the configuration for a specific host, including firewall policies and the ports cargoship opens on the node.

func (*ZarfHostConfig) Merge

func (c *ZarfHostConfig) Merge(update ZarfHostConfig)

Merge copies Policy and Ports from update into c, for whichever of those fields are empty in c, and unions update's firewall rules into c's.

type ZarfHostEngine

type ZarfHostEngine struct {
	// NodeLabels maps Kubernetes node label keys to their values.
	NodeLabels map[string]string `json:"labels,omitempty"`
	// NodeTaints lists the Kubernetes node taints cargoship applies to the node.
	NodeTaints []string `json:"taints,omitempty"`
}

ZarfHostEngine defines configuration options for node-level metadata, specifically Kubernetes node labels and taints applied to a cluster host.

func (*ZarfHostEngine) Merge

func (c *ZarfHostEngine) Merge(update ZarfHostEngine)

Merge copies NodeLabels and NodeTaints from update into c, for whichever of those fields are empty in c.

type ZarfHostGroup

type ZarfHostGroup struct {
	// Profile is the profile name shared by Hosts. Empty for hosts that selected no profile.
	Profile string
	// Hosts are the hosts that selected Profile, in their original relative order.
	Hosts ZarfHosts
}

ZarfHostGroup is a set of hosts that share the same profile.

type ZarfHostMetadata

type ZarfHostMetadata struct {
	// Arch is the CPU architecture detected on the host.
	Arch string
	// BinaryTempFile lists temporary paths on the host cargoship uses to stage the engine binary during install.
	BinaryTempFile []string
	// DistroVersion is the version of the distro engine detected on the host.
	DistroVersion string
	// EngineUploaded indicates whether cargoship has already uploaded the distro engine binary to the host.
	EngineUploaded bool
	// ExistingConfig is the engine configuration currently present on the host.
	ExistingConfig string
	// Hostname is the hostname the host reports.
	Hostname string
	// Install is the function cargoship calls to install the distro engine on the host.
	Install func(context.Context, *ZarfHost) error
	// Installed indicates whether a distro engine is already installed on the host.
	Installed bool
	// IsLeader indicates whether this host is the cluster's control-plane leader.
	IsLeader bool
	// MachineID identifies the node to the distro engine.
	MachineID string
	// ModulesAdded indicates whether cargoship added a new kernel module to the host.
	ModulesAdded bool
	// NeedsUpgrade indicates whether the host needs the distro engine upgraded.
	NeedsUpgrade bool
	// NewConfig is the engine configuration cargoship will write to the host.
	NewConfig string
	// Ready indicates whether the distro service is up and running.
	Ready bool
	// UploadedFiles lists "category\tpath" entries cargoship uploaded to this host during the
	// current run. It is used to detect files a previous version left behind that the current
	// upload no longer produces, e.g. an engine binary renamed by a version bump.
	UploadedFiles []string
}

ZarfHostMetadata holds values cargoship discovers about a host at runtime.

type ZarfHostPort

type ZarfHostPort struct {
	// Protocol is the type of allowed traffic.
	Protocol string `json:"protocol" xml:"protocol,attr" jsonschema:"enum=tcp,enum=udp"`
	// Port is the port number, or port range, cargoship opens.
	Port string `json:"port" xml:"port,attr" jsonschema:"oneof_type=string;integer"`
}

ZarfHostPort is a port cargoship opens on the public side of the firewall.

type ZarfHosts

type ZarfHosts []*ZarfHost

ZarfHosts is an ordered list of hosts that cargoship manages together.

func (ZarfHosts) BatchedParallelEach

func (hosts ZarfHosts) BatchedParallelEach(ctx context.Context, batchSize int, filter ...func(context.Context, *ZarfHost) error) error

BatchedParallelEach runs each filter on every host in parallel, in groups of batchSize hosts. It completes one group before it starts the next. It stops and returns the error if ctx is canceled or a group returns an error.

func (ZarfHosts) Controllers

func (hosts ZarfHosts) Controllers() ZarfHosts

Controllers returns the hosts that act as a controller. This includes hosts with role controller, controller+worker, or single.

func (ZarfHosts) Each

func (hosts ZarfHosts) Each(ctx context.Context, filters ...func(context.Context, *ZarfHost) error) error

Each runs each filter on every host, in the order given. It stops and returns the error if ctx is canceled or a filter returns an error.

func (ZarfHosts) Filter

func (hosts ZarfHosts) Filter(filter func(h *ZarfHost) bool) ZarfHosts

Filter returns the hosts for which filter returns true.

func (ZarfHosts) Find

func (hosts ZarfHosts) Find(filter func(h *ZarfHost) bool) *ZarfHost

Find returns the first host for which filter returns true. It returns nil if no host matches.

func (ZarfHosts) First

func (hosts ZarfHosts) First() *ZarfHost

First returns the first host. It returns nil if there are no hosts.

func (ZarfHosts) GroupByProfile

func (hosts ZarfHosts) GroupByProfile() []ZarfHostGroup

GroupByProfile splits hosts into groups by their Profile field, preserving each host's relative order within its group. Groups are ordered by each profile's first appearance in hosts, so the result is deterministic.

func (ZarfHosts) Last

func (hosts ZarfHosts) Last() *ZarfHost

Last returns the last host. It returns nil if there are no hosts.

func (ZarfHosts) ParallelEach

func (hosts ZarfHosts) ParallelEach(ctx context.Context, filters ...func(context.Context, *ZarfHost) error) error

ParallelEach runs each filter on every host in parallel. It runs the filters in the order given, completing one filter across all hosts before it starts the next. It collects every error and returns them combined.

func (ZarfHosts) WithRole

func (hosts ZarfHosts) WithRole(s string) ZarfHosts

WithRole returns the hosts that have the given role.

func (ZarfHosts) Workers

func (hosts ZarfHosts) Workers() ZarfHosts

Workers returns the hosts with role worker.

type ZarfRuntimeMeta

type ZarfRuntimeMeta struct {
	// ControllerTLS lists the names and addresses on the controller TLS certificate.
	ControllerTLS []string
	// ControllerToken authorizes a worker node to join the cluster as a controller.
	ControllerToken string
	// AgentToken authorizes a worker node to join the cluster as an agent.
	AgentToken string
	// LoadBalancer is the hostname clients use to reach the cluster control plane.
	LoadBalancer string
	// Leader is the controller host that stores the cluster join tokens.
	Leader *ZarfHost
	// Registries lists the container registries the cluster uses.
	Registries []ZarfClusterRegistries
}

ZarfRuntimeMeta stores data gathered while the phases run.

Jump to

Keyboard shortcuts

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