485 lines
13 KiB
Plaintext
485 lines
13 KiB
Plaintext
|
|
# Info: KCL CoreDNS configuration schemas for provisioning system
|
||
|
|
# Author: CoreDNS Integration Agent
|
||
|
|
# Release: 1.0.0
|
||
|
|
# Date: 2025-10-06
|
||
|
|
# Purpose: Define CoreDNS service configuration, zones, and DNS management
|
||
|
|
|
||
|
|
import regex
|
||
|
|
|
||
|
|
schema CoreDNSConfig:
|
||
|
|
"""
|
||
|
|
CoreDNS service configuration
|
||
|
|
|
||
|
|
Defines how CoreDNS is deployed and managed within the provisioning system.
|
||
|
|
Supports local binary, Docker, remote, and hybrid deployment modes.
|
||
|
|
|
||
|
|
Examples:
|
||
|
|
# Local mode with auto-start
|
||
|
|
CoreDNSConfig {
|
||
|
|
mode = "local"
|
||
|
|
local = LocalCoreDNS {
|
||
|
|
enabled = True
|
||
|
|
auto_start = True
|
||
|
|
zones = ["provisioning.local", "workspace.local"]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Remote mode
|
||
|
|
CoreDNSConfig {
|
||
|
|
mode = "remote"
|
||
|
|
remote = RemoteCoreDNS {
|
||
|
|
enabled = True
|
||
|
|
endpoints = ["https://dns1.example.com", "https://dns2.example.com"]
|
||
|
|
zones = ["production.local"]
|
||
|
|
}
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
# Deployment mode: local, remote, hybrid, or disabled
|
||
|
|
mode: "local" | "remote" | "hybrid" | "disabled" = "local"
|
||
|
|
|
||
|
|
# Local CoreDNS configuration
|
||
|
|
local?: LocalCoreDNS
|
||
|
|
|
||
|
|
# Remote CoreDNS configuration
|
||
|
|
remote?: RemoteCoreDNS
|
||
|
|
|
||
|
|
# Dynamic DNS update configuration
|
||
|
|
dynamic_updates: DynamicDNS = DynamicDNS {}
|
||
|
|
|
||
|
|
# Upstream DNS servers for forwarding
|
||
|
|
upstream: [str] = ["8.8.8.8", "1.1.1.1"]
|
||
|
|
|
||
|
|
# Global TTL for DNS records (seconds)
|
||
|
|
default_ttl: int = 300
|
||
|
|
|
||
|
|
# Enable DNS query logging
|
||
|
|
enable_logging: bool = True
|
||
|
|
|
||
|
|
# Enable metrics endpoint
|
||
|
|
enable_metrics: bool = True
|
||
|
|
|
||
|
|
# Metrics port
|
||
|
|
metrics_port: int = 9153
|
||
|
|
|
||
|
|
check:
|
||
|
|
len(upstream) > 0, "At least one upstream DNS server required"
|
||
|
|
default_ttl > 0 and default_ttl <= 86400, "TTL must be 1-86400 seconds"
|
||
|
|
metrics_port >= 1024 and metrics_port <= 65535, "Metrics port must be 1024-65535"
|
||
|
|
mode != "local" or local != Undefined, "Local config required when mode is 'local'"
|
||
|
|
mode != "remote" or remote != Undefined, "Remote config required when mode is 'remote'"
|
||
|
|
mode != "hybrid" or (local != Undefined and remote != Undefined), \
|
||
|
|
"Both local and remote config required when mode is 'hybrid'"
|
||
|
|
|
||
|
|
schema LocalCoreDNS:
|
||
|
|
"""
|
||
|
|
Local CoreDNS binary configuration
|
||
|
|
|
||
|
|
Manages CoreDNS running as a local binary or Docker container.
|
||
|
|
"""
|
||
|
|
# Enable local CoreDNS
|
||
|
|
enabled: bool = True
|
||
|
|
|
||
|
|
# Deployment type: binary or docker
|
||
|
|
deployment_type: "binary" | "docker" = "binary"
|
||
|
|
|
||
|
|
# Path to CoreDNS binary
|
||
|
|
binary_path: str = "~/.provisioning/bin/coredns"
|
||
|
|
|
||
|
|
# Path to Corefile
|
||
|
|
config_path: str = "~/.provisioning/coredns/Corefile"
|
||
|
|
|
||
|
|
# Path to zone files directory
|
||
|
|
zones_path: str = "~/.provisioning/coredns/zones"
|
||
|
|
|
||
|
|
# DNS listening port
|
||
|
|
port: int = 5353
|
||
|
|
|
||
|
|
# Auto-start CoreDNS on system startup
|
||
|
|
auto_start: bool = True
|
||
|
|
|
||
|
|
# Auto-restart on failure
|
||
|
|
auto_restart: bool = True
|
||
|
|
|
||
|
|
# Managed DNS zones
|
||
|
|
zones: [str] = ["provisioning.local", "workspace.local"]
|
||
|
|
|
||
|
|
# PID file path (for binary mode)
|
||
|
|
pid_file?: str = "~/.provisioning/coredns/coredns.pid"
|
||
|
|
|
||
|
|
# Log file path
|
||
|
|
log_file?: str = "~/.provisioning/coredns/coredns.log"
|
||
|
|
|
||
|
|
# Docker configuration (for docker mode)
|
||
|
|
docker?: DockerCoreDNS
|
||
|
|
|
||
|
|
check:
|
||
|
|
port >= 1024 and port <= 65535, "Port must be 1024-65535"
|
||
|
|
len(zones) > 0, "At least one zone required"
|
||
|
|
deployment_type != "docker" or docker != Undefined, \
|
||
|
|
"Docker config required when deployment_type is 'docker'"
|
||
|
|
|
||
|
|
schema DockerCoreDNS:
|
||
|
|
"""
|
||
|
|
Docker-based CoreDNS deployment configuration
|
||
|
|
"""
|
||
|
|
# Docker image
|
||
|
|
image: str = "coredns/coredns:1.11.1"
|
||
|
|
|
||
|
|
# Container name
|
||
|
|
container_name: str = "provisioning-coredns"
|
||
|
|
|
||
|
|
# Restart policy
|
||
|
|
restart_policy: "no" | "always" | "unless-stopped" | "on-failure" = "unless-stopped"
|
||
|
|
|
||
|
|
# Network mode
|
||
|
|
network_mode: str = "bridge"
|
||
|
|
|
||
|
|
# Publish DNS port
|
||
|
|
publish_port: bool = True
|
||
|
|
|
||
|
|
# Volume mounts (host:container)
|
||
|
|
volumes: [str] = []
|
||
|
|
|
||
|
|
check:
|
||
|
|
len(image) > 0, "Docker image required"
|
||
|
|
len(container_name) > 0, "Container name required"
|
||
|
|
|
||
|
|
schema RemoteCoreDNS:
|
||
|
|
"""
|
||
|
|
Remote CoreDNS service configuration
|
||
|
|
|
||
|
|
Connect to external CoreDNS instances for DNS management.
|
||
|
|
"""
|
||
|
|
# Enable remote CoreDNS
|
||
|
|
enabled: bool = True
|
||
|
|
|
||
|
|
# Remote CoreDNS API endpoints
|
||
|
|
endpoints: [str]
|
||
|
|
|
||
|
|
# Managed zones on remote servers
|
||
|
|
zones: [str]
|
||
|
|
|
||
|
|
# Authentication token file path
|
||
|
|
auth_token_path?: str
|
||
|
|
|
||
|
|
# TLS verification
|
||
|
|
verify_tls: bool = True
|
||
|
|
|
||
|
|
# Connection timeout (seconds)
|
||
|
|
timeout: int = 30
|
||
|
|
|
||
|
|
# Health check interval (seconds)
|
||
|
|
health_check_interval: int = 60
|
||
|
|
|
||
|
|
check:
|
||
|
|
len(endpoints) > 0, "At least one remote endpoint required"
|
||
|
|
len(zones) > 0, "At least one zone required"
|
||
|
|
timeout > 0 and timeout <= 300, "Timeout must be 1-300 seconds"
|
||
|
|
health_check_interval >= 10, "Health check interval must be >= 10 seconds"
|
||
|
|
|
||
|
|
schema DynamicDNS:
|
||
|
|
"""
|
||
|
|
Dynamic DNS update configuration
|
||
|
|
|
||
|
|
Enables automatic DNS updates when infrastructure changes.
|
||
|
|
"""
|
||
|
|
# Enable dynamic DNS updates
|
||
|
|
enabled: bool = True
|
||
|
|
|
||
|
|
# Orchestrator DNS API endpoint
|
||
|
|
api_endpoint: str = "http://localhost:8080/dns"
|
||
|
|
|
||
|
|
# Automatically register servers on creation
|
||
|
|
auto_register_servers: bool = True
|
||
|
|
|
||
|
|
# Automatically unregister servers on deletion
|
||
|
|
auto_unregister_servers: bool = True
|
||
|
|
|
||
|
|
# Default TTL for dynamic records (seconds)
|
||
|
|
ttl: int = 300
|
||
|
|
|
||
|
|
# Update strategy: immediate, batched, or scheduled
|
||
|
|
update_strategy: "immediate" | "batched" | "scheduled" = "immediate"
|
||
|
|
|
||
|
|
# Batch interval (seconds, for batched strategy)
|
||
|
|
batch_interval?: int = 60
|
||
|
|
|
||
|
|
# Retry configuration
|
||
|
|
retry_policy: RetryPolicy = RetryPolicy {}
|
||
|
|
|
||
|
|
check:
|
||
|
|
ttl > 0 and ttl <= 86400, "TTL must be 1-86400 seconds"
|
||
|
|
update_strategy != "batched" or batch_interval != Undefined, \
|
||
|
|
"Batch interval required for batched strategy"
|
||
|
|
batch_interval == Undefined or batch_interval >= 10, \
|
||
|
|
"Batch interval must be >= 10 seconds"
|
||
|
|
|
||
|
|
schema RetryPolicy:
|
||
|
|
"""
|
||
|
|
Retry policy for DNS update failures
|
||
|
|
"""
|
||
|
|
# Maximum retry attempts
|
||
|
|
max_attempts: int = 3
|
||
|
|
|
||
|
|
# Initial delay before first retry (seconds)
|
||
|
|
initial_delay: int = 5
|
||
|
|
|
||
|
|
# Backoff multiplier for subsequent retries
|
||
|
|
backoff_multiplier: float = 2.0
|
||
|
|
|
||
|
|
# Maximum delay between retries (seconds)
|
||
|
|
max_delay: int = 60
|
||
|
|
|
||
|
|
check:
|
||
|
|
max_attempts > 0 and max_attempts <= 10, "Max attempts must be 1-10"
|
||
|
|
initial_delay > 0, "Initial delay must be positive"
|
||
|
|
backoff_multiplier >= 1.0, "Backoff multiplier must be >= 1.0"
|
||
|
|
max_delay >= initial_delay, "Max delay must be >= initial delay"
|
||
|
|
|
||
|
|
schema DNSZone:
|
||
|
|
"""
|
||
|
|
DNS zone configuration
|
||
|
|
|
||
|
|
Defines a DNS zone with SOA, NS, and other records.
|
||
|
|
|
||
|
|
Examples:
|
||
|
|
DNSZone {
|
||
|
|
name = "provisioning.local"
|
||
|
|
admin_email = "admin.provisioning.local"
|
||
|
|
nameservers = ["ns1.provisioning.local"]
|
||
|
|
records = [
|
||
|
|
DNSRecord {
|
||
|
|
name = "server-01"
|
||
|
|
type = "A"
|
||
|
|
value = "10.0.1.10"
|
||
|
|
}
|
||
|
|
]
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
# Zone name (must be FQDN with trailing dot in zone file)
|
||
|
|
name: str
|
||
|
|
|
||
|
|
# Zone file path
|
||
|
|
file_path?: str
|
||
|
|
|
||
|
|
# SOA record configuration
|
||
|
|
soa: SOARecord = SOARecord {}
|
||
|
|
|
||
|
|
# Nameserver hostnames
|
||
|
|
nameservers: [str]
|
||
|
|
|
||
|
|
# Admin email (dots replaced with @ in zone file)
|
||
|
|
admin_email: str = $"admin.{name}"
|
||
|
|
|
||
|
|
# DNS records
|
||
|
|
records: [DNSRecord] = []
|
||
|
|
|
||
|
|
# Default TTL for zone (seconds)
|
||
|
|
ttl: int = 3600
|
||
|
|
|
||
|
|
check:
|
||
|
|
len(name) > 0, "Zone name required"
|
||
|
|
regex.match(name, r"^[a-z0-9]([a-z0-9-\.]{0,253}[a-z0-9])?$"), \
|
||
|
|
"Zone name must be valid domain name"
|
||
|
|
len(nameservers) > 0, "At least one nameserver required"
|
||
|
|
ttl > 0, "TTL must be positive"
|
||
|
|
|
||
|
|
schema SOARecord:
|
||
|
|
"""
|
||
|
|
SOA (Start of Authority) record
|
||
|
|
"""
|
||
|
|
# Serial number (auto-incremented on updates)
|
||
|
|
serial: int = 1
|
||
|
|
|
||
|
|
# Refresh interval (seconds)
|
||
|
|
refresh: int = 3600
|
||
|
|
|
||
|
|
# Retry interval (seconds)
|
||
|
|
retry: int = 1800
|
||
|
|
|
||
|
|
# Expire time (seconds)
|
||
|
|
expire: int = 604800
|
||
|
|
|
||
|
|
# Minimum TTL (seconds)
|
||
|
|
minimum: int = 86400
|
||
|
|
|
||
|
|
check:
|
||
|
|
serial > 0, "Serial must be positive"
|
||
|
|
refresh > 0, "Refresh must be positive"
|
||
|
|
retry > 0, "Retry must be positive"
|
||
|
|
expire > refresh, "Expire must be > refresh"
|
||
|
|
minimum > 0, "Minimum must be positive"
|
||
|
|
|
||
|
|
schema DNSRecord:
|
||
|
|
"""
|
||
|
|
DNS resource record
|
||
|
|
|
||
|
|
Supports A, AAAA, CNAME, MX, TXT, NS, SRV, PTR records.
|
||
|
|
|
||
|
|
Examples:
|
||
|
|
# A record
|
||
|
|
DNSRecord {
|
||
|
|
name = "server-01"
|
||
|
|
type = "A"
|
||
|
|
value = "10.0.1.10"
|
||
|
|
}
|
||
|
|
|
||
|
|
# CNAME record
|
||
|
|
DNSRecord {
|
||
|
|
name = "web"
|
||
|
|
type = "CNAME"
|
||
|
|
value = "server-01.provisioning.local"
|
||
|
|
}
|
||
|
|
|
||
|
|
# MX record
|
||
|
|
DNSRecord {
|
||
|
|
name = "@"
|
||
|
|
type = "MX"
|
||
|
|
priority = 10
|
||
|
|
value = "mail.provisioning.local"
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
# Record name (hostname or @)
|
||
|
|
name: str
|
||
|
|
|
||
|
|
# Record type
|
||
|
|
type: "A" | "AAAA" | "CNAME" | "MX" | "TXT" | "NS" | "SOA" | "SRV" | "PTR"
|
||
|
|
|
||
|
|
# Record value (IP address, hostname, or text)
|
||
|
|
value: str
|
||
|
|
|
||
|
|
# TTL in seconds (optional, uses zone default)
|
||
|
|
ttl?: int
|
||
|
|
|
||
|
|
# Priority (for MX and SRV records)
|
||
|
|
priority?: int
|
||
|
|
|
||
|
|
# Weight (for SRV records)
|
||
|
|
weight?: int
|
||
|
|
|
||
|
|
# Port (for SRV records)
|
||
|
|
port?: int
|
||
|
|
|
||
|
|
# Comment
|
||
|
|
comment?: str
|
||
|
|
|
||
|
|
check:
|
||
|
|
len(name) > 0, "Record name required"
|
||
|
|
len(value) > 0, "Record value required"
|
||
|
|
|
||
|
|
# A record validation
|
||
|
|
type != "A" or regex.match(value, \
|
||
|
|
r"^((25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])$"), \
|
||
|
|
"A record value must be valid IPv4 address"
|
||
|
|
|
||
|
|
# AAAA record validation
|
||
|
|
type != "AAAA" or regex.match(value, r"^([0-9a-fA-F]{0,4}:){7}[0-9a-fA-F]{0,4}$"), \
|
||
|
|
"AAAA record value must be valid IPv6 address"
|
||
|
|
|
||
|
|
# MX/SRV priority validation
|
||
|
|
type not in ["MX", "SRV"] or priority != Undefined, \
|
||
|
|
"Priority required for MX and SRV records"
|
||
|
|
|
||
|
|
# SRV weight and port validation
|
||
|
|
type != "SRV" or (weight != Undefined and port != Undefined), \
|
||
|
|
"Weight and port required for SRV records"
|
||
|
|
|
||
|
|
# TTL validation
|
||
|
|
ttl == Undefined or (ttl > 0 and ttl <= 86400), \
|
||
|
|
"TTL must be 1-86400 seconds"
|
||
|
|
|
||
|
|
schema CorefilePlugin:
|
||
|
|
"""
|
||
|
|
Corefile plugin configuration
|
||
|
|
|
||
|
|
Defines a plugin block in Corefile.
|
||
|
|
"""
|
||
|
|
# Plugin name (file, forward, cache, etc.)
|
||
|
|
name: str
|
||
|
|
|
||
|
|
# Plugin arguments
|
||
|
|
args: [str] = []
|
||
|
|
|
||
|
|
# Plugin options (key-value pairs)
|
||
|
|
options: {str: str} = {}
|
||
|
|
|
||
|
|
check:
|
||
|
|
len(name) > 0, "Plugin name required"
|
||
|
|
|
||
|
|
schema CorefileZoneBlock:
|
||
|
|
"""
|
||
|
|
Corefile zone block configuration
|
||
|
|
|
||
|
|
Defines a zone block with plugins in Corefile.
|
||
|
|
"""
|
||
|
|
# Zone name (e.g., "provisioning.local:5353")
|
||
|
|
zone: str
|
||
|
|
|
||
|
|
# Port number
|
||
|
|
port: int = 53
|
||
|
|
|
||
|
|
# Plugins in this zone
|
||
|
|
plugins: [CorefilePlugin]
|
||
|
|
|
||
|
|
check:
|
||
|
|
len(zone) > 0, "Zone required"
|
||
|
|
port >= 1024 and port <= 65535, "Port must be 1024-65535"
|
||
|
|
len(plugins) > 0, "At least one plugin required"
|
||
|
|
|
||
|
|
schema DNSQueryLog:
|
||
|
|
"""
|
||
|
|
DNS query logging configuration
|
||
|
|
"""
|
||
|
|
# Enable query logging
|
||
|
|
enabled: bool = True
|
||
|
|
|
||
|
|
# Log file path
|
||
|
|
log_file: str = "~/.provisioning/coredns/queries.log"
|
||
|
|
|
||
|
|
# Log format: text or json
|
||
|
|
log_format: "text" | "json" = "text"
|
||
|
|
|
||
|
|
# Log level: debug, info, warn, error
|
||
|
|
log_level: "debug" | "info" | "warn" | "error" = "info"
|
||
|
|
|
||
|
|
# Rotate log files
|
||
|
|
rotate_enabled: bool = True
|
||
|
|
|
||
|
|
# Max log file size (MB)
|
||
|
|
max_size_mb: int = 100
|
||
|
|
|
||
|
|
# Max number of rotated files
|
||
|
|
max_backups: int = 5
|
||
|
|
|
||
|
|
check:
|
||
|
|
max_size_mb > 0 and max_size_mb <= 1024, "Max size must be 1-1024 MB"
|
||
|
|
max_backups >= 0 and max_backups <= 100, "Max backups must be 0-100"
|
||
|
|
|
||
|
|
schema DNSHealthCheck:
|
||
|
|
"""
|
||
|
|
CoreDNS health check configuration
|
||
|
|
"""
|
||
|
|
# Enable health checks
|
||
|
|
enabled: bool = True
|
||
|
|
|
||
|
|
# Health check endpoint
|
||
|
|
endpoint: str = "http://localhost:8080/health"
|
||
|
|
|
||
|
|
# Health check interval (seconds)
|
||
|
|
interval: int = 30
|
||
|
|
|
||
|
|
# Timeout for health check (seconds)
|
||
|
|
timeout: int = 5
|
||
|
|
|
||
|
|
# Unhealthy threshold (consecutive failures)
|
||
|
|
unhealthy_threshold: int = 3
|
||
|
|
|
||
|
|
# Healthy threshold (consecutive successes)
|
||
|
|
healthy_threshold: int = 2
|
||
|
|
|
||
|
|
check:
|
||
|
|
interval > 0, "Interval must be positive"
|
||
|
|
timeout > 0 and timeout < interval, "Timeout must be < interval"
|
||
|
|
unhealthy_threshold > 0, "Unhealthy threshold must be positive"
|
||
|
|
healthy_threshold > 0, "Healthy threshold must be positive"
|