Implement Limit controller - #868
Conversation
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
c416088 to
e556212
Compare
Update generated resources to reflect the addition of description in Limit spec Update the OLM bundle
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?
Fix parameters in dependencies in Limit actuator Fix default name in test utils
|
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 |
…to Keystone API issue Use prebuilt image to avoid slow creation of registered limits
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.
|
|
||
| // resourceLimit is the override value of the limit. | ||
| // +optional | ||
| ResourceLimit int32 `json:"resourceLimit,omitempty"` |
There was a problem hiding this comment.
I think this should be a pointer. If the ResourceLimit if set to 0, it will be omitted.
There was a problem hiding this comment.
Can you elaborate the part about it will be omitted? Do you mean it won't be shown in the yaml output or something else?
Here is a test I made. It was shown correctly in the status.resource
apiVersion: openstack.k-orc.cloud/v1alpha1
kind: Limit
metadata:
annotations:
...
creationTimestamp: "2026-08-04T10:08:32Z"
finalizers:
- openstack.k-orc.cloud/limit
generation: 1
name: limit-managed-domain
namespace: default
resourceVersion: "562155"
uid: defec55e-42a9-4e8e-b1a1-54b59af42405
spec:
cloudCredentialsRef:
cloudName: openstack-admin
secretName: openstack-clouds
managementPolicy: managed
resource:
projectRef: project-admin
resourceLimit: 0
resourceName: servers
serviceRef: nova
status:
conditions:
- lastTransitionTime: "2026-08-04T10:08:35Z"
message: OpenStack resource is available
observedGeneration: 1
reason: Success
status: "True"
type: Available
- lastTransitionTime: "2026-08-04T10:08:35Z"
message: OpenStack resource is up to date
observedGeneration: 1
reason: Success
status: "False"
type: Progressing
id: 22471bb8f6524711be117d40667c0bda
lastSyncTime: "2026-08-04T10:08:35Z"
resource:
projectID: 6fd7df4cf061469ab27d39d6c91b25a0
resourceLimit: 0
resourceName: servers
serviceID: b8e6f8f3a9264fcaa5dc99e34aea1e31| | 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.
| 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 handleDescriptionUpdate(updateOpts *limits.UpdateOpts, resource *resourceSpecT, osResource *osResourceT) { | ||
| description := ptr.Deref(resource.Description, "") |
There was a problem hiding this comment.
If the user unset the description from spec, the controller will keep the description as-is and we will have a mismatch between spec and status (no description x some description).
Wdyt of having this field as immutable?
There was a problem hiding this comment.
If this field is set to immutable, then user would lose the capability to update the description completely. I am considering adding a note for description to warn user that clearing them doesn't work until the issue is fixed in upstream. What do you think?
| 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: b8e6f8f3a9264fcaa5dc99e34aea1e31Add `resource.ServiceRef` check in the filter for serviceDependency creation
This PR implements the controller for
Limitin Keystone.Regionis not included in the spec as it is not available in ORC yet.As
Limitdepends onRegisteredLimitwhich hasn't been merged yet, a setup deployment is used in e2e test cases to create requiredRegisteredLimits and remove them when tearing down cases. The deployment is also used to disable createdDomains to facilitate the deletion of them.Close #851