Skip to content
This repository was archived by the owner on Apr 17, 2025. It is now read-only.

Commit 4d4a0c8

Browse files
authored
Merge pull request #299 from duduedri96/dev/cherry-pick-of-#293-v1.1
Cherry pick of #293 to v1.1
2 parents 0fc9d45 + b04dd8e commit 4d4a0c8

File tree

7 files changed

+74
-18
lines changed

7 files changed

+74
-18
lines changed

cmd/manager/main.go

+23
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package main
1818
import (
1919
"errors"
2020
"flag"
21+
"fmt"
2122
"net/http"
2223
"os"
2324
"strings"
@@ -72,6 +73,7 @@ var (
7273
excludedNamespaces arrayArg
7374
managedNamespaceLabels arrayArg
7475
managedNamespaceAnnots arrayArg
76+
nopropagationLabel arrayArg
7577
includedNamespacesRegex string
7678
webhooksOnly bool
7779
enableHRQ bool
@@ -156,10 +158,31 @@ func parseFlags() {
156158
flag.BoolVar(&enableHRQ, "enable-hrq", false, "Enables hierarchical resource quotas")
157159
flag.StringVar(&hncNamespace, "namespace", "hnc-system", "Namespace where hnc-manager and hnc resources deployed")
158160
flag.DurationVar(&hrqSyncInterval, "hrq-sync-interval", 1*time.Minute, "Frequency to double-check that all HRQ usages are up-to-date (shouldn't be needed)")
161+
flag.Var(&nopropagationLabel, "nopropagation-label", "A label specified as key=val that, if present, will cause HNC to skip objects that match this label. May be specified multiple times, with each key=value pair specifying one label. See the user guide for more information.")
159162
flag.Parse()
160163

161164
// Assign the array args to the configuration variables after the args are parsed.
162165
config.UnpropagatedAnnotations = unpropagatedAnnotations
166+
167+
// Assign the exclusion label args to the configuration
168+
for _, label := range nopropagationLabel {
169+
keyVal := strings.Split(label, "=")
170+
if len(keyVal) != 2 {
171+
setupLog.Info(fmt.Sprintf("--nopropagation-label must contain exactly one equal sign (=): %s", label))
172+
os.Exit(1)
173+
}
174+
labelKey := keyVal[0]
175+
labelValue := keyVal[1]
176+
177+
if len(labelKey) == 0 {
178+
setupLog.Info(fmt.Sprintf("--nopropagation-label must not have an empty key for the label: %s", label))
179+
os.Exit(1)
180+
}
181+
182+
setupLog.Info(fmt.Sprintf("Will exclude objects that match label %s", label))
183+
config.NoPropagationLabels = append(config.NoPropagationLabels, config.NoPropagationLabel{Key: labelKey, Value: labelValue})
184+
}
185+
163186
config.SetNamespaces(includedNamespacesRegex, excludedNamespaces...)
164187
if err := config.SetManagedMeta(managedNamespaceLabels, managedNamespaceAnnots); err != nil {
165188
setupLog.Error(err, "Illegal flag values")

config/manager/manager.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ spec:
4949
- "--excluded-namespace=kube-public"
5050
- "--excluded-namespace=hnc-system"
5151
- "--excluded-namespace=kube-node-lease"
52+
# Preserves the existing behavior of skipping Rancher objects.
53+
# Please don't add any more nopropagation labels to the list of args.
54+
- "--nopropagation-label=cattle.io/creator=norman"
5255
ports:
5356
- containerPort: 9443
5457
name: webhook-server

docs/user-guide/concepts.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,10 @@ objects from being propagated by HNC.
445445
auto-created in new namespaces by Istio and Kubernetes respectively
446446
* Any objects with the label
447447
`cattle.io/creator:norman`, which are [inserted by Rancher to support
448-
Projects](https://rancher.com/docs/rancher/v2.6/en/system-tools/#remove))
448+
Projects](https://rancher.com/docs/rancher/v2.6/en/system-tools/#remove)).
449+
Can be disabled by removing the default command line argument on the manager
450+
`--nopropagation-label=cattle.io/creator=norman`. Refer to [How-to:
451+
Modify command-line arguments](how-to.md#modify-command-line-arguments) for more details.
449452
* *HNC v1.1+:* Secrets with type `helm.sh/release.v1`, which is auto-created in
450453
the namespaces where their respective Helm releases are deployed to.
451454

docs/user-guide/how-to.md

+9
Original file line numberDiff line numberDiff line change
@@ -972,3 +972,12 @@ Interesting parameters include:
972972
load on your metrics database (through increased metric cardinality) and also
973973
by increasing how carefully you need to guard your metrics against
974974
unauthorized viewers.
975+
* `--nopropagation-label`: has the same effect as the `propagate.hnc.x-k8s.io/none`
976+
annotation as specified in [limiting propagation](how-to.md#limit-the-propagation-of-an-object-to-descendant-namespaces),
977+
but is useful when there's no control over what annotations the object has in order
978+
to disable the propagation of that object. This argument may be specified multiple
979+
times, with each parameter representing one `key=val` pair of a label that should
980+
exclude an object from propagation.
981+
* Rancher objects that have the label `cattle.io/creator=norman` are not propagated
982+
by the default manifests (refer to [Concepts: built in exceptions](concepts.md#built-in-exceptions)
983+
for more information).

internal/config/default_config.go

+11
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,14 @@ package config
88
// This value is controlled by the --unpropagated-annotation command line, which may be set multiple
99
// times.
1010
var UnpropagatedAnnotations []string
11+
12+
// NoPropagationLabel specifies a label Key and Value which will cause an object to be excluded
13+
// from propagation if the object defines that label with this specific value.
14+
type NoPropagationLabel struct {
15+
Key string
16+
Value string
17+
}
18+
19+
// NoPropagationLabels is a configuration slice that contains all NoPropagationLabel labels that should
20+
// cause objects to be ignored from propagation.
21+
var NoPropagationLabels []NoPropagationLabel

internal/objects/reconciler_test.go

+18-1
Original file line numberDiff line numberDiff line change
@@ -446,15 +446,20 @@ var _ = Describe("Basic propagation", func() {
446446
Eventually(HasObject(ctx, "secrets", barName, "helm-secret")).Should(BeFalse())
447447
})
448448

449-
It("should not propagate builtin exclusions by labels", func() {
449+
It("should not propagate objects excluded by labels", func() {
450450
SetParent(ctx, barName, fooName)
451+
config.NoPropagationLabels = append(config.NoPropagationLabels, config.NoPropagationLabel{Key: "cattle.io/creator", Value: "norman"})
452+
config.NoPropagationLabels = append(config.NoPropagationLabels, config.NoPropagationLabel{Key: "ignore-label", Value: "label"})
453+
451454
MakeObjectWithLabels(ctx, "roles", fooName, "role-with-labels-blocked", map[string]string{"cattle.io/creator": "norman"})
455+
MakeObjectWithLabels(ctx, "roles", fooName, "role-with-labels-blocked-2", map[string]string{"ignore-label": "label"})
452456
MakeObjectWithLabels(ctx, "roles", fooName, "role-with-labels-wrong-value", map[string]string{"cattle.io/creator": "testme"})
453457
MakeObjectWithLabels(ctx, "roles", fooName, "role-with-labels-something", map[string]string{"app": "hello-world"})
454458
AddToHNCConfig(ctx, api.RBACGroup, api.RoleKind, api.Propagate)
455459

456460
// the first one should not propagate, everything else should
457461
Consistently(HasObject(ctx, "roles", barName, "role-with-labels-blocked")).Should(BeFalse())
462+
Consistently(HasObject(ctx, "roles", barName, "role-with-labels-blocked-2")).Should(BeFalse())
458463
Eventually(HasObject(ctx, "roles", barName, "role-with-labels-wrong-value")).Should(BeTrue())
459464
Eventually(HasObject(ctx, "roles", barName, "role-with-labels-something")).Should(BeTrue())
460465

@@ -467,6 +472,18 @@ var _ = Describe("Basic propagation", func() {
467472
Eventually(HasObject(ctx, "configmaps", barName, "cm-with-label-2")).Should(BeTrue())
468473
})
469474

475+
It("should not propagate objects excluded by labels when using all annotation", func() {
476+
SetParent(ctx, barName, fooName)
477+
config.NoPropagationLabels = append(config.NoPropagationLabels, config.NoPropagationLabel{Key: "cattle.io/creator", Value: "norman"})
478+
479+
MakeObjectWithLabels(ctx, "roles", fooName, "role-with-labels-blocked", map[string]string{"cattle.io/creator": "norman"})
480+
UpdateObjectWithAnnotations(ctx, "roles", fooName, "role-with-labels-blocked", map[string]string{"propagate.hnc.x-k8s.io/all": "true"})
481+
AddToHNCConfig(ctx, api.RBACGroup, api.RoleKind, api.Propagate)
482+
483+
// The object should not be propagated even though it uses the `all` annotation
484+
Consistently(HasObject(ctx, "roles", barName, "role-with-labels-blocked")).Should(BeFalse())
485+
})
486+
470487
It("should be removed if the hierarchy changes", func() {
471488
SetParent(ctx, barName, fooName)
472489
SetParent(ctx, bazName, barName)

internal/selectors/selectors.go

+6-16
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"k8s.io/apimachinery/pkg/util/validation"
1414

1515
api "sigs.k8s.io/hierarchical-namespaces/api/v1alpha2"
16+
"sigs.k8s.io/hierarchical-namespaces/internal/config"
1617
)
1718

1819
// ShouldPropagate returns true if the given object should be propagated
@@ -43,8 +44,10 @@ func ShouldPropagate(inst *unstructured.Unstructured, nsLabels labels.Set, mode
4344
if none, err := GetNoneSelector(inst); err != nil || none {
4445
return false, err
4546
}
46-
if all, err := GetAllSelector(inst); err != nil || all {
47-
return true, err
47+
if all, err := GetAllSelector(inst); err != nil {
48+
return false, err
49+
} else if all {
50+
propIfNotExcluded = true
4851
}
4952
if excluded, err := isExcluded(inst); excluded {
5053
return false, err
@@ -197,19 +200,6 @@ func GetAllSelector(inst *unstructured.Unstructured) (bool, error) {
197200
// cmExclusionsByName are known (istio and kube-root) CA configmap which are excluded from propagation
198201
var cmExclusionsByName = []string{"istio-ca-root-cert", "kube-root-ca.crt"}
199202

200-
// A label as a key, value pair, used to exclude resources matching this label (both key and value).
201-
type ExclusionByLabelsSpec struct {
202-
Key string
203-
Value string
204-
}
205-
206-
// ExclusionByLabelsSpec are known label key-value pairs which are excluded from propagation. Right
207-
// now only used to exclude resources created by Rancher, see "System Tools > Remove"
208-
// (https://rancher.com/docs/rancher/v2.6/en/system-tools/#remove)
209-
var exclusionByLabels = []ExclusionByLabelsSpec{
210-
{Key: "cattle.io/creator", Value: "norman"},
211-
}
212-
213203
// A annotation as a key, value pair, used to exclude resources matching this annotation
214204
type ExclusionByAnnotationsSpec struct {
215205
Key string
@@ -246,7 +236,7 @@ func isExcluded(inst *unstructured.Unstructured) (bool, error) {
246236
}
247237

248238
// exclusion by labels
249-
for _, res := range exclusionByLabels {
239+
for _, res := range config.NoPropagationLabels {
250240
gotLabelValue, ok := inst.GetLabels()[res.Key]
251241
// check for presence has to be explicit, as empty label values are allowed and a
252242
// nonexisting key in the `labels` map will also return an empty string ("") - potentially

0 commit comments

Comments
 (0)