mirror of
https://github.com/harivansh-afk/agentikube.git
synced 2026-04-17 07:03:27 +00:00
init
This commit is contained in:
commit
0595d93c49
28 changed files with 1763 additions and 0 deletions
102
internal/config/config.go
Normal file
102
internal/config/config.go
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Config is the top-level configuration parsed from agentikube.yaml.
|
||||
type Config struct {
|
||||
Namespace string `yaml:"namespace"`
|
||||
Compute ComputeConfig `yaml:"compute"`
|
||||
Storage StorageConfig `yaml:"storage"`
|
||||
Sandbox SandboxConfig `yaml:"sandbox"`
|
||||
}
|
||||
|
||||
type ComputeConfig struct {
|
||||
Type string `yaml:"type"` // karpenter | fargate
|
||||
InstanceTypes []string `yaml:"instanceTypes"`
|
||||
CapacityTypes []string `yaml:"capacityTypes"`
|
||||
MaxCPU int `yaml:"maxCpu"`
|
||||
MaxMemory string `yaml:"maxMemory"`
|
||||
Consolidation bool `yaml:"consolidation"`
|
||||
FargateSelectors []FargateSelector `yaml:"fargateSelectors"`
|
||||
}
|
||||
|
||||
type FargateSelector struct {
|
||||
Namespace string `yaml:"namespace"`
|
||||
}
|
||||
|
||||
type StorageConfig struct {
|
||||
Type string `yaml:"type"` // efs
|
||||
FilesystemID string `yaml:"filesystemId"`
|
||||
BasePath string `yaml:"basePath"`
|
||||
UID int `yaml:"uid"`
|
||||
GID int `yaml:"gid"`
|
||||
ReclaimPolicy string `yaml:"reclaimPolicy"`
|
||||
}
|
||||
|
||||
type SandboxConfig struct {
|
||||
Image string `yaml:"image"`
|
||||
Ports []int `yaml:"ports"`
|
||||
MountPath string `yaml:"mountPath"`
|
||||
Resources ResourcesConfig `yaml:"resources"`
|
||||
Env map[string]string `yaml:"env"`
|
||||
SecurityContext SecurityContext `yaml:"securityContext"`
|
||||
Probes ProbesConfig `yaml:"probes"`
|
||||
WarmPool WarmPoolConfig `yaml:"warmPool"`
|
||||
NetworkPolicy NetworkPolicy `yaml:"networkPolicy"`
|
||||
}
|
||||
|
||||
type ResourcesConfig struct {
|
||||
Requests ResourceValues `yaml:"requests"`
|
||||
Limits ResourceValues `yaml:"limits"`
|
||||
}
|
||||
|
||||
type ResourceValues struct {
|
||||
CPU string `yaml:"cpu"`
|
||||
Memory string `yaml:"memory"`
|
||||
}
|
||||
|
||||
type SecurityContext struct {
|
||||
RunAsUser int `yaml:"runAsUser"`
|
||||
RunAsGroup int `yaml:"runAsGroup"`
|
||||
RunAsNonRoot bool `yaml:"runAsNonRoot"`
|
||||
}
|
||||
|
||||
type ProbesConfig struct {
|
||||
Port int `yaml:"port"`
|
||||
StartupFailureThreshold int `yaml:"startupFailureThreshold"`
|
||||
}
|
||||
|
||||
type WarmPoolConfig struct {
|
||||
Enabled bool `yaml:"enabled"`
|
||||
Size int `yaml:"size"`
|
||||
TTLMinutes int `yaml:"ttlMinutes"`
|
||||
}
|
||||
|
||||
type NetworkPolicy struct {
|
||||
EgressAllowAll bool `yaml:"egressAllowAll"`
|
||||
IngressPorts []int `yaml:"ingressPorts"`
|
||||
}
|
||||
|
||||
// Load reads and parses the config file at the given path.
|
||||
func Load(path string) (*Config, error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reading config file: %w", err)
|
||||
}
|
||||
|
||||
var cfg Config
|
||||
if err := yaml.Unmarshal(data, &cfg); err != nil {
|
||||
return nil, fmt.Errorf("parsing config file: %w", err)
|
||||
}
|
||||
|
||||
if err := Validate(&cfg); err != nil {
|
||||
return nil, fmt.Errorf("validating config: %w", err)
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
99
internal/config/validate.go
Normal file
99
internal/config/validate.go
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Validate checks that all required fields are present and values are valid.
|
||||
func Validate(cfg *Config) error {
|
||||
var errs []string
|
||||
|
||||
if cfg.Namespace == "" {
|
||||
errs = append(errs, "namespace is required")
|
||||
}
|
||||
|
||||
// Compute validation
|
||||
switch cfg.Compute.Type {
|
||||
case "karpenter":
|
||||
if len(cfg.Compute.InstanceTypes) == 0 {
|
||||
errs = append(errs, "compute.instanceTypes is required when type is karpenter")
|
||||
}
|
||||
if len(cfg.Compute.CapacityTypes) == 0 {
|
||||
errs = append(errs, "compute.capacityTypes is required when type is karpenter")
|
||||
}
|
||||
if cfg.Compute.MaxCPU <= 0 {
|
||||
errs = append(errs, "compute.maxCpu must be > 0")
|
||||
}
|
||||
if cfg.Compute.MaxMemory == "" {
|
||||
errs = append(errs, "compute.maxMemory is required when type is karpenter")
|
||||
}
|
||||
case "fargate":
|
||||
if len(cfg.Compute.FargateSelectors) == 0 {
|
||||
errs = append(errs, "compute.fargateSelectors is required when type is fargate")
|
||||
}
|
||||
case "":
|
||||
errs = append(errs, "compute.type is required (karpenter or fargate)")
|
||||
default:
|
||||
errs = append(errs, fmt.Sprintf("compute.type must be karpenter or fargate, got %q", cfg.Compute.Type))
|
||||
}
|
||||
|
||||
// Storage validation
|
||||
if cfg.Storage.Type == "" {
|
||||
errs = append(errs, "storage.type is required")
|
||||
} else if cfg.Storage.Type != "efs" {
|
||||
errs = append(errs, fmt.Sprintf("storage.type must be efs, got %q", cfg.Storage.Type))
|
||||
}
|
||||
if cfg.Storage.FilesystemID == "" {
|
||||
errs = append(errs, "storage.filesystemId is required")
|
||||
}
|
||||
if cfg.Storage.BasePath == "" {
|
||||
errs = append(errs, "storage.basePath is required")
|
||||
}
|
||||
if cfg.Storage.ReclaimPolicy == "" {
|
||||
cfg.Storage.ReclaimPolicy = "Retain"
|
||||
} else if cfg.Storage.ReclaimPolicy != "Retain" && cfg.Storage.ReclaimPolicy != "Delete" {
|
||||
errs = append(errs, fmt.Sprintf("storage.reclaimPolicy must be Retain or Delete, got %q", cfg.Storage.ReclaimPolicy))
|
||||
}
|
||||
|
||||
// Storage defaults
|
||||
if cfg.Storage.UID == 0 {
|
||||
cfg.Storage.UID = 1000
|
||||
}
|
||||
if cfg.Storage.GID == 0 {
|
||||
cfg.Storage.GID = 1000
|
||||
}
|
||||
|
||||
// Sandbox validation
|
||||
if cfg.Sandbox.Image == "" {
|
||||
errs = append(errs, "sandbox.image is required")
|
||||
}
|
||||
if len(cfg.Sandbox.Ports) == 0 {
|
||||
errs = append(errs, "sandbox.ports is required")
|
||||
}
|
||||
if cfg.Sandbox.MountPath == "" {
|
||||
errs = append(errs, "sandbox.mountPath is required")
|
||||
}
|
||||
|
||||
// Warm pool defaults
|
||||
if cfg.Sandbox.WarmPool.Size == 0 && cfg.Sandbox.WarmPool.Enabled {
|
||||
cfg.Sandbox.WarmPool.Size = 5
|
||||
}
|
||||
if cfg.Sandbox.WarmPool.TTLMinutes == 0 {
|
||||
cfg.Sandbox.WarmPool.TTLMinutes = 120
|
||||
}
|
||||
|
||||
// Probes defaults
|
||||
if cfg.Sandbox.Probes.Port == 0 && len(cfg.Sandbox.Ports) > 0 {
|
||||
cfg.Sandbox.Probes.Port = cfg.Sandbox.Ports[0]
|
||||
}
|
||||
if cfg.Sandbox.Probes.StartupFailureThreshold == 0 {
|
||||
cfg.Sandbox.Probes.StartupFailureThreshold = 30
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
return fmt.Errorf("config validation errors:\n - %s", strings.Join(errs, "\n - "))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue