Add mcp dns and mcp node routes commands
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>
This commit is contained in:
@@ -26,8 +26,8 @@ type DNSRegistrar struct {
|
||||
logger *slog.Logger
|
||||
}
|
||||
|
||||
// dnsRecord is the JSON representation of an MCNS record.
|
||||
type dnsRecord struct {
|
||||
// DNSRecord is the JSON representation of an MCNS record.
|
||||
type DNSRecord struct {
|
||||
ID int `json:"ID"`
|
||||
Name string `json:"Name"`
|
||||
Type string `json:"Type"`
|
||||
@@ -136,8 +136,87 @@ func (d *DNSRegistrar) RemoveRecord(ctx context.Context, serviceName string) err
|
||||
return nil
|
||||
}
|
||||
|
||||
// DNSZone is the JSON representation of an MCNS zone.
|
||||
type DNSZone struct {
|
||||
Name string `json:"Name"`
|
||||
}
|
||||
|
||||
// ListZones returns all zones from MCNS.
|
||||
func (d *DNSRegistrar) ListZones(ctx context.Context) ([]DNSZone, error) {
|
||||
if d == nil {
|
||||
return nil, fmt.Errorf("DNS registrar not configured")
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/v1/zones", d.serverURL)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create list zones request: %w", err)
|
||||
}
|
||||
req.Header.Set("Authorization", "Bearer "+d.token)
|
||||
|
||||
resp, err := d.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list zones: %w", err)
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read list zones response: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("list zones: mcns returned %d: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
var envelope struct {
|
||||
Zones []DNSZone `json:"zones"`
|
||||
}
|
||||
if err := json.Unmarshal(body, &envelope); err != nil {
|
||||
return nil, fmt.Errorf("parse list zones response: %w", err)
|
||||
}
|
||||
return envelope.Zones, nil
|
||||
}
|
||||
|
||||
// ListZoneRecords returns all records in the given zone (no filters).
|
||||
func (d *DNSRegistrar) ListZoneRecords(ctx context.Context, zone string) ([]DNSRecord, error) {
|
||||
if d == nil {
|
||||
return nil, fmt.Errorf("DNS registrar not configured")
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("%s/v1/zones/%s/records", d.serverURL, zone)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create list zone records request: %w", err)
|
||||
}
|
||||
req.Header.Set("Authorization", "Bearer "+d.token)
|
||||
|
||||
resp, err := d.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list zone records: %w", err)
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read list zone records response: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("list zone records: mcns returned %d: %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
var envelope struct {
|
||||
Records []DNSRecord `json:"records"`
|
||||
}
|
||||
if err := json.Unmarshal(body, &envelope); err != nil {
|
||||
return nil, fmt.Errorf("parse list zone records response: %w", err)
|
||||
}
|
||||
return envelope.Records, nil
|
||||
}
|
||||
|
||||
// listRecords returns A records matching the service name in the zone.
|
||||
func (d *DNSRegistrar) listRecords(ctx context.Context, serviceName string) ([]dnsRecord, error) {
|
||||
func (d *DNSRegistrar) listRecords(ctx context.Context, serviceName string) ([]DNSRecord, error) {
|
||||
url := fmt.Sprintf("%s/v1/zones/%s/records?name=%s&type=A", d.serverURL, d.zone, serviceName)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
@@ -161,7 +240,7 @@ func (d *DNSRegistrar) listRecords(ctx context.Context, serviceName string) ([]d
|
||||
}
|
||||
|
||||
var envelope struct {
|
||||
Records []dnsRecord `json:"records"`
|
||||
Records []DNSRecord `json:"records"`
|
||||
}
|
||||
if err := json.Unmarshal(body, &envelope); err != nil {
|
||||
return nil, fmt.Errorf("parse list response: %w", err)
|
||||
|
||||
Reference in New Issue
Block a user