config

package
v0.4.0 Latest Latest
Warning

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

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

Documentation

Overview

Package config resolves the environment ate-setup installs into. It layers the developer's .ate-dev-env.sh (sourced through bash, so existing setups keep working), the ambient process environment, and command line flags into a single typed Config.

Index

Constants

View Source
const (
	RouterEnvoy        = "envoy"
	RouterAgentgateway = "agentgateway"

	SandboxClassGvisor  = "gvisor"
	SandboxClassMicrovm = "microvm"

	// Cluster size profiles. size0 is the shipped footprint; size10 assumes a
	// dedicated node for PostgreSQL and raises the store, its client pool, and
	// the podcertificate controller's API rate limits to match.
	ClusterSizeSize0  = "size0"
	ClusterSizeSize10 = "size10"
)

Enumerated values for the install-shaping flags.

View Source
const (
	DefaultPostgresSchema        = postgressetup.Schema
	DefaultPostgresReadWriteRole = postgressetup.ReadWriteRole
	DefaultPostgresOwnerRole     = postgressetup.OwnerRole
)
View Source
const (
	CloudSQLIPTypePrivate = "private"
	CloudSQLIPTypePublic  = "public"
	CloudSQLIPTypePSC     = "psc"
)

Cloud SQL Auth Proxy IP types, the values ATE_API_POSTGRES_CLOUDSQL_IP_TYPE accepts.

View Source
const (
	K8sCredentialProviderName    = "k8s.io"
	K8sCredentialProviderAddress = "k8s-credential-provider." + installdefaults.SystemNamespace + ".svc:50051"
)

The bundled Kubernetes Secrets provider, which the installer deploys with a NetworkPolicy that admits only the egress gateway. Its default address is the Service in manifests/egress-credential-injection/k8s-credential-provider.yaml.

View Source
const (
	FileAPIVersion = "install.ate.dev/v1alpha1"
	FileKind       = "SubstrateInstall"
)

The identifying header every configuration document carries. Versioning the document from the start means a later schema change can be detected rather than mis-parsed.

View Source
const ConfigPathEnv = "ATE_CONFIG"

ConfigPathEnv names the configuration document when --config is not given.

It exists so the file channel crosses hack/install-ate.sh, which forwards only a fixed set of flags but passes the whole environment to the child process. Every other setting reaches ate-setup that way already.

View Source
const DefaultRolloutTimeout = 60 * time.Second

DefaultRolloutTimeout is the default wait timeout for workload rollouts.

View Source
const Size10PostgresPoolParams = "&pool_max_conns=64&pool_min_conns=4"

Size10PostgresPoolParams is appended to the bundled read/write connection on size10 clusters. pgxpool defaults MaxConns to max(4, runtime.NumCPU()), which under-uses the size10 server's raised max_connections; pinning the pool makes the client side open the sockets the server is provisioned for.

Variables

