-
Notifications
You must be signed in to change notification settings - Fork 102
AppCred support #1430
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
base: main
Are you sure you want to change the base?
AppCred support #1430
Conversation
|
Skipping CI for Draft Pull Request. |
|
Merge Failed. This change or one of its cross-repo dependencies was unable to be automatically merged with the current state of its repository. Please rebase the change and upload a new patchset. |
|
Unable to freeze job graph: Job adoption-standalone-to-crc-ceph-provider depends on openstack-k8s-operators-content-provider which was not run. |
|
recheck |
|
Build failed (check pipeline). Post https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/fb95ce639e164bb190aa3b41fcda82da ✔️ openstack-k8s-operators-content-provider SUCCESS in 1h 59m 19s |
|
Build failed (check pipeline). Post https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/64ab1660f5ff460cb0bdb2682d3b4149 ❌ openstack-k8s-operators-content-provider FAILURE in 15m 15s |
|
Build failed (check pipeline). Post https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/5ebbd01a8bc549b2956a87c3507363e2 ❌ openstack-k8s-operators-content-provider FAILURE in 13m 33s |
|
Build failed (check pipeline). Post https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/67ea6f17ebce4477b46d077171537d98 ❌ openstack-k8s-operators-content-provider FAILURE in 13m 49s |
|
Build failed (check pipeline). Post https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/65697c077ffe4630a698b4a94657a08a ❌ openstack-k8s-operators-content-provider FAILURE in 16m 43s |
|
Build failed (check pipeline). Post https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/8b21d132d2c944f4bb8faccfff711e47 ❌ openstack-k8s-operators-content-provider FAILURE in 14m 09s |
62fd3e5 to
27db2bd
Compare
|
Merge Failed. This change or one of its cross-repo dependencies was unable to be automatically merged with the current state of its repository. Please rebase the change and upload a new patchset. |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: Deydra71 The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Build failed (check pipeline). Post https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/21e4c9cefa5a40fb8f263dd22018565d ❌ openstack-k8s-operators-content-provider FAILURE in 17m 16s |
ca2820b to
5749926
Compare
5749926 to
93346ce
Compare
|
Build failed (check pipeline). Post https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/704f0b2acfe24dd797cd6e492e34058d ❌ openstack-k8s-operators-content-provider FAILURE in 16m 16s |
93346ce to
5fbafa0
Compare
|
Merge Failed. This change or one of its cross-repo dependencies was unable to be automatically merged with the current state of its repository. Please rebase the change and upload a new patchset. |
e9e9a01 to
7e74505
Compare
|
Build failed (check pipeline). Post https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/dd42cbd419dc474287f25fb88d135e5e ❌ openstack-k8s-operators-content-provider FAILURE in 15m 35s |
7e74505 to
79ae205
Compare
|
Build failed (check pipeline). Post https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/60f380b19b72420684a8b9ba527bb1db ❌ openstack-k8s-operators-content-provider FAILURE in 18m 52s |
79ae205 to
b98631b
Compare
|
Build failed (check pipeline). Post https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/650f861e266649e684e94e8e38236ca9 ❌ openstack-k8s-operators-content-provider FAILURE in 13m 53s |
b98631b to
5a36538
Compare
|
Build failed (check pipeline). Post https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/fe0e210d9f7d44429cfde38f83a800be ❌ openstack-k8s-operators-content-provider FAILURE in 18m 57s |
vyzigold
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.
In telemetry, we have an enabled switch for the whole telemetry similarly to other services to disable / enable the whole telemetry. But we also allow to enable / disable each individual part of telemetry, so we have additional enabled switches for aodh, ceilometer and cloudkitty, which I think should be also used to determine whether to create the application credentials. See my suggestions.
| {"glance", instance.Spec.Glance.Enabled, instance.Spec.Glance.ApplicationCredential}, | ||
| {"nova", instance.Spec.Nova.Enabled, instance.Spec.Nova.ApplicationCredential}, | ||
| {"swift", instance.Spec.Swift.Enabled, instance.Spec.Swift.ApplicationCredential}, | ||
| {"ceilometer", instance.Spec.Telemetry.Enabled, instance.Spec.Telemetry.ApplicationCredentialCeilometer}, |
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.
| {"ceilometer", instance.Spec.Telemetry.Enabled, instance.Spec.Telemetry.ApplicationCredentialCeilometer}, | |
| {"ceilometer", instance.Spec.Telemetry.Enabled && instance.Spec.Telemetry.Template.Ceilometer.Enabled, instance.Spec.Telemetry.ApplicationCredentialCeilometer}, |
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.
Yes, good catch. We don't want to rely on solely "disabled implies empty template 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.
Note: I can't accept suggestions directly, because we need dereference the pointer:
{"ceilometer",
instance.Spec.Telemetry.Enabled &&
instance.Spec.Telemetry.Template.Ceilometer.Enabled != nil &&
*instance.Spec.Telemetry.Template.Ceilometer.Enabled,
instance.Spec.Telemetry.ApplicationCredentialCeilometer,
},
| {"manila", instance.Spec.Manila.Enabled, instance.Spec.Manila.ApplicationCredential}, | ||
| {"designate", instance.Spec.Designate.Enabled, instance.Spec.Designate.ApplicationCredential}, | ||
| {"watcher", instance.Spec.Watcher.Enabled, instance.Spec.Watcher.ApplicationCredential}, | ||
| {"aodh", instance.Spec.Telemetry.Enabled, instance.Spec.Telemetry.ApplicationCredentialAodh}, |
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.
| {"aodh", instance.Spec.Telemetry.Enabled, instance.Spec.Telemetry.ApplicationCredentialAodh}, | |
| {"aodh", instance.Spec.Telemetry.Enabled && instance.Spec.Telemetry.Template.Autoscaling.Enabled, instance.Spec.Telemetry.ApplicationCredentialAodh}, |
| {"designate", instance.Spec.Designate.Enabled, instance.Spec.Designate.ApplicationCredential}, | ||
| {"watcher", instance.Spec.Watcher.Enabled, instance.Spec.Watcher.ApplicationCredential}, | ||
| {"aodh", instance.Spec.Telemetry.Enabled, instance.Spec.Telemetry.ApplicationCredentialAodh}, | ||
| {"cloudkitty", instance.Spec.Telemetry.Enabled, instance.Spec.Telemetry.ApplicationCredentialCloudKitty}, |
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.
| {"cloudkitty", instance.Spec.Telemetry.Enabled, instance.Spec.Telemetry.ApplicationCredentialCloudKitty}, | |
| {"cloudkitty", instance.Spec.Telemetry.Enabled && instance.Spec.Telemetry.Template.CloudKitty.Enabled, instance.Spec.Telemetry.ApplicationCredentialCloudKitty}, |
5a36538 to
062b528
Compare
|
Build failed (check pipeline). Post https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/097e3f645c1a4f4094a7fcfe49b94d04 ❌ openstack-k8s-operators-content-provider FAILURE in 11m 20s |
062b528 to
cfde225
Compare
|
Build failed (check pipeline). Post https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/c0c013624c3444e9a20465996192328f ❌ openstack-k8s-operators-content-provider FAILURE in 12m 20s |
Signed-off-by: Veronika Fisarova <[email protected]>
cfde225 to
ea36bc5
Compare
|
Build failed (check pipeline). Post https://softwarefactory-project.io/zuul/t/rdoproject.org/buildset/a7e544c73217452b93106c7807a5aea4 ❌ openstack-k8s-operators-content-provider FAILURE in 11m 40s |
|
@Deydra71: The following tests failed, say
Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
| // Enabled indicates whether an ApplicationCredential should be created | ||
| // +kubebuilder:validation:Optional | ||
| // +kubebuilder:default=false | ||
| Enabled bool `json:"enabled"` |
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.
wondering if we need this global switch, if you always have to enable it also on the per service level. if there is the req to always do it in each service do we need a global switch? wouldn't a global switch only make sense if we default the per service to true. like:
- switch global to true ac is enable for all services
- if you want to disable it for some services switch them to off
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 know having two switches might feel confusing, but I was thinking about them as two different layers of control. - per-service enablement should stay explicit so the operator isn’t surprised by authentication changing in a service they didn’t mean to migrate yet. The global switch is mainly there for ops convenience and safety: if we ever need to disable AppCred everywhere, we can flip one flag instead of going service-by-service again. If we made per-service default to true, it could be missed and then users would wonder why auth changed unexpectedly. With opt-in per service and global gate, rollout stays controlled and predictable, and we can still turn it off fast at once.
But this is just my idea, I'm open to suggestion based on better practices.
| // ServiceAppCredSection allows service-specific overrides of the global AC configuration | ||
| type ServiceAppCredSection struct { | ||
| // +kubebuilder:validation:Optional | ||
| // +kubebuilder:default=false |
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.
see my comment on the global parameter, should this one default to true?
| // ACRule describes a single access rule for an ApplicationCredential | ||
| // +k8s:openapi-gen=true | ||
| type ACRule struct { | ||
| // Service is the name of the service to target (e.g. "identity"). |
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.
from where to get the service name? can we link a reference or will it be in product doc or how to use ac rules?
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 access rules are a keystone upstream feature for app creds. It is documented directly in the OpenStackClient CLI docs and it will be documented in the product doc how to get the necessary fields (service, path, method) from the cluster.
@vakwetu Can you please provide better answer than me, I remember that I added the AccessRules based on your suggesitons.
| // +kubebuilder:validation:Required | ||
| // +kubebuilder:validation:MinLength=1 | ||
| Service string `json:"service"` | ||
| // Path is the HTTP path (e.g. "/v3/auth/tokens"). |
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.
from where you get this? you have to know or is there some doc? or do we document this as part of the AC feature in product doc?
| // Whether the AC should be unrestricted | ||
| Unrestricted *bool `json:"unrestricted,omitempty"` | ||
|
|
||
| // AccessRules lets the service override either the global rules |
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.
is there an or missing?
| } | ||
| r.Spec.Cinder.Template.Default() | ||
| // Default Auth fields for Application Credentials | ||
| if r.Spec.Cinder.Template.CinderAPI.Auth.ApplicationCredentialSecret == "" { |
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 are setting it to a string of the secret name in the webhook, even the secret might not be there, not sure if I understand the intend of this. shouldn't we only set the ApplicationCredentialSecret in the controller if AC is enabled and the secret got created?
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.
YEs, we should set this only when app cred are enabled. The original intent was to declare where the secret is, not if it exists, because service operators are designed to handle this, eg in glance-operator/pull/812
But I will change it to appear only when app creds are enabled to not raise confusion.
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 think we should remove any defaulting via webhooks. if e.g. for glance AC gets enabled in its ReconcileGlance https://github.com/openstack-k8s-operators/openstack-operator/blob/main/internal/openstack/glance.go#L68 the operator should request the AC and check/wait until the AC is ready. if ready, it sets the parameter in the template. if it gets disabled, it removes the parameter in the template, or nils it. not sure what it is.
| @@ -1,34 +1,34 @@ | |||
| module github.com/openstack-k8s-operators/openstack-operator/api | |||
| module github.com/openstack-k8s-operators/openstack-operator/apis | |||
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.
is this correct?
|
|
||
| // ReconcileApplicationCredentials ensures an AC CR per enabled service, | ||
| // propagating its secret name, passwordSelector, and serviceUser fields. | ||
| func ReconcileApplicationCredentials( |
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.
can you explain the process when AC get enabled. I was expecting that the creation of the AC for each service happens in each of the service reconciler logics to have it there as a pre-step if enabled from beginning or when enabled later. seems right now we have a dedicated ReconcileApplicationCredentials logic which then patches each service template with a lot of hard coded stuff. I don't think this is how we want to do it, or is there a need to do it that way?
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.
So, based on the agreed ZDPR design - the AC CR creation should happen in the opesntack-operator and service operators act only as consumers of the AC Secret. However what I didn't realize is that right now we don't take the actual service info from the actual service CR, btu from OpenStackControlPlane.Spec templates.
Would it be sufficient to get the service info from the actual service CR, would eliminate the hard-coded switch statement that reaches into template structures, eg:
// In openstack-operator
ffunc ReconcileApplicationCredentials(ctx, instance, helper) error {
// ... global enabled check ...
// Glance
if instance.Spec.Glance.Enabled && isACEnabledForService(instance, "glance") {
glanceCR := &glancev1.Glance{}
err := helper.GetClient().Get(ctx, types.NamespacedName{
Name: "glance",
Namespace: instance.Namespace,
}, glanceCR)
if err != nil {
if errors.IsNotFound(err) {
log.Info("Glance CR not found yet, skipping AC creation")
// AC will be created on next reconcile
} else {
return fmt.Errorf("failed to get Glance CR: %w", err)
}
} else {
acConfig := mergeAppCred(
instance.Spec.ApplicationCredential,
instance.Spec.Glance.ApplicationCredential,
)
err := reconcileApplicationCredential(
ctx, helper, instance,
"ac-glance", // One AC name
glanceCR.Spec.ServiceUser, // One service user
glanceCR.Spec.Secret,
glanceCR.Spec.PasswordSelectors.Service,
acConfig,
)
if err != nil {
return fmt.Errorf("failed to reconcile AC for glance: %w", err)
}
}
}
// other services
// ironic will be different, because it has two keystone service users
return nil
}
Of course we need to add some check if the service is not created yet, so it doesn't fail on the first reconcile. And the structure of each service might be little different.
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.
check #1430 (comment) . thats I think how we should do it. we can have some helpers in internal/openstack/applicationcredential.go, so that it is simple func call from each Reconcile func. which this we do not have to maintain any list of possible service, or have to add something to a template outside of where the template gets created and updated.
OSPRH-14738
This PR add ApplicationCredential support enabling both global defaults and service-specific overrides in OpenStackControlPlane.
CRD updates:
spec.applicationCredentialsection withenabled,expirationDaysandgracePeriodDaysenabled:falsein every supported service, whileexpirationDaysandgracePeriodDaysare hidden unless specified directly (in that case global values are used).Controller logic:
enable: trueenabledis turned offExample:
In the example barbican is using days overrides, while cinder is using default values.
Depends-On: openstack-k8s-operators/keystone-operator#567