environment

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: May 14, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package environment manages disposable cluster lifecycles.

Index

Constants

This section is empty.

Variables

View Source
var AddonRegistry = map[string]Addon{
	"falco": {
		Name: "falco",
		Steps: []BootstrapStep{
			{
				Name:      "add-falco-helm-repo",
				Type:      StepShell,
				Path:      "",
				Feature:   "addon-falco",
				Args:      []string{},
				Namespace: "",
			},
			{
				Name:      "install-falco",
				Type:      StepHelmInstall,
				Release:   "falco",
				Path:      "falcosecurity/falco",
				Namespace: "falco",
				Feature:   "addon-falco",
				Args:      []string{"--create-namespace", "--set", "driver.kind=ebpf", "--set", "falcosidekick.enabled=false"},
			},
		},
	},
	"gatekeeper": {
		Name: "gatekeeper",
		Steps: []BootstrapStep{
			{
				Name:      "install-gatekeeper",
				Type:      StepHelmInstall,
				Release:   "gatekeeper",
				Path:      "gatekeeper/gatekeeper",
				Namespace: "gatekeeper-system",
				Feature:   "addon-gatekeeper",
				Args:      []string{"--create-namespace"},
			},
		},
	},
	"trivy-operator": {
		Name: "trivy-operator",
		Steps: []BootstrapStep{
			{
				Name:      "install-trivy-operator",
				Type:      StepHelmInstall,
				Release:   "trivy-operator",
				Path:      "aqua/trivy-operator",
				Namespace: "trivy-system",
				Feature:   "addon-trivy",
				Args:      []string{"--create-namespace"},
			},
		},
	},
	"cilium": {
		Name: "cilium",
		Steps: []BootstrapStep{
			{
				Name:      "install-cilium",
				Type:      StepHelmInstall,
				Release:   "cilium",
				Path:      "cilium/cilium",
				Namespace: "kube-system",
				Feature:   "addon-cilium",
				Args:      []string{"--set", "hubble.enabled=false"},
			},
		},
	},
	"calico": {
		Name: "calico",
		Steps: []BootstrapStep{
			{
				Name:    "install-calico",
				Type:    StepKubectlApply,
				Path:    "https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/calico.yaml",
				Feature: "addon-calico",
			},
		},
	},
}

