Skip to content

Commit 39c1152

Browse files
committed
Add AC finalizer management
Signed-off-by: Veronika Fisarova <vfisarov@redhat.com>
1 parent b70eb51 commit 39c1152

8 files changed

Lines changed: 313 additions & 10 deletions

File tree

api/bases/designate.openstack.org_designateapis.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,13 @@ spec:
442442
type: object
443443
description: API endpoints
444444
type: object
445+
applicationCredentialSecret:
446+
description: |-
447+
ApplicationCredentialSecret - the AC secret DesignateAPI is currently
448+
consuming and protecting with the openstack.org/designateapi-ac-consumer
449+
finalizer. Tracked so the controller can remove its finalizer from the
450+
old secret when the openstack-operator rotates the reference.
451+
type: string
445452
conditions:
446453
description: Conditions
447454
items:

api/v1beta1/designateapi_types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@ type DesignateAPIStatus struct {
122122
// NetworkAttachments status of the deployment pods
123123
NetworkAttachments map[string][]string `json:"networkAttachments,omitempty"`
124124

125+
// ApplicationCredentialSecret - the AC secret DesignateAPI is currently
126+
// consuming and protecting with the openstack.org/designateapi-ac-consumer
127+
// finalizer. Tracked so the controller can remove its finalizer from the
128+
// old secret when the openstack-operator rotates the reference.
129+
ApplicationCredentialSecret string `json:"applicationCredentialSecret,omitempty"`
130+
125131
// ObservedGeneration - the most recent generation observed for this
126132
// service. If the observed generation is less than the spec generation,
127133
// then the controller has not processed the latest changes injected by

config/crd/bases/designate.openstack.org_designateapis.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,13 @@ spec:
442442
type: object
443443
description: API endpoints
444444
type: object
445+
applicationCredentialSecret:
446+
description: |-
447+
ApplicationCredentialSecret - the AC secret DesignateAPI is currently
448+
consuming and protecting with the openstack.org/designateapi-ac-consumer
449+
finalizer. Tracked so the controller can remove its finalizer from the
450+
old secret when the openstack-operator rotates the reference.
451+
type: string
445452
conditions:
446453
description: Conditions
447454
items:

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ require (
1313
github.com/openshift/api v3.9.0+incompatible
1414
github.com/openstack-k8s-operators/designate-operator/api v0.1.1-0.20240807132522-6c2eca7c6bbb
1515
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260508091801-73f228e6af31
16-
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260507114237-f0b612d6c21f
16+
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260520090027-4d7b7a01c0bf
1717
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260518125357-72bdd580c587
1818
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20260506154724-30a976ba8ef0
19-
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260506154724-30a976ba8ef0
20-
github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260503164939-40728ae44d65
19+
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260518125357-72bdd580c587
20+
github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260421135251-4fb605db7d18
2121
gopkg.in/yaml.v2 v2.4.0
2222
k8s.io/api v0.31.14
2323
k8s.io/apimachinery v0.31.14

go.sum

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,18 +132,18 @@ github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e h1:E1OdwSpqWuDPCedyU
132132
github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo=
133133
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260508091801-73f228e6af31 h1:FWa0vNs175LpV1eSZ60YOGFdbJ3LqxQ1fxfprBRg7T4=
134134
github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20260508091801-73f228e6af31/go.mod h1:/S2AN21zV70V1XuL0Of2dCjYWNkKwQSyNI8l/iQVrMs=
135-
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260507114237-f0b612d6c21f h1:28WYAUIef3uion0Pps6doCSSbgZtIcodGzwG6BHhCOw=
136-
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260507114237-f0b612d6c21f/go.mod h1:4ryvbSYuoN522BIPijnm0wMemPgJVKf7jCv8BNDq46I=
135+
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260520090027-4d7b7a01c0bf h1:FoKK0zNo48i4ZMFxScupCK/YAmy6Ps4IILz3CK4BCTI=
136+
github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20260520090027-4d7b7a01c0bf/go.mod h1:VNX1Mda2u5+yGxycIyVrgABucitMDR9ct3Lj6ROS92I=
137137
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260518125357-72bdd580c587 h1:p03uEXoSreyu7LpFmb9YyYM8tEx2D2+7qqhLXNWHTq0=
138138
github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20260518125357-72bdd580c587/go.mod h1:JC04T5G4E/he5ukonV1oCqa0QzFkLv761VbLruVghJM=
139139
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20260506154724-30a976ba8ef0 h1:kMie+G0aHlGwDHjimjj8AUxTl2R7LGfai/8pev2T+TY=
140140
github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20260506154724-30a976ba8ef0/go.mod h1:7yqbVpg0k0vW+kZks+TMU/cd1ovoejyHfVPWcyGYLHI=
141141
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260506154724-30a976ba8ef0 h1:wuzSibIT9F/5RbMmxvBVFj6fy2vtKo58nibzmk5L4PM=
142142
github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20260506154724-30a976ba8ef0/go.mod h1:tft3oDiN+v6wX3ILPXGUM/gCLJz6QtrPN63hxpJ3E24=
143-
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260506154724-30a976ba8ef0 h1:mG3QhS/QWv9Y/AkZZ5OzO6hu6+l5oDXnI/Q5ZUbj6Zs=
144-
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260506154724-30a976ba8ef0/go.mod h1:ZYG9CQe7cOePOKQbenEZFA28kPdkUOe9QKbDRwGhEV0=
145-
github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260503164939-40728ae44d65 h1:MNjmU326MKwYU6xT6AL2aKbr/0ids87wP5B+s5CL2O0=
146-
github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260503164939-40728ae44d65/go.mod h1:I2LO+wGIzbirVczQ9qo/49y2F5Zo/MEg/pabkXOrY2M=
143+
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260518125357-72bdd580c587 h1:jpouKcgs2Kc5z2JHIpvsXMxEonfXLgzX3KswuBoeKQ0=
144+
github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20260518125357-72bdd580c587/go.mod h1:nLS2oK4pBo756JNN1cPgr44S0X9V11QScgVla89Ojok=
145+
github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260421135251-4fb605db7d18 h1:fMMY6pp7+PEkcsdDoodTfJ6ct2RyGI8VB+toVJxxB5w=
146+
github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20260421135251-4fb605db7d18/go.mod h1:g/xgMnzNHxdTkqnEgAKwVOv75uPN4nuApbkGqSvASvs=
147147
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
148148
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
149149
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=

internal/controller/designateapi_controller.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,19 @@ func (r *DesignateAPIReconciler) reconcileDelete(ctx context.Context, instance *
528528
); err != nil {
529529
return ctrlResult, err
530530
}
531+
// Remove consumer finalizer from AC secrets DesignateAPI was consuming.
532+
// Check both status and spec to handle the edge case where the reconciler
533+
// crashed after adding the finalizer but before updating the status.
534+
for _, secretName := range []string{
535+
instance.Status.ApplicationCredentialSecret,
536+
instance.Spec.Auth.ApplicationCredentialSecret,
537+
} {
538+
if err := keystonev1.RemoveACSecretConsumerFinalizer(ctx, helper, instance.Namespace,
539+
secretName, designate.ACConsumerFinalizer); err != nil {
540+
return ctrl.Result{}, err
541+
}
542+
}
543+
531544
// We did all the cleanup on the objects we created so we can remove the
532545
// finalizer from ourselves to allow the deletion
533546
controllerutil.RemoveFinalizer(instance, helper.GetFinalizer())
@@ -905,6 +918,24 @@ func (r *DesignateAPIReconciler) reconcileNormal(ctx context.Context, instance *
905918
return ctrl.Result{}, nil
906919
}
907920

921+
// Add consumer finalizer to the new AC secret early, before deployment.
922+
// The old secret's finalizer is removed later (after all services deploy)
923+
// so that rapid rotations don't revoke a credential still in use by pods.
924+
if instance.Spec.Auth.ApplicationCredentialSecret != "" {
925+
if err := keystonev1.ManageACSecretFinalizer(ctx, helper, instance.Namespace,
926+
instance.Spec.Auth.ApplicationCredentialSecret,
927+
"",
928+
designate.ACConsumerFinalizer); err != nil {
929+
instance.Status.Conditions.Set(condition.FalseCondition(
930+
condition.ServiceConfigReadyCondition,
931+
condition.ErrorReason,
932+
condition.SeverityWarning,
933+
condition.ServiceConfigReadyErrorMessage,
934+
err.Error()))
935+
return ctrl.Result{}, err
936+
}
937+
}
938+
908939
instance.Status.Conditions.MarkTrue(condition.ServiceConfigReadyCondition, condition.ServiceConfigReadyMessage)
909940

910941
// Create ConfigMaps and Secrets - end
@@ -1088,6 +1119,25 @@ func (r *DesignateAPIReconciler) reconcileNormal(ctx context.Context, instance *
10881119
}
10891120
// create Deployment - end
10901121

1122+
// Manage the old AC secret's finalizer and status tracking.
1123+
// On rotation (old != new), only remove the old secret's finalizer after
1124+
// all sub-services are ready with the new credentials. This prevents
1125+
// premature revocation during rapid rotations.
1126+
isRotation := instance.Status.ApplicationCredentialSecret != "" && instance.Status.ApplicationCredentialSecret != instance.Spec.Auth.ApplicationCredentialSecret
1127+
1128+
if isRotation {
1129+
allServicesReady := instance.Status.Conditions.AllSubConditionIsTrue()
1130+
if allServicesReady {
1131+
if err := keystonev1.RemoveACSecretConsumerFinalizer(ctx, helper, instance.Namespace,
1132+
instance.Status.ApplicationCredentialSecret, designate.ACConsumerFinalizer); err != nil {
1133+
return ctrl.Result{}, err
1134+
}
1135+
instance.Status.ApplicationCredentialSecret = instance.Spec.Auth.ApplicationCredentialSecret
1136+
}
1137+
} else {
1138+
instance.Status.ApplicationCredentialSecret = instance.Spec.Auth.ApplicationCredentialSecret
1139+
}
1140+
10911141
// We reached the end of the Reconcile, update the Ready condition based on
10921142
// the sub conditions
10931143
if instance.Status.Conditions.AllSubConditionIsTrue() {

internal/designate/const.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,7 @@ const (
101101

102102
// SharedTSIGKeyName is the name of the shared TSIG key used for all non-default pools
103103
SharedTSIGKeyName = "multipool-shared-key"
104+
105+
// ACConsumerFinalizer is added to AC secrets that designate is actively consuming
106+
ACConsumerFinalizer = "openstack.org/designateapi-ac-consumer"
104107
)

0 commit comments

Comments
 (0)