View Source
var Registry = []Setting{
	{

		Key: "kindCluster.enabled", Env: "ATE_INSTALL_KIND", Flag: "kind", Kind: KindBool, Default: "false",
		Usage: "Target a local Kind cluster: kind overlays, the local registry, and host-architecture builds",
	},
	{
		Key: "kindCluster.name", Env: "KIND_CLUSTER_NAME", Flag: "kind-cluster-name", Kind: KindString, Default: "kind",
		Usage: "Name of the Kind cluster to target",
	},
	{
		Key: "namespace", Env: "ATE_NAMESPACE", Flag: "namespace", Kind: KindString,
		Default: installdefaults.SystemNamespace,
		Usage:   "Namespace the control plane is installed into",
	},
	{
		Key: "kubeconfig", Env: "KUBECONFIG", Flag: "kubeconfig", Kind: KindString,
		Usage: "Path to the kubeconfig file",
	},
	{
		Key: "context", Env: "KUBECTL_CONTEXT", Flag: "context", Kind: KindString,
		Usage: "Name of the kubeconfig context to use",
	},

	{
		Key: "gcp.projectID", Env: "PROJECT_ID", Flag: "gcp-project-id", Kind: KindString,
		Usage: "GCP project holding the target cluster",
	},
	{
		Key: "gcp.clusterName", Env: "CLUSTER_NAME", Flag: "gcp-cluster-name", Kind: KindString,
		Usage: "GKE cluster name, used to fetch credentials and derive the JWT issuer",
	},
	{
		Key: "gcp.clusterLocation", Env: "CLUSTER_LOCATION", Flag: "gcp-cluster-location", Kind: KindString,
		Usage: "GKE cluster location",
	},

	{
		Key: "ko.dockerRepo", Env: "KO_DOCKER_REPO", Flag: "ko-docker-repo", Kind: KindString,
		Usage: "Registry ko pushes built images to",
	},
	{
		Key: "ko.defaultPlatforms", Env: "KO_DEFAULTPLATFORMS", Flag: "ko-default-platforms", Kind: KindString,
		Usage: "Platforms ko builds for",
	},
	{
		Key: "actorJWT.algorithm", Env: "ACTOR_JWT_ALGORITHM", Flag: "actor-jwt-algorithm",
		Kind: KindString, Default: "ES256",
		Usage: "Signing algorithm of the key in a new actor JWT pool: ES256 or RS256",
	},
	{

		Key: "docker.buildFlags", Env: "DOCKER_BUILD_FLAGS", Flag: "docker-build-flags",
		Kind:  KindString,
		Usage: "Extra docker buildx build flags for the images ko cannot build, whitespace-separated",
	},
	{
		Key: "images.repo", Env: "ATE_IMAGE_REPO", Flag: "image-repo", Kind: KindString,
		Usage: "Install pre-built images from this registry path instead of building from source",
	},
	{
		Key: "images.tag", Env: "ATE_IMAGE_TAG", Flag: "image-tag", Kind: KindString,
		Usage: "Tag the pre-built images carry (required with --image-repo)",
	},

	{
		Key: "storage.bucketName", Env: "BUCKET_NAME", Flag: "storage-bucket-name", Kind: KindString,
		Usage: "Snapshot bucket the demos are templated with",
	},

	{
		Key: "atenet.dataplane", Env: "ATE_ATENET_DATAPLANE", Flag: "atenet-dataplane", Kind: KindString,
		Default: RouterEnvoy,
		Usage:   "Atenet ingress and egress dataplane: envoy or agentgateway",
	},
	{
		Key: "atenet.egress.additionalExtprocService", Env: "ATE_ADDITIONAL_EGRESS_EXTPROC_SERVICE",
		Flag: "experimental-additional-egress-extproc-service", Kind: KindString,
		Usage: "Run an additional ext_proc authorization filter served by NS/SVC:PORT " +
			"(requires --atenet-dataplane=envoy)",
	},

	{
		Key: "ateapi.expectedJWTIssuer", Env: "EXPECTED_JWT_ISSUER", Flag: "ateapi-expected-jwt-issuer",
		Kind:  KindString,
		Usage: "Service account token issuer ate-api-server trusts, overriding derivation and discovery",
	},
	{

		Key: "atenet.egress.credentialProvider", Env: "ATE_CREDENTIAL_PROVIDER",
		Flag: "credential-provider", Kind: KindString,
		Usage: "Credential provider the egress gateway injects credentials from, as JSON; " +
			"required by deploy ate-system and deploy atenet. " + credentialProviderUsage +
			". A provider requires --atenet-dataplane=envoy",
	},
	{

		Key: "ateapi.postgres.readWrite.connectionString", Env: "ATE_API_POSTGRES_READ_WRITE_CONNECTION_STRING",
		Kind: KindString, Secret: true,
		Usage: "PostgreSQL connection string ate-api-server uses for normal application access",
	},
	{
		Key: "ateapi.postgres.owner.connectionString", Env: "ATE_API_POSTGRES_OWNER_CONNECTION_STRING",
		Kind: KindString, Secret: true,
		Usage: "PostgreSQL connection string ate-api-server uses for schema changes, " +
			"defaulting to the read-write one",
	},
	{
		Key: "ateapi.postgres.readWrite.role", Env: "ATE_API_POSTGRES_READ_WRITE_ROLE",
		Flag: "ateapi-postgres-read-write-role", Kind: KindString,
		Default: DefaultPostgresReadWriteRole,
		Usage:   "PostgreSQL role owning normal application access",
	},
	{
		Key: "ateapi.postgres.owner.role", Env: "ATE_API_POSTGRES_OWNER_ROLE",
		Flag: "ateapi-postgres-owner-role", Kind: KindString,
		Default: DefaultPostgresOwnerRole,
		Usage:   "PostgreSQL role owning the schema",
	},
	{
		Key: "ateapi.postgres.schema", Env: "ATE_API_POSTGRES_SCHEMA", Flag: "ateapi-postgres-schema",
		Kind:  KindString,
		Usage: "PostgreSQL schema holding the Substrate tables",
	},
	{
		Key: "ateapi.postgres.poolMaxConns", Env: "ATE_API_POSTGRES_POOL_MAX_CONNS",
		Flag: "ateapi-postgres-pool-max-conns", Kind: KindString,
		Usage: "Maximum connections in the apiserver's pgxpool",
	},
	{
		Key: "ateapi.postgres.serverCAFile", Env: "ATE_API_POSTGRES_SERVER_CA_FILE",
		Flag: "ateapi-postgres-server-ca-file", Kind: KindString,
		Usage: "Local PEM file holding an external PostgreSQL server CA",
	},
	{
		Key: "ateapi.postgres.cloudsql.instance", Env: "ATE_API_POSTGRES_CLOUDSQL_INSTANCE",
		Flag: "ateapi-postgres-cloudsql-instance", Kind: KindString,
		Usage: "Cloud SQL instance connection name, PROJECT:REGION:INSTANCE",
	},
	{
		Key: "ateapi.postgres.cloudsql.gsa", Env: "ATE_API_POSTGRES_CLOUDSQL_GSA",
		Flag: "ateapi-postgres-cloudsql-gsa", Kind: KindString,
		Usage: "Google service account the Cloud SQL Auth Proxy authenticates as",
	},
	{
		Key: "ateapi.postgres.cloudsql.iamAuth", Env: "ATE_API_POSTGRES_CLOUDSQL_IAM_AUTH",
		Flag: "ateapi-postgres-cloudsql-iam-auth", Kind: KindString,
		Usage: "Enable automatic IAM database authentication: true or false",
	},
	{
		Key: "ateapi.postgres.cloudsql.ipType", Env: "ATE_API_POSTGRES_CLOUDSQL_IP_TYPE",
		Flag: "ateapi-postgres-cloudsql-ip-type", Kind: KindString,
		Usage: "Instance address the Cloud SQL proxy dials: private, public or psc",
	},

	{
		Key: "podcert.workersPerSigner", Env: "ATE_INSTALL_PODCERT_WORKERS_PER_SIGNER",
		Flag: "podcert-workers-per-signer", Kind: KindInt, Default: "0",
		Usage: "Worker goroutines per signer in podcertificate-controller",
	},

	{
		Key: "rolloutTimeout", Env: "ATE_INSTALL_ROLLOUT_TIMEOUT", Flag: "rollout-timeout",
		Kind: KindDuration, Default: DefaultRolloutTimeout.String(),
		Usage: "Timeout for workload rollouts, as a duration string",
	},
	{
		Key: "clusterSize", Env: "ATE_INSTALL_CLUSTER_SIZE", Flag: "cluster-size", Kind: KindString,
		Default: ClusterSizeSize0,
		Usage:   "Coarse-grained sizing of Substrate: size0 or size10",
	},
	{
		Key: "cordonControlPlane", Env: "ATE_INSTALL_CORDON_CONTROL_PLANE", Flag: "cordon-control-plane",
		Kind: KindBool, Default: "false",
		Usage: "Keep the control plane off the worker nodes. Assumes a small shared pool labeled " +
			"and tainted ate.dev/workloadType=ate-control-plane:NoSchedule, and a one-node pool " +
			"labeled and tainted ate.dev/workloadType=ate-postgres:NoSchedule for postgres alone",
	},
	{
		Key: "otlpEndpoint", Env: "ATE_OTLP_ENDPOINT", Flag: "otlp-endpoint", Kind: KindString,
		Usage: "Send control plane telemetry to this OTLP collector instead of the cluster default",
	},

	{
		Key: "benchmark.actorMemory", Env: "BENCHMARK_ACTOR_MEMORY", Flag: "benchmark-actor-memory",
		Kind:  KindString,
		Usage: "Memory limit for benchmark actors",
	},
	{
		Key: "record.dir", Env: "ATE_RECORD_DIR", Flag: "record-dir", Kind: KindString,
		Usage: "Directory install records are written to (default: the user cache directory)",
	},
	{
		Key: "demo.anthropicAPIKey", Env: "ANTHROPIC_API_KEY",
		Kind: KindString, Secret: true,
		Usage: "API key required by the claude-code-multiplex demo",
	},
}

