Skip to content

Commit ec1d15f

Browse files
committed
Add application credential finalizer management
Signed-off-by: Veronika Fisarova <vfisarov@redhat.com>
1 parent 4d37539 commit ec1d15f

10 files changed

Lines changed: 389 additions & 18 deletions

File tree

api/bases/placement.openstack.org_placementapis.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,13 @@ spec:
412412
status:
413413
description: PlacementAPIStatus defines the observed state of PlacementAPI
414414
properties:
415+
applicationCredentialSecret:
416+
description: |-
417+
ApplicationCredentialSecret - the AC secret placement is currently
418+
consuming and protecting with the openstack.org/placementapi-ac-consumer
419+
finalizer. Tracked so the controller can remove its finalizer from the
420+
old secret when the openstack-operator rotates the reference.
421+
type: string
415422
conditions:
416423
description: Conditions
417424
items:

api/go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ go 1.24.4
44

55
require (
66
github.com/google/go-cmp v0.7.0
7-
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260416122644-5476763a36b6
7+
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260508091801-73f228e6af31
88
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260518125357-72bdd580c587
99
github.com/robfig/cron/v3 v3.0.1
1010
k8s.io/api v0.31.14
@@ -43,6 +43,7 @@ require (
4343
github.com/prometheus/client_model v0.6.2 // indirect
4444
github.com/prometheus/common v0.65.0 // indirect
4545
github.com/prometheus/procfs v0.16.1 // indirect
46+
github.com/rogpeppe/go-internal v1.13.1 // indirect
4647
github.com/spf13/pflag v1.0.7 // indirect
4748
github.com/x448/float16 v0.8.4 // indirect
4849
go.yaml.in/yaml/v2 v2.4.2 // indirect

api/go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ github.com/onsi/ginkgo/v2 v2.28.2 h1:DTrMfpqxiNUyQ3Y0zhn1n3cOO2euFgQPYIpkWwxVFps
7878
github.com/onsi/ginkgo/v2 v2.28.2/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE=
7979
github.com/onsi/gomega v1.41.0 h1:OwKp4pXNgVxf6sCplzYo794OFNuoL2q2SBMU5NSWOjA=
8080
github.com/onsi/gomega v1.41.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A=
81-
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260416122644-5476763a36b6 h1:117Gu9HCSu2tAp579WnCJ9QtnslH2qnPB8UFvn8ZpqE=
82-
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260416122644-5476763a36b6/go.mod h1:i7l8cihvFktd/LSuyvL2z6OcwauarQGoVhDMePL4VyI=
81+
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260508091801-73f228e6af31 h1:FWa0vNs175LpV1eSZ60YOGFdbJ3LqxQ1fxfprBRg7T4=
82+
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260508091801-73f228e6af31/go.mod h1:/S2AN21zV70V1XuL0Of2dCjYWNkKwQSyNI8l/iQVrMs=
8383
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260518125357-72bdd580c587 h1:p03uEXoSreyu7LpFmb9YyYM8tEx2D2+7qqhLXNWHTq0=
8484
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260518125357-72bdd580c587/go.mod h1:JC04T5G4E/he5ukonV1oCqa0QzFkLv761VbLruVghJM=
8585
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=

api/placement/v1beta1/api_types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,12 @@ type PlacementAPIStatus struct {
182182

183183
// LastAppliedTopology - the last applied Topology
184184
LastAppliedTopology *topologyv1.TopoRef `json:"lastAppliedTopology,omitempty"`
185+
186+
// ApplicationCredentialSecret - the AC secret placement is currently
187+
// consuming and protecting with the openstack.org/placementapi-ac-consumer
188+
// finalizer. Tracked so the controller can remove its finalizer from the
189+
// old secret when the openstack-operator rotates the reference.
190+
ApplicationCredentialSecret string `json:"applicationCredentialSecret,omitempty"`
185191
}
186192

187193
// PlacementAPI is the Schema for the placementapis API

config/crd/bases/placement.openstack.org_placementapis.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,13 @@ spec:
412412
status:
413413
description: PlacementAPIStatus defines the observed state of PlacementAPI
414414
properties:
415+
applicationCredentialSecret:
416+
description: |-
417+
ApplicationCredentialSecret - the AC secret placement is currently
418+
consuming and protecting with the openstack.org/placementapi-ac-consumer
419+
finalizer. Tracked so the controller can remove its finalizer from the
420+
old secret when the openstack-operator rotates the reference.
421+
type: string
415422
conditions:
416423
description: Conditions
417424
items:

go.mod

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ require (
1010
github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.7
1111
github.com/onsi/ginkgo/v2 v2.28.2
1212
github.com/onsi/gomega v1.41.0
13-
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260416122644-5476763a36b6
14-
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260420052838-77f94aef5af2
13+
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260508091801-73f228e6af31
14+
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260520090027-4d7b7a01c0bf
1515
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260518125357-72bdd580c587
16-
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20260417092244-81c71b39e981
17-
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260417092244-81c71b39e981
16+
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20260506154724-30a976ba8ef0
17+
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260518125357-72bdd580c587
1818
github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260413152655-564a51226a2a
1919
github.com/openstack-k8s-operators/nova-operator/api v0.0.0-20221209164002-f9e6b9363961
2020
go.uber.org/zap v1.28.0
@@ -65,7 +65,7 @@ require (
6565
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
6666
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
6767
github.com/openshift/api v3.9.0+incompatible // indirect
68-
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260417092244-81c71b39e981 // indirect
68+
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260506154724-30a976ba8ef0 // indirect
6969
github.com/pkg/errors v0.9.1 // indirect
7070
github.com/prometheus/client_golang v1.22.0 // indirect
7171
github.com/prometheus/client_model v0.6.2 // indirect

go.sum

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -118,18 +118,18 @@ github.com/onsi/gomega v1.41.0 h1:OwKp4pXNgVxf6sCplzYo794OFNuoL2q2SBMU5NSWOjA=
118118
github.com/onsi/gomega v1.41.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A=
119119
github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e h1:E1OdwSpqWuDPCedyUt0GEdoAE+r5TXy7YS21yNEo+2U=
120120
github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo=
121-
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260416122644-5476763a36b6 h1:117Gu9HCSu2tAp579WnCJ9QtnslH2qnPB8UFvn8ZpqE=
122-
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260416122644-5476763a36b6/go.mod h1:i7l8cihvFktd/LSuyvL2z6OcwauarQGoVhDMePL4VyI=
123-
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260420052838-77f94aef5af2 h1:h7pTz90cHqX6nTYjYDphuitIfD4UpM9yGnI3AbLdHrY=
124-
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260420052838-77f94aef5af2/go.mod h1:SpO4CL7c5/1HG+61fP6kWhL2+3aqR+5SNatdZueKrz8=
121+
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260508091801-73f228e6af31 h1:FWa0vNs175LpV1eSZ60YOGFdbJ3LqxQ1fxfprBRg7T4=
122+
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260508091801-73f228e6af31/go.mod h1:/S2AN21zV70V1XuL0Of2dCjYWNkKwQSyNI8l/iQVrMs=
123+
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260520090027-4d7b7a01c0bf h1:FoKK0zNo48i4ZMFxScupCK/YAmy6Ps4IILz3CK4BCTI=
124+
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260520090027-4d7b7a01c0bf/go.mod h1:VNX1Mda2u5+yGxycIyVrgABucitMDR9ct3Lj6ROS92I=
125125
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260518125357-72bdd580c587 h1:p03uEXoSreyu7LpFmb9YyYM8tEx2D2+7qqhLXNWHTq0=
126126
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260518125357-72bdd580c587/go.mod h1:JC04T5G4E/he5ukonV1oCqa0QzFkLv761VbLruVghJM=
127-
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20260417092244-81c71b39e981 h1:jN3Kvt+RYUTaL9EXeeeIqRXVjqeNF74SuLTDXmi4X2Y=
128-
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20260417092244-81c71b39e981/go.mod h1:7yqbVpg0k0vW+kZks+TMU/cd1ovoejyHfVPWcyGYLHI=
129-
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260417092244-81c71b39e981 h1:X3/Gc+i0ZxaROExrpLXonz9EPhftlubFnOK4aSkRLvo=
130-
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260417092244-81c71b39e981/go.mod h1:3loLaPUDQyvbPekylZd9OCLF+EXH2klRI9IeeQhuMcs=
131-
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260417092244-81c71b39e981 h1:KAQ8T+Ri3JWgsyK1D6QybScMh6fpkYUUA+0ntnOiAl4=
132-
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260417092244-81c71b39e981/go.mod h1:dEjz8zHRIlP3vnMmWdHytlLeSZ6BHcIiSTPM7xTQxFg=
127+
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20260506154724-30a976ba8ef0 h1:kMie+G0aHlGwDHjimjj8AUxTl2R7LGfai/8pev2T+TY=
128+
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20260506154724-30a976ba8ef0/go.mod h1:7yqbVpg0k0vW+kZks+TMU/cd1ovoejyHfVPWcyGYLHI=
129+
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260506154724-30a976ba8ef0 h1:wuzSibIT9F/5RbMmxvBVFj6fy2vtKo58nibzmk5L4PM=
130+
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260506154724-30a976ba8ef0/go.mod h1:tft3oDiN+v6wX3ILPXGUM/gCLJz6QtrPN63hxpJ3E24=
131+
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260518125357-72bdd580c587 h1:jpouKcgs2Kc5z2JHIpvsXMxEonfXLgzX3KswuBoeKQ0=
132+
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260518125357-72bdd580c587/go.mod h1:nLS2oK4pBo756JNN1cPgr44S0X9V11QScgVla89Ojok=
133133
github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260413152655-564a51226a2a h1:1VRHhhCE8U0+Q6jPNppxcklIVfK7gZ2Js9VaLpPR7sw=
134134
github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260413152655-564a51226a2a/go.mod h1:g/xgMnzNHxdTkqnEgAKwVOv75uPN4nuApbkGqSvASvs=
135135
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=

internal/controller/placement/api_controller.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,21 @@ func (r *PlacementAPIReconciler) Reconcile(ctx context.Context, req ctrl.Request
456456
return ctrl.Result{}, nil
457457
}
458458

459+
if instance.Spec.Auth.ApplicationCredentialSecret != "" {
460+
if err := keystonev1.ManageACSecretFinalizer(ctx, h, instance.Namespace,
461+
instance.Spec.Auth.ApplicationCredentialSecret,
462+
"",
463+
placement.ACConsumerFinalizer); err != nil {
464+
instance.Status.Conditions.Set(condition.FalseCondition(
465+
condition.ServiceConfigReadyCondition,
466+
condition.ErrorReason,
467+
condition.SeverityWarning,
468+
condition.ServiceConfigReadyErrorMessage,
469+
err.Error()))
470+
return ctrl.Result{}, err
471+
}
472+
}
473+
459474
instance.Status.Conditions.MarkTrue(condition.ServiceConfigReadyCondition, condition.ServiceConfigReadyMessage)
460475

461476
serviceAnnotations, result, err := r.ensureNetworkAttachments(ctx, h, instance)
@@ -503,6 +518,26 @@ func (r *PlacementAPIReconciler) Reconcile(ctx context.Context, req ctrl.Request
503518
return ctrl.Result{}, err
504519
}
505520

521+
// Manage the old AC secret's finalizer and status tracking.
522+
// On rotation (old != new), only remove the old secret's finalizer after
523+
// all sub-services are ready with the new credentials. This prevents
524+
// premature revocation during rapid rotations.
525+
isRotation := instance.Status.ApplicationCredentialSecret != "" &&
526+
instance.Status.ApplicationCredentialSecret != instance.Spec.Auth.ApplicationCredentialSecret
527+
528+
if isRotation {
529+
allServicesReady := instance.Status.Conditions.AllSubConditionIsTrue()
530+
if allServicesReady {
531+
if err := keystonev1.RemoveACSecretConsumerFinalizer(ctx, h, instance.Namespace,
532+
instance.Status.ApplicationCredentialSecret, placement.ACConsumerFinalizer); err != nil {
533+
return ctrl.Result{}, err
534+
}
535+
instance.Status.ApplicationCredentialSecret = instance.Spec.Auth.ApplicationCredentialSecret
536+
}
537+
} else {
538+
instance.Status.ApplicationCredentialSecret = instance.Spec.Auth.ApplicationCredentialSecret
539+
}
540+
506541
return ctrl.Result{}, nil
507542
}
508543

@@ -1095,6 +1130,17 @@ func (r *PlacementAPIReconciler) reconcileDelete(ctx context.Context, instance *
10951130
}
10961131
}
10971132

1133+
// Remove consumer finalizer from AC secrets placement was consuming.
1134+
for _, secretName := range []string{
1135+
instance.Status.ApplicationCredentialSecret,
1136+
instance.Spec.Auth.ApplicationCredentialSecret,
1137+
} {
1138+
if err := keystonev1.RemoveACSecretConsumerFinalizer(ctx, helper, instance.Namespace,
1139+
secretName, placement.ACConsumerFinalizer); err != nil {
1140+
return ctrl.Result{}, err
1141+
}
1142+
}
1143+
10981144
// We did all the cleanup on the objects we created so we can remove the
10991145
// finalizer from ourselves to allow the deletion
11001146
controllerutil.RemoveFinalizer(instance, helper.GetFinalizer())
@@ -1333,6 +1379,25 @@ func (r *PlacementAPIReconciler) ensureDeployment(
13331379
}
13341380
// create Deployment - end
13351381

1382+
// Manage the old AC secret's finalizer and status tracking.
1383+
// On rotation (old != new), only remove the old secret's finalizer after
1384+
// all sub-services are ready with the new credentials. This prevents
1385+
// premature revocation during rapid rotations.
1386+
isRotation := instance.Status.ApplicationCredentialSecret != "" && instance.Status.ApplicationCredentialSecret != instance.Spec.Auth.ApplicationCredentialSecret
1387+
1388+
if isRotation {
1389+
allServicesReady := instance.Status.Conditions.AllSubConditionIsTrue()
1390+
if allServicesReady {
1391+
if err := keystonev1.RemoveACSecretConsumerFinalizer(ctx, h, instance.Namespace,
1392+
instance.Status.ApplicationCredentialSecret, placement.ACConsumerFinalizer); err != nil {
1393+
return ctrl.Result{}, err
1394+
}
1395+
instance.Status.ApplicationCredentialSecret = instance.Spec.Auth.ApplicationCredentialSecret
1396+
}
1397+
} else {
1398+
instance.Status.ApplicationCredentialSecret = instance.Spec.Auth.ApplicationCredentialSecret
1399+
}
1400+
13361401
Log.Info("Reconciled Service successfully")
13371402
return ctrl.Result{}, nil
13381403

internal/placement/const.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,7 @@ const (
3636
// PlacementUserID is the linux user ID used by Kolla for the placement
3737
// user in the service containers
3838
PlacementUserID int64 = 42482
39+
40+
// ACConsumerFinalizer is added to AC secrets that placement is actively consuming
41+
ACConsumerFinalizer = "openstack.org/placementapi-ac-consumer"
3942
)

0 commit comments

Comments
 (0)