manifest

package
v0.0.0-...-a5a3bde Latest Latest
Warning

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

Go to latest
Published: Sep 1, 2025 License: Apache-2.0 Imports: 21 Imported by: 0

Documentation

Overview

Package manifest provides functions for parsing and manipulating manifest files.

Package manifest provides functions for parsing and manipulating manifest files. This package includes functionality for applying default values from JSON schemas to manifest structures, with support for caching and type conversion.

The package uses github.com/go-viper/mapstructure for robust type conversion between map[string]any (from JSON/YAML) and strongly-typed Go structs, which provides better error handling, type safety, and maintainability compared to manual reflection-based conversion.

Default Value Application

The package supports sophisticated default value application including:

  • Schema-based defaults from JSON Schema definitions
  • Pattern-based defaults for dynamic component names
  • Environment-specific placeholder substitution
  • Resource preset resolution

Usage Examples

Basic manifest creation with defaults:

manifest, err := CreateManifestWithDefaults("my-project", "v1-alpha.1")
if err != nil {
	log.Fatal(err)
}

Applying defaults to existing manifest:

manifest := &Manifest{
	ApiVersion: "v1-alpha.1",
	Project:    "my-project",
	Components: map[string]Component{
		"web": {Image: "nginx:latest"},
	},
}
err := FillManifestWithDefaults(manifest, "v1-alpha.1")
// web component now has default role="service", kind="stateless", port=8080

Extracting schema defaults:

defaults, err := GetDefaultValues("v1-alpha.1", schema.SchemaTypeManifest)
// defaults["components.[^[a-zA-Z0-9_-]+$].role"] = "service"
// defaults["components.[^[a-zA-Z0-9_-]+$].port"] = 8080

Package manifest provides functions for parsing and manipulating manifest files.

Package manifest provides functions for parsing and manipulating manifest files.

Package manifest provides functions for parsing and manipulating manifest files.

Package manifest provides functions for parsing and manipulating manifest files.

Package manifest provides functions for parsing and manipulating manifest files.

Package manifest provides functions for parsing and manipulating manifest files.

Index

Constants

View Source
const (
	// DefaultManifestPath is the default path for the Deployah manifest file
	DefaultManifestPath = "deployah.yaml"

	// DefaultEnvFile is the default environment file name
	DefaultEnvFile = ".env"

	// DefaultConfigFile is the default configuration file name
	DefaultConfigFile = "config.yaml"

	// DeployahConfigDir is the default directory for Deployah-specific files
	DeployahConfigDir = ".deployah"

	// EnvFilePrefix is the prefix for environment-specific files
	EnvFilePrefix = ".env."

	// ConfigFilePrefix is the prefix for environment-specific config files
	ConfigFilePrefix = "config."

	// ConfigFileSuffix is the suffix for configuration files
	ConfigFileSuffix = ".yaml"
)

File and Path Constants

View Source
const (
	// EnvVarPrefix is the prefix for Deployah-specific environment variables
	EnvVarPrefix = "DPY_VAR_"

	// LogLevelEnvVar is the environment variable for log level override
	LogLevelEnvVar = "DPY_LOG_LEVEL"
)

Environment Variables

View Source
const (
	// MaxComponentNameLength is the maximum allowed length for component names
	MaxComponentNameLength = 63

	// MaxProjectNameLength is the maximum allowed length for project names
	MaxProjectNameLength = 63

	// MaxEnvironmentNameLength is the maximum allowed length for environment names
	MaxEnvironmentNameLength = 63

	// ComponentNamePattern is the regex pattern for valid component names
	ComponentNamePattern = "^[a-zA-Z0-9_-]+$"

	// ProjectNamePattern is the regex pattern for valid project names
	ProjectNamePattern = "^[a-zA-Z0-9_-]+$"

	// EnvironmentNamePattern is the regex pattern for valid environment names
	EnvironmentNamePattern = "^[a-zA-Z0-9_-]+$"
)

Validation Constants

