Skip to content

Commit e56a018

Browse files
stuggiclaude
andcommitted
[b/r] Label cert secrets at creation time, simplify backup controller
Move cert-manager secret labeling from the backup controller to the controllers that create the certificates: - CA cert secrets: labeled restore=true with order 10 via SecretTemplate in ca.go (controlplane controller) - Leaf cert secrets: labeled restore=false in common.go (controlplane controller) — cert-manager regenerates these from restored CA - EDPM node cert secrets: labeled restore=false in cert.go (dataplane controller) This removes cert-manager introspection from the backup controller (isCertManagerOperatorSecret, labelResourceRestoreFalse). The controller now skips secrets that already have a restore label and only manages user-provided resources without ownerRefs. Also removes the excludeLabelKeys default for secrets (no longer needed) and fixes operator-lint by removing omitempty from fields with defaults. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 23672aa commit e56a018

9 files changed

Lines changed: 100 additions & 265 deletions

File tree

api/backup/v1beta1/openstackbackupconfig_types.go

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,23 @@ type OpenStackBackupConfigSpec struct {
2929
// DefaultRestoreOrder is the restore order assigned to user-provided resources
3030
// +kubebuilder:validation:Optional
3131
// +kubebuilder:default="10"
32-
DefaultRestoreOrder string `json:"defaultRestoreOrder,omitempty"`
32+
DefaultRestoreOrder string `json:"defaultRestoreOrder"`
3333

3434
// Secrets configuration for backup labeling
35-
// Defaults: Excludes service-cert and osdp-service labeled secrets
3635
// +kubebuilder:validation:Optional
37-
// +kubebuilder:default={enabled:true,excludeLabelKeys:{"service-cert","osdp-service"}}
38-
Secrets ResourceBackupConfig `json:"secrets,omitempty"`
36+
// +kubebuilder:default={enabled:true}
37+
Secrets ResourceBackupConfig `json:"secrets"`
3938

4039
// ConfigMaps configuration for backup labeling
4140
// Defaults: Excludes kube-root-ca.crt and openshift-service-ca.crt
4241
// +kubebuilder:validation:Optional
4342
// +kubebuilder:default={enabled:true,excludeNames:{"kube-root-ca.crt","openshift-service-ca.crt"}}
44-
ConfigMaps ResourceBackupConfig `json:"configMaps,omitempty"`
43+
ConfigMaps ResourceBackupConfig `json:"configMaps"`
4544

4645
// NetworkAttachmentDefinitions configuration for backup labeling
4746
// +kubebuilder:validation:Optional
4847
// +kubebuilder:default={enabled:true}
49-
NetworkAttachmentDefinitions ResourceBackupConfig `json:"networkAttachmentDefinitions,omitempty"`
48+
NetworkAttachmentDefinitions ResourceBackupConfig `json:"networkAttachmentDefinitions"`
5049

5150
// Issuers configuration for backup labeling of cert-manager Issuers.
5251
// Only custom (user-provided) Issuers without ownerReferences are labeled.
@@ -56,15 +55,15 @@ type OpenStackBackupConfigSpec struct {
5655
// since Issuers reference CA secrets).
5756
// +kubebuilder:validation:Optional
5857
// +kubebuilder:default={enabled:true,restoreOrder:"20"}
59-
Issuers ResourceBackupConfig `json:"issuers,omitempty"`
58+
Issuers ResourceBackupConfig `json:"issuers"`
6059
}
6160

6261
// ResourceBackupConfig defines backup labeling rules for a resource type
6362
type ResourceBackupConfig struct {
6463
// Enabled controls whether to label this resource type for backup
6564
// +kubebuilder:validation:Optional
6665
// +kubebuilder:default=true
67-
Enabled bool `json:"enabled,omitempty"`
66+
Enabled bool `json:"enabled"`
6867

6968
// RestoreOrder overrides the default restore order for this resource type.
7069
// If empty, the global DefaultRestoreOrder is used.

api/bases/backup.openstack.org_openstackbackupconfigs.yaml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -196,12 +196,7 @@ spec:
196196
secrets:
197197
default:
198198
enabled: true
199-
excludeLabelKeys:
200-
- service-cert
201-
- osdp-service
202-
description: |-
203-
Secrets configuration for backup labeling
204-
Defaults: Excludes service-cert and osdp-service labeled secrets
199+
description: Secrets configuration for backup labeling
205200
properties:
206201
enabled:
207202
default: true

bindata/crds/crds.yaml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,6 @@ spec:
234234
If empty, the global DefaultRestoreOrder is used.
235235
type: string
236236
type: object
237-
targetNamespace:
238-
default: openstack
239-
description: TargetNamespace is the namespace to watch for resources
240-
to label
241-
type: string
242237
type: object
243238
status:
244239
description: OpenStackBackupConfigStatus defines the observed state of

config/crd/bases/backup.openstack.org_openstackbackupconfigs.yaml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -196,12 +196,7 @@ spec:
196196
secrets:
197197
default:
198198
enabled: true
199-
excludeLabelKeys:
200-
- service-cert
201-
- osdp-service
202-
description: |-
203-
Secrets configuration for backup labeling
204-
Defaults: Excludes service-cert and osdp-service labeled secrets
199+
description: Secrets configuration for backup labeling
205200
properties:
206201
enabled:
207202
default: true

internal/controller/backup/openstackbackupconfig_controller.go

Lines changed: 7 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -237,80 +237,10 @@ func (r *OpenStackBackupConfigReconciler) labelResource(ctx context.Context, log
237237
return r.Update(ctx, obj)
238238
}
239239

240-
// labelResourceRestoreFalse explicitly sets restore: "false" on a resource to
241-
// indicate it should not be restored. This makes the exclusion visible.
242-
// Also removes restore-order since it's meaningless when restore is disabled.
243-
func (r *OpenStackBackupConfigReconciler) labelResourceRestoreFalse(ctx context.Context, log logr.Logger, obj client.Object) error {
244-
labels := obj.GetLabels()
245-
if labels == nil {
246-
labels = make(map[string]string)
247-
}
248-
249-
// Check if already set correctly
250-
_, hasOrder := labels[backup.BackupRestoreOrderLabel]
251-
if labels[backup.BackupRestoreLabel] == "false" && !hasOrder {
252-
return nil
253-
}
254-
255-
labels[backup.BackupRestoreLabel] = "false"
256-
delete(labels, backup.BackupRestoreOrderLabel)
257-
obj.SetLabels(labels)
258-
259-
log.Info("Labeled resource restore=false", "name", obj.GetName())
260-
return r.Update(ctx, obj)
261-
}
262-
263-
// isCertManagerOperatorSecret checks if a secret is managed by cert-manager for an
264-
// operator-created (non-CA) Certificate. Such secrets do not need the restore label
265-
// because cert-manager will regenerate them from the restored CA Issuer and Certificate CRs.
266-
// The secrets are still included in the namespace-wide backup (no label needed for that).
267-
//
268-
// Returns true (skip restore label) for:
269-
// - Operator-created non-CA cert secrets (Certificate CR has ownerRef, isCA != true)
270-
//
271-
// Returns false (set restore label) for:
272-
// - Non-cert-manager secrets
273-
// - CA certificate secrets (spec.isCA: true) — must be restored to preserve CA identity
274-
// - Secrets from user-created Certificates (no ownerRef on Certificate CR)
275-
func (r *OpenStackBackupConfigReconciler) isCertManagerOperatorSecret(ctx context.Context, log logr.Logger, secret *corev1.Secret) bool {
276-
certName, hasCertAnnotation := secret.Annotations["cert-manager.io/certificate-name"]
277-
if !hasCertAnnotation {
278-
return false
279-
}
280-
281-
// Look up the Certificate CR
282-
cert := &certmgrv1.Certificate{}
283-
if err := r.Get(ctx, types.NamespacedName{
284-
Name: certName,
285-
Namespace: secret.Namespace,
286-
}, cert); err != nil {
287-
// Certificate not found — could be deleted, treat secret as user-provided
288-
log.V(1).Info("Certificate CR not found for secret, treating as user-provided",
289-
"secret", secret.Name, "certificate", certName)
290-
return false
291-
}
292-
293-
// CA certificates must be restored to preserve the CA identity
294-
if cert.Spec.IsCA {
295-
log.V(1).Info("Secret is for CA certificate, will be backed up",
296-
"secret", secret.Name, "certificate", certName)
297-
return false
298-
}
299-
300-
// If the Certificate CR has no ownerRef, it's user-created — restore the secret
301-
if len(cert.GetOwnerReferences()) == 0 {
302-
return false
303-
}
304-
305-
// Operator-created, non-CA certificate — cert-manager will regenerate
306-
log.V(1).Info("Skipping operator-managed cert secret (will be regenerated)",
307-
"secret", secret.Name, "certificate", certName)
308-
return true
309-
}
310-
311240
// labelSecrets labels secrets in the target namespace.
312-
// Secrets managed by cert-manager for operator-created non-CA Certificates get
313-
// restore: "false" — cert-manager will regenerate them from the restored CA Issuer.
241+
// Secrets that already have a restore label (set by the controlplane controller
242+
// for cert-manager secrets) are skipped — the operator knows best whether a cert
243+
// secret should be restored or regenerated.
314244
// User annotation overrides take precedence over all default behavior.
315245
func (r *OpenStackBackupConfigReconciler) labelSecrets(ctx context.Context, log logr.Logger, instance *backupv1beta1.OpenStackBackupConfig) (int, error) {
316246
secretList := &corev1.SecretList{}
@@ -335,16 +265,13 @@ func (r *OpenStackBackupConfigReconciler) labelSecrets(ctx context.Context, log
335265
continue
336266
}
337267

338-
if !shouldLabelResource(secret, instance.Spec.Secrets) {
268+
// Skip secrets that already have a restore label (set by the operator
269+
// at creation time, e.g. cert-manager CA/leaf cert secrets)
270+
if _, hasRestoreLabel := secret.Labels[backup.BackupRestoreLabel]; hasRestoreLabel {
339271
continue
340272
}
341273

342-
// Operator-managed non-CA cert secrets: explicitly set restore=false
343-
if r.isCertManagerOperatorSecret(ctx, log, secret) {
344-
if err := r.labelResourceRestoreFalse(ctx, log, secret); err != nil {
345-
log.Error(err, "Failed to label cert secret restore=false", "name", secret.Name)
346-
errs = append(errs, fmt.Errorf("secret %s: %w", secret.Name, err))
347-
}
274+
if !shouldLabelResource(secret, instance.Spec.Secrets) {
348275
continue
349276
}
350277

internal/dataplane/cert.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import (
3737
certmgrv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
3838
infranetworkv1 "github.com/openstack-k8s-operators/infra-operator/apis/network/v1beta1"
3939
"github.com/openstack-k8s-operators/lib-common/modules/certmanager"
40+
"github.com/openstack-k8s-operators/lib-common/modules/common/backup"
4041
"github.com/openstack-k8s-operators/lib-common/modules/common/helper"
4142
"github.com/openstack-k8s-operators/lib-common/modules/common/secret"
4243
"github.com/openstack-k8s-operators/lib-common/modules/common/util"
@@ -114,10 +115,11 @@ func EnsureTLSCerts(ctx context.Context, helper *helper.Helper,
114115
// For now we just add the hostname so we can select all the certs on one node
115116
hostName := node.HostName
116117
labels := map[string]string{
117-
HostnameLabel: hostName,
118-
ServiceLabel: service.Name,
119-
ServiceKeyLabel: certKey,
120-
NodeSetLabel: instance.Name,
118+
HostnameLabel: hostName,
119+
ServiceLabel: service.Name,
120+
ServiceKeyLabel: certKey,
121+
NodeSetLabel: instance.Name,
122+
backup.BackupRestoreLabel: "false",
121123
}
122124
certName = service.Name + "-" + certKey + "-" + hostName
123125

internal/openstack/ca.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
certmgrv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
1818
certmgrmetav1 "github.com/cert-manager/cert-manager/pkg/apis/meta/v1"
1919
"github.com/openstack-k8s-operators/lib-common/modules/certmanager"
20+
"github.com/openstack-k8s-operators/lib-common/modules/common/backup"
2021
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
2122
"github.com/openstack-k8s-operators/lib-common/modules/common/helper"
2223
"github.com/openstack-k8s-operators/lib-common/modules/common/secret"
@@ -654,9 +655,11 @@ func createRootCACertAndIssuer(
654655
Duration: caCfg.Duration,
655656
RenewBefore: caCfg.RenewBefore,
656657
SecretTemplate: &certmgrv1.CertificateSecretTemplate{
657-
Labels: map[string]string{
658-
caCertSelector: "",
659-
},
658+
Labels: util.MergeMaps(
659+
map[string]string{caCertSelector: ""},
660+
backup.GetBackupLabels(backup.CategoryControlPlane),
661+
backup.GetRestoreLabels(backup.RestoreOrder10, backup.CategoryControlPlane),
662+
),
660663
},
661664
})
662665
cert := certmanager.NewCertificate(caCertReq, 5)

internal/openstack/common.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
ironicv1 "github.com/openstack-k8s-operators/ironic-operator/api/v1beta1"
2222
keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1"
2323
"github.com/openstack-k8s-operators/lib-common/modules/certmanager"
24+
"github.com/openstack-k8s-operators/lib-common/modules/common/backup"
2425
"github.com/openstack-k8s-operators/lib-common/modules/common/clusterdns"
2526
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
2627
"github.com/openstack-k8s-operators/lib-common/modules/common/helper"
@@ -331,7 +332,7 @@ func EnsureEndpointConfig(
331332
},
332333
Ips: nil,
333334
Annotations: ed.Annotations,
334-
Labels: util.MergeMaps(ed.Labels, map[string]string{serviceCertSelector: ""}),
335+
Labels: util.MergeMaps(ed.Labels, map[string]string{serviceCertSelector: "", backup.BackupRestoreLabel: "false"}),
335336
Usages: nil,
336337
}
337338

@@ -381,7 +382,7 @@ func EnsureEndpointConfig(
381382
},
382383
Ips: nil,
383384
Annotations: ed.Annotations,
384-
Labels: util.MergeMaps(ed.Labels, map[string]string{serviceCertSelector: ""}),
385+
Labels: util.MergeMaps(ed.Labels, map[string]string{serviceCertSelector: "", backup.BackupRestoreLabel: "false"}),
385386
Usages: nil,
386387
}
387388

@@ -638,7 +639,7 @@ func (ed *EndpointDetail) CreateRoute(
638639
Hostnames: []string{*ed.Hostname},
639640
Ips: nil,
640641
Annotations: ed.Annotations,
641-
Labels: util.MergeMaps(ed.Labels, map[string]string{serviceCertSelector: ""}),
642+
Labels: util.MergeMaps(ed.Labels, map[string]string{serviceCertSelector: "", backup.BackupRestoreLabel: "false"}),
642643
Usages: nil,
643644
}
644645
if instance.Spec.TLS.Ingress.Cert.Duration != nil {

0 commit comments

Comments
 (0)