Add KeyPair controller with Server integration
Summary
This PR implements full KeyPair controller support and integrates it with the Server resource, enabling SSH key management and server access control through Kubernetes resources.
Changes
Commit 1: Add KeyPair controller implementation
Implements complete KeyPair resource controller with the following features:
API & Types:
- KeyPair CRD with spec for both importing existing keys and uploading
KeyPairImportfor importing public keys from secretsKeyPairSpecfor OpenStack resource creation with public key- Validation for immutability (keypairs cannot be updated in OpenStack)
Controller Implementation:
- Client-side name filtering for import/adoption (OpenStack API only supports userID filtering)
- Deletion guard support through dependency system
- Status reporting with resource details (fingerprint, type, public key)
Commit 2: Add keypair integration to Server resource
Enables servers to be created with SSH keypairs for access:
API Changes:
- Added optional
keypairReffield toServerResourceSpec - Marked as immutable (matches OpenStack behavior - can't change after creation)
Controller Changes:
- Added keypair dependency watch (triggers reconciliation when keypair becomes Available)
- No deletion guard since keypairs are only injected during server boot
Actuator Changes:
- Fetch and validate referenced KeyPair exists and is Available before server creation
- Use gophercloud's
keypairs.CreateOptsExtextension pattern to injectkey_name - Get actual OpenStack keypair name from
keypair.Status.Resource.Name
Notes
- KeyPairs are immutable in OpenStack Nova API, so spec changes after creation will be rejected
- The keypair name in OpenStack may differ from the CR name if
spec.resource.nameis set - No deletion guard on server->keypair reference since keypairs are only injected at boot time
Fixes: https://github.com/k-orc/openstack-resource-controller/issues/136
Assisted-by: claude
Hey Ella, if you could split your work in multiple commits that would help with the review.
I have found it very helpful, when working on controllers after we created the scaffolding tool, to have at least 2 separate commits:
- the first one that just runs the scaffolding tool and commits all the generated files. We should write the exact command we ran in the commit message for reproducibility.
- a second commit that fills the blank and effectively implements the specific parts of the controller, including the API changes and the tests.
- more commits as necessary, such as adding keypair support to servers like you did.
I'll try to have a first pass at your work today.
Hi @mandre I'll work on splitting it tomorrow just 1 missing thing that I already know is missing as I haven't got to is is kuttl testing for the integration with the existing server controller so I'll try to get that into the patch tomorrow as well.
Hi, @eshulman2. Thanks for the work! Before reviewing, I want to confirm one thing.
Do we want to support compute API microversions before 2.92? I ask because the generation of key pairs has been removed from the Nova API.[1][2]
[1] https://specs.openstack.org/openstack/nova-specs/specs/zed/implemented/keypair-generation-removal.html [2] https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#microversion-2-92
@winiciusallan raised a good point. I believe we should remove the ability to generate keypairs as it's gone from nova.
BTW, I'm getting a different result than the one you have in the first commit when running the command from the commit message. I assume you passed arguments interactively. May I suggest you add the -interactive=false flag to your command line? It also seems like you've marked Project as a required dependency at creation, which seems odd.
Hi @winiciusallan , @mandre I believe those issues should be fixed. I encountered another issue with the KeyPairImport. keypairs uses names as their UUID and doesn't have an ID that matches the existing ID validation (kubebuilder:validation:Format:=uuid). This is currently a problem for the keypairimport as it is generated expecting to work with a UUID. I added a flag to the templates to allow having a non kubebuilder:validation:Format:=uuid validation for the name based id.
Hi @winiciusallan , @mandre I believe those issues should be fixed. I encountered another issue with the KeyPairImport. keypairs uses names as their UUID and doesn't have an ID that matches the existing ID validation (kubebuilder:validation:Format:=uuid). This is currently a problem for the keypairimport as it is generated expecting to work with a UUID. I added a flag to the templates to allow having a non kubebuilder:validation:Format:=uuid validation for the name based id.
That's ok for me. There are still cases which we currently don't handle yet, so adding a new spec for it seems good.
Btw, I'll try to take a look at your code today or at the latest tomorrow.
Failed to assess the semver bump. See logs for details.