diff --git a/docs/advanced/master-commandline-reference.md b/docs/advanced/master-commandline-reference.md index a1aa8e876..73b9bbc82 100644 --- a/docs/advanced/master-commandline-reference.md +++ b/docs/advanced/master-commandline-reference.md @@ -175,9 +175,10 @@ nfd-master -label-whitelist='.*cpuid\.' The `-extra-label-ns` flag specifies a comma-separated list of allowed feature label namespaces. By default, nfd-master only allows creating labels in the -default `feature.node.kubernetes.io` label namespace. This option can be used -to allow vendor-specific namespaces for custom labels from the local and custom -feature sources. +default `feature.node.kubernetes.io` label namespace and its sub-namespaces +(e.g. `vendor.feature.node.kubernetes.io`). This option can be used to allow +other vendor or application specific namespaces for custom labels from the +local and custom feature sources. The same namespace control and this flag applies Extended Resources (created with `-resource-labels`), too. diff --git a/docs/get-started/features.md b/docs/get-started/features.md index c254d259b..158b7d638 100644 --- a/docs/get-started/features.md +++ b/docs/get-started/features.md @@ -27,7 +27,15 @@ feature sources that work accross the system. Each discovered feature is advertised a label in the Kubernetes Node object. The published node labels encode a few pieces of information: -- Namespace, (all built-in labels use `feature.node.kubernetes.io`) +- Namespace + - all built-in labels use `feature.node.kubernetes.io` + - user-specified custom labels ([custom](#custom) and + [local](#local--user-specific-features) feature sources) + - `feature.node.kubernetes.io` and its sub-namespaces (e.g. + `vendor.profile.node.kubernetes.io`) are allowed by default + - additional namespaces may be enabled with the + [`--extra-label-ns`](../advanced/master-commandline-reference#-extra-label-ns) + command line flag of nfd-master - The source for each label (e.g. `cpu`). - The name of the discovered feature as it appears in the underlying source, (e.g. `cpuid.AESNI` from cpu). @@ -354,7 +362,7 @@ custom: pciId: vendor: ["15b3"] device: ["1014", "1017"] - - name: "my.accumulated.feature" + - name: "vendor.feature.node.kubernetes.io/accumulated.feature" matchOn: - loadedKMod : ["some_kmod1", "some_kmod2"] - pciId: @@ -392,7 +400,7 @@ __In the example above:__ contains a PCI device with a PCI vendor ID of `15b3` _AND_ PCI device ID of `1014` _or_ `1017`. - A node would contain the label: - `feature.node.kubernetes.io/custom-my.accumulated.feature=true` if + `vendor.feature.node.kubernetes.io/accumulated.feature=true` if `some_kmod1` _AND_ `some_kmod2` kernel modules are loaded __OR__ the node contains a PCI device with a PCI vendor ID of `15b3` _AND_ PCI device ID of `1014` _OR_ `1017`. @@ -568,8 +576,10 @@ This makes it possible for the user to fully control the feature label names, e.g. for overriding labels created by other feature sources. You can also override the default namespace of your labels using this format: -`/[=]`. You must whitelist your namespace using the -`-extra-label-ns` option on the master. In this case, the name of the +`/[=]`. If using something else than +`[.]feature.node.kubernetes.io`, you must whitelist your namespace +using the `-extra-label-ns` option on the master. +In this case, the name of the file will not be added to the label name. For example, if you want to add the label `my.namespace.org/my-label=value`, your hook output or file must contains `my.namespace.org/my-label=value` and you must add diff --git a/pkg/nfd-master/nfd-master-internal_test.go b/pkg/nfd-master/nfd-master-internal_test.go index 4e957cba8..bf5ea8e62 100644 --- a/pkg/nfd-master/nfd-master-internal_test.go +++ b/pkg/nfd-master/nfd-master-internal_test.go @@ -354,15 +354,18 @@ func TestSetLabels(t *testing.T) { Convey("When --extra-label-ns and --instance are specified", func() { // In the gRPC request the label names may omit the default ns instance := "foo" + vendorLabel := "vendor." + LabelNs + "/feature-4" mockLabels := map[string]string{"feature-1": "val-1", "valid.ns/feature-2": "val-2", - "invalid.ns/feature-3": "val-3"} + "invalid.ns/feature-3": "val-3", + vendorLabel: " val-4"} expectedPatches := []apihelper.JsonPatch{ apihelper.NewJsonPatch("add", "/metadata/annotations", instance+"."+wvAnnotation, workerVer), - apihelper.NewJsonPatch("add", "/metadata/annotations", instance+"."+flAnnotation, "feature-1,valid.ns/feature-2"), + apihelper.NewJsonPatch("add", "/metadata/annotations", instance+"."+flAnnotation, "feature-1,valid.ns/feature-2,"+vendorLabel), apihelper.NewJsonPatch("add", "/metadata/annotations", instance+"."+erAnnotation, ""), apihelper.NewJsonPatch("add", "/metadata/labels", LabelNs+"/feature-1", mockLabels["feature-1"]), apihelper.NewJsonPatch("add", "/metadata/labels", "valid.ns/feature-2", mockLabels["valid.ns/feature-2"]), + apihelper.NewJsonPatch("add", "/metadata/labels", vendorLabel, mockLabels[vendorLabel]), } mockMaster.args.ExtraLabelNs = map[string]struct{}{"valid.ns": {}} diff --git a/pkg/nfd-master/nfd-master.go b/pkg/nfd-master/nfd-master.go index 508450fd4..ae18c85e1 100644 --- a/pkg/nfd-master/nfd-master.go +++ b/pkg/nfd-master/nfd-master.go @@ -46,6 +46,9 @@ const ( // LabelNs defines the Namespace for feature labels LabelNs = "feature.node.kubernetes.io" + // LabelSubNsSuffix is the suffix for allowed label sub-namespaces + LabelSubNsSuffix = "." + LabelNs + // AnnotationNsBase namespace for all NFD-related annotations AnnotationNsBase = "nfd.node.kubernetes.io" @@ -314,7 +317,7 @@ func filterFeatureLabels(labels Labels, extraLabelNs map[string]struct{}, labelW ns, name := splitNs(label) // Check label namespace, filter out if ns is not whitelisted - if ns != LabelNs { + if ns != LabelNs && !strings.HasSuffix(ns, LabelSubNsSuffix) { if _, ok := extraLabelNs[ns]; !ok { klog.Errorf("Namespace %q is not allowed. Ignoring label %q\n", ns, label) continue