AddonRegistry maps addon names to their installation steps. Profile-based addons (argocd, aws-localstack) are realized through checked-in profile hooks in profiles/<name>/*.sh, not through this registry.

Functions

func AddHelmRepos

func AddHelmRepos(ctx context.Context, runner CommandRunner) error

AddHelmRepos ensures the Helm repositories needed by the registered addons are available. Call this once before running addon bootstrap steps.

func BuildKindConfig

func BuildKindConfig(k8s scenario.KubernetesConfig) string

BuildKindConfig generates a kind cluster config YAML from KubernetesConfig. Returns empty string when no special configuration is needed.

Types

type Addon

type Addon struct {
	Name  string
	Steps []BootstrapStep
}

Addon describes a cluster addon that can be installed via bootstrap.

type AssetResolver

type AssetResolver struct {
	RootDir string
}

AssetResolver maps a provider and execution profile to filesystem paths under a checked-in asset tree. RootDir must be the repository root containing the clusters/ and profiles/ directories.

func (AssetResolver) Resolve

func (r AssetResolver) Resolve(provider string, profile scenario.ExecutionProfile) (ProfileAssets, error)

Resolve returns the asset paths for the given provider and profile. It requires clusters/<provider>/<profile>.yaml to exist. For non-default profiles it also requires profiles/<profile>/install.sh to exist. Healthcheck and cleanup scripts are optional.

type BootstrapPlan

type BootstrapPlan struct {
	Steps []BootstrapStep
}

BootstrapPlan is an ordered list of bootstrap steps.

func DefaultBootstrapPlan

func DefaultBootstrapPlan() *BootstrapPlan

DefaultBootstrapPlan returns the common bootstrap plan shared by all scenarios.

func (*BootstrapPlan) Requires

func (p *BootstrapPlan) Requires(feature string) bool

Requires returns true if the plan includes a step with the given feature.

type BootstrapStep

type BootstrapStep struct {
	Name      string
	Type      StepType
	Path      string
	Feature   string
	Release   string
	Namespace string
	Duration  string
	Args      []string
}

BootstrapStep describes a single bootstrap action.

func AddonSteps

func AddonSteps(cni string, addons []string) ([]BootstrapStep, []string)

AddonSteps returns the bootstrap steps needed to install the requested addons and CNI. Unknown addon names are returned as warnings.

func (*BootstrapStep) CommandArgs

func (s *BootstrapStep) CommandArgs(kubeconfigPath string) []string

CommandArgs returns the shell command arguments for this step.

type Bootstrapper

type Bootstrapper struct {
	Runner CommandRunner
}

Bootstrapper executes a bootstrap plan against a cluster.

func NewBootstrapper

func NewBootstrapper(runner CommandRunner) *Bootstrapper

NewBootstrapper returns a Bootstrapper with the given runner.

func (*Bootstrapper) Execute

func (b *Bootstrapper) Execute(ctx context.Context, plan *BootstrapPlan, kubeconfigPath string) error

Execute runs all steps in the plan sequentially.

type ClusterLifecycle

type ClusterLifecycle interface {
	// Provisioning — ClusterSpec carries either a checked-in config file path
	// or legacy KubernetesConfig for backward compatibility.
	// When spec is zero-valued, creates a plain cluster.
	Create(ctx context.Context, clusterName string, spec ClusterSpec) (*Handle, error)
	Destroy(ctx context.Context, handle *Handle) error
	Recreate(ctx context.Context, clusterName string, spec ClusterSpec) (*Handle, error)

	// Health
	HealthCheck(ctx context.Context, kubeconfigPath string) error

	// Namespace lifecycle
	ForceDeleteNamespace(ctx context.Context, kubeconfigPath, ns string) error
	CreateNamespace(ctx context.Context, kubeconfigPath, ns string) error

	// Scheduling verification
	RunCanary(ctx context.Context, kubeconfigPath, ns string) error
}

ClusterLifecycle is the full contract for cluster management. Kind, k3d, remote clusters — all implement this interface.

type ClusterSpec

type ClusterSpec struct {
	// Profile is the execution profile that triggered this cluster creation.
	Profile scenario.ExecutionProfile

	// ConfigPath is the absolute path to a checked-in provider config file
	// (e.g. clusters/kind/default.yaml). When set, the provider uses this
	// file directly instead of generating configuration from Go code.
	ConfigPath string

	// LegacyKubernetes holds the old-style KubernetesConfig from scenario
	// YAML. Used as a fallback when ConfigPath is empty.
	LegacyKubernetes scenario.KubernetesConfig
}

ClusterSpec describes what cluster to create. Providers check ConfigPath first (checked-in asset file), then fall back to LegacyKubernetes (generated config from scenario YAML).

type CommandRunner

type CommandRunner interface {
	Run(ctx context.Context, cmd *exec.Cmd) ([]byte, error)
}

CommandRunner executes shell commands. Extracted for testing.

type ExecRunner

type ExecRunner struct{}

ExecRunner runs commands via os/exec.

func (*ExecRunner) Run

func (r *ExecRunner) Run(ctx context.Context, cmd *exec.Cmd) ([]byte, error)

Run executes cmd and returns combined output.

type Handle

type Handle struct {
	ClusterName    string
	KubeconfigPath string
}

Handle holds references to a provisioned environment.

type K3dProvider

type K3dProvider struct {
	ReuseExisting bool
	// contains filtered or unexported fields
}

K3dProvider manages k3d cluster lifecycles.

func NewK3dProvider

func NewK3dProvider() *K3dProvider

NewK3dProvider returns a K3dProvider with the default command runner.

func (*K3dProvider) Create

func (p *K3dProvider) Create(ctx context.Context, clusterName string, spec ClusterSpec) (*Handle, error)

Create provisions a new k3d cluster and writes a kubeconfig file. When spec.ConfigPath is set, uses the checked-in config file. Otherwise, creates a plain cluster (LegacyKubernetes options are not supported by k3d and are logged as warnings).

func (*K3dProvider) CreateNamespace

func (k *K3dProvider) CreateNamespace(ctx context.Context, kubeconfigPath, ns string) error

CreateNamespace creates a namespace, ignoring "already exists" errors.

func (*K3dProvider) Destroy

func (p *K3dProvider) Destroy(ctx context.Context, handle *Handle) error

Destroy tears down the k3d cluster and removes the kubeconfig file.

func (*K3dProvider) ForceDeleteNamespace

func (k *K3dProvider) ForceDeleteNamespace(ctx context.Context, kubeconfigPath, ns string) error

ForceDeleteNamespace force-deletes a namespace and waits for removal.

func (*K3dProvider) HealthCheck

func (k *K3dProvider) HealthCheck(ctx context.Context, kubeconfigPath string) error

HealthCheck verifies node conditions (pressure, readiness) and checks for stuck pods.

func (*K3dProvider) Recreate

func (p *K3dProvider) Recreate(ctx context.Context, clusterName string, spec ClusterSpec) (*Handle, error)

Recreate tears down and re-creates the k3d cluster.

func (*K3dProvider) RunCanary

func (k *K3dProvider) RunCanary(ctx context.Context, kubeconfigPath, ns string) error

RunCanary runs a lightweight pod to verify scheduling works.

type KindProvider

type KindProvider struct {
	ReuseExisting bool
	// contains filtered or unexported fields
}

KindProvider manages kind cluster lifecycles.

func NewKindProvider

func NewKindProvider() *KindProvider

NewKindProvider returns a KindProvider with the default command runner.

func (*KindProvider) Create

func (p *KindProvider) Create(ctx context.Context, clusterName string, spec ClusterSpec) (*Handle, error)

Create provisions a kind cluster. When spec.ConfigPath is set, the checked-in config file is used directly. Otherwise, falls back to generating a config from spec.LegacyKubernetes.

func (*KindProvider) CreateNamespace

func (k *KindProvider) CreateNamespace(ctx context.Context, kubeconfigPath, ns string) error

CreateNamespace creates a namespace, ignoring "already exists" errors.

func (*KindProvider) Destroy

func (p *KindProvider) Destroy(ctx context.Context, handle *Handle) error

Destroy tears down the kind cluster and removes the kubeconfig file.

func (*KindProvider) ForceDeleteNamespace

func (k *KindProvider) ForceDeleteNamespace(ctx context.Context, kubeconfigPath, ns string) error

ForceDeleteNamespace force-deletes a namespace and waits for removal.

func (*KindProvider) HealthCheck

func (k *KindProvider) HealthCheck(ctx context.Context, kubeconfigPath string) error

HealthCheck verifies node conditions (pressure, readiness) and checks for stuck pods.

func (*KindProvider) Recreate

func (p *KindProvider) Recreate(ctx context.Context, clusterName string, spec ClusterSpec) (*Handle, error)

Recreate destroys and recreates a kind cluster from scratch.

func (*KindProvider) RunCanary

func (k *KindProvider) RunCanary(ctx context.Context, kubeconfigPath, ns string) error

RunCanary runs a lightweight pod to verify scheduling works.

type Lease

type Lease struct {
	Profile        scenario.ExecutionProfile
	KubeconfigPath string
	ExtraEnv       []string
	Provider       ClusterLifecycle
	Shared         bool
	// contains filtered or unexported fields
}

Lease represents an acquired environment ready for scenario execution. Call Release when done to clean up the underlying resources (run profile cleanup hooks, destroy cluster, etc.).

func (*Lease) Release

func (l *Lease) Release(ctx context.Context) error

Release frees all resources held by this lease.

type LocalProvisioner

type LocalProvisioner struct {
	Providers map[string]ClusterLifecycle
	Runner    CommandRunner
	Assets    AssetResolver
	Profiles  *ProfileRunner
}

LocalProvisioner creates cluster leases using local ClusterLifecycle providers and runs profile hooks (install, healthcheck, cleanup) from checked-in assets.

func NewLocalProvisioner

func NewLocalProvisioner(providers map[string]ClusterLifecycle, runner CommandRunner, assetsRoot string) *LocalProvisioner

NewLocalProvisioner returns a LocalProvisioner with the given providers, runner, and asset root directory. The assetsRoot is the repository root containing the clusters/ and profiles/ directories.

func (*LocalProvisioner) Acquire

func (p *LocalProvisioner) Acquire(ctx context.Context, req ProvisionRequest) (*Lease, error)

Acquire provisions an environment matching the requested profile and returns a lease. The caller must call Lease.Release when done.

func (*LocalProvisioner) Recreate

func (p *LocalProvisioner) Recreate(ctx context.Context, req ProvisionRequest) (*Lease, error)

Recreate refreshes the requested environment. Owned clusters are recreated through the provider; external kubeconfigs keep the same cluster and rerun profile setup only.

type ProfileAssets

type ProfileAssets struct {
	// ClusterConfigPath is the provider-specific cluster configuration file.
	ClusterConfigPath string

	// ProfileDir is the root of the profile's hook directory.
	ProfileDir string

	// InstallScript is the path to install.sh, empty for the default profile.
	InstallScript string

	// HealthcheckScript is the path to healthcheck.sh, empty if not present.
	HealthcheckScript string

	// CleanupScript is the path to cleanup.sh, empty if not present.
	CleanupScript string
}

ProfileAssets holds resolved filesystem paths for a provider+profile combination. All paths are absolute so downstream code does not depend on working directory.

type ProfileRunRequest

type ProfileRunRequest struct {
	Assets      ProfileAssets
	Profile     scenario.ExecutionProfile
	Provider    string
	ClusterName string
	Kubeconfig  string
	ExtraEnv    map[string]string // additional env vars (e.g., BENCH_LOCALSTACK_SERVICES)
}

ProfileRunRequest describes the inputs for preparing a profile.

type ProfileRunResult

type ProfileRunResult struct {
	// ExtraEnv contains KEY=VALUE strings parsed from lease.env.
	ExtraEnv []string

	// Release runs cleanup.sh (best-effort) and removes the work directory.
	// It is safe to call multiple times; only the first call takes effect.
	Release func(context.Context) error
}

ProfileRunResult holds the output of a successful profile preparation.

type ProfileRunner

type ProfileRunner struct{}

ProfileRunner executes profile lifecycle hooks (install, healthcheck, cleanup) and parses lease.env output produced by install scripts.

func (*ProfileRunner) Prepare

Prepare creates a temporary work directory, runs install.sh then healthcheck.sh, parses lease.env from the work directory, and returns a result whose Release function will run cleanup.sh and remove the work directory.

On install or healthcheck failure, best-effort cleanup runs before returning the error.

type ProvisionRequest

type ProvisionRequest struct {
	Scenario           *scenario.Scenario
	Profile            scenario.ExecutionProfile
	ProviderName       string
	ClusterName        string
	ReuseCluster       bool
	ExistingKubeconfig string
	Shared             bool
}

ProvisionRequest describes what the caller needs from the provisioner.

type Provisioner

type Provisioner interface {
	Acquire(ctx context.Context, req ProvisionRequest) (*Lease, error)
}

Provisioner acquires environment leases for scenario execution.

type StepType

type StepType string

StepType identifies the kind of bootstrap action.

const (
	StepKubectlApply  StepType = "kubectl-apply"
	StepKubectlCreate StepType = "kubectl-create"
	StepKubectl       StepType = "kubectl"
	StepHelmInstall   StepType = "helm-install"
	StepShell         StepType = "shell"
	StepSleep         StepType = "sleep"
)

Jump to

Keyboard shortcuts

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