Registry is the settings the installer itself owns. Each entry is the one place a setting is declared: the flag, the environment variable and the file key are all projections of it.

Settings that belong to one command are added by RegisterCommand instead; All returns both.

Functions

func BindCommandFlags added in v0.4.0

func BindCommandFlags(path string, fs *pflag.FlagSet)

BindCommandFlags registers the settings scoped to one command path, on that command's own flag set. A setting naming several paths is bound to each: one setting with two bindings, not two settings.

func BindFlags added in v0.4.0

func BindFlags(fs *pflag.FlagSet)

BindFlags registers the settings that belong to no single command, as persistent flags on the root.

Call it at the point flags are wired rather than capturing All() earlier: a command registers its settings in its own init, and package initialization order puts that before the command tree is built, not before this package loads.

func Keys added in v0.4.0

func Keys() []string

Keys returns every canonical key, sorted.

func RecordDir added in v0.4.0

func RecordDir(configured string) (string, error)

RecordDir is where records are written: the directory the caller was configured with, or the user cache directory.

Not the repository root: an operator installing from a release has no checkout, and writing into someone's working tree to record their own run is a surprise. An operator who wants these under version control points the setting at the repository that holds them.

The configured directory is a parameter rather than a setting this package reads, so nothing here depends on a particular key existing.

