-
Notifications
You must be signed in to change notification settings - Fork 34
Keystone: support for Service controller #566
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Failed to assess the semver bump. See logs for details. |
|
I have found it very helpful, when working on controllers after we created the scaffolding tool, to have at least 2 separate commits:
This helps figure out quickly the specific parts of the controller and find potential bugs and missing bits more easily. If we agree on this patter, we may want to add it as a requirement in our developers docs. |
95db1e9 to
c41700b
Compare
|
Failed to assess the semver bump. See logs for details. |
As discussed in #567, we have some gaps to fill in the developer documentation. This may be a good addition. I've reverted some stuff and pushed the commits. I will just need to make another commit to resolve merge conflicts. |
|
Failed to assess the semver bump. See logs for details. |
7039f65 to
cf16119
Compare
|
Failed to assess the semver bump. See logs for details. |
api/v1alpha1/service_types.go
Outdated
| Enabled *bool `json:"enabled,omitempty"` | ||
|
|
||
| // extra indicates key-value information about the service. | ||
| Extra map[string]any `json:"extra,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That appears to be legacy, undocumented API. I'd recommend we stick with what's documented at https://docs.openstack.org/api-ref/identity/v3/#create-service.
@dlaw4608 had the same problem with the Role controller, and he ended up updating gophercloud to properly support the missing fields (so that we can eventually deprecate Extra in gophercloud). Have a look at gophercloud/gophercloud#3532.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it makes sense to update gophercloud struct to support only keystone API fields. I can open a PR for this.
Although keystone has extra in its schema, it should get only valid values when making requests.
https://github.com/openstack/keystone/blob/master/keystone/catalog/backends/sql.py#L60
I think we can block this PR for now until gophercloud's PR is not accepted. If I keep working on this we'll need to change the Service controller and all others that depend on it when deprecating Extra. Wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we don't want to wait until the next release, I can make it work with free-forms Extra values and make the changes to use valid API values after the release.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In any case, we don't want to expose undocumented Keystone fields in the ORC API. We should have Description even if internally we implement it via the Extra field, until gophercloud properly has first class support for Description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, we want to add Name.
mandre
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few comments on the API (this is really the critical part in ORC and we want to get it right). We shouldn't expose the undocumented Extra fields of keystone, even if internally we may use it until gophercloud implements all the fields.
api/v1alpha1/service_types.go
Outdated
| Enabled *bool `json:"enabled,omitempty"` | ||
|
|
||
| // extra indicates key-value information about the service. | ||
| Extra map[string]any `json:"extra,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In any case, we don't want to expose undocumented Keystone fields in the ORC API. We should have Description even if internally we implement it via the Extra field, until gophercloud properly has first class support for Description.
| type ServiceResourceSpec struct { | ||
| // type indicates which resource the service is responsible for. | ||
| // +kubebuilder:validation:MinLength:=1 | ||
| // +kubebuilder:validation:MaxLength:=255 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
|
||
| // enabled indicates whether the service is enabled or not. | ||
| // +kubebuilder:default=true | ||
| Enabled *bool `json:"enabled,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there's a default value (docs say it's optional), we want to make the field optional. If not, we should make it required and drop the pointer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although docs say its optional, I decided to define a default value because the schema defines it.
https://github.com/openstack/keystone/blob/master/keystone/catalog/backends/sql.py#L57
api/v1alpha1/service_types.go
Outdated
| Enabled *bool `json:"enabled,omitempty"` | ||
|
|
||
| // extra indicates key-value information about the service. | ||
| Extra map[string]any `json:"extra,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, we want to add Name.
api/v1alpha1/service_types.go
Outdated
| // github.com/gophercloud/gophercloud/v2/openstack/identity/v3/services | ||
| // extra indicates key-value information about the service. | ||
| // +optional | ||
| Extra map[string]any `json:"extra,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There too, we'll want to add Name and Description. In the controller's implementation, we'll fetch that from the Extra fields until gophercloud has better support for these fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Handling the description was kinda tricky, but I believe it is working properly now.
|
Failed to assess the semver bump. See logs for details. |
|
Failed to assess the semver bump. See logs for details. |
|
@mandre do you have a clue why make-generate is failing? I have run locally a couple of times and it seems ok. Replacing the diff text manually makes sense? also, I already fixed the lint. I'm waiting for your response to the above question to commit once. 😄 |
$ go run ./cmd/scaffold-controller \
-interactive=false \
-kind Service \
-gophercloud-client NewIdentityV3 \
-gophercloud-module github.com/gophercloud/gophercloud/v2/openstack/identity/v3/services
Signed-off-by: Winicius Silva <winiciusab12@gmail.com>
b97b23d to
43bc4a5
Compare
mandre
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems very close to a merging state. Really nice work!
I've noticed you made iterative commits, where you added new commits to address review comments. That's OK during the review phase as it makes each change stand out, but we should rebase and squash the commits to keep clean history when we're happy with the PR status. Would you mind doing it before we merge your PR?
api/v1alpha1/service_types.go
Outdated
| // +kubebuilder:validation:MinLength:=1 | ||
| // +kubebuilder:validation:MaxLength:=255 | ||
| // +optional | ||
| Description *string `json:"description,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should drop the pointer as it's not needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little confused about when I need to use a pointer for types. If my Description isn't a pointer, when unmarshalling from the user input, if I don't specify the Description field in spec, will it fall as a default value (like an empty string)? And consequently omitted from json, as I passed omitempty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry if that wasn't clear, we should drop the pointer from Description in the ServiceResourceStatus but not in the ServiceResourceSpec, because we want to leave the possibility to unset the value in the Spec but we will always report what OpenStack returns in the Status (in other words, we shouldn't have changed the types the scaffolding did for Description).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was my mistake, actually. I thought you were talking about Description in spec, so I removed pointer from there 😅 . I'll fix it
Thanks for the explanation, this makes a lot of sense to me. The docs is also very clear about it too.
| assertAll: | ||
| - celExpr: "service.status.id != ''" | ||
| - celExpr: "service.status.resource.extra.name != ''" | ||
| - celExpr: "service.status.resource.name != ''" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These two checks (name and type being != '') are redundant with the kuttl matcher. Not a big deal, but would be cleaner to remove them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Thanks! That's ok for me! For the sake of clarity, do you want me to keep only commits with changes after running the scaffolding-tool and the implementation itself? Before merging, I would like to highlight something I noticed yesterday. I don't implement support for filling the |
The scaffolding should be its own commit (just running the command that is documented in the commit message + make generate), then all the necessary commits to implement the controller. Typically, you'd end up with 2 commits: the scaffolding and the implementation of the controller + tests, but it's very possible that you'd have more commits if for example you need to do refactoring or have other controllers make use of your new controllers. We want to split the commits in logical changes that make sense separately (I'll leave that up to you how you want to logically split your commits). Take a look at how @eshulman2 did on #568, this is a very good example.
That's fine, we don't want to expose Extra from the ORC API because:
|
43bc4a5 to
c9de13a
Compare
|
Hi @mandre! Thanks for the clear explanation. I've decided to keep only two commits (one with scaffolding tool generated code, and another with controller implementation itself). You may take a last look, but I believe it is now ready to go. |
c9de13a to
ed70f86
Compare
api/v1alpha1/service_types.go
Outdated
| // +kubebuilder:validation:MinLength:=1 | ||
| // +kubebuilder:validation:MaxLength:=255 | ||
| // +optional | ||
| Description *string `json:"description,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry if that wasn't clear, we should drop the pointer from Description in the ServiceResourceStatus but not in the ServiceResourceSpec, because we want to leave the possibility to unset the value in the Spec but we will always report what OpenStack returns in the Status (in other words, we shouldn't have changed the types the scaffolding did for Description).
api/v1alpha1/service_types.go
Outdated
| // name is a Human-readable name for the resource. Might not be unique. | ||
| // +kubebuilder:validation:MaxLength=1024 | ||
| // name indicates the name of service. | ||
| // +kubebuilder:validation:MinLength:=1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not add minimum length validation to the status. We will just return what OpenStack return [1]. We however want to have a limit on the maximum size of the resource for CEL validation budget. You may want to check this talk from Joel Speed who explains the reasons [2].
[1] https://k-orc.cloud/development/api-contracts/#resourcestatus
[2] https://www.youtube.com/watch?v=IfaPAqDfJHk
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! In the video, Joel talks a lot about MaxLength, but out of curiosity, can MinLength in some way affect the cost of validation? Well, if kube-apiserver considers the worst case for the cost, I don't think it should be considered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
internal/controllers/service/tests/service-update/00-assert.yaml
Outdated
Show resolved
Hide resolved
internal/controllers/service/tests/service-update/00-minimal-resource.yaml
Outdated
Show resolved
Hide resolved
internal/controllers/service/tests/service-update/02-assert.yaml
Outdated
Show resolved
Hide resolved
internal/controllers/service/tests/service-import/01-create-trap-resource.yaml
Outdated
Show resolved
Hide resolved
ed70f86 to
8c85525
Compare
mandre
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the lag, I thought I submitted my review yesterday but looks like not.
I just have minor nits, then it's good to go.
api/v1alpha1/service_types.go
Outdated
| // description is a human-readable description for the resource. | ||
| // +kubebuilder:validation:MaxLength=1024 | ||
| // description indicates the description of service. | ||
| // +kubebuilder:validation:MinLength:=1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's drop the MinLength check in the resource status (we should make that part of the linter if we figure out how to do it).
internal/controllers/service/tests/service-create-full/00-assert.yaml
Outdated
Show resolved
Hide resolved
8c85525 to
6132aa5
Compare
Signed-off-by: Winicius Silva <winiciusab12@gmail.com>
6132aa5 to
85a5f41
Compare
This pull request introduces support for the Keystone Service controller
Closes: #429
Reviewer notes: