Scaffold the tomswallapi control plane #1

Merged
benvin merged 5 commits from benvin/scaffold-control-plane into main 2026-07-19 21:39:28 +10:00
Owner

Why

tomswallapi is the fleet control plane for tomswall: declare zones, address groups, and firewall policy once, and the API compiles each intent into the per-device rules every firewall and router on the path needs, serving each device its rendered config. This lands the initial service so the model, storage, and compiler can be iterated on.

Changes

  • Scaffold the Go service (chi + pgx + slog), matching house style: distroless Dockerfile, Makefile with make patch|minor|major release tags, Woodpecker pre-commit/test/build/docker pipelines, docker-compose, pre-commit config, README.
  • Add the domain model and the shorewall-style zone:+ipset/&fqdn source/dest grammar (bare zones allowed, bare selectors rejected).
  • Add the Postgres storage layer (pgx repository) with embedded auto-migrations and CRUD for zones, address groups, portgroups, rules, policies, fabrics, devices, and bindings; every mutation bumps a global config generation.
  • Add the compiler that projects the global model through a device's bindings into an interface-agnostic (saddr/daddr, no iif/oif) rendered config, ECMP-safe: firewalls always enforce, routers enforce only when their fabric opts in; referenced address groups are emitted as named sets.
  • Serve GET /devices/{name}/config as generation-stamped YAML for agents, plus a device status-report endpoint; guard mutations and the agent endpoint with bearer tokens.
  • Add unit tests for the grammar parser and the compiler (enforcement gating, ASN set emission, resolver precedence).
## Why tomswallapi is the fleet control plane for tomswall: declare zones, address groups, and firewall policy once, and the API compiles each intent into the per-device rules every firewall and router on the path needs, serving each device its rendered config. This lands the initial service so the model, storage, and compiler can be iterated on. ## Changes - Scaffold the Go service (chi + pgx + slog), matching house style: distroless Dockerfile, Makefile with `make patch|minor|major` release tags, Woodpecker pre-commit/test/build/docker pipelines, docker-compose, pre-commit config, README. - Add the domain model and the shorewall-style `zone:+ipset`/`&fqdn` source/dest grammar (bare zones allowed, bare selectors rejected). - Add the Postgres storage layer (pgx repository) with embedded auto-migrations and CRUD for zones, address groups, portgroups, rules, policies, fabrics, devices, and bindings; every mutation bumps a global config generation. - Add the compiler that projects the global model through a device's bindings into an interface-agnostic (saddr/daddr, no iif/oif) rendered config, ECMP-safe: firewalls always enforce, routers enforce only when their fabric opts in; referenced address groups are emitted as named sets. - Serve `GET /devices/{name}/config` as generation-stamped YAML for agents, plus a device status-report endpoint; guard mutations and the agent endpoint with bearer tokens. - Add unit tests for the grammar parser and the compiler (enforcement gating, ASN set emission, resolver precedence).
unkinben added 5 commits 2026-07-19 21:19:52 +10:00
Add the store package (pgx-backed repository) with CRUD for the core resources
the compiler needs: fabrics, zones, address groups, portgroups, devices,
bindings, rules, policies. Every mutation bumps a global config generation.
Wire real JSON CRUD handlers with token auth, source/dest grammar validation on
rule create, and the agent status-report endpoint. Migration 0001 verified
against Postgres 17.
Project the fleet-global model through a device's bindings into a rendered,
interface-agnostic config: rules compile to saddr/daddr forward matches with no
iif/oif so they are correct under FRR/ECMP. Firewalls always enforce; routers
enforce only when their fabric opts into defense-in-depth. Referenced address
groups are emitted as named sets carrying their source (static CIDRs, dns FQDNs,
or asn numbers) so membership churns out-of-band without a rule reload. Wire
GET /devices/{name}/config to compile and serve YAML, generation-stamped. Add
portgroups/policies/settings store methods and portgroup CRUD. Pure Render is
unit-tested for enforcement gating, ASN set emission, and resolver precedence.
Merge Gitea repo initialization
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
3fb55d5899
benvin merged commit 91f84434e1 into main 2026-07-19 21:39:28 +10:00
Sign in to join this conversation.