View Source
const (
	// PlaceholderName is the placeholder used in templates for name substitution
	PlaceholderName = "{name}"

	// ComponentsPrefix is the prefix for component paths in schemas
	ComponentsPrefix = "components."

	// EnvironmentsPrefix is the prefix for environment paths in schemas
	EnvironmentsPrefix = "environments."

	// ArrayItemIndexTemplate is the template for array item indices in schema paths
	ArrayItemIndexTemplate = "[0]"

	// EnvFileSuffix is the suffix to remove from environment names during cleanup
	EnvFileSuffix = "/*"
)

Manifest Processing

View Source
const (
	// DefaultResourcePreset is the default resource preset when none is specified
	DefaultResourcePreset = "small"

	// MinCPUMillicores is the minimum CPU allocation in millicores
	MinCPUMillicores = 10

	// MaxCPUMillicores is the maximum CPU allocation in millicores
	MaxCPUMillicores = 16000

	// MinMemoryMB is the minimum memory allocation in megabytes
	MinMemoryMB = 16

	// MaxMemoryMB is the maximum memory allocation in megabytes
	MaxMemoryMB = 32768
)

Resource Management

View Source
const (
	// LabelPrefix is the prefix for all Deployah-managed labels
	LabelPrefix = "deployah.dev"

	// LabelProject is the label key for project identification
	LabelProject = LabelPrefix + "/project"

	// LabelEnvironment is the label key for environment identification
	LabelEnvironment = LabelPrefix + "/environment"

	// LabelManagedBy is the label key indicating management by Deployah
	LabelManagedBy = LabelPrefix + "/managed-by"

	// LabelVersion is the label key for API version tracking
	LabelVersion = LabelPrefix + "/version"

	// LabelComponent is the label key for component identification
	LabelComponent = LabelPrefix + "/component"

	// ManagedByValue is the value used for the managed-by label
	ManagedByValue = "deployah"
)

Kubernetes Labels

Variables

View Source
var ResourcePresetMappings = map[ResourcePreset]map[string]Resources{
	ResourcePresetNano: {
		"requests": {
			CPU:              stringPtr("100m"),
			Memory:           stringPtr("128Mi"),
			EphemeralStorage: stringPtr("50Mi"),
		},
		"limits": {
			CPU:              stringPtr("150m"),
			Memory:           stringPtr("192Mi"),
			EphemeralStorage: stringPtr("2Gi"),
		},
	},
	ResourcePresetMicro: {
		"requests": {
			CPU:              stringPtr("250m"),
			Memory:           stringPtr("256Mi"),
			EphemeralStorage: stringPtr("50Mi"),
		},
		"limits": {
			CPU:              stringPtr("375m"),
			Memory:           stringPtr("384Mi"),
			EphemeralStorage: stringPtr("2Gi"),
		},
	},
	ResourcePresetSmall: {
		"requests": {
			CPU:              stringPtr("500m"),
			Memory:           stringPtr("512Mi"),
			EphemeralStorage: stringPtr("50Mi"),
		},
		"limits": {
			CPU:              stringPtr("750m"),
			Memory:           stringPtr("768Mi"),
			EphemeralStorage: stringPtr("2Gi"),
		},
	},
	ResourcePresetMedium: {
		"requests": {
			CPU:              stringPtr("500m"),
			Memory:           stringPtr("1024Mi"),
			EphemeralStorage: stringPtr("50Mi"),
		},
		"limits": {
			CPU:              stringPtr("750m"),
			Memory:           stringPtr("1536Mi"),
			EphemeralStorage: stringPtr("2Gi"),
		},
	},
	ResourcePresetLarge: {
		"requests": {
			CPU:              stringPtr("1000m"),
			Memory:           stringPtr("2048Mi"),
			EphemeralStorage: stringPtr("50Mi"),
		},
		"limits": {
			CPU:              stringPtr("1500m"),
			Memory:           stringPtr("3072Mi"),
			EphemeralStorage: stringPtr("2Gi"),
		},
	},
	ResourcePresetXLarge: {
		"requests": {
			CPU:              stringPtr("1000m"),
			Memory:           stringPtr("3072Mi"),
			EphemeralStorage: stringPtr("50Mi"),
		},
		"limits": {
			CPU:              stringPtr("3000m"),
			Memory:           stringPtr("6144Mi"),
			EphemeralStorage: stringPtr("2Gi"),
		},
	},
	ResourcePreset2XLarge: {
		"requests": {
			CPU:              stringPtr("1000m"),
			Memory:           stringPtr("3072Mi"),
			EphemeralStorage: stringPtr("50Mi"),
		},
		"limits": {
			CPU:              stringPtr("6000m"),
			Memory:           stringPtr("12288Mi"),
			EphemeralStorage: stringPtr("2Gi"),
		},
	},
}