func RecordFailure added in v0.4.0

func RecordFailure(dir, context string, r *Resolved, failedAt string) (string, []string, error)

RecordFailure writes the configuration an incomplete run used, under a name that does not collide with earlier attempts.

Nothing reads it. A failed run must not change what a later run resolves -- a botched value would otherwise become the default and reach the cluster on the next success -- so recovering it is an explicit act: pass the path to --config.

func RecordSuccess added in v0.4.0

func RecordSuccess(dir, context string, r *Resolved) (string, []string, error)

RecordSuccess writes the configuration a completed run used, replacing the previous record for that context. It returns the path and the secret settings it left out.

func RegisterCommand added in v0.4.0

func RegisterCommand(settings ...Setting)

RegisterCommand records settings owned by one command, to be called from the owning package's init. A command declares its own configuration rather than a central list growing a line for every command, which is how demos.Register already works.

It does not validate. A panic here would fire during package initialization, before any test could observe it, and would abort the test binary instead of failing a test. Validate reports the same problems and is callable.

func RepoRoot

func RepoRoot() (string, error)

RepoRoot walks up from the working directory to the module root. This replaces `git rev-parse --show-toplevel` and works in a source tarball with no .git directory.

func Validate added in v0.4.0

func Validate() error

Validate reports duplicate names and missing channels across the merged set.

It cannot run inside package config's own tests: the settings it is meant to catch are registered by the command packages, which config does not import. The caller is the test in package main, which imports the whole command tree, and Execute, so a bad registration fails at startup.

Types

type CloudSQLConfig added in v0.2.0

type CloudSQLConfig struct {
	// Instance is the instance connection name, PROJECT:REGION:INSTANCE.
	Instance string
	// InstanceSet records whether ATE_API_POSTGRES_CLOUDSQL_INSTANCE was
	// present in the environment at all, empty value included.
	InstanceSet bool

	// GSA is the Google service account the proxy authenticates as, and whose
	// email (minus the .gserviceaccount.com suffix) is the IAM database user.
	GSA string
	// IAMAuth enables automatic IAM database authentication ("true" or
	// "false"). Empty defaults to enabled.
	IAMAuth string
	// IPType selects which instance address the proxy dials: one of the
	// CloudSQLIPType constants. Empty defaults to private.
	IPType string
}

CloudSQLConfig is the operator's Cloud SQL intent, as expressed by the ATE_API_POSTGRES_CLOUDSQL_* variables.

Every field is empty-means-unspecified except Instance, which is three-way: a non-empty instance selects Cloud SQL, an explicitly empty one removes it, and an unset one (InstanceSet false) adopts whatever the target cluster already records. Without that distinction a redeploy from a shell that simply never exported the variable would tear the proxy sidecar out from under a working installation.

type Config

