### Start Nginx with Traefik Labels (Docker) Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/getting-started.md Example of starting an Nginx container with Traefik labels to test routing. ```bash docker run -d \ --label "traefik.http.routers.test.rule=Host(\`test.example.com\`)" \ nginx ``` -------------------------------- ### Home Assistant Integration Example Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/providers/webhook.md Example configuration for triggering Home Assistant automations via webhooks. ```yaml environment: - DNSWEAVER_HASS_TYPE=webhook - DNSWEAVER_HASS_URL=http://homeassistant:8123/api/webhook/dns_update - DNSWEAVER_HASS_AUTH_TOKEN_FILE=/run/secrets/hass_token - DNSWEAVER_HASS_RECORD_TYPE=A - DNSWEAVER_HASS_TARGET=192.0.2.100 - DNSWEAVER_HASS_DOMAINS=*.home.example.com ``` -------------------------------- ### Install Dnsweaver from Local Helm Chart Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/getting-started.md Install dnsweaver using a local Helm chart after cloning the repository. ```bash git clone https://github.com/maxfield-allison/dnsweaver.git helm install dnsweaver deploy/helm/dnsweaver/ \ --namespace dnsweaver --create-namespace ``` -------------------------------- ### Split-Horizon Configuration Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/providers/cloudflare.md Example setup using both internal (Technitium) and external (Cloudflare) DNS providers. ```yaml environment: - DNSWEAVER_INSTANCES=internal,external # Internal: Direct to reverse proxy - DNSWEAVER_INTERNAL_TYPE=technitium - DNSWEAVER_INTERNAL_URL=http://dns-server:5380 - DNSWEAVER_INTERNAL_TOKEN_FILE=/run/secrets/technitium_token - DNSWEAVER_INTERNAL_ZONE=example.com - DNSWEAVER_INTERNAL_RECORD_TYPE=A - DNSWEAVER_INTERNAL_TARGET=192.0.2.100 - DNSWEAVER_INTERNAL_DOMAINS=*.example.com # External: Through Cloudflare Tunnel - DNSWEAVER_EXTERNAL_TYPE=cloudflare - DNSWEAVER_EXTERNAL_TOKEN_FILE=/run/secrets/cloudflare_token - DNSWEAVER_EXTERNAL_ZONE=example.com - DNSWEAVER_EXTERNAL_RECORD_TYPE=CNAME - DNSWEAVER_EXTERNAL_TARGET=abc123.cfargotunnel.com - DNSWEAVER_EXTERNAL_DOMAINS=*.example.com - DNSWEAVER_EXTERNAL_PROXIED=true ``` -------------------------------- ### DNSWEAVER Instances Configuration Example Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/contributing/architecture.md Example configuration demonstrating how to define multiple dnsweaver instances, each binding a provider to specific domain patterns and record types using environment variables. ```bash DNSWEAVER_INSTANCES=internal-dns,cloudflare # Instance: internal-dns DNSWEAVER_INTERNAL_DNS_TYPE=technitium DNSWEAVER_INTERNAL_DNS_DOMAINS=*.home.example.com DNSWEAVER_INTERNAL_DNS_RECORD_TYPE=A # Instance: cloudflare DNSWEAVER_CLOUDFLARE_TYPE=cloudflare DNSWEAVER_CLOUDFLARE_DOMAINS=*.example.com DNSWEAVER_CLOUDFLARE_RECORD_TYPE=CNAME ``` -------------------------------- ### Install Dnsweaver using Kustomize Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/getting-started.md Apply the base Kustomize configuration to install dnsweaver on a Kubernetes cluster. ```bash kubectl apply -k https://github.com/maxfield-allison/dnsweaver/deploy/kustomize/base ``` -------------------------------- ### Docker Compose Example Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/sources/native-labels.md A complete Docker Compose example demonstrating how to configure the dnsweaver service and a sample application using native labels. ```APIDOC ## Docker Compose Example This example shows a `docker-compose.yml` file with the dnsweaver service and a sample application using native labels. ```yaml services: dnsweaver: image: maxamill/dnsweaver:latest environment: - DNSWEAVER_SOURCES=dnsweaver # Only native labels - DNSWEAVER_INSTANCES=internal - DNSWEAVER_INTERNAL_TYPE=technitium - DNSWEAVER_INTERNAL_URL=http://dns:5380 - DNSWEAVER_INTERNAL_TOKEN_FILE=/run/secrets/dns_token - DNSWEAVER_INTERNAL_ZONE=example.com - DNSWEAVER_INTERNAL_RECORD_TYPE=A - DNSWEAVER_INTERNAL_TARGET=192.0.2.100 - DNSWEAVER_INTERNAL_DOMAINS=*.example.com volumes: - /var/run/docker.sock:/var/run/docker.sock:ro my-service: image: nginx labels: - "dnsweaver.hostname=my-service.example.com" ``` ``` -------------------------------- ### Install dependencies Source: https://github.com/maxfield-allison/dnsweaver/blob/main/CONTRIBUTING.md Download required Go modules. ```bash go mod download ``` -------------------------------- ### Example: SRV Record (Minecraft Server) Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/sources/native-labels.md Example of creating an SRV record for service discovery, such as for a Minecraft server. ```APIDOC ## Example: SRV Record (Minecraft Server) Create an SRV record for service discovery. ```yaml services: minecraft: image: itzg/minecraft-server labels: - "dnsweaver.records.mc.hostname=_minecraft._tcp.mc.example.com" - "dnsweaver.records.mc.type=SRV" - "dnsweaver.records.mc.port=25565" - "dnsweaver.records.mc.priority=10" - "dnsweaver.records.mc.weight=100" ``` ``` -------------------------------- ### Example: Database Server Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/sources/native-labels.md Example of creating an A record for a database service using a simple hostname label. ```APIDOC ## Example: Database Server Create an A record for a database service. ```yaml services: postgres: image: postgres:15 labels: - "dnsweaver.hostname=db.internal.example.com" ``` ``` -------------------------------- ### Install dnsweaver with Helm Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/deployment/kubernetes.md Install dnsweaver using Helm, specifying provider configuration directly via command-line flags or by referencing a values file. ```bash helm install dnsweaver deploy/helm/dnsweaver/ \ --namespace dnsweaver --create-namespace \ --set config.providers[0].name=internal \ --set config.providers[0].type=technitium \ --set config.providers[0].domains[0]="*.internal.example.com" \ --set config.providers[0].config.url=http://dns:5380 \ --set config.providers[0].config.zone=internal.example.com ``` ```bash helm install dnsweaver deploy/helm/dnsweaver/ \ --namespace dnsweaver --create-namespace \ -f my-values.yaml ``` -------------------------------- ### Initialize MockProvider Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/testing/README.md Setup a mock provider instance with custom record sets and behavior functions. ```go mock := testutil.NewMockProvider("test-provider", "example.com.") mock.AddRecords( testutil.ARecord("app.example.com", "192.0.2.1"), ) mock.SetCreateFunc(func(ctx context.Context, rec provider.Record) error { return nil // custom behavior }) ``` -------------------------------- ### Implement Provider Integration Test Setup Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/testing/templates/provider-template.md Boilerplate for initializing a provider instance using environment variables for integration tests. ```go //go:build integration package myprovider_test import ( "context" "os" "testing" "time" ) func testProvider(t *testing.T) *Provider { t.Helper() apiURL := os.Getenv("MYPROVIDER_TEST_URL") apiKey := os.Getenv("MYPROVIDER_TEST_API_KEY") zone := os.Getenv("MYPROVIDER_TEST_ZONE") if apiURL == "" || zone == "" { t.Skip("MYPROVIDER_TEST_URL and MYPROVIDER_TEST_ZONE must be set") } // ... create and return provider } func TestIntegration_CreateAndQueryA(t *testing.T) { p := testProvider(t) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // ... test logic } ``` -------------------------------- ### Example: Multi-Hostname Service with Named Records Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/sources/native-labels.md Example of creating multiple DNS records for a service using named records. ```APIDOC ## Example: Multi-Hostname Service Create records for each service endpoint using named records. ```yaml services: minio: image: minio/minio labels: - "dnsweaver.records.console.hostname=minio.example.com" - "dnsweaver.records.api.hostname=s3.example.com" ``` ``` -------------------------------- ### dnsweaver YAML Configuration Example Source: https://context7.com/maxfield-allison/dnsweaver/llms.txt An example of a dnsweaver configuration file (config.yml) demonstrating settings for logging, reconciler, Docker, server, sources, and providers. ```yaml # config.yml logging: level: info format: json reconciler: interval: 60s dry_run: false cleanup_orphans: true ownership_tracking: true docker: host: unix:///var/run/docker.sock mode: auto platform: docker server: port: 8080 sources: - name: traefik - name: dnsweaver providers: - name: internal type: technitium domains: - "*.internal.example.com" - "*.home.example.com" record_type: A target: 192.0.2.100 ttl: 300 mode: managed config: url: http://dns.example.com:5380 token: ${TECHNITIUM_TOKEN} zone: internal.example.com - name: public type: cloudflare domains: - "*.example.com" exclude_domains: - "*.internal.example.com" record_type: CNAME target: lb.example.com config: api_token: ${CLOUDFLARE_TOKEN} zone_id: ${CLOUDFLARE_ZONE_ID} proxied: "false" ``` -------------------------------- ### Commit message examples Source: https://github.com/maxfield-allison/dnsweaver/blob/main/CONTRIBUTING.md Examples of valid conventional commit messages. ```text feat(provider): add Cloudflare DNS provider fix(reconciler): handle empty hostname list docs: update configuration reference ``` -------------------------------- ### Commit message examples Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/contributing/index.md Examples of valid commit messages following the conventional commit format. ```text feat(provider): add AdGuard Home provider support fix(docker): handle container restart events correctly docs: update Technitium configuration examples ``` -------------------------------- ### Standard Ingress Example Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/sources/kubernetes.md This example shows a standard Kubernetes Ingress resource. DNS Weaver automatically extracts the hostname 'app.example.com' and creates a DNS record using the default settings of the matching DNS provider. ```yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-app spec: rules: - host: app.example.com http: paths: - path: / pathType: Prefix backend: service: name: my-app port: number: 80 ``` -------------------------------- ### Install dnsweaver via CLI Source: https://context7.com/maxfield-allison/dnsweaver/llms.txt Commands to pull the container image or deploy via Kubernetes package managers. ```bash # Docker Hub docker pull maxamill/dnsweaver:latest # GitHub Container Registry docker pull ghcr.io/maxfield-allison/dnsweaver:latest # Kubernetes with Kustomize kubectl apply -k https://github.com/maxfield-allison/dnsweaver/deploy/kustomize/base # Kubernetes with Helm helm install dnsweaver oci://ghcr.io/maxfield-allison/charts/dnsweaver \ --namespace dnsweaver --create-namespace ``` -------------------------------- ### Database Server Record Example Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/sources/native-labels.md Create an A record for a database service. ```yaml services: postgres: image: postgres:15 labels: - "dnsweaver.hostname=db.internal.example.com" ``` -------------------------------- ### Full Docker Compose Example Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/sources/native-labels.md A complete configuration showing the dnsweaver service definition and a target container using native labels. ```yaml services: dnsweaver: image: maxamill/dnsweaver:latest environment: - DNSWEAVER_SOURCES=dnsweaver # Only native labels - DNSWEAVER_INSTANCES=internal - DNSWEAVER_INTERNAL_TYPE=technitium - DNSWEAVER_INTERNAL_URL=http://dns:5380 - DNSWEAVER_INTERNAL_TOKEN_FILE=/run/secrets/dns_token - DNSWEAVER_INTERNAL_ZONE=example.com - DNSWEAVER_INTERNAL_RECORD_TYPE=A - DNSWEAVER_INTERNAL_TARGET=192.0.2.100 - DNSWEAVER_INTERNAL_DOMAINS=*.example.com volumes: - /var/run/docker.sock:/var/run/docker.sock:ro my-service: image: nginx labels: - "dnsweaver.hostname=my-service.example.com" ``` -------------------------------- ### SSH Authentication Methods Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/providers/dnsmasq.md Configuration examples for key-based and password-based SSH authentication. ```yaml environment: - DNSWEAVER_ROUTER_SSH_KEY_FILE=/ssh/id_ed25519 volumes: - ./ssh_keys/router_key:/ssh/id_ed25519:ro ``` ```yaml environment: - DNSWEAVER_ROUTER_SSH_KEY_FILE_FILE=/run/secrets/router_ssh_key secrets: - router_ssh_key ``` ```yaml environment: - DNSWEAVER_ROUTER_SSH_PASSWORD_FILE=/run/secrets/router_password secrets: - router_password ``` -------------------------------- ### Traefik YAML Configuration Example Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/sources/traefik-files.md Example of a Traefik router configuration in YAML format. This defines a router named 'my-app' that listens for requests to 'app.example.com' on the 'web' entrypoint. ```yaml # /config/traefik/apps.yml http: routers: my-app: rule: Host(`app.example.com`) service: my-app entryPoints: - web ``` -------------------------------- ### Basic Cloudflare Configuration Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/providers/cloudflare.md Example environment variables for a standard Cloudflare dnsweaver instance. ```yaml environment: - DNSWEAVER_INSTANCES=cloudflare - DNSWEAVER_CLOUDFLARE_TYPE=cloudflare - DNSWEAVER_CLOUDFLARE_TOKEN_FILE=/run/secrets/cloudflare_token - DNSWEAVER_CLOUDFLARE_ZONE=example.com - DNSWEAVER_CLOUDFLARE_RECORD_TYPE=CNAME - DNSWEAVER_CLOUDFLARE_TARGET=tunnel.example.com - DNSWEAVER_CLOUDFLARE_DOMAINS=*.example.com ``` -------------------------------- ### Helm Chart Installation for dnsweaver on Kubernetes Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/index.md Install dnsweaver on Kubernetes using the Helm chart. This command sets up the dnsweaver release, namespace, and configures the internal DNS provider settings. ```bash helm install dnsweaver oci://ghcr.io/maxfield-allison/charts/dnsweaver \ --namespace dnsweaver --create-namespace \ --set config.instances="internal-dns" \ --set config.providers.internal-dns.type=technitium \ --set config.providers.internal-dns.url=http://dns.internal:5380 \ --set config.providers.internal-dns.zone=home.example.com \ --set config.providers.internal-dns.recordType=A \ --set config.providers.internal-dns.target=192.0.2.100 \ --set config.providers.internal-dns.domains="*.home.example.com" ``` -------------------------------- ### Example Managed Configuration File Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/providers/dnsmasq.md The resulting configuration file generated by dnsweaver within the dnsmasq directory. ```text # /etc/dnsmasq.d/dnsweaver.conf (managed by dnsweaver) address=/app.home.example.com/192.0.2.100 address=/web.home.example.com/192.0.2.100 cname=alias.home.example.com,target.home.example.com ``` -------------------------------- ### Troubleshoot Pod Startup Issues Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/deployment/kubernetes.md Use these kubectl commands to diagnose why a dnsweaver pod might not be starting. Check logs and describe the pod for detailed events. ```bash kubectl -n dnsweaver logs deploy/dnsweaver kubectl -n dnsweaver describe pod -l app.kubernetes.io/name=dnsweaver ``` -------------------------------- ### Example HTTPS Record Format Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/providers/technitium.md This is an example of the format for a companion HTTPS record created by dnsweaver. It specifies priority, target, and ALPN protocol. ```dns app.example.com 300 IN HTTPS 1 . alpn="h2" ``` -------------------------------- ### Traefik TOML Configuration Example Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/sources/traefik-files.md Example of a Traefik router configuration in TOML format. This defines a router named 'my-app' that listens for requests to 'app.example.com' on the 'web' entrypoint. ```toml # /config/traefik/apps.toml [http.routers.my-app] rule = "Host(`app.example.com`)" service = "my-app" entryPoints = ["web"] ``` -------------------------------- ### Deploy dnsweaver in a Swarm Stack Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/sources/swarm.md A complete example of a docker-compose stack file for deploying dnsweaver as a service. ```yaml version: "3.8" services: dnsweaver: image: maxamill/dnsweaver:latest environment: - DNSWEAVER_INSTANCES=internal - DNSWEAVER_INTERNAL_TYPE=technitium - DNSWEAVER_INTERNAL_URL=http://dns:5380 - DNSWEAVER_INTERNAL_TOKEN_FILE=/run/secrets/dns_token - DNSWEAVER_INTERNAL_ZONE=home.example.com - DNSWEAVER_INTERNAL_RECORD_TYPE=A - DNSWEAVER_INTERNAL_TARGET=192.0.2.100 - DNSWEAVER_INTERNAL_DOMAINS=*.home.example.com volumes: - /var/run/docker.sock:/var/run/docker.sock:ro deploy: mode: replicated replicas: 1 placement: constraints: - node.role == manager secrets: - dns_token secrets: dns_token: external: true ``` -------------------------------- ### Install dnsweaver via Docker Source: https://github.com/maxfield-allison/dnsweaver/blob/main/README.md Pull the latest dnsweaver image from Docker Hub or GitHub Container Registry. ```bash # Docker Hub docker pull maxamill/dnsweaver:latest # GitHub Container Registry docker pull ghcr.io/maxfield-allison/dnsweaver:latest ``` -------------------------------- ### Example JSON Log Entry Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/observability.md Sample of the structured JSON output produced by DNSWeaver. ```json { "time": "2024-01-15T10:30:00Z", "level": "info", "msg": "record created", "provider": "internal", "hostname": "app.example.com", "record_type": "A", "target": "192.0.2.100" } ``` -------------------------------- ### Configure Split-Horizon DNS Source: https://github.com/maxfield-allison/dnsweaver/blob/main/README.md Example environment variables for setting up Split-Horizon DNS. This configures both internal and external DNS instances with different providers and targets. ```yaml environment: - DNSWEAVER_INSTANCES=internal,external # Internal: Technitium → private IP - DNSWEAVER_INTERNAL_TYPE=technitium - DNSWEAVER_INTERNAL_RECORD_TYPE=A - DNSWEAVER_INTERNAL_TARGET=192.0.2.100 - DNSWEAVER_INTERNAL_DOMAINS=*.example.com # External: Cloudflare → tunnel CNAME - DNSWEAVER_EXTERNAL_TYPE=cloudflare - DNSWEAVER_EXTERNAL_RECORD_TYPE=CNAME - DNSWEAVER_EXTERNAL_TARGET=tunnel.example.com - DNSWEAVER_EXTERNAL_DOMAINS=*.example.com ``` -------------------------------- ### Multi-Hostname Service Example Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/sources/native-labels.md Create distinct records for different service endpoints using named records. ```yaml services: minio: image: minio/minio labels: - "dnsweaver.records.console.hostname=minio.example.com" - "dnsweaver.records.api.hostname=s3.example.com" ``` -------------------------------- ### Debug with Delve Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/contributing/development.md Install and use the Delve debugger to inspect the application at runtime. ```bash # Install delve go install github.com/go-delve/delve/cmd/dlv@latest # Debug dlv debug ./cmd/dnsweaver -- [args] ``` -------------------------------- ### dnsweaver Configuration Loading Flow Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/contributing/architecture.md Illustrates the sequence of steps involved in loading and processing dnsweaver configuration, starting from environment variables. ```text Environment Variables → internal/config.LoadConfig() → Parse DNSWEAVER_INSTANCES → For each instance: → Load instance-specific vars (TYPE, DOMAINS, TARGET, etc.) → Apply _FILE suffix resolution (Docker secrets) → Validate required fields → Create provider via providers/.New() → Create reconciler with all provider instances → Create watcher with platform adapters → Start event loop ``` -------------------------------- ### Example: Combine with Traefik Labels Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/sources/native-labels.md Demonstrates how to use both Traefik labels for HTTP routing and dnsweaver labels for direct DNS records within the same service. ```APIDOC ## Combine with Traefik Labels Use both Traefik and native dnsweaver labels for a service. ```yaml services: webapp: image: myapp:latest labels: # Traefik for HTTP routing - "traefik.http.routers.webapp.rule=Host(`webapp.example.com`)" # Additional DNS record via dnsweaver - "dnsweaver.hostname=webapp-direct.example.com" ``` Both hostnames will be processed if both sources are enabled. ``` -------------------------------- ### Build the project Source: https://github.com/maxfield-allison/dnsweaver/blob/main/CONTRIBUTING.md Compile the DNSWeaver binary. ```bash go build -o dnsweaver ./cmd/dnsweaver ``` -------------------------------- ### Docker Compose with YAML Configuration Source: https://context7.com/maxfield-allison/dnsweaver/llms.txt Example Docker Compose setup for dnsweaver that uses a YAML configuration file and environment variables for sensitive data. ```yaml # Docker Compose using config file services: dnsweaver: image: maxamill/dnsweaver:latest environment: - DNSWEAVER_CONFIG=/config/config.yml - TECHNITIUM_TOKEN=${TECHNITIUM_TOKEN} - CLOUDFLARE_TOKEN=${CLOUDFLARE_TOKEN} volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./config.yml:/config/config.yml:ro ``` -------------------------------- ### Configure Multi-Provider DNS with Environment Variables Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/providers/index.md Set up dnsweaver to manage DNS records across different providers simultaneously using environment variables. This example configures internal and external DNS resolution for a domain. ```bash DNSWEAVER_INSTANCES=internal,external # Internal: Technitium for LAN resolution DNSWEAVER_INTERNAL_TYPE=technitium DNSWEAVER_INTERNAL_RECORD_TYPE=A DNSWEAVER_INTERNAL_TARGET=192.0.2.100 DNSWEAVER_INTERNAL_DOMAINS=*.example.com # External: Cloudflare for public resolution DNSWEAVER_EXTERNAL_TYPE=cloudflare DNSWEAVER_EXTERNAL_RECORD_TYPE=CNAME DNSWEAVER_EXTERNAL_TARGET=proxy.example.com DNSWEAVER_EXTERNAL_DOMAINS=*.example.com ``` -------------------------------- ### DNS Record Ownership Tracking Example Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/contributing/architecture.md Demonstrates how dnsweaver uses TXT records to track ownership of managed DNS records, enabling multi-instance coordination and preventing accidental deletion of manual records. ```text # For hostname "app.example.com": _dnsweaver.app.example.com TXT "heritage=dnsweaver,instance=internal-dns" ``` -------------------------------- ### Implement record creation logic in Go Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/contributing/adding-provider.md Demonstrates a switch-based implementation for handling different DNS record types during creation. ```go func (p *Provider) Create(ctx context.Context, record provider.Record) error { switch record.Type { case provider.RecordTypeA, provider.RecordTypeAAAA: return p.client.AddAddressRecord(ctx, record.Hostname, record.Type, record.Target, p.ttl) case provider.RecordTypeCNAME: return p.client.AddCNAME(ctx, record.Hostname, record.Target, p.ttl) case provider.RecordTypeTXT: return p.client.AddTXT(ctx, record.Hostname, record.Target, p.ttl) case provider.RecordTypeSRV: if record.SRV == nil { return fmt.Errorf("SRV data is required for SRV records") } return p.client.AddSRV(ctx, record.Hostname, int(record.SRV.Priority), int(record.SRV.Weight), int(record.SRV.Port), record.Target, p.ttl) default: return fmt.Errorf("unsupported record type: %s", record.Type) } } ``` -------------------------------- ### Run Full Pre-release Validation Locally Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/testing/RELEASE-CHECKLIST.md Execute gofmt for formatting and linting, run unit tests with race detection, and build the project. Ensure all commands complete successfully before proceeding. ```bash gofmt -w . gofmt -l . golangci-lint run ./... go test ./... -count=1 -race go build ./... make test-integration # Requires test environment ``` -------------------------------- ### Clone and branch repository Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/contributing/index.md Initial steps to set up a local development environment by cloning the repository and creating a feature branch. ```bash git clone https://github.com/your-username/dnsweaver.git cd dnsweaver git checkout -b feature/your-feature-name ``` -------------------------------- ### Bad Error Message Example Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/testing/templates/config-template.md Shows an example of a poor, non-specific error message that lacks actionable information for the operator. ```plaintext "invalid config" ``` -------------------------------- ### Implementing Discover Method for a Source Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/contributing/adding-source.md Details the implementation of the Discover method, which is responsible for fetching and returning all currently known hostnames from the source. Includes logging of discovered hostnames. ```go func (s *MySource) Discover(ctx context.Context) ([]Hostname, error) { var hostnames []Hostname // Your discovery logic here // Example: Read from a file, query an API, etc. items, err := s.fetchItems(ctx) if err != nil { return nil, fmt.Errorf("fetching items: %w", err) } for _, item := range items { hostname := s.extractHostname(item) if hostname != "" { hostnames = append(hostnames, Hostname{ Name: hostname, SourceType: s.Type(), SourceID: item.ID, Labels: item.Labels, }) } } s.logger.Debug("discovered hostnames", slog.String("source", s.name), slog.Int("count", len(hostnames)), ) return hostnames, nil } ``` -------------------------------- ### Kubernetes Development Workflow Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/contributing/development.md Commands for setting up a local kind cluster and deploying dnsweaver for testing. ```bash # Create a local cluster with kind kind create cluster --name dnsweaver-dev # Deploy dnsweaver from local build make docker-build kind load docker-image dnsweaver:dev --name dnsweaver-dev kubectl apply -k deploy/kustomize/base # Watch logs kubectl logs -n dnsweaver deploy/dnsweaver -f # Create a test Ingress to trigger DNS record creation kubectl apply -f - <.New() → Create reconciler with all provider instances → Create watcher with platform adapters → Start event loop ``` ``` -------------------------------- ### Filter Logs with jq Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/observability.md Command-line examples for filtering structured logs using jq. ```bash # View only errors docker logs dnsweaver 2>&1 | jq 'select(.level == "error")' # View record changes docker logs dnsweaver 2>&1 | jq 'select(.msg | contains("record"))' # View specific provider docker logs dnsweaver 2>&1 | jq 'select(.provider == "internal")' ``` -------------------------------- ### Configure Multiple Providers with Mixed Modes Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/configuration/modes.md Demonstrates how to define multiple provider instances with different operational modes in a single configuration file. ```yaml providers: # Internal DNS: fully managed - name: internal type: technitium mode: managed domains: ["*.home.example.com"] # Public DNS: additive only (manual cleanup) - name: public type: cloudflare mode: additive domains: ["*.example.com"] # Dedicated container zone: authoritative - name: containers type: technitium mode: authoritative domains: ["*.containers.internal.example.com"] ``` -------------------------------- ### Docker Compose Healthcheck Configuration Source: https://context7.com/maxfield-allison/dnsweaver/llms.txt Example of configuring DNSWeaver's healthcheck within Docker Compose. ```APIDOC ## Docker Compose Healthcheck Configuration ### Description This snippet shows how to configure the healthcheck for the dnsweaver service in a Docker Compose file. ### Docker Compose Configuration ```yaml services: dnsweaver: image: maxamill/dnsweaver:latest healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080/health"] interval: 30s timeout: 10s retries: 3 start_period: 10s ``` ``` -------------------------------- ### Troubleshooting Commands Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/providers/dnsmasq.md Commands to verify configuration files, reload mechanisms, and permissions. ```bash cat /etc/dnsmasq.d/dnsweaver.conf ``` ```bash ssh root@192.168.1.1 "cat /tmp/dnsmasq.d/dnsweaver.conf" ``` ```bash docker exec dnsweaver /bin/sh -c "$RELOAD_COMMAND" ``` ```bash docker exec dnsweaver touch /etc/dnsmasq.d/test.conf ``` -------------------------------- ### Docker Compose with SSH Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/providers/dnsmasq.md Complete example for managing a remote router using Docker Compose and secrets. ```yaml services: dnsweaver: image: maxamill/dnsweaver:latest environment: - DNSWEAVER_INSTANCES=router - DNSWEAVER_ROUTER_TYPE=dnsmasq - DNSWEAVER_ROUTER_CONFIG_DIR=/tmp/dnsmasq.d - DNSWEAVER_ROUTER_CONFIG_FILE=dnsweaver.conf - DNSWEAVER_ROUTER_RECORD_TYPE=A - DNSWEAVER_ROUTER_TARGET=192.0.2.100 - DNSWEAVER_ROUTER_DOMAINS=*.home.example.com - DNSWEAVER_ROUTER_RELOAD_COMMAND=killall -HUP dnsmasq - DNSWEAVER_ROUTER_SSH_HOST=192.168.1.1 - DNSWEAVER_ROUTER_SSH_USER=root - DNSWEAVER_ROUTER_SSH_KEY_FILE_FILE=/run/secrets/router_ssh_key volumes: - /var/run/docker.sock:/var/run/docker.sock:ro secrets: - router_ssh_key secrets: router_ssh_key: file: ./ssh_keys/router_id_ed25519 ``` -------------------------------- ### Ownership TXT Record Format Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/configuration/multi-instance.md Example of the TXT record generated to track ownership of DNS records. ```text _dnsweaver.app.example.com TXT "heritage=dnsweaver,instance=internal-mgr" ``` -------------------------------- ### Configure Kubernetes Deployment Secrets Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/configuration/secrets.md Example of referencing Kubernetes Secrets directly within a Deployment manifest. ```yaml apiVersion: apps/v1 kind: Deployment metadata: name: dnsweaver spec: template: spec: containers: - name: dnsweaver env: - name: DNSWEAVER_INTERNAL_DNS_TOKEN valueFrom: secretKeyRef: name: dnsweaver-credentials key: technitium-token - name: DNSWEAVER_CLOUDFLARE_TOKEN valueFrom: secretKeyRef: name: dnsweaver-credentials key: cloudflare-token ``` -------------------------------- ### Run tests Source: https://github.com/maxfield-allison/dnsweaver/blob/main/CONTRIBUTING.md Execute the project test suite. ```bash go test -v ./... ``` -------------------------------- ### Multi-Provider Swarm Stack Configuration Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/deployment/swarm.md Configuration for split-horizon DNS setups using multiple providers simultaneously. ```yaml version: "3.8" services: dnsweaver: image: maxamill/dnsweaver:latest environment: - DNSWEAVER_DOCKER_HOST=tcp://socket-proxy:2375 - DNSWEAVER_INSTANCES=internal,external # Internal DNS - DNSWEAVER_INTERNAL_TYPE=technitium - DNSWEAVER_INTERNAL_URL=http://dns:5380 - DNSWEAVER_INTERNAL_TOKEN_FILE=/run/secrets/technitium_token - DNSWEAVER_INTERNAL_ZONE=example.com - DNSWEAVER_INTERNAL_RECORD_TYPE=A - DNSWEAVER_INTERNAL_TARGET=192.0.2.100 - DNSWEAVER_INTERNAL_DOMAINS=*.example.com # External DNS - DNSWEAVER_EXTERNAL_TYPE=cloudflare - DNSWEAVER_EXTERNAL_TOKEN_FILE=/run/secrets/cloudflare_token - DNSWEAVER_EXTERNAL_ZONE=example.com - DNSWEAVER_EXTERNAL_RECORD_TYPE=CNAME - DNSWEAVER_EXTERNAL_TARGET=tunnel.example.com - DNSWEAVER_EXTERNAL_DOMAINS=*.example.com - DNSWEAVER_EXTERNAL_EXCLUDE_DOMAINS=*.internal.example.com deploy: mode: replicated replicas: 1 placement: constraints: - node.role == manager secrets: - technitium_token - cloudflare_token secrets: technitium_token: external: true cloudflare_token: external: true ``` -------------------------------- ### Run dnsweaver tests via Makefile Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/testing/README.md Standard commands for executing unit, integration, and coverage-enabled tests. ```bash # Run all unit tests make test # Run with coverage make test-cover # Run short tests only make test-short # Run integration tests (requires env vars) make test-integration ``` -------------------------------- ### Pi-hole API Mode Configuration Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/providers/pihole.md Configuration example for using dnsweaver with Pi-hole in API mode. This is the recommended approach. ```APIDOC ## Pi-hole API Mode Configuration ### Description Configure dnsweaver to interact with Pi-hole via its API for managing DNS records. ### Method Environment Variables ### Endpoint N/A (Configuration) ### Parameters #### Environment Variables - **DNSWEAVER_INSTANCES** (string) - Required - Specifies the instance name, e.g., `pihole`. - **DNSWEAVER_PIHOLE_TYPE** (string) - Required - Must be `pihole`. - **DNSWEAVER_PIHOLE_ACCESS_MODE** (string) - Required - Set to `api` for API mode. - **DNSWEAVER_PIHOLE_URL** (string) - Required (API mode) - The URL of the Pi-hole web interface (e.g., `http://pihole:80`). - **DNSWEAVER_PIHOLE_PASSWORD_FILE** (string) - Required (API mode, alternative to PASSWORD) - Path to a file containing the Pi-hole web interface password. - **DNSWEAVER_PIHOLE_RECORD_TYPE** (string) - Required - The type of DNS record to manage (`A`, `AAAA`, `CNAME`). - **DNSWEAVER_PIHOLE_TARGET** (string) - Required - The IP address or hostname for the DNS record. - **DNSWEAVER_PIHOLE_DOMAINS** (string) - Required - Glob patterns for domains to match (e.g., `*.home.example.com`). - **DNSWEAVER_PIHOLE_PASSWORD** (string) - Required (API mode, alternative to PASSWORD_FILE) - The Pi-hole web interface password. - **DNSWEAVER_PIHOLE_API_VERSION** (string) - Optional - Pi-hole API version (`v5`, `v6`, `auto`). Defaults to `auto`. - **DNSWEAVER_PIHOLE_ZONE** (string) - Optional - DNS zone for record filtering. - **DNSWEAVER_PIHOLE_TTL** (string) - Optional - Record TTL in seconds. Defaults to `300`. - **DNSWEAVER_PIHOLE_EXCLUDE_DOMAINS** (string) - Optional - Glob patterns to exclude. ### Request Example ```yaml environment: - DNSWEAVER_INSTANCES=pihole - DNSWEAVER_PIHOLE_TYPE=pihole - DNSWEAVER_PIHOLE_ACCESS_MODE=api - DNSWEAVER_PIHOLE_URL=http://pihole:80 - DNSWEAVER_PIHOLE_PASSWORD_FILE=/run/secrets/pihole_password - DNSWEAVER_PIHOLE_RECORD_TYPE=A - DNSWEAVER_PIHOLE_TARGET=192.0.2.100 - DNSWEAVER_PIHOLE_DOMAINS=*.home.example.com ``` ### Response N/A (Configuration) ### Response Example N/A (Configuration) ``` -------------------------------- ### Configure MockServer for HTTP testing Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/testing/README.md Create a local HTTP server to mock API responses during provider testing. ```go server := testutil.NewMockServer(t) server.Handle("/api/zones/list", testutil.JSONResponse(200, zonesPayload)) defer server.Close() // Use server.URL as the provider API endpoint ``` -------------------------------- ### Prometheus Query Examples Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/observability.md Common PromQL queries for monitoring provider health, record operations, and system performance. ```promql # Provider health dnsweaver_provider_healthy # Providers still initializing dnsweaver_providers_pending > 0 # Record creation rate per provider rate(dnsweaver_records_created_total[5m]) # Failed record operations rate(dnsweaver_records_failed_total[5m]) # Provider API error rate rate(dnsweaver_provider_api_requests_total{status="error"}[5m]) # Provider API latency (p95) histogram_quantile(0.95, rate(dnsweaver_provider_api_duration_seconds_bucket[5m])) # Reconciliation success rate rate(dnsweaver_reconciliations_total{status="success"}[5m]) / rate(dnsweaver_reconciliations_total[5m]) # Hostname extraction rate by source rate(dnsweaver_hostnames_extracted_total[5m]) # Docker event rate by type rate(dnsweaver_docker_events_processed_total[5m]) ``` -------------------------------- ### Troubleshooting Commands Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/providers/webhook.md Commands to verify connectivity and authentication against the webhook endpoint. ```bash docker exec dnsweaver curl -v http://dns-api.internal/records ``` ```bash curl -H "Authorization: Bearer $(cat /run/secrets/api_token)" \ http://dns-api.internal/records ``` -------------------------------- ### Define Dashboard Panel JSON Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/observability.md Example JSON structure for a Grafana dashboard panel targeting the provider health metric. ```json { "panels": [ { "title": "Provider Health", "type": "stat", "targets": [ { "expr": "dnsweaver_provider_healthy" } ] } ] } ``` -------------------------------- ### Compare Exposed vs Secure Secret Configuration Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/configuration/secrets.md Demonstrates the difference between hardcoding a secret and using the _FILE suffix to reference a secret file. ```yaml environment: - DNSWEAVER_INTERNAL_DNS_TOKEN=my-secret-token # ❌ Exposed in environment ``` ```yaml environment: - DNSWEAVER_INTERNAL_DNS_TOKEN_FILE=/run/secrets/dns_token # ✅ Secure secrets: - dns_token ``` -------------------------------- ### Deploy dnsweaver with Kustomize Source: https://github.com/maxfield-allison/dnsweaver/blob/main/README.md Use this command to deploy dnsweaver to your Kubernetes cluster using Kustomize. ```bash # Using Kustomize kubectl apply -k https://github.com/maxfield-allison/dnsweaver/deploy/kustomize/base ``` -------------------------------- ### Check Readiness Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/observability.md Verify if the service is ready to process events. ```bash curl http://localhost:8080/ready ``` -------------------------------- ### Troubleshooting Commands Source: https://github.com/maxfield-allison/dnsweaver/blob/main/docs/sources/swarm.md Commands to verify service labels, node roles, and service logs. ```bash docker service inspect myapp --format '{{json .Spec.Labels}}' ``` ```bash docker node ls # Run from manager ``` ```bash docker service logs dnsweaver 2>&1 | grep -i "myapp" ```