CLI Contract: dns-helper
Feature Branch: 001-safety-reliability-refactor
Date: 2026-03-03
Overview
dns-helper is a single-binary CLI tool that updates the local hosts file with DNS entries resolved from a user-specified DNS server. It exposes three subcommands: add, delete, and a usage/help display on invalid input.
Binary Name
Global Behavior
- Prints banner on every invocation:
DNSHelper v1.0, Copyright (c) 2024 Emberkom LLC, blank line.
- All error messages are printed to stderr.
- Informational output (banner, summaries, warnings) is printed to stdout.
- Exit code
0 on full success. Non-zero on any error or partial failure.
Subcommand: add (aliases: a)
Synopsis
Flags
| Flag |
Required |
Type |
Description |
-host |
Yes |
string |
Comma-separated list of hostnames to resolve and add |
-server |
Yes |
string |
DNS server to use for resolution (hostname or IP) |
Behavior
- Validates that both
-host and -server are provided and non-empty.
- Resolves each hostname against the specified DNS server (follows CNAME chains, deduplicates IPs).
- Acquires lock file.
- Reads the current hosts file and parses the managed block.
- Removes any existing managed entries for the specified hostnames.
- Adds new entries for all successfully resolved hostnames.
- Writes the updated hosts file atomically (temp file + rename, with pre-write backup).
- Releases lock file.
- Prints summary of changes.
Output — Success (exit 0)
Output — Partial Failure (exit 1)
Output — Validation Error (exit 1)
Exit Codes
| Code |
Meaning |
| 0 |
All hostnames resolved and written successfully |
| 1 |
Any error: validation failure, DNS failure, file write failure, partial resolution |
Subcommand: delete (aliases: d, del)
Synopsis
Flags
| Flag |
Required |
Type |
Description |
-host |
Yes* |
string |
Comma-separated list of hostnames to remove (*not required when using all) |
Behavior — Delete Specific Hosts
- Validates that
-host is provided and non-empty.
- Acquires lock file.
- Reads the current hosts file and parses the managed block.
- Removes all managed entries matching the specified hostnames.
- Writes the updated hosts file atomically.
- Releases lock file.
- Prints summary.
Behavior — Delete All
- Acquires lock file.
- Reads the current hosts file and parses the managed block.
- Removes the entire managed block (start marker through end marker).
- Writes the updated hosts file atomically.
- Releases lock file.
- Prints summary.
Output — Success (exit 0)
Output — No Entries Found (exit 0)
Output — Delete All (exit 0)
Exit Codes
| Code |
Meaning |
| 0 |
Deletion completed (or no entries to delete) |
| 1 |
Error: validation failure, file write failure, corrupt managed block |
Invalid / No Subcommand
Synopsis
Behavior
- Prints usage information to stdout.
- Does not modify the hosts file.
- Exits with code 1.
Output (exit 1)
Error Conditions
| Condition |
Message (stderr) |
Exit Code |
Hosts File Modified? |
| No subcommand |
Usage text (stdout) |
1 |
No |
| Unknown subcommand |
Usage text (stdout) |
1 |
No |
Missing -host (add) |
Error: -host flag is required for the add command |
1 |
No |
Missing -server (add) |
Error: -server flag is required for the add command |
1 |
No |
Empty -host value |
Error: -host flag is required for the add command |
1 |
No |
| DNS resolution failure (all hosts) |
Error: failed to resolve <host>: <reason> |
1 |
No |
| DNS resolution partial failure |
Warning per host + entries for successful hosts written |
1 |
Yes (partial) |
| Hosts file not found |
Error: file does not exist: <path> |
1 |
No |
| Permission denied |
Error: permission denied: <path> |
1 |
No |
| Corrupt managed block |
Error: managed block is corrupt: <details> |
1 |
No |
| Lock file unavailable |
Error: could not acquire lock file <path>: another instance may be running |
1 |
No |
| Write failure |
Error: writing hosts file: <details> |
1 |
No (atomic write) |
Hosts File Managed Block Format
- Start marker:
# DNSHelper <<-> START CONFIG
- End marker:
# DNSHelper <->> END CONFIG
- Each entry:
<IPv4>\t<hostname> (tab-separated)
- Entries are deduplicated by full line content.
- Block is omitted entirely when there are no managed entries.