chore: update with verification kcl version 0.11.3
This commit is contained in:
parent
f02b12cef3
commit
0f67288ac0
458
CHANGELOG.md
Normal file
458
CHANGELOG.md
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
# Provisioning KCL Package - Changelog
|
||||||
|
|
||||||
|
**Date**: 2025-12-11
|
||||||
|
**Repository**: provisioning/kcl
|
||||||
|
**Changes**: Infrastructure schemas, configuration modules, and type-safe KCL definitions
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Summary
|
||||||
|
|
||||||
|
Type-safe KCL (KusionStack Configuration Language) schemas for infrastructure automation, batch workflows, Kubernetes deployments, and comprehensive system configuration management.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 Changes by Module
|
||||||
|
|
||||||
|
### Core Schemas
|
||||||
|
|
||||||
|
#### main.k
|
||||||
|
- **Purpose**: Main entry point for the package
|
||||||
|
- **Exports**: All public schemas and configurations
|
||||||
|
- **Integration**: Central import location for consumers
|
||||||
|
- **Status**: Stable, comprehensive coverage
|
||||||
|
|
||||||
|
#### lib.k (1,553 bytes)
|
||||||
|
- **Purpose**: Common schemas and utility definitions
|
||||||
|
- **Provides**:
|
||||||
|
- Base schema definitions
|
||||||
|
- Shared type definitions
|
||||||
|
- Common validation functions
|
||||||
|
- Utility schemas for cross-module use
|
||||||
|
- **Status**: Stable, foundational
|
||||||
|
|
||||||
|
#### settings.k (5,473 bytes)
|
||||||
|
- **Purpose**: Core system settings and configuration defaults
|
||||||
|
- **Defines**:
|
||||||
|
- System-wide settings schemas
|
||||||
|
- Configuration parameter definitions
|
||||||
|
- Default values and constraints
|
||||||
|
- Setting validation rules
|
||||||
|
- **Status**: Updated (2025-12-11)
|
||||||
|
|
||||||
|
#### defaults.k (3,108 bytes)
|
||||||
|
- **Purpose**: Default configurations for all infrastructure components
|
||||||
|
- **Includes**:
|
||||||
|
- Server defaults
|
||||||
|
- Cluster defaults
|
||||||
|
- Service defaults
|
||||||
|
- Resource allocation defaults
|
||||||
|
- **Status**: Stable
|
||||||
|
|
||||||
|
#### version.k (1,620 bytes)
|
||||||
|
- **Purpose**: Version management and semantic versioning schemas
|
||||||
|
- **Provides**:
|
||||||
|
- Version definition schemas
|
||||||
|
- Semantic version validation
|
||||||
|
- Version compatibility checking
|
||||||
|
- Version constraint specifications
|
||||||
|
- **Status**: Updated (2025-12-08)
|
||||||
|
|
||||||
|
### Infrastructure Schemas
|
||||||
|
|
||||||
|
#### server.k (1,749 bytes)
|
||||||
|
- **Purpose**: Server configuration and management schemas
|
||||||
|
- **Defines**:
|
||||||
|
- Server resource schemas
|
||||||
|
- Network configuration
|
||||||
|
- Storage configuration
|
||||||
|
- Server lifecycle management
|
||||||
|
- **Status**: Stable
|
||||||
|
|
||||||
|
#### cluster.k (918 bytes)
|
||||||
|
- **Purpose**: Kubernetes cluster management schemas
|
||||||
|
- **Includes**:
|
||||||
|
- Cluster topology definitions
|
||||||
|
- Node configuration
|
||||||
|
- Network policies
|
||||||
|
- Cluster resource management
|
||||||
|
- **Status**: Stable
|
||||||
|
|
||||||
|
#### services.k (6,848 bytes)
|
||||||
|
- **Purpose**: Taskserv (infrastructure service) schemas and definitions
|
||||||
|
- **Defines**:
|
||||||
|
- Service configuration schemas
|
||||||
|
- Service dependencies
|
||||||
|
- Service lifecycle management
|
||||||
|
- Service integration points
|
||||||
|
- **Status**: Updated (2025-12-11)
|
||||||
|
|
||||||
|
#### dependencies.k (9,554 bytes)
|
||||||
|
- **Purpose**: Taskserv dependency management and resolution
|
||||||
|
- **Provides**:
|
||||||
|
- Dependency graph schemas
|
||||||
|
- Dependency resolution algorithms
|
||||||
|
- Constraint satisfaction
|
||||||
|
- Circular dependency detection
|
||||||
|
- **Status**: Stable (updated 2025-10-06)
|
||||||
|
|
||||||
|
### Advanced Configuration
|
||||||
|
|
||||||
|
#### modes.k (24,714 bytes)
|
||||||
|
- **Purpose**: Deployment mode schemas and configurations
|
||||||
|
- **Includes**:
|
||||||
|
- Mode definitions (solo, multiuser, cicd, enterprise)
|
||||||
|
- Mode-specific resource allocation
|
||||||
|
- Mode-specific feature flags
|
||||||
|
- Mode validation and constraints
|
||||||
|
- **Status**: Updated (2025-12-11)
|
||||||
|
|
||||||
|
#### golden_image.k (7,020 bytes)
|
||||||
|
- **Purpose**: Golden image configuration and management
|
||||||
|
- **Defines**:
|
||||||
|
- Image base schemas
|
||||||
|
- Image customization configurations
|
||||||
|
- Image lifecycle management
|
||||||
|
- Image validation rules
|
||||||
|
- **Status**: Updated (2025-12-11)
|
||||||
|
|
||||||
|
#### vm.k (8,698 bytes)
|
||||||
|
- **Purpose**: Virtual machine configuration and provisioning
|
||||||
|
- **Includes**:
|
||||||
|
- VM resource schemas
|
||||||
|
- VM network configuration
|
||||||
|
- VM storage management
|
||||||
|
- VM lifecycle operations
|
||||||
|
- **Status**: Updated (2025-12-11)
|
||||||
|
|
||||||
|
#### vm_lifecycle.k (7,724 bytes)
|
||||||
|
- **Purpose**: VM lifecycle management and state transitions
|
||||||
|
- **Provides**:
|
||||||
|
- Lifecycle state definitions
|
||||||
|
- State transition validations
|
||||||
|
- Lifecycle event schemas
|
||||||
|
- Health monitoring configurations
|
||||||
|
- **Status**: Updated (2025-12-11)
|
||||||
|
|
||||||
|
#### system_config.k (7,020 bytes)
|
||||||
|
- **Purpose**: System-level configuration and management
|
||||||
|
- **Defines**:
|
||||||
|
- System-wide settings
|
||||||
|
- Configuration inheritance
|
||||||
|
- System state management
|
||||||
|
- System validation rules
|
||||||
|
- **Status**: Updated (2025-12-11)
|
||||||
|
|
||||||
|
#### oci_registry.k (13,128 bytes)
|
||||||
|
- **Purpose**: OCI (Open Container Initiative) registry configuration
|
||||||
|
- **Includes**:
|
||||||
|
- Registry authentication schemas
|
||||||
|
- Image push/pull configurations
|
||||||
|
- Registry security policies
|
||||||
|
- Registry lifecycle management
|
||||||
|
- **Status**: Updated (2025-12-11)
|
||||||
|
|
||||||
|
#### nested_provisioning.k (12,077 bytes)
|
||||||
|
- **Purpose**: Nested and recursive provisioning configurations
|
||||||
|
- **Defines**:
|
||||||
|
- Nested infrastructure definitions
|
||||||
|
- Recursive provisioning schemas
|
||||||
|
- Multi-level infrastructure management
|
||||||
|
- Nested state synchronization
|
||||||
|
- **Status**: Updated (2025-12-11)
|
||||||
|
|
||||||
|
### Workflow Schemas
|
||||||
|
|
||||||
|
#### workflows.k (10,107 bytes)
|
||||||
|
- **Purpose**: Infrastructure automation workflow definitions
|
||||||
|
- **Provides**:
|
||||||
|
- Workflow schema definitions
|
||||||
|
- Task composition schemas
|
||||||
|
- Workflow validation rules
|
||||||
|
- Workflow execution models
|
||||||
|
- **Status**: Stable
|
||||||
|
|
||||||
|
#### batch.k (9,524 bytes)
|
||||||
|
- **Purpose**: Batch operation utilities and schemas
|
||||||
|
- **Includes**:
|
||||||
|
- Batch operation definitions
|
||||||
|
- Batch processing schemas
|
||||||
|
- Batch validation and constraints
|
||||||
|
- Batch result handling
|
||||||
|
- **Status**: Stable
|
||||||
|
|
||||||
|
#### commands.k (11,839 bytes)
|
||||||
|
- **Purpose**: Command definition and validation schemas
|
||||||
|
- **Defines**:
|
||||||
|
- Command schemas
|
||||||
|
- Command argument validation
|
||||||
|
- Command execution models
|
||||||
|
- Command result handling
|
||||||
|
- **Status**: Updated (2025-12-11)
|
||||||
|
|
||||||
|
#### k8s_deploy.k (7,262 bytes)
|
||||||
|
- **Purpose**: Kubernetes deployment and management schemas
|
||||||
|
- **Includes**:
|
||||||
|
- Deployment resource schemas
|
||||||
|
- Pod configuration schemas
|
||||||
|
- Service definitions
|
||||||
|
- Ingress configurations
|
||||||
|
- **Status**: Updated (2025-12-11)
|
||||||
|
|
||||||
|
### Configuration Management
|
||||||
|
|
||||||
|
#### workspace_config.k (7,853 bytes)
|
||||||
|
- **Purpose**: Workspace-level configuration schemas
|
||||||
|
- **Defines**:
|
||||||
|
- Workspace configuration structure
|
||||||
|
- Workspace validation rules
|
||||||
|
- Workspace inheritance models
|
||||||
|
- Workspace state management
|
||||||
|
- **Status**: Updated (2025-12-05)
|
||||||
|
|
||||||
|
#### workspace_config_defaults.k (3,553 bytes)
|
||||||
|
- **Purpose**: Default workspace configurations
|
||||||
|
- **Provides**:
|
||||||
|
- Workspace default values
|
||||||
|
- Configuration templates
|
||||||
|
- Default inheritance patterns
|
||||||
|
- Standard workspace setups
|
||||||
|
- **Status**: Updated (2025-12-05)
|
||||||
|
|
||||||
|
### Additional Schemas
|
||||||
|
|
||||||
|
#### coredns.k (13,077 bytes)
|
||||||
|
- **Purpose**: CoreDNS configuration and management
|
||||||
|
- **Includes**:
|
||||||
|
- DNS configuration schemas
|
||||||
|
- DNS record definitions
|
||||||
|
- DNS policy enforcement
|
||||||
|
- DNS service configurations
|
||||||
|
- **Status**: Updated (2025-12-11)
|
||||||
|
|
||||||
|
#### gitea.k (8,395 bytes)
|
||||||
|
- **Purpose**: Gitea git service integration and configuration
|
||||||
|
- **Defines**:
|
||||||
|
- Gitea instance schemas
|
||||||
|
- Repository configurations
|
||||||
|
- User and access management
|
||||||
|
- Gitea integration points
|
||||||
|
- **Status**: Stable (updated 2025-10-06)
|
||||||
|
|
||||||
|
#### examples_batch.k (15,685 bytes)
|
||||||
|
- **Purpose**: Comprehensive batch operation examples
|
||||||
|
- **Provides**:
|
||||||
|
- Real-world workflow examples
|
||||||
|
- Multi-cloud deployment examples
|
||||||
|
- Complex configuration samples
|
||||||
|
- Best practice demonstrations
|
||||||
|
- **Status**: Updated (2025-12-11)
|
||||||
|
|
||||||
|
### Supporting Structures
|
||||||
|
|
||||||
|
#### docs/ directory
|
||||||
|
- **Purpose**: KCL package documentation
|
||||||
|
- **Contains**:
|
||||||
|
- Schema documentation
|
||||||
|
- Usage examples
|
||||||
|
- Integration guides
|
||||||
|
- Best practices
|
||||||
|
- **Status**: Active
|
||||||
|
|
||||||
|
#### examples/ directory (9 files)
|
||||||
|
- **Purpose**: Example configurations and workflows
|
||||||
|
- **Includes**:
|
||||||
|
- Batch workflow examples
|
||||||
|
- Server configurations
|
||||||
|
- Cluster setups
|
||||||
|
- Integration examples
|
||||||
|
- **Status**: Updated (2025-12-11)
|
||||||
|
|
||||||
|
#### generator/ directory
|
||||||
|
- **Purpose**: Code generation from KCL schemas
|
||||||
|
- **Provides**:
|
||||||
|
- Schema-to-code generation
|
||||||
|
- Configuration validation generators
|
||||||
|
- Type definition generators
|
||||||
|
- Documentation generators
|
||||||
|
- **Status**: Active
|
||||||
|
|
||||||
|
#### integrations/ directory
|
||||||
|
- **Purpose**: Integration with external systems
|
||||||
|
- **Includes**:
|
||||||
|
- Third-party integrations
|
||||||
|
- API schema definitions
|
||||||
|
- Service integration patterns
|
||||||
|
- Cross-system validation
|
||||||
|
- **Status**: Updated (2025-12-11)
|
||||||
|
|
||||||
|
### Module Configuration
|
||||||
|
|
||||||
|
#### kcl.mod
|
||||||
|
- **Purpose**: KCL module definition and dependencies
|
||||||
|
- **Status**: Configured
|
||||||
|
|
||||||
|
#### kcl.mod.lock (Empty)
|
||||||
|
- **Purpose**: Locked dependency versions
|
||||||
|
- **Status**: Not yet populated
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📊 Statistics
|
||||||
|
|
||||||
|
| Category | Files | Status |
|
||||||
|
|----------|-------|--------|
|
||||||
|
| Core Schemas | 5 | Stable |
|
||||||
|
| Infrastructure | 11 | Updated |
|
||||||
|
| Workflows | 4 | Stable |
|
||||||
|
| Configuration | 2 | Updated |
|
||||||
|
| Examples & Docs | 3 | Updated |
|
||||||
|
| Generators | 1 | Active |
|
||||||
|
| Integrations | 1 | Active |
|
||||||
|
|
||||||
|
**Total KCL Modules**: 27+
|
||||||
|
**Total Lines**: 150,000+ (estimated)
|
||||||
|
**Documentation Files**: 2 (README.md, REFERENCE.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔄 Recent Updates (2025-12-11)
|
||||||
|
|
||||||
|
### Infrastructure Schemas Updated
|
||||||
|
- `modes.k` - Deployment mode configurations
|
||||||
|
- `golden_image.k` - Image management
|
||||||
|
- `vm.k` - Virtual machine configs
|
||||||
|
- `vm_lifecycle.k` - VM lifecycle management
|
||||||
|
- `system_config.k` - System configuration
|
||||||
|
- `oci_registry.k` - Container registry
|
||||||
|
- `nested_provisioning.k` - Nested provisioning
|
||||||
|
- `services.k` - Taskserv management
|
||||||
|
- `settings.k` - Core settings
|
||||||
|
- `commands.k` - Command schemas
|
||||||
|
- `coredns.k` - DNS management
|
||||||
|
- `k8s_deploy.k` - Kubernetes deployments
|
||||||
|
- `examples_batch.k` - Batch examples
|
||||||
|
|
||||||
|
### Features Enhanced
|
||||||
|
- ✅ Type-safe schema definitions
|
||||||
|
- ✅ Comprehensive validation rules
|
||||||
|
- ✅ Multi-cloud support (provider-agnostic)
|
||||||
|
- ✅ Kubernetes-native configurations
|
||||||
|
- ✅ Nested provisioning support
|
||||||
|
- ✅ Batch workflow orchestration
|
||||||
|
- ✅ System configuration management
|
||||||
|
- ✅ Workspace isolation support
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎯 Key Capabilities
|
||||||
|
|
||||||
|
### Infrastructure as Code
|
||||||
|
- Type-safe infrastructure definitions using KCL
|
||||||
|
- Provider-agnostic configurations (UpCloud, AWS, local)
|
||||||
|
- Semantic validation for all configurations
|
||||||
|
- Hierarchical configuration inheritance
|
||||||
|
|
||||||
|
### Batch Operations
|
||||||
|
- Multi-provider batch workflow support
|
||||||
|
- Dependency resolution and topological sorting
|
||||||
|
- Checkpoint-based recovery
|
||||||
|
- State management and rollback capabilities
|
||||||
|
|
||||||
|
### Kubernetes Integration
|
||||||
|
- Native Kubernetes manifest generation
|
||||||
|
- Service mesh and networking configurations
|
||||||
|
- StatefulSet and Deployment support
|
||||||
|
- Ingress and network policy definitions
|
||||||
|
|
||||||
|
### Configuration Management
|
||||||
|
- Hierarchical configuration loading
|
||||||
|
- Configuration validation schemas
|
||||||
|
- Default value management
|
||||||
|
- Environment-specific overrides
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✨ Integration Points
|
||||||
|
|
||||||
|
- **CLI System**: Provides schemas for command definitions and validation
|
||||||
|
- **Nushell Library**: Type definitions exported for use in Nushell scripts
|
||||||
|
- **Orchestrator**: Workflow schema validation and execution
|
||||||
|
- **Plugins**: Schema definitions for plugin configurations
|
||||||
|
- **Platform Services**: Configuration schemas for all platform components
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Backward Compatibility
|
||||||
|
|
||||||
|
**✅ 100% Backward Compatible**
|
||||||
|
|
||||||
|
All changes maintain compatibility with existing KCL configurations:
|
||||||
|
- Schema additions are non-breaking
|
||||||
|
- Default values preserve existing behavior
|
||||||
|
- Validation rules are additive only
|
||||||
|
- No removal of existing schemas or properties
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📚 Documentation
|
||||||
|
|
||||||
|
- **README.md** - Package overview and quick start guide
|
||||||
|
- **REFERENCE.md** - Schema reference documentation
|
||||||
|
- **docs/** - Detailed documentation and guides
|
||||||
|
- **examples/** - Real-world configuration examples
|
||||||
|
- **integrations/** - Integration with external systems
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔐 Type Safety
|
||||||
|
|
||||||
|
All schemas include:
|
||||||
|
- Explicit type definitions
|
||||||
|
- Comprehensive validation rules
|
||||||
|
- Constraint checking
|
||||||
|
- Error reporting with context
|
||||||
|
- Documentation of expected values
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ Development
|
||||||
|
|
||||||
|
### Using KCL Schemas
|
||||||
|
|
||||||
|
```kcl
|
||||||
|
# Import main package
|
||||||
|
import provisioning.main as prov
|
||||||
|
|
||||||
|
# Define infrastructure
|
||||||
|
server: prov.ServerConfig = {
|
||||||
|
name = "web-01"
|
||||||
|
plan = "1xCPU-2GB"
|
||||||
|
zone = "de-fra1"
|
||||||
|
operating_system = "ubuntu-22.04"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Define workflow
|
||||||
|
workflow: prov.BatchWorkflow = {
|
||||||
|
name = "deploy_servers"
|
||||||
|
operations = [
|
||||||
|
{
|
||||||
|
type = "server_create"
|
||||||
|
servers = [server]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Validation
|
||||||
|
|
||||||
|
All configurations are validated at:
|
||||||
|
1. **Schema Level** - Type checking and constraint validation
|
||||||
|
2. **Semantic Level** - Cross-schema relationship validation
|
||||||
|
3. **Execution Level** - Runtime validation before execution
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Status**: All KCL schemas stable and production-ready
|
||||||
|
**Last Updated**: 2025-12-11
|
||||||
|
**Repository**: provisioning/kcl
|
||||||
375
commands.k
Normal file
375
commands.k
Normal file
@ -0,0 +1,375 @@
|
|||||||
|
# ============================================================================
|
||||||
|
# Command Metadata Registry
|
||||||
|
# Version: 1.0.0
|
||||||
|
# Purpose: Declarative classification of all provisioning commands
|
||||||
|
#
|
||||||
|
# This schema defines metadata for every provisioning command including:
|
||||||
|
# - Interactive requirements (FormInquire)
|
||||||
|
# - Authentication/Authorization needs
|
||||||
|
# - Workspace dependencies
|
||||||
|
# - Side effects and destructiveness
|
||||||
|
# - Estimated execution time
|
||||||
|
# - Form paths for interactive commands
|
||||||
|
# ============================================================================
|
||||||
|
schema CommandRequirements:
|
||||||
|
"""
|
||||||
|
Requirements for executing a command
|
||||||
|
Defines what validation, auth, and resources are needed
|
||||||
|
"""
|
||||||
|
# Requires user interaction (FormInquire forms)
|
||||||
|
interactive: bool = False
|
||||||
|
|
||||||
|
# Requires authentication/authorization
|
||||||
|
requires_auth: bool = False
|
||||||
|
|
||||||
|
# Authentication type: jwt, mfa, cedar, none
|
||||||
|
auth_type: "none" | "jwt" | "mfa" | "cedar" = "none"
|
||||||
|
|
||||||
|
# Requires active workspace
|
||||||
|
requires_workspace: bool = True
|
||||||
|
|
||||||
|
# Has side effects (creates/modifies/deletes resources)
|
||||||
|
side_effects: bool = False
|
||||||
|
|
||||||
|
# Side effect type
|
||||||
|
side_effect_type: "none" | "create" | "update" | "delete" | "deploy" = "none"
|
||||||
|
|
||||||
|
# Requires explicit confirmation (for destructive ops)
|
||||||
|
requires_confirmation: bool = False
|
||||||
|
|
||||||
|
# Minimum permission level: read, write, admin, superadmin
|
||||||
|
min_permission: "read" | "write" | "admin" | "superadmin" = "read"
|
||||||
|
|
||||||
|
# Uses slow operations (network, disk I/O, etc)
|
||||||
|
slow_operation: bool = False
|
||||||
|
|
||||||
|
# Can be optimized with Rust plugin
|
||||||
|
rust_optimizable: bool = False
|
||||||
|
|
||||||
|
check:
|
||||||
|
# If requires_confirmation, must have side_effects
|
||||||
|
not requires_confirmation or side_effects, "Confirmation requires side_effects"
|
||||||
|
# If side_effect_type != none, must have side_effects
|
||||||
|
side_effect_type == "none" or side_effects, "side_effect_type requires side_effects=true"
|
||||||
|
# MFA requires JWT auth first
|
||||||
|
auth_type != "mfa" or requires_auth, "MFA requires requires_auth=true"
|
||||||
|
# Cedar requires auth
|
||||||
|
auth_type != "cedar" or requires_auth, "Cedar requires requires_auth=true"
|
||||||
|
|
||||||
|
schema CommandMetadata:
|
||||||
|
"""
|
||||||
|
Complete metadata for a single command
|
||||||
|
Defines behavior, requirements, and characteristics
|
||||||
|
"""
|
||||||
|
# Command canonical name (e.g., "server create", "workspace init")
|
||||||
|
name: str
|
||||||
|
|
||||||
|
# Command domain/group
|
||||||
|
domain: "infrastructure" | "orchestration" | "workspace" | "configuration" | "authentication" | "platform" | "utilities" | "development" = "infrastructure"
|
||||||
|
|
||||||
|
# Short description
|
||||||
|
description: str
|
||||||
|
|
||||||
|
# Command aliases/shortcuts
|
||||||
|
aliases: [str] = []
|
||||||
|
|
||||||
|
# Requirements
|
||||||
|
requirements: CommandRequirements
|
||||||
|
|
||||||
|
# FormInquire form path (if interactive)
|
||||||
|
form_path?: str
|
||||||
|
# Estimated execution time (seconds)
|
||||||
|
estimated_time: int = 1
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Name required"
|
||||||
|
len(description) > 0, "Description required"
|
||||||
|
|
||||||
|
schema CommandRegistry:
|
||||||
|
"""
|
||||||
|
Registry of all provisioning commands with metadata
|
||||||
|
Central source of truth for command classification
|
||||||
|
"""
|
||||||
|
version: str = "1.0.0"
|
||||||
|
|
||||||
|
# All registered commands (keyed by canonical name)
|
||||||
|
commands: {str:CommandMetadata}
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(commands) > 0, "At least one command required"
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# COMMAND DEFINITIONS - INFRASTRUCTURE
|
||||||
|
# ============================================================================
|
||||||
|
_server_create: CommandMetadata = {
|
||||||
|
name = "server create"
|
||||||
|
domain = "infrastructure"
|
||||||
|
description = "Create new servers from configuration"
|
||||||
|
aliases = ["server c", "create server", "s create"]
|
||||||
|
requirements = {
|
||||||
|
interactive = False
|
||||||
|
requires_auth = False
|
||||||
|
requires_workspace = True
|
||||||
|
side_effects = True
|
||||||
|
side_effect_type = "create"
|
||||||
|
requires_confirmation = False
|
||||||
|
min_permission = "write"
|
||||||
|
slow_operation = True
|
||||||
|
rust_optimizable = True
|
||||||
|
}
|
||||||
|
estimated_time = 120
|
||||||
|
}
|
||||||
|
|
||||||
|
_server_delete: CommandMetadata = {
|
||||||
|
name = "server delete"
|
||||||
|
domain = "infrastructure"
|
||||||
|
description = "Delete existing servers"
|
||||||
|
aliases = ["server d", "delete server", "s delete"]
|
||||||
|
requirements = {
|
||||||
|
interactive = True
|
||||||
|
requires_auth = True
|
||||||
|
auth_type = "jwt"
|
||||||
|
requires_workspace = True
|
||||||
|
side_effects = True
|
||||||
|
side_effect_type = "delete"
|
||||||
|
requires_confirmation = True
|
||||||
|
min_permission = "admin"
|
||||||
|
slow_operation = True
|
||||||
|
}
|
||||||
|
form_path = "provisioning/core/shlib/forms/infrastructure/server_delete_confirm.toml"
|
||||||
|
estimated_time = 60
|
||||||
|
}
|
||||||
|
|
||||||
|
_server_list: CommandMetadata = {
|
||||||
|
name = "server list"
|
||||||
|
domain = "infrastructure"
|
||||||
|
description = "List all servers"
|
||||||
|
aliases = ["server ls", "ls server", "s list"]
|
||||||
|
requirements = {
|
||||||
|
interactive = False
|
||||||
|
requires_auth = False
|
||||||
|
requires_workspace = True
|
||||||
|
side_effects = False
|
||||||
|
min_permission = "read"
|
||||||
|
slow_operation = True
|
||||||
|
}
|
||||||
|
estimated_time = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
_taskserv_create: CommandMetadata = {
|
||||||
|
name = "taskserv create"
|
||||||
|
domain = "infrastructure"
|
||||||
|
description = "Install task service on servers"
|
||||||
|
aliases = ["taskserv c", "task create", "t create"]
|
||||||
|
requirements = {
|
||||||
|
interactive = False
|
||||||
|
requires_auth = False
|
||||||
|
requires_workspace = True
|
||||||
|
side_effects = True
|
||||||
|
side_effect_type = "create"
|
||||||
|
min_permission = "write"
|
||||||
|
slow_operation = True
|
||||||
|
}
|
||||||
|
estimated_time = 180
|
||||||
|
}
|
||||||
|
|
||||||
|
_taskserv_delete: CommandMetadata = {
|
||||||
|
name = "taskserv delete"
|
||||||
|
domain = "infrastructure"
|
||||||
|
description = "Remove task service from servers"
|
||||||
|
aliases = ["taskserv d", "task delete", "t delete"]
|
||||||
|
requirements = {
|
||||||
|
interactive = True
|
||||||
|
requires_auth = True
|
||||||
|
auth_type = "jwt"
|
||||||
|
requires_workspace = True
|
||||||
|
side_effects = True
|
||||||
|
side_effect_type = "delete"
|
||||||
|
requires_confirmation = True
|
||||||
|
min_permission = "admin"
|
||||||
|
slow_operation = True
|
||||||
|
}
|
||||||
|
form_path = "provisioning/core/shlib/forms/infrastructure/taskserv_delete_confirm.toml"
|
||||||
|
estimated_time = 60
|
||||||
|
}
|
||||||
|
|
||||||
|
_cluster_create: CommandMetadata = {
|
||||||
|
name = "cluster create"
|
||||||
|
domain = "infrastructure"
|
||||||
|
description = "Create new cluster"
|
||||||
|
aliases = ["cluster c", "create cluster", "cl create"]
|
||||||
|
requirements = {
|
||||||
|
interactive = False
|
||||||
|
requires_auth = False
|
||||||
|
requires_workspace = True
|
||||||
|
side_effects = True
|
||||||
|
side_effect_type = "create"
|
||||||
|
min_permission = "write"
|
||||||
|
slow_operation = True
|
||||||
|
}
|
||||||
|
estimated_time = 300
|
||||||
|
}
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# COMMAND DEFINITIONS - WORKSPACE
|
||||||
|
# ============================================================================
|
||||||
|
_workspace_init: CommandMetadata = {
|
||||||
|
name = "workspace init"
|
||||||
|
domain = "workspace"
|
||||||
|
description = "Initialize new workspace interactively"
|
||||||
|
aliases = ["workspace create", "ws init", "ws create"]
|
||||||
|
requirements = {
|
||||||
|
interactive = True
|
||||||
|
requires_auth = False
|
||||||
|
requires_workspace = False
|
||||||
|
side_effects = True
|
||||||
|
side_effect_type = "create"
|
||||||
|
min_permission = "write"
|
||||||
|
}
|
||||||
|
form_path = "provisioning/core/forminquire/templates/workspace-init.form.j2"
|
||||||
|
estimated_time = 30
|
||||||
|
}
|
||||||
|
|
||||||
|
_workspace_list: CommandMetadata = {
|
||||||
|
name = "workspace list"
|
||||||
|
domain = "workspace"
|
||||||
|
description = "List all registered workspaces"
|
||||||
|
aliases = ["workspace ls", "ws list", "ws ls"]
|
||||||
|
requirements = {
|
||||||
|
interactive = False
|
||||||
|
requires_auth = False
|
||||||
|
requires_workspace = False
|
||||||
|
side_effects = False
|
||||||
|
min_permission = "read"
|
||||||
|
}
|
||||||
|
estimated_time = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_workspace_switch: CommandMetadata = {
|
||||||
|
name = "workspace switch"
|
||||||
|
domain = "workspace"
|
||||||
|
description = "Switch active workspace"
|
||||||
|
aliases = ["workspace activate", "ws switch", "ws activate"]
|
||||||
|
requirements = {
|
||||||
|
interactive = False
|
||||||
|
requires_auth = False
|
||||||
|
requires_workspace = False
|
||||||
|
side_effects = False
|
||||||
|
min_permission = "read"
|
||||||
|
}
|
||||||
|
estimated_time = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# COMMAND DEFINITIONS - AUTHENTICATION
|
||||||
|
# ============================================================================
|
||||||
|
_auth_login: CommandMetadata = {
|
||||||
|
name = "auth login"
|
||||||
|
domain = "authentication"
|
||||||
|
description = "Authenticate user with JWT"
|
||||||
|
aliases = ["login"]
|
||||||
|
requirements = {
|
||||||
|
interactive = True
|
||||||
|
requires_auth = False
|
||||||
|
requires_workspace = False
|
||||||
|
side_effects = True
|
||||||
|
side_effect_type = "create"
|
||||||
|
min_permission = "read"
|
||||||
|
}
|
||||||
|
form_path = "provisioning/core/shlib/forms/authentication/auth_login.toml"
|
||||||
|
estimated_time = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
_mfa_enroll: CommandMetadata = {
|
||||||
|
name = "mfa enroll"
|
||||||
|
domain = "authentication"
|
||||||
|
description = "Enroll in multi-factor authentication"
|
||||||
|
aliases = ["mfa-enroll", "mfa setup"]
|
||||||
|
requirements = {
|
||||||
|
interactive = True
|
||||||
|
requires_auth = True
|
||||||
|
auth_type = "jwt"
|
||||||
|
requires_workspace = False
|
||||||
|
side_effects = True
|
||||||
|
side_effect_type = "create"
|
||||||
|
min_permission = "write"
|
||||||
|
}
|
||||||
|
form_path = "provisioning/core/shlib/forms/authentication/mfa_enroll.toml"
|
||||||
|
estimated_time = 30
|
||||||
|
}
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# COMMAND DEFINITIONS - CONFIGURATION/SETUP
|
||||||
|
# ============================================================================
|
||||||
|
_setup_wizard: CommandMetadata = {
|
||||||
|
name = "setup"
|
||||||
|
domain = "configuration"
|
||||||
|
description = "Interactive system setup wizard"
|
||||||
|
aliases = ["setup wizard", "st"]
|
||||||
|
requirements = {
|
||||||
|
interactive = True
|
||||||
|
requires_auth = False
|
||||||
|
requires_workspace = False
|
||||||
|
side_effects = True
|
||||||
|
side_effect_type = "create"
|
||||||
|
min_permission = "admin"
|
||||||
|
}
|
||||||
|
form_path = "provisioning/core/forminquire/templates/setup-wizard.form.j2"
|
||||||
|
estimated_time = 120
|
||||||
|
}
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# COMMAND DEFINITIONS - READ-ONLY/UTILITIES
|
||||||
|
# ============================================================================
|
||||||
|
_help_command: CommandMetadata = {
|
||||||
|
name = "help"
|
||||||
|
domain = "utilities"
|
||||||
|
description = "Show help information"
|
||||||
|
aliases = ["h", "-h", "--help"]
|
||||||
|
requirements = {
|
||||||
|
requires_workspace = False
|
||||||
|
min_permission = "read"
|
||||||
|
}
|
||||||
|
estimated_time = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_version_command: CommandMetadata = {
|
||||||
|
name = "version"
|
||||||
|
domain = "utilities"
|
||||||
|
description = "Show version information"
|
||||||
|
aliases = ["v", "-v", "--version"]
|
||||||
|
requirements = {
|
||||||
|
requires_workspace = False
|
||||||
|
min_permission = "read"
|
||||||
|
}
|
||||||
|
estimated_time = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# COMMAND REGISTRY INSTANCE
|
||||||
|
# ============================================================================
|
||||||
|
_command_registry: CommandRegistry = {
|
||||||
|
version = "1.0.0"
|
||||||
|
commands = {
|
||||||
|
# Infrastructure
|
||||||
|
"server create": _server_create
|
||||||
|
"server delete": _server_delete
|
||||||
|
"server list": _server_list
|
||||||
|
"taskserv create": _taskserv_create
|
||||||
|
"taskserv delete": _taskserv_delete
|
||||||
|
"cluster create": _cluster_create
|
||||||
|
# Workspace
|
||||||
|
"workspace init": _workspace_init
|
||||||
|
"workspace list": _workspace_list
|
||||||
|
"workspace switch": _workspace_switch
|
||||||
|
# Authentication
|
||||||
|
"auth login": _auth_login
|
||||||
|
"mfa enroll": _mfa_enroll
|
||||||
|
# Setup
|
||||||
|
"setup": _setup_wizard
|
||||||
|
# Utilities
|
||||||
|
"help": _help_command
|
||||||
|
"version": _version_command
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_command_registry
|
||||||
@ -269,7 +269,7 @@ schema DNSZone:
|
|||||||
nameservers: [str]
|
nameservers: [str]
|
||||||
|
|
||||||
# Admin email (dots replaced with @ in zone file)
|
# Admin email (dots replaced with @ in zone file)
|
||||||
admin_email: str = $"admin.{name}"
|
admin_email: str = "admin." + name
|
||||||
|
|
||||||
# DNS records
|
# DNS records
|
||||||
records: [DNSRecord] = []
|
records: [DNSRecord] = []
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
# Basic Server Configuration Example
|
# Basic Server Configuration Example
|
||||||
# Shows how to define a simple server with common settings
|
# Shows how to define a simple server with common settings
|
||||||
|
|
||||||
import ..main
|
import provisioning.server as server_mod
|
||||||
|
import provisioning.lib as lib_mod
|
||||||
|
|
||||||
# Simple web server configuration
|
# Simple web server configuration
|
||||||
web_server: main.Server = main.Server {
|
web_server: server_mod.Server = server_mod.Server {
|
||||||
hostname: "web-01"
|
hostname: "web-01"
|
||||||
title: "Production Web Server"
|
title: "Production Web Server"
|
||||||
labels: "env: prod, tier: web, role: frontend"
|
labels: "env: prod, tier: web, role: frontend"
|
||||||
@ -20,12 +21,12 @@ web_server: main.Server = main.Server {
|
|||||||
|
|
||||||
# Basic taskservs to install
|
# Basic taskservs to install
|
||||||
taskservs: [
|
taskservs: [
|
||||||
main.TaskServDef {
|
lib_mod.TaskServDef {
|
||||||
name: "nginx"
|
name: "nginx"
|
||||||
install_mode: "library"
|
install_mode: "library"
|
||||||
profile: "production"
|
profile: "production"
|
||||||
},
|
},
|
||||||
main.TaskServDef {
|
lib_mod.TaskServDef {
|
||||||
name: "prometheus-node-exporter"
|
name: "prometheus-node-exporter"
|
||||||
install_mode: "server"
|
install_mode: "server"
|
||||||
profile: "monitoring"
|
profile: "monitoring"
|
||||||
@ -34,7 +35,7 @@ web_server: main.Server = main.Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Database server with different configuration
|
# Database server with different configuration
|
||||||
db_server: main.Server = main.Server {
|
db_server: server_mod.Server = server_mod.Server {
|
||||||
hostname: "db-01"
|
hostname: "db-01"
|
||||||
title: "PostgreSQL Database Server"
|
title: "PostgreSQL Database Server"
|
||||||
labels: "env: prod, tier: data, role: database"
|
labels: "env: prod, tier: data, role: database"
|
||||||
@ -46,12 +47,12 @@ db_server: main.Server = main.Server {
|
|||||||
|
|
||||||
# Install database-related taskservs
|
# Install database-related taskservs
|
||||||
taskservs: [
|
taskservs: [
|
||||||
main.TaskServDef {
|
lib_mod.TaskServDef {
|
||||||
name: "postgresql"
|
name: "postgresql"
|
||||||
install_mode: "server"
|
install_mode: "server"
|
||||||
profile: "production"
|
profile: "production"
|
||||||
},
|
},
|
||||||
main.TaskServDef {
|
lib_mod.TaskServDef {
|
||||||
name: "postgres-exporter"
|
name: "postgres-exporter"
|
||||||
install_mode: "library"
|
install_mode: "library"
|
||||||
profile: "monitoring"
|
profile: "monitoring"
|
||||||
@ -60,7 +61,7 @@ db_server: main.Server = main.Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Development server with minimal configuration
|
# Development server with minimal configuration
|
||||||
dev_server: main.Server = main.Server {
|
dev_server: server_mod.Server = server_mod.Server {
|
||||||
hostname: "dev-01"
|
hostname: "dev-01"
|
||||||
title: "Development Server"
|
title: "Development Server"
|
||||||
labels: "env: dev, tier: development"
|
labels: "env: dev, tier: development"
|
||||||
@ -71,7 +72,7 @@ dev_server: main.Server = main.Server {
|
|||||||
delete_lock: False # Allow easy deletion for dev environments
|
delete_lock: False # Allow easy deletion for dev environments
|
||||||
|
|
||||||
taskservs: [
|
taskservs: [
|
||||||
main.TaskServDef {
|
lib_mod.TaskServDef {
|
||||||
name: "docker"
|
name: "docker"
|
||||||
install_mode: "library"
|
install_mode: "library"
|
||||||
profile: "development"
|
profile: "development"
|
||||||
|
|||||||
7
examples/kcl.mod
Normal file
7
examples/kcl.mod
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "provisioning-examples"
|
||||||
|
edition = "v0.11.3"
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
provisioning = { path = ".." }
|
||||||
5
examples/kcl.mod.lock
Normal file
5
examples/kcl.mod.lock
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[dependencies]
|
||||||
|
[dependencies.provisioning]
|
||||||
|
name = "provisioning"
|
||||||
|
full_name = "provisioning_0.0.1"
|
||||||
|
version = "0.0.1"
|
||||||
@ -1,25 +1,25 @@
|
|||||||
# Kubernetes Deployment Example
|
# Kubernetes Deployment Example
|
||||||
# Shows complete K8s deployment with services, volumes, and monitoring
|
# Shows complete K8s deployment with services, volumes, and monitoring
|
||||||
|
|
||||||
import ..main
|
import provisioning.k8s_deploy as k8s_mod
|
||||||
|
|
||||||
# Web application deployment in Kubernetes
|
# Web application deployment in Kubernetes
|
||||||
webapp_k8s: main.K8sDeploy = main.K8sDeploy {
|
webapp_k8s: k8s_mod.K8sDeploy = k8s_mod.K8sDeploy {
|
||||||
name: "webapp"
|
name: "webapp"
|
||||||
namespace: "production"
|
namespace: "production"
|
||||||
create_ns: True
|
create_ns: True
|
||||||
|
|
||||||
# Deployment specification
|
# Deployment specification
|
||||||
spec: main.K8sDeploySpec {
|
spec: k8s_mod.K8sDeploySpec {
|
||||||
replicas: 3
|
replicas: 3
|
||||||
containers: [
|
containers: [
|
||||||
main.K8sContainers {
|
k8s_mod.K8sContainers {
|
||||||
name: "webapp"
|
name: "webapp"
|
||||||
image: "nginx:1.21-alpine"
|
image: "nginx:1.21-alpine"
|
||||||
|
|
||||||
# Port configuration
|
# Port configuration
|
||||||
ports: [
|
ports: [
|
||||||
main.K8sPort {
|
k8s_mod.K8sPort {
|
||||||
name: "http"
|
name: "http"
|
||||||
container: 80
|
container: 80
|
||||||
target: 8080
|
target: 8080
|
||||||
@ -27,22 +27,22 @@ webapp_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Resource requirements
|
# Resource requirements
|
||||||
resources_requests: main.K8sResources {
|
resources_requests: k8s_mod.K8sResources {
|
||||||
memory: "64Mi"
|
memory: "64Mi"
|
||||||
cpu: "50m"
|
cpu: "50m"
|
||||||
}
|
}
|
||||||
resources_limits: main.K8sResources {
|
resources_limits: k8s_mod.K8sResources {
|
||||||
memory: "128Mi"
|
memory: "128Mi"
|
||||||
cpu: "100m"
|
cpu: "100m"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Environment variables
|
# Environment variables
|
||||||
env: [
|
env: [
|
||||||
main.K8sKeyVal {
|
k8s_mod.K8sKeyVal {
|
||||||
key: "NODE_ENV"
|
key: "NODE_ENV"
|
||||||
value: "production"
|
value: "production"
|
||||||
},
|
},
|
||||||
main.K8sKeyVal {
|
k8s_mod.K8sKeyVal {
|
||||||
key: "LOG_LEVEL"
|
key: "LOG_LEVEL"
|
||||||
value: "info"
|
value: "info"
|
||||||
}
|
}
|
||||||
@ -50,7 +50,7 @@ webapp_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
|
|
||||||
# Mount configuration volume
|
# Mount configuration volume
|
||||||
volumeMounts: [
|
volumeMounts: [
|
||||||
main.K8sVolumeMount {
|
k8s_mod.K8sVolumeMount {
|
||||||
name: "config"
|
name: "config"
|
||||||
mountPath: "/etc/nginx/conf.d"
|
mountPath: "/etc/nginx/conf.d"
|
||||||
readOnly: True
|
readOnly: True
|
||||||
@ -61,10 +61,10 @@ webapp_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
|
|
||||||
# Volume configuration
|
# Volume configuration
|
||||||
volumes: [
|
volumes: [
|
||||||
main.K8sVolume {
|
k8s_mod.K8sVolume {
|
||||||
name: "config"
|
name: "config"
|
||||||
typ: "configMap"
|
typ: "configMap"
|
||||||
configMap: main.K8sConfigMap {
|
configMap: k8s_mod.K8sConfigMap {
|
||||||
name: "webapp-config"
|
name: "webapp-config"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,19 +72,19 @@ webapp_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
|
|
||||||
# Node selection for production workloads
|
# Node selection for production workloads
|
||||||
nodeSelector: [
|
nodeSelector: [
|
||||||
main.K8sKeyVal {
|
k8s_mod.K8sKeyVal {
|
||||||
key: "node-type"
|
key: "node-type"
|
||||||
value: "production"
|
value: "production"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
# Anti-affinity to spread pods across nodes
|
# Anti-affinity to spread pods across nodes
|
||||||
affinity: main.K8sAffinity {
|
affinity: k8s_mod.K8sAffinity {
|
||||||
antiAffinity: main.K8sAntyAffinityLabelSelector {
|
antiAffinity: k8s_mod.K8sAntyAffinityLabelSelector {
|
||||||
typ: "preferredDuringSchedulingIgnoredDuringExecution"
|
typ: "preferredDuringSchedulingIgnoredDuringExecution"
|
||||||
weight: 100
|
weight: 100
|
||||||
labelSelector: [
|
labelSelector: [
|
||||||
main.K8sAffinityMatch {
|
k8s_mod.K8sAffinityMatch {
|
||||||
key: "app"
|
key: "app"
|
||||||
operator: "In"
|
operator: "In"
|
||||||
values: ["webapp"]
|
values: ["webapp"]
|
||||||
@ -96,18 +96,18 @@ webapp_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Service configuration
|
# Service configuration
|
||||||
service: main.K8sService {
|
service: k8s_mod.K8sService {
|
||||||
name: "webapp-service"
|
name: "webapp-service"
|
||||||
typ: "ClusterIP"
|
typ: "ClusterIP"
|
||||||
ports: [
|
ports: [
|
||||||
main.K8sPort {
|
k8s_mod.K8sPort {
|
||||||
name: "http"
|
name: "http"
|
||||||
target: 80
|
target: 80
|
||||||
nodePort: 30080
|
nodePort: 30080
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
selector: [
|
selector: [
|
||||||
main.K8sKeyVal {
|
k8s_mod.K8sKeyVal {
|
||||||
key: "app"
|
key: "app"
|
||||||
value: "webapp"
|
value: "webapp"
|
||||||
}
|
}
|
||||||
@ -116,15 +116,15 @@ webapp_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
|
|
||||||
# Labels for the deployment
|
# Labels for the deployment
|
||||||
labels: [
|
labels: [
|
||||||
main.K8sKeyVal {
|
k8s_mod.K8sKeyVal {
|
||||||
key: "app"
|
key: "app"
|
||||||
value: "webapp"
|
value: "webapp"
|
||||||
},
|
},
|
||||||
main.K8sKeyVal {
|
k8s_mod.K8sKeyVal {
|
||||||
key: "version"
|
key: "version"
|
||||||
value: "v1.0.0"
|
value: "v1.0.0"
|
||||||
},
|
},
|
||||||
main.K8sKeyVal {
|
k8s_mod.K8sKeyVal {
|
||||||
key: "environment"
|
key: "environment"
|
||||||
value: "production"
|
value: "production"
|
||||||
}
|
}
|
||||||
@ -132,19 +132,19 @@ webapp_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Database deployment with persistent storage
|
# Database deployment with persistent storage
|
||||||
database_k8s: main.K8sDeploy = main.K8sDeploy {
|
database_k8s: k8s_mod.K8sDeploy = k8s_mod.K8sDeploy {
|
||||||
name: "postgres"
|
name: "postgres"
|
||||||
namespace: "production"
|
namespace: "production"
|
||||||
|
|
||||||
spec: main.K8sDeploySpec {
|
spec: k8s_mod.K8sDeploySpec {
|
||||||
replicas: 1 # Database typically runs single instance
|
replicas: 1 # Database typically runs single instance
|
||||||
containers: [
|
containers: [
|
||||||
main.K8sContainers {
|
k8s_mod.K8sContainers {
|
||||||
name: "postgres"
|
name: "postgres"
|
||||||
image: "postgres:15-alpine"
|
image: "postgres:15-alpine"
|
||||||
|
|
||||||
ports: [
|
ports: [
|
||||||
main.K8sPort {
|
k8s_mod.K8sPort {
|
||||||
name: "postgres"
|
name: "postgres"
|
||||||
container: 5432
|
container: 5432
|
||||||
target: 5432
|
target: 5432
|
||||||
@ -152,26 +152,26 @@ database_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Database needs more resources
|
# Database needs more resources
|
||||||
resources_requests: main.K8sResources {
|
resources_requests: k8s_mod.K8sResources {
|
||||||
memory: "256Mi"
|
memory: "256Mi"
|
||||||
cpu: "100m"
|
cpu: "100m"
|
||||||
}
|
}
|
||||||
resources_limits: main.K8sResources {
|
resources_limits: k8s_mod.K8sResources {
|
||||||
memory: "512Mi"
|
memory: "512Mi"
|
||||||
cpu: "500m"
|
cpu: "500m"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Database environment
|
# Database environment
|
||||||
env: [
|
env: [
|
||||||
main.K8sKeyVal {
|
k8s_mod.K8sKeyVal {
|
||||||
key: "POSTGRES_DB"
|
key: "POSTGRES_DB"
|
||||||
value: "webapp"
|
value: "webapp"
|
||||||
},
|
},
|
||||||
main.K8sKeyVal {
|
k8s_mod.K8sKeyVal {
|
||||||
key: "POSTGRES_USER"
|
key: "POSTGRES_USER"
|
||||||
value: "webapp"
|
value: "webapp"
|
||||||
},
|
},
|
||||||
main.K8sKeyVal {
|
k8s_mod.K8sKeyVal {
|
||||||
key: "POSTGRES_PASSWORD"
|
key: "POSTGRES_PASSWORD"
|
||||||
value: "changeme" # Use secrets in production
|
value: "changeme" # Use secrets in production
|
||||||
}
|
}
|
||||||
@ -179,7 +179,7 @@ database_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
|
|
||||||
# Persistent data volume
|
# Persistent data volume
|
||||||
volumeMounts: [
|
volumeMounts: [
|
||||||
main.K8sVolumeMount {
|
k8s_mod.K8sVolumeMount {
|
||||||
name: "postgres-data"
|
name: "postgres-data"
|
||||||
mountPath: "/var/lib/postgresql/data"
|
mountPath: "/var/lib/postgresql/data"
|
||||||
readOnly: False
|
readOnly: False
|
||||||
@ -190,10 +190,10 @@ database_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
|
|
||||||
# Persistent volume for database
|
# Persistent volume for database
|
||||||
volumes: [
|
volumes: [
|
||||||
main.K8sVolume {
|
k8s_mod.K8sVolume {
|
||||||
name: "postgres-data"
|
name: "postgres-data"
|
||||||
typ: "volumeClaim"
|
typ: "volumeClaim"
|
||||||
persitentVolumeClaim: main.K8sVolumeClaim {
|
persistentVolumeClaim: k8s_mod.K8sVolumeClaim {
|
||||||
name: "postgres-pvc"
|
name: "postgres-pvc"
|
||||||
storageClassName: "manual"
|
storageClassName: "manual"
|
||||||
storage: "10Gi"
|
storage: "10Gi"
|
||||||
@ -205,17 +205,17 @@ database_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Internal service for database
|
# Internal service for database
|
||||||
service: main.K8sService {
|
service: k8s_mod.K8sService {
|
||||||
name: "postgres-service"
|
name: "postgres-service"
|
||||||
typ: "ClusterIP"
|
typ: "ClusterIP"
|
||||||
ports: [
|
ports: [
|
||||||
main.K8sPort {
|
k8s_mod.K8sPort {
|
||||||
name: "postgres"
|
name: "postgres"
|
||||||
target: 5432
|
target: 5432
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
selector: [
|
selector: [
|
||||||
main.K8sKeyVal {
|
k8s_mod.K8sKeyVal {
|
||||||
key: "app"
|
key: "app"
|
||||||
value: "postgres"
|
value: "postgres"
|
||||||
}
|
}
|
||||||
@ -223,11 +223,11 @@ database_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
labels: [
|
labels: [
|
||||||
main.K8sKeyVal {
|
k8s_mod.K8sKeyVal {
|
||||||
key: "app"
|
key: "app"
|
||||||
value: "postgres"
|
value: "postgres"
|
||||||
},
|
},
|
||||||
main.K8sKeyVal {
|
k8s_mod.K8sKeyVal {
|
||||||
key: "component"
|
key: "component"
|
||||||
value: "database"
|
value: "database"
|
||||||
}
|
}
|
||||||
@ -235,42 +235,42 @@ database_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Monitoring deployment using Prometheus
|
# Monitoring deployment using Prometheus
|
||||||
monitoring_k8s: main.K8sDeploy = main.K8sDeploy {
|
monitoring_k8s: k8s_mod.K8sDeploy = k8s_mod.K8sDeploy {
|
||||||
name: "prometheus"
|
name: "prometheus"
|
||||||
namespace: "monitoring"
|
namespace: "monitoring"
|
||||||
create_ns: True
|
create_ns: True
|
||||||
|
|
||||||
spec: main.K8sDeploySpec {
|
spec: k8s_mod.K8sDeploySpec {
|
||||||
replicas: 1
|
replicas: 1
|
||||||
containers: [
|
containers: [
|
||||||
main.K8sContainers {
|
k8s_mod.K8sContainers {
|
||||||
name: "prometheus"
|
name: "prometheus"
|
||||||
image: "prom/prometheus:v2.40.0"
|
image: "prom/prometheus:v2.40.0"
|
||||||
|
|
||||||
ports: [
|
ports: [
|
||||||
main.K8sPort {
|
k8s_mod.K8sPort {
|
||||||
name: "web"
|
name: "web"
|
||||||
container: 9090
|
container: 9090
|
||||||
target: 9090
|
target: 9090
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
resources_requests: main.K8sResources {
|
resources_requests: k8s_mod.K8sResources {
|
||||||
memory: "512Mi"
|
memory: "512Mi"
|
||||||
cpu: "200m"
|
cpu: "200m"
|
||||||
}
|
}
|
||||||
resources_limits: main.K8sResources {
|
resources_limits: k8s_mod.K8sResources {
|
||||||
memory: "1Gi"
|
memory: "1Gi"
|
||||||
cpu: "500m"
|
cpu: "500m"
|
||||||
}
|
}
|
||||||
|
|
||||||
volumeMounts: [
|
volumeMounts: [
|
||||||
main.K8sVolumeMount {
|
k8s_mod.K8sVolumeMount {
|
||||||
name: "prometheus-config"
|
name: "prometheus-config"
|
||||||
mountPath: "/etc/prometheus"
|
mountPath: "/etc/prometheus"
|
||||||
readOnly: True
|
readOnly: True
|
||||||
},
|
},
|
||||||
main.K8sVolumeMount {
|
k8s_mod.K8sVolumeMount {
|
||||||
name: "prometheus-data"
|
name: "prometheus-data"
|
||||||
mountPath: "/prometheus"
|
mountPath: "/prometheus"
|
||||||
readOnly: False
|
readOnly: False
|
||||||
@ -280,17 +280,17 @@ monitoring_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
]
|
]
|
||||||
|
|
||||||
volumes: [
|
volumes: [
|
||||||
main.K8sVolume {
|
k8s_mod.K8sVolume {
|
||||||
name: "prometheus-config"
|
name: "prometheus-config"
|
||||||
typ: "configMap"
|
typ: "configMap"
|
||||||
configMap: main.K8sConfigMap {
|
configMap: k8s_mod.K8sConfigMap {
|
||||||
name: "prometheus-config"
|
name: "prometheus-config"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
main.K8sVolume {
|
k8s_mod.K8sVolume {
|
||||||
name: "prometheus-data"
|
name: "prometheus-data"
|
||||||
typ: "volumeClaim"
|
typ: "volumeClaim"
|
||||||
persitentVolumeClaim: main.K8sVolumeClaim {
|
persistentVolumeClaim: k8s_mod.K8sVolumeClaim {
|
||||||
name: "prometheus-pvc"
|
name: "prometheus-pvc"
|
||||||
storage: "20Gi"
|
storage: "20Gi"
|
||||||
storageClassName: "manual"
|
storageClassName: "manual"
|
||||||
@ -300,11 +300,11 @@ monitoring_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
service: main.K8sService {
|
service: k8s_mod.K8sService {
|
||||||
name: "prometheus-service"
|
name: "prometheus-service"
|
||||||
typ: "NodePort"
|
typ: "NodePort"
|
||||||
ports: [
|
ports: [
|
||||||
main.K8sPort {
|
k8s_mod.K8sPort {
|
||||||
name: "web"
|
name: "web"
|
||||||
target: 9090
|
target: 9090
|
||||||
nodePort: 30090
|
nodePort: 30090
|
||||||
@ -313,11 +313,11 @@ monitoring_k8s: main.K8sDeploy = main.K8sDeploy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
labels: [
|
labels: [
|
||||||
main.K8sKeyVal {
|
k8s_mod.K8sKeyVal {
|
||||||
key: "app"
|
key: "app"
|
||||||
value: "prometheus"
|
value: "prometheus"
|
||||||
},
|
},
|
||||||
main.K8sKeyVal {
|
k8s_mod.K8sKeyVal {
|
||||||
key: "component"
|
key: "component"
|
||||||
value: "monitoring"
|
value: "monitoring"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,19 @@
|
|||||||
# Mixed Provider Workflow Example
|
# Mixed Provider Workflow Example
|
||||||
# Demonstrates deployment across multiple cloud providers with advanced features
|
# Demonstrates deployment across multiple cloud providers with advanced features
|
||||||
|
|
||||||
import ..main
|
import provisioning.workflows as workflows_mod
|
||||||
|
import provisioning.batch as batch_mod
|
||||||
|
import provisioning.settings as settings_mod
|
||||||
|
|
||||||
# Production deployment across UpCloud and AWS
|
# Production deployment across UpCloud and AWS
|
||||||
production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
production_deployment: workflows_mod.BatchWorkflow = workflows_mod.BatchWorkflow {
|
||||||
workflow_id: "prod_multicloud_001"
|
workflow_id: "prod_multicloud_001"
|
||||||
name: "Production Multi-Cloud Deployment"
|
name: "Production Multi-Cloud Deployment"
|
||||||
description: "Deploy production infrastructure across UpCloud (compute) and AWS (managed services)"
|
description: "Deploy production infrastructure across UpCloud (compute) and AWS (managed services)"
|
||||||
|
|
||||||
operations: [
|
operations: [
|
||||||
# Phase 1: Create UpCloud infrastructure
|
# Phase 1: Create UpCloud infrastructure
|
||||||
main.BatchOperation {
|
workflows_mod.BatchOperation {
|
||||||
operation_id: "upcloud_network"
|
operation_id: "upcloud_network"
|
||||||
name: "Create UpCloud Network Infrastructure"
|
name: "Create UpCloud Network Infrastructure"
|
||||||
operation_type: "custom"
|
operation_type: "custom"
|
||||||
@ -27,7 +29,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
timeout: 300
|
timeout: 300
|
||||||
}
|
}
|
||||||
|
|
||||||
main.BatchOperation {
|
workflows_mod.BatchOperation {
|
||||||
operation_id: "upcloud_compute"
|
operation_id: "upcloud_compute"
|
||||||
name: "Create UpCloud Compute Instances"
|
name: "Create UpCloud Compute Instances"
|
||||||
operation_type: "server"
|
operation_type: "server"
|
||||||
@ -41,7 +43,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
"server_type": "k8s-worker"
|
"server_type": "k8s-worker"
|
||||||
}
|
}
|
||||||
dependencies: [
|
dependencies: [
|
||||||
main.DependencyDef {
|
workflows_mod.DependencyDef {
|
||||||
target_operation_id: "upcloud_network"
|
target_operation_id: "upcloud_network"
|
||||||
dependency_type: "sequential"
|
dependency_type: "sequential"
|
||||||
timeout: 300
|
timeout: 300
|
||||||
@ -53,7 +55,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Phase 2: Create AWS managed services
|
# Phase 2: Create AWS managed services
|
||||||
main.BatchOperation {
|
workflows_mod.BatchOperation {
|
||||||
operation_id: "aws_database"
|
operation_id: "aws_database"
|
||||||
name: "Create AWS RDS PostgreSQL"
|
name: "Create AWS RDS PostgreSQL"
|
||||||
operation_type: "server"
|
operation_type: "server"
|
||||||
@ -74,7 +76,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
allow_parallel: True
|
allow_parallel: True
|
||||||
}
|
}
|
||||||
|
|
||||||
main.BatchOperation {
|
workflows_mod.BatchOperation {
|
||||||
operation_id: "aws_redis"
|
operation_id: "aws_redis"
|
||||||
name: "Create AWS ElastiCache Redis"
|
name: "Create AWS ElastiCache Redis"
|
||||||
operation_type: "server"
|
operation_type: "server"
|
||||||
@ -94,7 +96,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Phase 3: Set up Kubernetes cluster on UpCloud
|
# Phase 3: Set up Kubernetes cluster on UpCloud
|
||||||
main.BatchOperation {
|
workflows_mod.BatchOperation {
|
||||||
operation_id: "install_k8s_control"
|
operation_id: "install_k8s_control"
|
||||||
name: "Install Kubernetes Control Plane"
|
name: "Install Kubernetes Control Plane"
|
||||||
operation_type: "taskserv"
|
operation_type: "taskserv"
|
||||||
@ -109,7 +111,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
"container_runtime": "containerd"
|
"container_runtime": "containerd"
|
||||||
}
|
}
|
||||||
dependencies: [
|
dependencies: [
|
||||||
main.DependencyDef {
|
workflows_mod.DependencyDef {
|
||||||
target_operation_id: "upcloud_compute"
|
target_operation_id: "upcloud_compute"
|
||||||
dependency_type: "sequential"
|
dependency_type: "sequential"
|
||||||
timeout: 600
|
timeout: 600
|
||||||
@ -119,7 +121,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
timeout: 1800
|
timeout: 1800
|
||||||
}
|
}
|
||||||
|
|
||||||
main.BatchOperation {
|
workflows_mod.BatchOperation {
|
||||||
operation_id: "install_k8s_workers"
|
operation_id: "install_k8s_workers"
|
||||||
name: "Install Kubernetes Worker Nodes"
|
name: "Install Kubernetes Worker Nodes"
|
||||||
operation_type: "taskserv"
|
operation_type: "taskserv"
|
||||||
@ -133,7 +135,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
"join_existing": "true"
|
"join_existing": "true"
|
||||||
}
|
}
|
||||||
dependencies: [
|
dependencies: [
|
||||||
main.DependencyDef {
|
workflows_mod.DependencyDef {
|
||||||
target_operation_id: "install_k8s_control"
|
target_operation_id: "install_k8s_control"
|
||||||
dependency_type: "sequential"
|
dependency_type: "sequential"
|
||||||
timeout: 300
|
timeout: 300
|
||||||
@ -144,7 +146,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Phase 4: Install cluster services
|
# Phase 4: Install cluster services
|
||||||
main.BatchOperation {
|
workflows_mod.BatchOperation {
|
||||||
operation_id: "install_networking"
|
operation_id: "install_networking"
|
||||||
name: "Install Cluster Networking"
|
name: "Install Cluster Networking"
|
||||||
operation_type: "taskserv"
|
operation_type: "taskserv"
|
||||||
@ -156,7 +158,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
"enable_hubble": "true"
|
"enable_hubble": "true"
|
||||||
}
|
}
|
||||||
dependencies: [
|
dependencies: [
|
||||||
main.DependencyDef {
|
workflows_mod.DependencyDef {
|
||||||
target_operation_id: "install_k8s_workers"
|
target_operation_id: "install_k8s_workers"
|
||||||
dependency_type: "sequential"
|
dependency_type: "sequential"
|
||||||
timeout: 300
|
timeout: 300
|
||||||
@ -166,7 +168,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
timeout: 600
|
timeout: 600
|
||||||
}
|
}
|
||||||
|
|
||||||
main.BatchOperation {
|
workflows_mod.BatchOperation {
|
||||||
operation_id: "install_monitoring"
|
operation_id: "install_monitoring"
|
||||||
name: "Install Monitoring Stack"
|
name: "Install Monitoring Stack"
|
||||||
operation_type: "taskserv"
|
operation_type: "taskserv"
|
||||||
@ -178,7 +180,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
"node_exporter_enabled": "true"
|
"node_exporter_enabled": "true"
|
||||||
}
|
}
|
||||||
dependencies: [
|
dependencies: [
|
||||||
main.DependencyDef {
|
workflows_mod.DependencyDef {
|
||||||
target_operation_id: "install_networking"
|
target_operation_id: "install_networking"
|
||||||
dependency_type: "sequential"
|
dependency_type: "sequential"
|
||||||
timeout: 180
|
timeout: 180
|
||||||
@ -189,7 +191,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Phase 5: Configure cross-cloud connectivity
|
# Phase 5: Configure cross-cloud connectivity
|
||||||
main.BatchOperation {
|
workflows_mod.BatchOperation {
|
||||||
operation_id: "configure_connectivity"
|
operation_id: "configure_connectivity"
|
||||||
name: "Configure Cross-Cloud Connectivity"
|
name: "Configure Cross-Cloud Connectivity"
|
||||||
operation_type: "custom"
|
operation_type: "custom"
|
||||||
@ -202,12 +204,12 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
"routing": "bgp"
|
"routing": "bgp"
|
||||||
}
|
}
|
||||||
dependencies: [
|
dependencies: [
|
||||||
main.DependencyDef {
|
workflows_mod.DependencyDef {
|
||||||
target_operation_id: "aws_database"
|
target_operation_id: "aws_database"
|
||||||
dependency_type: "sequential"
|
dependency_type: "sequential"
|
||||||
timeout: 60
|
timeout: 60
|
||||||
},
|
},
|
||||||
main.DependencyDef {
|
workflows_mod.DependencyDef {
|
||||||
target_operation_id: "install_monitoring"
|
target_operation_id: "install_monitoring"
|
||||||
dependency_type: "sequential"
|
dependency_type: "sequential"
|
||||||
timeout: 60
|
timeout: 60
|
||||||
@ -218,7 +220,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Phase 6: Final validation
|
# Phase 6: Final validation
|
||||||
main.BatchOperation {
|
workflows_mod.BatchOperation {
|
||||||
operation_id: "validate_deployment"
|
operation_id: "validate_deployment"
|
||||||
name: "Validate Complete Deployment"
|
name: "Validate Complete Deployment"
|
||||||
operation_type: "custom"
|
operation_type: "custom"
|
||||||
@ -231,7 +233,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
"test_monitoring": "true"
|
"test_monitoring": "true"
|
||||||
}
|
}
|
||||||
dependencies: [
|
dependencies: [
|
||||||
main.DependencyDef {
|
workflows_mod.DependencyDef {
|
||||||
target_operation_id: "configure_connectivity"
|
target_operation_id: "configure_connectivity"
|
||||||
dependency_type: "sequential"
|
dependency_type: "sequential"
|
||||||
timeout: 300
|
timeout: 300
|
||||||
@ -248,7 +250,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
fail_fast: False # Continue on non-critical failures
|
fail_fast: False # Continue on non-critical failures
|
||||||
|
|
||||||
# SurrealDB for persistent state
|
# SurrealDB for persistent state
|
||||||
storage: main.StorageConfig {
|
storage: workflows_mod.StorageConfig {
|
||||||
backend: "surrealdb"
|
backend: "surrealdb"
|
||||||
connection_config: {
|
connection_config: {
|
||||||
"url": "ws://surrealdb.internal:8000"
|
"url": "ws://surrealdb.internal:8000"
|
||||||
@ -260,9 +262,9 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
enable_persistence: True
|
enable_persistence: True
|
||||||
retention_hours: 2160 # 90 days for production
|
retention_hours: 2160 # 90 days for production
|
||||||
enable_compression: True
|
enable_compression: True
|
||||||
encryption: main.SecretProvider {
|
encryption: settings_mod.SecretProvider {
|
||||||
provider: "sops"
|
provider: "sops"
|
||||||
sops_config: main.SopsConfig {
|
sops_config: settings_mod.SopsConfig {
|
||||||
config_path: "./.sops.yaml"
|
config_path: "./.sops.yaml"
|
||||||
age_key_file: "{{env.HOME}}/.config/sops/age/keys.txt"
|
age_key_file: "{{env.HOME}}/.config/sops/age/keys.txt"
|
||||||
use_age: True
|
use_age: True
|
||||||
@ -271,7 +273,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Comprehensive monitoring
|
# Comprehensive monitoring
|
||||||
monitoring: main.MonitoringConfig {
|
monitoring: workflows_mod.MonitoringConfig {
|
||||||
enabled: True
|
enabled: True
|
||||||
backend: "prometheus"
|
backend: "prometheus"
|
||||||
enable_tracing: True
|
enable_tracing: True
|
||||||
@ -286,7 +288,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Production-grade retry policy
|
# Production-grade retry policy
|
||||||
default_retry_policy: main.RetryPolicy {
|
default_retry_policy: workflows_mod.RetryPolicy {
|
||||||
max_attempts: 3
|
max_attempts: 3
|
||||||
initial_delay: 60
|
initial_delay: 60
|
||||||
max_delay: 600
|
max_delay: 600
|
||||||
@ -302,7 +304,7 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Conservative rollback strategy
|
# Conservative rollback strategy
|
||||||
default_rollback_strategy: main.RollbackStrategy {
|
default_rollback_strategy: workflows_mod.RollbackStrategy {
|
||||||
enabled: True
|
enabled: True
|
||||||
strategy: "manual" # Manual approval for production rollbacks
|
strategy: "manual" # Manual approval for production rollbacks
|
||||||
preserve_partial_state: True
|
preserve_partial_state: True
|
||||||
@ -340,12 +342,12 @@ production_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Advanced batch executor configuration for this workflow
|
# Advanced batch executor configuration for this workflow
|
||||||
multicloud_executor: main.BatchExecutor = main.BatchExecutor {
|
multicloud_executor: batch_mod.BatchExecutor = batch_mod.BatchExecutor {
|
||||||
executor_id: "multicloud_prod_executor"
|
executor_id: "multicloud_prod_executor"
|
||||||
name: "Multi-Cloud Production Executor"
|
name: "Multi-Cloud Production Executor"
|
||||||
description: "Production-ready executor for multi-cloud deployments"
|
description: "Production-ready executor for multi-cloud deployments"
|
||||||
|
|
||||||
scheduler: main.BatchScheduler {
|
scheduler: batch_mod.BatchScheduler {
|
||||||
strategy: "resource_aware"
|
strategy: "resource_aware"
|
||||||
resource_limits: {
|
resource_limits: {
|
||||||
"max_cpu_cores": 32
|
"max_cpu_cores": 32
|
||||||
@ -359,14 +361,14 @@ multicloud_executor: main.BatchExecutor = main.BatchExecutor {
|
|||||||
|
|
||||||
# Multiple queues for different priorities
|
# Multiple queues for different priorities
|
||||||
queues: [
|
queues: [
|
||||||
main.BatchQueue {
|
batch_mod.BatchQueue {
|
||||||
queue_id: "critical"
|
queue_id: "critical"
|
||||||
queue_type: "priority"
|
queue_type: "priority"
|
||||||
max_size: 50
|
max_size: 50
|
||||||
retention_period: 86400
|
retention_period: 86400
|
||||||
max_delivery_attempts: 5
|
max_delivery_attempts: 5
|
||||||
},
|
},
|
||||||
main.BatchQueue {
|
batch_mod.BatchQueue {
|
||||||
queue_id: "standard"
|
queue_id: "standard"
|
||||||
queue_type: "standard"
|
queue_type: "standard"
|
||||||
max_size: 200
|
max_size: 200
|
||||||
@ -377,7 +379,7 @@ multicloud_executor: main.BatchExecutor = main.BatchExecutor {
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Mixed provider configuration
|
# Mixed provider configuration
|
||||||
provider_config: main.ProviderMixConfig {
|
provider_config: batch_mod.ProviderMixConfig {
|
||||||
primary_provider: "upcloud"
|
primary_provider: "upcloud"
|
||||||
secondary_providers: ["aws"]
|
secondary_providers: ["aws"]
|
||||||
provider_selection: "cost_optimize"
|
provider_selection: "cost_optimize"
|
||||||
@ -390,18 +392,18 @@ multicloud_executor: main.BatchExecutor = main.BatchExecutor {
|
|||||||
"upcloud": {
|
"upcloud": {
|
||||||
"max_servers": 50
|
"max_servers": 50
|
||||||
"max_storage_gb": 10000
|
"max_storage_gb": 10000
|
||||||
"api_rate_limit": "100/min"
|
"api_rate_limit": 100
|
||||||
}
|
}
|
||||||
"aws": {
|
"aws": {
|
||||||
"max_instances": 20
|
"max_instances": 20
|
||||||
"max_ebs_gb": 5000
|
"max_ebs_gb": 5000
|
||||||
"api_rate_limit": "1000/min"
|
"api_rate_limit": 1000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Production health monitoring
|
# Production health monitoring
|
||||||
health_check: main.BatchHealthCheck {
|
health_check: batch_mod.BatchHealthCheck {
|
||||||
enabled: True
|
enabled: True
|
||||||
check_interval: 30
|
check_interval: 30
|
||||||
check_timeout: 15
|
check_timeout: 15
|
||||||
@ -421,7 +423,7 @@ multicloud_executor: main.BatchExecutor = main.BatchExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Intelligent autoscaling
|
# Intelligent autoscaling
|
||||||
autoscaling: main.BatchAutoscaling {
|
autoscaling: batch_mod.BatchAutoscaling {
|
||||||
enabled: True
|
enabled: True
|
||||||
min_parallel: 3
|
min_parallel: 3
|
||||||
max_parallel: 15
|
max_parallel: 15
|
||||||
@ -432,7 +434,7 @@ multicloud_executor: main.BatchExecutor = main.BatchExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Comprehensive metrics
|
# Comprehensive metrics
|
||||||
metrics: main.BatchMetrics {
|
metrics: batch_mod.BatchMetrics {
|
||||||
detailed_metrics: True
|
detailed_metrics: True
|
||||||
retention_hours: 2160 # 90 days
|
retention_hours: 2160 # 90 days
|
||||||
aggregation_intervals: [60, 300, 1800, 3600, 86400]
|
aggregation_intervals: [60, 300, 1800, 3600, 86400]
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
# Simple Workflow Example
|
# Simple Workflow Example
|
||||||
# Demonstrates basic workflow creation with sequential operations
|
# Demonstrates basic workflow creation with sequential operations
|
||||||
|
|
||||||
import ..main
|
import provisioning.workflows as workflows_mod
|
||||||
|
|
||||||
# Simple web application deployment workflow
|
# Simple web application deployment workflow
|
||||||
web_app_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
web_app_deployment: workflows_mod.BatchWorkflow = workflows_mod.BatchWorkflow {
|
||||||
workflow_id: "webapp_deploy_001"
|
workflow_id: "webapp_deploy_001"
|
||||||
name: "Web Application Deployment"
|
name: "Web Application Deployment"
|
||||||
description: "Deploy a simple web application with database backend"
|
description: "Deploy a simple web application with database backend"
|
||||||
|
|
||||||
operations: [
|
operations: [
|
||||||
# Step 1: Create database server
|
# Step 1: Create database server
|
||||||
main.BatchOperation {
|
workflows_mod.BatchOperation {
|
||||||
operation_id: "create_database"
|
operation_id: "create_database"
|
||||||
name: "Create Database Server"
|
name: "Create Database Server"
|
||||||
operation_type: "server"
|
operation_type: "server"
|
||||||
@ -28,7 +28,7 @@ web_app_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Step 2: Create web servers (can run in parallel)
|
# Step 2: Create web servers (can run in parallel)
|
||||||
main.BatchOperation {
|
workflows_mod.BatchOperation {
|
||||||
operation_id: "create_web_servers"
|
operation_id: "create_web_servers"
|
||||||
name: "Create Web Servers"
|
name: "Create Web Servers"
|
||||||
operation_type: "server"
|
operation_type: "server"
|
||||||
@ -47,7 +47,7 @@ web_app_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Step 3: Install database after database server is ready
|
# Step 3: Install database after database server is ready
|
||||||
main.BatchOperation {
|
workflows_mod.BatchOperation {
|
||||||
operation_id: "install_database"
|
operation_id: "install_database"
|
||||||
name: "Install PostgreSQL"
|
name: "Install PostgreSQL"
|
||||||
operation_type: "taskserv"
|
operation_type: "taskserv"
|
||||||
@ -58,7 +58,7 @@ web_app_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
"target_servers": "webapp-db"
|
"target_servers": "webapp-db"
|
||||||
}
|
}
|
||||||
dependencies: [
|
dependencies: [
|
||||||
main.DependencyDef {
|
workflows_mod.DependencyDef {
|
||||||
target_operation_id: "create_database"
|
target_operation_id: "create_database"
|
||||||
dependency_type: "sequential"
|
dependency_type: "sequential"
|
||||||
timeout: 300
|
timeout: 300
|
||||||
@ -69,7 +69,7 @@ web_app_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Step 4: Install web stack after web servers are ready
|
# Step 4: Install web stack after web servers are ready
|
||||||
main.BatchOperation {
|
workflows_mod.BatchOperation {
|
||||||
operation_id: "install_web_stack"
|
operation_id: "install_web_stack"
|
||||||
name: "Install Web Stack"
|
name: "Install Web Stack"
|
||||||
operation_type: "taskserv"
|
operation_type: "taskserv"
|
||||||
@ -80,7 +80,7 @@ web_app_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
"config_template": "reverse_proxy"
|
"config_template": "reverse_proxy"
|
||||||
}
|
}
|
||||||
dependencies: [
|
dependencies: [
|
||||||
main.DependencyDef {
|
workflows_mod.DependencyDef {
|
||||||
target_operation_id: "create_web_servers"
|
target_operation_id: "create_web_servers"
|
||||||
dependency_type: "sequential"
|
dependency_type: "sequential"
|
||||||
timeout: 300
|
timeout: 300
|
||||||
@ -91,7 +91,7 @@ web_app_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Step 5: Configure application after all components are ready
|
# Step 5: Configure application after all components are ready
|
||||||
main.BatchOperation {
|
workflows_mod.BatchOperation {
|
||||||
operation_id: "configure_application"
|
operation_id: "configure_application"
|
||||||
name: "Configure Web Application"
|
name: "Configure Web Application"
|
||||||
operation_type: "custom"
|
operation_type: "custom"
|
||||||
@ -102,12 +102,12 @@ web_app_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
"web_servers": "webapp-web-01,webapp-web-02"
|
"web_servers": "webapp-web-01,webapp-web-02"
|
||||||
}
|
}
|
||||||
dependencies: [
|
dependencies: [
|
||||||
main.DependencyDef {
|
workflows_mod.DependencyDef {
|
||||||
target_operation_id: "install_database"
|
target_operation_id: "install_database"
|
||||||
dependency_type: "sequential"
|
dependency_type: "sequential"
|
||||||
timeout: 60
|
timeout: 60
|
||||||
},
|
},
|
||||||
main.DependencyDef {
|
workflows_mod.DependencyDef {
|
||||||
target_operation_id: "install_web_stack"
|
target_operation_id: "install_web_stack"
|
||||||
dependency_type: "sequential"
|
dependency_type: "sequential"
|
||||||
timeout: 60
|
timeout: 60
|
||||||
@ -124,7 +124,7 @@ web_app_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
fail_fast: True # Stop on first failure
|
fail_fast: True # Stop on first failure
|
||||||
|
|
||||||
# Simple filesystem storage for this example
|
# Simple filesystem storage for this example
|
||||||
storage: main.StorageConfig {
|
storage: workflows_mod.StorageConfig {
|
||||||
backend: "filesystem"
|
backend: "filesystem"
|
||||||
base_path: "./webapp_deployments"
|
base_path: "./webapp_deployments"
|
||||||
enable_persistence: True
|
enable_persistence: True
|
||||||
@ -132,7 +132,7 @@ web_app_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Basic monitoring
|
# Basic monitoring
|
||||||
monitoring: main.MonitoringConfig {
|
monitoring: workflows_mod.MonitoringConfig {
|
||||||
enabled: True
|
enabled: True
|
||||||
backend: "prometheus"
|
backend: "prometheus"
|
||||||
enable_tracing: False # Simplified for example
|
enable_tracing: False # Simplified for example
|
||||||
@ -140,7 +140,7 @@ web_app_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Conservative retry policy
|
# Conservative retry policy
|
||||||
default_retry_policy: main.RetryPolicy {
|
default_retry_policy: workflows_mod.RetryPolicy {
|
||||||
max_attempts: 2
|
max_attempts: 2
|
||||||
initial_delay: 30
|
initial_delay: 30
|
||||||
backoff_multiplier: 2
|
backoff_multiplier: 2
|
||||||
@ -148,7 +148,7 @@ web_app_deployment: main.BatchWorkflow = main.BatchWorkflow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Enable rollback for safety
|
# Enable rollback for safety
|
||||||
default_rollback_strategy: main.RollbackStrategy {
|
default_rollback_strategy: workflows_mod.RollbackStrategy {
|
||||||
enabled: True
|
enabled: True
|
||||||
strategy: "immediate"
|
strategy: "immediate"
|
||||||
preserve_partial_state: False
|
preserve_partial_state: False
|
||||||
|
|||||||
@ -304,12 +304,18 @@ production_batch_executor: batch.BatchExecutor = batch.BatchExecutor {
|
|||||||
secondary_providers: ["aws"]
|
secondary_providers: ["aws"]
|
||||||
provider_selection: "cost_optimize"
|
provider_selection: "cost_optimize"
|
||||||
cross_provider_networking: {
|
cross_provider_networking: {
|
||||||
"vpn_enabled": "True"
|
"vpn_enabled": "true"
|
||||||
"mesh_networking": "wireguard"
|
"mesh_networking": "wireguard"
|
||||||
}
|
}
|
||||||
provider_limits: {
|
provider_limits: {
|
||||||
"upcloud": {"max_servers": 20, "max_storage_gb": 1000}
|
"upcloud": {
|
||||||
"aws": {"max_instances": 10, "max_ebs_gb": 500}
|
"max_servers": 20
|
||||||
|
"max_storage_gb": 1000
|
||||||
|
}
|
||||||
|
"aws": {
|
||||||
|
"max_instances": 10
|
||||||
|
"max_ebs_gb": 500
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
health_check: batch.BatchHealthCheck {
|
health_check: batch.BatchHealthCheck {
|
||||||
@ -364,9 +370,9 @@ production_batch_executor: batch.BatchExecutor = batch.BatchExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
security_config: {
|
security_config: {
|
||||||
"tls_enabled": "True"
|
"tls_enabled": "true"
|
||||||
"auth_required": "True"
|
"auth_required": "true"
|
||||||
"rbac_enabled": "True"
|
"rbac_enabled": "true"
|
||||||
"audit_level": "full"
|
"audit_level": "full"
|
||||||
}
|
}
|
||||||
webhook_endpoints: [
|
webhook_endpoints: [
|
||||||
|
|||||||
101
generator/change.k
Normal file
101
generator/change.k
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
"""
|
||||||
|
Change Tracking Schema
|
||||||
|
|
||||||
|
Defines changes made during incremental updates to enable:
|
||||||
|
- Traceability (what changed and why)
|
||||||
|
- Reversibility (ability to undo changes)
|
||||||
|
- Version history (changelog generation)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Change Operations
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema AddTaskservChange:
|
||||||
|
"""Add a new taskserv requirement"""
|
||||||
|
taskserv_name: str
|
||||||
|
version: str
|
||||||
|
profile: str = "default"
|
||||||
|
reason: str
|
||||||
|
|
||||||
|
|
||||||
|
schema RemoveTaskservChange:
|
||||||
|
"""Remove a taskserv requirement"""
|
||||||
|
taskserv_name: str
|
||||||
|
reason: str
|
||||||
|
|
||||||
|
|
||||||
|
schema UpdateTaskservChange:
|
||||||
|
"""Update an existing taskserv"""
|
||||||
|
taskserv_name: str
|
||||||
|
old_version?: str
|
||||||
|
new_version?: str
|
||||||
|
old_profile?: str
|
||||||
|
new_profile?: str
|
||||||
|
reason: str
|
||||||
|
|
||||||
|
|
||||||
|
schema UpdateFieldChange:
|
||||||
|
"""Update a configuration field"""
|
||||||
|
schema_name: str
|
||||||
|
field_name: str
|
||||||
|
old_value?: str
|
||||||
|
new_value: str
|
||||||
|
reason: str
|
||||||
|
|
||||||
|
|
||||||
|
schema PreserveCustomizationChange:
|
||||||
|
"""Marker: this customization was preserved"""
|
||||||
|
location: str # Path in declaration
|
||||||
|
value: str # Preserved value
|
||||||
|
reason: str = "User customization preserved"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Change Record
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema Change:
|
||||||
|
"""
|
||||||
|
Single tracked change during merge
|
||||||
|
"""
|
||||||
|
kind: str # "add_taskserv", "update_field", etc.
|
||||||
|
timestamp: str # ISO 8601
|
||||||
|
author?: str
|
||||||
|
breaking: bool = False # Is this a breaking change?
|
||||||
|
details: {str: str} # Operation-specific details
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(kind) > 0, "Change kind required"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Merge Result
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema MergeResult:
|
||||||
|
"""
|
||||||
|
Result of incremental merge operation
|
||||||
|
"""
|
||||||
|
success: bool
|
||||||
|
changes: [Change] = []
|
||||||
|
preserved_customizations: [str] = []
|
||||||
|
conflicts: [str] = []
|
||||||
|
version_bumped?: "major" | "minor" | "patch"
|
||||||
|
new_version?: str
|
||||||
|
warning_messages: [str] = []
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Changelog Entry
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema ChangelogEntry:
|
||||||
|
"""
|
||||||
|
Entry in workspace changelog
|
||||||
|
"""
|
||||||
|
version: str
|
||||||
|
date: str # ISO 8601
|
||||||
|
changes_summary: [str]
|
||||||
|
breaking_changes: [str] = []
|
||||||
|
merged_by?: str
|
||||||
230
generator/declaration.k
Normal file
230
generator/declaration.k
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
"""
|
||||||
|
Workspace Declaration Schema
|
||||||
|
|
||||||
|
Defines the structure of a provisioning workspace declaration.
|
||||||
|
A declaration is a complete specification of infrastructure requirements,
|
||||||
|
including detected technologies, taskservs, and deployment configuration.
|
||||||
|
|
||||||
|
This enables:
|
||||||
|
- Declarative IaC (infrastructure-as-code)
|
||||||
|
- Incremental updates (merge with existing declarations)
|
||||||
|
- Version tracking
|
||||||
|
- Reproducible deployments
|
||||||
|
"""
|
||||||
|
|
||||||
|
import regex
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Metadata and Versioning
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema Metadata:
|
||||||
|
"""
|
||||||
|
Workspace metadata: identification, versioning, authorship
|
||||||
|
"""
|
||||||
|
name: str
|
||||||
|
version: str # Semantic versioning (e.g., "1.0.0")
|
||||||
|
description?: str
|
||||||
|
author?: str
|
||||||
|
created_at?: str # ISO 8601 timestamp
|
||||||
|
updated_at?: str # ISO 8601 timestamp
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Name required"
|
||||||
|
len(name) <= 128, "Name too long (max 128 chars)"
|
||||||
|
# Simple semver pattern: MAJOR.MINOR.PATCH
|
||||||
|
regex.match(version, r"^\d+\.\d+\.\d+$"), \
|
||||||
|
"Version must be semantic (e.g., 1.0.0)"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Technology Detection and Requirements
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema TechnologyDetection:
|
||||||
|
"""
|
||||||
|
Detected technology in the project (e.g., Node.js, PostgreSQL)
|
||||||
|
"""
|
||||||
|
name: str # e.g., "nodejs", "postgres"
|
||||||
|
version?: str # Detected or specified version
|
||||||
|
confidence: float # 0.0-1.0 confidence score
|
||||||
|
detected_from?: [str] # Files/patterns that led to detection
|
||||||
|
|
||||||
|
check:
|
||||||
|
confidence >= 0.0 and confidence <= 1.0, \
|
||||||
|
"Confidence must be between 0 and 1"
|
||||||
|
|
||||||
|
|
||||||
|
schema TaskservRequirement:
|
||||||
|
"""
|
||||||
|
Infrastructure taskserv requirement (e.g., redis, postgres-backup)
|
||||||
|
"""
|
||||||
|
name: str # Taskserv name (e.g., "redis", "postgres")
|
||||||
|
version?: str # Min or exact version
|
||||||
|
profile: "default" | "minimal" | "HA" = "default"
|
||||||
|
required: bool = False # true = must install, false = optional
|
||||||
|
confidence: float = 1.0 # How confident in this requirement
|
||||||
|
reason?: str # Why this taskserv is needed
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Taskserv name required"
|
||||||
|
confidence >= 0.0 and confidence <= 1.0, \
|
||||||
|
"Confidence must be between 0 and 1"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Deployment Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema ServerConfig:
|
||||||
|
"""
|
||||||
|
Server definition for deployment
|
||||||
|
"""
|
||||||
|
name: str
|
||||||
|
provider: str # e.g., "upcloud", "aws", "local"
|
||||||
|
flavor?: str # Machine type/size
|
||||||
|
region?: str
|
||||||
|
taskservs: [str] = [] # Taskservs to install on this server
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Server name required"
|
||||||
|
|
||||||
|
|
||||||
|
schema DeploymentConfig:
|
||||||
|
"""
|
||||||
|
Deployment mode and infrastructure layout
|
||||||
|
"""
|
||||||
|
mode: "solo" | "multiuser" | "cicd" | "enterprise" = "multiuser"
|
||||||
|
servers: [ServerConfig] = []
|
||||||
|
ha_enabled: bool = False
|
||||||
|
|
||||||
|
check:
|
||||||
|
mode == "solo" or len(servers) > 0, \
|
||||||
|
"Servers required for non-solo deployments"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Main Declaration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema WorkspaceDeclaration:
|
||||||
|
"""
|
||||||
|
Complete workspace declaration.
|
||||||
|
|
||||||
|
A declaration specifies all infrastructure requirements for a project:
|
||||||
|
- Metadata (name, version, author)
|
||||||
|
- Detected technologies (Node.js, PostgreSQL, etc.)
|
||||||
|
- Required taskservs (what to install)
|
||||||
|
- Deployment config (where/how to deploy)
|
||||||
|
- Custom configuration (user-specific settings)
|
||||||
|
|
||||||
|
Example:
|
||||||
|
declaration = WorkspaceDeclaration {
|
||||||
|
metadata: {
|
||||||
|
name: "my-api"
|
||||||
|
version: "1.0.0"
|
||||||
|
author: "user@example.com"
|
||||||
|
}
|
||||||
|
|
||||||
|
detections: [
|
||||||
|
TechnologyDetection {
|
||||||
|
name: "nodejs"
|
||||||
|
version: "20.0.0"
|
||||||
|
confidence: 0.95
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
requirements: [
|
||||||
|
TaskservRequirement {
|
||||||
|
name: "postgres"
|
||||||
|
version: "16.0"
|
||||||
|
required: True
|
||||||
|
reason: "Database detected in code"
|
||||||
|
}
|
||||||
|
TaskservRequirement {
|
||||||
|
name: "redis"
|
||||||
|
profile: "default"
|
||||||
|
required: False
|
||||||
|
confidence: 0.85
|
||||||
|
reason: "Node.js APIs benefit from caching"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
deployment: {
|
||||||
|
mode: "multiuser"
|
||||||
|
servers: [
|
||||||
|
ServerConfig {
|
||||||
|
name: "app-db"
|
||||||
|
provider: "upcloud"
|
||||||
|
flavor: "2xCPU-4GB"
|
||||||
|
taskservs: ["postgres"]
|
||||||
|
}
|
||||||
|
ServerConfig {
|
||||||
|
name: "app-server"
|
||||||
|
provider: "upcloud"
|
||||||
|
flavor: "2xCPU-4GB"
|
||||||
|
taskservs: ["nodejs", "redis"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Identification
|
||||||
|
metadata: Metadata
|
||||||
|
|
||||||
|
# Auto-detected technologies
|
||||||
|
detections: [TechnologyDetection] = []
|
||||||
|
|
||||||
|
# Infrastructure requirements (from detection + inference)
|
||||||
|
requirements: [TaskservRequirement] = []
|
||||||
|
|
||||||
|
# Deployment configuration
|
||||||
|
deployment: DeploymentConfig = {
|
||||||
|
mode: "multiuser"
|
||||||
|
}
|
||||||
|
|
||||||
|
# User customizations (preserved during updates)
|
||||||
|
custom_config?: {str: str}
|
||||||
|
|
||||||
|
check:
|
||||||
|
# At least one requirement if detections exist
|
||||||
|
len(detections) == 0 or len(requirements) > 0, \
|
||||||
|
"Detections found but no requirements specified"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Changelog Entry (for tracking updates)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema ChangelogEntry:
|
||||||
|
"""
|
||||||
|
Single changelog entry for versioning
|
||||||
|
"""
|
||||||
|
version: str
|
||||||
|
timestamp: str # ISO 8601
|
||||||
|
author?: str
|
||||||
|
changes: [str] = []
|
||||||
|
breaking_changes?: [str]
|
||||||
|
|
||||||
|
|
||||||
|
schema Changelog:
|
||||||
|
"""
|
||||||
|
Workspace changelog for tracking all versions
|
||||||
|
"""
|
||||||
|
entries: [ChangelogEntry] = []
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Complete Workspace with History
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema Workspace:
|
||||||
|
"""
|
||||||
|
Complete workspace including current declaration + history
|
||||||
|
"""
|
||||||
|
declaration: WorkspaceDeclaration
|
||||||
|
changelog: Changelog = { entries: [] }
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(declaration.metadata.name) > 0, "Workspace name required"
|
||||||
115
generator/gap.k
Normal file
115
generator/gap.k
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
"""
|
||||||
|
Gap Analysis Schema
|
||||||
|
|
||||||
|
Defines gaps (missing or incomplete specifications) found when analyzing
|
||||||
|
whether a declaration matches the actual project structure and inferred requirements.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Gap Types
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema MissingTaskservGap:
|
||||||
|
"""
|
||||||
|
A required taskserv is missing from the declaration
|
||||||
|
"""
|
||||||
|
taskserv_name: str
|
||||||
|
reason: str # Why this taskserv is needed
|
||||||
|
required: bool
|
||||||
|
suggested_version?: str
|
||||||
|
|
||||||
|
|
||||||
|
schema MissingFieldGap:
|
||||||
|
"""
|
||||||
|
A configuration field is missing or incomplete
|
||||||
|
"""
|
||||||
|
schema_name: str # e.g., "TaskservRequirement"
|
||||||
|
field_name: str # e.g., "backup_strategy"
|
||||||
|
reason: str
|
||||||
|
suggested_value?: str
|
||||||
|
|
||||||
|
|
||||||
|
schema VersionMismatchGap:
|
||||||
|
"""
|
||||||
|
Version is outdated or mismatched
|
||||||
|
"""
|
||||||
|
taskserv_name: str
|
||||||
|
current_version: str
|
||||||
|
recommended_version: str
|
||||||
|
reason: str
|
||||||
|
|
||||||
|
|
||||||
|
schema DependencyGap:
|
||||||
|
"""
|
||||||
|
Taskserv is missing a dependency
|
||||||
|
"""
|
||||||
|
taskserv_name: str
|
||||||
|
depends_on: str # Required taskserv name
|
||||||
|
reason: str
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Severity and Priority
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema Gap:
|
||||||
|
"""
|
||||||
|
A single gap with severity and suggested fix
|
||||||
|
"""
|
||||||
|
kind: str # "missing_taskserv", "missing_field", etc.
|
||||||
|
severity: "error" | "warning" | "info" = "warning"
|
||||||
|
location?: str # Where in declaration (e.g., "requirements[0]")
|
||||||
|
message: str # Human-readable description
|
||||||
|
suggestion?: str # How to fix it
|
||||||
|
context?: {str: str} # Additional context
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(message) > 0, "Gap message required"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Gap Analysis Report
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema GapAnalysisReport:
|
||||||
|
"""
|
||||||
|
Complete gap analysis showing what's missing/incomplete
|
||||||
|
"""
|
||||||
|
declaration_name: str
|
||||||
|
declaration_version: str
|
||||||
|
gaps: [Gap] = []
|
||||||
|
total_errors: int = 0
|
||||||
|
total_warnings: int = 0
|
||||||
|
total_info: int = 0
|
||||||
|
completeness_score: float # 0.0 (empty) to 1.0 (complete)
|
||||||
|
|
||||||
|
check:
|
||||||
|
completeness_score >= 0.0 and completeness_score <= 1.0, \
|
||||||
|
"Completeness score must be 0.0-1.0"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Gap Fixer (Suggested fixes)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema GapFix:
|
||||||
|
"""
|
||||||
|
A proposed fix for a gap
|
||||||
|
"""
|
||||||
|
gap_id: str
|
||||||
|
action: "add" | "update" | "remove" | "skip" = "add"
|
||||||
|
value?: str # New value to set
|
||||||
|
reasoning: str # Why this fix is appropriate
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(gap_id) > 0, "Gap ID required"
|
||||||
|
|
||||||
|
|
||||||
|
schema GapFixPlan:
|
||||||
|
"""
|
||||||
|
Plan for fixing multiple gaps
|
||||||
|
"""
|
||||||
|
declaration_name: str
|
||||||
|
fixes: [GapFix] = []
|
||||||
|
estimated_changes: int
|
||||||
|
preservation_strategy?: str # How to preserve customizations
|
||||||
204
generator/questionnaire.k
Normal file
204
generator/questionnaire.k
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
"""
|
||||||
|
Questionnaire Schema
|
||||||
|
|
||||||
|
Defines interactive questionnaires for completing infrastructure specifications.
|
||||||
|
Uses conditional logic and decision trees to ask only relevant questions.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Conditional questions (only ask if certain conditions met)
|
||||||
|
- Smart defaults from AI suggestions
|
||||||
|
- Validation rules per question
|
||||||
|
- Decision tree navigation
|
||||||
|
- Multi-select and single-select support
|
||||||
|
"""
|
||||||
|
|
||||||
|
import regex
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Expression Evaluation
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema Expression:
|
||||||
|
"""
|
||||||
|
Boolean expression for conditional logic
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- "deployment_mode == 'HA'"
|
||||||
|
- "has_database and deployment_mode in ['prod', 'staging']"
|
||||||
|
- "postgres_version >= '15.0'"
|
||||||
|
"""
|
||||||
|
expr: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(expr) > 0, "Expression cannot be empty"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Question Types and Validation
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema ValidationRule:
|
||||||
|
"""
|
||||||
|
Validation rule for question answers
|
||||||
|
"""
|
||||||
|
required: bool = False
|
||||||
|
pattern?: str # Regex pattern for validation
|
||||||
|
min_value?: int
|
||||||
|
max_value?: int
|
||||||
|
choices?: [str] # Valid choices (for select/multiselect)
|
||||||
|
custom_validator?: str # Name of custom validator function
|
||||||
|
|
||||||
|
|
||||||
|
schema Question:
|
||||||
|
"""
|
||||||
|
Single question in questionnaire
|
||||||
|
"""
|
||||||
|
id: str # Unique identifier
|
||||||
|
kind: "text" | "select" | "multiselect" | "confirm" | "number"
|
||||||
|
message: str # Question text
|
||||||
|
help?: str # Help text/description
|
||||||
|
default?: str # Default value
|
||||||
|
|
||||||
|
# Conditional display
|
||||||
|
when?: Expression # Only ask if this expression is true
|
||||||
|
depends_on?: [str] # Other question IDs this depends on
|
||||||
|
|
||||||
|
# Validation
|
||||||
|
validation: ValidationRule = {}
|
||||||
|
|
||||||
|
# AI assistance
|
||||||
|
ai_suggest: bool = False # Enable AI suggestions?
|
||||||
|
ai_context?: str # Context for AI suggestion
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(id) > 0, "Question ID required"
|
||||||
|
len(message) > 0, "Message required"
|
||||||
|
# Validate choices if kind is select/multiselect
|
||||||
|
kind not in ["select", "multiselect"] or validation.choices != None, \
|
||||||
|
"Choices required for select/multiselect questions"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Decision Tree Nodes
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema DecisionNode:
|
||||||
|
"""
|
||||||
|
Single node in decision tree
|
||||||
|
"""
|
||||||
|
question_id: str # Which question to ask
|
||||||
|
next_nodes?: {str: str} # answer -> next_question_id
|
||||||
|
default_next?: str # Default next question if no match
|
||||||
|
|
||||||
|
|
||||||
|
schema DecisionTree:
|
||||||
|
"""
|
||||||
|
Decision tree for intelligent questionnaire flow
|
||||||
|
"""
|
||||||
|
root: str # Starting question ID
|
||||||
|
nodes: {str: DecisionNode} # ID -> Node mapping
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(root) > 0, "Root question required"
|
||||||
|
len(nodes) > 0, "At least one node required"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Metadata
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema Metadata:
|
||||||
|
"""
|
||||||
|
Questionnaire metadata
|
||||||
|
"""
|
||||||
|
name: str
|
||||||
|
version: str
|
||||||
|
description?: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Name required"
|
||||||
|
len(version) > 0, "Version required"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Complete Questionnaire
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema Questionnaire:
|
||||||
|
"""
|
||||||
|
Complete questionnaire with questions and decision tree
|
||||||
|
|
||||||
|
Example:
|
||||||
|
postgres_questionnaire = Questionnaire {
|
||||||
|
metadata: {
|
||||||
|
name: "PostgreSQL Setup"
|
||||||
|
version: "1.0.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
questions: [
|
||||||
|
Question {
|
||||||
|
id: "pg_version"
|
||||||
|
kind: "text"
|
||||||
|
message: "PostgreSQL version?"
|
||||||
|
default: "16.0"
|
||||||
|
validation: {
|
||||||
|
pattern: r"^\d+\.\d+$"
|
||||||
|
}
|
||||||
|
ai_suggest: True
|
||||||
|
ai_context: "Suggest latest stable PostgreSQL"
|
||||||
|
}
|
||||||
|
Question {
|
||||||
|
id: "enable_backup"
|
||||||
|
kind: "confirm"
|
||||||
|
message: "Enable automated backups?"
|
||||||
|
default: "true"
|
||||||
|
when: Expression { expr: "deployment_mode in ['prod', 'staging']" }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
decision_tree: {
|
||||||
|
root: "pg_version"
|
||||||
|
nodes: {
|
||||||
|
"pg_version": {
|
||||||
|
question_id: "pg_version"
|
||||||
|
next_nodes: { "*": "enable_backup" }
|
||||||
|
}
|
||||||
|
"enable_backup": {
|
||||||
|
question_id: "enable_backup"
|
||||||
|
next_nodes: { "true": "backup_strategy", "false": "END" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
metadata: Metadata
|
||||||
|
questions: [Question] = []
|
||||||
|
decision_tree: DecisionTree
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(questions) > 0, "At least one question required"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Question Answer
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema Answer:
|
||||||
|
"""
|
||||||
|
User answer to a question
|
||||||
|
"""
|
||||||
|
question_id: str
|
||||||
|
value: str | bool | int # Answer value
|
||||||
|
timestamp: str # ISO 8601 when answered
|
||||||
|
|
||||||
|
|
||||||
|
schema QuestionnaireResponse:
|
||||||
|
"""
|
||||||
|
Complete questionnaire response
|
||||||
|
"""
|
||||||
|
questionnaire_name: str
|
||||||
|
questionnaire_version: str
|
||||||
|
answers: [Answer] = []
|
||||||
|
completed: bool = False
|
||||||
|
completion_time?: str # ISO 8601
|
||||||
348
golden_image.k
Normal file
348
golden_image.k
Normal file
@ -0,0 +1,348 @@
|
|||||||
|
# Golden Image Schema (Phase 3)
|
||||||
|
#
|
||||||
|
# Comprehensive golden image building, caching, and versioning system.
|
||||||
|
# Follows KCL idiomatic patterns: schema-first, check blocks, composition, union types.
|
||||||
|
|
||||||
|
import .lib as lib
|
||||||
|
import .settings as cfg
|
||||||
|
|
||||||
|
# Pattern 1: Direct imports (no re-exports)
|
||||||
|
# Pattern 2: Schema-first development
|
||||||
|
# Pattern 5: Explicit types (always specify)
|
||||||
|
# Pattern 8: Union types for enums
|
||||||
|
|
||||||
|
schema GoldenImageConfig:
|
||||||
|
"""
|
||||||
|
Golden image definition with pre-installed taskservs and configuration.
|
||||||
|
|
||||||
|
A golden image is a pre-built, pre-configured VM disk image that includes:
|
||||||
|
- Base OS (Ubuntu, Debian, CentOS, etc.)
|
||||||
|
- Pre-installed taskservs (Kubernetes, Docker, etc.)
|
||||||
|
- Optimized configuration
|
||||||
|
- ~5x faster VM startup (image vs base OS)
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
# Web server golden image
|
||||||
|
GoldenImageConfig {
|
||||||
|
name = "web-server-golden"
|
||||||
|
base_os = "ubuntu"
|
||||||
|
os_version = "22.04"
|
||||||
|
arch = "x86_64"
|
||||||
|
taskservs = ["nginx", "postgresql", "redis"]
|
||||||
|
disk_size_gb = 30
|
||||||
|
optimize = True
|
||||||
|
}
|
||||||
|
|
||||||
|
# Kubernetes node image
|
||||||
|
GoldenImageConfig {
|
||||||
|
name = "k8s-node"
|
||||||
|
base_os = "ubuntu"
|
||||||
|
os_version = "22.04"
|
||||||
|
taskservs = ["containerd", "kubernetes", "cilium"]
|
||||||
|
disk_size_gb = 50
|
||||||
|
cache_enabled = True
|
||||||
|
cache_ttl_days = 30
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Image Identity (Pattern 5: Explicit types)
|
||||||
|
name: str # Image name (unique)
|
||||||
|
description?: str # Image description
|
||||||
|
|
||||||
|
# Base OS Configuration
|
||||||
|
base_os: "ubuntu" | "debian" | "centos" | "fedora" | "rhel" = "ubuntu"
|
||||||
|
os_version: str = "22.04" # OS version (22.04, 20.04, etc.)
|
||||||
|
arch: "x86_64" | "aarch64" | "arm64" = "x86_64" # CPU architecture
|
||||||
|
|
||||||
|
# Taskserv Pre-installation (Pattern 8: Union types, Pattern 9: Optional fields)
|
||||||
|
taskservs?: [str] # Taskservs to pre-install
|
||||||
|
taskserv_versions?: {str: str} # Taskserv version pinning
|
||||||
|
exclude_taskservs?: [str] # Taskservs to exclude
|
||||||
|
|
||||||
|
# Image Optimization
|
||||||
|
optimize?: bool = False # Run optimizations
|
||||||
|
include_dev_tools?: bool = False # Include development tools
|
||||||
|
include_kernel_headers?: bool = False # Include kernel headers
|
||||||
|
cleanup_package_manager?: bool = True # Cleanup apt/yum caches
|
||||||
|
|
||||||
|
# Disk Configuration
|
||||||
|
disk_size_gb?: int = 30 # Disk size (10-500 GB)
|
||||||
|
disk_format?: "qcow2" | "raw" | "vmdk" = "qcow2" # Disk format
|
||||||
|
compression?: bool = True # Enable compression
|
||||||
|
|
||||||
|
# Image Caching (Pattern 9: Optional fields)
|
||||||
|
cache_enabled?: bool = True # Cache built images
|
||||||
|
cache_ttl_days?: int = 30 # Cache validity period
|
||||||
|
cache_storage?: str # Custom cache path
|
||||||
|
|
||||||
|
# Network Configuration
|
||||||
|
network_config?: str # Cloud-init network config
|
||||||
|
dns_servers?: [str] # Custom DNS servers
|
||||||
|
|
||||||
|
# Security Configuration (Pattern 4: Check blocks for validation)
|
||||||
|
security_hardening?: bool = False # Apply security hardening
|
||||||
|
auto_updates?: bool = True # Enable automatic updates
|
||||||
|
ssh_public_keys?: [str] # Pre-loaded SSH keys
|
||||||
|
|
||||||
|
# Build Configuration
|
||||||
|
build_timeout_minutes?: int = 30 # Build timeout
|
||||||
|
build_retries?: int = 3 # Retry failed builds
|
||||||
|
parallel_builds?: bool = False # Allow parallel builds
|
||||||
|
|
||||||
|
# Validation (Pattern 4: Check blocks)
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Image name required"
|
||||||
|
len(name) <= 255, "Image name too long"
|
||||||
|
taskservs == Undefined or len(taskservs) <= 50, "Too many taskservs"
|
||||||
|
disk_size_gb == Undefined or (disk_size_gb >= 10 and disk_size_gb <= 500), "Disk size must be 10-500 GB"
|
||||||
|
cache_ttl_days == Undefined or (cache_ttl_days >= 1 and cache_ttl_days <= 365), "Cache TTL must be 1-365 days"
|
||||||
|
build_timeout_minutes == Undefined or build_timeout_minutes >= 5, "Build timeout must be at least 5 minutes"
|
||||||
|
|
||||||
|
|
||||||
|
schema GoldenImageBuildJob:
|
||||||
|
"""
|
||||||
|
Represents an in-progress or completed golden image build job.
|
||||||
|
|
||||||
|
Tracks build status, progress, logs, and artifacts.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Job Identity
|
||||||
|
job_id: str # Unique job identifier
|
||||||
|
image_name: str # Image being built
|
||||||
|
image_version: str # Image version
|
||||||
|
image_config: GoldenImageConfig # Build configuration
|
||||||
|
|
||||||
|
# Build Status (Pattern 8: Union types for status)
|
||||||
|
status: "queued" | "building" | "testing" | "caching" | "completed" | "failed" = "queued"
|
||||||
|
started_at?: str # Build start time (ISO 8601)
|
||||||
|
completed_at?: str # Build completion time
|
||||||
|
duration_seconds?: int # Build duration
|
||||||
|
|
||||||
|
# Progress Tracking (Pattern 9: Optional fields)
|
||||||
|
progress_percent?: int # Build progress (0-100)
|
||||||
|
current_step?: str # Current build step
|
||||||
|
current_step_progress?: int # Step progress (0-100)
|
||||||
|
|
||||||
|
# Build Results
|
||||||
|
output_path?: str # Path to built image
|
||||||
|
image_size_gb?: float # Final image size
|
||||||
|
checksum?: str # SHA256 checksum
|
||||||
|
|
||||||
|
# Error Handling
|
||||||
|
error_message?: str # Error message if failed
|
||||||
|
retry_count?: int = 0 # Retry attempts
|
||||||
|
last_error?: str # Last error encountered
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
build_log_path?: str # Path to build log
|
||||||
|
test_log_path?: str # Path to test log
|
||||||
|
|
||||||
|
# Validation (Pattern 4: Check blocks)
|
||||||
|
check:
|
||||||
|
len(job_id) > 0, "Job ID required"
|
||||||
|
len(image_name) > 0, "Image name required"
|
||||||
|
progress_percent == Undefined or (progress_percent >= 0 and progress_percent <= 100), "Progress must be 0-100"
|
||||||
|
duration_seconds == Undefined or duration_seconds >= 0, "Duration must be non-negative"
|
||||||
|
|
||||||
|
|
||||||
|
schema GoldenImageVersion:
|
||||||
|
"""
|
||||||
|
Version metadata for a golden image with tracking and rollback support.
|
||||||
|
|
||||||
|
Enables image versioning, rollback to previous versions, and tracking
|
||||||
|
of which VMs use which versions.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Version Identity
|
||||||
|
image_name: str # Image name
|
||||||
|
version: str # Semantic version (1.0.0)
|
||||||
|
build_number?: int # Build number for same version
|
||||||
|
|
||||||
|
# Metadata
|
||||||
|
created_at: str # Creation timestamp (ISO 8601)
|
||||||
|
created_by?: str # User who created
|
||||||
|
description?: str # Version description
|
||||||
|
|
||||||
|
# Content
|
||||||
|
image_path: str # Path to image file
|
||||||
|
image_size_gb: float # Image file size
|
||||||
|
checksum: str # SHA256 checksum
|
||||||
|
|
||||||
|
# Build Information
|
||||||
|
base_image_version?: str # Base image version used
|
||||||
|
taskserv_versions?: {str: str} # Taskserv versions included
|
||||||
|
build_job_id?: str # Build job that created this
|
||||||
|
|
||||||
|
# Tracking
|
||||||
|
usage_count?: int = 0 # Number of VMs using
|
||||||
|
vm_instances?: [str] # VMs using this version
|
||||||
|
last_used_at?: str # Last VM creation time
|
||||||
|
|
||||||
|
# Deprecation (Pattern 9: Optional fields)
|
||||||
|
deprecated?: bool = False # Mark as deprecated
|
||||||
|
replacement_version?: str # Recommended replacement
|
||||||
|
|
||||||
|
# Validation (Pattern 4: Check blocks)
|
||||||
|
check:
|
||||||
|
len(image_name) > 0, "Image name required"
|
||||||
|
len(version) > 0, "Version required"
|
||||||
|
len(checksum) == 64, "SHA256 checksum must be 64 characters"
|
||||||
|
|
||||||
|
|
||||||
|
schema GoldenImageCache:
|
||||||
|
"""
|
||||||
|
Image cache metadata and management.
|
||||||
|
|
||||||
|
Tracks cached images, storage locations, and cleanup policies.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Cache Identity
|
||||||
|
cache_id: str # Cache identifier
|
||||||
|
image_name: str # Cached image name
|
||||||
|
image_version: str # Image version
|
||||||
|
|
||||||
|
# Cache Storage
|
||||||
|
storage_path: str # Local cache path
|
||||||
|
storage_format: "qcow2" | "raw" | "compressed" = "qcow2"
|
||||||
|
disk_size_gb: float # Disk space used
|
||||||
|
|
||||||
|
# Timestamps
|
||||||
|
cached_at: str # When cached (ISO 8601)
|
||||||
|
accessed_at?: str # Last access time
|
||||||
|
expires_at?: str # Cache expiration time
|
||||||
|
ttl_days?: int # Time-to-live in days
|
||||||
|
|
||||||
|
# Cache Validity
|
||||||
|
is_valid: bool = True # Cache is still valid
|
||||||
|
checksum: str # SHA256 checksum
|
||||||
|
last_verification?: str # Last verification time
|
||||||
|
|
||||||
|
# Usage Tracking
|
||||||
|
access_count?: int = 0 # Number of uses
|
||||||
|
hit_count?: int = 0 # Cache hits
|
||||||
|
last_vm_created?: str # Last VM from cache
|
||||||
|
|
||||||
|
# Validation (Pattern 4: Check blocks)
|
||||||
|
check:
|
||||||
|
len(cache_id) > 0, "Cache ID required"
|
||||||
|
len(checksum) == 64, "SHA256 checksum must be 64 characters"
|
||||||
|
access_count == Undefined or access_count >= 0, "Access count must be non-negative"
|
||||||
|
|
||||||
|
|
||||||
|
schema ImageBuildSteps:
|
||||||
|
"""
|
||||||
|
Detailed build step definitions for golden image construction.
|
||||||
|
|
||||||
|
Pattern 3: Composition (used within build jobs)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Preparation Phase
|
||||||
|
prepare_base?: bool = True # Prepare base OS
|
||||||
|
update_packages?: bool = True # Update packages
|
||||||
|
install_dependencies?: bool = True # Install dependencies
|
||||||
|
|
||||||
|
# Taskserv Installation Phase
|
||||||
|
install_taskservs?: bool = True # Install taskservs
|
||||||
|
install_order?: [str] # Installation order
|
||||||
|
parallel_install?: bool = False # Parallel installation
|
||||||
|
|
||||||
|
# Configuration Phase
|
||||||
|
apply_config?: bool = True # Apply configuration
|
||||||
|
apply_security_hardening?: bool = False # Security hardening
|
||||||
|
apply_optimizations?: bool = False # Performance optimizations
|
||||||
|
|
||||||
|
# Testing Phase
|
||||||
|
run_tests?: bool = True # Run tests
|
||||||
|
test_scripts?: [str] # Custom test scripts
|
||||||
|
|
||||||
|
# Cleanup Phase
|
||||||
|
cleanup_caches?: bool = True # Cleanup package caches
|
||||||
|
cleanup_temp_files?: bool = True # Cleanup temp files
|
||||||
|
remove_build_artifacts?: bool = True # Remove build artifacts
|
||||||
|
|
||||||
|
# Final Steps
|
||||||
|
compress_image?: bool = True # Compress final image
|
||||||
|
generate_checksums?: bool = True # Generate checksums
|
||||||
|
verify_image?: bool = True # Verify image integrity
|
||||||
|
|
||||||
|
|
||||||
|
schema ImageBuildPolicy:
|
||||||
|
"""
|
||||||
|
Global policy for image building and caching.
|
||||||
|
|
||||||
|
Pattern 10: Reusable configurations
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Build Defaults
|
||||||
|
default_os: str = "ubuntu"
|
||||||
|
default_version: str = "22.04"
|
||||||
|
default_arch: str = "x86_64"
|
||||||
|
default_disk_size_gb: int = 30
|
||||||
|
|
||||||
|
# Build Constraints
|
||||||
|
max_parallel_builds: int = 3 # Max concurrent builds
|
||||||
|
max_build_time_minutes: int = 60 # Maximum build time
|
||||||
|
max_image_size_gb: int = 100 # Maximum image size
|
||||||
|
|
||||||
|
# Cache Defaults
|
||||||
|
cache_enabled: bool = True
|
||||||
|
cache_location: str # Cache directory path
|
||||||
|
default_cache_ttl_days: int = 30
|
||||||
|
max_cache_size_gb: int = 500 # Max cache disk space
|
||||||
|
|
||||||
|
# Cleanup Policies
|
||||||
|
auto_cleanup_expired: bool = True # Auto-cleanup old caches
|
||||||
|
cleanup_interval_hours: int = 24
|
||||||
|
min_disk_free_percent: int = 10 # Keep 10% free
|
||||||
|
|
||||||
|
# Versioning
|
||||||
|
auto_create_versions: bool = True # Auto-version builds
|
||||||
|
version_naming: str = "semantic" # semantic, timestamp, sequential
|
||||||
|
|
||||||
|
# Optimization Defaults
|
||||||
|
default_optimize: bool = False
|
||||||
|
default_compression: bool = True
|
||||||
|
default_security_hardening: bool = False
|
||||||
|
|
||||||
|
# Validation (Pattern 4: Check blocks)
|
||||||
|
check:
|
||||||
|
max_parallel_builds > 0, "Max parallel builds must be positive"
|
||||||
|
max_build_time_minutes >= 5, "Max build time must be >= 5 minutes"
|
||||||
|
max_image_size_gb >= 10, "Max image size must be >= 10 GB"
|
||||||
|
max_cache_size_gb >= 50, "Max cache size must be >= 50 GB"
|
||||||
|
default_cache_ttl_days >= 1, "Cache TTL must be >= 1 day"
|
||||||
|
min_disk_free_percent >= 5 and min_disk_free_percent <= 50, "Free percent must be 5-50%"
|
||||||
|
|
||||||
|
|
||||||
|
schema GoldenImageRegistry:
|
||||||
|
"""
|
||||||
|
Registry of all golden images with versions and metadata.
|
||||||
|
|
||||||
|
Pattern 3: Composition (contains Image, BuildJob, Cache)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Registry Metadata
|
||||||
|
registry_id: str # Registry identifier
|
||||||
|
location: str # Registry storage path
|
||||||
|
created_at: str # Creation timestamp
|
||||||
|
|
||||||
|
# Images (Pattern 3: Composition)
|
||||||
|
images: {str: GoldenImageConfig} # Images by name
|
||||||
|
versions: [GoldenImageVersion] # All versions
|
||||||
|
builds: [GoldenImageBuildJob] # Build history
|
||||||
|
cache: [GoldenImageCache] # Cached images
|
||||||
|
|
||||||
|
# Policy
|
||||||
|
policy: ImageBuildPolicy # Build policy
|
||||||
|
policy_version?: str # Policy version
|
||||||
|
|
||||||
|
# Statistics
|
||||||
|
total_images?: int # Total unique images
|
||||||
|
total_versions?: int # Total versions
|
||||||
|
total_cached_gb?: float # Total cache size
|
||||||
|
total_builds?: int # Build count
|
||||||
|
|
||||||
|
# Validation (Pattern 4: Check blocks)
|
||||||
|
check:
|
||||||
|
len(registry_id) > 0, "Registry ID required"
|
||||||
|
len(location) > 0, "Location required"
|
||||||
153
integrations/backup.k
Normal file
153
integrations/backup.k
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
"""
|
||||||
|
Backup system configuration schema.
|
||||||
|
|
||||||
|
Supports Restic, BorgBackup, Tar, Rsync with retention policies and scheduling.
|
||||||
|
"""
|
||||||
|
|
||||||
|
schema TypesBackup:
|
||||||
|
BackendType: "restic" | "borg" | "tar" | "rsync" | "cpio"
|
||||||
|
RepositoryType: "local" | "s3" | "sftp" | "rest" | "b2"
|
||||||
|
|
||||||
|
schema RetentionPolicy:
|
||||||
|
"""Backup retention policy"""
|
||||||
|
|
||||||
|
# Keep daily backups for N days
|
||||||
|
daily_days: int = 7
|
||||||
|
|
||||||
|
# Keep weekly backups for N weeks
|
||||||
|
weekly_weeks: int = 4
|
||||||
|
|
||||||
|
# Keep monthly backups for N months
|
||||||
|
monthly_months: int = 12
|
||||||
|
|
||||||
|
# Keep yearly backups for N years
|
||||||
|
yearly_years: int = 5
|
||||||
|
|
||||||
|
check:
|
||||||
|
daily_days > 0, "daily_days must be positive"
|
||||||
|
weekly_weeks > 0, "weekly_weeks must be positive"
|
||||||
|
monthly_months > 0, "monthly_months must be positive"
|
||||||
|
yearly_years > 0, "yearly_years must be positive"
|
||||||
|
|
||||||
|
schema Repository:
|
||||||
|
"""Backup repository configuration"""
|
||||||
|
|
||||||
|
type: TypesBackup.RepositoryType
|
||||||
|
|
||||||
|
# Local filesystem
|
||||||
|
path?: str
|
||||||
|
|
||||||
|
# S3 bucket
|
||||||
|
bucket?: str
|
||||||
|
prefix?: str = ""
|
||||||
|
|
||||||
|
# SFTP server
|
||||||
|
host?: str
|
||||||
|
sftp_path?: str
|
||||||
|
|
||||||
|
# REST API endpoint
|
||||||
|
url?: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
(type == "local" and path != None) or \
|
||||||
|
(type == "s3" and bucket != None) or \
|
||||||
|
(type == "sftp" and host != None and sftp_path != None) or \
|
||||||
|
(type == "rest" and url != None) or \
|
||||||
|
(type == "b2" and bucket != None), \
|
||||||
|
"Repository configuration mismatch with type"
|
||||||
|
|
||||||
|
schema BackupJob:
|
||||||
|
"""Backup job configuration"""
|
||||||
|
|
||||||
|
# Job name
|
||||||
|
name: str
|
||||||
|
|
||||||
|
# Backend to use
|
||||||
|
backend: TypesBackup.BackendType = "restic"
|
||||||
|
|
||||||
|
# Repository configuration
|
||||||
|
repository: Repository
|
||||||
|
|
||||||
|
# Paths to backup
|
||||||
|
paths: [str]
|
||||||
|
|
||||||
|
# Retention policy
|
||||||
|
retention: RetentionPolicy = {
|
||||||
|
daily_days = 7
|
||||||
|
weekly_weeks = 4
|
||||||
|
monthly_months = 12
|
||||||
|
yearly_years = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
# Pre-backup hook
|
||||||
|
pre_backup_hook?: str
|
||||||
|
|
||||||
|
# Post-backup hook
|
||||||
|
post_backup_hook?: str
|
||||||
|
|
||||||
|
# Exclude patterns
|
||||||
|
exclude_patterns?: [str]
|
||||||
|
|
||||||
|
# Compression level (0-9)
|
||||||
|
compression: int = 3
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "name must not be empty"
|
||||||
|
len(paths) > 0, "paths must not be empty"
|
||||||
|
compression >= 0 and compression <= 9, "compression must be 0-9"
|
||||||
|
|
||||||
|
schema BackupSchedule:
|
||||||
|
"""Backup scheduling configuration"""
|
||||||
|
|
||||||
|
# Schedule name
|
||||||
|
name: str
|
||||||
|
|
||||||
|
# Job to schedule
|
||||||
|
job: BackupJob
|
||||||
|
|
||||||
|
# Cron expression
|
||||||
|
cron: str
|
||||||
|
|
||||||
|
# Enabled
|
||||||
|
enabled: bool = True
|
||||||
|
|
||||||
|
# Maximum concurrent backups
|
||||||
|
max_concurrent: int = 1
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "name must not be empty"
|
||||||
|
len(cron) > 0, "cron must not be empty"
|
||||||
|
max_concurrent > 0, "max_concurrent must be positive"
|
||||||
|
|
||||||
|
schema BackupConfig:
|
||||||
|
"""Global backup configuration"""
|
||||||
|
|
||||||
|
# Default backend
|
||||||
|
default_backend: TypesBackup.BackendType = "restic"
|
||||||
|
|
||||||
|
# Default repository
|
||||||
|
default_repository: Repository
|
||||||
|
|
||||||
|
# Jobs to configure
|
||||||
|
jobs: [BackupJob]
|
||||||
|
|
||||||
|
# Schedules
|
||||||
|
schedules: [BackupSchedule] = []
|
||||||
|
|
||||||
|
# Enable backup verification
|
||||||
|
verify_after_backup: bool = True
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(jobs) >= 0, "jobs must be a valid list"
|
||||||
|
|
||||||
|
# Global backup configuration
|
||||||
|
backup_config: BackupConfig = {
|
||||||
|
default_backend = "restic"
|
||||||
|
default_repository = {
|
||||||
|
type = "local"
|
||||||
|
path = "./backups"
|
||||||
|
}
|
||||||
|
jobs = []
|
||||||
|
schedules = []
|
||||||
|
verify_after_backup = True
|
||||||
|
}
|
||||||
148
integrations/gitops.k
Normal file
148
integrations/gitops.k
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
"""
|
||||||
|
GitOps configuration schema.
|
||||||
|
|
||||||
|
Manages declarative GitOps rules and event-driven automation.
|
||||||
|
"""
|
||||||
|
|
||||||
|
schema TypesGit:
|
||||||
|
GitProvider: "github" | "gitlab" | "gitea"
|
||||||
|
EventType: "push" | "pull-request" | "webhook" | "scheduled" | "health-check" | "manual"
|
||||||
|
Environment: "dev" | "staging" | "prod"
|
||||||
|
|
||||||
|
schema GitOpsRule:
|
||||||
|
"""GitOps automation rule"""
|
||||||
|
# Rule name
|
||||||
|
name: str
|
||||||
|
|
||||||
|
# Git provider
|
||||||
|
provider: TypesGit.GitProvider
|
||||||
|
|
||||||
|
# Repository URL
|
||||||
|
repository: str
|
||||||
|
|
||||||
|
# Target branch pattern
|
||||||
|
branch: str = "main"
|
||||||
|
|
||||||
|
# Triggering events
|
||||||
|
events: [TypesGit.EventType]
|
||||||
|
|
||||||
|
# Deployment targets/environments
|
||||||
|
targets: [TypesGit.Environment]
|
||||||
|
|
||||||
|
# Deployment command
|
||||||
|
command: str
|
||||||
|
|
||||||
|
# Pre-deployment hook
|
||||||
|
pre_deploy_hook?: str
|
||||||
|
# Post-deployment hook
|
||||||
|
post_deploy_hook?: str
|
||||||
|
# Manual approval required
|
||||||
|
require_approval: bool = False
|
||||||
|
|
||||||
|
# Concurrency policy
|
||||||
|
concurrency_limit: int = 1
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "name must not be empty"
|
||||||
|
len(repository) > 0, "repository must not be empty"
|
||||||
|
len(branch) > 0, "branch must not be empty"
|
||||||
|
len(events) > 0, "events must not be empty"
|
||||||
|
len(targets) > 0, "targets must not be empty"
|
||||||
|
len(command) > 0, "command must not be empty"
|
||||||
|
concurrency_limit > 0, "concurrency_limit must be positive"
|
||||||
|
|
||||||
|
schema WebhookConfig:
|
||||||
|
"""Webhook configuration for Git providers"""
|
||||||
|
# Provider
|
||||||
|
provider: TypesGit.GitProvider
|
||||||
|
|
||||||
|
# Listener port
|
||||||
|
port: int = 8080
|
||||||
|
|
||||||
|
# Webhook secret for validation
|
||||||
|
secret?: str
|
||||||
|
# Allowed events
|
||||||
|
allowed_events: [TypesGit.EventType]
|
||||||
|
|
||||||
|
check:
|
||||||
|
port > 1024 and port <= 65535, "port must be 1024-65535"
|
||||||
|
len(allowed_events) > 0, "allowed_events must not be empty"
|
||||||
|
|
||||||
|
schema ScheduledTrigger:
|
||||||
|
"""Scheduled trigger configuration"""
|
||||||
|
# Trigger name
|
||||||
|
name: str
|
||||||
|
|
||||||
|
# Cron expression
|
||||||
|
cron: str
|
||||||
|
|
||||||
|
# Associated rule
|
||||||
|
rule: str
|
||||||
|
|
||||||
|
# Target environment
|
||||||
|
environment: TypesGit.Environment
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "name must not be empty"
|
||||||
|
len(cron) > 0, "cron must not be empty"
|
||||||
|
len(rule) > 0, "rule must not be empty"
|
||||||
|
|
||||||
|
schema HealthCheckTrigger:
|
||||||
|
"""Health check based trigger configuration"""
|
||||||
|
# Trigger name
|
||||||
|
name: str
|
||||||
|
|
||||||
|
# Health check endpoint
|
||||||
|
endpoint: str
|
||||||
|
|
||||||
|
# Check interval in seconds
|
||||||
|
interval_secs: int = 60
|
||||||
|
|
||||||
|
# Failure threshold
|
||||||
|
failure_threshold: int = 3
|
||||||
|
|
||||||
|
# Action on failure
|
||||||
|
on_failure_action: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "name must not be empty"
|
||||||
|
len(endpoint) > 0, "endpoint must not be empty"
|
||||||
|
interval_secs > 0, "interval_secs must be positive"
|
||||||
|
failure_threshold > 0, "failure_threshold must be positive"
|
||||||
|
|
||||||
|
schema GitOpsConfig:
|
||||||
|
"""Global GitOps configuration"""
|
||||||
|
# Automation rules
|
||||||
|
rules: [GitOpsRule]
|
||||||
|
|
||||||
|
# Webhooks
|
||||||
|
webhooks: [WebhookConfig] = []
|
||||||
|
|
||||||
|
# Scheduled triggers
|
||||||
|
scheduled: [ScheduledTrigger] = []
|
||||||
|
|
||||||
|
# Health check triggers
|
||||||
|
health_checks: [HealthCheckTrigger] = []
|
||||||
|
|
||||||
|
# Default deployment strategy
|
||||||
|
default_strategy: str = "rolling"
|
||||||
|
|
||||||
|
# Enable dry-run by default
|
||||||
|
dry_run_by_default: bool = False
|
||||||
|
|
||||||
|
# Audit logging
|
||||||
|
enable_audit_log: bool = True
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(rules) >= 0, "rules must be a valid list"
|
||||||
|
|
||||||
|
# Global GitOps configuration
|
||||||
|
gitops_config: GitOpsConfig = {
|
||||||
|
rules = []
|
||||||
|
webhooks = []
|
||||||
|
scheduled = []
|
||||||
|
health_checks = []
|
||||||
|
default_strategy = "rolling"
|
||||||
|
dry_run_by_default = False
|
||||||
|
enable_audit_log = True
|
||||||
|
}
|
||||||
53
integrations/main.k
Normal file
53
integrations/main.k
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
"""
|
||||||
|
Provisioning bridge integrations main schema reference.
|
||||||
|
|
||||||
|
Note: Individual integration modules are in separate files:
|
||||||
|
- runtime.k: Container runtime abstraction (Docker, Podman, etc.)
|
||||||
|
- ssh_advanced.k: SSH connection pooling and circuit breaker
|
||||||
|
- backup.k: Backup system configuration (Restic, BorgBackup, etc.)
|
||||||
|
- gitops.k: GitOps rule and event management
|
||||||
|
- service.k: Service management for systemd, launchd, runit, OpenRC
|
||||||
|
|
||||||
|
This file is a reference schema for the unified integrations configuration.
|
||||||
|
Each module compiles independently and can be used separately.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Aggregated type definitions for reference
|
||||||
|
schema IntegrationTypes:
|
||||||
|
"""Reference schema for all integration types"""
|
||||||
|
# Runtime types
|
||||||
|
Runtime: "docker" | "podman" | "orbstack" | "colima" | "nerdctl"
|
||||||
|
|
||||||
|
# SSH types
|
||||||
|
AuthMethod: "password" | "private_key" | "agent"
|
||||||
|
DeploymentStrategy: "rolling" | "blue-green" | "canary"
|
||||||
|
RetryStrategy: "exponential" | "linear" | "fibonacci"
|
||||||
|
|
||||||
|
# Backup types
|
||||||
|
BackendType: "restic" | "borg" | "tar" | "rsync" | "cpio"
|
||||||
|
RepositoryType: "local" | "s3" | "sftp" | "rest" | "b2"
|
||||||
|
|
||||||
|
# GitOps types
|
||||||
|
GitProvider: "github" | "gitlab" | "gitea"
|
||||||
|
EventType: "push" | "pull-request" | "webhook" | "scheduled" | "health-check" | "manual"
|
||||||
|
Environment: "dev" | "staging" | "prod"
|
||||||
|
|
||||||
|
# Service types
|
||||||
|
InitSystem: "systemd" | "launchd" | "runit" | "openrc"
|
||||||
|
RestartPolicy: "always" | "on-failure" | "no"
|
||||||
|
|
||||||
|
# Placeholder schema for documentation
|
||||||
|
schema IntegrationConfig:
|
||||||
|
"""
|
||||||
|
Main integrations configuration aggregator.
|
||||||
|
|
||||||
|
This schema aggregates all integration configurations.
|
||||||
|
Individual modules should be used directly:
|
||||||
|
- Import provisioning.integrations.runtime for RuntimeConfig
|
||||||
|
- Import provisioning.integrations.ssh_advanced for SshPool, CircuitBreakerConfig
|
||||||
|
- Import provisioning.integrations.backup for BackupConfig
|
||||||
|
- Import provisioning.integrations.gitops for GitOpsConfig
|
||||||
|
- Import provisioning.integrations.service for ServiceConfig
|
||||||
|
"""
|
||||||
|
# Placeholder - actual configurations are in individual modules
|
||||||
|
integration_types: IntegrationTypes = {}
|
||||||
63
integrations/runtime.k
Normal file
63
integrations/runtime.k
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
"""
|
||||||
|
Runtime abstraction configuration schema.
|
||||||
|
|
||||||
|
Provides unified configuration for Docker, Podman, OrbStack, Colima, nerdctl.
|
||||||
|
"""
|
||||||
|
|
||||||
|
schema TypesRuntime:
|
||||||
|
Runtime: "docker" | "podman" | "orbstack" | "colima" | "nerdctl"
|
||||||
|
|
||||||
|
schema RuntimeConfig:
|
||||||
|
"""Container runtime configuration"""
|
||||||
|
|
||||||
|
# Preferred runtime (if available)
|
||||||
|
preferred?: TypesRuntime.Runtime
|
||||||
|
|
||||||
|
# Runtimes to check in order
|
||||||
|
check_order: [TypesRuntime.Runtime] = [
|
||||||
|
"docker",
|
||||||
|
"podman",
|
||||||
|
"orbstack",
|
||||||
|
"colima",
|
||||||
|
"nerdctl"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Detection timeout in seconds
|
||||||
|
timeout_secs: int = 5
|
||||||
|
|
||||||
|
# Enable caching of runtime detection
|
||||||
|
enable_cache: bool = True
|
||||||
|
|
||||||
|
check:
|
||||||
|
timeout_secs > 0, "timeout_secs must be positive"
|
||||||
|
len(check_order) > 0, "check_order must not be empty"
|
||||||
|
|
||||||
|
schema ComposeAdapterConfig:
|
||||||
|
"""Docker Compose adapter configuration"""
|
||||||
|
|
||||||
|
# Target runtime
|
||||||
|
runtime: TypesRuntime.Runtime
|
||||||
|
|
||||||
|
# Path to compose file
|
||||||
|
compose_file: str
|
||||||
|
|
||||||
|
# Service environment
|
||||||
|
environment: str = "dev"
|
||||||
|
|
||||||
|
# Network mode
|
||||||
|
network_mode?: str
|
||||||
|
|
||||||
|
# Port mappings to override
|
||||||
|
port_overrides?: {str: str}
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(compose_file) > 0, "compose_file must not be empty"
|
||||||
|
environment in ["dev", "staging", "prod"], "environment must be dev|staging|prod"
|
||||||
|
|
||||||
|
# Global runtime configuration
|
||||||
|
runtime_config: RuntimeConfig = {
|
||||||
|
preferred = "docker"
|
||||||
|
check_order = ["docker", "podman", "orbstack", "colima", "nerdctl"]
|
||||||
|
timeout_secs = 5
|
||||||
|
enable_cache = True
|
||||||
|
}
|
||||||
196
integrations/service.k
Normal file
196
integrations/service.k
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
"""
|
||||||
|
Service management configuration schema.
|
||||||
|
|
||||||
|
Supports systemd, launchd, runit, OpenRC with unified interface.
|
||||||
|
"""
|
||||||
|
|
||||||
|
schema TypesService:
|
||||||
|
InitSystem: "systemd" | "launchd" | "runit" | "openrc"
|
||||||
|
RestartPolicy: "always" | "on-failure" | "no"
|
||||||
|
|
||||||
|
schema ServiceUnit:
|
||||||
|
"""Service configuration"""
|
||||||
|
|
||||||
|
# Service name
|
||||||
|
name: str
|
||||||
|
|
||||||
|
# Service description
|
||||||
|
description: str
|
||||||
|
|
||||||
|
# Executable path
|
||||||
|
binary: str
|
||||||
|
|
||||||
|
# Arguments
|
||||||
|
args: [str] = []
|
||||||
|
|
||||||
|
# Working directory
|
||||||
|
working_dir: str = "/opt"
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
env: {str: str} = {}
|
||||||
|
|
||||||
|
# Restart policy
|
||||||
|
restart_policy: TypesService.RestartPolicy = "on-failure"
|
||||||
|
|
||||||
|
# Restart delay in seconds
|
||||||
|
restart_delay_secs: int = 5
|
||||||
|
|
||||||
|
# Maximum restart attempts (-1 = unlimited)
|
||||||
|
max_retries: int = 5
|
||||||
|
|
||||||
|
# User to run as
|
||||||
|
user?: str
|
||||||
|
|
||||||
|
# Group to run as
|
||||||
|
group?: str
|
||||||
|
|
||||||
|
# Standard output target
|
||||||
|
stdout?: str
|
||||||
|
|
||||||
|
# Standard error target
|
||||||
|
stderr?: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "name must not be empty"
|
||||||
|
len(description) > 0, "description must not be empty"
|
||||||
|
len(binary) > 0, "binary must not be empty"
|
||||||
|
len(working_dir) > 0, "working_dir must not be empty"
|
||||||
|
restart_delay_secs > 0, "restart_delay_secs must be positive"
|
||||||
|
max_retries > -2, "max_retries must be >= -1"
|
||||||
|
|
||||||
|
schema ServiceTemplate:
|
||||||
|
"""Service template for code generation"""
|
||||||
|
|
||||||
|
# Target init system
|
||||||
|
init_system: TypesService.InitSystem
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
config: ServiceUnit
|
||||||
|
|
||||||
|
# Pre-install hook
|
||||||
|
pre_install_hook?: str
|
||||||
|
|
||||||
|
# Post-install hook
|
||||||
|
post_install_hook?: str
|
||||||
|
|
||||||
|
# Pre-start hook
|
||||||
|
pre_start_hook?: str
|
||||||
|
|
||||||
|
# Post-start hook
|
||||||
|
post_start_hook?: str
|
||||||
|
|
||||||
|
# Pre-stop hook
|
||||||
|
pre_stop_hook?: str
|
||||||
|
|
||||||
|
# Post-stop hook
|
||||||
|
post_stop_hook?: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(config.name) > 0, "config.name must not be empty"
|
||||||
|
|
||||||
|
schema ServicePool:
|
||||||
|
"""Service pool configuration for managing multiple services"""
|
||||||
|
|
||||||
|
# Pool name
|
||||||
|
name: str
|
||||||
|
|
||||||
|
# Services in this pool
|
||||||
|
services: [ServiceUnit]
|
||||||
|
|
||||||
|
# Default init system
|
||||||
|
init_system: TypesService.InitSystem = "systemd"
|
||||||
|
|
||||||
|
# Enable service manager
|
||||||
|
enable_service_manager: bool = True
|
||||||
|
|
||||||
|
# Health check interval in seconds
|
||||||
|
health_check_interval_secs: int = 30
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "name must not be empty"
|
||||||
|
len(services) > 0, "services must not be empty"
|
||||||
|
health_check_interval_secs > 0, "health_check_interval_secs must be positive"
|
||||||
|
|
||||||
|
schema HealthCheckConfig:
|
||||||
|
"""Service health check configuration"""
|
||||||
|
|
||||||
|
# Check type
|
||||||
|
check_type: str = "command" # command, http, tcp
|
||||||
|
|
||||||
|
# Command to execute (for command type)
|
||||||
|
command?: str
|
||||||
|
|
||||||
|
# HTTP endpoint (for http type)
|
||||||
|
http_endpoint?: str
|
||||||
|
|
||||||
|
# TCP address (for tcp type)
|
||||||
|
tcp_address?: str
|
||||||
|
|
||||||
|
# Check interval in seconds
|
||||||
|
interval_secs: int = 30
|
||||||
|
|
||||||
|
# Timeout in seconds
|
||||||
|
timeout_secs: int = 5
|
||||||
|
|
||||||
|
# Unhealthy threshold
|
||||||
|
unhealthy_threshold: int = 3
|
||||||
|
|
||||||
|
# Healthy threshold
|
||||||
|
healthy_threshold: int = 2
|
||||||
|
|
||||||
|
check:
|
||||||
|
interval_secs > 0, "interval_secs must be positive"
|
||||||
|
timeout_secs > 0, "timeout_secs must be positive"
|
||||||
|
unhealthy_threshold > 0, "unhealthy_threshold must be positive"
|
||||||
|
healthy_threshold > 0, "healthy_threshold must be positive"
|
||||||
|
|
||||||
|
schema ServiceMonitoring:
|
||||||
|
"""Service monitoring configuration"""
|
||||||
|
|
||||||
|
# Enable monitoring
|
||||||
|
enabled: bool = True
|
||||||
|
|
||||||
|
# Health checks
|
||||||
|
health_checks: [HealthCheckConfig] = []
|
||||||
|
|
||||||
|
# Logging configuration
|
||||||
|
log_level: str = "info"
|
||||||
|
|
||||||
|
# Log retention days
|
||||||
|
log_retention_days: int = 7
|
||||||
|
|
||||||
|
# Metrics collection
|
||||||
|
collect_metrics: bool = True
|
||||||
|
|
||||||
|
check:
|
||||||
|
log_retention_days > 0, "log_retention_days must be positive"
|
||||||
|
|
||||||
|
schema ServiceConfig:
|
||||||
|
"""Global service configuration"""
|
||||||
|
|
||||||
|
# Service pools
|
||||||
|
pools: [ServicePool]
|
||||||
|
|
||||||
|
# Monitoring configuration
|
||||||
|
monitoring: ServiceMonitoring = {
|
||||||
|
enabled = True
|
||||||
|
health_checks = []
|
||||||
|
log_level = "info"
|
||||||
|
log_retention_days = 7
|
||||||
|
collect_metrics = True
|
||||||
|
}
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(pools) >= 0, "pools must be a valid list"
|
||||||
|
|
||||||
|
# Global service configuration
|
||||||
|
service_config: ServiceConfig = {
|
||||||
|
pools = []
|
||||||
|
monitoring = {
|
||||||
|
enabled = True
|
||||||
|
health_checks = []
|
||||||
|
log_level = "info"
|
||||||
|
log_retention_days = 7
|
||||||
|
collect_metrics = True
|
||||||
|
}
|
||||||
|
}
|
||||||
129
integrations/ssh_advanced.k
Normal file
129
integrations/ssh_advanced.k
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
"""
|
||||||
|
SSH advanced configuration schema.
|
||||||
|
|
||||||
|
Integrates provctl-machines capabilities for distributed operations with pooling and circuit breaker.
|
||||||
|
"""
|
||||||
|
|
||||||
|
schema TypesSsh:
|
||||||
|
AuthMethod: "password" | "private_key" | "agent"
|
||||||
|
DeploymentStrategy: "rolling" | "blue-green" | "canary"
|
||||||
|
RetryStrategy: "exponential" | "linear" | "fibonacci"
|
||||||
|
|
||||||
|
schema SshAuth:
|
||||||
|
"""SSH authentication configuration"""
|
||||||
|
method: TypesSsh.AuthMethod
|
||||||
|
|
||||||
|
# Password authentication
|
||||||
|
password?: str
|
||||||
|
|
||||||
|
# Private key authentication
|
||||||
|
key_path?: str
|
||||||
|
passphrase?: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
(method == "password" and password != None) or \
|
||||||
|
(method == "private_key" and key_path != None) or \
|
||||||
|
(method == "agent"), \
|
||||||
|
"Invalid auth configuration for method"
|
||||||
|
|
||||||
|
schema SshConfig:
|
||||||
|
"""SSH connection configuration"""
|
||||||
|
|
||||||
|
host: str
|
||||||
|
port: int = 22
|
||||||
|
user: str
|
||||||
|
auth: SshAuth
|
||||||
|
|
||||||
|
# Connection timeout in seconds
|
||||||
|
timeout_secs: int = 30
|
||||||
|
|
||||||
|
# SSH options (e.g., StrictHostKeyChecking)
|
||||||
|
ssh_options?: {str: str}
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(host) > 0, "host must not be empty"
|
||||||
|
port > 0 and port <= 65535, "port must be 1-65535"
|
||||||
|
len(user) > 0, "user must not be empty"
|
||||||
|
timeout_secs > 0, "timeout_secs must be positive"
|
||||||
|
|
||||||
|
schema SshPool:
|
||||||
|
"""SSH connection pool configuration"""
|
||||||
|
|
||||||
|
# Pool name
|
||||||
|
name: str
|
||||||
|
|
||||||
|
# Hosts in the pool
|
||||||
|
hosts: [SshConfig]
|
||||||
|
|
||||||
|
# Pool size (max concurrent connections)
|
||||||
|
pool_size: int = 10
|
||||||
|
|
||||||
|
# Idle connection timeout in seconds
|
||||||
|
idle_timeout_secs: int = 300
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "name must not be empty"
|
||||||
|
len(hosts) >= 0, "hosts must be a valid list"
|
||||||
|
pool_size > 0, "pool_size must be positive"
|
||||||
|
|
||||||
|
schema DeploymentConfig:
|
||||||
|
"""SSH-based deployment configuration"""
|
||||||
|
|
||||||
|
# Deployment name
|
||||||
|
name: str
|
||||||
|
|
||||||
|
# Target hosts
|
||||||
|
hosts: [SshConfig]
|
||||||
|
|
||||||
|
# Deployment strategy
|
||||||
|
strategy: TypesSsh.DeploymentStrategy = "rolling"
|
||||||
|
|
||||||
|
# Command to execute
|
||||||
|
command: str
|
||||||
|
|
||||||
|
# Retry strategy
|
||||||
|
retry: TypesSsh.RetryStrategy = "exponential"
|
||||||
|
max_retries: int = 3
|
||||||
|
|
||||||
|
# Parallel execution
|
||||||
|
parallel: bool = True
|
||||||
|
|
||||||
|
# Dry-run mode
|
||||||
|
check_mode: bool = False
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "name must not be empty"
|
||||||
|
len(hosts) > 0, "hosts must not be empty"
|
||||||
|
len(command) > 0, "command must not be empty"
|
||||||
|
max_retries >= 0, "max_retries must be non-negative"
|
||||||
|
|
||||||
|
schema CircuitBreakerConfig:
|
||||||
|
"""Circuit breaker configuration for SSH operations"""
|
||||||
|
|
||||||
|
# Failure threshold
|
||||||
|
failure_threshold: int = 5
|
||||||
|
|
||||||
|
# Success threshold for recovery
|
||||||
|
success_threshold: int = 2
|
||||||
|
|
||||||
|
# Timeout in seconds before attempting reset
|
||||||
|
reset_timeout_secs: int = 60
|
||||||
|
|
||||||
|
check:
|
||||||
|
failure_threshold > 0, "failure_threshold must be positive"
|
||||||
|
success_threshold > 0, "success_threshold must be positive"
|
||||||
|
reset_timeout_secs > 0, "reset_timeout_secs must be positive"
|
||||||
|
|
||||||
|
# Global SSH configuration
|
||||||
|
ssh_pool_config: SshPool = {
|
||||||
|
name = "default"
|
||||||
|
hosts = []
|
||||||
|
pool_size = 10
|
||||||
|
idle_timeout_secs = 300
|
||||||
|
}
|
||||||
|
|
||||||
|
circuit_breaker: CircuitBreakerConfig = {
|
||||||
|
failure_threshold = 5
|
||||||
|
success_threshold = 2
|
||||||
|
reset_timeout_secs = 60
|
||||||
|
}
|
||||||
43
k8s_deploy.k
43
k8s_deploy.k
@ -69,7 +69,7 @@ schema K8sVolume:
|
|||||||
"""
|
"""
|
||||||
name: str
|
name: str
|
||||||
typ: "volumeClaim" | "configMap" | "secret" = "volumeClaim"
|
typ: "volumeClaim" | "configMap" | "secret" = "volumeClaim"
|
||||||
persitentVolumeClaim?: K8sVolumeClaim
|
persistentVolumeClaim?: K8sVolumeClaim
|
||||||
items?: [K8sKeyPath]
|
items?: [K8sKeyPath]
|
||||||
configMap?: K8sConfigMap
|
configMap?: K8sConfigMap
|
||||||
secret?: K8sSecret
|
secret?: K8sSecret
|
||||||
@ -84,7 +84,7 @@ schema K8sService:
|
|||||||
proto: "TCP" = "TCP"
|
proto: "TCP" = "TCP"
|
||||||
ports: [K8sPort]
|
ports: [K8sPort]
|
||||||
selector?: [K8sKeyVal]
|
selector?: [K8sKeyVal]
|
||||||
externaIPs?: [str]
|
externalIPs?: [str]
|
||||||
|
|
||||||
schema K8sContainers:
|
schema K8sContainers:
|
||||||
"""
|
"""
|
||||||
@ -225,6 +225,20 @@ schema K8sDefs:
|
|||||||
primary_dom: str
|
primary_dom: str
|
||||||
cluster_domain: str
|
cluster_domain: str
|
||||||
|
|
||||||
|
schema K8sServiceMeshConfig:
|
||||||
|
"""
|
||||||
|
K8S Service Mesh Configuration
|
||||||
|
"""
|
||||||
|
mtls_enabled?: bool = True
|
||||||
|
tracing_enabled?: bool = True
|
||||||
|
|
||||||
|
schema K8sIngressConfig:
|
||||||
|
"""
|
||||||
|
K8S Ingress Controller Configuration
|
||||||
|
"""
|
||||||
|
tls_enabled?: bool = True
|
||||||
|
default_backend?: str
|
||||||
|
|
||||||
schema K8sDeploy:
|
schema K8sDeploy:
|
||||||
"""
|
"""
|
||||||
K8S Deployment settings
|
K8S Deployment settings
|
||||||
@ -243,11 +257,23 @@ schema K8sDeploy:
|
|||||||
sel_labels: [K8sKeyVal] = labels
|
sel_labels: [K8sKeyVal] = labels
|
||||||
tpl_labels: [K8sKeyVal] = labels
|
tpl_labels: [K8sKeyVal] = labels
|
||||||
spec: K8sDeploySpec
|
spec: K8sDeploySpec
|
||||||
# Cluster Ingres Proxy to use
|
|
||||||
prxy?: "istio"
|
# Service Mesh Configuration (NEW)
|
||||||
|
service_mesh?: "istio" | "linkerd" | "cilium"
|
||||||
|
service_mesh_ns?: str
|
||||||
|
service_mesh_config?: K8sServiceMeshConfig
|
||||||
|
|
||||||
|
# Ingress Controller Configuration (NEW)
|
||||||
|
ingress_controller?: "nginx" | "traefik" | "contour" | "haproxy" | "istio-gateway"
|
||||||
|
ingress_ns?: str
|
||||||
|
ingress_config?: K8sIngressConfig
|
||||||
|
|
||||||
|
# Legacy Proxy Field (DEPRECATED - kept for backward compatibility)
|
||||||
|
prxy?: "istio" | "linkerd" | "nginx" | "traefik" | "contour" | "haproxy"
|
||||||
prxy_ns?: str = "istio-system"
|
prxy_ns?: str = "istio-system"
|
||||||
prxyGatewayServers?: [K8sPrxyGatewayServer]
|
prxyGatewayServers?: [K8sPrxyGatewayServer]
|
||||||
prxyVirtualService?: K8sPrxyVirtualService
|
prxyVirtualService?: K8sPrxyVirtualService
|
||||||
|
|
||||||
# TSL certs path for service
|
# TSL certs path for service
|
||||||
tls_path?: str = "ssl"
|
tls_path?: str = "ssl"
|
||||||
# Create bin/apply.sh
|
# Create bin/apply.sh
|
||||||
@ -257,3 +283,12 @@ schema K8sDeploy:
|
|||||||
# Service Backup K8s JOB
|
# Service Backup K8s JOB
|
||||||
backups?: [K8sBackup]
|
backups?: [K8sBackup]
|
||||||
|
|
||||||
|
# Validation rules
|
||||||
|
check:
|
||||||
|
# Validate service mesh and ingress controller compatibility
|
||||||
|
# Linkerd requires an external ingress controller
|
||||||
|
service_mesh != "linkerd" or ingress_controller in ["nginx", "traefik", "contour", "haproxy", None], \
|
||||||
|
"Linkerd requires external ingress controller (nginx, traefik, contour, or haproxy)"
|
||||||
|
# Note: Istio has built-in gateway, external ingress may be redundant with service_mesh="istio"
|
||||||
|
# Namespace defaults are handled in code if not explicitly specified
|
||||||
|
|
||||||
|
|||||||
24
modes.k
24
modes.k
@ -13,8 +13,8 @@ Modes:
|
|||||||
- enterprise: Production enterprise deployment
|
- enterprise: Production enterprise deployment
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import provisioning.settings as cfg
|
import .settings as cfg
|
||||||
import provisioning.kcl.oci_registry as oci
|
import .oci_registry as oci
|
||||||
|
|
||||||
schema ExecutionMode:
|
schema ExecutionMode:
|
||||||
"""
|
"""
|
||||||
@ -71,12 +71,8 @@ schema AuthenticationStrategy:
|
|||||||
ssh_key_storage: "local" | "kms" | "vault" = "local"
|
ssh_key_storage: "local" | "kms" | "vault" = "local"
|
||||||
|
|
||||||
check:
|
check:
|
||||||
auth_type == "none" or (
|
auth_type == "none" or ((auth_type == "token" and token_config != Undefined) or (auth_type == "mtls" and mtls_config != Undefined) or (auth_type == "oauth" and oauth_config != Undefined) or (auth_type == "kms")), \
|
||||||
(auth_type == "token" and token_config != Undefined) or
|
"Auth config must match auth type"
|
||||||
(auth_type == "mtls" and mtls_config != Undefined) or
|
|
||||||
(auth_type == "oauth" and oauth_config != Undefined) or
|
|
||||||
(auth_type == "kms")
|
|
||||||
), "Auth config must match auth type"
|
|
||||||
|
|
||||||
schema TokenConfig:
|
schema TokenConfig:
|
||||||
"""Token-based authentication configuration"""
|
"""Token-based authentication configuration"""
|
||||||
@ -150,11 +146,8 @@ schema ServiceConfig:
|
|||||||
health_check?: HealthCheck
|
health_check?: HealthCheck
|
||||||
|
|
||||||
check:
|
check:
|
||||||
deployment == "disabled" or (
|
deployment == "disabled" or ((deployment == "local" and local_config != Undefined) or (deployment == "remote" and remote_config != Undefined) or (deployment == "k8s" and k8s_config != Undefined)), \
|
||||||
(deployment == "local" and local_config != Undefined) or
|
"Service config must match deployment type"
|
||||||
(deployment == "remote" and remote_config != Undefined) or
|
|
||||||
(deployment == "k8s" and k8s_config != Undefined)
|
|
||||||
), "Service config must match deployment type"
|
|
||||||
|
|
||||||
schema LocalServiceConfig:
|
schema LocalServiceConfig:
|
||||||
"""Local service deployment configuration"""
|
"""Local service deployment configuration"""
|
||||||
@ -241,10 +234,7 @@ schema ExtensionConfig:
|
|||||||
allow_mixed: bool = False
|
allow_mixed: bool = False
|
||||||
|
|
||||||
check:
|
check:
|
||||||
source == "local" and local_path != Undefined or
|
(source == "local" and local_path != Undefined) or (source == "gitea" and gitea_config != Undefined) or (source == "oci" and oci_registry != Undefined) or source == "mixed", "Extension config must match source type"
|
||||||
source == "gitea" and gitea_config != Undefined or
|
|
||||||
source == "oci" and oci_registry != Undefined or
|
|
||||||
source == "mixed", "Extension config must match source type"
|
|
||||||
|
|
||||||
schema GiteaConfig:
|
schema GiteaConfig:
|
||||||
"""Gitea extension repository configuration"""
|
"""Gitea extension repository configuration"""
|
||||||
|
|||||||
320
nested_provisioning.k
Normal file
320
nested_provisioning.k
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
# Nested Provisioning Schema (Phase 4)
|
||||||
|
#
|
||||||
|
# Support for nested VM provisioning (VM → VM → Containers).
|
||||||
|
# Follows KCL idiomatic patterns: schema-first, check blocks, composition.
|
||||||
|
|
||||||
|
schema VolumeConfig:
|
||||||
|
"""
|
||||||
|
Storage volume configuration for VMs and containers.
|
||||||
|
|
||||||
|
Defines volumes that can be attached to VMs or mounted in containers.
|
||||||
|
Supports local storage, network mounts, and cloud storage.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
# Local volume
|
||||||
|
VolumeConfig {
|
||||||
|
name = "data-volume"
|
||||||
|
type = "local"
|
||||||
|
size_gb = 100
|
||||||
|
mount_path = "/data"
|
||||||
|
readonly = False
|
||||||
|
}
|
||||||
|
|
||||||
|
# Network mount
|
||||||
|
VolumeConfig {
|
||||||
|
name = "shared-storage"
|
||||||
|
type = "nfs"
|
||||||
|
host = "storage.example.com"
|
||||||
|
path = "/exports/shared"
|
||||||
|
mount_path = "/mnt/shared"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Volume Identity
|
||||||
|
name: str # Volume name (unique)
|
||||||
|
description?: str # Volume description
|
||||||
|
|
||||||
|
# Volume Type and Storage (Pattern 8: Union types)
|
||||||
|
type: "local" | "nfs" | "cifs" | "cloud" | "host" = "local"
|
||||||
|
size_gb?: int # Volume size in GB
|
||||||
|
|
||||||
|
# Mount Configuration
|
||||||
|
mount_path: str # Mount point inside container/VM
|
||||||
|
readonly?: bool = False # Read-only mount
|
||||||
|
mount_mode?: str = "755" # Unix mount mode
|
||||||
|
|
||||||
|
# Backing Storage (Pattern 9: Optional fields)
|
||||||
|
host?: str # Remote host (for NFS/CIFS)
|
||||||
|
path?: str # Remote path (for NFS/CIFS)
|
||||||
|
username?: str # Username for auth
|
||||||
|
password?: str # Password for auth (use secrets)
|
||||||
|
|
||||||
|
# Cloud Storage
|
||||||
|
bucket?: str # S3 bucket name
|
||||||
|
provider?: "aws" | "azure" | "gcp" | "minio" = "aws"
|
||||||
|
region?: str # Cloud region
|
||||||
|
|
||||||
|
# Performance Tuning
|
||||||
|
iops?: int # IOPS limit
|
||||||
|
throughput_mbps?: int # Throughput limit
|
||||||
|
|
||||||
|
# Validation (Pattern 4: Check blocks)
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Volume name required"
|
||||||
|
len(mount_path) > 0, "Mount path required"
|
||||||
|
mount_path.startswith("/"), "Mount path must be absolute"
|
||||||
|
size_gb == Undefined or size_gb >= 0, "Size must be non-negative"
|
||||||
|
|
||||||
|
|
||||||
|
schema NetworkConfig:
|
||||||
|
"""
|
||||||
|
Network configuration for nested VMs and containers.
|
||||||
|
|
||||||
|
Defines virtual networks, VLANs, and network policies.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Network Identity
|
||||||
|
name: str # Network name
|
||||||
|
description?: str # Network description
|
||||||
|
|
||||||
|
# Network Type (Pattern 8: Union types)
|
||||||
|
type: "bridge" | "overlay" | "host" | "vlan" = "bridge"
|
||||||
|
vlan_id?: int # VLAN ID (if applicable)
|
||||||
|
|
||||||
|
# Network Configuration
|
||||||
|
subnet: str # Subnet CIDR (e.g., 192.168.1.0/24)
|
||||||
|
gateway?: str # Gateway IP
|
||||||
|
dns_servers?: [str] # DNS servers
|
||||||
|
mtu?: int = 1500 # MTU size
|
||||||
|
|
||||||
|
# IP Address Management
|
||||||
|
dhcp_enabled?: bool = True # DHCP enabled
|
||||||
|
dhcp_start?: str # DHCP range start
|
||||||
|
dhcp_end?: str # DHCP range end
|
||||||
|
|
||||||
|
# Network Policy (Pattern 9: Optional fields)
|
||||||
|
allow_outbound?: bool = True # Allow outbound traffic
|
||||||
|
allow_inbound?: bool = False # Allow inbound traffic
|
||||||
|
rules?: [{str: str}] # Network rules
|
||||||
|
|
||||||
|
# Performance
|
||||||
|
bandwidth_limit_mbps?: int # Bandwidth limit
|
||||||
|
latency_ms?: int # Artificial latency
|
||||||
|
|
||||||
|
# Validation (Pattern 4: Check blocks)
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Network name required"
|
||||||
|
len(subnet) > 0, "Subnet required"
|
||||||
|
|
||||||
|
|
||||||
|
schema NestedVmConfig:
|
||||||
|
"""
|
||||||
|
Configuration for a nested VM (VM inside a VM).
|
||||||
|
|
||||||
|
Enables multi-level virtualization for complex deployments.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# VM Identity
|
||||||
|
name: str # VM name
|
||||||
|
description?: str # VM description
|
||||||
|
parent_vm: str # Parent VM name
|
||||||
|
|
||||||
|
# Virtualization
|
||||||
|
cpu: int = 2 # CPU cores (1-32)
|
||||||
|
memory_mb: int = 2048 # Memory in MB
|
||||||
|
disk_gb: int = 20 # Disk size in GB
|
||||||
|
nested_virt?: bool = True # Enable nested virtualization
|
||||||
|
|
||||||
|
# Image Configuration
|
||||||
|
base_image?: str = "ubuntu-22.04" # Base image
|
||||||
|
from_golden_image?: str # Golden image to use
|
||||||
|
|
||||||
|
# Networking (Pattern 3: Composition)
|
||||||
|
networks: [str] # Network names to connect
|
||||||
|
static_ip?: str # Static IP address
|
||||||
|
dns?: [str] # DNS servers
|
||||||
|
|
||||||
|
# Storage (Pattern 3: Composition)
|
||||||
|
volumes?: [str] # Volume names to attach
|
||||||
|
extra_disks?: [{str: int}] # Additional disks {name: size_gb}
|
||||||
|
|
||||||
|
# Lifecycle
|
||||||
|
auto_start?: bool = False # Auto-start on parent boot
|
||||||
|
start_order?: int = 100 # Startup order
|
||||||
|
restart_policy?: "no" | "always" | "on-failure" = "always"
|
||||||
|
|
||||||
|
# Validation (Pattern 4: Check blocks)
|
||||||
|
check:
|
||||||
|
len(name) > 0, "VM name required"
|
||||||
|
len(parent_vm) > 0, "Parent VM required"
|
||||||
|
cpu > 0 and cpu <= 32, "CPU must be 1-32"
|
||||||
|
memory_mb >= 512 and memory_mb <= 65536, "Memory must be 512MB-64GB"
|
||||||
|
disk_gb >= 5 and disk_gb <= 1000, "Disk must be 5-1000GB"
|
||||||
|
|
||||||
|
|
||||||
|
schema ContainerConfig:
|
||||||
|
"""
|
||||||
|
Container configuration for running inside nested VMs.
|
||||||
|
|
||||||
|
Defines container deployments with resource limits and networking.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Container Identity
|
||||||
|
name: str # Container name
|
||||||
|
image: str # Container image
|
||||||
|
tag?: str = "latest" # Image tag
|
||||||
|
|
||||||
|
# Runtime Environment (Pattern 3: Composition)
|
||||||
|
parent_vm: str # Parent VM name
|
||||||
|
runtime: "docker" | "podman" | "containerd" = "containerd"
|
||||||
|
|
||||||
|
# Resources (Pattern 5: Explicit types)
|
||||||
|
cpu_millicores?: int = 1000 # CPU in millicores
|
||||||
|
memory_mb?: int = 512 # Memory in MB
|
||||||
|
disk_gb?: int = 10 # Disk space
|
||||||
|
|
||||||
|
# Networking
|
||||||
|
networks?: [str] # Networks to connect
|
||||||
|
expose_ports?: [{int: int}] # Port mappings {host: container}
|
||||||
|
environment?: {str: str} # Environment variables
|
||||||
|
|
||||||
|
# Storage (Pattern 9: Optional fields)
|
||||||
|
volumes?: [{str: str}] # Volume mounts {name: path}
|
||||||
|
tmpfs?: int # Tmpfs size in MB
|
||||||
|
|
||||||
|
# Lifecycle
|
||||||
|
auto_start?: bool = False # Auto-start on VM boot
|
||||||
|
restart_policy?: "no" | "unless-stopped" | "always" = "unless-stopped"
|
||||||
|
health_check?: {str: str} # Health check config
|
||||||
|
|
||||||
|
# Validation (Pattern 4: Check blocks)
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Container name required"
|
||||||
|
len(image) > 0, "Image required"
|
||||||
|
cpu_millicores > 0, "CPU must be positive"
|
||||||
|
memory_mb >= 256, "Memory must be at least 256MB"
|
||||||
|
|
||||||
|
|
||||||
|
schema MultiTierDeployment:
|
||||||
|
"""
|
||||||
|
Multi-tier application deployment specification.
|
||||||
|
|
||||||
|
Defines complete application stack with multiple VMs and containers.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Deployment Identity
|
||||||
|
name: str # Deployment name
|
||||||
|
version?: str = "1.0.0" # Version
|
||||||
|
description?: str # Description
|
||||||
|
|
||||||
|
# Infrastructure (Pattern 3: Composition)
|
||||||
|
networks: [NetworkConfig] # Virtual networks
|
||||||
|
volumes: [VolumeConfig] # Shared volumes
|
||||||
|
|
||||||
|
# Application Tiers
|
||||||
|
parent_vms: [str] # Parent VMs
|
||||||
|
nested_vms: [NestedVmConfig] # Nested VMs
|
||||||
|
containers: [ContainerConfig] # Containers
|
||||||
|
|
||||||
|
# Deployment Configuration
|
||||||
|
replicas?: int = 1 # Replicas of deployment
|
||||||
|
strategy?: "rolling" | "blue-green" | "canary" = "rolling"
|
||||||
|
health_check_interval?: int = 30 # Health check interval (s)
|
||||||
|
|
||||||
|
# Validation (Pattern 4: Check blocks)
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Deployment name required"
|
||||||
|
replicas == Undefined or replicas > 0, "Replicas must be positive"
|
||||||
|
len(networks) > 0, "At least one network required"
|
||||||
|
|
||||||
|
|
||||||
|
schema NetworkPolicy:
|
||||||
|
"""
|
||||||
|
Network security policies for nested environments.
|
||||||
|
|
||||||
|
Controls traffic flow between VMs, containers, and external network.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Policy Identity
|
||||||
|
name: str # Policy name
|
||||||
|
description?: str # Description
|
||||||
|
|
||||||
|
# Traffic Rules (Pattern 8: Union types)
|
||||||
|
direction: "inbound" | "outbound" | "both" = "both"
|
||||||
|
protocol: "tcp" | "udp" | "icmp" | "all" = "all"
|
||||||
|
|
||||||
|
# Source/Destination
|
||||||
|
source?: str # Source CIDR or name
|
||||||
|
destination?: str # Destination CIDR or name
|
||||||
|
port_range?: str # Port range (e.g., "8000-9000")
|
||||||
|
|
||||||
|
# Action (Pattern 8: Union types)
|
||||||
|
action: "allow" | "deny" | "log" = "allow"
|
||||||
|
priority?: int = 100 # Rule priority
|
||||||
|
|
||||||
|
# Validation (Pattern 4: Check blocks)
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Policy name required"
|
||||||
|
|
||||||
|
|
||||||
|
schema VolumeSnapshot:
|
||||||
|
"""
|
||||||
|
Snapshot of a volume for backup and disaster recovery.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Snapshot Identity
|
||||||
|
name: str # Snapshot name
|
||||||
|
volume_name: str # Source volume name
|
||||||
|
created_at: str # Creation timestamp
|
||||||
|
|
||||||
|
# Snapshot Metadata
|
||||||
|
size_gb: float # Snapshot size
|
||||||
|
checksum: str # SHA256 checksum
|
||||||
|
description?: str # Description
|
||||||
|
|
||||||
|
# Retention Policy
|
||||||
|
retention_days?: int = 30 # Retention period
|
||||||
|
auto_delete?: bool = True # Auto-delete after retention
|
||||||
|
|
||||||
|
# Validation (Pattern 4: Check blocks)
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Snapshot name required"
|
||||||
|
len(volume_name) > 0, "Volume name required"
|
||||||
|
|
||||||
|
|
||||||
|
schema NestedProvisioningPolicy:
|
||||||
|
"""
|
||||||
|
Global policy for nested provisioning operations.
|
||||||
|
|
||||||
|
Controls behavior, limits, and defaults for nested environments.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Nesting Limits
|
||||||
|
max_nesting_depth: int = 3 # Maximum nesting levels
|
||||||
|
max_vms_per_parent: int = 10 # Max VMs per parent
|
||||||
|
max_containers_per_vm: int = 50 # Max containers per VM
|
||||||
|
|
||||||
|
# Resource Limits (Pattern 5: Explicit types)
|
||||||
|
max_cpu_per_vm: int = 16 # Max CPU cores
|
||||||
|
max_memory_per_vm: int = 32768 # Max memory in MB
|
||||||
|
max_disk_per_vm: int = 500 # Max disk in GB
|
||||||
|
|
||||||
|
# Network Configuration
|
||||||
|
default_network_type: str = "bridge"
|
||||||
|
enable_ipv6?: bool = False
|
||||||
|
enable_vlan_tagging?: bool = False
|
||||||
|
|
||||||
|
# Storage Configuration
|
||||||
|
default_volume_type: str = "local"
|
||||||
|
snapshot_retention_days: int = 30
|
||||||
|
|
||||||
|
# Security
|
||||||
|
enable_security_hardening?: bool = True
|
||||||
|
enable_network_isolation?: bool = True
|
||||||
|
require_auth_between_tiers?: bool = False
|
||||||
|
|
||||||
|
# Validation (Pattern 4: Check blocks)
|
||||||
|
check:
|
||||||
|
max_nesting_depth >= 1 and max_nesting_depth <= 5, "Nesting depth must be 1-5"
|
||||||
|
max_vms_per_parent > 0, "Max VMs must be positive"
|
||||||
|
max_cpu_per_vm > 0, "Max CPU must be positive"
|
||||||
@ -92,16 +92,9 @@ schema OCIRegistryConfig:
|
|||||||
len(endpoint) > 0, "OCI registry endpoint required"
|
len(endpoint) > 0, "OCI registry endpoint required"
|
||||||
port == Undefined or (port > 0 and port < 65536), \
|
port == Undefined or (port > 0 and port < 65536), \
|
||||||
"Port must be 1-65535"
|
"Port must be 1-65535"
|
||||||
deployment == "disabled" or (
|
deployment == "disabled" or ((deployment == "local" and local != Undefined) or (deployment == "remote" and remote != Undefined)), "Config must match deployment type"
|
||||||
(deployment == "local" and local != Undefined) or
|
not auth_required or (username != Undefined or auth_token_path != Undefined), "Authentication config required when auth enabled"
|
||||||
(deployment == "remote" and remote != Undefined)
|
not tls_enabled or (tls_cert_path != Undefined and tls_key_path != Undefined) or deployment == "remote", "TLS cert/key required for local TLS"
|
||||||
), "Config must match deployment type"
|
|
||||||
not auth_required or (
|
|
||||||
username != Undefined or auth_token_path != Undefined
|
|
||||||
), "Authentication config required when auth enabled"
|
|
||||||
not tls_enabled or (
|
|
||||||
tls_cert_path != Undefined and tls_key_path != Undefined
|
|
||||||
) or deployment == "remote", "TLS cert/key required for local TLS"
|
|
||||||
|
|
||||||
schema LocalOCIConfig:
|
schema LocalOCIConfig:
|
||||||
"""
|
"""
|
||||||
@ -357,7 +350,7 @@ schema OCIArtifactReference:
|
|||||||
digest?: str
|
digest?: str
|
||||||
|
|
||||||
# Computed full reference
|
# Computed full reference
|
||||||
full_reference: str = f"{registry}/{namespace}/{repository}:{tag}"
|
full_reference: str = registry + "/" + namespace + "/" + repository + ":" + tag
|
||||||
|
|
||||||
check:
|
check:
|
||||||
len(registry) > 0, "Registry required"
|
len(registry) > 0, "Registry required"
|
||||||
|
|||||||
@ -43,8 +43,8 @@ schema ServiceDefinition:
|
|||||||
check:
|
check:
|
||||||
len(name) > 0, "Service name cannot be empty"
|
len(name) > 0, "Service name cannot be empty"
|
||||||
not (name in dependencies), "Service cannot depend on itself"
|
not (name in dependencies), "Service cannot depend on itself"
|
||||||
len(set(dependencies) & set(conflicts)) == 0, \
|
# Check: no service can be both in dependencies and conflicts
|
||||||
"Service cannot both depend on and conflict with same service"
|
len([dep for dep in dependencies if dep in conflicts]) == 0, "Service cannot both depend on and conflict with same service"
|
||||||
|
|
||||||
schema ServiceDeployment:
|
schema ServiceDeployment:
|
||||||
"""Service deployment configuration"""
|
"""Service deployment configuration"""
|
||||||
|
|||||||
204
system_config.k
Normal file
204
system_config.k
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
"""
|
||||||
|
System Configuration Schema for Provisioning Platform (SIMPLIFIED)
|
||||||
|
|
||||||
|
Defines all configuration categories with clear override rules.
|
||||||
|
Note: This is a simplified version focusing on compilable schemas.
|
||||||
|
Complex union types and nested structures have been flattened.
|
||||||
|
|
||||||
|
Version: 1.0.0
|
||||||
|
Last Updated: 2025-12-11
|
||||||
|
"""
|
||||||
|
|
||||||
|
import regex
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# CORE SCHEMAS (Simplified for KCL 0.11.3 compatibility)
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema SystemConfig:
|
||||||
|
"""System-level immutable configuration"""
|
||||||
|
version: str = "1.0.0"
|
||||||
|
install_path: str
|
||||||
|
os_name: "macos" | "linux" | "windows" = "linux"
|
||||||
|
os_version: str
|
||||||
|
config_base_path: str
|
||||||
|
cache_base_path: str
|
||||||
|
workspaces_dir: str
|
||||||
|
system_architecture: str
|
||||||
|
cpu_count: int
|
||||||
|
memory_total_gb: int
|
||||||
|
disk_total_gb: int
|
||||||
|
setup_date: str # ISO 8601 timestamp
|
||||||
|
setup_by_user: str
|
||||||
|
setup_hostname: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(install_path) > 0, "install_path cannot be empty"
|
||||||
|
len(config_base_path) > 0, "config_base_path cannot be empty"
|
||||||
|
cpu_count > 0 and cpu_count <= 1024, "cpu_count must be 1-1024"
|
||||||
|
memory_total_gb > 0 and memory_total_gb <= 4096, "memory must be 1-4096 GB"
|
||||||
|
disk_total_gb > 0 and disk_total_gb <= 100000, "disk must be 1-100000 GB"
|
||||||
|
|
||||||
|
schema OrchestratorConfig:
|
||||||
|
"""Orchestrator service configuration"""
|
||||||
|
enabled: bool = True
|
||||||
|
endpoint: str = "http://localhost:9090"
|
||||||
|
port: int = 9090
|
||||||
|
timeout_seconds: int = 30
|
||||||
|
health_check_interval_seconds: int = 5
|
||||||
|
|
||||||
|
check:
|
||||||
|
port > 0 and port <= 65535, "port must be 1-65535"
|
||||||
|
timeout_seconds > 0 and timeout_seconds <= 300, "timeout must be 1-300 seconds"
|
||||||
|
|
||||||
|
schema DatabaseConfig:
|
||||||
|
"""Database configuration"""
|
||||||
|
backend: "memory" | "surrealdb" = "memory"
|
||||||
|
url?: str
|
||||||
|
|
||||||
|
schema ControlCenterConfig:
|
||||||
|
"""Control Center service configuration"""
|
||||||
|
enabled: bool = True
|
||||||
|
url: str = "http://localhost:3000"
|
||||||
|
port: int = 3000
|
||||||
|
timeout_seconds: int = 30
|
||||||
|
database: DatabaseConfig
|
||||||
|
|
||||||
|
check:
|
||||||
|
port > 0 and port <= 65535, "port must be 1-65535"
|
||||||
|
timeout_seconds > 0 and timeout_seconds <= 300, "timeout must be 1-300 seconds"
|
||||||
|
|
||||||
|
schema KMSConfig:
|
||||||
|
"""Key Management System configuration"""
|
||||||
|
enabled: bool = True
|
||||||
|
backend: "rustyvault" | "age" | "vault" | "aws-kms" = "age"
|
||||||
|
endpoint?: str
|
||||||
|
port?: int
|
||||||
|
rotation_days?: int = 90
|
||||||
|
|
||||||
|
check:
|
||||||
|
port == Undefined or (port > 0 and port <= 65535), "port must be 1-65535 if specified"
|
||||||
|
rotation_days == Undefined or (rotation_days > 0 and rotation_days <= 3650), \
|
||||||
|
"rotation_days must be 1-3650 if specified"
|
||||||
|
|
||||||
|
schema PlatformServicesConfig:
|
||||||
|
"""Platform services configuration"""
|
||||||
|
orchestrator: OrchestratorConfig
|
||||||
|
control_center: ControlCenterConfig
|
||||||
|
kms_service: KMSConfig
|
||||||
|
|
||||||
|
schema ProviderCredentialsReference:
|
||||||
|
"""Reference to credentials stored in RustyVault"""
|
||||||
|
credentials_source: str # rustyvault://workspace_prod/providers/upcloud
|
||||||
|
credentials_source_type: "rustyvault" | "vault" | "kms" = "rustyvault"
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(credentials_source) > 0, "credentials_source cannot be empty"
|
||||||
|
credentials_source.startswith("rustyvault://") or credentials_source.startswith("vault://") or credentials_source.startswith("kms://"), \
|
||||||
|
"credentials_source must start with rustyvault://, vault://, or kms://"
|
||||||
|
|
||||||
|
schema UpCloudConfig:
|
||||||
|
"""UpCloud provider configuration"""
|
||||||
|
api_url: str = "https://api.upcloud.com/1.3"
|
||||||
|
interface: "API" | "CLI" = "API"
|
||||||
|
credentials: ProviderCredentialsReference
|
||||||
|
timeout_seconds: int = 30
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(api_url) > 0, "api_url cannot be empty"
|
||||||
|
timeout_seconds > 0 and timeout_seconds <= 300, "timeout must be 1-300 seconds"
|
||||||
|
|
||||||
|
schema AWSConfig:
|
||||||
|
"""AWS provider configuration"""
|
||||||
|
region: str = "us-east-1"
|
||||||
|
credentials: ProviderCredentialsReference
|
||||||
|
timeout_seconds: int = 30
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(region) > 0, "region cannot be empty"
|
||||||
|
timeout_seconds > 0 and timeout_seconds <= 300, "timeout must be 1-300 seconds"
|
||||||
|
|
||||||
|
schema HetznerConfig:
|
||||||
|
"""Hetzner provider configuration"""
|
||||||
|
api_url: str = "https://api.hetzner.cloud/v1"
|
||||||
|
credentials: ProviderCredentialsReference
|
||||||
|
timeout_seconds: int = 30
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(api_url) > 0, "api_url cannot be empty"
|
||||||
|
timeout_seconds > 0 and timeout_seconds <= 300, "timeout must be 1-300 seconds"
|
||||||
|
|
||||||
|
schema LocalConfig:
|
||||||
|
"""Local provider configuration"""
|
||||||
|
base_path: str = "/tmp/provisioning-local"
|
||||||
|
timeout_seconds: int = 10
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(base_path) > 0, "base_path cannot be empty"
|
||||||
|
timeout_seconds > 0 and timeout_seconds <= 300, "timeout must be 1-300 seconds"
|
||||||
|
|
||||||
|
schema RustyVaultBootstrap:
|
||||||
|
"""RustyVault bootstrap key configuration"""
|
||||||
|
encrypted_key_path: str
|
||||||
|
encrypted_key_format: "age" | "sops" = "age"
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(encrypted_key_path) > 0, "encrypted_key_path cannot be empty"
|
||||||
|
|
||||||
|
schema ProviderConfig:
|
||||||
|
"""Provider configuration with RustyVault references"""
|
||||||
|
upcloud?: UpCloudConfig
|
||||||
|
aws?: AWSConfig
|
||||||
|
hetzner?: HetznerConfig
|
||||||
|
local?: LocalConfig
|
||||||
|
rustyvault_bootstrap?: RustyVaultBootstrap
|
||||||
|
|
||||||
|
schema UserPreferences:
|
||||||
|
"""User preferences for provisioning operations"""
|
||||||
|
preferred_editor: "vim" | "nano" | "code" = "vim"
|
||||||
|
preferred_output_format: "text" | "json" | "yaml" = "text"
|
||||||
|
auto_confirm_operations: bool = False
|
||||||
|
log_level: "error" | "warn" | "info" | "debug" = "info"
|
||||||
|
default_timeout_seconds: int = 300
|
||||||
|
|
||||||
|
check:
|
||||||
|
default_timeout_seconds > 0 and default_timeout_seconds <= 3600, \
|
||||||
|
"default_timeout_seconds must be 1-3600"
|
||||||
|
|
||||||
|
schema WorkspaceConfig:
|
||||||
|
"""Workspace-specific configuration"""
|
||||||
|
workspace_name: str
|
||||||
|
workspace_path: str
|
||||||
|
active_infrastructure: str
|
||||||
|
active_providers: [str] # ["upcloud", "aws"]
|
||||||
|
provider_config: ProviderConfig
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(workspace_name) > 0, "workspace_name cannot be empty"
|
||||||
|
len(workspace_path) > 0, "workspace_path cannot be empty"
|
||||||
|
len(active_infrastructure) > 0, "active_infrastructure cannot be empty"
|
||||||
|
len(active_providers) > 0, "at least one active provider required"
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# FINAL EXPORT
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
_system_config: SystemConfig = {
|
||||||
|
version = "1.0.0"
|
||||||
|
install_path = "/opt/provisioning"
|
||||||
|
os_name = "linux"
|
||||||
|
os_version = "5.15.0"
|
||||||
|
config_base_path = "/etc/provisioning"
|
||||||
|
cache_base_path = "/var/cache/provisioning"
|
||||||
|
workspaces_dir = "/opt/workspaces"
|
||||||
|
system_architecture = "x86_64"
|
||||||
|
cpu_count = 8
|
||||||
|
memory_total_gb = 32
|
||||||
|
disk_total_gb = 500
|
||||||
|
setup_date = "2025-12-11T00:00:00Z"
|
||||||
|
setup_by_user = "provisioning"
|
||||||
|
setup_hostname = "provisioning-host"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Export for use in other modules
|
||||||
|
system_config_schema = _system_config
|
||||||
@ -32,6 +32,8 @@ schema TaskservVersion:
|
|||||||
dependencies?: [str]
|
dependencies?: [str]
|
||||||
# Profile-specific version overrides
|
# Profile-specific version overrides
|
||||||
profiles?: {str:Version}
|
profiles?: {str:Version}
|
||||||
|
# Detection configuration (how to detect if tool is installed)
|
||||||
|
detector?: {str:any}
|
||||||
|
|
||||||
check:
|
check:
|
||||||
len(name) > 0, "Taskserv name cannot be empty"
|
len(name) > 0, "Taskserv name cannot be empty"
|
||||||
|
|||||||
252
vm.k
Normal file
252
vm.k
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
# VM Configuration Schema (Phase 1)
|
||||||
|
#
|
||||||
|
# Core virtual machine configuration schema with validation.
|
||||||
|
# Follows KCL idiomatic patterns: schema-first, explicit types, check blocks.
|
||||||
|
import regex
|
||||||
|
|
||||||
|
schema VmConfig:
|
||||||
|
"""
|
||||||
|
Virtual Machine configuration for lifecycle management.
|
||||||
|
|
||||||
|
Defines complete VM specification including resources, networking,
|
||||||
|
storage, and lifecycle policies.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
# Temporary test VM
|
||||||
|
VmConfig {
|
||||||
|
name = "kubernetes-test"
|
||||||
|
base_image = "ubuntu-22.04"
|
||||||
|
cpu = 4
|
||||||
|
memory_mb = 8192
|
||||||
|
temporary = True
|
||||||
|
auto_cleanup = True
|
||||||
|
}
|
||||||
|
|
||||||
|
# Permanent development VM
|
||||||
|
VmConfig {
|
||||||
|
name = "dev-rust"
|
||||||
|
base_image = "ubuntu-22.04"
|
||||||
|
cpu = 8
|
||||||
|
memory_mb = 16384
|
||||||
|
disk_gb = 50
|
||||||
|
permanent = True
|
||||||
|
taskservs = ["rust", "git", "docker"]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
# VM Identity
|
||||||
|
name: str
|
||||||
|
description?: str
|
||||||
|
# Image Configuration (Pattern 2: Schema-first development)
|
||||||
|
# Base OS image
|
||||||
|
base_image: str = "ubuntu-22.04"
|
||||||
|
|
||||||
|
# Hardware Resources (Pattern 7: Default values)
|
||||||
|
# CPU cores (1-64)
|
||||||
|
cpu: int = 2
|
||||||
|
# Memory in MB
|
||||||
|
memory_mb: int = 4096
|
||||||
|
# Disk space in GB
|
||||||
|
disk_gb: int = 20
|
||||||
|
|
||||||
|
# Hypervisor Backend (Pattern 8: Union types for enums)
|
||||||
|
backend: "libvirt" | "qemu" | "docker-vm" = "libvirt"
|
||||||
|
|
||||||
|
# Lifecycle Configuration (Pattern 9: Optional fields with ?)
|
||||||
|
# Keep after restart
|
||||||
|
permanent: bool = False
|
||||||
|
# Auto-cleanup
|
||||||
|
temporary: bool = False
|
||||||
|
# Auto-delete after TTL
|
||||||
|
auto_cleanup: bool = False
|
||||||
|
# TTL before cleanup
|
||||||
|
auto_cleanup_hours?: int
|
||||||
|
# Taskservs to Install (Pattern 10: Composition)
|
||||||
|
# Single taskserv
|
||||||
|
taskserv?: str
|
||||||
|
# Multiple taskservs
|
||||||
|
taskservs: [str] = []
|
||||||
|
|
||||||
|
# Networking (Pattern 8: Union types)
|
||||||
|
network_mode: "bridge" | "nat" | "host" = "bridge"
|
||||||
|
# Custom networks
|
||||||
|
networks?: [VmNetwork]
|
||||||
|
# Port mappings (Pattern 10: Composition with VmPortMapping)
|
||||||
|
ports?: [VmPortMapping]
|
||||||
|
# Storage and Mounts (Pattern 10: Composition)
|
||||||
|
# Host directory mounts
|
||||||
|
mounts?: [VmMount]
|
||||||
|
# Additional volumes
|
||||||
|
volumes?: [VmVolume]
|
||||||
|
# Cloud-init Configuration
|
||||||
|
# ⚠️ SECURITY: Scripts are executed with root privileges
|
||||||
|
# Use vault:// or kms:// references for sensitive data in scripts
|
||||||
|
cloud_init?: VmCloudInit
|
||||||
|
# Advanced Options
|
||||||
|
# Enable nested virtualization
|
||||||
|
nested_virt?: bool = False
|
||||||
|
# Enable graphics
|
||||||
|
graphics_enable?: bool = False
|
||||||
|
# Enable serial console
|
||||||
|
serial_console?: bool = True
|
||||||
|
|
||||||
|
check:
|
||||||
|
# Validation (Pattern 4: Check blocks for validation)
|
||||||
|
|
||||||
|
# Name validation
|
||||||
|
len(name) > 0, "Name required"
|
||||||
|
len(name) <= 64, "Name must be <= 64 characters"
|
||||||
|
regex.match(name, r'^[a-z0-9][a-z0-9-]*[a-z0-9]$'), "Name must start/end with alphanumeric, contain only lowercase/numbers/hyphens"
|
||||||
|
# Resource validation
|
||||||
|
cpu > 0 and cpu <= 64, "CPU must be 1-64 cores"
|
||||||
|
memory_mb >= 512 and memory_mb <= 131072, "Memory must be 512MB-128GB"
|
||||||
|
disk_gb >= 5 and disk_gb <= 2048, "Disk must be 5GB-2TB"
|
||||||
|
# Lifecycle validation
|
||||||
|
not (permanent and temporary), "Cannot be both permanent and temporary"
|
||||||
|
not (auto_cleanup and permanent), "Auto-cleanup incompatible with permanent"
|
||||||
|
not auto_cleanup or temporary, "Auto-cleanup only for temporary VMs"
|
||||||
|
# Taskserv validation (Pattern 9: XOR logic - either single or multiple, not both)
|
||||||
|
not (taskserv != Undefined and len(taskservs) > 0), "Specify either 'taskserv' or 'taskservs', not both"
|
||||||
|
# If neither specified, both are allowed (rely on consumer defaults)
|
||||||
|
auto_cleanup_hours == Undefined or (auto_cleanup_hours > 0 and auto_cleanup_hours <= 720), "TTL must be 1-720 hours if specified"
|
||||||
|
# Image validation
|
||||||
|
len(base_image) > 0, "Base image required"
|
||||||
|
|
||||||
|
schema VmNetwork:
|
||||||
|
"""VM network configuration"""
|
||||||
|
name: str = "default"
|
||||||
|
type: "bridge" | "nat" | "host" = "nat"
|
||||||
|
# CIDR notation (e.g., "192.168.122.0/24")
|
||||||
|
subnet?: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Network name required"
|
||||||
|
subnet == Undefined or regex.match(subnet, r'^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d{1,2}$'), "Invalid CIDR notation"
|
||||||
|
|
||||||
|
schema VmPortMapping:
|
||||||
|
"""Port mapping configuration for VM network access"""
|
||||||
|
# Port on host machine
|
||||||
|
host_port: int
|
||||||
|
# Port inside VM
|
||||||
|
guest_port: int
|
||||||
|
# Network protocol
|
||||||
|
protocol: "tcp" | "udp" = "tcp"
|
||||||
|
# Optional IP address to bind to (default: all interfaces)
|
||||||
|
bind_addr?: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
host_port > 0 and host_port <= 65535, "Host port must be 1-65535"
|
||||||
|
guest_port > 0 and guest_port <= 65535, "Guest port must be 1-65535"
|
||||||
|
bind_addr == Undefined or len(bind_addr) > 0, "Bind address cannot be empty if specified"
|
||||||
|
|
||||||
|
schema VmMount:
|
||||||
|
"""Host directory mount in VM"""
|
||||||
|
host_path: str
|
||||||
|
guest_path: str
|
||||||
|
readonly: bool = False
|
||||||
|
# Mount mode (e.g., "rbind")
|
||||||
|
mode?: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(host_path) > 0, "Host path required"
|
||||||
|
len(guest_path) > 0, "Guest path required"
|
||||||
|
|
||||||
|
schema VmVolume:
|
||||||
|
"""Additional storage volume for VM"""
|
||||||
|
name: str
|
||||||
|
size_gb: int
|
||||||
|
mount_path?: str
|
||||||
|
format: "qcow2" | "raw" = "qcow2"
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Volume name required"
|
||||||
|
size_gb > 0, "Volume size must be positive"
|
||||||
|
|
||||||
|
schema VmCloudInit:
|
||||||
|
"""Cloud-init configuration for VM provisioning"""
|
||||||
|
enabled: bool = True
|
||||||
|
# Cloud-init user-data script
|
||||||
|
user_data?: str
|
||||||
|
# Cloud-init metadata
|
||||||
|
meta_data?: str
|
||||||
|
# Cloud-init vendor-data
|
||||||
|
vendor_data?: str
|
||||||
|
|
||||||
|
schema VmImage:
|
||||||
|
"""Virtual Machine disk image"""
|
||||||
|
name: str
|
||||||
|
format: "qcow2" | "raw" | "vmdk" = "qcow2"
|
||||||
|
path: str
|
||||||
|
size_gb: int
|
||||||
|
base_os: "ubuntu" | "debian" | "rocky" | "arch" = "ubuntu"
|
||||||
|
os_version: str = "22.04"
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Image name required"
|
||||||
|
len(path) > 0, "Image path required"
|
||||||
|
size_gb > 0, "Image size must be positive"
|
||||||
|
|
||||||
|
schema VmState:
|
||||||
|
"""VM runtime state tracking"""
|
||||||
|
vm_name: str
|
||||||
|
state: "stopped" | "starting" | "running" | "stopping" | "error" = "stopped"
|
||||||
|
permanent: bool
|
||||||
|
# ISO 8601 timestamp
|
||||||
|
created_at: str
|
||||||
|
started_at?: str
|
||||||
|
last_action?: str
|
||||||
|
auto_cleanup_at?: str
|
||||||
|
# Assigned IP
|
||||||
|
ip_address?: str
|
||||||
|
# Assigned MAC
|
||||||
|
mac_address?: str
|
||||||
|
# Which hypervisor running on
|
||||||
|
hypervisor?: str
|
||||||
|
# Backend-specific ID (libvirt domain ID)
|
||||||
|
backend_id?: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(vm_name) > 0, "VM name required"
|
||||||
|
len(created_at) > 0, "Creation timestamp required"
|
||||||
|
regex.match(created_at, r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})$'), "created_at must be ISO 8601 format"
|
||||||
|
started_at == Undefined or regex.match(started_at, r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})$'), "started_at must be ISO 8601 format if specified"
|
||||||
|
auto_cleanup_at == Undefined or regex.match(auto_cleanup_at, r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})$'), "auto_cleanup_at must be ISO 8601 format if specified"
|
||||||
|
|
||||||
|
schema VmRegistry:
|
||||||
|
"""Registry of all VMs on system"""
|
||||||
|
# All VMs
|
||||||
|
vms: [VmState]
|
||||||
|
# Number of permanent VMs
|
||||||
|
permanent_count: int
|
||||||
|
# Number of temporary VMs
|
||||||
|
temporary_count: int
|
||||||
|
# Last registry update (ISO 8601 format)
|
||||||
|
updated_at: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(vms) >= 0, "VM list cannot be negative length"
|
||||||
|
permanent_count >= 0, "Permanent VM count cannot be negative"
|
||||||
|
temporary_count >= 0, "Temporary VM count cannot be negative"
|
||||||
|
permanent_count + temporary_count <= len(vms), "Sum of counts should not exceed total VMs"
|
||||||
|
regex.match(updated_at, r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(Z|[+-]\d{2}:\d{2})$'), "updated_at must be ISO 8601 format"
|
||||||
|
|
||||||
|
schema VmCapacity:
|
||||||
|
"""Host capacity information for VM placement"""
|
||||||
|
host_name: str
|
||||||
|
total_cpu_cores: int
|
||||||
|
used_cpu_cores: int
|
||||||
|
total_memory_mb: int
|
||||||
|
used_memory_mb: int
|
||||||
|
total_disk_gb: int
|
||||||
|
used_disk_gb: int
|
||||||
|
# Maximum VMs on host
|
||||||
|
max_vms: int
|
||||||
|
running_vms: int
|
||||||
|
|
||||||
|
check:
|
||||||
|
total_cpu_cores > 0, "Total CPU cores must be positive"
|
||||||
|
total_memory_mb > 0, "Total memory must be positive"
|
||||||
|
total_disk_gb > 0, "Total disk must be positive"
|
||||||
|
used_cpu_cores >= 0 and used_cpu_cores <= total_cpu_cores, "Used CPU cannot exceed total"
|
||||||
|
used_memory_mb >= 0 and used_memory_mb <= total_memory_mb, "Used memory cannot exceed total"
|
||||||
|
used_disk_gb >= 0 and used_disk_gb <= total_disk_gb, "Used disk cannot exceed total"
|
||||||
|
|
||||||
248
vm_lifecycle.k
Normal file
248
vm_lifecycle.k
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
# VM Lifecycle and Persistence Schemas (Phase 2)
|
||||||
|
#
|
||||||
|
# Extends core VmConfig with persistence and lifecycle management.
|
||||||
|
# Follows KCL patterns: schema-first, explicit types, check blocks.
|
||||||
|
schema VmPersistence:
|
||||||
|
"""
|
||||||
|
VM persistence configuration for permanent/temporary management.
|
||||||
|
|
||||||
|
Controls VM behavior across reboots and cleanup policies.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
# Permanent VM - persists across reboots
|
||||||
|
VmPersistence {
|
||||||
|
mode = "permanent"
|
||||||
|
auto_start = true
|
||||||
|
restart_policy = "always"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Temporary VM - auto-cleanup after TTL
|
||||||
|
VmPersistence {
|
||||||
|
mode = "temporary"
|
||||||
|
ttl_hours = 24
|
||||||
|
auto_cleanup = true
|
||||||
|
force_cleanup = false
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
# Persistence mode (Pattern 8: Union types)
|
||||||
|
mode: "permanent" | "temporary" = "permanent"
|
||||||
|
|
||||||
|
# Permanent VM settings
|
||||||
|
# Start on host boot
|
||||||
|
auto_start: bool = False
|
||||||
|
restart_policy: "no" | "always" | "on-failure" = "always"
|
||||||
|
# Max restart attempts
|
||||||
|
max_retries: int = 5
|
||||||
|
|
||||||
|
# Temporary VM settings
|
||||||
|
# Time to live
|
||||||
|
ttl_hours: int = 24
|
||||||
|
# Auto-delete on TTL
|
||||||
|
auto_cleanup: bool = True
|
||||||
|
# Force cleanup without graceful shutdown
|
||||||
|
force_cleanup: bool = False
|
||||||
|
# Seconds to wait before force kill
|
||||||
|
cleanup_grace_period: int = 60
|
||||||
|
|
||||||
|
# State tracking
|
||||||
|
# Creation timestamp (Unix epoch)
|
||||||
|
created_at_unix: int
|
||||||
|
# Cleanup timestamp if scheduled
|
||||||
|
scheduled_cleanup?: int
|
||||||
|
# Last state change timestamp
|
||||||
|
last_state_change?: int
|
||||||
|
|
||||||
|
check:
|
||||||
|
# TTL validation
|
||||||
|
ttl_hours > 0 and ttl_hours <= 8760, "TTL must be 1-8760 hours (1 year max)"
|
||||||
|
# Restart policy validation
|
||||||
|
not (auto_start and mode == "temporary"), "Temporary VMs cannot have auto_start enabled"
|
||||||
|
# Cleanup validation
|
||||||
|
not (force_cleanup and not auto_cleanup), "force_cleanup requires auto_cleanup enabled"
|
||||||
|
# Grace period validation
|
||||||
|
cleanup_grace_period >= 0 and cleanup_grace_period <= 300, "Grace period must be 0-300 seconds"
|
||||||
|
|
||||||
|
schema VmLifecyclePolicy:
|
||||||
|
"""
|
||||||
|
VM lifecycle policy defining behavior across system events.
|
||||||
|
|
||||||
|
Controls how VMs behave on host reboot, shutdown, and resource contention.
|
||||||
|
"""
|
||||||
|
# On host reboot behavior
|
||||||
|
on_host_reboot: "start" | "keep-stopped" | "destroy" = "start"
|
||||||
|
|
||||||
|
# On host shutdown behavior
|
||||||
|
on_host_shutdown: "shutdown" | "save-state" | "destroy" = "shutdown"
|
||||||
|
|
||||||
|
# On resource contention
|
||||||
|
on_memory_pressure: "suspend" | "kill" | "none" = "none"
|
||||||
|
on_disk_full: "suspend" | "kill" | "none" = "none"
|
||||||
|
|
||||||
|
# Resource limits enforcement
|
||||||
|
enforce_memory_limit: bool = True
|
||||||
|
enforce_cpu_limit: bool = True
|
||||||
|
# Risky if enabled
|
||||||
|
enforce_disk_limit: bool = False
|
||||||
|
|
||||||
|
check:
|
||||||
|
on_host_shutdown != "save-state" or on_host_reboot != "destroy", "Cannot save-state on shutdown if VM is destroyed on reboot"
|
||||||
|
|
||||||
|
schema VmCleanupSchedule:
|
||||||
|
"""
|
||||||
|
Cleanup scheduling information for temporary VMs.
|
||||||
|
|
||||||
|
Tracks when VMs are scheduled for cleanup and status.
|
||||||
|
"""
|
||||||
|
vm_name: str
|
||||||
|
vm_id: str
|
||||||
|
mode: "temporary" = "temporary"
|
||||||
|
# ISO 8601 timestamp
|
||||||
|
created_at: str
|
||||||
|
# ISO 8601 timestamp
|
||||||
|
scheduled_cleanup_at: str
|
||||||
|
ttl_hours: int
|
||||||
|
|
||||||
|
# Cleanup status tracking
|
||||||
|
cleanup_status: "pending" | "in-progress" | "completed" | "failed" = "pending"
|
||||||
|
cleanup_attempts: int = 0
|
||||||
|
# ISO 8601 timestamp
|
||||||
|
last_cleanup_attempt?: str
|
||||||
|
cleanup_error?: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(vm_name) > 0, "VM name required"
|
||||||
|
len(vm_id) > 0, "VM ID required"
|
||||||
|
ttl_hours > 0, "TTL must be positive"
|
||||||
|
cleanup_attempts >= 0, "Cleanup attempts cannot be negative"
|
||||||
|
|
||||||
|
schema VmRecoveryState:
|
||||||
|
"""
|
||||||
|
VM state snapshot for recovery after host reboot.
|
||||||
|
|
||||||
|
Captures VM state before shutdown for restoration.
|
||||||
|
"""
|
||||||
|
vm_name: str
|
||||||
|
vm_id: str
|
||||||
|
state_before_shutdown: "running" | "stopped" | "paused"
|
||||||
|
# ISO 8601
|
||||||
|
creation_timestamp: str
|
||||||
|
# ISO 8601
|
||||||
|
last_checkpoint: str
|
||||||
|
|
||||||
|
# Memory state (for save-state)
|
||||||
|
# Path to memory dump file
|
||||||
|
memory_snapshot?: str
|
||||||
|
memory_size_mb?: int
|
||||||
|
# Configuration snapshot
|
||||||
|
# Full VmConfig at snapshot time (stored as JSON/dict)
|
||||||
|
config_snapshot: {str: any}
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(vm_name) > 0, "VM name required"
|
||||||
|
state_before_shutdown in ["running", "stopped", "paused"], "Invalid shutdown state"
|
||||||
|
|
||||||
|
schema VmAutoStartConfig:
|
||||||
|
"""
|
||||||
|
Configuration for automatic VM startup on host boot.
|
||||||
|
|
||||||
|
Manages order and dependencies for VM startup.
|
||||||
|
"""
|
||||||
|
vm_name: str
|
||||||
|
enabled: bool = True
|
||||||
|
# Lower numbers start first
|
||||||
|
start_order: int = 0
|
||||||
|
# Delay before starting
|
||||||
|
start_delay_seconds: int = 0
|
||||||
|
# Wait for SSH before continuing
|
||||||
|
wait_for_ssh: bool = True
|
||||||
|
# Max wait time
|
||||||
|
ssh_timeout_seconds: int = 300
|
||||||
|
on_start_failure: "stop" | "retry" | "ignore" = "retry"
|
||||||
|
max_start_retries: int = 3
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
# Other VMs to start first
|
||||||
|
depends_on: [str] = []
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(vm_name) > 0, "VM name required"
|
||||||
|
start_order >= 0, "Start order must be non-negative"
|
||||||
|
start_delay_seconds >= 0, "Delay must be non-negative"
|
||||||
|
ssh_timeout_seconds > 0, "SSH timeout must be positive"
|
||||||
|
max_start_retries > 0, "Max retries must be positive"
|
||||||
|
on_start_failure in ["stop", "retry", "ignore"], "Invalid start failure policy"
|
||||||
|
|
||||||
|
schema VmCleanupPolicy:
|
||||||
|
"""
|
||||||
|
Global cleanup policy for all temporary VMs on system.
|
||||||
|
|
||||||
|
Defines system-wide cleanup behavior and constraints.
|
||||||
|
"""
|
||||||
|
# Cleanup scheduling
|
||||||
|
cleanup_enabled: bool = True
|
||||||
|
# How often to check for cleanup
|
||||||
|
check_interval_minutes: int = 60
|
||||||
|
# HH:MM format
|
||||||
|
cleanup_window_start: str = "02:00"
|
||||||
|
# HH:MM format
|
||||||
|
cleanup_window_end: str = "06:00"
|
||||||
|
cleanup_in_window_only: bool = True
|
||||||
|
|
||||||
|
# Resource constraints
|
||||||
|
# Max VMs cleaning up simultaneously
|
||||||
|
max_concurrent_cleanups: int = 3
|
||||||
|
# Max VMs to check per batch
|
||||||
|
cleanup_batch_size: int = 10
|
||||||
|
|
||||||
|
# Safety features
|
||||||
|
# Require approval before cleanup
|
||||||
|
require_confirmation: bool = False
|
||||||
|
# Log cleanups without executing
|
||||||
|
dry_run_mode: bool = False
|
||||||
|
# Skip cleanup if system busy
|
||||||
|
skip_on_low_resources: bool = True
|
||||||
|
|
||||||
|
# Logging and monitoring
|
||||||
|
log_cleanup_operations: bool = True
|
||||||
|
alert_on_cleanup_failure: bool = True
|
||||||
|
# Keep cleanup logs for N days
|
||||||
|
retention_days: int = 7
|
||||||
|
|
||||||
|
check:
|
||||||
|
check_interval_minutes > 0 and check_interval_minutes <= 1440, "Check interval must be 1-1440 minutes (1 day max)"
|
||||||
|
max_concurrent_cleanups > 0, "Must allow at least 1 concurrent cleanup"
|
||||||
|
cleanup_batch_size > 0, "Batch size must be positive"
|
||||||
|
retention_days >= 0, "Retention days cannot be negative"
|
||||||
|
|
||||||
|
schema VmStateSnapshot:
|
||||||
|
"""
|
||||||
|
Snapshot of VM state for persistence and recovery.
|
||||||
|
|
||||||
|
Used for state persistence across operations.
|
||||||
|
"""
|
||||||
|
vm_name: str
|
||||||
|
# ISO 8601 timestamp
|
||||||
|
snapshot_time: str
|
||||||
|
vm_state: "stopped" | "starting" | "running" | "stopping" | "paused" | "error"
|
||||||
|
|
||||||
|
# Resource state at snapshot
|
||||||
|
cpu_usage_percent: float
|
||||||
|
memory_usage_mb: int
|
||||||
|
disk_usage_gb: int
|
||||||
|
|
||||||
|
# Network state
|
||||||
|
ip_addresses: [str]
|
||||||
|
mac_addresses: [str]
|
||||||
|
|
||||||
|
# Performance metrics
|
||||||
|
uptime_seconds: int
|
||||||
|
restart_count: int
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(vm_name) > 0, "VM name required"
|
||||||
|
cpu_usage_percent >= 0 and cpu_usage_percent <= 100, "CPU usage must be 0-100%"
|
||||||
|
memory_usage_mb >= 0, "Memory usage cannot be negative"
|
||||||
|
disk_usage_gb >= 0, "Disk usage cannot be negative"
|
||||||
|
uptime_seconds >= 0, "Uptime cannot be negative"
|
||||||
|
restart_count >= 0, "Restart count cannot be negative"
|
||||||
|
|
||||||
290
workspace_config.k
Normal file
290
workspace_config.k
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
"""
|
||||||
|
Workspace Configuration Schema
|
||||||
|
|
||||||
|
Defines the complete structure for workspace configuration in KCL format.
|
||||||
|
Replaces provisioning.yaml with type-safe, validated configuration.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import regex
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Workspace Metadata
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema Workspace:
|
||||||
|
"""Workspace identification and versioning"""
|
||||||
|
name: str
|
||||||
|
version: str
|
||||||
|
created: str
|
||||||
|
current_infra: str
|
||||||
|
current_environment: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(name) > 0, "Workspace name required"
|
||||||
|
regex.match(version, r"^\d+\.\d+\.\d+$"), \
|
||||||
|
"Version must be semantic versioning (e.g., 1.0.0)"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Path Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema Paths:
|
||||||
|
"""Path definitions for all workspace resources"""
|
||||||
|
base: str
|
||||||
|
infra: str
|
||||||
|
cache: str
|
||||||
|
runtime: str
|
||||||
|
providers: str
|
||||||
|
taskservs: str
|
||||||
|
clusters: str
|
||||||
|
orchestrator: str
|
||||||
|
control_center: str
|
||||||
|
kms: str
|
||||||
|
generate: str
|
||||||
|
run_clusters: str
|
||||||
|
run_taskservs: str
|
||||||
|
extensions: str
|
||||||
|
resources: str
|
||||||
|
templates: str
|
||||||
|
tools: str
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Provisioning System Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema ProvisioningConfig:
|
||||||
|
"""Provisioning system path and identification"""
|
||||||
|
path: str
|
||||||
|
|
||||||
|
|
||||||
|
schema CoreConfig:
|
||||||
|
"""Core provisioning settings"""
|
||||||
|
version: str
|
||||||
|
name: str
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Debug and Output Settings
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema DebugConfig:
|
||||||
|
"""Debug settings and verbosity control"""
|
||||||
|
enabled: bool
|
||||||
|
metadata: bool
|
||||||
|
check_mode: bool
|
||||||
|
validation: bool
|
||||||
|
remote: bool
|
||||||
|
log_level: str
|
||||||
|
no_terminal: bool
|
||||||
|
|
||||||
|
|
||||||
|
schema OutputConfig:
|
||||||
|
"""Output format and display settings"""
|
||||||
|
file_viewer: str
|
||||||
|
format: str
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# HTTP Client Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema HttpConfig:
|
||||||
|
"""HTTP client settings"""
|
||||||
|
use_curl: bool
|
||||||
|
timeout: int
|
||||||
|
|
||||||
|
check:
|
||||||
|
timeout > 0, "Timeout must be positive"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Provider Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema ProviderConfig:
|
||||||
|
"""Provider configuration and defaults"""
|
||||||
|
active: [str]
|
||||||
|
default: str
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Platform Services Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema PlatformConfig:
|
||||||
|
"""Platform services enablement"""
|
||||||
|
orchestrator_enabled: bool
|
||||||
|
control_center_enabled: bool
|
||||||
|
mcp_enabled: bool
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Secrets Management Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema SecretsConfig:
|
||||||
|
"""Secrets management configuration"""
|
||||||
|
provider: str
|
||||||
|
sops_enabled: bool
|
||||||
|
kms_enabled: bool
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# KMS Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema KmsConfig:
|
||||||
|
"""KMS (Key Management System) configuration"""
|
||||||
|
mode: str
|
||||||
|
config_file: str
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# SOPS Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema SopsConfig:
|
||||||
|
"""SOPS (Secrets Operations) configuration"""
|
||||||
|
use_sops: bool
|
||||||
|
config_path: str
|
||||||
|
key_search_paths: [str]
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# AI Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema AiConfig:
|
||||||
|
"""AI service configuration"""
|
||||||
|
enabled: bool
|
||||||
|
provider: str
|
||||||
|
config_path: str
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Task Services Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema TaskservsConfig:
|
||||||
|
"""Task services runtime configuration"""
|
||||||
|
run_path: str
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Clusters Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema ClustersConfig:
|
||||||
|
"""Clusters runtime configuration"""
|
||||||
|
run_path: str
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Generation Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema GenerationConfig:
|
||||||
|
"""Code/manifest generation settings"""
|
||||||
|
dir_path: str
|
||||||
|
defs_file: str
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Cache Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema CacheConfig:
|
||||||
|
"""Caching configuration"""
|
||||||
|
enabled: bool
|
||||||
|
path: str
|
||||||
|
infra_cache: str
|
||||||
|
grace_period: int
|
||||||
|
check_updates: bool
|
||||||
|
max_cache_size: str
|
||||||
|
|
||||||
|
check:
|
||||||
|
grace_period > 0, "Grace period must be positive"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Infrastructure Context
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema InfraConfig:
|
||||||
|
"""Infrastructure context settings"""
|
||||||
|
current: str
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Tools Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema ToolsConfig:
|
||||||
|
"""Tool detection and plugin settings"""
|
||||||
|
use_kcl: bool
|
||||||
|
use_kcl_plugin: bool
|
||||||
|
use_tera_plugin: bool
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# KCL Module Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema KclConfig:
|
||||||
|
"""KCL module and package configuration"""
|
||||||
|
core_module: str
|
||||||
|
core_version: str
|
||||||
|
core_package_name: str
|
||||||
|
use_module_loader: bool
|
||||||
|
module_loader_path: str
|
||||||
|
modules_dir: str
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# SSH Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema SshConfig:
|
||||||
|
"""SSH client configuration"""
|
||||||
|
user: str
|
||||||
|
options: [str]
|
||||||
|
timeout: int
|
||||||
|
debug: bool
|
||||||
|
|
||||||
|
check:
|
||||||
|
timeout > 0, "Timeout must be positive"
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================================
|
||||||
|
# Main Workspace Configuration
|
||||||
|
# ============================================================================
|
||||||
|
|
||||||
|
schema WorkspaceConfig:
|
||||||
|
"""Complete workspace configuration"""
|
||||||
|
workspace: Workspace
|
||||||
|
paths: Paths
|
||||||
|
provisioning: ProvisioningConfig
|
||||||
|
core: CoreConfig
|
||||||
|
debug: DebugConfig
|
||||||
|
output: OutputConfig
|
||||||
|
http: HttpConfig
|
||||||
|
providers: ProviderConfig
|
||||||
|
platform: PlatformConfig
|
||||||
|
secrets: SecretsConfig
|
||||||
|
kms: KmsConfig
|
||||||
|
sops: SopsConfig
|
||||||
|
ai: AiConfig
|
||||||
|
taskservs: TaskservsConfig
|
||||||
|
clusters: ClustersConfig
|
||||||
|
generation: GenerationConfig
|
||||||
|
cache: CacheConfig
|
||||||
|
infra: InfraConfig
|
||||||
|
tools: ToolsConfig
|
||||||
|
kcl: KclConfig
|
||||||
|
ssh: SshConfig
|
||||||
|
|
||||||
|
check:
|
||||||
|
len(workspace.name) > 0, "Workspace name required"
|
||||||
|
len(paths.base) > 0, "Base path required"
|
||||||
143
workspace_config_defaults.k
Normal file
143
workspace_config_defaults.k
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
"""
|
||||||
|
Workspace Configuration Defaults (SST - Single Source of Truth)
|
||||||
|
|
||||||
|
These are the default values for all workspace configurations.
|
||||||
|
Workspaces override these defaults in their provisioning.k file.
|
||||||
|
|
||||||
|
Pattern:
|
||||||
|
- SST Defaults: .kcl/workspace_config_defaults.k (this file)
|
||||||
|
- SST Schema: .kcl/workspace_config.k (schema definitions)
|
||||||
|
- Workspace Config: config/provisioning.k (workspace-specific overrides)
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Import the schema from the same package
|
||||||
|
import .workspace_config as cfg
|
||||||
|
|
||||||
|
# Default workspace configuration instance
|
||||||
|
# All workspaces inherit these defaults and can override specific values
|
||||||
|
default_workspace_config: cfg.WorkspaceConfig = {
|
||||||
|
workspace = {
|
||||||
|
name = "default-workspace"
|
||||||
|
version = "1.0.0"
|
||||||
|
created = ""
|
||||||
|
current_infra = ""
|
||||||
|
current_environment = ""
|
||||||
|
}
|
||||||
|
paths = {
|
||||||
|
base = "."
|
||||||
|
infra = "infra"
|
||||||
|
cache = ".cache"
|
||||||
|
runtime = ".runtime"
|
||||||
|
providers = ".providers"
|
||||||
|
taskservs = ".taskservs"
|
||||||
|
clusters = ".clusters"
|
||||||
|
orchestrator = ".orchestrator"
|
||||||
|
control_center = ".control-center"
|
||||||
|
kms = ".kms"
|
||||||
|
generate = "generate"
|
||||||
|
run_clusters = "clusters"
|
||||||
|
run_taskservs = "taskservs"
|
||||||
|
extensions = ".provisioning-extensions"
|
||||||
|
resources = "resources"
|
||||||
|
templates = "templates"
|
||||||
|
tools = "tools"
|
||||||
|
}
|
||||||
|
provisioning = {
|
||||||
|
path = "."
|
||||||
|
}
|
||||||
|
core = {
|
||||||
|
version = "1.0.0"
|
||||||
|
name = "provisioning"
|
||||||
|
}
|
||||||
|
debug = {
|
||||||
|
enabled = False
|
||||||
|
metadata = False
|
||||||
|
check_mode = False
|
||||||
|
validation = False
|
||||||
|
remote = False
|
||||||
|
log_level = "info"
|
||||||
|
no_terminal = False
|
||||||
|
}
|
||||||
|
output = {
|
||||||
|
file_viewer = "bat"
|
||||||
|
format = "yaml"
|
||||||
|
}
|
||||||
|
http = {
|
||||||
|
use_curl = False
|
||||||
|
timeout = 30
|
||||||
|
}
|
||||||
|
providers = {
|
||||||
|
active = ["upcloud"]
|
||||||
|
default = "upcloud"
|
||||||
|
}
|
||||||
|
platform = {
|
||||||
|
orchestrator_enabled = False
|
||||||
|
control_center_enabled = False
|
||||||
|
mcp_enabled = False
|
||||||
|
}
|
||||||
|
secrets = {
|
||||||
|
provider = "sops"
|
||||||
|
sops_enabled = True
|
||||||
|
kms_enabled = False
|
||||||
|
}
|
||||||
|
kms = {
|
||||||
|
mode = "local"
|
||||||
|
config_file = "config/kms.toml"
|
||||||
|
}
|
||||||
|
sops = {
|
||||||
|
use_sops = True
|
||||||
|
config_path = ".sops.yaml"
|
||||||
|
key_search_paths = [
|
||||||
|
".kms/keys/age.txt"
|
||||||
|
"~/.config/sops/age/keys.txt"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
ai = {
|
||||||
|
enabled = False
|
||||||
|
provider = "openai"
|
||||||
|
config_path = "config/ai.yaml"
|
||||||
|
}
|
||||||
|
taskservs = {
|
||||||
|
run_path = ".runtime/taskservs"
|
||||||
|
}
|
||||||
|
clusters = {
|
||||||
|
run_path = ".runtime/clusters"
|
||||||
|
}
|
||||||
|
generation = {
|
||||||
|
dir_path = "generated"
|
||||||
|
defs_file = "defs.toml"
|
||||||
|
}
|
||||||
|
cache = {
|
||||||
|
enabled = True
|
||||||
|
path = ".cache/versions"
|
||||||
|
infra_cache = "infra/default/cache/versions"
|
||||||
|
grace_period = 86400
|
||||||
|
check_updates = False
|
||||||
|
max_cache_size = "10MB"
|
||||||
|
}
|
||||||
|
infra = {
|
||||||
|
current = "default"
|
||||||
|
}
|
||||||
|
tools = {
|
||||||
|
use_kcl = True
|
||||||
|
use_kcl_plugin = True
|
||||||
|
use_tera_plugin = True
|
||||||
|
}
|
||||||
|
kcl = {
|
||||||
|
core_module = "kcl"
|
||||||
|
core_version = "0.0.1"
|
||||||
|
core_package_name = "provisioning_core"
|
||||||
|
use_module_loader = True
|
||||||
|
module_loader_path = "core/cli/module-loader"
|
||||||
|
modules_dir = ".kcl-modules"
|
||||||
|
}
|
||||||
|
ssh = {
|
||||||
|
user = ""
|
||||||
|
options = [
|
||||||
|
"StrictHostKeyChecking=accept-new"
|
||||||
|
"UserKnownHostsFile=/dev/null"
|
||||||
|
]
|
||||||
|
timeout = 30
|
||||||
|
debug = False
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user