ResourcePresetMappings defines the resource specifications for each preset

Functions

func ClearSchemaCache

func ClearSchemaCache()

ClearSchemaCache clears all cached schemas and patterns. This function is primarily useful for testing to ensure clean state between test runs and for memory management in long-running applications.

Example usage in tests:

func TestSchemaDefaults(t *testing.T) {
	defer ClearSchemaCache() // Clean up after test
	// ... test code that modifies schemas
}

func FillManifestWithDefaults

func FillManifestWithDefaults(manifest *Manifest, version string) error

FillManifestWithDefaults fills a Manifest struct with default values from JSON schemas. This function applies defaults from both manifest and environment schemas, handles resource preset resolution, and supports environment-specific placeholder substitution.

The function processes defaults in this order:

  1. Apply manifest schema defaults to components
  2. Resolve resource presets to concrete values
  3. Merge manifest and environment defaults
  4. Apply merged defaults to environments with placeholder substitution

Parameters:

  • manifest: Manifest to fill with defaults (modified in-place)
  • version: Schema version to use for default extraction

Returns:

  • error: If schema loading, default extraction, or application fails

Example:

manifest := &Manifest{
	ApiVersion: "v1-alpha.1",
	Project:    "my-app",
	Components: map[string]Component{
		"web": {Image: "nginx:latest"}, // Only image specified
	},
	Environments: []Environment{
		{Name: "production"}, // Only name specified
	},
}
err := FillManifestWithDefaults(manifest, "v1-alpha.1")
// After filling:
// manifest.Components["web"].Role = "service"
// manifest.Components["web"].Port = 8080
// manifest.Environments[0].EnvFile = ".env.production"

func Save

func Save(manifest *Manifest, path string) error

Save writes the manifest to a YAML file at the specified path.

func SubstituteVariables

func SubstituteVariables(data []byte, env *Environment) ([]byte, error)

SubstituteVariables substitutes variables in the manifest data using the environment variables. The variables are substituted in the following order: 1. Variables from the environment definition (lowest priority) 2. Variables from the env file (medium priority) 3. Variables from the OS environment variables (highest priority) The variables are substituted using the envsubst package.

func ValidateAPIVersion

func ValidateAPIVersion(manifestObj map[string]any) (string, error)

ValidateAPIVersion checks the manifest's apiVersion field for presence, type, and validity. Returns the apiVersion string if valid, or an error otherwise.

func ValidateComponentName

func ValidateComponentName(name string) error

ValidateComponentName validates a component name against the JSON schema pattern

func ValidateComponentResources

func ValidateComponentResources(component Component) error

ValidateComponentResources validates that a component has valid resource configuration. A component can have either: 1. Explicit resources (resources field with actual values) 2. Resource preset (resourcePreset field) 3. Neither (will use defaults) But it cannot have both resources and resourcePreset, and cannot have empty resources object.

func ValidateEnvName

func ValidateEnvName(name string) error

ValidateEnvName validates an environment name against the JSON schema pattern

func ValidateEnvVarName

func ValidateEnvVarName(name string) error

ValidateEnvVarName validates an environment variable name against the JSON schema pattern

func ValidateEnvironments

func ValidateEnvironments(manifestObj map[string]any, version string) error

ValidateEnvironments validates the environments YAML against the provided JSON schema file. version should be the version of the schema (e.g., "v1-alpha.1"). This is a strict validation: unknown fields are not allowed.

func ValidateHostname

func ValidateHostname(hostname string) error

ValidateHostname validates a hostname against the JSON schema pattern

func ValidateManifest

func ValidateManifest(manifestObj map[string]any, version string) error

Validate validates the manifest YAML against the provided JSON schema file. version should be the version of the schema (e.g., "v1-alpha.1"). This is a strict validation: unknown fields are not allowed.

