feat(firewall-apply): gather peers with no cached facts and fail closed #10

Merged
claudiomaradonna merged 1 commit from feat/firewall-peer-facts into main 2026-09-25 20:21:52 +02:00

Why

A restricted firewall rule (swarm, gluster, ai-stack) derives its
sources from the facts of its from_group members. A member outside the
current play — the rest of a cluster under -e target=<host>, or every
other member while serial runs the first host alone — was read from the
fact cache, and one with nothing cached was silently filtered out. The
result was a chain rendered without the peers, cutting the host out of
its own cluster, unless someone had warmed the cache by hand first.

What changed

  • Before resolving a service's rules, firewall-apply gathers every peer
    with no facts (never gathered, or expired past fact_caching_timeout)
    through a read-only, delegated ansible.builtin.setup. The facts land in
    the per-inventory cache, so later batches and runs need no connection.
    It runs under --check too, so the preview shows the real table.
  • A peer that still has no facts fails the host before the render,
    naming every missing peer; the table already loaded stays as it was.
  • New firewall_apply_absent_peers (default [], pass with -e) names
    peers known to be down: they are neither gathered nor waited for, and
    the rules narrow to the peers that remain.
  • The manual warm-up procedure is removed from the swarm, gluster and No changes this session
    ai-stack READMEs and ADVANCED_USAGE.md; the firewall-apply README's
    "Peer addresses" section now owns the mechanism.

Behaviour change: a cluster member that is down and not listed in
firewall_apply_absent_peers now stops the run instead of being dropped
from the rules. In the first serial batch that ends the play for the
batches after it.

Verification

  • make check passes: lint at the production profile, syntax and all
    gates. The peers gate gains two cases: a peer with nothing cached is
    gathered and cached, and an unreachable peer fails the collect by name.
  • Not run: make test, make verify, make propagation (no podman in
    the environment used). Not yet run against a real inventory.

Risks and follow-ups

  • Before merging: make verify, then --check --diff --tags firewall with
    -e target=<one cluster member> against a real tenant. Expect the
    gather step for the other members and an unchanged peer chain.
  • One peer that stays down blocks the handbook for its cluster until it is
    back or passed in firewall_apply_absent_peers.
## Why A restricted firewall rule (`swarm`, `gluster`, `ai-stack`) derives its sources from the facts of its `from_group` members. A member outside the current play — the rest of a cluster under `-e target=<host>`, or every other member while `serial` runs the first host alone — was read from the fact cache, and one with nothing cached was silently filtered out. The result was a chain rendered without the peers, cutting the host out of its own cluster, unless someone had warmed the cache by hand first. ## What changed - Before resolving a service's rules, `firewall-apply` gathers every peer with no facts (never gathered, or expired past `fact_caching_timeout`) through a read-only, delegated `ansible.builtin.setup`. The facts land in the per-inventory cache, so later batches and runs need no connection. It runs under `--check` too, so the preview shows the real table. - A peer that still has no facts fails the host **before** the render, naming every missing peer; the table already loaded stays as it was. - New `firewall_apply_absent_peers` (default `[]`, pass with `-e`) names peers known to be down: they are neither gathered nor waited for, and the rules narrow to the peers that remain. - The manual warm-up procedure is removed from the swarm, gluster and No changes this session ai-stack READMEs and `ADVANCED_USAGE.md`; the firewall-apply README's "Peer addresses" section now owns the mechanism. Behaviour change: a cluster member that is down and not listed in `firewall_apply_absent_peers` now stops the run instead of being dropped from the rules. In the first `serial` batch that ends the play for the batches after it. ## Verification - `make check` passes: lint at the production profile, syntax and all gates. The `peers` gate gains two cases: a peer with nothing cached is gathered and cached, and an unreachable peer fails the collect by name. - Not run: `make test`, `make verify`, `make propagation` (no podman in the environment used). Not yet run against a real inventory. ## Risks and follow-ups - Before merging: `make verify`, then `--check --diff --tags firewall` with `-e target=<one cluster member>` against a real tenant. Expect the gather step for the other members and an unchanged peer chain. - One peer that stays down blocks the handbook for its cluster until it is back or passed in `firewall_apply_absent_peers`.
A restricted rule derives its sources from its group's facts, and a peer
outside the play with nothing cached was filtered out without a word: the
first batch of a cluster, or any run narrowed with -e target, rendered a
chain that shut the rest of the cluster out, unless the cache had been
warmed by hand first.

firewall-apply now gathers such peers itself, read-only through a
delegated setup that also caches them, under --check too. A peer that
still has no facts fails the host before the render, naming it, so the
loaded table stays as it was. firewall_apply_absent_peers, passed with -e,
names peers known to be down. The manual warm-up step is gone from the
docs; the firewall-apply README owns the mechanism.

The peers gate covers a gathered-and-cached peer and an unreachable one
that must fail the collect by name.
claudiomaradonna deleted branch feat/firewall-peer-facts 2026-09-25 20:21:57 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
claudiomaradonna/castrum!10
No description provided.