type Config struct {
	// Root is the repository root. All manifest paths are relative to it.
	Root string

	// Kind selects the local Kind install profile (ATE_INSTALL_KIND).
	Kind bool

	// Namespace is the namespace the control plane is installed into, from
	// ATE_NAMESPACE. It defaults to the canonical installdefaults.SystemNamespace,
	// so an install that does not set it is unaffected. The checked-in manifests
	// under manifests/ate-install/ name that namespace literally, so the
	// manifest-applying steps refuse any other value; see Env.RequireCanonicalNamespace.
	Namespace string

	// Kubeconfig and Context select the target cluster. Empty Context means
	// "use the current context" (the KUBECTL_CONTEXT convention).
	//
	// Kubeconfig is a single file, handed to client-go as its explicit path. It
	// falls back to $KUBECONFIG rather than staying empty so that ate-setup and
	// the shell scripts it delegates to agree on the cluster — but only when
	// that variable names one file. See loadKubeconfig.
	Kubeconfig string
	Context    string

	// GKE cluster coordinates, used to fetch credentials and to derive the
	// service account JWT issuer.
	ProjectID       string
	ClusterName     string
	ClusterLocation string

	// ExpectedJWTIssuer is the service account token issuer ate-api-server
	// trusts (EXPECTED_JWT_ISSUER). It overrides both the GKE derivation from
	// the coordinates above and OpenID discovery, for clusters whose issuer
	// follows neither form.
	ExpectedJWTIssuer string

	// ActorJWTAlgorithm is the signing algorithm of the key in a new actor JWT
	// pool (ACTOR_JWT_ALGORITHM): ES256 or RS256.
	ActorJWTAlgorithm string

	// BucketName is the snapshot bucket demos are templated with.
	BucketName string

	// KODockerRepo is where ko pushes images (KO_DOCKER_REPO).
	KODockerRepo string
	// KODefaultPlatforms constrains ko's build platforms.
	KODefaultPlatforms string
	// DockerBuildFlags are extra docker buildx build flags for the images ko
	// cannot build (DOCKER_BUILD_FLAGS, whitespace-separated).
	DockerBuildFlags []string

	// Images selects where container images come from. Its zero value builds
	// them from source with ko, which is what a developer install does.
	Images images.Source

	// Router selects the atenet router dataplane.
	Router string
	// The read/write and owner connections can use different login identities.
	// With one configured connection, both pools use it. Both empty selects
	// bundled PostgreSQL.
	PostgresReadWriteConnectionString string
	PostgresOwnerConnectionString     string
	PostgresReadWriteRole             string
	PostgresOwnerRole                 string
	// These distinguish an explicit role override from the default when
	// adopting an existing Cloud SQL installation.
	PostgresReadWriteRoleSet bool
	PostgresOwnerRoleSet     bool
	// PostgresSchema is the PostgreSQL schema for the Substrate tables
	// (ATE_API_POSTGRES_SCHEMA). Empty means DefaultPostgresSchema.
	PostgresSchema string
	// PostgresPoolMaxConns sizes the apiserver's read/write pool
	// (ATE_API_POSTGRES_POOL_MAX_CONNS). Empty leaves the DSN or pgxpool default.
	PostgresPoolMaxConns string
	// PostgresServerCAFile is a local PEM file holding the server CA of an
	// external PostgreSQL (ATE_API_POSTGRES_SERVER_CA_FILE). Its contents are
	// published as the postgres-server-ca Secret, which ate-api-server mounts
	// at /run/postgres-server-ca/server-ca.pem for sslmode=verify-ca DSNs.
	PostgresServerCAFile string
	// CloudSQL points the apiserver at a Cloud SQL instance through the Auth
	// Proxy sidecar instead of a directly reachable PostgreSQL.
	CloudSQL CloudSQLConfig

	// RolloutTimeout is the timeout duration for rollout status checks.
	RolloutTimeout time.Duration

	// PodcertWorkersPerSigner overrides WORKERS_PER_SIGNER on podcertificate-controller.
	PodcertWorkersPerSigner int

	// ClusterSize is the footprint profile (ATE_INSTALL_CLUSTER_SIZE): size0
	// or size10.
	ClusterSize string

	// CordonControlPlane keeps the control plane off the worker nodes
	// (ATE_INSTALL_CORDON_CONTROL_PLANE). It assumes a small shared pool
	// labeled and tainted ate.dev/workloadType=ate-control-plane:NoSchedule,
	// and a one-node pool labeled and tainted
	// ate.dev/workloadType=ate-postgres:NoSchedule for postgres alone.
	CordonControlPlane bool

	// AdditionalEgressExtprocService is the optional NS/SVC:PORT external processor filter.
	AdditionalEgressExtprocService string

	// CredentialProviderJSON is the --credential-provider value; see
	// CredentialProvider for its schema.
	CredentialProviderJSON string

	// AnthropicAPIKey is required only by the claude-code-multiplex demo.
	AnthropicAPIKey string

	// OtlpEndpoint is where the control plane ships telemetry
	// (ATE_OTLP_ENDPOINT). Benchmark actors are pointed at it too.
	OtlpEndpoint string
	// BenchmarkActorMemory is the memory limit for benchmark actors
	// (BENCHMARK_ACTOR_MEMORY). Empty leaves the workload default in place.
	BenchmarkActorMemory string
	// contains filtered or unexported fields
}

Config is the fully resolved installation environment. Fields sourced from the developer environment keep their shell names in the comments so the mapping back to .ate-dev-env.sh stays obvious.

func LoadFlags added in v0.4.0

func LoadFlags(fs *pflag.FlagSet, o LoadOptions) (*Config, error)

LoadFlags resolves the effective configuration from a bound flag set.

Precedence, lowest to highest: .ate-dev-env.sh, the process environment, the configuration file, then flags. The file outranks the environment because it is the artifact an operator owns and reviews; ambient state must not silently outrank it.

func (*Config) CredentialProvider added in v0.4.0

func (c *Config) CredentialProvider() (CredentialProvider, error)

CredentialProvider parses --credential-provider, a JSON object that either turns injection off with enabled false or names a provider and its address. Only the bundled provider has a default address. A missing value is reported here rather than in validate because only the deploys that render the egress gateway need it.

func (*Config) EnsureClusterCredentials

func (c *Config) EnsureClusterCredentials(ctx context.Context) error

EnsureClusterCredentials fetches GKE credentials when the configuration names a project but no explicit context.

This reproduces the prologue of the shell installer: a developer whose .ate-dev-env.sh sets PROJECT_ID gets their kubeconfig populated before anything talks to the cluster. Setting a context (or KUBECTL_CONTEXT) is taken as "I already have credentials" and skips the call, as it did there.

func (*Config) KoEnv

func (c *Config) KoEnv() []string