func ValidateManifestComponents

func ValidateManifestComponents(manifest *Manifest) error

ValidateManifestComponents validates all components in a manifest.

func ValidatePort

func ValidatePort(portStr string) error

ValidatePort validates that the port number is a valid number between 1024 and 65535

func ValidateProjectName

func ValidateProjectName(name string) error

ValidateProjectName validates a project name against the JSON schema pattern

Types

type Autoscaling

type Autoscaling struct {
	Enabled     bool     `json:"enabled,omitempty" yaml:"enabled,omitempty"`
	MinReplicas int      `json:"minReplicas,omitempty" yaml:"minReplicas,omitempty"`
	MaxReplicas int      `json:"maxReplicas,omitempty" yaml:"maxReplicas,omitempty"`
	Metrics     []Metric `json:"metrics,omitempty" yaml:"metrics,omitempty"`
}

Autoscaling defines the autoscaling settings for the component.

type Component

type Component struct {
	Role           ComponentRole     `json:"role,omitempty" yaml:"role,omitempty"`
	EnvFile        string            `json:"envFile,omitempty" yaml:"envFile,omitempty"`
	ConfigFile     string            `json:"configFile,omitempty" yaml:"configFile,omitempty"`
	Environments   []string          `json:"environments,omitempty" yaml:"environments,omitempty"`
	Kind           ComponentKind     `json:"kind,omitempty" yaml:"kind,omitempty"`
	Image          string            `json:"image" yaml:"image"`
	Command        []string          `json:"command,omitempty" yaml:"command,omitempty"`
	Args           []string          `json:"args,omitempty" yaml:"args,omitempty"`
	Port           int               `json:"port,omitempty" yaml:"port,omitempty"`
	Autoscaling    *Autoscaling      `json:"autoscaling,omitempty" yaml:"autoscaling,omitempty"`
	Resources      Resources         `json:"resources,omitempty" yaml:"resources,omitempty"`
	ResourcePreset ResourcePreset    `json:"resourcePreset,omitempty" yaml:"resourcePreset,omitempty"`
	Ingress        *Ingress          `json:"ingress,omitempty" yaml:"ingress,omitempty"`
	Env            map[string]string `json:"env,omitempty" yaml:"env,omitempty"`
}

Component defines a deployable unit in the project.

type ComponentKind

type ComponentKind string

ComponentKind specifies the kind of the component.

const (
	ComponentKindStateless ComponentKind = "stateless"
	ComponentKindStateful  ComponentKind = "stateful"
)

type ComponentRole

type ComponentRole string

ComponentRole defines the role of the component within the application and determines the default deployment strategy.

const (
	ComponentRoleService ComponentRole = "service"
	ComponentRoleWorker  ComponentRole = "worker"
	ComponentRoleJob     ComponentRole = "job"
)

type DefaultValues

type DefaultValues map[string]any

DefaultValues represents the default values extracted from a JSON schema. The map keys are dot-notation paths to fields, and values are the default values to apply.

Examples of keys:

  • "components.[^[a-zA-Z0-9_-]+$].role" -> "service" (pattern-based component default)
  • "components.web.port" -> 8080 (specific component default)
  • "environments.[0].envFile" -> ".env.{name}" (environment template with placeholder)
  • "environments.production.configFile" -> "config.production.yaml" (specific environment)

func GetDefaultValues

func GetDefaultValues(version string, schemaType schema.SchemaType) (DefaultValues, error)

GetDefaultValues extracts all default values from a JSON schema. This is the main entry point for retrieving schema-based defaults for a specific version and type.

Parameters:

  • version: Schema version identifier (e.g., "v1-alpha.1")
  • schemaType: Type of schema to process (manifest or environments)

Returns:

  • DefaultValues: Map of paths to default values extracted from the schema
  • error: If schema loading or processing fails

Example usage:

defaults, err := GetDefaultValues("v1-alpha.1", schema.SchemaTypeManifest)
if err != nil {
	return err
}
// defaults now contains:
// "components.[^[a-zA-Z0-9_-]+$].role" -> "service"
// "components.[^[a-zA-Z0-9_-]+$].port" -> 8080
// etc.

