config package - github.com/nebari-dev/nebari-infrastructure-core/pkg/config - Go Packages

config

package
v0.14.0 Latest Latest
Warning

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

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

Documentation

Index

Constants

View Source
const (
	// CertificateTypeSelfSigned mints a cert via cert-manager's self-signed ClusterIssuer.
	CertificateTypeSelfSigned = "selfsigned"
	// CertificateTypeLetsEncrypt mints a cert via cert-manager's ACME (Let's Encrypt) ClusterIssuer.
	CertificateTypeLetsEncrypt = "letsencrypt"
	// CertificateTypeExisting uses a user-supplied TLS certificate instead of cert-manager.
	CertificateTypeExisting = "existing"

	// DefaultGatewayTLSSecretName is the default name of the TLS secret the gateway references.
	// The cert is the gateway's, shared across argocd / keycloak / the apex domain.
	DefaultGatewayTLSSecretName = "nebari-gateway-tls"
	// DefaultGatewayTLSNamespace is the namespace the gateway expects its TLS secret in.
	DefaultGatewayTLSNamespace = "envoy-gateway-system"
)

Certificate type values accepted in CertificateConfig.Type.

View Source
const PlaceholderValue = "CHANGEME"

PlaceholderValue is the literal sentinel that marks an unfilled config value. Any scalar value or mapping key whose text contains this token (case-sensitive) is treated as a placeholder and rejected before any provider API call.

A literal sentinel is used, rather than pattern-matching values like "example.com", so the check is explicit and greppable and never rejects a user who legitimately owns such a value. Example and starter configs must use this exact token wherever the reader is expected to substitute their own value.

Variables

This section is empty.

Functions

func CheckPlaceholders added in v0.14.0

func CheckPlaceholders(raw []byte) error

CheckPlaceholders scans the raw YAML config for the CHANGEME sentinel and returns a *PlaceholderError naming every offending field, or nil if none are found.

It walks the parsed YAML node tree (not the Go struct) so the check is independent of NebariConfig's fields: it covers provider blocks, nested maps, sequences, and — unlike a struct walk — mapping KEYS. Only scalar values (including the contents of "|" and ">" block scalars) and mapping keys are inspected; YAML comments are never scanned, so a CHANGEME inside a "#" comment does not trip the check. A "#" line inside a block scalar is content, not a comment, and is scanned like any other value.

The check is intended for the validate and deploy paths only. It is not part of NebariConfig.Validate, so destroy/kubeconfig (which only need a parseable config) are not gated on it.

A malformed document is reported as a parse error rather than as a silent "no placeholders" result, so a caller that passes unparsed bytes cannot read garbage as clean. At the call sites in pkg/nic this cannot fire: they scan the bytes the config was parsed from, retained by the parser, so the scanned and parsed documents are the same bytes rather than two reads of one path.

func DefaultLocalRepositoryPath added in v0.13.0

func DefaultLocalRepositoryPath(projectName string) string

DefaultLocalRepositoryPath returns the host directory NIC manages for a project's local GitOps repository when the local repository provider is used without an explicit path. It lives under the user's home directory so the repository is durable and stays on host paths that kind/Docker Desktop can mount reliably.

func UnmarshalProviderConfig

func UnmarshalProviderConfig(ctx context.Context, providerConfig any, target any) error

UnmarshalProviderConfig converts the any provider config to a concrete type. The target parameter should be a pointer to the provider-specific config struct. This function re-marshals and unmarshals to handle the type conversion properly.

Types

type ACMEConfig

type ACMEConfig struct {
	// Email is the email address for Let's Encrypt registration
	Email string `yaml:"email"`

	// Server is the ACME server URL (defaults to Let's Encrypt production)
	// Use "https://acme-staging-v02.api.letsencrypt.org/directory" for testing
	Server string `yaml:"server,omitempty"`
}

