mcp dns queries MCNS via an agent to list all zones and DNS records. mcp node routes queries mc-proxy on each node for listener/route status, matching the mcproxyctl status output format. New agent RPCs: ListDNSRecords, ListProxyRoutes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"time"
|
|
|
|
mcpv1 "git.wntrmute.dev/mc/mcp/gen/mcp/v1"
|
|
"git.wntrmute.dev/mc/mcp/internal/config"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
func dnsCmd() *cobra.Command {
|
|
return &cobra.Command{
|
|
Use: "dns",
|
|
Short: "List all DNS zones and records from MCNS",
|
|
RunE: runDNS,
|
|
}
|
|
}
|
|
|
|
func runDNS(_ *cobra.Command, _ []string) error {
|
|
cfg, err := config.LoadCLIConfig(cfgPath)
|
|
if err != nil {
|
|
return fmt.Errorf("load config: %w", err)
|
|
}
|
|
|
|
// DNS is centralized — query the first reachable agent.
|
|
resp, nodeName, err := queryDNS(cfg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(resp.GetZones()) == 0 {
|
|
fmt.Println("no DNS zones configured")
|
|
return nil
|
|
}
|
|
|
|
_ = nodeName
|
|
for i, zone := range resp.GetZones() {
|
|
if i > 0 {
|
|
fmt.Println()
|
|
}
|
|
fmt.Printf("ZONE: %s\n", zone.GetName())
|
|
|
|
if len(zone.GetRecords()) == 0 {
|
|
fmt.Println(" (no records)")
|
|
continue
|
|
}
|
|
|
|
w := newTable()
|
|
_, _ = fmt.Fprintln(w, " NAME\tTYPE\tVALUE\tTTL")
|
|
for _, r := range zone.GetRecords() {
|
|
_, _ = fmt.Fprintf(w, " %s\t%s\t%s\t%d\n",
|
|
r.GetName(), r.GetType(), r.GetValue(), r.GetTtl())
|
|
}
|
|
_ = w.Flush()
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// queryDNS tries each configured agent and returns the first successful
|
|
// DNS listing. DNS is centralized so any agent with MCNS configured works.
|
|
func queryDNS(cfg *config.CLIConfig) (*mcpv1.ListDNSRecordsResponse, string, error) {
|
|
for _, node := range cfg.Nodes {
|
|
client, conn, err := dialAgent(node.Address, cfg)
|
|
if err != nil {
|
|
_, _ = fmt.Fprintf(os.Stderr, "warning: %s: %v\n", node.Name, err)
|
|
continue
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
|
resp, err := client.ListDNSRecords(ctx, &mcpv1.ListDNSRecordsRequest{})
|
|
cancel()
|
|
_ = conn.Close()
|
|
|
|
if err != nil {
|
|
_, _ = fmt.Fprintf(os.Stderr, "warning: %s: list DNS: %v\n", node.Name, err)
|
|
continue
|
|
}
|
|
|
|
return resp, node.Name, nil
|
|
}
|
|
|
|
return nil, "", fmt.Errorf("no reachable agent with DNS configured")
|
|
}
|