KoEnv returns the environment overrides ko needs for this configuration.

func (*Config) Manifest

func (c *Config) Manifest(parts ...string) string

Manifest resolves a path under manifests/ate-install.

func (*Config) Path

func (c *Config) Path(parts ...string) string

Path resolves a repo-relative path.

func (*Config) PostgresSchemaName

func (c *Config) PostgresSchemaName() string

PostgresSchemaName returns the configured schema, falling back to the shell installer's default. ate-api-server rejects an empty value.

func (*Config) Resolved added in v0.4.0

func (c *Config) Resolved() *Resolved

Resolved returns every setting and its origin. Command-scoped settings are not fields on Config: a command reads its own by key.

A Config built directly rather than by Load has resolved nothing, which is what tests do. Reporting declared defaults keeps every lookup working instead of panicking on a nil map.

func (*Config) ScriptEnv

func (c *Config) ScriptEnv() []string

ScriptEnv returns the environment for the shell scripts ate-setup still delegates to (the benchmark and micro-VM helpers).

Those scripts read the same variables the shell installer exported to them, so this reproduces that environment: .ate-dev-env.sh under the process environment, with the resolved configuration layered on top so that flags such as --context and --kind reach them.

func (*Config) SetResolved added in v0.4.0

func (c *Config) SetResolved(r *Resolved)

SetResolved attaches resolved settings to a Config built directly. Load does this itself; the callers here are tests and the demo test harness.

func (*Config) Size10 added in v0.2.0

func (c *Config) Size10() bool

Size10 reports whether the size10 footprint profile is selected.

func (*Config) WaitTimeout

func (c *Config) WaitTimeout(historical time.Duration) time.Duration

WaitTimeout returns how long to wait for a workload whose historical timeout was historical.

The shell installer applied --rollout-timeout to the ate-system rollouts only; the podcertificate-controller wait and the CSI driver waits were fixed at 120s because they are the slow bootstrap paths — an image pull on a cold cluster, in the CSI case a driver being torn down and reinstalled. Honoring the flag everywhere would let its 60s default halve exactly those waits.

So the flag now reaches every wait, but only when someone asked for it. Left alone, each site keeps the timeout the scripts gave it.

type ConflictError added in v0.4.0

type ConflictError struct {
	A, B Value
	// Why states the rule that was broken.
	Why string
}

ConflictError reports two values that cannot hold together, naming the channel each came from.

func (*ConflictError) Error added in v0.4.0

func (e *ConflictError) Error() string

type CredentialProvider added in v0.4.0

type CredentialProvider struct {
	// Name is the host of the ate-secret:// credential URIs the provider
	// serves, e.g. k8s.io.
	Name string
	// Address is the host:port the gateway dials the provider at.
	Address string
}

CredentialProvider is the credential provider the egress gateway is pointed at. The zero value means injection is off.

func (CredentialProvider) Enabled added in v0.4.0

func (p CredentialProvider) Enabled() bool

Enabled reports whether the gateway is given a provider.

func (CredentialProvider) Kubernetes added in v0.4.0

func (p CredentialProvider) Kubernetes() bool

Kubernetes reports whether the provider is the bundled one.

func (CredentialProvider) ServerName added in v0.4.0

func (p CredentialProvider) ServerName() string

ServerName is the SAN the gateway expects on the provider's serving certificate: the address without its port.

type Document added in v0.4.0

type Document struct {
	Metadata DocumentMetadata
	// contains filtered or unexported fields
}

Document is a resolved configuration as a file. The same shape serves the record of a run and the --config input of the next one, so retrying takes no conversion step.

func NewDocument added in v0.4.0

func NewDocument(r *Resolved, meta DocumentMetadata) (*Document, []string)

NewDocument records the settings a channel supplied.

Settings still on their declared default are omitted. An unset setting has to keep tracking its default when a later release changes it, and writing the default out would freeze the value this run happened to get.

Secret settings are omitted whatever supplied them, and their keys are returned so the caller can say which a retry must re-supply. Without that, the omission is discovered only when the retry fails.

func (*Document) Keys added in v0.4.0

func (d *Document) Keys() []string

Keys returns the settings the document records, sorted.

func (*Document) Marshal added in v0.4.0

func (d *Document) Marshal() ([]byte, error)

Marshal renders the document, nesting the dotted keys so the result is ordinary --config input rather than a second format.

Scalars are written in their declared kind: a count reads as 7, not "7". ParseFile accepts either, but a document an operator edits should look like the example in the documentation.

type DocumentMetadata added in v0.4.0

type DocumentMetadata struct {
	// Context is the cluster the run targeted, and names the file.
	Context string `json:"context,omitempty"`
	// Outcome is whether the run completed.
	Outcome Outcome `json:"outcome,omitempty"`
	// FailedAt is the command that returned an error, for a failed run.
	FailedAt string `json:"failedAt,omitempty"`
	// WrittenAt and WrittenBy identify the run for a reader comparing two
	// documents.
	WrittenAt string `json:"writtenAt,omitempty"`
	WrittenBy string `json:"writtenBy,omitempty"`
}

