feat: the configuration that says which services run together (4.17.0) #47

Merged
christianmanivong merged 1 commits from feat/service-clusters into main 2026-10-18 13:32:33 +00:00
Owner

ServiceClustersMixin.get_service_clusters() reads the configuration that proves two hosts run one service together, not merely that they answer at one virtual IP. This is for NetOrk/netork#1125.

Mechanism What it reads Roles
Patroni scope, name and restapi.connect_address from its YAML, then /cluster (the members its DCS lists) leader / sync_standby / replica
adguardhome-sync ORIGIN_URL, REPLICA*_URL of its container origin → replicas
BunkerWeb a worker's API_WHITELIST_IP; a manager's BUNKERWEB_INSTANCES manager → workers

It uses the template form of VirtualIpsMixin: one sh -c command and one parser live here, and the driver only supplies _run_service_clusters_command.

On the host:

  • The awk programs print allowlisted fields only.
  • URLs lose their user:password@.
  • The DCS endpoints stay on the host.

Fallbacks:

  • The command runs as root first, then again without root.
  • None per mechanism means "did not look"; [] means "has none".

Tests: 34 new.

  • Parser tests for each mechanism.
  • The real command run with mawk, gawk and busybox awk against stub systemctl, docker and curl. The fixtures plant secrets (Patroni superuser, the sync's logins, a DB URI, a URL with userinfo) that must never appear in the output.
  • The full suite passes (720) and mypy --strict is clean.

Live check, read only: run through the linux driver on .50's hosts:

  • dns-01: origin 10.9.100.5:3000 → replica 10.9.100.6:3000.
  • proxy-02: worker of manager 10.50.100.5.
  • db-01 / db-02: scope netork-db, leader / sync_standby.
  • Only ORIGIN_URL, REPLICA1_URL and API_WHITELIST_IP left the hosts.

Version 4.17.0. napalm-linux mixes it in next.

`ServiceClustersMixin.get_service_clusters()` reads the configuration that proves two hosts run one service together, not merely that they answer at one virtual IP. This is for NetOrk/netork#1125. | Mechanism | What it reads | Roles | |---|---|---| | Patroni | `scope`, `name` and `restapi.connect_address` from its YAML, then `/cluster` (the members its DCS lists) | leader / sync_standby / replica | | adguardhome-sync | `ORIGIN_URL`, `REPLICA*_URL` of its container | origin → replicas | | BunkerWeb | a worker's `API_WHITELIST_IP`; a manager's `BUNKERWEB_INSTANCES` | manager → workers | It uses the template form of `VirtualIpsMixin`: one `sh -c` command and one parser live here, and the driver only supplies `_run_service_clusters_command`. **On the host:** - The awk programs print allowlisted fields only. - URLs lose their `user:password@`. - The DCS endpoints stay on the host. **Fallbacks:** - The command runs as root first, then again without root. - `None` per mechanism means "did not look"; `[]` means "has none". **Tests:** 34 new. - Parser tests for each mechanism. - The real command run with mawk, gawk and busybox awk against stub `systemctl`, `docker` and `curl`. The fixtures plant secrets (Patroni superuser, the sync's logins, a DB URI, a URL with userinfo) that must never appear in the output. - The full suite passes (720) and `mypy --strict` is clean. **Live check, read only:** run through the linux driver on .50's hosts: - dns-01: origin 10.9.100.5:3000 → replica 10.9.100.6:3000. - proxy-02: worker of manager 10.50.100.5. - db-01 / db-02: scope netork-db, leader / sync_standby. - Only `ORIGIN_URL`, `REPLICA1_URL` and `API_WHITELIST_IP` left the hosts. Version 4.17.0. napalm-linux mixes it in next.
christianmanivong added 1 commit 2026-10-18 13:28:45 +00:00
feat: the configuration that says which services run together (4.17.0)
CI / test (3.10) (push) Successful in 29s
CI / test (3.11) (push) Successful in 24s
CI / test (3.12) (push) Successful in 27s
CI / test (3.13) (push) Successful in 27s
CI / test (3.10) (pull_request) Successful in 26s
CI / test (3.11) (pull_request) Successful in 25s
CI / test (3.12) (pull_request) Successful in 27s
CI / test (3.13) (pull_request) Successful in 26s
2bd7bcc77c
ServiceClustersMixin.get_service_clusters() -> ServiceClustersDict
{patroni, adguardhome_sync, bunkerweb}: per mechanism the clusters the
host's configuration says it belongs to, each with its members (address,
port, name, role as the mechanism words it, this_host, config_from) and the
unit or container it was read from (source).

- Patroni: scope, name and restapi.connect_address from its YAML, then the
  members and roles /cluster lists from the DCS.
- adguardhome-sync: ORIGIN_URL and REPLICA*_URL; the origin pushes to each
  replica.
- BunkerWeb: a worker's API_WHITELIST_IP names the manager it admits, a
  manager's BUNKERWEB_INSTANCES its workers.

Two hosts answering at one virtual IP prove nothing; this is the evidence
that they run one service (NetOrk/netork#1125). One generic command for
every Linux host, filtered on the host like the virtual IPs' one:
allowlisted fields only, URLs without user:password@, DCS endpoints stay
there. Root first, then without it; None per mechanism is "did not look".
christianmanivong merged commit a0e70d1686 into main 2026-10-18 13:32:33 +00:00
christianmanivong deleted branch feat/service-clusters 2026-10-18 13:32:33 +00:00
Sign in to join this conversation.