Implement Limit controller - #868
Conversation
e556212 to
0b8d70e
Compare
dlaw4608
left a comment
There was a problem hiding this comment.
Hey Winston, great job on the PR!! , I left a few comments after a quick first look, I am looking into it more but just to show you what I found so far WDYT?
|
Thanks @dlaw4608 for the review. I will fix them. At the same time, I am also trying to figure out the CI failures. |
0b8d70e to
b41c2e4
Compare
|
After further debugging, I found two issues in the CI e2e failures.
Limits can be created successfully.
This makes all limit import related test cases unable to pass in |
3540f8b to
60bb5b3
Compare
|
I added a step in e2e workflow to skip the limit import test cases for openstack versions other than |
winiciusallan
left a comment
There was a problem hiding this comment.
Hey @chenwng, I did a first round of review, but I need to take a look at the rest. Thanks for your PR.
| | group | | ✔ | ✔ | | ||
| | image | ✔ | ✔ | ✔ | | ||
| | keypair | | ◐ | ◐ | | ||
| | limit | | | ◐ | |
There was a problem hiding this comment.
When we have RegionRef on this controller, I believe we will be pretty much done.
There was a problem hiding this comment.
Yes. After Region controller is merged, we can add the RegionRef field.
There was a problem hiding this comment.
We have the Region controller now, we can now add RegionRef. However, don't feel pressured to add support for it in this PR, we can do with a follow-up.
| return nil, progress.WrapError(err) | ||
| } | ||
|
|
||
| logger.Info("limit created", "createOpts", createOpts) |
There was a problem hiding this comment.
Let's remove this. Maybe you have put for debug purposes.
There was a problem hiding this comment.
I added it during debugging the CI issue and it was because I wasn't able to tell if the limit actually was created. And after debugging, I thought given it is informational and helps understand whether the controller is working normally, so I left it.
I understand there are other general places printing logs which would tell whether a resource has been created successfully after reconciling, such as Reconcile successful, but I would argue some concret log confirming it would help better when checking the log for either information only or troubleshooting.
| // There seems to be a bug that keystone doesn't clear the description field when receiving a PATCH request with an empty description. | ||
| // This will cause the `Progressing` condition stuck with `Resource status will be refreshed`. | ||
| // Tested with `openstack limit set --description ""` | ||
| handleDescriptionUpdate(&updateOpts, resource, osResource) | ||
| // The same issue exists with resourceLimit. Updating resourceLimit with 0 doesn't work. | ||
| handleResourceLimitUpdate(&updateOpts, resource, osResource) |
There was a problem hiding this comment.
Indeed it looks like something on Keystone's side. Keystone doesn't differentiate description unset and empty string. I think this is something that we could address in upstream if you would like to give it a try.
There was a problem hiding this comment.
Thanks for pointing to the root cause. I am not quite familiar with the implementation of keystone. I will put it in low priority and probably give it a try in the future when I have time.
| func validateUpdate(resource *resourceSpecT, osResource *osResourceT) error { | ||
| if resource.DomainRef != nil && osResource.ProjectID != "" { | ||
| return errInvalidDomainRefUpdate | ||
| } | ||
|
|
||
| if resource.ProjectRef != nil && osResource.DomainID != "" { | ||
| return errInvalidProjectRefUpdate | ||
| } | ||
|
|
||
| return nil | ||
| } |
There was a problem hiding this comment.
What is your idea with this function? Are not these fields already immutable and checked during creation?
There was a problem hiding this comment.
If user sets ProjectRef first, later he sets DomainRef and removes ProjectRef in the modifed yaml, this will not trigger the API validation of ProjectRef because ProjectRef is nil and not modified. Adding this validtion would block user to do such a change given we don't have a webhook avaiable.
Here is an example without this validation. After creating this Limit, I modifed the yaml with domianRef = default without projectRef. You can see below the spec and the status.resource don't match anymore.
apiVersion: openstack.k-orc.cloud/v1alpha1
kind: Limit
metadata:
annotations:
...
finalizers:
- openstack.k-orc.cloud/limit
generation: 2
name: limit-managed-domain
namespace: default
resourceVersion: "557586"
uid: 409c3ab1-91fa-4f29-b9c3-bba4e1353399
spec:
cloudCredentialsRef:
cloudName: openstack-admin
secretName: openstack-clouds
managementPolicy: managed
resource:
description: Managed limit
domainRef: default
resourceLimit: 50
resourceName: servers
serviceRef: nova
status:
conditions:
- lastTransitionTime: "2026-08-04T09:14:05Z"
message: OpenStack resource is available
observedGeneration: 2
reason: Success
status: "True"
type: Available
- lastTransitionTime: "2026-08-04T09:14:05Z"
message: OpenStack resource is up to date
observedGeneration: 2
reason: Success
status: "False"
type: Progressing
id: 56f2b0102ca1461dbf45e0c7558d90aa
lastSyncTime: "2026-08-04T09:14:28Z"
resource:
description: Managed limit
projectID: 6fd7df4cf061469ab27d39d6c91b25a0
resourceLimit: 50
resourceName: servers
serviceID: b8e6f8f3a9264fcaa5dc99e34aea1e31|
@chenwng FYI, RegisteredLimit has been merged |
|
@gndrmnn thanks. I will update this PR accordingly. |
| | group | | ✔ | ✔ | | ||
| | image | ✔ | ✔ | ✔ | | ||
| | keypair | | ◐ | ◐ | | ||
| | limit | | | ◐ | |
There was a problem hiding this comment.
We have the Region controller now, we can now add RegionRef. However, don't feel pressured to add support for it in this PR, we can do with a follow-up.
|
|
||
| - name: Run e2e tests | ||
| run: | | ||
| if [[ "${{ matrix.name }}" != "gazpacho" ]]; then |
There was a problem hiding this comment.
This seems very fragile. Don't we have a better way to skip tests? Perhaps we need to improve kuttl (in my experience, they're very receptive).
There was a problem hiding this comment.
I was considering using labels, but then it seems I will need to update all cases with labels. If kubettl has something like --skip-labels, it will be a good fit for this case.
| spec: | ||
| containers: | ||
| - name: setup-teardown | ||
| image: ghcr.io/chenwng/orc-helper:latest |
There was a problem hiding this comment.
What is this container image about, why do we need it?
I suspect the cleanup can be executed via CRD operations, like we do in the role tests for example.
Also we can't run an image from a personal registry, especially one tagged with latest for obvious supply chain dependency reasons.
There was a problem hiding this comment.
It was used to create RegisteredLimits during case setup and delete RegisteredLimits and disable Domains during teardown before RegisteredLimit was merged. I will update it since RegisteredLimit has been merged.
We can use steps to do cleanup for things like disabling Domains. However, I suspect in case there is any failure before these cleanup steps, they will not be executed and the Domains will get stuck. Ideally, kuttl should have something like pre-crd/resource-delete step/hook to allow some user cleanup actions which can always run no matter if the case fails or not. I didn't find such a feature in kuttl, or maybe I missed it.
There was a problem hiding this comment.
Agreed that it would be nice if kuttl had something like a cleanup step that runs unconditionally of previous steps success. Another possible enhancement to the project 😉
There was a problem hiding this comment.
Removed the setup/cleanup deployments. I will find some time for the kuttl enhancements for teardown step and --skip-labels.
go run ./cmd/scaffold-controller -interactive=false \
-kind=Limit \
-gophercloud-client=NewIdentityV3 \
-gophercloud-module=github.com/gophercloud/gophercloud/v2/openstack/identity/v3/limits \
-gophercloud-type=Limit \
-openstack-json-object=limit \
-available-polling-period=0 \
-deleting-polling-period=0 \
-required-create-dependency=Service \
-optional-create-dependency=Project \
-optional-create-dependency=Domain \
-import-dependency=Service \
-import-dependency=Project \
-import-dependency=Domain
Update generated resources to reflect the addition of description in Limit spec Update the OLM bundle
Fix parameters in dependencies in Limit actuator Fix default name in test utils
…to Keystone API issue Use prebuilt image to avoid slow creation of registered limits
Add `resource.ServiceRef` check in the filter for serviceDependency creation
* Set ResourceLimit in imitResourceStatus to pointer type * Update description for ResourceLimit and Description fields * Update example file config/samples/openstack_v1alpha1_limit.yaml
* Remove temporary setup/cleanup deployments * Use `RegisteredLimit` to create registered limits * Add steps to disable domains before deletion
2da7215 to
c089c09
Compare
This PR implements the controller for
Limitin Keystone.Close #851