Skip to content

Commit 9cc729f

Browse files
authored
[v0.13] Fix namespace label equality check and nil map panic (#5174)
* 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 6a6e4ef commit 9cc729f

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
@@ -3,7 +3,7 @@ package deployer
33
import (
44
"context"
55
"fmt"
6-
"reflect"
6+
"maps"
77
"regexp"
88
"strings"
99

@@ -177,25 +177,28 @@ func (d *Deployer) setNamespaceLabelsAndAnnotations(ctx context.Context, bd *fle
177177
return err
178178
}
179179

180-
if reflect.DeepEqual(bd.Spec.Options.NamespaceLabels, ns.Labels) && reflect.DeepEqual(bd.Spec.Options.NamespaceAnnotations, ns.Annotations) {
181-
return nil
182-
}
183-
180+
desiredLabels := maps.Clone(ns.Labels)
184181
if bd.Spec.Options.NamespaceLabels != nil {
185-
addLabelsFromOptions(log.FromContext(ctx), ns.Labels, bd.Spec.Options.NamespaceLabels)
182+
if desiredLabels == nil {
183+
desiredLabels = make(map[string]string)
184+
}
185+
addLabelsFromOptions(log.FromContext(ctx), desiredLabels, bd.Spec.Options.NamespaceLabels)
186186
}
187+
desiredAnnotations := maps.Clone(ns.Annotations)
187188
if bd.Spec.Options.NamespaceAnnotations != nil {
188-
if ns.Annotations == nil {
189-
ns.Annotations = map[string]string{}
189+
if desiredAnnotations == nil {
190+
desiredAnnotations = make(map[string]string)
190191
}
191-
addAnnotationsFromOptions(ns.Annotations, bd.Spec.Options.NamespaceAnnotations)
192+
addAnnotationsFromOptions(desiredAnnotations, bd.Spec.Options.NamespaceAnnotations)
192193
}
193-
err = d.updateNamespace(ctx, ns)
194-
if err != nil {
195-
return err
194+
195+
if maps.Equal(desiredLabels, ns.Labels) && maps.Equal(desiredAnnotations, ns.Annotations) {
196+
return nil
196197
}
197198

198-
return nil
199+
ns.Labels = desiredLabels
200+
ns.Annotations = desiredAnnotations
201+
return d.updateNamespace(ctx, ns)
199202
}
200203

201204
// updateNamespace updates a namespace resource in the cluster.
@@ -222,7 +225,10 @@ func (d *Deployer) fetchNamespace(ctx context.Context, releaseID string) (*corev
222225

223226
const podSecurityLabelPrefix = "pod-security.kubernetes.io/"
224227

225-
// 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.
228+
// addLabelsFromOptions updates nsLabels to contain labels from optLabels, while preserving
229+
// the `kubernetes.io/metadata.name` label added by Kubernetes when creating the namespace
230+
// and any existing `pod-security.kubernetes.io/*` labels. Labels with the
231+
// `pod-security.kubernetes.io/` prefix in optLabels are ignored.
226232
func addLabelsFromOptions(logger logr.Logger, nsLabels map[string]string, optLabels map[string]string) {
227233
for k, v := range optLabels {
228234
if strings.HasPrefix(k, podSecurityLabelPrefix) {

0 commit comments

Comments
 (0)