358 lines
9.2 KiB
Text
358 lines
9.2 KiB
Text
|
|
# CoreDNS Docker Management
|
||
|
|
# Manage CoreDNS in Docker containers using docker-compose
|
||
|
|
|
||
|
|
# ../utils/log.nu does not exist — dangling import removed (ADR-025 L2).
|
||
|
|
use domain/coredns/corefile.nu [generate-corefile write-corefile]
|
||
|
|
use zones.nu create-zone-file
|
||
|
|
|
||
|
|
# Start CoreDNS Docker container
|
||
|
|
export def "coredns docker start" [
|
||
|
|
--check
|
||
|
|
] {
|
||
|
|
log info "Starting CoreDNS Docker container"
|
||
|
|
|
||
|
|
if $check {
|
||
|
|
print "Check mode: Would start CoreDNS Docker container"
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
let compose_file = get-compose-file-path
|
||
|
|
|
||
|
|
if not ($compose_file | path exists) {
|
||
|
|
log error $"docker-compose.yml not found at ($compose_file)"
|
||
|
|
print "Error: docker-compose.yml not found"
|
||
|
|
print $"Expected location: ($compose_file)"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
# Ensure configuration exists
|
||
|
|
ensure-coredns-config
|
||
|
|
|
||
|
|
let result = (do {
|
||
|
|
docker-compose -f $compose_file up -d
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $result.exit_code == 0 {
|
||
|
|
print "✓ CoreDNS Docker container started"
|
||
|
|
print ""
|
||
|
|
print "Check status with: provisioning dns docker status"
|
||
|
|
print "View logs with: provisioning dns docker logs"
|
||
|
|
} else {
|
||
|
|
log error "Failed to start CoreDNS Docker container"
|
||
|
|
print "✗ Failed to start CoreDNS Docker container"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Stop CoreDNS Docker container
|
||
|
|
export def "coredns docker stop" [
|
||
|
|
--check
|
||
|
|
] {
|
||
|
|
log info "Stopping CoreDNS Docker container"
|
||
|
|
|
||
|
|
if $check {
|
||
|
|
print "Check mode: Would stop CoreDNS Docker container"
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
let compose_file = get-compose-file-path
|
||
|
|
|
||
|
|
let result = (do {
|
||
|
|
docker-compose -f $compose_file down
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $result.exit_code == 0 {
|
||
|
|
print "✓ CoreDNS Docker container stopped"
|
||
|
|
} else {
|
||
|
|
log error "Failed to stop CoreDNS Docker container"
|
||
|
|
print "✗ Failed to stop CoreDNS Docker container"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Restart CoreDNS Docker container
|
||
|
|
export def "coredns docker restart" [
|
||
|
|
--check
|
||
|
|
] {
|
||
|
|
log info "Restarting CoreDNS Docker container"
|
||
|
|
|
||
|
|
if $check {
|
||
|
|
print "Check mode: Would restart CoreDNS Docker container"
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
let compose_file = get-compose-file-path
|
||
|
|
|
||
|
|
let result = (do {
|
||
|
|
docker-compose -f $compose_file restart
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $result.exit_code == 0 {
|
||
|
|
print "✓ CoreDNS Docker container restarted"
|
||
|
|
} else {
|
||
|
|
log error "Failed to restart CoreDNS Docker container"
|
||
|
|
print "✗ Failed to restart CoreDNS Docker container"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Show CoreDNS Docker container status
|
||
|
|
export def "coredns docker status" [] {
|
||
|
|
let compose_file = get-compose-file-path
|
||
|
|
|
||
|
|
print "CoreDNS Docker Status\n=====================\n"
|
||
|
|
|
||
|
|
let ps_result = (do {
|
||
|
|
docker-compose -f $compose_file ps
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $ps_result.exit_code == 0 {
|
||
|
|
print $ps_result.stdout
|
||
|
|
} else {
|
||
|
|
print "✗ Failed to get status (docker-compose may not be available)"
|
||
|
|
}
|
||
|
|
|
||
|
|
print "\nContainer Details:\n"
|
||
|
|
|
||
|
|
let details_result = (do {
|
||
|
|
docker ps --filter "name=provisioning-coredns" --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $details_result.exit_code == 0 {
|
||
|
|
print $details_result.stdout
|
||
|
|
} else {
|
||
|
|
print "✗ Failed to get container details"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Show CoreDNS Docker container logs
|
||
|
|
export def "coredns docker logs" [
|
||
|
|
--follow (-f) # Follow log output
|
||
|
|
--lines: int = 50 # Number of lines to show
|
||
|
|
] {
|
||
|
|
let compose_file = get-compose-file-path
|
||
|
|
|
||
|
|
let result = (do {
|
||
|
|
if $follow {
|
||
|
|
docker-compose -f $compose_file logs -f --tail $lines
|
||
|
|
} else {
|
||
|
|
docker-compose -f $compose_file logs --tail $lines
|
||
|
|
}
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $result.exit_code != 0 {
|
||
|
|
log error "Failed to get CoreDNS Docker logs"
|
||
|
|
print "✗ Failed to get logs"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Execute command in CoreDNS Docker container
|
||
|
|
export def "coredns docker exec" [
|
||
|
|
...command: string # Command to execute
|
||
|
|
] {
|
||
|
|
let compose_file = get-compose-file-path
|
||
|
|
|
||
|
|
let result = (do {
|
||
|
|
docker-compose -f $compose_file exec coredns ...$command
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $result.exit_code != 0 {
|
||
|
|
log error "Failed to execute command in CoreDNS Docker container"
|
||
|
|
print "✗ Failed to execute command"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Pull latest CoreDNS Docker image
|
||
|
|
export def "coredns docker pull" [
|
||
|
|
--version: string = "1.11.1"
|
||
|
|
] {
|
||
|
|
log info $"Pulling CoreDNS Docker image: ($version)"
|
||
|
|
|
||
|
|
let result = (do {
|
||
|
|
docker pull $"coredns/coredns:($version)"
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $result.exit_code == 0 {
|
||
|
|
print $"✓ CoreDNS Docker image pulled: ($version)"
|
||
|
|
} else {
|
||
|
|
log error "Failed to pull CoreDNS Docker image"
|
||
|
|
print "✗ Failed to pull image"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Update CoreDNS Docker container to latest version
|
||
|
|
export def "coredns docker update" [
|
||
|
|
--version: string = "latest"
|
||
|
|
--check
|
||
|
|
] {
|
||
|
|
log info "Updating CoreDNS Docker container"
|
||
|
|
|
||
|
|
if $check {
|
||
|
|
print "Check mode: Would update CoreDNS Docker container"
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
# Pull new image
|
||
|
|
coredns docker pull --version $version
|
||
|
|
|
||
|
|
# Restart with new image
|
||
|
|
coredns docker restart
|
||
|
|
|
||
|
|
print "✓ CoreDNS Docker container updated"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Show CoreDNS Docker container health
|
||
|
|
export def "coredns docker health" [] {
|
||
|
|
let health = (do {
|
||
|
|
docker inspect provisioning-coredns --format "{{.State.Health.Status}}"
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $health.exit_code == 0 {
|
||
|
|
let status = $health.stdout | str trim
|
||
|
|
|
||
|
|
print $"Health Status: ($status)"
|
||
|
|
|
||
|
|
match $status {
|
||
|
|
"healthy" => { print "✓ Container is healthy" }
|
||
|
|
"unhealthy" => { print "✗ Container is unhealthy" }
|
||
|
|
"starting" => { print "⏳ Container is starting" }
|
||
|
|
_ => { print $"Unknown status: ($status)" }
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
print "✗ Container not found or no health check configured"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Remove CoreDNS Docker container and volumes
|
||
|
|
export def "coredns docker remove" [
|
||
|
|
--volumes (-v) # Remove volumes as well
|
||
|
|
--force # Skip confirmation
|
||
|
|
--check
|
||
|
|
] {
|
||
|
|
if not $force {
|
||
|
|
let confirm = input "Are you sure you want to remove CoreDNS Docker container? (yes/no): "
|
||
|
|
|
||
|
|
if $confirm != "yes" {
|
||
|
|
print "Cancelled"
|
||
|
|
return
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if $check {
|
||
|
|
print "Check mode: Would remove CoreDNS Docker container"
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
let compose_file = get-compose-file-path
|
||
|
|
|
||
|
|
let result = (do {
|
||
|
|
if $volumes {
|
||
|
|
docker-compose -f $compose_file down -v
|
||
|
|
} else {
|
||
|
|
docker-compose -f $compose_file down
|
||
|
|
}
|
||
|
|
} | complete)
|
||
|
|
|
||
|
|
if $result.exit_code == 0 {
|
||
|
|
if $volumes {
|
||
|
|
print "✓ CoreDNS Docker container and volumes removed"
|
||
|
|
} else {
|
||
|
|
print "✓ CoreDNS Docker container removed"
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
log error "Failed to remove CoreDNS Docker container"
|
||
|
|
print "✗ Failed to remove container"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Helper: Get docker-compose file path
|
||
|
|
def get-compose-file-path [] -> string {
|
||
|
|
let project_root = get-project-root
|
||
|
|
$"($project_root)/provisioning/config/coredns/docker-compose.yml"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Helper: Get project root
|
||
|
|
def get-project-root [] -> string {
|
||
|
|
# Try to find project root by looking for provisioning directory
|
||
|
|
mut current = pwd
|
||
|
|
|
||
|
|
loop {
|
||
|
|
if ($"($current)/provisioning" | path exists) {
|
||
|
|
return $current
|
||
|
|
}
|
||
|
|
|
||
|
|
let parent = $current | path dirname
|
||
|
|
|
||
|
|
if $parent == $current {
|
||
|
|
# Reached filesystem root
|
||
|
|
break
|
||
|
|
}
|
||
|
|
|
||
|
|
$current = $parent
|
||
|
|
}
|
||
|
|
|
||
|
|
# Fallback: use current directory
|
||
|
|
pwd
|
||
|
|
}
|
||
|
|
|
||
|
|
# Helper: Ensure CoreDNS configuration exists
|
||
|
|
def ensure-coredns-config [] {
|
||
|
|
let config_dir = $"([$env.HOME, '.provisioning', 'coredns'] | path join)"
|
||
|
|
let corefile_path = $"($config_dir)/Corefile"
|
||
|
|
let zones_path = $"($config_dir)/zones"
|
||
|
|
|
||
|
|
# Create directories
|
||
|
|
mkdir $config_dir
|
||
|
|
mkdir $zones_path
|
||
|
|
|
||
|
|
# Generate Corefile if not exists
|
||
|
|
if not ($corefile_path | path exists) {
|
||
|
|
log info "Generating default Corefile"
|
||
|
|
|
||
|
|
let default_config = {
|
||
|
|
mode: "local"
|
||
|
|
local: {
|
||
|
|
port: 5353
|
||
|
|
zones_path: $zones_path
|
||
|
|
zones: ["provisioning.local"]
|
||
|
|
}
|
||
|
|
upstream: ["8.8.8.8", "1.1.1.1"]
|
||
|
|
enable_logging: true
|
||
|
|
}
|
||
|
|
|
||
|
|
let corefile_content = generate-corefile $default_config
|
||
|
|
write-corefile $corefile_path $corefile_content
|
||
|
|
}
|
||
|
|
|
||
|
|
# Create zone files if not exist
|
||
|
|
let zones = ["provisioning.local"]
|
||
|
|
|
||
|
|
for zone in $zones {
|
||
|
|
let zone_file = $"($zones_path)/($zone).zone"
|
||
|
|
|
||
|
|
if not ($zone_file | path exists) {
|
||
|
|
log info $"Creating default zone file: ($zone)"
|
||
|
|
create-zone-file $zone $zones_path
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Show docker-compose configuration
|
||
|
|
export def "coredns docker config" [] {
|
||
|
|
let compose_file = get-compose-file-path
|
||
|
|
|
||
|
|
if not ($compose_file | path exists) {
|
||
|
|
print $"✗ docker-compose.yml not found at ($compose_file)"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
print $"Docker Compose Configuration\n============================\n"
|
||
|
|
print $"File: ($compose_file)\n"
|
||
|
|
|
||
|
|
docker-compose -f $compose_file config
|
||
|
|
}
|