230 lines
6.4 KiB
Markdown
230 lines
6.4 KiB
Markdown
# 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
|
||
|
|
|
||
|
|
```
|
||
|
|
dns-helper[.exe]
|
||
|
|
```
|
||
|
|
|
||
|
|
## 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
|
||
|
|
|
||
|
|
```
|
||
|
|
dns-helper add -host <hostnames> -server <dns-server>
|
||
|
|
```
|
||
|
|
|
||
|
|
### 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
|
||
|
|
|
||
|
|
1. Validates that both `-host` and `-server` are provided and non-empty.
|
||
|
|
2. Resolves each hostname against the specified DNS server (follows CNAME chains, deduplicates IPs).
|
||
|
|
3. Acquires lock file.
|
||
|
|
4. Reads the current hosts file and parses the managed block.
|
||
|
|
5. Removes any existing managed entries for the specified hostnames.
|
||
|
|
6. Adds new entries for all successfully resolved hostnames.
|
||
|
|
7. Writes the updated hosts file atomically (temp file + rename, with pre-write backup).
|
||
|
|
8. Releases lock file.
|
||
|
|
9. Prints summary of changes.
|
||
|
|
|
||
|
|
### Output — Success (exit 0)
|
||
|
|
|
||
|
|
```
|
||
|
|
DNSHelper v1.0
|
||
|
|
Copyright (c) 2024 Emberkom LLC
|
||
|
|
|
||
|
|
Added 3 entries for host1.example.com
|
||
|
|
Added 2 entries for host2.example.com
|
||
|
|
```
|
||
|
|
|
||
|
|
### Output — Partial Failure (exit 1)
|
||
|
|
|
||
|
|
```
|
||
|
|
DNSHelper v1.0
|
||
|
|
Copyright (c) 2024 Emberkom LLC
|
||
|
|
|
||
|
|
Added 3 entries for host1.example.com
|
||
|
|
Warning: failed to resolve host2.example.com: NXDOMAIN
|
||
|
|
```
|
||
|
|
|
||
|
|
### Output — Validation Error (exit 1)
|
||
|
|
|
||
|
|
```
|
||
|
|
DNSHelper v1.0
|
||
|
|
Copyright (c) 2024 Emberkom LLC
|
||
|
|
|
||
|
|
Error: -host flag is required for the add command
|
||
|
|
```
|
||
|
|
|
||
|
|
### 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
|
||
|
|
|
||
|
|
```
|
||
|
|
dns-helper delete -host <hostnames>
|
||
|
|
dns-helper delete all
|
||
|
|
```
|
||
|
|
|
||
|
|
### Flags
|
||
|
|
|
||
|
|
| Flag | Required | Type | Description |
|
||
|
|
|------|----------|------|-------------|
|
||
|
|
| `-host` | Yes* | string | Comma-separated list of hostnames to remove (*not required when using `all`) |
|
||
|
|
|
||
|
|
### Behavior — Delete Specific Hosts
|
||
|
|
|
||
|
|
1. Validates that `-host` is provided and non-empty.
|
||
|
|
2. Acquires lock file.
|
||
|
|
3. Reads the current hosts file and parses the managed block.
|
||
|
|
4. Removes all managed entries matching the specified hostnames.
|
||
|
|
5. Writes the updated hosts file atomically.
|
||
|
|
6. Releases lock file.
|
||
|
|
7. Prints summary.
|
||
|
|
|
||
|
|
### Behavior — Delete All
|
||
|
|
|
||
|
|
1. Acquires lock file.
|
||
|
|
2. Reads the current hosts file and parses the managed block.
|
||
|
|
3. Removes the entire managed block (start marker through end marker).
|
||
|
|
4. Writes the updated hosts file atomically.
|
||
|
|
5. Releases lock file.
|
||
|
|
6. Prints summary.
|
||
|
|
|
||
|
|
### Output — Success (exit 0)
|
||
|
|
|
||
|
|
```
|
||
|
|
DNSHelper v1.0
|
||
|
|
Copyright (c) 2024 Emberkom LLC
|
||
|
|
|
||
|
|
Removed 3 entries for host1.example.com
|
||
|
|
```
|
||
|
|
|
||
|
|
### Output — No Entries Found (exit 0)
|
||
|
|
|
||
|
|
```
|
||
|
|
DNSHelper v1.0
|
||
|
|
Copyright (c) 2024 Emberkom LLC
|
||
|
|
|
||
|
|
No managed entries found for host1.example.com
|
||
|
|
```
|
||
|
|
|
||
|
|
### Output — Delete All (exit 0)
|
||
|
|
|
||
|
|
```
|
||
|
|
DNSHelper v1.0
|
||
|
|
Copyright (c) 2024 Emberkom LLC
|
||
|
|
|
||
|
|
Removed all managed entries (5 entries removed)
|
||
|
|
```
|
||
|
|
|
||
|
|
### 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
|
||
|
|
|
||
|
|
```
|
||
|
|
dns-helper
|
||
|
|
dns-helper <invalid-subcommand>
|
||
|
|
```
|
||
|
|
|
||
|
|
### Behavior
|
||
|
|
|
||
|
|
1. Prints usage information to stdout.
|
||
|
|
2. Does **not** modify the hosts file.
|
||
|
|
3. Exits with code 1.
|
||
|
|
|
||
|
|
### Output (exit 1)
|
||
|
|
|
||
|
|
```
|
||
|
|
DNSHelper v1.0
|
||
|
|
Copyright (c) 2024 Emberkom LLC
|
||
|
|
|
||
|
|
This utility will update the local hosts file with DNS entries obtained by the specified DNS server.
|
||
|
|
Usage: dns-helper [add|delete] -host hostname [-server dns.example.com]
|
||
|
|
Example:
|
||
|
|
dns-helper add -host xyz.acme.com -server dns.example.com
|
||
|
|
This will use dns.example.com to find and add all IP addresses for xyz.acme.com to the local hosts file.
|
||
|
|
dns-helper delete -host hostname.example.com
|
||
|
|
This will delete all entries for hostname.example.com from the local hosts file.
|
||
|
|
dns-helper delete all
|
||
|
|
This will delete all entries from the local hosts file that were added by this utility.
|
||
|
|
Note: Adding a hostname will first remove all entries in the hosts file that match the same hostname.
|
||
|
|
This utility will only remove entries from the hosts file that it added.
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 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
|
||
|
|
|
||
|
|
```
|
||
|
|
# DNSHelper <<-> START CONFIG
|
||
|
|
1.2.3.4 hostname1.example.com
|
||
|
|
5.6.7.8 hostname1.example.com
|
||
|
|
9.10.11.12 hostname2.example.com
|
||
|
|
# DNSHelper <->> END CONFIG
|
||
|
|
```
|
||
|
|
|
||
|
|
- 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.
|