# dns-sync modular A plugin-based DNS reconciliation service. ## Plugin contract Source modules live under `dns_sync/plugins/sources/` and export a class named `Plugin` with: - `name` - `discover() -> list[DesiredRecord]` Provider modules live under `dns_sync/plugins/providers/` and export `Plugin` with: - `name` - `capabilities` - `connect()` - `list_records()` - `add_record()` - `update_record()` - `delete_record()` - `verify_record()` - `capacity()` Plugins are convention-loaded from environment variables. No registry edit is needed: - `PROXY=npm` loads `dns_sync.plugins.sources.npm.Plugin` - `DNS_PROVIDER=verizon` loads `dns_sync.plugins.providers.verizon.Plugin` ## Current plugins Sources: `npm`, `file` Providers: `verizon` ## Main environment ```text PROXY=npm PROXY_IP=192.168.1.101 PROXY_API_PORT=81 PROXY_API_SCHEME=http DNS_PROVIDER=verizon DOMAIN_MATCHING=false DOMAIN=example.com SYNC_INTERVAL=1 NPM_IDENTITY=... NPM_SECRET=... ROUTER_PASSWORD=... ``` `DNS_TARGET_IP` optionally overrides the default DNS destination, which is `PROXY_IP`. ## Domain filtering Filtering is performed by the central engine after source discovery and before reconciliation, so all source plugins get identical behavior. ```text DOMAIN_MATCHING=true DOMAIN=example.com ``` This includes the apex and every subdomain: ```text example.com app.example.com deep.app.example.com *.example.com ``` It excludes unrelated names such as: ```text example.net notexample.com example.com.evil.net ``` When `DOMAIN_MATCHING=false`, `DOMAIN` is ignored and all discovered records are eligible for reconciliation. When `DOMAIN_MATCHING=true`, `DOMAIN` is required.