type Environment

type Environment struct {
	Name       string            `json:"name" yaml:"name"`
	EnvFile    string            `json:"envFile,omitempty" yaml:"envFile,omitempty"`
	ConfigFile string            `json:"configFile,omitempty" yaml:"configFile,omitempty"`
	Variables  map[string]string `json:"variables,omitempty" yaml:"variables,omitempty"`
}

Environment defines the environment definition in the project.

func ResolveEnvironment

func ResolveEnvironment(environments []Environment, desiredEnvironment string) (*Environment, error)

ResolveEnvironment returns the environment by name, or the default if name is empty. Returns an error if not found or if multiple environments are defined but none specified.

type Ingress

type Ingress struct {
	Host string `json:"host" yaml:"host"`
	TLS  bool   `json:"tls" yaml:"tls"`
}

Ingress specifies the ingress settings for exposing the component via HTTP/HTTPS.

type Manifest

type Manifest struct {
	// ApiVersion is the schema version of the manifest (e.g., "v1-alpha.1").
	ApiVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
	// Project is the project name.
	Project string `json:"project" yaml:"project"`
	// Environments is a list of environment definitions.
	Environments []Environment `json:"environments,omitempty" yaml:"environments,omitempty"`
	// Components is a map of component names to their configuration.
	Components map[string]Component `json:"components" yaml:"components"`
}

Manifest defines the structure of the project manifest.

func CreateManifestWithDefaults

func CreateManifestWithDefaults(projectName, version string) (*Manifest, error)

CreateManifestWithDefaults creates a new Manifest with default values applied. This is a convenience function that creates a minimal manifest structure and then applies all relevant defaults from the specified schema version.

Parameters:

  • projectName: Name of the project
  • version: Schema version to use for defaults

Returns:

  • *Manifest: New manifest with defaults applied
  • error: If creation or default application fails

Example:

manifest, err := CreateManifestWithDefaults("my-app", "v1-alpha.1")
// Returns:
// &Manifest{
//     ApiVersion: "v1-alpha.1",
//     Project:    "my-app",
//     Components: map[string]Component{}, // Empty but initialized
// }

func Load

func Load(ctx context.Context, path string, envName string) (*Manifest, error)

Load reads and parses the manifest YAML file at the given path, resolves the environment (using the provided envName or default resolution rules), and substitutes variables according to precedence (environment definition < env file < OS environment). Returns the fully parsed Manifest struct or an error.

func (*Manifest) EnvironmentNames

func (m *Manifest) EnvironmentNames() []string

EnvironmentNames returns the list of environment names defined in the manifest. Returns an empty slice if no environments are defined.

type Metric

type Metric struct {
	Type   MetricType `json:"type" yaml:"type"`
	Target int        `json:"target" yaml:"target"`
}

Metric defines a metric used to trigger autoscaling.

type MetricType

type MetricType string

MetricType specifies the type of metric to monitor.

const (
	MetricTypeCPU    MetricType = "cpu"
	MetricTypeMemory MetricType = "memory"
)

type ResourcePreset

type ResourcePreset string

ResourcePreset specifies the resource preset for the component.

const (
	ResourcePresetNano    ResourcePreset = "nano"
	ResourcePresetMicro   ResourcePreset = "micro"
	ResourcePresetSmall   ResourcePreset = "small"
	ResourcePresetMedium  ResourcePreset = "medium"
	ResourcePresetLarge   ResourcePreset = "large"
	ResourcePresetXLarge  ResourcePreset = "xlarge"
	ResourcePreset2XLarge ResourcePreset = "2xlarge"
)

type Resources

type Resources struct {
	CPU              *string `json:"cpu,omitempty" yaml:"cpu,omitempty"`
	Memory           *string `json:"memory,omitempty" yaml:"memory,omitempty"`
	EphemeralStorage *string `json:"ephemeralStorage,omitempty" yaml:"ephemeralStorage,omitempty"`
}

Resources defines the resource requests and limits for the component.

Directories

Path Synopsis
Package schema offers utilities for accessing and managing versioned schema files.
Package schema offers utilities for accessing and managing versioned schema files.

Jump to

Keyboard shortcuts

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