631 lines
11 KiB
Markdown
631 lines
11 KiB
Markdown
|
|
# Configuration Validation Guide
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
The new configuration system includes comprehensive schema validation to catch errors early and ensure configuration correctness.
|
||
|
|
|
||
|
|
## Schema Validation Features
|
||
|
|
|
||
|
|
### 1. Required Fields Validation
|
||
|
|
|
||
|
|
Ensures all required fields are present:
|
||
|
|
|
||
|
|
```toml
|
||
|
|
# Schema definition
|
||
|
|
[required]
|
||
|
|
fields = ["name", "version", "enabled"]
|
||
|
|
|
||
|
|
# Valid config
|
||
|
|
name = "my-service"
|
||
|
|
version = "1.0.0"
|
||
|
|
enabled = true
|
||
|
|
|
||
|
|
# Invalid - missing 'enabled'
|
||
|
|
name = "my-service"
|
||
|
|
version = "1.0.0"
|
||
|
|
# Error: Required field missing: enabled
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Type Validation
|
||
|
|
|
||
|
|
Validates field types:
|
||
|
|
|
||
|
|
```toml
|
||
|
|
# Schema
|
||
|
|
[fields.port]
|
||
|
|
type = "int"
|
||
|
|
|
||
|
|
[fields.name]
|
||
|
|
type = "string"
|
||
|
|
|
||
|
|
[fields.enabled]
|
||
|
|
type = "bool"
|
||
|
|
|
||
|
|
# Valid
|
||
|
|
port = 8080
|
||
|
|
name = "orchestrator"
|
||
|
|
enabled = true
|
||
|
|
|
||
|
|
# Invalid - wrong type
|
||
|
|
port = "8080" # Error: Expected int, got string
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. Enum Validation
|
||
|
|
|
||
|
|
Restricts values to predefined set:
|
||
|
|
|
||
|
|
```toml
|
||
|
|
# Schema
|
||
|
|
[fields.environment]
|
||
|
|
type = "string"
|
||
|
|
enum = ["dev", "staging", "prod"]
|
||
|
|
|
||
|
|
# Valid
|
||
|
|
environment = "prod"
|
||
|
|
|
||
|
|
# Invalid
|
||
|
|
environment = "production" # Error: Must be one of: dev, staging, prod
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4. Range Validation
|
||
|
|
|
||
|
|
Validates numeric ranges:
|
||
|
|
|
||
|
|
```toml
|
||
|
|
# Schema
|
||
|
|
[fields.port]
|
||
|
|
type = "int"
|
||
|
|
min = 1024
|
||
|
|
max = 65535
|
||
|
|
|
||
|
|
# Valid
|
||
|
|
port = 8080
|
||
|
|
|
||
|
|
# Invalid - below minimum
|
||
|
|
port = 80 # Error: Must be >= 1024
|
||
|
|
|
||
|
|
# Invalid - above maximum
|
||
|
|
port = 70000 # Error: Must be <= 65535
|
||
|
|
```
|
||
|
|
|
||
|
|
### 5. Pattern Validation
|
||
|
|
|
||
|
|
Validates string patterns using regex:
|
||
|
|
|
||
|
|
```toml
|
||
|
|
# Schema
|
||
|
|
[fields.email]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
|
||
|
|
|
||
|
|
# Valid
|
||
|
|
email = "admin@example.com"
|
||
|
|
|
||
|
|
# Invalid
|
||
|
|
email = "not-an-email" # Error: Does not match pattern
|
||
|
|
```
|
||
|
|
|
||
|
|
### 6. Deprecated Fields
|
||
|
|
|
||
|
|
Warns about deprecated configuration:
|
||
|
|
|
||
|
|
```toml
|
||
|
|
# Schema
|
||
|
|
[deprecated]
|
||
|
|
fields = ["old_field"]
|
||
|
|
|
||
|
|
[deprecated_replacements]
|
||
|
|
old_field = "new_field"
|
||
|
|
|
||
|
|
# Config using deprecated field
|
||
|
|
old_field = "value" # Warning: old_field is deprecated. Use new_field instead.
|
||
|
|
```
|
||
|
|
|
||
|
|
## Using Schema Validator
|
||
|
|
|
||
|
|
### Command Line
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Validate workspace config
|
||
|
|
provisioning workspace config validate
|
||
|
|
|
||
|
|
# Validate provider config
|
||
|
|
provisioning provider validate aws
|
||
|
|
|
||
|
|
# Validate platform service config
|
||
|
|
provisioning platform validate orchestrator
|
||
|
|
|
||
|
|
# Validate with detailed output
|
||
|
|
provisioning workspace config validate --verbose
|
||
|
|
```
|
||
|
|
|
||
|
|
### Programmatic Usage
|
||
|
|
|
||
|
|
```nushell
|
||
|
|
use provisioning/core/nulib/lib_provisioning/config/schema_validator.nu *
|
||
|
|
|
||
|
|
# Load config
|
||
|
|
let config = (open ~/workspaces/my-project/config/provisioning.yaml | from yaml)
|
||
|
|
|
||
|
|
# Validate against schema
|
||
|
|
let result = (validate-workspace-config $config)
|
||
|
|
|
||
|
|
# Check results
|
||
|
|
if $result.valid {
|
||
|
|
print "✅ Configuration is valid"
|
||
|
|
} else {
|
||
|
|
print "❌ Configuration has errors:"
|
||
|
|
for error in $result.errors {
|
||
|
|
print $" • ($error.message)"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Display warnings
|
||
|
|
if ($result.warnings | length) > 0 {
|
||
|
|
print "⚠️ Warnings:"
|
||
|
|
for warning in $result.warnings {
|
||
|
|
print $" • ($warning.message)"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pretty Print Results
|
||
|
|
|
||
|
|
```nushell
|
||
|
|
# Validate and print formatted results
|
||
|
|
let result = (validate-workspace-config $config)
|
||
|
|
print-validation-results $result
|
||
|
|
```
|
||
|
|
|
||
|
|
## Schema Examples
|
||
|
|
|
||
|
|
### Workspace Schema
|
||
|
|
|
||
|
|
File: `/Users/Akasha/project-provisioning/provisioning/config/workspace.schema.toml`
|
||
|
|
|
||
|
|
```toml
|
||
|
|
[required]
|
||
|
|
fields = ["workspace", "paths"]
|
||
|
|
|
||
|
|
[fields.workspace]
|
||
|
|
type = "record"
|
||
|
|
|
||
|
|
[fields.workspace.name]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^[a-z][a-z0-9-]*$"
|
||
|
|
|
||
|
|
[fields.workspace.version]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^\\d+\\.\\d+\\.\\d+$"
|
||
|
|
|
||
|
|
[fields.paths]
|
||
|
|
type = "record"
|
||
|
|
|
||
|
|
[fields.paths.base]
|
||
|
|
type = "string"
|
||
|
|
|
||
|
|
[fields.paths.infra]
|
||
|
|
type = "string"
|
||
|
|
|
||
|
|
[fields.debug]
|
||
|
|
type = "record"
|
||
|
|
|
||
|
|
[fields.debug.enabled]
|
||
|
|
type = "bool"
|
||
|
|
|
||
|
|
[fields.debug.log_level]
|
||
|
|
type = "string"
|
||
|
|
enum = ["debug", "info", "warn", "error"]
|
||
|
|
```
|
||
|
|
|
||
|
|
### Provider Schema (AWS)
|
||
|
|
|
||
|
|
File: `/Users/Akasha/project-provisioning/provisioning/extensions/providers/aws/config.schema.toml`
|
||
|
|
|
||
|
|
```toml
|
||
|
|
[required]
|
||
|
|
fields = ["provider", "credentials"]
|
||
|
|
|
||
|
|
[fields.provider]
|
||
|
|
type = "record"
|
||
|
|
|
||
|
|
[fields.provider.name]
|
||
|
|
type = "string"
|
||
|
|
enum = ["aws"]
|
||
|
|
|
||
|
|
[fields.provider.region]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^[a-z]{2}-[a-z]+-\\d+$"
|
||
|
|
|
||
|
|
[fields.provider.enabled]
|
||
|
|
type = "bool"
|
||
|
|
|
||
|
|
[fields.credentials]
|
||
|
|
type = "record"
|
||
|
|
|
||
|
|
[fields.credentials.type]
|
||
|
|
type = "string"
|
||
|
|
enum = ["environment", "file", "iam_role"]
|
||
|
|
|
||
|
|
[fields.compute]
|
||
|
|
type = "record"
|
||
|
|
|
||
|
|
[fields.compute.default_instance_type]
|
||
|
|
type = "string"
|
||
|
|
|
||
|
|
[fields.compute.default_ami]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^ami-[a-f0-9]{8,17}$"
|
||
|
|
|
||
|
|
[fields.network]
|
||
|
|
type = "record"
|
||
|
|
|
||
|
|
[fields.network.vpc_id]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^vpc-[a-f0-9]{8,17}$"
|
||
|
|
|
||
|
|
[fields.network.subnet_id]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^subnet-[a-f0-9]{8,17}$"
|
||
|
|
|
||
|
|
[deprecated]
|
||
|
|
fields = ["old_region_field"]
|
||
|
|
|
||
|
|
[deprecated_replacements]
|
||
|
|
old_region_field = "provider.region"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Platform Service Schema (Orchestrator)
|
||
|
|
|
||
|
|
File: `/Users/Akasha/project-provisioning/provisioning/platform/orchestrator/config.schema.toml`
|
||
|
|
|
||
|
|
```toml
|
||
|
|
[required]
|
||
|
|
fields = ["service", "server"]
|
||
|
|
|
||
|
|
[fields.service]
|
||
|
|
type = "record"
|
||
|
|
|
||
|
|
[fields.service.name]
|
||
|
|
type = "string"
|
||
|
|
enum = ["orchestrator"]
|
||
|
|
|
||
|
|
[fields.service.enabled]
|
||
|
|
type = "bool"
|
||
|
|
|
||
|
|
[fields.server]
|
||
|
|
type = "record"
|
||
|
|
|
||
|
|
[fields.server.host]
|
||
|
|
type = "string"
|
||
|
|
|
||
|
|
[fields.server.port]
|
||
|
|
type = "int"
|
||
|
|
min = 1024
|
||
|
|
max = 65535
|
||
|
|
|
||
|
|
[fields.workers]
|
||
|
|
type = "int"
|
||
|
|
min = 1
|
||
|
|
max = 32
|
||
|
|
|
||
|
|
[fields.queue]
|
||
|
|
type = "record"
|
||
|
|
|
||
|
|
[fields.queue.max_size]
|
||
|
|
type = "int"
|
||
|
|
min = 100
|
||
|
|
max = 10000
|
||
|
|
|
||
|
|
[fields.queue.storage_path]
|
||
|
|
type = "string"
|
||
|
|
```
|
||
|
|
|
||
|
|
### KMS Service Schema
|
||
|
|
|
||
|
|
File: `/Users/Akasha/project-provisioning/provisioning/core/services/kms/config.schema.toml`
|
||
|
|
|
||
|
|
```toml
|
||
|
|
[required]
|
||
|
|
fields = ["kms", "encryption"]
|
||
|
|
|
||
|
|
[fields.kms]
|
||
|
|
type = "record"
|
||
|
|
|
||
|
|
[fields.kms.enabled]
|
||
|
|
type = "bool"
|
||
|
|
|
||
|
|
[fields.kms.provider]
|
||
|
|
type = "string"
|
||
|
|
enum = ["aws_kms", "gcp_kms", "azure_kv", "vault", "local"]
|
||
|
|
|
||
|
|
[fields.encryption]
|
||
|
|
type = "record"
|
||
|
|
|
||
|
|
[fields.encryption.algorithm]
|
||
|
|
type = "string"
|
||
|
|
enum = ["AES-256-GCM", "ChaCha20-Poly1305"]
|
||
|
|
|
||
|
|
[fields.encryption.key_rotation_days]
|
||
|
|
type = "int"
|
||
|
|
min = 30
|
||
|
|
max = 365
|
||
|
|
|
||
|
|
[fields.vault]
|
||
|
|
type = "record"
|
||
|
|
|
||
|
|
[fields.vault.address]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^https?://.*$"
|
||
|
|
|
||
|
|
[fields.vault.token_path]
|
||
|
|
type = "string"
|
||
|
|
|
||
|
|
[deprecated]
|
||
|
|
fields = ["old_kms_type"]
|
||
|
|
|
||
|
|
[deprecated_replacements]
|
||
|
|
old_kms_type = "kms.provider"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Validation Workflow
|
||
|
|
|
||
|
|
### 1. Development
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Create new config
|
||
|
|
vim ~/workspaces/dev/config/provisioning.yaml
|
||
|
|
|
||
|
|
# Validate immediately
|
||
|
|
provisioning workspace config validate
|
||
|
|
|
||
|
|
# Fix errors and revalidate
|
||
|
|
vim ~/workspaces/dev/config/provisioning.yaml
|
||
|
|
provisioning workspace config validate
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. CI/CD Pipeline
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
# GitLab CI
|
||
|
|
validate-config:
|
||
|
|
stage: validate
|
||
|
|
script:
|
||
|
|
- provisioning workspace config validate
|
||
|
|
- provisioning provider validate aws
|
||
|
|
- provisioning provider validate upcloud
|
||
|
|
- provisioning platform validate orchestrator
|
||
|
|
only:
|
||
|
|
changes:
|
||
|
|
- "*/config/**/*"
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. Pre-Deployment
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Validate all configurations before deployment
|
||
|
|
provisioning workspace config validate --verbose
|
||
|
|
provisioning provider validate --all
|
||
|
|
provisioning platform validate --all
|
||
|
|
|
||
|
|
# If valid, proceed with deployment
|
||
|
|
if [[ $? -eq 0 ]]; then
|
||
|
|
provisioning deploy --workspace production
|
||
|
|
fi
|
||
|
|
```
|
||
|
|
|
||
|
|
## Error Messages
|
||
|
|
|
||
|
|
### Clear Error Format
|
||
|
|
|
||
|
|
```
|
||
|
|
❌ Validation failed
|
||
|
|
|
||
|
|
Errors:
|
||
|
|
• Required field missing: workspace.name
|
||
|
|
• Field port type mismatch: expected int, got string
|
||
|
|
• Field environment must be one of: dev, staging, prod
|
||
|
|
• Field port must be >= 1024
|
||
|
|
• Field email does not match pattern: ^[a-zA-Z0-9._%+-]+@.*$
|
||
|
|
|
||
|
|
⚠️ Warnings:
|
||
|
|
• Field old_field is deprecated. Use new_field instead.
|
||
|
|
```
|
||
|
|
|
||
|
|
### Error Details
|
||
|
|
|
||
|
|
Each error includes:
|
||
|
|
- **field**: Which field has the error
|
||
|
|
- **type**: Error type (missing_required, type_mismatch, invalid_enum, etc.)
|
||
|
|
- **message**: Human-readable description
|
||
|
|
- **Additional context**: Expected values, patterns, ranges
|
||
|
|
|
||
|
|
## Common Validation Patterns
|
||
|
|
|
||
|
|
### Pattern 1: Hostname Validation
|
||
|
|
|
||
|
|
```toml
|
||
|
|
[fields.hostname]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pattern 2: Email Validation
|
||
|
|
|
||
|
|
```toml
|
||
|
|
[fields.email]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pattern 3: Semantic Version
|
||
|
|
|
||
|
|
```toml
|
||
|
|
[fields.version]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9]+)?$"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pattern 4: URL Validation
|
||
|
|
|
||
|
|
```toml
|
||
|
|
[fields.url]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^https?://[a-zA-Z0-9.-]+(:[0-9]+)?(/.*)?$"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pattern 5: IPv4 Address
|
||
|
|
|
||
|
|
```toml
|
||
|
|
[fields.ip_address]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pattern 6: AWS Resource ID
|
||
|
|
|
||
|
|
```toml
|
||
|
|
[fields.instance_id]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^i-[a-f0-9]{8,17}$"
|
||
|
|
|
||
|
|
[fields.ami_id]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^ami-[a-f0-9]{8,17}$"
|
||
|
|
|
||
|
|
[fields.vpc_id]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^vpc-[a-f0-9]{8,17}$"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Testing Validation
|
||
|
|
|
||
|
|
### Unit Tests
|
||
|
|
|
||
|
|
```nushell
|
||
|
|
# Run validation test suite
|
||
|
|
nu provisioning/tests/config_validation_tests.nu
|
||
|
|
```
|
||
|
|
|
||
|
|
### Integration Tests
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Test with real configs
|
||
|
|
provisioning test validate --workspace dev
|
||
|
|
provisioning test validate --workspace staging
|
||
|
|
provisioning test validate --workspace prod
|
||
|
|
```
|
||
|
|
|
||
|
|
### Custom Validation
|
||
|
|
|
||
|
|
```nushell
|
||
|
|
# Create custom validation function
|
||
|
|
def validate-custom-config [config: record] {
|
||
|
|
let result = (validate-workspace-config $config)
|
||
|
|
|
||
|
|
# Add custom business logic validation
|
||
|
|
if ($config.workspace.name | str starts-with "prod") {
|
||
|
|
if not $config.debug.enabled == false {
|
||
|
|
$result.errors = ($result.errors | append {
|
||
|
|
field: "debug.enabled"
|
||
|
|
type: "custom"
|
||
|
|
message: "Debug must be disabled in production"
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$result
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Best Practices
|
||
|
|
|
||
|
|
### 1. Validate Early
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Validate during development
|
||
|
|
provisioning workspace config validate
|
||
|
|
|
||
|
|
# Don't wait for deployment
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Use Strict Schemas
|
||
|
|
|
||
|
|
```toml
|
||
|
|
# Be explicit about types and constraints
|
||
|
|
[fields.port]
|
||
|
|
type = "int"
|
||
|
|
min = 1024
|
||
|
|
max = 65535
|
||
|
|
|
||
|
|
# Don't leave fields unvalidated
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. Document Patterns
|
||
|
|
|
||
|
|
```toml
|
||
|
|
# Include examples in schema
|
||
|
|
[fields.email]
|
||
|
|
type = "string"
|
||
|
|
pattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
|
||
|
|
# Example: user@example.com
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4. Handle Deprecation
|
||
|
|
|
||
|
|
```toml
|
||
|
|
# Always provide replacement guidance
|
||
|
|
[deprecated_replacements]
|
||
|
|
old_field = "new_field" # Clear migration path
|
||
|
|
```
|
||
|
|
|
||
|
|
### 5. Test Schemas
|
||
|
|
|
||
|
|
```nushell
|
||
|
|
# Include test cases in comments
|
||
|
|
# Valid: "admin@example.com"
|
||
|
|
# Invalid: "not-an-email"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### Schema File Not Found
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Error: Schema file not found: /path/to/schema.toml
|
||
|
|
|
||
|
|
# Solution: Ensure schema exists
|
||
|
|
ls -la /Users/Akasha/project-provisioning/provisioning/config/*.schema.toml
|
||
|
|
```
|
||
|
|
|
||
|
|
### Pattern Not Matching
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Error: Field hostname does not match pattern
|
||
|
|
|
||
|
|
# Debug: Test pattern separately
|
||
|
|
echo "my-hostname" | grep -E "^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Type Mismatch
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Error: Expected int, got string
|
||
|
|
|
||
|
|
# Check config
|
||
|
|
cat ~/workspaces/dev/config/provisioning.yaml | yq '.server.port'
|
||
|
|
# Output: "8080" (string)
|
||
|
|
|
||
|
|
# Fix: Remove quotes
|
||
|
|
vim ~/workspaces/dev/config/provisioning.yaml
|
||
|
|
# Change: port: "8080"
|
||
|
|
# To: port: 8080
|
||
|
|
```
|
||
|
|
|
||
|
|
## Additional Resources
|
||
|
|
|
||
|
|
- [Migration Guide](./MIGRATION_GUIDE.md)
|
||
|
|
- [Workspace Guide](./WORKSPACE_GUIDE.md)
|
||
|
|
- [Schema Files](../config/*.schema.toml)
|
||
|
|
- [Validation Tests](../tests/config_validation_tests.nu)
|