Repository navigation
Apply one Domain on its proxy server with cloudfall domains apply (#117) - #137
Merged
Merged
Conversation
Contributor
Author
|
@romamo Decided without waiting: Why: S-004-1, 3, 5..10 ask for this command; every existing command behaves as before. Reply with a comment starting with |
cloudfall domains apply <domain> [--issue-certificate] [--yes] runs domains.yml limited to the Domain's proxy server and to that Domain, so no baseline, firewall or service task runs. Without --yes it answers a plan after every controller-side check. --issue-certificate refuses tls.mode: disabled, and checks on the controller that the primary name and every alias resolve to the proxy server (domains_dns_unverified); a proxied Domain skips the check. The resolver is a protocol passed to the lifecycle calls, so tests answer DNS offline. migrate's dns-verify shares the proxy address computation. Fixes #117 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
migrate goes back to its own address computation: any OSError from the server hostname lookup counts as no address, and a scoped link-local address is kept as written. Tests pin both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The server schema accepts any IPv6 spelling (2001:DB8::10), but IpAddress requires canonical notation, so --issue-certificate crashed with a ValueError instead of running the DNS check. Canonicalise the parsed address before building the expected set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
shipmill-romamo
Bot
force-pushed
the
feat/117-domains-apply
branch
from
October 27, 2026 10:18
ad995db to
51c8193
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements the
domains applypart of S-004 (docs/specs/004-domains-apply.md): criteria S-004-1, 3, 5, 6, 7, 8, 9 and 10.domains observeand the MCP tools (S-004-4, 14, 15, 16) stay with #118, so the spec is not marked built.domainsgroup withcloudfall domains apply <domain> [--issue-certificate] [--deployments DIR] [--yes], modeled ondeploy: the project is validated first (CONFIG_INVALID), an unknown id exitsPRECONDITION(lifecycle_domain_missing), and both refusals come before the inventory render--yesit runsdomains.ymlwith--limit <proxy.server>andcloudfall_domains_domain_id, the one-Domain run Converge one Domain in domains.yml and record the previous vhost hash (S-004-2, 11, 12, 13, 17) #116 added, and answersstatus: "ok",action: "domains-apply",domain,servers,receiptandeffect: "updated". A run that writes no receipt is refused (lifecycle_receipt_missing), asdeploydoes. Without--yesit answers the plan (status: "plan",would_run,instruction,effect: "would_update") after running every controller-side check, the DNS check included--issue-certificaterefusestls.mode: disabled(PRECONDITION,domains_tls_disabled) before anything else. On adns-onlyDomain it then requires the primary name and every alias to resolve to at least one address of the proxy server (PRECONDITION,domains_dns_unverified, naming each failing name and what it resolved to), then passescloudfall_domains_issue_certificates: true. AproxiedDomain skips the check (dns_check: "skipped-proxied"); a checked one answers"verified"; without the flagdns_checkisnullNameResolverprotocol passed intopreview_domain_apply/apply_domain(SystemNameResolveron the CLI,getaddrinfo), so tests answer DNS offline without monkeypatching.lifecycle.proxy_addressescomputes the proxy address set the way migrate'sdns-verifydoes (server address or what its hostname resolves to, plusnetwork.ipv4);migrateitself is unchanged and keeps its own codedomains applyis aserverscommand gated by--yes; output keysdomainanddnsCheckare added (additive).sdk/README.mdnames the commandFixes #117
Test plan
sdk/tests/test_domains_apply.py:apply_domainruns the realdomains.ymlunderansible-playbookagainst the rendered inventory of the examples (servers h1, h2; crm-site proxied on h2), every host on a local connection andcloudfall_nginx_siteswapped throughANSIBLE_ROLES_PATHfor a recorder. The play recap lists only h2, every task that ran belongs todomains.ymlor the stub, the stub sawcloudfall_nginx_site_issue_certificateas asked, and the receipt is written. A static check holdsdomains.ymlto the oneinclude_roleofcloudfall_nginx_site, with noroles/import_playbook, and the role to no dependencies or nested role includescloudfall.cli.main: plan output,CONFIG_INVALIDwith and without--yes, proxied--issue-certificateplan,domains_tls_disabledwith and without--yes; none renders the inventory or writes a receipt. An unknown id exitslifecycle_domain_missingtoo--yes), with no step run; proxied asks no resolver; TLS disabled is refused before DNS; the certificate run passes--limit h2and the extra vars and answersdnsCheck: "verified"and the receiptengine/tests/test_domains_certificate.py: Templar replays of the role'swhenconditions (issuance runs on a fresh Domain and is skipped oncefullchain.pemexists;certbot.timeris enabled either way), and the role's receipt tasks run for real twice on localhost: the second receipt'sconfigurationSha256equals itspreviousConfigurationSha256(S-004-10)sdk/tests/test_commands.py:domains applyjoins the--yes-gated setsdk/tests/test_migrate.py: pins migrate'sdns-verifyaddresses as on main: an unresolvable server hostname (.invalid) adds no address and raises nothing, and a scoped link-local address (fe80::1%eth0) is kept as writtenuv run ruff check .,uv run mypy,uv run cloudfall config validate --project config/examples, and the tests of the touched and neighbouring files (test_domains_apply,test_commands,test_migrate,test_domains_converge,test_lifecycle,test_project,test_app,test_agent_server,test_catalog,test_arguments,test_domains_certificate,test_domains_one_domain: 153 passed). No Ansible file changed, so ansible-lint was not needed. The full suite is left to CIfullchain.pempresent andcertbot.timeractive on a Debian host (S-004-9), and the second run's actual skip ofIssue the declared certificateagainst a real certificate (S-004-10); the realSystemNameResolveragainst public DNSPlan
domains applycommand and catalog entry, tests per criterion (see the spec's Behaviour)specs.py coverage --spec 004; S-004-4, 14, 15, 16 stay with Add cloudfall domains observe and the domains MCP tools (S-004-4, 14, 15, 16) #118)🤖 Generated with Claude Code