Skip to content

Commit c8932b5

Browse files
authored
[v0.15] Fix namespace label equality check and nil map panic (#5172)
* Fix namespace label equality check before update Compare the computed desired state against the current namespace labels and annotations instead of comparing raw options directly. The previous reflect.DeepEqual check could never return true because ns.Labels always includes kubernetes.io/metadata.name (and now also preserved pod-security labels), causing an unnecessary updateNamespace call on every reconcile even when no label changes were needed. * Fix nil map panic and update addLabelsFromOptions doc comment addLabelsFromOptions panics when ns.Labels is nil (maps.Clone returns nil) and NamespaceLabels options are non-nil. Add the same nil guard already present for annotations. Update the function doc comment to reflect the actual label retention rules: options labels, kubernetes.io/metadata.name, and existing pod-security.kubernetes.io/* labels are preserved; pod-security labels from options are ignored.
1 parent 6cbe000 commit c8932b5

1 file changed

Lines changed: 20 additions & 14 deletions

File tree

internal/cmd/agent/deployer/deployer.go

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"context"
55
"errors"
66
"fmt"
7-
"reflect"
7+
"maps"
88
"regexp"
99
"strings"
1010

@@ -197,25 +197,28 @@ func (d *Deployer) setNamespaceLabelsAndAnnotations(ctx context.Context, bd *fle
197197
return err
198198
}
199199

200-
if reflect.DeepEqual(bd.Spec.Options.NamespaceLabels, ns.Labels) && reflect.DeepEqual(bd.Spec.Options.NamespaceAnnotations, ns.Annotations) {
201-
return nil
202-
}
203-
200+
desiredLabels := maps.Clone(ns.Labels)
204201
if bd.Spec.Options.NamespaceLabels != nil {
205-
addLabelsFromOptions(log.FromContext(ctx), ns.Labels, bd.Spec.Options.NamespaceLabels)
202+
if desiredLabels == nil {
203+
desiredLabels = make(map[string]string)
204+
}
205+
addLabelsFromOptions(log.FromContext(ctx), desiredLabels, bd.Spec.Options.NamespaceLabels)
206206
}
207+
desiredAnnotations := maps.Clone(ns.Annotations)
207208
if bd.Spec.Options.NamespaceAnnotations != nil {
208-
if ns.Annotations == nil {
209-
ns.Annotations = map[string]string{}
209+
if desiredAnnotations == nil {
210+
desiredAnnotations = make(map[string]string)
210211
}
211-
addAnnotationsFromOptions(ns.Annotations, bd.Spec.Options.NamespaceAnnotations)
212+
addAnnotationsFromOptions(desiredAnnotations, bd.Spec.Options.NamespaceAnnotations)
212213
}
213-
err = d.updateNamespace(ctx, ns)
214-
if err != nil {
215-
return err
214+
215+
if maps.Equal(desiredLabels, ns.Labels) && maps.Equal(desiredAnnotations, ns.Annotations) {
216+
return nil
216217
}
217218

218-
return nil
219+
ns.Labels = desiredLabels
220+
ns.Annotations = desiredAnnotations
221+
return d.updateNamespace(ctx, ns)
219222
}
220223

221224
// updateNamespace updates a namespace resource in the cluster.
@@ -242,7 +245,10 @@ func (d *Deployer) fetchNamespace(ctx context.Context, releaseID string) (*corev
242245

243246
const podSecurityLabelPrefix = "pod-security.kubernetes.io/"
244247

245-
// addLabelsFromOptions updates nsLabels so that it only contains all labels specified in optLabels, plus the `kubernetes.io/metadata.name` labels added by kubernetes when creating the namespace.
248+
// addLabelsFromOptions updates nsLabels to contain labels from optLabels, while preserving
249+
// the `kubernetes.io/metadata.name` label added by Kubernetes when creating the namespace
250+
// and any existing `pod-security.kubernetes.io/*` labels. Labels with the
251+
// `pod-security.kubernetes.io/` prefix in optLabels are ignored.
246252
func addLabelsFromOptions(logger logr.Logger, nsLabels map[string]string, optLabels map[string]string) {
247253
for k, v := range optLabels {
248254
if strings.HasPrefix(k, podSecurityLabelPrefix) {

0 commit comments

Comments
 (0)