package main import ( "flag" "fmt" "io" "os" "github.com/wzray/dns/internal/client" ) const defaultServer = "http://localhost:8080" func main() { os.Exit(run(os.Args[1:], os.Stdout, os.Stderr)) } func run(args []string, stdout, stderr io.Writer) int { fs := flag.NewFlagSet("dns-cli", flag.ContinueOnError) fs.SetOutput(stderr) server := fs.String("server", envOr("DNS_SERVER_URL", defaultServer), "Base URL of the dns-server (env: DNS_SERVER_URL)") fs.Usage = func() { printRootUsage(stderr, fs) } if err := fs.Parse(args); err != nil { return 2 } rest := fs.Args() if len(rest) == 0 { printRootUsage(stderr, fs) return 2 } cmd, cmdArgs := rest[0], rest[1:] c := client.New(*server) switch cmd { case "help", "-h", "--help": printRootUsage(stdout, fs) return 0 case "list", "ls": return runList(c, cmdArgs, stdout, stderr) case "add": return runAdd(c, cmdArgs, stdout, stderr) case "remove", "rm", "delete": return runRemove(c, cmdArgs, stdout, stderr) default: fmt.Fprintf(stderr, "unknown command: %q\n\n", cmd) printRootUsage(stderr, fs) return 2 } } func runList(c *client.Client, args []string, stdout, stderr io.Writer) int { fs := flag.NewFlagSet("list", flag.ContinueOnError) fs.SetOutput(stderr) fs.Usage = func() { fmt.Fprintln(stderr, "Usage: dns-cli list") fmt.Fprintln(stderr, "\nList configured DNS nameservers.") } if err := fs.Parse(args); err != nil { return 2 } if fs.NArg() != 0 { fmt.Fprintln(stderr, "list: unexpected arguments") fs.Usage() return 2 } servers, err := c.List() if err != nil { fmt.Fprintf(stderr, "error: %v\n", err) return 1 } if len(servers) == 0 { fmt.Fprintln(stdout, "(no nameservers configured)") return 0 } for _, s := range servers { fmt.Fprintln(stdout, s) } return 0 } func runAdd(c *client.Client, args []string, stdout, stderr io.Writer) int { fs := flag.NewFlagSet("add", flag.ContinueOnError) fs.SetOutput(stderr) fs.Usage = func() { fmt.Fprintln(stderr, "Usage: dns-cli add
") fmt.Fprintln(stderr, "\nAdd a DNS nameserver (IPv4 or IPv6).") } if err := fs.Parse(args); err != nil { return 2 } if fs.NArg() != 1 { fmt.Fprintln(stderr, "add: exactly one
argument is required") fs.Usage() return 2 } addr := fs.Arg(0) if err := c.Add(addr); err != nil { fmt.Fprintf(stderr, "error: %v\n", err) return 1 } fmt.Fprintf(stdout, "added: %s\n", addr) return 0 } func runRemove(c *client.Client, args []string, stdout, stderr io.Writer) int { fs := flag.NewFlagSet("remove", flag.ContinueOnError) fs.SetOutput(stderr) fs.Usage = func() { fmt.Fprintln(stderr, "Usage: dns-cli remove
") fmt.Fprintln(stderr, "\nRemove a DNS nameserver. Aliases: rm, delete.") } if err := fs.Parse(args); err != nil { return 2 } if fs.NArg() != 1 { fmt.Fprintln(stderr, "remove: exactly one
argument is required") fs.Usage() return 2 } addr := fs.Arg(0) if err := c.Remove(addr); err != nil { fmt.Fprintf(stderr, "error: %v\n", err) return 1 } fmt.Fprintf(stdout, "removed: %s\n", addr) return 0 } func printRootUsage(w io.Writer, fs *flag.FlagSet) { fmt.Fprintln(w, "dns-cli — manage DNS nameservers on a remote host via the dns-server REST API.") fmt.Fprintln(w) fmt.Fprintln(w, "Usage:") fmt.Fprintln(w, " dns-cli [global flags] [args]") fmt.Fprintln(w) fmt.Fprintln(w, "Commands:") fmt.Fprintln(w, " list List configured DNS nameservers") fmt.Fprintln(w, " add
Add a DNS nameserver") fmt.Fprintln(w, " remove Remove a DNS nameserver (aliases: rm, delete)") fmt.Fprintln(w, " help Show this help") fmt.Fprintln(w) fmt.Fprintln(w, "Global flags:") fs.PrintDefaults() fmt.Fprintln(w) fmt.Fprintln(w, "Run 'dns-cli --help' for command-specific help.") } func envOr(key, def string) string { if v := os.Getenv(key); v != "" { return v } return def }