Files
mesh-catalog/modules/networkmanager/cmd/uplink-tools/manager.go
T
jochen c619a672a3
mesh/merge-gate pass: builds networkmanager, systemd-networkd, sent nowhere; no bus step; 4 wait(s) for a person; every machine composes with the change as…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group feat/node-uplink-verbs delivered: every member is delivered
Serve the uplink seat's verbs from both of its holders (hq ADR 0241)
What a machine resolves through had no tool: the resolver file and who
wrote it, and every link with its default route and the resolvers its
manager knows. Each holder serves the same two node-uplink verbs; the
reading is one text carried by both, held to it by a test, and only
asking the manager for a link's names is each holder's own.
2026-10-07 19:19:52 +02:00

53 lines
1.5 KiB
Go

package main
// NetworkManager's word on each link's names: `nmcli device show`, read in its terse form. A link
// NetworkManager does not manage — a tunnel a VPN client raised with `ip`, the mesh's own — is not in it,
// and the links verb says the link without what the manager does not know.
import (
"context"
"strings"
)
func managerDNS(ctx context.Context) (map[string]LinkDNS, error) {
out, err := execRunner(ctx, "nmcli", "-t", "-f", "GENERAL.DEVICE,GENERAL.STATE,IP4.DNS,IP6.DNS,IP4.DOMAIN,IP6.DOMAIN",
"device", "show")
if err != nil {
return nil, err
}
return parseNmcli(out), nil
}
// parseNmcli reads `nmcli -t device show`: blocks of KEY:value lines, one block per device.
func parseNmcli(out string) map[string]LinkDNS {
links := map[string]LinkDNS{}
device := ""
var cur LinkDNS
flush := func() {
if device != "" && (len(cur.Servers) > 0 || len(cur.Domains) > 0) {
cur.Manager = "NetworkManager"
links[device] = cur
}
device, cur = "", LinkDNS{}
}
for _, line := range strings.Split(out, "\n") {
key, value, ok := strings.Cut(strings.TrimSpace(line), ":")
if !ok {
continue
}
switch {
case key == "GENERAL.DEVICE":
flush()
device = value
case key == "GENERAL.STATE":
cur.State = value
case strings.HasPrefix(key, "IP4.DNS"), strings.HasPrefix(key, "IP6.DNS"):
cur.Servers = append(cur.Servers, value)
case strings.HasPrefix(key, "IP4.DOMAIN"), strings.HasPrefix(key, "IP6.DOMAIN"):
cur.Domains = append(cur.Domains, value)
}
}
flush()
return links
}