Table of Contents
Configuration Validation
This directory contains documentation for Blueberry IDP's configuration validation and warning systems.
Overview
The validation system ensures that user-provided configuration overrides are safe, valid, and compatible with the platform's constraints while providing helpful feedback for invalid configurations.
Validation Architecture
Multi-Layer Validation
- Schema Validation - Against Helm values schema
- Field Classification - Categorize override types
- Resource Constraint Checking - GKE Autopilot compliance
- Security Policy Enforcement - Platform security rules
Validation Categories
Non-Overridable Fields
System-managed fields that cannot be overridden by users:
- backend.env.DATABASE_URL
- Always computed from MySQL settings
- backend.env.REDIS_HOST
- Always set to service name
- frontend.env.VITE_BACKEND_PUBLIC_URL
- Always computed
- *.image.repository
- Fixed by repository configuration
- *.resources
- GKE Autopilot manages automatically
Computed Fields
Fields that are dynamically calculated at runtime:
- backend.ingress.host
- Based on environment name and domain
- frontend.ingress.host
- Based on environment name and service
- backend.env.DATABASE_URL
- Computed from MySQL configuration
- frontend.env.VITE_BACKEND_PUBLIC_URL
- Computed from backend URL
Required Fields
Fields that are always overridden at runtime:
- environment.name
- Environment identifier
- environment.namespace
- Kubernetes namespace
- environment.ttl
- Environment time-to-live
- *.image.tag
- Container image tags
- *.gitCommitSha
- Git commit references
Resource Specifications
Resource-related fields blocked for GKE Autopilot:
- resources
, requests
, limits
- cpu
, memory
specifications
- storage
and volume
configurations
Validation Process
Input Processing
def validate_user_overrides(overrides: dict) -> dict:
"""Validate user overrides and return warnings."""
warnings = []
filtered_overrides = {}
# Classification sets
non_overridable_keys = set(RUNTIME_OVERRIDES.get("non_overridable", []))
computed_keys = set(RUNTIME_OVERRIDES.get("computed", {}).keys())
required_keys = set(RUNTIME_OVERRIDES.get("required", []))
Warning Generation
The system generates specific warnings for different violation types:
Non-Overridable Warning
{
"field": "backend.env.DATABASE_URL",
"type": "non_overridable",
"message": "Field 'backend.env.DATABASE_URL' is non-overridable (system managed) and will be ignored"
}
Computed Warning
{
"field": "frontend1.env.VITE_BACKEND_PUBLIC_URL",
"type": "computed",
"message": "Field 'frontend1.env.VITE_BACKEND_PUBLIC_URL' is computed at runtime and will be ignored"
}
Resource Specification Warning
{
"field": "backend.resources.requests.cpu",
"type": "resource_spec",
"message": "Field 'backend.resources.requests.cpu' contains resource specifications which are not allowed in GKE Autopilot and will be ignored"
}
Configuration Constraint Examples
Valid Overrides
# ✅ Valid: Custom environment variables
backend:
env:
CUSTOM_API_ENDPOINT: "https://api.example.com"
FEATURE_FLAG_ENABLED: "true"
# ✅ Valid: Service configuration
backend:
replicas: 3
port: 8080
# ✅ Valid: Application settings
mysql:
auth:
database: "my_custom_db"
Invalid Overrides
# ❌ Invalid: Non-overridable field
backend:
env:
DATABASE_URL: "mysql://custom:pass@host:3306/db" # System managed
# ❌ Invalid: Computed field
frontend1:
env:
VITE_BACKEND_PUBLIC_URL: "https://custom.domain.com" # Computed at runtime
# ❌ Invalid: Resource specification
backend:
resources:
requests:
cpu: "500m" # GKE Autopilot manages resources
memory: "1Gi"
# ❌ Invalid: Required field
environment:
name: "custom-name" # Always overridden at runtime
Environment Variable Validation
Allowed Environment Variables
Environment variables under backend.env
and frontend.env
are generally allowed:
backend:
env:
# ✅ Custom application settings
LOG_LEVEL: "debug"
API_TIMEOUT: "30s"
FEATURE_TOGGLES: "feature1,feature2"
# ✅ Integration endpoints
EXTERNAL_SERVICE_URL: "https://api.partner.com"
WEBHOOK_SECRET: "webhook-secret-key"
Blocked Environment Variables
System-managed environment variables are blocked:
backend:
env:
# ❌ Database connection (computed)
DATABASE_URL: "mysql://..."
# ❌ Redis connection (system managed)
REDIS_HOST: "custom-redis"
REDIS_PORT: "6380"
Best Practices
User Configuration
- Use environment variables for custom application settings
- Avoid overriding system-managed fields
- Test configuration changes in development environments
- Review validation warnings carefully
Platform Development
- Document all non-overridable fields
- Provide clear warning messages
- Implement comprehensive validation rules
- Monitor validation patterns for improvements
Error Handling
- Always validate user input
- Provide actionable error messages
- Log validation events for monitoring
- Implement graceful degradation
Implementation Examples
Validation Function
def validate_user_overrides(overrides: dict) -> dict:
"""Validate user overrides and return warnings."""
warnings = []
filtered_overrides = {}
for key, value in overrides.items():
if key in non_overridable_keys:
warnings.append({
"field": key,
"type": "non_overridable",
"message": f"Field '{key}' is non-overridable (system managed) and will be ignored"
})
elif contains_resource_spec(key, value):
warnings.append({
"field": key,
"type": "resource_spec",
"message": f"Field '{key}' contains resource specifications which are not allowed in GKE Autopilot and will be ignored"
})
else:
filtered_overrides[key] = value
return {"warnings": warnings, "filtered_overrides": filtered_overrides}
Resource Detection
def contains_resource_spec(key: str, value: Any) -> bool:
"""Check if a key or its nested values contain resource specifications."""
resource_related_patterns = ["resources", "requests", "limits", "cpu", "memory"]
# Check if the key itself indicates resources
for pattern in resource_related_patterns:
if pattern in key.lower():
return True
# Check nested dictionaries
if isinstance(value, dict):
for k, v in value.items():
if contains_resource_spec(k, v):
return True
return False
Troubleshooting
Common Validation Errors
- "Field is non-overridable": Field is system-managed, use different approach
- "Contains resource specifications": Remove CPU/memory settings for GKE Autopilot
- "Field is computed at runtime": Field is automatically calculated, remove override
Debugging Validation
- Review validation warnings in API responses
- Check field names against schema documentation
- Test overrides in development environment
- Use validation endpoint to test configurations
Related Files
blueberry/models/helm_values.py
- Validation implementationcharts/environment/values.yaml
- Environment Helm schemablueberry/api/config_sets.py
- API validation endpointsblueberry/services/environment_creator.py
- Runtime validation