ACMEConfig holds ACME (Let's Encrypt) configuration

type AzureBackupTarget added in v0.11.0

type AzureBackupTarget struct {
	Container       string `yaml:"container"`
	StorageAccount  string `yaml:"storage_account"`
	Prefix          string `yaml:"prefix,omitempty"`
	CreateContainer bool   `yaml:"create_container,omitempty"`
	RetainOnDestroy *bool  `yaml:"retain_on_destroy,omitempty"`
	Endpoint        string `yaml:"endpoint,omitempty"`
	AccountNameEnv  string `yaml:"account_name_env"`
	AccountKeyEnv   string `yaml:"account_key_env"`
}

AzureBackupTarget configures a Longhorn-native azblob:// backup target.

func (*AzureBackupTarget) RetainOnDestroyEnabled added in v0.11.0

func (t *AzureBackupTarget) RetainOnDestroyEnabled() bool

RetainOnDestroyEnabled defaults to true for an Azure target.

type BackupSchedules added in v0.11.0

type BackupSchedules struct {
	Snapshot ScheduleConfig `yaml:"snapshot"`
	Backup   ScheduleConfig `yaml:"backup"`
}

BackupSchedules holds the two RecurringJob schedules.

type BackupsConfig added in v0.11.0

type BackupsConfig struct {
	Longhorn *LonghornBackupConfig `yaml:"longhorn,omitempty"`
}

BackupsConfig is the top-level `backups:` block. Today it only carries Longhorn backup configuration, but the block exists to group future backup concerns under one key.

func (*BackupsConfig) LonghornConfig added in v0.11.0

func (c *BackupsConfig) LonghornConfig() *LonghornBackupConfig

LonghornConfig returns the nested Longhorn config, nil-safe.

func (*BackupsConfig) LonghornEnabled added in v0.11.0

func (c *BackupsConfig) LonghornEnabled() bool

LonghornEnabled reports whether Longhorn backups should be configured. A nil BackupsConfig or nil Longhorn block is disabled (backups are opt-in).

func (*BackupsConfig) Validate added in v0.11.0

func (c *BackupsConfig) Validate(providerName string) error

Validate checks the backups block. nil-safe: a nil BackupsConfig (or disabled Longhorn block) validates clean. providerName is the selected cluster provider.

type CACertRef added in v0.11.0

type CACertRef struct {
	Kind      string `yaml:"kind"` // "secret" | "configmap"
	Name      string `yaml:"name"`
	Namespace string `yaml:"namespace,omitempty"`
	Key       string `yaml:"key"`
}

CACertRef references a pre-existing Secret or ConfigMap key holding a PEM CA bundle. NIC reads it at deploy time and injects it as the AWS_CERT key.

type CertEnv added in v0.8.0

type CertEnv struct {
	CertEnv string `yaml:"cert_env"`
	KeyEnv  string `yaml:"key_env"`
}

CertEnv names environment variables holding raw (non-base64) PEM material.

type CertFiles added in v0.8.0

type CertFiles struct {
	CertFile string `yaml:"cert_file"`
	KeyFile  string `yaml:"key_file"`
}

CertFiles points at PEM cert/key files on disk.

type CertificateConfig

type CertificateConfig struct {
	// Type is the certificate type: "selfsigned", "letsencrypt", or "existing"
	Type string `yaml:"type,omitempty"`

	// ACME configuration for Let's Encrypt
	ACME *ACMEConfig `yaml:"acme,omitempty"`

	// SecretName overrides the name of the TLS secret the gateway references.
	// Defaults to "nebari-gateway-tls". For type=existing with existing_secret,
	// the gateway references ExistingSecret.Name instead.
	SecretName string `yaml:"secret_name,omitempty"`

	// ExistingSecret references a kubernetes.io/tls secret the user already created.
	// Mutually exclusive with Files and Env. Only valid when Type=existing.
	ExistingSecret *ExistingSecretRef `yaml:"existing_secret,omitempty"`

	// Files reads PEM material from disk; NIC creates the secret directly.
	// Mutually exclusive with ExistingSecret and Env. Only valid when Type=existing.
	Files *CertFiles `yaml:"files,omitempty"`

	// Env reads raw PEM material from environment variables; NIC creates the secret directly.
	// Mutually exclusive with ExistingSecret and Files. Only valid when Type=existing.
	Env *CertEnv `yaml:"env,omitempty"`
}

CertificateConfig holds TLS certificate configuration

func (*CertificateConfig) GatewaySecretRef added in v0.8.0

func (c *CertificateConfig) GatewaySecretRef() (name, namespace string)

GatewaySecretRef returns the (name, namespace) the gateway listener should reference. For existing_secret it points at the user's secret; otherwise it is ResolvedSecretName in DefaultGatewayTLSNamespace.

func (*CertificateConfig) IsCrossNamespaceSecret added in v0.8.0

func (c *CertificateConfig) IsCrossNamespaceSecret() bool

IsCrossNamespaceSecret reports whether the gateway references a TLS secret in a namespace other than DefaultGatewayTLSNamespace, which requires a ReferenceGrant.

func (*CertificateConfig) ResolvedSecretName added in v0.8.0

func (c *CertificateConfig) ResolvedSecretName() string

ResolvedSecretName returns the name of the TLS secret NIC creates (files/env sources) or, for selfsigned/letsencrypt, the cert-manager secret name. Defaults to DefaultGatewayTLSSecretName.

func (*CertificateConfig) Validate added in v0.8.0

func (c *CertificateConfig) Validate() error

Validate checks the certificate configuration. A nil receiver is valid (no certificate block configured).

type ClusterConfig added in v0.2.0

type ClusterConfig struct {
	// Providers captures the provider name as key and its config as value.
	Providers map[string]any `yaml:",inline"`
}

ClusterConfig holds typed cloud provider configuration. The provider name is the map key, the provider config is the map value. Example YAML:

cluster:
  aws:
    region: us-west-2

func (*ClusterConfig) ProviderConfig added in v0.2.0

func (c *ClusterConfig) ProviderConfig() map[string]any

ProviderConfig returns the cluster provider config as a map. Returns nil if no provider is configured or the value is not a map. Precondition: Validate() ensures exactly one entry in the map.

func (*ClusterConfig) ProviderName added in v0.2.0

func (c *ClusterConfig) ProviderName() string

ProviderName returns the name of the configured cluster provider, or an empty string if none is configured. Precondition: Validate() ensures exactly one entry in the map.

func (*ClusterConfig) Validate added in v0.2.0

func (c *ClusterConfig) Validate(validProviders []string) error

Validate checks that exactly one valid cluster provider is configured. When validProviders is non-empty, the provider name is checked against the list.

type DNSConfig

type DNSConfig struct {
	// Providers captures the provider name as key and its config as value.
	Providers map[string]any `yaml:",inline"`
}

DNSConfig holds typed DNS provider configuration. The provider name is the map key, the provider config is the map value. Example YAML:

dns:
  cloudflare:
    zone_name: example.com

func (*DNSConfig) ProviderConfig

func (d *DNSConfig) ProviderConfig() map[string]any

ProviderConfig returns the DNS provider config as a map. Returns nil if no provider is configured or the value is not a map. Precondition: Validate() ensures exactly one entry in the map.

func (*DNSConfig) ProviderName

func (d *DNSConfig) ProviderName() string

ProviderName returns the name of the configured DNS provider, or an empty string if none is configured. Precondition: Validate() ensures exactly one entry in the map.

func (*DNSConfig) Validate

func (d *DNSConfig) Validate(validProviders []string) error

Validate checks that exactly one valid DNS provider is configured. When validProviders is non-empty, the provider name is checked against the list.

type ExistingSecretRef added in v0.8.0

type ExistingSecretRef struct {
	// Name is the secret name (required).
	Name string `yaml:"name"`
	// Namespace is the secret's namespace. Defaults to envoy-gateway-system.
	Namespace string `yaml:"namespace,omitempty"`
}

ExistingSecretRef references a pre-existing TLS secret.

type LonghornBackupConfig added in v0.11.0

type LonghornBackupConfig struct {
	Enabled *bool              `yaml:"enabled,omitempty"`
	S3      *S3BackupTarget    `yaml:"s3,omitempty"`
	Azure   *AzureBackupTarget `yaml:"azure,omitempty"`

	// AllowRecurringJobWhileVolumeDetached maps to the cluster-wide Longhorn
	// Setting. nil defaults to true (the pack's behaviour): JupyterHub user PVCs
	// detach when servers idle out, and Longhorn's stock default of false would
	// silently skip them at the cron tick.
	AllowRecurringJobWhileVolumeDetached *bool `yaml:"allow_recurring_job_while_volume_detached,omitempty"`

	Schedules BackupSchedules `yaml:"schedules,omitempty"`
}

LonghornBackupConfig drives the Longhorn snapshot/backup schedules, the cluster Setting, and the S3/azblob BackupTarget + credential Secret. Exactly one of S3 / Azure may be set when Enabled.

func (*LonghornBackupConfig) AllowDetached added in v0.11.0

func (c *LonghornBackupConfig) AllowDetached() bool

AllowDetached returns the effective allow-recurring-job-while-volume-detached value, defaulting to true.

func (*LonghornBackupConfig) BackupTargetURL added in v0.11.0

func (c *LonghornBackupConfig) BackupTargetURL() string

BackupTargetURL builds the Longhorn backupTargetURL for the configured target.

  • S3: s3://<bucket>@<region>/<prefix>
  • azblob: azblob://<container>@core.windows.net/<prefix>

Returns "" when no target is set.

func (*LonghornBackupConfig) IsEnabled added in v0.11.0

func (c *LonghornBackupConfig) IsEnabled() bool

IsEnabled reports whether this Longhorn backup block is enabled. Unlike the install-side longhorn.Config (which defaults nil-Enabled to true), backups are opt-in: a present block with no `enabled` defaults to true, but a nil block is off (handled by BackupsConfig.LonghornEnabled).

func (*LonghornBackupConfig) Validate added in v0.11.0

func (c *LonghornBackupConfig) Validate(providerName string) error

Validate checks a single Longhorn backup block. Assumes the block is enabled.

type NebariConfig

type NebariConfig struct {
	ProjectName string `yaml:"project_name"`
	Domain      string `yaml:"domain,omitempty"`

	// Cluster Provider configuration.
	// Only one provider can be configured at a time.
	Cluster *ClusterConfig `yaml:"cluster,omitempty"`

	// DNS provider configuration (optional).
	// Only one provider can be configured at a time.
	DNS *DNSConfig `yaml:"dns,omitempty"`

	// Repository configures the GitOps repository provider.
	// Only one provider can be configured at a time.
	Repository *RepositoryConfig `yaml:"repository,omitempty"`

	// Certificate configuration (optional)
	Certificate *CertificateConfig `yaml:"certificate,omitempty"`

	// TrustBundle, when set, propagates an enterprise CA bundle both to worker-node
	// OS trust stores (via the cluster provider) and into the cluster via
	// trust-manager. Required when egress is TLS-inspected by a corporate proxy.
	TrustBundle *TrustBundleConfig `yaml:"trust_bundle,omitempty"`

	// Backups configures off-cluster backup scheduling (Longhorn). Optional.
	Backups *BackupsConfig `yaml:"backups,omitempty"`
	// contains filtered or unexported fields
}

NebariConfig represents the parsed nebari-config.yaml structure

func ParseConfig

func ParseConfig(ctx context.Context, filePath string) (*NebariConfig, error)

ParseConfig reads and parses a nebari-config.yaml file. This is a convenience wrapper around ParseConfigBytes that handles file I/O.

func ParseConfigBytes

func ParseConfigBytes(data []byte) (*NebariConfig, error)

ParseConfigBytes parses YAML configuration from bytes. This is the core parsing logic, separated from file I/O for testability. Call Validate on the returned config to check for semantic errors.

The source bytes are retained on the returned config so checks that must read the original document still run for this entrypoint. Without that, a caller parsing bytes directly and then deploying would silently skip placeholder rejection: the gate treats an absent source as "no YAML to scan" and returns nil, which is right for a config built in Go but wrong for one parsed here. There is no path to record, so such an error names the fields but not a file.

func (*NebariConfig) SourcePath added in v0.14.0

func (c *NebariConfig) SourcePath() string

SourcePath returns the file this config was parsed from, or "" when it was not parsed from a file.

func (*NebariConfig) SourceRaw added in v0.14.0

func (c *NebariConfig) SourceRaw() []byte

SourceRaw returns the original YAML this config was parsed from, or nil when it was not parsed from YAML. Callers must treat it as read-only.

func (*NebariConfig) Validate

func (c *NebariConfig) Validate(opts ValidateOptions) error

Validate checks that the configuration is valid. The opts parameter provides the set of valid provider names, injected by the caller. Returns an error describing the first validation failure encountered.

type PlaceholderError added in v0.14.0

type PlaceholderError struct {
	// FieldPaths is the sorted set of offending paths. It always has at least
	// one entry.
	FieldPaths []string
}

PlaceholderError reports that a config still holds the CHANGEME placeholder. FieldPaths lists every dotted path (built from mapping keys and sequence indices) whose scalar value or key contains the sentinel, e.g. "cluster.aws.region" or "cluster.aws.node_groups.CHANGEME". Callers that know the config file path (pkg/nic, which reads it off the parsed config) wrap this so the user sees both the fields and the file.

func (*PlaceholderError) Error added in v0.14.0

func (e *PlaceholderError) Error() string

type RepositoryConfig added in v0.13.0

type RepositoryConfig struct {
	// Providers captures the provider name as key and its config as value.
	Providers map[string]any `yaml:",inline"`
}

RepositoryConfig holds typed GitOps repository provider configuration. The provider name is the map key, the provider config is the map value. Example YAML:

repository:
  existing:
    url: "git@github.com:my-org/my-gitops-repo.git"
    branch: main

func (*RepositoryConfig) ProviderConfig added in v0.13.0

func (r *RepositoryConfig) ProviderConfig() map[string]any

ProviderConfig returns the repository provider config as a map. Returns nil if no provider is configured or the value is not a map. Precondition: Validate() ensures exactly one entry in the map.

func (*RepositoryConfig) ProviderName added in v0.13.0

func (r *RepositoryConfig) ProviderName() string

ProviderName returns the name of the configured repository provider, or an empty string if none is configured. Precondition: Validate() ensures exactly one entry in the map.

func (*RepositoryConfig) Validate added in v0.13.0

func (r *RepositoryConfig) Validate(validProviders []string) error

Validate checks that exactly one valid repository provider is configured. When validProviders is non-empty, the provider name is checked against the list.

type S3BackupTarget added in v0.11.0

type S3BackupTarget struct {
	Bucket             string     `yaml:"bucket"`
	Region             string     `yaml:"region"`
	Prefix             string     `yaml:"prefix,omitempty"`
	CreateBucket       bool       `yaml:"create_bucket,omitempty"`
	RetainOnDestroy    *bool      `yaml:"retain_on_destroy,omitempty"`
	Endpoint           string     `yaml:"endpoint,omitempty"`
	VirtualHostedStyle bool       `yaml:"virtual_hosted_style,omitempty"`
	AccessKeyIDEnv     string     `yaml:"access_key_id_env"`
	SecretAccessKeyEnv string     `yaml:"secret_access_key_env"`
	CACert             *CACertRef `yaml:"ca_cert,omitempty"`
}

S3BackupTarget configures an AWS-native or S3-compatible backup target.

func (*S3BackupTarget) PodIdentityAuth added in v0.11.0

func (t *S3BackupTarget) PodIdentityAuth(providerName string) bool

PodIdentityAuth reports whether this S3 target uses keyless IAM-role authentication (EKS Pod Identity) rather than static access keys. That path applies only to a native AWS S3 target — the aws provider with no custom endpoint — when neither credential env var is set. In that case NIC omits the AWS keys from the Longhorn credential Secret and provisions a Pod Identity association for Longhorn's service account so its AWS SDK resolves creds from the cluster role.

func (*S3BackupTarget) RetainOnDestroyEnabled added in v0.11.0

func (t *S3BackupTarget) RetainOnDestroyEnabled() bool

RetainOnDestroyEnabled defaults to true for an S3 target.

type ScheduleConfig added in v0.11.0

type ScheduleConfig struct {
	Cron        string `yaml:"cron"`
	Retain      int    `yaml:"retain"`
	Concurrency int    `yaml:"concurrency"`
}

ScheduleConfig is one RecurringJob's cron/retain/concurrency.

type TrustBundleConfig added in v0.9.0

type TrustBundleConfig struct {
	Path   string `yaml:"path,omitempty"`
	Inline string `yaml:"inline,omitempty"`
}

TrustBundleConfig specifies the source of an extra CA bundle. Exactly one of Path or Inline must be set. Path is a filesystem path to a PEM file on the operator's machine; Inline is the PEM text itself.

When set at the top level of NebariConfig, the bundle is propagated both to worker-node OS trust stores (via the cluster provider) and into the cluster via trust-manager (the in-pod half of the trust-bundle propagation).

func (*TrustBundleConfig) ResolveBase64 added in v0.9.0

func (t *TrustBundleConfig) ResolveBase64() (string, error)

ResolveBase64 returns the configured CA bundle as a base64-encoded PEM string, suitable for passing straight to the terraform-aws-eks-cluster module's extra_ca_bundle input. Returns an empty string when the bundle is unset.

func (*TrustBundleConfig) ResolvePEM added in v0.9.0

func (t *TrustBundleConfig) ResolvePEM() (string, error)

ResolvePEM returns the configured CA bundle as raw PEM text. Returns an empty string when the bundle is unset.

func (*TrustBundleConfig) Validate added in v0.9.0

func (t *TrustBundleConfig) Validate() error

Validate performs structural checks only and never touches disk, so it is safe in environments where a path:-based PEM isn't present (CI, config linting). It enforces mutual exclusion of path/inline and, for inline values (which are available without I/O), the PEM-marker checks. The file read and the same PEM-marker checks for path:-based bundles happen later at resolve time (ResolvePEM/ResolveBase64), called during deploy and destroy.

type ValidateOptions added in v0.2.0

type ValidateOptions struct {
	ClusterProviders    []string
	DNSProviders        []string
	RepositoryProviders []string
}

ValidateOptions configures validation behavior. Provider lists are injected by the caller (typically from a registry) to keep the config package decoupled from provider implementations.

Jump to

Keyboard shortcuts

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