Add Keystone-on-kind integration test (forge)#294
Draft
berendt wants to merge 6 commits into
Draft
Conversation
e9961b9 to
3c6f403
Compare
Stand up a kind cluster with a Keystone-only forge ControlPlane and emit an ephemeral clouds.yaml for the admin cloud. forge is pinned to a known-good commit and its own installer provides the pinned kind/kubectl toolchain. create.py indexes its role cache directly, so it aborts on a bare Keystone that lacks load-balancer_member (Octavia normally provisions it). Pre-create the roles create.py expects, keeping create.py itself untouched. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Christian Berendt <berendt@osism.tech>
run.sh deploys Keystone, runs the real `tox -e create` path as admin with --nodomain-name-prefix so the project is named exactly opm-integration-test, then asserts it with verify.py. A trap tears down the kind cluster on every exit path but only when this run created it, dumping diagnostics first on failure. verify.py is a standalone openstacksdk script -- not named test_*.py -- so `tox -e test` does not collect it. tox passes OS_CLIENT_CONFIG_FILE through to the create env, and the generated clouds.yaml is gitignored. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Christian Berendt <berendt@osism.tech>
integration runs the full provision/create/verify/teardown cycle; integration-up deploys Keystone and leaves the cluster running for local debugging; integration-down deletes the kind cluster. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Christian Berendt <berendt@osism.tech>
pre-integration.yml prepares an IPv6-only Zuul node: the ensure-pip / ensure-pipenv / ensure-docker roles, the libldap/libsasl build deps the create env needs, and the accept_ra=2 sysctl fix that keeps RAs honoured once kind enables IPv6 forwarding. The pinned kind/kubectl toolchain comes from forge's install-test-deps, invoked by deploy_keystone.sh. test-integration.yml installs tox and openstacksdk into a venv and runs make integration from the checkout. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Christian Berendt <berendt@osism.tech>
openstack-project-manager-integration runs on ubuntu-noble with a 2400s timeout. It is added to the check pipeline so the kind+Keystone job runs on every change. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Christian Berendt <berendt@osism.tech>
Cover prerequisites, the make targets, the environment overrides, what verify.py asserts, and the ephemeral-credentials handling. Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Christian Berendt <berendt@osism.tech>
3c6f403 to
2693744
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
Adds the first integration test for
openstack-project-manager: it deploys a live, Keystone-only Keystone on a kind cluster via forge, then drives the realtox -e createpath as the admin account to create one project and asserts the result through the OpenStack SDK. This is the first thing in the repo that exercises a realopenstack.connect()/keystonepath instead of the mocks used bytest/unit/.Closes #293
Change set (in commit order)
68776e6Add forge Keystone deploy script and ControlPlane CRtest/integration/controlplane.yaml: a Keystone-only forgeControlPlaneCR (release2025.2, single replica, exposed atkeystone.127-0-0-1.nip.io:8443/v3via theopenstack-gwgateway).test/integration/deploy_keystone.sh: clones forge pinned to a known-good commit (FORGE_REF), uses forge's owninstall-test-depsto provide the pinnedkind/kubectltoolchain, stands up the kind cluster + ControlPlane, then mints an ephemeralclouds.yamlfrom the operator-projectedcontrolplane-keystone-admin-credentialsSecret. It refuses to clobber anOS_CLIENT_CONFIG_FILEthat points outside the dedicated in-tree path, serializesclouds.yamlwith a YAML library (not a heredoc) so an arbitrary admin password can't corrupt the file, and pre-creates thememberandload-balancer_memberroles. The latter is needed becausecreate.pyindexes its role cache directly and a bare Keystone shipsmemberbut notload-balancer_member(Octavia normally provisions it) —create.pyitself is left untouched.b7bd7ecAdd integration run.sh orchestration and SDK verifiertest/integration/run.sh: orchestrates deploy →tox -e create(as admin, with--nodomain-name-prefixso the project is named exactlyopm-integration-test) →verify.py. AnEXITtrap always tears down the kind cluster, but only when this run created it (a pre-existing debug cluster is reused and left in place); on failure it dumps diagnostics first. Best-effort project deletion keeps reruns idempotent unlessKEEP_PROJECT=1.test/integration/verify.py: a standalone openstacksdk script (deliberately not namedtest_*.py, sotox -e testnever collects it) that asserts thedefaultdomain resolves, theopm-integration-testproject exists in it, and the matching per-project group exists; it exits non-zero on any failed assertion..gitignore: ignores the generatedtest/integration/clouds.yaml.tox.ini: passesOS_CLIENT_CONFIG_FILEthrough to the create env.1be0a3cAdd Makefile integration targetsmake integration(full provision/create/verify/teardown cycle),make integration-up(deploy and leave the cluster running for local debugging),make integration-down(delete the kind cluster).b470a8eAdd Ansible pre/test playbooks for integration jobplaybooks/pre-integration.yml: prepares an IPv6-only Zuul node —ensure-pip/ensure-pipenv/ensure-dockerroles, thelibldap2-dev/libsasl2-devbuild deps the create env needs, and anaccept_ra=2sysctl fix so the node keeps honouring router advertisements once kind enables IPv6 forwarding.playbooks/test-integration.yml: installstox+openstacksdkinto a throwaway venv and runsmake integrationfrom the checkout.bb61192Add periodic-daily Zuul integration job.zuul.yaml: definesopenstack-project-manager-integration(ubuntu-noble, 2400s timeout) and adds it to periodic-daily only, so the heavy kind+Keystone job does not slow the check gate (which is left unchanged).c3db56aDocument the integration test harnesstest/integration/README.md: prerequisites, the make targets, the environment overrides, whatverify.pyasserts, and the ephemeral-credentials handling.Notes / divergences from the issue
ControlPlanerather than a full forge control plane, keeping the job as light as feasible for the single happy-path assertion.load-balancer_memberworkaround: the only accommodation to the production code is pre-creating rolescreate.pyexpects (member,load-balancer_member) on the bare Keystone.create.pyis intentionally left untouched; the workaround lives entirely indeploy_keystone.sh.periodic-daily, not the check pipeline, so PRs are not gated on the multi-minute kind+Keystone bring-up.create.pyprovisions, giving the happy path a slightly stronger assertion than the issue's minimal "create a project".Implemented by planwerk-agent 84299e2 with Claude:claude-opus-4-8