Skip to content

Validate PostgreSQL databases owned by a declared role (#121) - #131

Merged
shipmill-romamo[bot] merged 2 commits into
mainfrom
feat/121-owned-postgresql-validation
Oct 27, 2026
Merged

shipmill-romamo[bot] merged 2 commits into
mainfrom
feat/121-owned-postgresql-validation

Conversation

@shipmill-romamo

Copy link
Copy Markdown
Contributor

Summary

Schema and config validate part of S-006 (standalone PostgreSQL). A PostgreSQL Service database may name an owner role and its passwordRef (environment, path, key) instead of an application. A project of one Server, its server type, and such a Service, with no Application or Component, now validates. spec.postgresql.remoteAccess (listenAddress, allowedSources) is accepted and checked.

  • config/schemas/v1/service.schema.json: a database entry takes exactly one of application or owner (oneOf); owner requires passwordRef (dependentRequired); application forbids passwordRef (dependentSchemas). remoteAccess takes one IPv4 or IPv6 listen address (wildcards refused) and a non-empty list of sources
  • sdk/src/cloudfall/validation.py: service_database_owner_reserved for postgres, alloy, or the Linux user of an Application with a database on the same service; service_remote_access_unused, service_remote_access_unfirewalled, service_remote_access_port_open, service_remote_access_open, plus service_remote_access_source_invalid for a source that isn't a canonical CIDR. The changes stay inside the service validators (the PostgreSQL part moved into _validate_postgresql_service)
  • sdk/src/cloudfall/inventory.py: new OwnedPostgresDatabase (name, owner, SecretValueReference) and PostgresRemoteAccess. The model holds the reference only, never a password value. An owned database renders name, owner, passwordRef with no application key
  • sdk/src/cloudfall/domain.py: new value objects PostgresRoleName, SecretKeyName, IpNetworkCidr

Converging these declarations is #122. Until it lands, the cloudfall_postgresql role's argument spec refuses an owned database or remoteAccess before any task runs. I checked this against the rendered inventory with Ansible's ArgumentSpecValidator: it reports "missing required arguments: application" and unsupported passwordRef and remoteAccess.

Test plan

  • New sdk/tests/test_owned_postgresql.py: one test per criterion S-006-1, 2, 3, 4 and 11, plus tests for rendering, an owner whose name matches an application user on another server, a non-canonical source, and wildcard listen addresses
  • uv run ruff check ., uv run mypy, uv run cloudfall config validate --project config/examples: all pass
  • sdk/tests/test_validation.py, test_inventory.py, test_data_migration.py, test_migrate.py, engine/tests/test_ansible_inventory.py, test_postgresql_templates.py: 68 passed
  • cloudfall-engine inventory render --project config/examples writes a byte-identical file on this branch and on origin/main (cmp). That is the inventory half of S-006-12; its test is Converge owned PostgreSQL databases with their role and password (S-006-5, 6, 7, 12, 13) #122's
  • Full suite left to CI

Fixes #121

Plan

  • Serves: quality bar
  • Files: config/schemas/v1/service.schema.json, sdk/src/cloudfall/domain.py, sdk/src/cloudfall/inventory.py, sdk/src/cloudfall/validation.py, sdk/tests/test_owned_postgresql.py, changelog.d/121-owned-postgresql-validation.md
  • Order: tests for S-006-1/2/3/4/11 first, then the schema, value objects, inventory model, and service validation
  • Proof: S-006-1, S-006-2, S-006-3, S-006-4, S-006-11 (specs.py coverage --spec 006); byte-identical example inventory render

🤖 Generated with Claude Code

shipmill-romamo Bot and others added 2 commits October 27, 2026 10:27
A PostgreSQL Service database may now name an owner role and its
passwordRef instead of an application, so a team can declare only its
database. The schema takes exactly one of application or owner, owner
needs passwordRef, and remoteAccess declares a listen address and
allowed sources. config validate refuses reserved owners and a
remoteAccess that serves no owner, has no firewall, finds the port
already open, or allows every address.

The inventory models the reference, never a value. Configs that
validated before render byte-identical. Converging the role is #122:
until then the PostgreSQL role's argument spec refuses an owned
database or remoteAccess before any task runs.

Fixes #121

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The schema refused only the literal 0.0.0.0 and ::, so ::0 or
0:0:0:0:0:0:0:0 passed config validate as a listen address, and a
non-canonical IPv6 address passed validate but crashed the inventory
render on IpAddress. Validate the address through IpAddress and refuse
an unspecified one with service_remote_access_listen_invalid.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@shipmill-romamo
shipmill-romamo Bot force-pushed the feat/121-owned-postgresql-validation branch from 6144007 to 375f12a Compare October 27, 2026 08:39
@shipmill-romamo

Copy link
Copy Markdown
Contributor Author

@romamo Decided without waiting: owned-database validation adds two codes the spec doesn't name, service_remote_access_source_invalid (an allowed source that isn't a canonical CIDR, such as 10.0.0.1/24) and service_remote_access_listen_invalid (a wildcard listen address in any spelling, such as ::0, or a non-canonical one).

Why: S-006-8 and S-006-11 rule out open access; without these, ::0 slipped past the :: check and a non-canonical address crashed the inventory render. The "both or neither" rules of S-006-2 and S-006-3 are refused by the schema, with the field written spec.postgresql.databases.0 as every other field path in the repo is.
Not taken: accepting non-canonical forms and normalising them, which would store a different value than the operator wrote.

Reply with a comment starting with veto before 2026-10-28 08:45 UTC to reverse it, adding what you want instead if you like. A later veto still counts and gets a follow-up.

@shipmill-romamo shipmill-romamo Bot added the decided An agent decided at notify; the maintainer may veto label Oct 27, 2026
@shipmill-romamo
shipmill-romamo Bot merged commit 987ae9c into main Oct 27, 2026
1 check passed
@shipmill-romamo
shipmill-romamo Bot deleted the feat/121-owned-postgresql-validation branch October 27, 2026 08:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

decided An agent decided at notify; the maintainer may veto

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Validate PostgreSQL databases owned by a declared role (S-006-1..4, S-006-11)

0 participants