DocumentMetadata records which run produced a document. It is written by ate-setup and ignored when the document is read back as configuration.

type File added in v0.4.0

type File struct {
	// Path is where the document was read from, for error messages.
	Path string
	// contains filtered or unexported fields
}

File is a parsed configuration document. Settings are held flattened, keyed by the same dotted keys Registry declares, so lookups need no knowledge of how the YAML was nested.

func ParseFile added in v0.4.0

func ParseFile(path string) (*File, error)

ParseFile reads a configuration document.

Unknown keys are rejected rather than ignored: a typo in a setting name would otherwise leave the install silently running on the default.

func (*File) Get added in v0.4.0

func (f *File) Get(key string) (string, bool)

Get returns the raw value for a canonical key.

func (*File) Keys added in v0.4.0

func (f *File) Keys() []string

Keys returns every key the document set, sorted.

type InvalidError added in v0.4.0

type InvalidError struct {
	Value Value
	// Want describes the accepted values, e.g. "envoy or agentgateway".
	Want string
}

InvalidError reports a value that is not valid for its setting, naming the channel it came from so the reader knows which one to edit.

func (*InvalidError) Error added in v0.4.0

func (e *InvalidError) Error() string

type LoadOptions added in v0.4.0

type LoadOptions struct {
	// ConfigPath is the --config document. Empty falls back to $ATE_CONFIG,
	// and then to no file layer.
	ConfigPath string
	// NoDevEnv skips sourcing .ate-dev-env.sh even when it exists.
	NoDevEnv bool
}

LoadOptions carries the inputs that select where configuration comes from, as opposed to the settings themselves.

type Origin added in v0.4.0

type Origin int

Origin is the channel a resolved value came from.

const (
	// OriginDefault is the setting's declared default; no channel supplied it.
	OriginDefault Origin = iota
	OriginEnv
	OriginFile
	OriginFlag
	// OriginKindProfile is a value a Kind install derived for itself because
	// no channel supplied one. It is not a channel an operator writes to: the
	// way to override it is any of the three above.
	OriginKindProfile
)

func (Origin) Describe added in v0.4.0

func (o Origin) Describe(s Setting) string

Describe names the origin the way the operator would refer to it, so an error message points at the thing they would edit.

func (Origin) String added in v0.4.0

func (o Origin) String() string

type Outcome added in v0.4.0

type Outcome string

Outcome is how the run that produced a document ended.

const (
	Succeeded Outcome = "succeeded"
	Failed    Outcome = "failed"
)

type ReportOptions added in v0.4.0

type ReportOptions struct {
	// OmitDefaults lists only the settings a channel supplied.
	//
	// The full listing is the default: the report answers "where did every
	// value come from", and a setting left out of it is one the reader has to
	// go and look up. Omitting is for callers that already know, or that have
	// more output than the configuration is worth.
	OmitDefaults bool
}

ReportOptions selects how much of the configuration is listed.

type RequiredError added in v0.4.0

type RequiredError struct {
	Setting Setting
}

RequiredError reports a setting no channel supplied.

The message names all three channels because the reader may know only one of them: telling someone who configures by file to set an environment variable sends them to the wrong place.

func (*RequiredError) Error added in v0.4.0

func (e *RequiredError) Error() string

type ResolveOptions added in v0.4.0

type ResolveOptions struct {
	// File is the parsed configuration document, or nil when --config was not
	// given.
	File *File
	// Env is the environment to read, normally Environ().
	Env map[string]string
}

ResolveOptions carries inputs that are not themselves settings.

type Resolved added in v0.4.0

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

Resolved is every setting after the channels have been layered.

func Resolve added in v0.4.0

func Resolve(fs *pflag.FlagSet, opts ResolveOptions) (*Resolved, error)

Resolve layers the channels in precedence order, lowest to highest:

environment < file < flag

A channel that does not carry a setting leaves the lower layer in place. The file outranking the environment is deliberate: the file is the artifact an operator owns and reviews, so ambient state must not silently outrank it.

func (*Resolved) Bool added in v0.4.0

func (r *Resolved) Bool(key string) bool

Bool returns the resolved boolean for key.

func (*Resolved) ClusterKey added in v0.4.0

func (r *Resolved) ClusterKey() string

ClusterKey identifies the cluster a run targeted, for naming its record.

The context setting is empty for most installs: the documented deploys do not pass --context, and the cluster is then whichever one the kubeconfig already selects. Naming the record from the setting alone would put every such install in one file, where a second cluster silently replaces the first. An unset context is therefore resolved the same way the run itself resolves it.

func (*Resolved) Duration added in v0.4.0

func (r *Resolved) Duration(key string) time.Duration

Duration returns the resolved duration for key.

func (*Resolved) Int added in v0.4.0

func (r *Resolved) Int(key string) int

Int returns the resolved integer for key.

func (*Resolved) Origins added in v0.4.0

func (r *Resolved) Origins() []Value

Origins lists every setting a channel supplied, sorted by key. Used to show where the effective configuration came from.

func (*Resolved) Report added in v0.4.0

func (r *Resolved) Report(w io.Writer, opts ReportOptions)

Report writes the settings a run is about to apply and where each came from.

A value can arrive from a flag, an exported variable or a configuration file, and only the first of those is visible in the command the operator typed. Reporting on every run is what keeps an inherited variable or a forgotten file from changing an install silently. Errors name the channel too, but an install that succeeds with the wrong value never produces one.

Every setting is listed, with the channel that supplied it. A value that came from a default is worth seeing for the same reason a supplied one is: next release it may be a different default. ReportOptions.OmitDefaults shortens it to what was set.

A setting a channel mentions is set, whatever it is set to -- an empty value is a value, and is how a setting is cleared. Only an absent setting falls through to the layer below, which in the shell is the difference between "export FOO=" and "unset FOO". What an empty value means then depends on the kind: a string takes it literally, a bool reads it as false, and an int or a duration has no empty form, so it is reported as invalid rather than ignored.

func (*Resolved) Require added in v0.4.0

func (r *Resolved) Require(key string) error

Require returns a RequiredError when no channel supplied key and the setting has no default.

func (*Resolved) String added in v0.4.0

func (r *Resolved) String(key string) string

String returns the resolved string for key, or "" if the key is unknown.

func (*Resolved) Supplied added in v0.4.0

func (r *Resolved) Supplied(key string) bool

Supplied reports whether any channel set the key, as opposed to it holding its declared default.

func (*Resolved) Value added in v0.4.0

func (r *Resolved) Value(key string) (Value, bool)

Value returns the resolved value for a key. The bool is false for a key that is not in Registry, which is a programming error rather than a user one.

type Setting added in v0.4.0

type Setting struct {
	// Key is the canonical name and the path in the configuration file,
	// dot-separated: "ateapi.postgres.connectionString".
	Key string
	// Env is the environment variable that supplies this setting.
	Env string
	// Flag is the command-line name, without the leading dashes.
	Flag string
	// Kind is the value type. Resolve parses raw strings against it.
	Kind ValueKind
	// Default applies when no channel supplies a value.
	Default string
	// Secret suppresses the value wherever configuration is displayed.
	Secret bool
	// Usage is the flag help text.
	Usage string
	// Commands restricts the flag to those command paths, named as they are
	// typed: "deploy benchmarks". Empty means a persistent flag on the root.
	//
	// Only the flag channel is scoped. The environment and the file reach
	// every setting, because a configuration document describes a whole
	// install and must parse the same way whichever subcommand reads it.
	Commands []string
}

Setting declares one configurable value. It is the single definition: the flag set, the environment reader and the file schema are all projections of Registry, so a setting cannot reach one channel and miss another.

func All added in v0.4.0

func All() []Setting

All returns every setting, installer-owned and command-registered, in declaration order. The file and the environment read this, so a configuration document parses identically whichever subcommand runs.

func Lookup added in v0.4.0

func Lookup(key string) (Setting, bool)

Lookup returns the setting with the given canonical key.

func (Setting) Channels added in v0.4.0

func (s Setting) Channels() string

Channels names every way the setting can be supplied.

Errors raised where no resolved value is at hand use it, because the reader may know only one of the three: telling someone who configures by file to set an environment variable sends them to the wrong place. A setting with no flag -- a secret -- names the two it has.

type Value added in v0.4.0

type Value struct {
	Setting Setting
	Raw     string
	From    Origin
	// Supplied is false when Raw is the declared default. It distinguishes an
	// empty value a channel provided from one nobody set, which the Cloud SQL
	// instance setting depends on.
	Supplied bool
}

Value is one setting's resolved value and the channel that supplied it.

func (Value) Display added in v0.4.0

func (v Value) Display() string

Display is the value as it may be shown. A secret that something supplied reports that it is set without disclosing what to: the reader needs to know which channel to go and change, not the credential itself. One sitting on its declared default has no credential to hide, and reporting "<set>" for it would claim a credential is configured when none is.

The value is returned undelimited, because the callers delimit differently: an error quotes it with %q, and the report pads it into a column.

type ValueKind added in v0.4.0

type ValueKind int

ValueKind is the type of a setting's value.

const (
	KindString ValueKind = iota
	KindBool
	KindInt
	KindDuration
)

Jump to

Keyboard shortcuts

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