Repository: kubernetes-sigs/node-feature-discovery
Pull request #1095 (2023-03-20 13:54:21)

e2e: add codecov uploader configuration
e2e: add codecov uploader configuration
Depends on https://github.com/kubernetes/test-infra/pull/29082.

netlify[bot]: ### <span aria-hidden="true">👷</span> Deploy Preview for *kubernetes-sigs-nfd* processing.


|  Name | Link |
|:-:|------------------------|
|<span aria-hidden="true">🔨</span> Latest commit | 44283f56fceda8232fcec337742bd6efac4ba4b0 |
|<span aria-hidden="true">🔍</span> Latest deploy log | https://app.netlify.com/sites/kubernetes-sigs-nfd/deploys/6418659107611100088f12ef |
marquiz: > For?

Download the codecov binary and upload the report. What you had in Makefile in the earler version
fmuyassarov: > > For?
> 
> Download the codecov binary and upload the report. What you had in Makefile in the earler version

ah, I read your comment too fast in https://github.com/kubernetes-sigs/node-feature-discovery/pull/1095#discussion_r1142980708 and understood that we want it to be as part of the test infra Prow job definition. I just noticed when read your comment again :) So, currently it is done in https://github.com/kubernetes/test-infra/pull/29101. We can keep wither there or in verify.sh. I don't have any preferences here.
marquiz: > ah, I read your comment too fast in [#1095 (comment)](https://github.com/kubernetes-sigs/node-feature-discovery/pull/1095#discussion_r1142980708) and understood that we want it to be as part of the test infra Prow job definition. I just noticed when read your comment again :) So, currently it is done in [kubernetes/test-infra#29101](https://github.com/kubernetes/test-infra/pull/29101). We can keep wither there or in verify.sh. I don't have any preferences here.

Ach sorry, I didn't realize that. I think it would make sense to move the stuff from [kubernetes/test-infra#29101](https://github.com/kubernetes/test-infra/pull/29101) to `scripts/test-infra/verify.sh`. Makes it easier to read and maintain IMO, plus we already do a bunch of installation/setup steps in verify.sh so it is logical to keep all of that in one place. WDYT?
ArangoGutierrez: Where are we here?  Can we think of v0.13 for this? or push to v0.14? 
marquiz: @fmuyassarov is on PTO. We can push this beyond v0.13, not a user facing feature
fmuyassarov: /hold 
until keys are created

Patch:
diff --git a/Dockerfile b/Dockerfile
index cf2192a52..b4130e10c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,7 +6,7 @@ ARG BASE_IMAGE_MINIMAL
 FROM ${BUILDER_IMAGE} as builder
 
 # Build and install the grpc-health-probe binary
-RUN GRPC_HEALTH_PROBE_VERSION=v0.4.17 && \
+RUN GRPC_HEALTH_PROBE_VERSION=v0.4.14 && \
 	go install github.com/grpc-ecosystem/grpc-health-probe@${GRPC_HEALTH_PROBE_VERSION} \
         # Rename it as it's referenced as grpc_health_probe in the deployment yamls
         # and in its own project https://github.com/grpc-ecosystem/grpc-health-probe
diff --git a/Makefile b/Makefile
index b3f41b3c1..a1b60a3d9 100644
--- a/Makefile
+++ b/Makefile
@@ -120,13 +120,8 @@ templates:
 	@# Need to prepend each line in the sample config with spaces in order to
 	@# fit correctly in the configmap spec.
 	@sed s'/^/    /' deployment/components/worker-config/nfd-worker.conf.example > nfd-worker.conf.tmp
-	@sed s'/^/    /' deployment/components/master-config/nfd-master.conf.example > nfd-master.conf.tmp
 	@sed s'/^/    /' deployment/components/topology-updater-config/nfd-topology-updater.conf.example > nfd-topology-updater.conf.tmp
 	@# The sed magic below replaces the block of text between the lines with start and end markers
-	@start=NFD-MASTER-CONF-START-DO-NOT-REMOVE; \
-	end=NFD-MASTER-CONF-END-DO-NOT-REMOVE; \
-	sed -e "/$$start/,/$$end/{ /$$start/{ p; r nfd-master.conf.tmp" \
-	    -e "}; /$$end/p; d }" -i deployment/helm/node-feature-discovery/values.yaml
 	@start=NFD-WORKER-CONF-START-DO-NOT-REMOVE; \
 	end=NFD-WORKER-CONF-END-DO-NOT-REMOVE; \
 	sed -e "/$$start/,/$$end/{ /$$start/{ p; r nfd-worker.conf.tmp" \
@@ -135,7 +130,6 @@ templates:
 	end=NFD-TOPOLOGY-UPDATER-CONF-END-DO-NOT-REMOVE; \
 	sed -e "/$$start/,/$$end/{ /$$start/{ p; r nfd-topology-updater.conf.tmp" \
 		-e "}; /$$end/p; d }" -i deployment/helm/node-feature-discovery/values.yaml
-	@rm nfd-master.conf.tmp
 	@rm nfd-worker.conf.tmp
 	@rm nfd-topology-updater.conf.tmp
 
diff --git a/README.md b/README.md
index 326d908c3..fbce5e7e7 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ features and system configuration!
 #### Quick-start – the short-short version
 
 ```bash
-$ kubectl apply -k https://github.com/kubernetes-sigs/node-feature-discovery/deployment/overlays/default?ref=v0.12.2
+$ kubectl apply -k https://github.com/kubernetes-sigs/node-feature-discovery/deployment/overlays/default?ref=v0.12.1
   namespace/node-feature-discovery created
   customresourcedefinition.apiextensions.k8s.io/nodefeaturerules.nfd.k8s-sigs.io created
   serviceaccount/nfd-master created
diff --git a/cmd/nfd-master/main.go b/cmd/nfd-master/main.go
index 58d0ca432..7f1d582c8 100644
--- a/cmd/nfd-master/main.go
+++ b/cmd/nfd-master/main.go
@@ -20,6 +20,7 @@ import (
 	"flag"
 	"fmt"
 	"os"
+	"regexp"
 
 	"k8s.io/klog/v2"
 
@@ -38,7 +39,7 @@ func main() {
 
 	printVersion := flags.Bool("version", false, "Print version and exit.")
 
-	args, overrides := initFlags(flags)
+	args := initFlags(flags)
 	// Inject klog flags
 	klog.InitFlags(flags)
 
@@ -54,18 +55,6 @@ func main() {
 		switch f.Name {
 		case "featurerules-controller":
 			klog.Warningf("-featurerules-controller is deprecated, use '-crd-controller' flag instead")
-		case "extra-label-ns":
-			args.Overrides.ExtraLabelNs = overrides.ExtraLabelNs
-		case "deny-label-ns":
-			args.Overrides.DenyLabelNs = overrides.DenyLabelNs
-		case "label-whitelist":
-			args.Overrides.LabelWhiteList = overrides.LabelWhiteList
-		case "resource-labels":
-			args.Overrides.ResourceLabels = overrides.ResourceLabels
-		case "enable-taints":
-			args.Overrides.EnableTaints = overrides.EnableTaints
-		case "no-publish":
-			args.Overrides.NoPublish = overrides.NoPublish
 		}
 	})
 
@@ -93,23 +82,35 @@ func main() {
 	}
 }
 
-func initFlags(flagset *flag.FlagSet) (*master.Args, *master.ConfigOverrideArgs) {
-	args := &master.Args{}
+func initFlags(flagset *flag.FlagSet) *master.Args {
+	args := &master.Args{
+		LabelWhiteList: utils.RegexpVal{Regexp: *regexp.MustCompile("")},
+		DenyLabelNs:    map[string]struct{}{"*.kubernetes.io": {}},
+	}
 
 	flagset.StringVar(&args.CaFile, "ca-file", "",
 		"Root certificate for verifying connections")
 	flagset.StringVar(&args.CertFile, "cert-file", "",
 		"Certificate used for authenticating connections")
+	flagset.Var(&args.DenyLabelNs, "deny-label-ns",
+		"Comma separated list of denied label namespaces")
+	flagset.Var(&args.ExtraLabelNs, "extra-label-ns",
+		"Comma separated list of allowed extra label namespaces")
 	flagset.StringVar(&args.Instance, "instance", "",
 		"Instance name. Used to separate annotation namespaces for multiple parallel deployments.")
 	flagset.StringVar(&args.KeyFile, "key-file", "",
 		"Private key matching -cert-file")
-	flagset.StringVar(&args.ConfigFile, "config", "/etc/kubernetes/node-feature-discovery/nfd-master.conf",
-		"Config file to use.")
 	flagset.StringVar(&args.Kubeconfig, "kubeconfig", "",
 		"Kubeconfig to use")
+	flagset.Var(&args.LabelWhiteList, "label-whitelist",
+		"Regular expression to filter label names to publish to the Kubernetes API server. "+
+			"NB: the label namespace is omitted i.e. the filter is only applied to the name part after '/'.")
 	flagset.BoolVar(&args.EnableNodeFeatureApi, "enable-nodefeature-api", false,
 		"Enable the NodeFeature CRD API for receiving node features. This will automatically disable the gRPC communication.")
+	flagset.BoolVar(&args.NoPublish, "no-publish", false,
+		"Do not publish feature labels")
+	flagset.BoolVar(&args.EnableTaints, "enable-taints", false,
+		"Enable node tainting feature")
 	flagset.BoolVar(&args.CrdController, "featurerules-controller", true,
 		"Enable NFD CRD API controller. DEPRECATED: use -crd-controller instead")
 	flagset.BoolVar(&args.CrdController, "crd-controller", true,
@@ -118,32 +119,11 @@ func initFlags(flagset *flag.FlagSet) (*master.Args, *master.ConfigOverrideArgs)
 		"Port on which to listen for connections.")
 	flagset.BoolVar(&args.Prune, "prune", false,
 		"Prune all NFD related attributes from all nodes of the cluaster and exit.")
+	flagset.Var(&args.ResourceLabels, "resource-labels",
+		"Comma separated list of labels to be exposed as extended resources.")
 	flagset.BoolVar(&args.VerifyNodeName, "verify-node-name", false,
 		"Verify worker node name against the worker's TLS certificate. "+
 			"Only takes effect when TLS authentication has been enabled.")
-	flagset.StringVar(&args.Options, "options", "",
-		"Specify config options from command line. Config options are specified "+
-			"in the same format as in the config file (i.e. json or yaml). These options")
-
-	overrides := &master.ConfigOverrideArgs{
-		LabelWhiteList: &utils.RegexpVal{},
-		DenyLabelNs:    &utils.StringSetVal{},
-		ExtraLabelNs:   &utils.StringSetVal{},
-		ResourceLabels: &utils.StringSetVal{},
-	}
-	flagset.Var(overrides.ExtraLabelNs, "extra-label-ns",
-		"Comma separated list of allowed extra label namespaces")
-	flagset.Var(overrides.LabelWhiteList, "label-whitelist",
-		"Regular expression to filter label names to publish to the Kubernetes API server. "+
-			"NB: the label namespace is omitted i.e. the filter is only applied to the name part after '/'.")
-	overrides.EnableTaints = flagset.Bool("enable-taints", false,
-		"Enable node tainting feature")
-	overrides.NoPublish = flagset.Bool("no-publish", false,
-		"Do not publish feature labels")
-	flagset.Var(overrides.DenyLabelNs, "deny-label-ns",
-		"Comma separated list of denied label namespaces")
-	flagset.Var(overrides.ResourceLabels, "resource-labels",
-		"Comma separated list of labels to be exposed as extended resources.")
 
-	return args, overrides
+	return args
 }
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 000000000..3fee5b700
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1,4 @@
+comment:
+  layout: "reach, diff, flags, files"
+  behavior: new
+  require_changes: false
diff --git a/deployment/base/master/master-deployment.yaml b/deployment/base/master/master-deployment.yaml
index e52c91a56..bb0e9979f 100644
--- a/deployment/base/master/master-deployment.yaml
+++ b/deployment/base/master/master-deployment.yaml
@@ -34,3 +34,6 @@ spec:
             failureThreshold: 10
           command:
             - "nfd-master"
+          args: []
+          volumeMounts: []
+      volumes: []
diff --git a/deployment/base/nfd-crds/nfd-api-crds.yaml b/deployment/base/nfd-crds/nfd-api-crds.yaml
index 775536f28..5d9e1e16d 100644
--- a/deployment/base/nfd-crds/nfd-api-crds.yaml
+++ b/deployment/base/nfd-crds/nfd-api-crds.yaml
@@ -155,11 +155,6 @@ spec:
                   description: Rule defines a rule for node customization such as
                     labeling.
                   properties:
-                    extendedResources:
-                      additionalProperties:
-                        type: string
-                      description: ExtendedResources to create if the rule matches.
-                      type: object
                     labels:
                       additionalProperties:
                         type: string
diff --git a/deployment/base/rbac/master-clusterrole.yaml b/deployment/base/rbac/master-clusterrole.yaml
index 155c5f069..d464e546e 100644
--- a/deployment/base/rbac/master-clusterrole.yaml
+++ b/deployment/base/rbac/master-clusterrole.yaml
@@ -7,7 +7,6 @@ rules:
   - ""
   resources:
   - nodes
-  - nodes/status
   verbs:
   - get
   - patch
diff --git a/deployment/components/common/kustomization.yaml b/deployment/components/common/kustomization.yaml
index 2776c6928..459b0cfa5 100644
--- a/deployment/components/common/kustomization.yaml
+++ b/deployment/components/common/kustomization.yaml
@@ -35,7 +35,3 @@ patches:
   target:
     labelSelector: app=nfd
     name: nfd
-- path: master-mounts.yaml
-  target:
-    labelSelector: app=nfd
-    name: nfd-master
diff --git a/deployment/components/common/master-mounts.yaml b/deployment/components/common/master-mounts.yaml
deleted file mode 100644
index 750f4241d..000000000
--- a/deployment/components/common/master-mounts.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-- op: add
-  path: /spec/template/spec/volumes
-  value:
-  - name: nfd-master-conf
-    configMap:
-      name: nfd-master-conf
-
-- op: add
-  path: /spec/template/spec/containers/0/volumeMounts
-  value:
-  - name: nfd-master-conf
-    mountPath: "/etc/kubernetes/node-feature-discovery"
-    readOnly: true
diff --git a/deployment/components/master-config/kustomization.yaml b/deployment/components/master-config/kustomization.yaml
deleted file mode 100644
index f042ce3d8..000000000
--- a/deployment/components/master-config/kustomization.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-apiVersion: kustomize.config.k8s.io/v1alpha1
-kind: Component
-
-generatorOptions:
-  disableNameSuffixHash: true
-
-configMapGenerator:
-- files:
-  - nfd-master.conf=nfd-master.conf.example
-  name: nfd-master-conf
diff --git a/deployment/components/master-config/nfd-master.conf.example b/deployment/components/master-config/nfd-master.conf.example
deleted file mode 100644
index 4f5ffffa3..000000000
--- a/deployment/components/master-config/nfd-master.conf.example
+++ /dev/null
@@ -1,6 +0,0 @@
-# noPublish: false
-# extraLabelNs: ["added.ns.io","added.kubernets.io"]
-# denyLabelNs: ["denied.ns.io","denied.kubernetes.io"]
-# resourceLabels: ["vendor-1.com/feature-1","vendor-2.io/feature-2"]
-# enableTaints: false
-# labelWhiteList: "foo"
diff --git a/deployment/helm/node-feature-discovery/crds/nfd-api-crds.yaml b/deployment/helm/node-feature-discovery/crds/nfd-api-crds.yaml
index 775536f28..5d9e1e16d 100644
--- a/deployment/helm/node-feature-discovery/crds/nfd-api-crds.yaml
+++ b/deployment/helm/node-feature-discovery/crds/nfd-api-crds.yaml
@@ -155,11 +155,6 @@ spec:
                   description: Rule defines a rule for node customization such as
                     labeling.
                   properties:
-                    extendedResources:
-                      additionalProperties:
-                        type: string
-                      description: ExtendedResources to create if the rule matches.
-                      type: object
                     labels:
                       additionalProperties:
                         type: string
diff --git a/deployment/helm/node-feature-discovery/templates/clusterrole.yaml b/deployment/helm/node-feature-discovery/templates/clusterrole.yaml
index 84b32644f..5cdef5718 100644
--- a/deployment/helm/node-feature-discovery/templates/clusterrole.yaml
+++ b/deployment/helm/node-feature-discovery/templates/clusterrole.yaml
@@ -10,7 +10,9 @@ rules:
   - ""
   resources:
   - nodes
+{{- if .Values.master.resourceLabels | empty | not }}
   - nodes/status
+{{- end }}
   verbs:
   - get
   - patch
diff --git a/deployment/helm/node-feature-discovery/templates/master.yaml b/deployment/helm/node-feature-discovery/templates/master.yaml
index 943b5ba1b..c259df529 100644
--- a/deployment/helm/node-feature-discovery/templates/master.yaml
+++ b/deployment/helm/node-feature-discovery/templates/master.yaml
@@ -92,9 +92,6 @@ spec:
             {{- if .Values.master.resourceLabels | empty | not }}
             - "-resource-labels={{- join "," .Values.master.resourceLabels }}"
             {{- end }}
-            {{- if .Values.master.enableTaints }}
-            - "-enable-taints"
-            {{- end }}
             {{- if .Values.master.crdController | kindIs "invalid" | not }}
             - "-crd-controller={{ .Values.master.crdController }}"
             {{- else }}
@@ -112,20 +109,10 @@ spec:
             - name: nfd-master-cert
               mountPath: "/etc/kubernetes/node-feature-discovery/certs"
               readOnly: true
-            - name: nfd-master-conf
-              mountPath: "/etc/kubernetes/node-feature-discovery"
-              readOnly: true
       volumes:
         - name: nfd-master-cert
           secret:
             secretName: nfd-master-cert
-        - name: nfd-master-conf
-          configMap:
-            name: {{ include "node-feature-discovery.fullname" . }}-master-conf
-            items:
-              - key: nfd-master.conf
-                path: nfd-master.conf
-
     ## /TLS ##
     {{- end }}
     {{- with .Values.master.nodeSelector }}
diff --git a/deployment/helm/node-feature-discovery/templates/nfd-master-conf.yaml b/deployment/helm/node-feature-discovery/templates/nfd-master-conf.yaml
deleted file mode 100644
index c806a8e5d..000000000
--- a/deployment/helm/node-feature-discovery/templates/nfd-master-conf.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: {{ include "node-feature-discovery.fullname" . }}-master-conf
-  namespace: {{ include "node-feature-discovery.namespace" . }}
-  labels:
-  {{- include "node-feature-discovery.labels" . | nindent 4 }}
-data:
-  nfd-master.conf: |-
-    {{- .Values.master.config | toYaml | nindent 4 }}
diff --git a/deployment/helm/node-feature-discovery/values.yaml b/deployment/helm/node-feature-discovery/values.yaml
index fc98f4e92..76271c1fd 100644
--- a/deployment/helm/node-feature-discovery/values.yaml
+++ b/deployment/helm/node-feature-discovery/values.yaml
@@ -13,14 +13,6 @@ namespaceOverride: ""
 enableNodeFeatureApi: false
 
 master:
-  config: ### <NFD-MASTER-CONF-START-DO-NOT-REMOVE>
-    # noPublish: false
-    # extraLabelNs: ["added.ns.io","added.kubernets.io"]
-    # denyLabelNs: ["denied.ns.io","denied.kubernetes.io"]
-    # resourceLabels: ["vendor-1.com/feature-1","vendor-2.io/feature-2"]
-    # enableTaints: false
-    # labelWhiteList: "foo"
-  ### <NFD-MASTER-CONF-END-DO-NOT-REMOVE>
   # The TCP port that nfd-master listens for incoming requests. Default: 8080
   port: 8080
   instance:
@@ -28,7 +20,6 @@ master:
   denyLabelNs: []
   extraLabelNs: []
   resourceLabels: []
-  enableTaints: false
   crdController: null
   featureRulesController: null
   deploymentAnnotations: {}
diff --git a/deployment/overlays/default-combined/kustomization.yaml b/deployment/overlays/default-combined/kustomization.yaml
index d980ea0b0..a7778fc83 100644
--- a/deployment/overlays/default-combined/kustomization.yaml
+++ b/deployment/overlays/default-combined/kustomization.yaml
@@ -14,4 +14,3 @@ resources:
 components:
 - ../../components/worker-config
 - ../../components/common
-- ../../components/master-config
diff --git a/deployment/overlays/default-job/kustomization.yaml b/deployment/overlays/default-job/kustomization.yaml
index 8d2850000..04bfd7688 100644
--- a/deployment/overlays/default-job/kustomization.yaml
+++ b/deployment/overlays/default-job/kustomization.yaml
@@ -15,4 +15,3 @@ resources:
 components:
 - ../../components/worker-config
 - ../../components/common
-- ../../components/master-config
diff --git a/deployment/overlays/default/kustomization.yaml b/deployment/overlays/default/kustomization.yaml
index 8774b59f8..317095e79 100644
--- a/deployment/overlays/default/kustomization.yaml
+++ b/deployment/overlays/default/kustomization.yaml
@@ -15,4 +15,3 @@ resources:
 components:
 - ../../components/worker-config
 - ../../components/common
-- ../../components/master-config
diff --git a/deployment/overlays/master-worker-topologyupdater/kustomization.yaml b/deployment/overlays/master-worker-topologyupdater/kustomization.yaml
index ebf0ac213..ebc3c1fc0 100644
--- a/deployment/overlays/master-worker-topologyupdater/kustomization.yaml
+++ b/deployment/overlays/master-worker-topologyupdater/kustomization.yaml
@@ -22,4 +22,3 @@ components:
 - ../../components/common
 - ../../components/topology-updater
 - ../../components/topology-updater-config
-- ../../components/master-config
diff --git a/docs/deployment/helm.md b/docs/deployment/helm.md
index f6961b686..c64bb2a93 100644
--- a/docs/deployment/helm.md
+++ b/docs/deployment/helm.md
@@ -112,7 +112,6 @@ We have introduced the following Chart parameters.
 | `master.instance`           | string  |                                         | Instance name. Used to separate annotation namespaces for multiple parallel deployments                                                  |
 | `master.extraLabelNs`       | array   | []                                      | List of allowed extra label namespaces                                                                                                   |
 | `master.resourceLabels`     | array   | []                                      | List of labels to be registered as extended resources                                                                                          |
-| `master.enableTaints`       | bool    | false                                   | Specifies whether to enable or disable node tainting                                                                                           |
 | `master.crdController`      | bool    | null                                    | Specifies whether the NFD CRD API controller is enabled. If not set, controller will be enabled if `master.instance` is empty. |
 | `master.featureRulesController` | bool | null                                   | DEPRECATED: use `master.crdController` instead |
 | `master.replicaCount`       | integer | 1                                       | Number of desired pods. This is a pointer to distinguish between explicit zero and not specified                                         |
@@ -130,7 +129,6 @@ We have introduced the following Chart parameters.
 | `master.annotations`        | dict    | {}                                      | NFD master pod [annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/)                                |
 | `master.affinity`           | dict    |                                         | NFD master pod required [node affinity](https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/) |
 | `master.deploymentAnnotations` | dict | {}                                      | NFD master deployment [annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/) |
-| `master.config`             | dict    |                                         | NFD master [configuration](../reference/master-configuration-reference) |
 
 ### Worker pod parameters
 
diff --git a/docs/deployment/uninstallation.md b/docs/deployment/uninstallation.md
index ee77ef543..0857ff713 100644
--- a/docs/deployment/uninstallation.md
+++ b/docs/deployment/uninstallation.md
@@ -23,8 +23,7 @@ Follow the uninstallation instructions of the deployment method used
 ## Removing feature labels
 
 NFD-Master has a special `-prune` command line flag for removing all
-nfd-related node labels, annotations, extended resources and taints from the
-cluster.
+nfd-related node labels, annotations and extended resources from the cluster.
 
 ```bash
 kubectl apply -k https://github.com/kubernetes-sigs/node-feature-discovery/deployment/overlays/prune?ref={{ site.release }}
diff --git a/docs/get-started/introduction.md b/docs/get-started/introduction.md
index 5e714479c..22302a6a3 100644
--- a/docs/get-started/introduction.md
+++ b/docs/get-started/introduction.md
@@ -17,8 +17,7 @@ sort: 1
 
 This software enables node feature discovery for Kubernetes. It detects
 hardware features available on each node in a Kubernetes cluster, and
-advertises those features using node labels and optionally node extended
-resources and node taints.
+advertises those features using node labels and optionally node taints.
 
 NFD consists of four software components:
 
diff --git a/docs/reference/master-commandline-reference.md b/docs/reference/master-commandline-reference.md
index bf8cc7787..a62f348d1 100644
--- a/docs/reference/master-commandline-reference.md
+++ b/docs/reference/master-commandline-reference.md
@@ -268,34 +268,6 @@ Example:
 nfd-master -resource-labels=vendor-1.com/feature-1,vendor-2.io/feature-2
 ```
 
-### -config
-
-The `-config` flag specifies the path of the nfd-master configuration file to
-use.
-
-Default: /etc/kubernetes/node-feature-discovery/nfd-master.conf
-
-Example:
-
-```bash
-nfd-master -config=/opt/nfd/master.conf
-```
-
-### -options
-
-The `-options` flag may be used to specify and override configuration file
-options directly from the command line. The required format is the same as in
-the config file i.e. JSON or YAML. Configuration options specified via this
-flag will override those from the configuration file:
-
-Default: *empty*
-
-Example:
-
-```bash
-nfd-master -options='{"noPublish": true}'
-```
-
 ### Logging
 
 The following logging-related flags are inherited from the
diff --git a/docs/reference/master-configuration-reference.md b/docs/reference/master-configuration-reference.md
deleted file mode 100644
index 7957d4ab5..000000000
--- a/docs/reference/master-configuration-reference.md
+++ /dev/null
@@ -1,111 +0,0 @@
----
-title: "Master config reference"
-layout: default
-sort: 3
----
-
-# Configuration file reference of nfd-master
-{: .no_toc}
-
-## Table of contents
-{: .no_toc .text-delta}
-
-1. TOC
-{:toc}
-
----
-
-See the
-[sample configuration file](https://github.com/kubernetes-sigs/node-feature-discovery/blob/{{site.release}}/deployment/components/master-config/nfd-master.conf.example)
-for a full example configuration.
-
-## noPublish
-
-`noPublish` option disables updates to the Node objects in the Kubernetes
-API server, making a "dry-run" flag for nfd-master. No Labels, Annotations, Taints
-or ExtendedResources of nodes are updated.
-
-Default: `false`
-
-Example:
-
-```yaml
-noPublish: true
-```
-
-## extraLabelNs
-`extraLabelNs` specifies a list of allowed feature
-label namespaces. This option can be used to allow
-other vendor or application specific namespaces for custom labels from the
-local and custom feature sources, even though these labels were denied using
-the `denyLabelNs` parameter.
-
-The same namespace control and this option applies to Extended Resources (created
-with `resourceLabels`), too.
-
-Default: *empty*
-
-Example:
-
-```yaml
-extraLabelNs: ["added.ns.io","added.kubernets.io"]
-```
-
-## denyLabelNs
-`denyLabelNs` specifies a list of excluded
-label namespaces. By default, nfd-master allows creating labels in all
-namespaces, excluding `kubernetes.io` namespace and its sub-namespaces
-(i.e. `*.kubernetes.io`). However, you should note that
-`kubernetes.io` and its sub-namespaces are always denied.
-This option can be used to exclude some vendors or application specific
-namespaces.
-Note that the namespaces `feature.node.kubernetes.io` and `profile.node.kubernetes.io`
-and their sub-namespaces are always allowed and cannot be denied.
-
-Default: *empty*
-
-Example:
-
-```yaml
-denyLabelNs: ["denied.ns.io","denied.kubernetes.io"]
-```
-
-## resourceLabels
-The `resourceLabels` option specifies a list of features to be
-advertised as extended resources instead of labels. Features that have integer
-values can be published as Extended Resources by listing them in this option.
-
-Default: *empty*
-
-Example:
-
-```yaml
-resourceLabels: ["vendor-1.com/feature-1","vendor-2.io/feature-2"]
-```
-
-## enableTaints
-`enableTaints` enables/disables node tainting feature of NFD.
-
-Default: *false*
-
-Example:
-
-```yaml
-enableTaints: true
-```
-
-## labelWhiteList
-`labelWhiteList` specifies a regular expression for filtering feature
-labels based on their name. Each label must match against the given reqular
-expression in order to be published.
-
-Note: The regular expression is only matches against the "basename" part of the
-label, i.e. to the part of the name after '/'. The label namespace is omitted.
-
-Default: *empty*
-
-Example:
-
-```yaml
-labelWhiteList: "foo"
-```
diff --git a/docs/reference/topology-gc-commandline-reference.md b/docs/reference/topology-gc-commandline-reference.md
index 583dbbcc9..bfabb1f19 100644
--- a/docs/reference/topology-gc-commandline-reference.md
+++ b/docs/reference/topology-gc-commandline-reference.md
@@ -1,7 +1,7 @@
 ---
 title: "Topology Garbage Collector Cmdline Reference"
 layout: default
-sort: 7
+sort: 6
 ---
 
 # NFD-Topology-Garbage-Collector Commandline Flags
diff --git a/docs/reference/topology-updater-commandline-reference.md b/docs/reference/topology-updater-commandline-reference.md
index 4d35f917f..f4d8764b6 100644
--- a/docs/reference/topology-updater-commandline-reference.md
+++ b/docs/reference/topology-updater-commandline-reference.md
@@ -1,7 +1,7 @@
 ---
 title: "Topology Updater Cmdline Reference"
 layout: default
-sort: 5
+sort: 4
 ---
 
 # NFD-Topology-Updater Commandline Flags
diff --git a/docs/reference/topology-updater-configuration-reference.md b/docs/reference/topology-updater-configuration-reference.md
index 6660a1587..cda081452 100644
--- a/docs/reference/topology-updater-configuration-reference.md
+++ b/docs/reference/topology-updater-configuration-reference.md
@@ -1,7 +1,7 @@
 ---
 title: "Topology-Updater config reference"
 layout: default
-sort: 6
+sort: 5
 ---
 
 # Configuration file reference of nfd-topology-updater
diff --git a/docs/reference/worker-configuration-reference.md b/docs/reference/worker-configuration-reference.md
index 540172caf..4d445f3a0 100644
--- a/docs/reference/worker-configuration-reference.md
+++ b/docs/reference/worker-configuration-reference.md
@@ -1,7 +1,7 @@
 ---
 title: "Worker config reference"
 layout: default
-sort: 4
+sort: 3
 ---
 
 # Configuration file reference of nfd-worker
diff --git a/docs/usage/customization-guide.md b/docs/usage/customization-guide.md
index b3bb104fb..6366f54f8 100644
--- a/docs/usage/customization-guide.md
+++ b/docs/usage/customization-guide.md
@@ -159,7 +159,6 @@ re-labeling delay up to the sleep-interval of nfd-worker (1 minute by default).
 
 See [Label rule format](#label-rule-format) for detailed description of
 available fields and how to write labeling rules.
-
 ### NodeFeatureRule tainting feature
 
 This feature is experimental.
@@ -210,15 +209,6 @@ spec:
 In this example, if the `my sample taint rule` rule is matched, `feature.node.kubernetes.io/pci-0300_1d0f.present=true:NoExecute`
 and `feature.node.kubernetes.io/cpu-cpuid.ADX:NoExecute` taints are set on the node.
 
-There are some limitations to the namespace part (i.e. prefix/) of the taint
-key:
-
-- `kubernetes.io/` and its sub-namespaces (like `sub.ns.kubernetes.io/`) cannot
-  generally be used
-- the only exception is `feature.node.kubernetes.io/` and its sub-namespaces
-  (like `sub.ns.feature.node.kubernetes.io`)
-- unprefixed keys (like `foo`) keys are disallowed
-
 ## Local feature source
 
 NFD-Worker has a special feature source named `local` which is an integration
@@ -485,7 +475,7 @@ details.
 labels specified in the `labels` field will override anything
 originating from `labelsTemplate`.
 
-#### Taints
+### Taints
 
 *taints* is a list of taint entries and each entry can have `key`, `value` and `effect`,
 where the `value` is optional. Effect could be `NoSchedule`, `PreferNoSchedule`
@@ -501,65 +491,6 @@ rules to use. In other words, these are variables that are not advertised as
 node labels. See [backreferences](#backreferences) for more details on the
 usage of vars.
 
-#### Extended resources
-
-The `.extendedResources` field is a list of extended resources to advertise.
-See [extended resources](#extended-resources) for more details.
-
-Take this rule as a referential example:
-
-```yaml
-apiVersion: nfd.k8s-sigs.io/v1alpha1
-kind: NodeFeatureRule
-metadata:
-  name: my-extended-resource-rule
-spec:
-  rules:
-    - name: "my extended resource rule"
-      extendedResources:
-        vendor.io/dynamic: "@kernel.version.major"
-        vendor.io/static: "123"
-      matchFeatures:
-        - feature: kernel.version
-          matchExpressions:
-            major: {op: Exists}
-```
-
-The extended resource `vendor.io/dynamic` is defined in the form `@feature.attribute`.
-The value of the extended resource will be the value of the attribute `major`
-of the feature `kernel.version`.
-
-The `@<feature-name>.<element-name>` format can be used to inject values of
-detected features to the extended resource. See
-[available features](#available-features) for possible values to use. Note that
-the value must be eligible as a
-Kubernetes resource quantity.
-
-This will yield into the following node status:
-
-```yaml
-  allocatable:
-    ...
-    vendor.io/dynamic: "5"
-    vendor.io/static: "123"
-    ...
-  capacity:
-    ...
-    vendor.io/dynamic: "5"
-    vendor.io/static: "123"
-    ...
-```
-
-There are some limitations to the namespace part (i.e. prefix)/ of the Extended
-Resources names:
-
-- `kubernetes.io/` and its sub-namespaces (like `sub.ns.kubernetes.io/`) cannot
-  generally be used
-- the only exception is `feature.node.kubernetes.io/` and its sub-namespaces
-  (like `sub.ns.feature.node.kubernetes.io`)
-- unprefixed names will get prefixed with `feature.node.kubernetes.io/`
-  automatically (e.g. `foo` becomes `feature.node.kubernetes.io/foo`)
-
 #### Vars template
 
 The `.varsTemplate` field specifies a text template for dynamically creating
@@ -670,17 +601,12 @@ The following features are available for matching:
 |                  |              | **`status`** | string | Status of the driver, possible values are 'active' and 'passive'
 |                  |              | **`turbo`**  | bool   | 'true' if turbo frequencies are enabled, otherwise 'false'
 |                  |              | **`scaling`** | string | Active scaling_governor, possible values are 'powersave' or 'performance'.
-| **`cpu.rdt`**    | attribute    |          |            | Intel RDT capabilities supported by the system
-|                  |              | **`<rdt-flag>`** |    | RDT capability is supported, see [RDT flags](#intel-rdt-flags) for details
-|                  |              | **`RDTL3CA_NUM_CLOSID`** | int  | The number or available CLOSID (Class of service ID) for Intel L3 Cache Allocation Technology
+| **`cpu.rdt`**    | flag         |          |            | Intel RDT capabilities supported by the system
+|                  |              | **`<rdt-flag>`** |    | RDT capability is supported, see [RDT flags](features.md#intel-rdt-flags) for details
 | **`cpu.security`** | attribute  |          |            | Features related to security and trusted execution environments
 |                  |              | **`sgx.enabled`** | bool | `true` if Intel SGX (Software Guard Extensions) has been enabled, otherwise does not exist
 |                  |              | **`se.enabled`** | bool  | `true` if IBM Secure Execution for Linux is available and has been enabled, otherwise does not exist
 |                  |              | **`tdx.enabled`** | bool | `true` if Intel TDX (Trusted Domain Extensions) is available on the host and has been enabled, otherwise does not exist
-|                  |              | **`tdx.total_keys`** | int | The total amount of keys an Intel TDX (Trusted Domain Extensions) host can provide.  It's only present if `tdx.enabled` is `true`.
-|                  |              | **`sev.enabled`** | bool | `true` if AMD SEV (Secure Encrypted Virtualization) is available on the host and has been enabled, otherwise does not exist
-|                  |              | **`sev.es.enabled`** | bool | `true` if AMD SEV-ES (Encrypted State supported) is available on the host and has been enabled, otherwise does not exist
-|                  |              | **`sev.snp.enabled`** | bool | `true` if AMD SEV-SNP (Secure Nested Paging supported) is available on the host and has been enabled, otherwise does not exist
 | **`cpu.sgx`**    | attribute    |          |            | **DEPRECATED**: replaced by **`cpu.security`** feature
 |                  |              | **`enabled`** | bool  | **DEPRECATED**: use **`sgx.enabled`** from **`cpu.security`** instead
 | **`cpu.sst`**    | attribute    |          |            | Intel SST (Speed Select Technology) capabilities
@@ -726,17 +652,6 @@ The following features are available for matching:
 | **`rule.matched`** | attribute  |          |            | Previously matched rules
 |                  |              | **`<label-or-var>`** | string | Label or var from a preceding rule that matched
 
-#### Intel RDT flags
-
-| Flag      | Description                                                      |
-| --------- | ---------------------------------------------------------------- |
-| RDTMON    | Intel RDT Monitoring Technology
-| RDTCMT    | Intel Cache Monitoring (CMT)
-| RDTMBM    | Intel Memory Bandwidth Monitoring (MBM)
-| RDTL3CA   | Intel L3 Cache Allocation Technology
-| RDTl2CA   | Intel L2 Cache Allocation Technology
-| RDTMBA    | Intel Memory Bandwidth Allocation (MBA) Technology
-
 ### Templating
 
 Rules support template-based creation of labels and vars with the
diff --git a/docs/usage/features.md b/docs/usage/features.md
index ed3e5b3df..1fdf3ddd5 100644
--- a/docs/usage/features.md
+++ b/docs/usage/features.md
@@ -54,26 +54,16 @@ option of nfd-worker.
 | **`cpu-pstate.turbo`**            | bool   | Set to 'true' if turbo frequencies are enabled in Intel pstate driver, set to 'false' if they have been disabled.
 | **`cpu-pstate.scaling_governor`** | string | The value of the Intel pstate scaling_governor when in use, either 'powersave' or 'performance'.
 | **`cpu-cstate.enabled`**          | bool   | Set to 'true' if cstates are set in the intel_idle driver, otherwise set to 'false'. Unset if intel_idle cpuidle driver is not active.
-| **`cpu-rdt.<rdt-flag>`**          | true   | **DEPRECATED** [Intel RDT][intel-rdt] capability is supported. See [RDT flags](customization-guide.md#intel-rdt-flags) for details.
+| **`cpu-rdt.<rdt-flag>`**          | true   | [Intel RDT][intel-rdt] capability is supported. See [RDT flags](#intel-rdt-flags) for details.
 | **`cpu-security.sgx.enabled`**    | true   | Set to 'true' if Intel SGX is enabled in BIOS (based a non-zero sum value of SGX EPC section sizes).
 | **`cpu-security.se.enabled`**     | true   | Set to 'true' if IBM Secure Execution for Linux (IBM Z & LinuxONE) is available and enabled (requires `/sys/firmware/uv/prot_virt_host` facility)
 | **`cpu-security.tdx.enabled`**    | true   | Set to 'true' if Intel TDX is available on the host and has been enabled (requires `/sys/module/kvm_intel/parameters/tdx`).
-| **`cpu-security.tdx.total_keys`** | int    | The total amount of keys an Intel TDX enabled host can provide, based on the `/sys/fs/cgroup/misc.capacity` information.
-| **`cpu-security.sev.enabled`**    | true   | Set to 'true' if ADM SEV is available on the host and has been enabled (requires `/sys/module/kvm_intel/parameters/sev`).
-| **`cpu-security.sev.es.enabled`** | true   | Set to 'true' if ADM SEV-ES is available on the host and has been enabled (requires `/sys/module/kvm_intel/parameters/sev_es`).
-| **`cpu-security.sev.snp.enabled`**| true   | Set to 'true' if ADM SEV-SNP is available on the host and has been enabled (requires `/sys/module/kvm_intel/parameters/sev_snp`).
 | **`cpu-sgx.enabled`**             | true   | **DEPRECATED**: use **`cpu-security.sgx.enabled`** instead.
 | **`cpu-se.enabled`**              | true   | **DEPRECATED**: use **`cpu-security.se.enabled`** instead.
 | **`cpu-model.vendor_id`**         | string | Comparable CPU vendor ID.
 | **`cpu-model.family`**            | int    | CPU family.
 | **`cpu-model.id`**                | int    | CPU model number.
 
-> NOTE: the `cpu-rdt.<rdt-flag>` labels are deprecated and will be removed in a
-> future release. They will remain to be available as features
-> for [NodeFeatureRule](custom-resources.md#nodefeaturerule) to consume.
-> See [customization guide](customization-guide.md#nodefeaturerule-custom-resource)
-> for details how to use NodeFeatureRule objects to create labels.
-
 The CPU label source is configurable, see
 [worker configuration](nfd-worker.md#worker-configuration) and
 [`sources.cpu`](../reference/worker-configuration-reference.md#sourcescpu)
@@ -160,6 +150,17 @@ See the full list in [github.com/klauspost/cpuid][klauspost-cpuid].
 | JSCVT     | Perform Conversion to Match Javascript
 | DCPOP     | Persistent Memory Support
 
+#### Intel RDT flags
+
+| Flag      | Description                                                      |
+| --------- | ---------------------------------------------------------------- |
+| RDTMON    | Intel RDT Monitoring Technology
+| RDTCMT    | Intel Cache Monitoring (CMT)
+| RDTMBM    | Intel Memory Bandwidth Monitoring (MBM)
+| RDTL3CA   | Intel L3 Cache Allocation Technology
+| RDTl2CA   | Intel L2 Cache Allocation Technology
+| RDTMBA    | Intel Memory Bandwidth Allocation (MBA) Technology
+
 ### Kernel
 
 | Feature | Value  | Description
diff --git a/docs/usage/nfd-master.md b/docs/usage/nfd-master.md
index 60d009e9a..4fac00d74 100644
--- a/docs/usage/nfd-master.md
+++ b/docs/usage/nfd-master.md
@@ -52,39 +52,6 @@ enabled.
 > present when gRPC interface is disabled
 > and [NodeFeature](custom-resources.md#nodefeature-custom-resource) API is used.
 
-## Master configuration
-
-NFD-Master supports dynamic configuration through a configuration file. The
-default location is `/etc/kubernetes/node-feature-discovery/nfd-master.conf`,
-but, this can be changed by specifying the`-config` command line flag.
-Configuration file is re-read whenever it is modified which makes run-time
-re-configuration of nfd-master straightforward.
-
-Master configuration file is read inside the container, and thus, Volumes and
-VolumeMounts are needed to make your configuration available for NFD. The
-preferred method is to use a ConfigMap which provides easy deployment and
-re-configurability.
-
-The provided nfd-master deployment templates create an empty configmap and
-mount it inside the nfd-master containers. In kustomize deployments,
-configuration can be edited with:
-
-```bash
-kubectl -n ${NFD_NS} edit configmap nfd-master-conf
-```
-
-In Helm deployments,
-[Master pod parameter](../deployment/helm.md#master-pod-parameters)
-`master.config` can be used to edit the respective configuration.
-
-See
-[nfd-master configuration file reference](../reference/master-configuration-reference.md)
-for more details.
-The (empty-by-default)
-[example config](https://github.com/kubernetes-sigs/node-feature-discovery/blob/{{site.release}}/deployment/components/master-config/nfd-master.conf.example)
-contains all available configuration options and can be used as a reference
-for creating a configuration.
-
 ## Deployment notes
 
 NFD-Master runs as a deployment, by default
diff --git a/examples/nodefeaturerule.yaml b/examples/nodefeaturerule.yaml
index 39bb699b4..6a6956b2a 100644
--- a/examples/nodefeaturerule.yaml
+++ b/examples/nodefeaturerule.yaml
@@ -14,18 +14,3 @@ spec:
         - feature: kernel.config
           matchExpressions:
             X86: {op: In, value: ["y"]}
----
-apiVersion: nfd.k8s-sigs.io/v1alpha1
-kind: NodeFeatureRule
-metadata:
-  name: my-sample-extened-resource
-spec:
-  rules:
-    - name: "my sample rule"
-      extendedResources:
-        vendor.io/dynamic: "@kernel.version.major"
-        vendor.io/static: "123"
-      matchFeatures:
-        - feature: kernel.version
-          matchExpressions:
-            major: {op: Exists}
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 671376c4a..79e082038 100644
--- a/go.mod
+++ b/go.mod
@@ -21,14 +21,14 @@ require (
 	golang.org/x/net v0.7.0
 	google.golang.org/grpc v1.49.0
 	google.golang.org/protobuf v1.28.1
-	k8s.io/api v0.26.3
-	k8s.io/apiextensions-apiserver v0.26.3
-	k8s.io/apimachinery v0.26.3
-	k8s.io/client-go v0.26.3
+	k8s.io/api v0.26.2
+	k8s.io/apiextensions-apiserver v0.26.2
+	k8s.io/apimachinery v0.26.2
+	k8s.io/client-go v0.26.2
 	k8s.io/klog/v2 v2.80.1
-	k8s.io/kubectl v0.26.3
-	k8s.io/kubelet v0.26.3
-	k8s.io/kubernetes v1.26.3
+	k8s.io/kubectl v0.26.2
+	k8s.io/kubelet v0.26.2
+	k8s.io/kubernetes v1.26.2
 	k8s.io/pod-security-admission v0.0.0
 	k8s.io/utils v0.0.0-20221128185143-99ec85e7a448
 	sigs.k8s.io/yaml v1.3.0
@@ -177,20 +177,20 @@ require (
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 	howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect
-	k8s.io/apiserver v0.26.3 // indirect
-	k8s.io/cloud-provider v0.26.3 // indirect
-	k8s.io/component-base v0.26.3 // indirect
-	k8s.io/component-helpers v0.26.3 // indirect
+	k8s.io/apiserver v0.26.2 // indirect
+	k8s.io/cloud-provider v0.26.2 // indirect
+	k8s.io/component-base v0.26.2 // indirect
+	k8s.io/component-helpers v0.26.2 // indirect
 	k8s.io/cri-api v0.0.0 // indirect
-	k8s.io/csi-translation-lib v0.26.3 // indirect
-	k8s.io/dynamic-resource-allocation v0.26.3 // indirect
-	k8s.io/kms v0.26.3 // indirect
+	k8s.io/csi-translation-lib v0.26.2 // indirect
+	k8s.io/dynamic-resource-allocation v0.26.2 // indirect
+	k8s.io/kms v0.26.2 // indirect
 	k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
 	k8s.io/kube-proxy v0.0.0 // indirect
 	k8s.io/kube-scheduler v0.0.0 // indirect
 	k8s.io/legacy-cloud-providers v0.0.0 // indirect
 	k8s.io/mount-utils v0.25.0 // indirect
-	sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.36 // indirect
+	sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.35 // indirect
 	sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
 	sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
 )
@@ -199,29 +199,29 @@ require (
 // need to override with commits (corresponding their kubernetes-* tags)
 replace (
 	github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2
-	k8s.io/api => k8s.io/api v0.26.3
-	k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.26.3
-	k8s.io/apimachinery => k8s.io/apimachinery v0.26.3
-	k8s.io/apiserver => k8s.io/apiserver v0.26.3
-	k8s.io/cli-runtime => k8s.io/cli-runtime v0.26.3
-	k8s.io/client-go => k8s.io/client-go v0.26.3
-	k8s.io/cloud-provider => k8s.io/cloud-provider v0.26.3
-	k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.26.3
-	k8s.io/code-generator => k8s.io/code-generator v0.26.3
-	k8s.io/component-base => k8s.io/component-base v0.26.3
-	k8s.io/component-helpers => k8s.io/component-helpers v0.26.3
-	k8s.io/controller-manager => k8s.io/controller-manager v0.26.3
-	k8s.io/cri-api => k8s.io/cri-api v0.26.3
-	k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.26.3
-	k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.26.3
-	k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.26.3
-	k8s.io/kube-proxy => k8s.io/kube-proxy v0.26.3
-	k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.26.3
-	k8s.io/kubectl => k8s.io/kubectl v0.26.3
-	k8s.io/kubelet => k8s.io/kubelet v0.26.3
-	k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.26.3
-	k8s.io/metrics => k8s.io/metrics v0.26.3
-	k8s.io/mount-utils => k8s.io/mount-utils v0.26.3
-	k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.26.3
-	k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.26.3
+	k8s.io/api => k8s.io/api v0.26.2
+	k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.26.2
+	k8s.io/apimachinery => k8s.io/apimachinery v0.26.2
+	k8s.io/apiserver => k8s.io/apiserver v0.26.2
+	k8s.io/cli-runtime => k8s.io/cli-runtime v0.26.2
+	k8s.io/client-go => k8s.io/client-go v0.26.2
+	k8s.io/cloud-provider => k8s.io/cloud-provider v0.26.2
+	k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.26.2
+	k8s.io/code-generator => k8s.io/code-generator v0.26.2
+	k8s.io/component-base => k8s.io/component-base v0.26.2
+	k8s.io/component-helpers => k8s.io/component-helpers v0.26.2
+	k8s.io/controller-manager => k8s.io/controller-manager v0.26.2
+	k8s.io/cri-api => k8s.io/cri-api v0.26.2
+	k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.26.2
+	k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.26.2
+	k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.26.2
+	k8s.io/kube-proxy => k8s.io/kube-proxy v0.26.2
+	k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.26.2
+	k8s.io/kubectl => k8s.io/kubectl v0.26.2
+	k8s.io/kubelet => k8s.io/kubelet v0.26.2
+	k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.26.2
+	k8s.io/metrics => k8s.io/metrics v0.26.2
+	k8s.io/mount-utils => k8s.io/mount-utils v0.26.2
+	k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.26.2
+	k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.26.2
 )
diff --git a/go.sum b/go.sum
index d7394e2b8..54cf7402b 100644
--- a/go.sum
+++ b/go.sum
@@ -1215,60 +1215,60 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
 howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M=
 howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
-k8s.io/api v0.26.3 h1:emf74GIQMTik01Aum9dPP0gAypL8JTLl/lHa4V9RFSU=
-k8s.io/api v0.26.3/go.mod h1:PXsqwPMXBSBcL1lJ9CYDKy7kIReUydukS5JiRlxC3qE=
-k8s.io/apiextensions-apiserver v0.26.3 h1:5PGMm3oEzdB1W/FTMgGIDmm100vn7IaUP5er36dB+YE=
-k8s.io/apiextensions-apiserver v0.26.3/go.mod h1:jdA5MdjNWGP+njw1EKMZc64xAT5fIhN6VJrElV3sfpQ=
-k8s.io/apimachinery v0.26.3 h1:dQx6PNETJ7nODU3XPtrwkfuubs6w7sX0M8n61zHIV/k=
-k8s.io/apimachinery v0.26.3/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I=
-k8s.io/apiserver v0.26.3 h1:blBpv+yOiozkPH2aqClhJmJY+rp53Tgfac4SKPDJnU4=
-k8s.io/apiserver v0.26.3/go.mod h1:CJe/VoQNcXdhm67EvaVjYXxR3QyfwpceKPuPaeLibTA=
-k8s.io/cli-runtime v0.26.3 h1:3ULe0oI28xmgeLMVXIstB+ZL5CTGvWSMVMLeHxitIuc=
-k8s.io/client-go v0.26.3 h1:k1UY+KXfkxV2ScEL3gilKcF7761xkYsSD6BC9szIu8s=
-k8s.io/client-go v0.26.3/go.mod h1:ZPNu9lm8/dbRIPAgteN30RSXea6vrCpFvq+MateTUuQ=
-k8s.io/cloud-provider v0.26.3 h1:qN4f0+PvgOZyKIIct+90eedYj8/S4EKPpSD9S+3RCFE=
-k8s.io/cloud-provider v0.26.3/go.mod h1:Hfxu0mvz426xlvz2tziw0m3ubr+sk05KKD4HPy2kwdY=
-k8s.io/cluster-bootstrap v0.26.3 h1:x+yLUle2BaGoAfHbqyzCabGLHR0caZ+9Cvr9BlExR7w=
-k8s.io/code-generator v0.26.3/go.mod h1:ryaiIKwfxEJEaywEzx3dhWOydpVctKYbqLajJf0O8dI=
-k8s.io/component-base v0.26.3 h1:oC0WMK/ggcbGDTkdcqefI4wIZRYdK3JySx9/HADpV0g=
-k8s.io/component-base v0.26.3/go.mod h1:5kj1kZYwSC6ZstHJN7oHBqcJC6yyn41eR+Sqa/mQc8E=
-k8s.io/component-helpers v0.26.3 h1:eQ682yg1GiIGAsde+l2xL0P2yMYJOvypWsz6h6FtkZo=
-k8s.io/component-helpers v0.26.3/go.mod h1:feC+CaxJXULs5TSD3lG8K5ecftOkF8eY0pHQgd7koEI=
-k8s.io/cri-api v0.26.3 h1:sVkvI3DjVwS4sV7XZZiuxRvBsCWfifZPE8ddusIlJLU=
-k8s.io/cri-api v0.26.3/go.mod h1:Oo8O7MKFPNDxfDf2LmrF/3Hf30q1C6iliGuv3la3tIA=
-k8s.io/csi-translation-lib v0.26.3 h1:XpC3yeBSz+qls9zk3Tqg6r2sZxFePGe1fIlSlmds5XA=
-k8s.io/csi-translation-lib v0.26.3/go.mod h1:i++hspfN3AZsA5cYQ1QFnflIQhirsoc/8bOLkaVJG/g=
-k8s.io/dynamic-resource-allocation v0.26.3 h1:WBI4xDoMySaH5VJe0y514O3rC4gyiJppC0EkDo6mHq0=
-k8s.io/dynamic-resource-allocation v0.26.3/go.mod h1:8nUg20y2DgAv8v+Yuv7O5+rLZa7jbjsU3KvDcBiv2b8=
+k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ=
+k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU=
+k8s.io/apiextensions-apiserver v0.26.2 h1:/yTG2B9jGY2Q70iGskMf41qTLhL9XeNN2KhI0uDgwko=
+k8s.io/apiextensions-apiserver v0.26.2/go.mod h1:Y7UPgch8nph8mGCuVk0SK83LnS8Esf3n6fUBgew8SH8=
+k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ=
+k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I=
+k8s.io/apiserver v0.26.2 h1:Pk8lmX4G14hYqJd1poHGC08G03nIHVqdJMR0SD3IH3o=
+k8s.io/apiserver v0.26.2/go.mod h1:GHcozwXgXsPuOJ28EnQ/jXEM9QeG6HT22YxSNmpYNh8=
+k8s.io/cli-runtime v0.26.2 h1:6XcIQOYW1RGNwFgRwejvyUyAojhToPmJLGr0JBMC5jw=
+k8s.io/client-go v0.26.2 h1:s1WkVujHX3kTp4Zn4yGNFK+dlDXy1bAAkIl+cFAiuYI=
+k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU=
+k8s.io/cloud-provider v0.26.2 h1:VlLGDayUV5VBpvMSBFqmpz2HHTjBLUw02wuZzNeEsW0=
+k8s.io/cloud-provider v0.26.2/go.mod h1:/Am9R0merLIZgVqPTE4Z1JkBcCrp2uXImHCxnvVARxc=
+k8s.io/cluster-bootstrap v0.26.2 h1:CePewHLcXZ+HXaAUstQz/rG7QsEn444UbiOePiphOzs=
+k8s.io/code-generator v0.26.2/go.mod h1:ryaiIKwfxEJEaywEzx3dhWOydpVctKYbqLajJf0O8dI=
+k8s.io/component-base v0.26.2 h1:IfWgCGUDzrD6wLLgXEstJKYZKAFS2kO+rBRi0p3LqcI=
+k8s.io/component-base v0.26.2/go.mod h1:DxbuIe9M3IZPRxPIzhch2m1eT7uFrSBJUBuVCQEBivs=
+k8s.io/component-helpers v0.26.2 h1:+JJ1gwyVsqSwZCJVLJotx/IPq2pMpo0kifeAzfo6i3U=
+k8s.io/component-helpers v0.26.2/go.mod h1:PRvoduZ5/IeKGGbZRki3J2cTQVwZLD+EUxIEbvvX0W4=
+k8s.io/cri-api v0.26.2 h1:Vifw8T4ZFzU5pQ5dj5rdDsPOSzmLAvhVcYEJpbjOYLY=
+k8s.io/cri-api v0.26.2/go.mod h1:Oo8O7MKFPNDxfDf2LmrF/3Hf30q1C6iliGuv3la3tIA=
+k8s.io/csi-translation-lib v0.26.2 h1:WWnJjYKBlnoMzwc77ioT9bppJPFYNAZ0uhzert/3QJ4=
+k8s.io/csi-translation-lib v0.26.2/go.mod h1:BlP3ulcmi+lHeS2WhKHqv2WYUuQMjedbqGs2+8+nnP4=
+k8s.io/dynamic-resource-allocation v0.26.2 h1:wueJDXqj3Yhzhz36l8R1MA/qt9gT53W0fPIsiDwdw+g=
+k8s.io/dynamic-resource-allocation v0.26.2/go.mod h1:LvsFr+Mp6LvEYypFPkB/xq0u+W368qVldQckybgQTgM=
 k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
 k8s.io/gengo v0.0.0-20220902162205-c0856e24416d/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
 k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
 k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
 k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
 k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
-k8s.io/kms v0.26.3 h1:+rC4BMeMBkH5hrfZt9WFMRrs2m3vY2rXymisNactcTY=
-k8s.io/kms v0.26.3/go.mod h1:69qGnf1NsFOQP07fBYqNLZklqEHSJF024JqYCaeVxHg=
-k8s.io/kube-aggregator v0.26.3 h1:nc4H5ymGkWPU3c9U9UM468JcmNENY/s/mDYVW3t3uRo=
+k8s.io/kms v0.26.2 h1:GM1gg3tFK3OUU/QQFi93yGjG3lJT8s8l3Wkn2+VxBLM=
+k8s.io/kms v0.26.2/go.mod h1:69qGnf1NsFOQP07fBYqNLZklqEHSJF024JqYCaeVxHg=
+k8s.io/kube-aggregator v0.26.2 h1:WtcLGisa5aCKBbBI1/Xe7gdjPlVb5Xhvs4a8Rdk8EXs=
 k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E=
 k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4=
-k8s.io/kube-proxy v0.26.3 h1:xKYTgH/HcmuLuIw/Ip2AVus70I9VwaFEQ5O7vGAveW8=
-k8s.io/kube-proxy v0.26.3/go.mod h1:995p2WbS0zgatqXcB81/4vdhdOrP1cq6jqmPtDmaPhc=
-k8s.io/kube-scheduler v0.26.3 h1:IOMIG5dUILnJIMnCbTUQokTb37Sd28vexquBSeajk6c=
-k8s.io/kube-scheduler v0.26.3/go.mod h1:mbym95ZdWOaftRMmdLRcAam9MCNf7iUjnPfZTl8uHTA=
-k8s.io/kubectl v0.26.3 h1:bZ5SgFyeEXw6XTc1Qji0iNdtqAC76lmeIIQULg2wNXM=
-k8s.io/kubectl v0.26.3/go.mod h1:02+gv7Qn4dupzN3fi/9OvqqdW+uG/4Zi56vc4Zmsp1g=
-k8s.io/kubelet v0.26.3 h1:6WT2dX/39cvc3q25xkFmMIT2EoV+gS/8gxZmUiDvG4U=
-k8s.io/kubelet v0.26.3/go.mod h1:yd5GJNMOFLMKxP1rmZhg6etbYAbdTimF87fBIBtRimA=
-k8s.io/kubernetes v1.26.3 h1:LtjNGNNpCTRyrWhDJMwTWDX+4h+GLwfULS8pu0xzSdk=
-k8s.io/kubernetes v1.26.3/go.mod h1:NxzR7U7mS+OGa3J/qweI86Pek//mlfHqDgt6NNGdz8g=
-k8s.io/legacy-cloud-providers v0.26.3 h1:gUDw7vFFKMM/vV/3MQNbw+H9fZOaH8z2/oK8/O7PCT0=
-k8s.io/legacy-cloud-providers v0.26.3/go.mod h1:Scn0CIcptay5seel6MhAzLtoBseK+fL46uJSP84cnPo=
-k8s.io/metrics v0.26.3 h1:pHI8XtmBbGGdh7bL0s2C3v93fJfxyktHPAFsnRYnDTo=
-k8s.io/mount-utils v0.26.3 h1:FxMDiPLCkrYgonfSaKHWltLNkyTg3Q/Xrwn94uwhd8k=
-k8s.io/mount-utils v0.26.3/go.mod h1:95yx9K6N37y8YZ0/lUh9U6ITosMODNaW0/v4wvaa0Xw=
-k8s.io/pod-security-admission v0.26.3 h1:MvPlB/cZW4x64VgZ3WbgnfPWpgtZY4w6ZllIMWmEy9Y=
-k8s.io/pod-security-admission v0.26.3/go.mod h1:9I+AV3O26WYsn4jpCD8WvdJy3xvqBWYz43kz0jwco1k=
-k8s.io/sample-apiserver v0.26.3 h1:aB2EdWA94fgztb1ey7vLZ/6t9PN4LVYZHF4PRJmlcZU=
+k8s.io/kube-proxy v0.26.2 h1:VQDZI3pGvPy1oVPH3K0qyIVgBA8pplCvfzFi4KLj9DU=
+k8s.io/kube-proxy v0.26.2/go.mod h1:lBmfsIdWoygNrhOXlVDYtg/mCHrKiFW0YXfljCRupes=
+k8s.io/kube-scheduler v0.26.2 h1:BYwddcxAvA5NNGlrvcIeKOeUYGYu9613oLWkuNDrdaQ=
+k8s.io/kube-scheduler v0.26.2/go.mod h1:pa3eMaUkjv1MARUXzPiaMzT0ALycE+kW0sZ8RRvG15s=
+k8s.io/kubectl v0.26.2 h1:SMPB4j48eVFxsYluBq3VLyqXtE6b72YnszkbTAtFye4=
+k8s.io/kubectl v0.26.2/go.mod h1:KYWOXSwp2BrDn3kPeoU/uKzKtdqvhK1dgZGd0+no4cM=
+k8s.io/kubelet v0.26.2 h1:egg7YfhCpH9wvLwQdL2Mzuy4/kC6hO91azY0jgdYPWA=
+k8s.io/kubelet v0.26.2/go.mod h1:IXthU5hcJQE6+K33LuaYYO0wUcYO8glhl/ip1Hzux44=
+k8s.io/kubernetes v1.26.2 h1:6Ve0nzlF2noVXf9jMHSJgbRZC0EkyOV22GYEv1K7MZI=
+k8s.io/kubernetes v1.26.2/go.mod h1:cv07eVU5+kF6ibpVtAvOGjIBsrfgevQL4ORK85/oqWc=
+k8s.io/legacy-cloud-providers v0.26.2 h1:GSPaEghGZsjEd9j7KjnPbQ1a7qccukB79TfOHNLm4YM=
+k8s.io/legacy-cloud-providers v0.26.2/go.mod h1:ARTqLUGcM7bEeFZOy0EaDwzTjJMDk7P9/ePNWaI//o8=
+k8s.io/metrics v0.26.2 h1:2gUvUWWnHPdE2tyA5DvyHC8HGryr+izhY9i5dzLP06s=
+k8s.io/mount-utils v0.26.2 h1:KoRKqCAAK2l37l71YMvKx6vaLToh52RkNx1RU/dSLGQ=
+k8s.io/mount-utils v0.26.2/go.mod h1:95yx9K6N37y8YZ0/lUh9U6ITosMODNaW0/v4wvaa0Xw=
+k8s.io/pod-security-admission v0.26.2 h1:R41JH34lRsqThGUCi1XdDFhG+UoRK4ZFzQ89FxgWDP8=
+k8s.io/pod-security-admission v0.26.2/go.mod h1:tb7Huh4QpEZZets79N8QQOtbvRBARSU0b8YqGTpTA7I=
+k8s.io/sample-apiserver v0.26.2 h1:geg9s+QzWyheJcFtUX9s1ajW5H/J4XzSFUOScj/IkZI=
 k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
 k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
 k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
@@ -1277,8 +1277,8 @@ k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
-sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.36 h1:PUuX1qIFv309AT8hF/CdPKDmsG/hn/L8zRX7VvISM3A=
-sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.36/go.mod h1:WxjusMwXlKzfAs4p9km6XJRndVt2FROgMVCE4cdohFo=
+sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.35 h1:+xBL5uTc+BkPBwmMi3vYfUJjq+N3K+H6PXeETwf5cPI=
+sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.35/go.mod h1:WxjusMwXlKzfAs4p9km6XJRndVt2FROgMVCE4cdohFo=
 sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
 sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
 sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM=
diff --git a/pkg/apis/nfd/v1alpha1/annotations_labels.go b/pkg/apis/nfd/v1alpha1/annotations_labels.go
index 3ed45beb0..978ba853c 100644
--- a/pkg/apis/nfd/v1alpha1/annotations_labels.go
+++ b/pkg/apis/nfd/v1alpha1/annotations_labels.go
@@ -29,21 +29,9 @@ const (
 	// ProfileLabelSubNsSuffix is the suffix for allowed profile label sub-namespaces.
 	ProfileLabelSubNsSuffix = "." + ProfileLabelNs
 
-	// TaintNs is the k8s.io namespace that can be used for NFD-managed taints.
-	TaintNs = "feature.node.kubernetes.io"
-
-	// TaintSubNsSuffix is the suffix for allowed sub-namespaces for NFD-managed taints.
-	TaintSubNsSuffix = "." + TaintNs
-
 	// AnnotationNs namespace for all NFD-related annotations.
 	AnnotationNs = "nfd.node.kubernetes.io"
 
-	// ExtendedResourceNs is the namespace for extended resources.
-	ExtendedResourceNs = "feature.node.kubernetes.io"
-
-	// ExtendedResourceSubNsSuffix is the suffix for allowed extended resources sub-namespaces.
-	ExtendedResourceSubNsSuffix = "." + ExtendedResourceNs
-
 	// ExtendedResourceAnnotation is the annotation that holds all extended resources managed by NFD.
 	ExtendedResourceAnnotation = AnnotationNs + "/extended-resources"
 
diff --git a/pkg/apis/nfd/v1alpha1/rule.go b/pkg/apis/nfd/v1alpha1/rule.go
index 01535d7d3..d7e3cd20c 100644
--- a/pkg/apis/nfd/v1alpha1/rule.go
+++ b/pkg/apis/nfd/v1alpha1/rule.go
@@ -30,15 +30,13 @@ import (
 // RuleOutput contains the output out rule execution.
 // +k8s:deepcopy-gen=false
 type RuleOutput struct {
-	ExtendedResources map[string]string
-	Labels            map[string]string
-	Vars              map[string]string
-	Taints            []corev1.Taint
+	Labels map[string]string
+	Vars   map[string]string
+	Taints []corev1.Taint
 }
 
 // Execute the rule against a set of input features.
 func (r *Rule) Execute(features *Features) (RuleOutput, error) {
-	extendedResources := make(map[string]string)
 	labels := make(map[string]string)
 	vars := make(map[string]string)
 
@@ -90,10 +88,6 @@ func (r *Rule) Execute(features *Features) (RuleOutput, error) {
 		}
 	}
 
-	for k, v := range r.ExtendedResources {
-		extendedResources[k] = v
-	}
-
 	for k, v := range r.Labels {
 		labels[k] = v
 	}
@@ -101,7 +95,7 @@ func (r *Rule) Execute(features *Features) (RuleOutput, error) {
 		vars[k] = v
 	}
 
-	ret := RuleOutput{ExtendedResources: extendedResources, Labels: labels, Vars: vars, Taints: r.Taints}
+	ret := RuleOutput{Labels: labels, Vars: vars, Taints: r.Taints}
 	utils.KlogDump(2, fmt.Sprintf("rule %q matched with: ", r.Name), "  ", ret)
 	return ret, nil
 }
diff --git a/pkg/apis/nfd/v1alpha1/types.go b/pkg/apis/nfd/v1alpha1/types.go
index c611086ff..c916daa86 100644
--- a/pkg/apis/nfd/v1alpha1/types.go
+++ b/pkg/apis/nfd/v1alpha1/types.go
@@ -163,10 +163,6 @@ type Rule struct {
 	// +optional
 	Taints []corev1.Taint `json:"taints,omitempty"`
 
-	// ExtendedResources to create if the rule matches.
-	// +optional
-	ExtendedResources map[string]string `json:"extendedResources"`
-
 	// MatchFeatures specifies a set of matcher terms all of which must match.
 	// +optional
 	MatchFeatures FeatureMatcher `json:"matchFeatures"`
diff --git a/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go
index fac8c2ad1..07073afac 100644
--- a/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go
@@ -527,13 +527,6 @@ func (in *Rule) DeepCopyInto(out *Rule) {
 			(*in)[i].DeepCopyInto(&(*out)[i])
 		}
 	}
-	if in.ExtendedResources != nil {
-		in, out := &in.ExtendedResources, &out.ExtendedResources
-		*out = make(map[string]string, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
 	if in.MatchFeatures != nil {
 		in, out := &in.MatchFeatures, &out.MatchFeatures
 		*out = make(FeatureMatcher, len(*in))
diff --git a/pkg/nfd-master/nfd-master.go b/pkg/nfd-master/nfd-master.go
index a82541bef..288773e68 100644
--- a/pkg/nfd-master/nfd-master.go
+++ b/pkg/nfd-master/nfd-master.go
@@ -21,9 +21,7 @@ import (
 	"crypto/x509"
 	"fmt"
 	"net"
-	"os"
 	"path"
-	"path/filepath"
 	"regexp"
 	"sort"
 	"strconv"
@@ -37,14 +35,13 @@ import (
 	"google.golang.org/grpc/health/grpc_health_v1"
 	"google.golang.org/grpc/peer"
 	corev1 "k8s.io/api/core/v1"
-	k8sQuantity "k8s.io/apimachinery/pkg/api/resource"
-	k8sLabels "k8s.io/apimachinery/pkg/labels"
+	"k8s.io/apimachinery/pkg/labels"
+	label "k8s.io/apimachinery/pkg/labels"
 	"k8s.io/client-go/kubernetes"
 	restclient "k8s.io/client-go/rest"
 	"k8s.io/klog/v2"
 	controller "k8s.io/kubernetes/pkg/controller"
 	taintutils "k8s.io/kubernetes/pkg/util/taints"
-	"sigs.k8s.io/yaml"
 
 	"sigs.k8s.io/node-feature-discovery/pkg/apihelper"
 	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
@@ -62,42 +59,24 @@ type ExtendedResources map[string]string
 // Annotations are used for NFD-related node metadata
 type Annotations map[string]string
 
-// NFDConfig contains the configuration settings of NfdMaster.
-type NFDConfig struct {
-	DenyLabelNs    utils.StringSetVal
-	ExtraLabelNs   utils.StringSetVal
-	LabelWhiteList utils.RegexpVal
-	NoPublish      bool
-	ResourceLabels utils.StringSetVal
-	EnableTaints   bool
-}
-
-// ConfigOverrideArgs are args that override config file options
-type ConfigOverrideArgs struct {
-	DenyLabelNs    *utils.StringSetVal
-	ExtraLabelNs   *utils.StringSetVal
-	LabelWhiteList *utils.RegexpVal
-	ResourceLabels *utils.StringSetVal
-	EnableTaints   *bool
-	NoPublish      *bool
-}
-
 // Args holds command line arguments
 type Args struct {
 	CaFile               string
 	CertFile             string
-	ConfigFile           string
+	DenyLabelNs          utils.StringSetVal
+	ExtraLabelNs         utils.StringSetVal
 	Instance             string
 	KeyFile              string
 	Kubeconfig           string
+	LabelWhiteList       utils.RegexpVal
 	CrdController        bool
 	EnableNodeFeatureApi bool
+	NoPublish            bool
+	EnableTaints         bool
 	Port                 int
 	Prune                bool
 	VerifyNodeName       bool
-	Options              string
-
-	Overrides ConfigOverrideArgs
+	ResourceLabels       utils.StringSetVal
 }
 
 type deniedNs struct {
@@ -114,17 +93,15 @@ type NfdMaster interface {
 type nfdMaster struct {
 	*nfdController
 
-	args           Args
-	namespace      string
-	nodeName       string
-	configFilePath string
-	server         *grpc.Server
-	stop           chan struct{}
-	ready          chan bool
-	apihelper      apihelper.APIHelpers
-	kubeconfig     *restclient.Config
+	args       Args
+	namespace  string
+	nodeName   string
+	server     *grpc.Server
+	stop       chan struct{}
+	ready      chan bool
+	apihelper  apihelper.APIHelpers
+	kubeconfig *restclient.Config
 	deniedNs
-	config *NFDConfig
 }
 
 // NewNfdMaster creates a new NfdMaster server instance.
@@ -156,25 +133,29 @@ func NewNfdMaster(args *Args) (NfdMaster, error) {
 			return nfd, fmt.Errorf("-ca-file needs to be specified alongside -cert-file and -key-file")
 		}
 	}
+	if args.DenyLabelNs == nil {
+		args.DenyLabelNs = make(utils.StringSetVal)
+	}
+	// Pre-process DenyLabelNS into 2 lists: one for normal ns, and the other for wildcard ns
+	normalDeniedNs, wildcardDeniedNs := preProcessDeniedNamespaces(args.DenyLabelNs)
+	nfd.deniedNs.normal = normalDeniedNs
+	nfd.deniedNs.wildcard = wildcardDeniedNs
+	// We forcibly deny kubernetes.io
+	nfd.deniedNs.normal["kubernetes.io"] = struct{}{}
+	nfd.deniedNs.wildcard[".kubernetes.io"] = struct{}{}
 
-	if args.ConfigFile != "" {
-		nfd.configFilePath = filepath.Clean(args.ConfigFile)
+	// Initialize Kubernetes API helpers
+	if !args.NoPublish {
+		kubeconfig, err := nfd.getKubeconfig()
+		if err != nil {
+			return nfd, err
+		}
+		nfd.apihelper = apihelper.K8sHelpers{Kubeconfig: kubeconfig}
 	}
 
 	return nfd, nil
 }
 
-func newDefaultConfig() *NFDConfig {
-	return &NFDConfig{
-		LabelWhiteList: utils.RegexpVal{Regexp: *regexp.MustCompile("")},
-		DenyLabelNs:    utils.StringSetVal{},
-		ExtraLabelNs:   utils.StringSetVal{},
-		NoPublish:      false,
-		ResourceLabels: utils.StringSetVal{},
-		EnableTaints:   false,
-	}
-}
-
 // Run NfdMaster server. The method returns in case of fatal errors or if Stop()
 // is called.
 func (m *nfdMaster) Run() error {
@@ -201,21 +182,13 @@ func (m *nfdMaster) Run() error {
 		}
 	}
 
-	// Create watcher for config file and read initial configuration
-	configWatch, err := utils.CreateFsWatcher(time.Second, m.configFilePath)
-	if err != nil {
-		return err
-	}
-	if err := m.configure(m.configFilePath, m.args.Options); err != nil {
-		return err
-	}
-
-	if !m.config.NoPublish {
+	if !m.args.NoPublish {
 		err := m.updateMasterNode()
 		if err != nil {
 			return fmt.Errorf("failed to update master node: %v", err)
 		}
 	}
+
 	// Run gRPC server
 	grpcErr := make(chan error, 1)
 	go m.runGrpcServer(grpcErr)
@@ -235,15 +208,6 @@ func (m *nfdMaster) Run() error {
 		case err := <-grpcErr:
 			return fmt.Errorf("error in serving gRPC: %w", err)
 
-		case <-configWatch.Events:
-			klog.Infof("reloading configuration")
-			if err := m.configure(m.configFilePath, m.args.Options); err != nil {
-				return err
-			}
-			// Update all nodes when the configuration changes
-			if m.nfdController != nil {
-				m.nfdController.updateAllNodesChan <- struct{}{}
-			}
 		case <-m.stop:
 			klog.Infof("shutting down nfd-master")
 			return nil
@@ -447,6 +411,7 @@ func (m *nfdMaster) updateMasterNode() error {
 // arriving through the gRPC API.
 func (m *nfdMaster) filterFeatureLabels(labels Labels) (Labels, ExtendedResources) {
 	outLabels := Labels{}
+
 	for label, value := range labels {
 		// Add possibly missing default ns
 		label := addNs(label, nfdv1alpha1.FeatureLabelNs)
@@ -458,7 +423,7 @@ func (m *nfdMaster) filterFeatureLabels(labels Labels) (Labels, ExtendedResource
 			!strings.HasSuffix(ns, nfdv1alpha1.FeatureLabelSubNsSuffix) && !strings.HasSuffix(ns, nfdv1alpha1.ProfileLabelSubNsSuffix) {
 			// If the namespace is denied, and not present in the extraLabelNs, label will be ignored
 			if isNamespaceDenied(ns, m.deniedNs.wildcard, m.deniedNs.normal) {
-				if _, ok := m.config.ExtraLabelNs[ns]; !ok {
+				if _, ok := m.args.ExtraLabelNs[ns]; !ok {
 					klog.Errorf("Namespace %q is not allowed. Ignoring label %q\n", ns, label)
 					continue
 				}
@@ -466,8 +431,8 @@ func (m *nfdMaster) filterFeatureLabels(labels Labels) (Labels, ExtendedResource
 		}
 
 		// Skip if label doesn't match labelWhiteList
-		if !m.config.LabelWhiteList.Regexp.MatchString(name) {
-			klog.Errorf("%s (%s) does not match the whitelist (%s) and will not be published.", name, label, m.config.LabelWhiteList.Regexp.String())
+		if !m.args.LabelWhiteList.Regexp.MatchString(name) {
+			klog.Errorf("%s (%s) does not match the whitelist (%s) and will not be published.", name, label, m.args.LabelWhiteList.Regexp.String())
 			continue
 		}
 		outLabels[label] = value
@@ -475,7 +440,7 @@ func (m *nfdMaster) filterFeatureLabels(labels Labels) (Labels, ExtendedResource
 
 	// Remove labels which are intended to be extended resources
 	extendedResources := ExtendedResources{}
-	for extendedResourceName := range m.config.ResourceLabels {
+	for extendedResourceName := range m.args.ResourceLabels {
 		// Add possibly missing default ns
 		extendedResourceName = addNs(extendedResourceName, nfdv1alpha1.FeatureLabelNs)
 		if value, ok := outLabels[extendedResourceName]; ok {
@@ -492,28 +457,6 @@ func (m *nfdMaster) filterFeatureLabels(labels Labels) (Labels, ExtendedResource
 	return outLabels, extendedResources
 }
 
-func filterTaints(taints []corev1.Taint) []corev1.Taint {
-	outTaints := []corev1.Taint{}
-
-	for _, taint := range taints {
-		ns, _ := splitNs(taint.Key)
-
-		// Check prefix of the key, filter out disallowed ones
-		if ns == "" {
-			klog.Errorf("taint keys without namespace (prefix/) are not allowed. Ignoring taint %v", ns, taint)
-			continue
-		}
-		if ns != nfdv1alpha1.TaintNs && !strings.HasSuffix(ns, nfdv1alpha1.TaintSubNsSuffix) &&
-			(ns == "kubernetes.io" || strings.HasSuffix(ns, ".kubernetes.io")) {
-			klog.Errorf("Prefix %q is not allowed for taint key. Ignoring taint %v", ns, taint)
-			continue
-		}
-		outTaints = append(outTaints, taint)
-	}
-
-	return outTaints
-}
-
 func verifyNodeName(cert *x509.Certificate, nodeName string) error {
 	if cert.Subject.CommonName == nodeName {
 		return nil
@@ -540,20 +483,6 @@ func isNamespaceDenied(labelNs string, wildcardDeniedNs map[string]struct{}, nor
 	return false
 }
 
-func isNamespaceAllowed(labelNs string, wildcardAllowedNs map[string]struct{}, normalAllowedNs map[string]struct{}) bool {
-	for allowedNs := range normalAllowedNs {
-		if labelNs == allowedNs {
-			return true
-		}
-	}
-	for allowedNs := range wildcardAllowedNs {
-		if strings.HasSuffix(labelNs, allowedNs) {
-			return true
-		}
-	}
-	return false
-}
-
 // SetLabels implements LabelerServer
 func (m *nfdMaster) SetLabels(c context.Context, r *pb.SetLabelsRequest) (*pb.SetLabelsReply, error) {
 	err := authorizeClient(c, m.args.VerifyNodeName, r.NodeName)
@@ -569,7 +498,8 @@ func (m *nfdMaster) SetLabels(c context.Context, r *pb.SetLabelsRequest) (*pb.Se
 	default:
 		klog.Infof("received labeling request for node %q", r.NodeName)
 	}
-	if !m.config.NoPublish {
+
+	if !m.args.NoPublish {
 		cli, err := m.apihelper.GetClient()
 		if err != nil {
 			return &pb.SetLabelsReply{}, err
@@ -609,7 +539,7 @@ func (m *nfdMaster) nfdAPIUpdateAllNodes() error {
 }
 
 func (m *nfdMaster) nfdAPIUpdateOneNode(nodeName string) error {
-	sel := k8sLabels.SelectorFromSet(k8sLabels.Set{nfdv1alpha1.NodeFeatureObjNodeNameLabel: nodeName})
+	sel := labels.SelectorFromSet(labels.Set{nfdv1alpha1.NodeFeatureObjNodeNameLabel: nodeName})
 	objs, err := m.nfdController.featureLister.List(sel)
 	if err != nil {
 		return fmt.Errorf("failed to get NodeFeature resources for node %q: %w", nodeName, err)
@@ -632,7 +562,7 @@ func (m *nfdMaster) nfdAPIUpdateOneNode(nodeName string) error {
 		return objs[i].Namespace < objs[j].Namespace
 	})
 
-	if m.config.NoPublish {
+	if m.args.NoPublish {
 		return nil
 	}
 
@@ -675,90 +605,23 @@ func (m *nfdMaster) nfdAPIUpdateOneNode(nodeName string) error {
 	return nil
 }
 
-// filterExtendedResources filters extended resources and returns a map
-// of valid extended resources.
-func (m *nfdMaster) filterExtendedResources(features *nfdv1alpha1.Features, extendedResources ExtendedResources) ExtendedResources {
-	outExtendedResources := ExtendedResources{}
-	deniedNs := map[string]struct{}{"kubernetes.io": {}}
-	deniedWildCarNs := map[string]struct{}{".kubernetes.io": {}}
-	allowedNs := map[string]struct{}{nfdv1alpha1.ExtendedResourceNs: {}}
-	allowedWildCardNs := map[string]struct{}{nfdv1alpha1.ExtendedResourceSubNsSuffix: {}}
-	for extendedResource, capacity := range extendedResources {
-		if strings.Contains(extendedResource, "/") {
-			// Check if given NS is allowed
-			ns, _ := splitNs(extendedResource)
-			if isNamespaceDenied(ns, deniedWildCarNs, deniedNs) {
-				if !isNamespaceAllowed(ns, allowedWildCardNs, allowedNs) {
-					klog.Errorf("namespace %q is not allowed. Ignoring Extended Resource  %q", ns, extendedResource)
-					continue
-				}
-			}
-		} else {
-			// Add possibly missing default ns
-			extendedResource = path.Join(nfdv1alpha1.ExtendedResourceNs, extendedResource)
-		}
-
-		// Dynamic Value
-		if strings.HasPrefix(capacity, "@") {
-			// capacity is a string in the form of attribute.featureset.elements
-			split := strings.SplitN(capacity[1:], ".", 3)
-			featureName := split[0] + "." + split[1]
-			elementName := split[2]
-			attrFeatureSet, ok := features.Attributes[featureName]
-			if !ok {
-				klog.Errorf("feature %s not found. Ignoring Extended Resource %q", featureName, extendedResource)
-				continue
-			}
-			element, ok := attrFeatureSet.Elements[elementName]
-			if !ok {
-				klog.Errorf("element %s not foundon feature %s. Ignoring Extended Resource %q", elementName, featureName, extendedResource)
-				continue
-			}
-			q, err := k8sQuantity.ParseQuantity(element)
-			if err != nil {
-				klog.Errorf("bad label value %s encountered for extended resource: %s", q.String(), extendedResource, err)
-				continue
-			}
-			outExtendedResources[extendedResource] = q.String()
-			continue
-		}
-		// Static Value (Pre-Defined at the NodeFeatureRule)
-		q, err := k8sQuantity.ParseQuantity(capacity)
-		if err != nil {
-			klog.Errorf("bad label value %s encountered for extended resource: %s", capacity, extendedResource, err)
-			continue
-		}
-		outExtendedResources[extendedResource] = q.String()
-	}
-	return outExtendedResources
-}
-
-func (m *nfdMaster) refreshNodeFeatures(cli *kubernetes.Clientset, nodeName string, annotations Annotations, labels map[string]string, features *nfdv1alpha1.Features) error {
-
+func (m *nfdMaster) refreshNodeFeatures(cli *kubernetes.Clientset, nodeName string, annotations, labels map[string]string, features *nfdv1alpha1.Features) error {
 	if labels == nil {
 		labels = make(map[string]string)
 	}
 
-	crLabels, crExtendedResources, crTaints := m.processNodeFeatureRule(features)
+	crLabels, crTaints := m.processNodeFeatureRule(features)
 
 	// Mix in CR-originated labels
 	for k, v := range crLabels {
 		labels[k] = v
 	}
 
-	// Remove labels which are intended to be extended resources via
-	// -resource-labels or their NS is not whitelisted
 	labels, extendedResources := m.filterFeatureLabels(labels)
 
-	// Mix in CR-originated extended resources with -resource-labels
-	for k, v := range crExtendedResources {
-		extendedResources[k] = v
-	}
-	extendedResources = m.filterExtendedResources(features, extendedResources)
-
 	var taints []corev1.Taint
-	if m.config.EnableTaints {
-		taints = filterTaints(crTaints)
+	if m.args.EnableTaints {
+		taints = crTaints
 	}
 
 	err := m.updateNodeObject(cli, nodeName, labels, annotations, extendedResources, taints)
@@ -875,22 +738,21 @@ func authorizeClient(c context.Context, checkNodeName bool, nodeName string) err
 	return nil
 }
 
-func (m *nfdMaster) processNodeFeatureRule(features *nfdv1alpha1.Features) (Labels, ExtendedResources, []corev1.Taint) {
+func (m *nfdMaster) processNodeFeatureRule(features *nfdv1alpha1.Features) (map[string]string, []corev1.Taint) {
 	if m.nfdController == nil {
-		return nil, nil, nil
+		return nil, nil
 	}
 
-	extendedResources := ExtendedResources{}
 	labels := make(map[string]string)
 	var taints []corev1.Taint
-	ruleSpecs, err := m.nfdController.ruleLister.List(k8sLabels.Everything())
+	ruleSpecs, err := m.nfdController.ruleLister.List(label.Everything())
 	sort.Slice(ruleSpecs, func(i, j int) bool {
 		return ruleSpecs[i].Name < ruleSpecs[j].Name
 	})
 
 	if err != nil {
 		klog.Errorf("failed to list NodeFeatureRule resources: %v", err)
-		return nil, nil, nil
+		return nil, nil
 	}
 
 	// Process all rule CRs
@@ -912,9 +774,6 @@ func (m *nfdMaster) processNodeFeatureRule(features *nfdv1alpha1.Features) (Labe
 			for k, v := range ruleOut.Labels {
 				labels[k] = v
 			}
-			for k, v := range ruleOut.ExtendedResources {
-				extendedResources[k] = v
-			}
 
 			// Feed back rule output to features map for subsequent rules to match
 			features.InsertAttributeFeatures(nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Labels)
@@ -922,7 +781,7 @@ func (m *nfdMaster) processNodeFeatureRule(features *nfdv1alpha1.Features) (Labe
 		}
 	}
 
-	return labels, extendedResources, taints
+	return labels, taints
 }
 
 // updateNodeObject ensures the Kubernetes node object is up to date,
@@ -962,6 +821,12 @@ func (m *nfdMaster) updateNodeObject(cli *kubernetes.Clientset, nodeName string,
 	patches := createPatches(oldLabels, node.Labels, labels, "/metadata/labels")
 	patches = append(patches, createPatches(nil, node.Annotations, annotations, "/metadata/annotations")...)
 
+	// Patch the node object in the apiserver
+	err = m.apihelper.PatchNode(cli, node.Name, patches)
+	if err != nil {
+		return fmt.Errorf("error while patching node object: %v", err)
+	}
+
 	// patch node status with extended resource changes
 	statusPatches := m.createExtendedResourcePatches(node, extendedResources)
 	err = m.apihelper.PatchNodeStatus(cli, node.Name, statusPatches)
@@ -969,12 +834,6 @@ func (m *nfdMaster) updateNodeObject(cli *kubernetes.Clientset, nodeName string,
 		return fmt.Errorf("error while patching extended resources: %v", err)
 	}
 
-	// Patch the node object in the apiserver
-	err = m.apihelper.PatchNode(cli, node.Name, patches)
-	if err != nil {
-		return fmt.Errorf("error while patching node object: %v", err)
-	}
-
 	if len(patches) > 0 || len(statusPatches) > 0 {
 		klog.Infof("node %q updated", nodeName)
 	} else {
@@ -1062,75 +921,6 @@ func (m *nfdMaster) createExtendedResourcePatches(n *corev1.Node, extendedResour
 	return patches
 }
 
-// Parse configuration options
-func (m *nfdMaster) configure(filepath string, overrides string) error {
-	// Create a new default config
-	c := newDefaultConfig()
-
-	// Try to read and parse config file
-	if filepath != "" {
-		data, err := os.ReadFile(filepath)
-		if err != nil {
-			if os.IsNotExist(err) {
-				klog.Infof("config file %q not found, using defaults", filepath)
-			} else {
-				return fmt.Errorf("error reading config file: %s", err)
-			}
-		} else {
-			err = yaml.Unmarshal(data, c)
-			if err != nil {
-				return fmt.Errorf("failed to parse config file: %s", err)
-			}
-
-			klog.Infof("configuration file %q parsed", filepath)
-		}
-	}
-
-	// Parse config overrides
-	if err := yaml.Unmarshal([]byte(overrides), c); err != nil {
-		return fmt.Errorf("failed to parse -options: %s", err)
-	}
-	if m.args.Overrides.NoPublish != nil {
-		c.NoPublish = *m.args.Overrides.NoPublish
-	}
-	if m.args.Overrides.DenyLabelNs != nil {
-		c.DenyLabelNs = *m.args.Overrides.DenyLabelNs
-	}
-	if m.args.Overrides.ExtraLabelNs != nil {
-		c.ExtraLabelNs = *m.args.Overrides.ExtraLabelNs
-	}
-	if m.args.Overrides.ResourceLabels != nil {
-		c.ResourceLabels = *m.args.Overrides.ResourceLabels
-	}
-	if m.args.Overrides.EnableTaints != nil {
-		c.EnableTaints = *m.args.Overrides.EnableTaints
-	}
-	if m.args.Overrides.LabelWhiteList != nil {
-		c.LabelWhiteList = *m.args.Overrides.LabelWhiteList
-	}
-
-	m.config = c
-	if !c.NoPublish {
-		kubeconfig, err := m.getKubeconfig()
-		if err != nil {
-			return err
-		}
-		m.apihelper = apihelper.K8sHelpers{Kubeconfig: kubeconfig}
-	}
-	// Pre-process DenyLabelNS into 2 lists: one for normal ns, and the other for wildcard ns
-	normalDeniedNs, wildcardDeniedNs := preProcessDeniedNamespaces(c.DenyLabelNs)
-	m.deniedNs.normal = normalDeniedNs
-	m.deniedNs.wildcard = wildcardDeniedNs
-	// We forcibly deny kubernetes.io
-	m.deniedNs.normal["kubernetes.io"] = struct{}{}
-	m.deniedNs.wildcard[".kubernetes.io"] = struct{}{}
-
-	utils.KlogDump(1, "effective configuration:", "  ", m.config)
-	klog.Infof("master (re-)configuration successfully completed")
-
-	return nil
-}
-
 // addNs adds a namespace if one isn't already found from src string
 func addNs(src string, nsToAdd string) string {
 	if strings.Contains(src, "/") {
diff --git a/pkg/nfd-worker/nfd-worker.go b/pkg/nfd-worker/nfd-worker.go
index e7f9a46f5..6c83483b7 100644
--- a/pkg/nfd-worker/nfd-worker.go
+++ b/pkg/nfd-worker/nfd-worker.go
@@ -548,7 +548,7 @@ func (w *nfdWorker) configure(filepath string, overrides string) error {
 	}
 
 	klog.Infof("worker (re-)configuration successfully completed")
-	utils.KlogDump(1, "effective configuration:", "  ", w.config)
+
 	return nil
 }
 
diff --git a/source/cpu/cpu.go b/source/cpu/cpu.go
index 33ffe3096..48dedfa13 100644
--- a/source/cpu/cpu.go
+++ b/source/cpu/cpu.go
@@ -164,12 +164,8 @@ func (s *cpuSource) GetLabels() (source.FeatureLabels, error) {
 	}
 
 	// RDT
-	for k, v := range features.Attributes[RdtFeature].Elements {
-		if k == "RDTL3CA_NUM_CLOSID" {
-			continue
-		}
-
-		labels["rdt."+k] = v
+	for k := range features.Flags[RdtFeature].Elements {
+		labels["rdt."+k] = true
 	}
 
 	// Security
@@ -231,9 +227,9 @@ func (s *cpuSource) Discover() error {
 	s.features.Attributes[PstateFeature] = nfdv1alpha1.NewAttributeFeatures(pstate)
 
 	// Detect RDT features
-	s.features.Attributes[RdtFeature] = nfdv1alpha1.NewAttributeFeatures(discoverRDT())
+	s.features.Flags[RdtFeature] = nfdv1alpha1.NewFlagFeatures(discoverRDT()...)
 
-	// Detect available guest protection(SGX,TDX,SEV) features
+	// Detect SGX features
 	s.features.Attributes[SecurityFeature] = nfdv1alpha1.NewAttributeFeatures(discoverSecurity())
 
 	// Detect SGX features
diff --git a/source/cpu/rdt_amd64.go b/source/cpu/rdt_amd64.go
index 30143a37c..07d110288 100644
--- a/source/cpu/rdt_amd64.go
+++ b/source/cpu/rdt_amd64.go
@@ -20,14 +20,6 @@ limitations under the License.
 package cpu
 
 import (
-	"bytes"
-	"os"
-	"path/filepath"
-	"strconv"
-
-	"github.com/opencontainers/runc/libcontainer/intelrdt"
-	"k8s.io/klog/v2"
-
 	"sigs.k8s.io/node-feature-discovery/pkg/cpuid"
 )
 
@@ -52,8 +44,8 @@ const (
 	RDT_ALLOCATION_EBX_MEMORY_BANDWIDTH_ALLOCATION              = 1 << 3
 )
 
-func discoverRDT() map[string]string {
-	attributes := map[string]string{}
+func discoverRDT() []string {
+	features := []string{}
 
 	// Read cpuid information
 	extFeatures := cpuid.Cpuid(LEAF_EXT_FEATURE_FLAGS, 0)
@@ -65,16 +57,16 @@ func discoverRDT() map[string]string {
 	if extFeatures.EBX&EXT_FEATURE_FLAGS_EBX_RDT_M != 0 {
 		if rdtMonitoring.EDX&RDT_MONITORING_EDX_L3_MONITORING != 0 {
 			// Monitoring is supported
-			attributes["RDTMON"] = "true"
+			features = append(features, "RDTMON")
 
 			// Cache Monitoring Technology (L3 occupancy monitoring)
 			if rdtL3Monitoring.EDX&RDT_MONITORING_SUBLEAF_L3_EDX_L3_OCCUPANCY_MONITORING != 0 {
-				attributes["RDTCMT"] = "true"
+				features = append(features, "RDTCMT")
 			}
 			// Memore Bandwidth Monitoring (L3 local&total bandwidth monitoring)
 			if rdtL3Monitoring.EDX&RDT_MONITORING_SUBLEAF_L3_EDX_L3_TOTAL_BANDWIDTH_MONITORING != 0 &&
 				rdtL3Monitoring.EDX&RDT_MONITORING_SUBLEAF_L3_EDX_L3_LOCAL_BANDWIDTH_MONITORING != 0 {
-				attributes["RDTMBM"] = "true"
+				features = append(features, "RDTMBM")
 			}
 		}
 	}
@@ -83,51 +75,17 @@ func discoverRDT() map[string]string {
 	if extFeatures.EBX&EXT_FEATURE_FLAGS_EBX_RDT_A != 0 {
 		// L3 Cache Allocation
 		if rdtAllocation.EBX&RDT_ALLOCATION_EBX_L3_CACHE_ALLOCATION != 0 {
-			attributes["RDTL3CA"] = "true"
-			numClosID := getNumClosID("L3")
-			if numClosID > -1 {
-				attributes["RDTL3CA_NUM_CLOSID"] = strconv.FormatInt(int64(numClosID), 10)
-			}
+			features = append(features, "RDTL3CA")
 		}
 		// L2 Cache Allocation
 		if rdtAllocation.EBX&RDT_ALLOCATION_EBX_L2_CACHE_ALLOCATION != 0 {
-			attributes["RDTL2CA"] = "true"
+			features = append(features, "RDTL2CA")
 		}
 		// Memory Bandwidth Allocation
 		if rdtAllocation.EBX&RDT_ALLOCATION_EBX_MEMORY_BANDWIDTH_ALLOCATION != 0 {
-			attributes["RDTMBA"] = "true"
+			features = append(features, "RDTMBA")
 		}
 	}
 
-	return attributes
-}
-
-func getNumClosID(level string) int64 {
-	resctrlRootDir, err := intelrdt.Root()
-	if err != nil {
-		klog.V(4).ErrorS(err, "can't find resctrl filesystem")
-		return -1
-	}
-
-	closidFile := filepath.Join(resctrlRootDir, "info", level, "num_closids")
-
-	if _, err := os.Stat(closidFile); err != nil {
-		klog.V(4).ErrorS(err, "failed to stat file", "fileName", closidFile)
-		return -1
-	}
-
-	closidsBytes, err := os.ReadFile(filepath.Join(resctrlRootDir, "info", level, "num_closids"))
-	if err != nil {
-		klog.V(4).ErrorS(err, "failed to read file", "fileName", closidFile)
-		return -1
-	}
-
-	numClosIDs, err := strconv.ParseInt(string(bytes.TrimSpace(closidsBytes)), 10, 64)
-	if err != nil {
-		klog.V(4).ErrorS(err, "failed to ParseInt", "num_closids", string(bytes.TrimSpace(closidsBytes)))
-		return -1
-	}
-
-	// subtract 1 for default control group
-	return numClosIDs - 1
+	return features
 }
diff --git a/source/cpu/rdt_stub.go b/source/cpu/rdt_stub.go
index d1482dbe8..addad4c00 100644
--- a/source/cpu/rdt_stub.go
+++ b/source/cpu/rdt_stub.go
@@ -19,6 +19,6 @@ limitations under the License.
 
 package cpu
 
-func discoverRDT() map[string]string {
-	return map[string]string{}
+func discoverRDT() []string {
+	return []string{}
 }
diff --git a/source/cpu/security_amd64.go b/source/cpu/security_amd64.go
index 9f3437c55..26bcfdb5b 100644
--- a/source/cpu/security_amd64.go
+++ b/source/cpu/security_amd64.go
@@ -20,11 +20,7 @@ limitations under the License.
 package cpu
 
 import (
-	"bufio"
-	"io"
 	"os"
-	"strconv"
-	"strings"
 
 	"github.com/klauspost/cpuid/v2"
 
@@ -40,23 +36,6 @@ func discoverSecurity() map[string]string {
 
 	if tdxEnabled() {
 		elems["tdx.enabled"] = "true"
-
-		tdxTotalKeys := getCgroupMiscCapacity("tdx")
-		if tdxTotalKeys > -1 {
-			elems["tdx.total_keys"] = strconv.FormatInt(int64(tdxTotalKeys), 10)
-		}
-	}
-
-	if sevParameterEnabled("sev") {
-		elems["sev.enabled"] = "true"
-	}
-
-	if sevParameterEnabled("sev_es") {
-		elems["sev.es.enabled"] = "true"
-	}
-
-	if sevParameterEnabled("sev_snp") {
-		elems["sev.snp.enabled"] = "true"
 	}
 
 	return elems
@@ -94,52 +73,3 @@ func tdxEnabled() bool {
 	}
 	return false
 }
-
-func sevParameterEnabled(parameter string) bool {
-	// SEV-SNP is supported and enabled when the kvm module `sev_snp` parameter is set to `Y`
-	// SEV-SNP support infers SEV (-ES) support
-	sevKvmParameterPath := hostpath.SysfsDir.Path("module/kvm_amd/parameters/", parameter)
-	if _, err := os.Stat(sevKvmParameterPath); err == nil {
-		if c, err := os.ReadFile(sevKvmParameterPath); err == nil && len(c) > 0 && (c[0] == '1' || c[0] == 'Y') {
-			return true
-		}
-	}
-	return false
-}
-
-func getCgroupMiscCapacity(resource string) int64 {
-	var totalResources int64 = -1
-
-	miscCgroups := hostpath.SysfsDir.Path("fs/cgroup/misc.capacity")
-	f, err := os.Open(miscCgroups)
-	if err != nil {
-		return totalResources
-	}
-	defer f.Close()
-
-	r := bufio.NewReader(f)
-	for {
-		line, _, err := r.ReadLine()
-		if err != nil {
-			if err == io.EOF {
-				break
-			}
-			return totalResources
-		}
-
-		if !strings.HasPrefix(string(line), resource) {
-			continue
-		}
-
-		s := strings.Split(string(line), " ")
-		resources, err := strconv.ParseInt(s[1], 10, 64)
-		if err != nil {
-			return totalResources
-		}
-
-		totalResources = resources
-		break
-	}
-
-	return totalResources
-}


Test patch:
diff --git a/pkg/nfd-master/nfd-master-internal_test.go b/pkg/nfd-master/nfd-master-internal_test.go
index cf821c8e7..2281e8f20 100644
--- a/pkg/nfd-master/nfd-master-internal_test.go
+++ b/pkg/nfd-master/nfd-master-internal_test.go
@@ -18,13 +18,10 @@ package nfdmaster
 
 import (
 	"fmt"
-	"os"
-	"path/filepath"
 	"regexp"
 	"sort"
 	"strings"
 	"testing"
-	"time"
 
 	"github.com/smartystreets/assertions"
 	. "github.com/smartystreets/goconvey/convey"
@@ -59,7 +56,7 @@ func newMockNode() *corev1.Node {
 func newMockMaster(apihelper apihelper.APIHelpers) *nfdMaster {
 	return &nfdMaster{
 		nodeName:  mockNodeName,
-		config:    &NFDConfig{LabelWhiteList: utils.RegexpVal{Regexp: *regexp.MustCompile("")}},
+		args:      Args{LabelWhiteList: utils.RegexpVal{Regexp: *regexp.MustCompile("")}},
 		apihelper: apihelper,
 	}
 }
@@ -86,12 +83,6 @@ func TestUpdateNodeObject(t *testing.T) {
 		}
 		sort.Strings(fakeExtResourceNames)
 
-		// Create a list of expected node status patches
-		statusPatches := []apihelper.JsonPatch{}
-		for k, v := range fakeExtResources {
-			statusPatches = append(statusPatches, apihelper.NewJsonPatch("add", "/status/capacity", k, v))
-		}
-
 		mockAPIHelper := new(apihelper.MockAPIHelpers)
 		mockMaster := newMockMaster(mockAPIHelper)
 		mockClient := &k8sclient.Clientset{}
@@ -114,10 +105,16 @@ func TestUpdateNodeObject(t *testing.T) {
 				metadataPatches = append(metadataPatches, apihelper.NewJsonPatch("add", "/metadata/annotations", k, v))
 			}
 
+			// Create a list of expected node status patches
+			statusPatches := []apihelper.JsonPatch{}
+			for k, v := range fakeExtResources {
+				statusPatches = append(statusPatches, apihelper.NewJsonPatch("add", "/status/capacity", k, v))
+			}
+
 			mockAPIHelper.On("GetClient").Return(mockClient, nil)
 			mockAPIHelper.On("GetNode", mockClient, mockNodeName).Return(mockNode, nil).Twice()
-			mockAPIHelper.On("PatchNodeStatus", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(statusPatches))).Return(nil)
 			mockAPIHelper.On("PatchNode", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(metadataPatches))).Return(nil)
+			mockAPIHelper.On("PatchNodeStatus", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(statusPatches))).Return(nil)
 			err := mockMaster.updateNodeObject(mockClient, mockNodeName, fakeFeatureLabels, fakeAnnotations, fakeExtResources, nil)
 
 			Convey("Error is nil", func() {
@@ -160,7 +157,6 @@ func TestUpdateNodeObject(t *testing.T) {
 			expectedError := errors.New("fake error")
 			mockAPIHelper.On("GetClient").Return(mockClient, nil)
 			mockAPIHelper.On("GetNode", mockClient, mockNodeName).Return(mockNode, nil).Twice()
-			mockAPIHelper.On("PatchNodeStatus", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(statusPatches))).Return(nil)
 			mockAPIHelper.On("PatchNode", mockClient, mockNodeName, mock.Anything).Return(expectedError).Twice()
 			err := mockMaster.updateNodeObject(mockClient, mockNodeName, fakeFeatureLabels, fakeAnnotations, fakeExtResources, nil)
 
@@ -329,8 +325,8 @@ func TestSetLabels(t *testing.T) {
 
 			mockHelper.On("GetClient").Return(mockClient, nil)
 			mockHelper.On("GetNode", mockClient, workerName).Return(mockNode, nil).Twice()
-			mockHelper.On("PatchNodeStatus", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedStatusPatches))).Return(nil)
 			mockHelper.On("PatchNode", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedPatches))).Return(nil)
+			mockHelper.On("PatchNodeStatus", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedStatusPatches))).Return(nil)
 			_, err := mockMaster.SetLabels(mockCtx, mockReq)
 			Convey("No error should be returned", func() {
 				So(err, ShouldBeNil)
@@ -345,11 +341,11 @@ func TestSetLabels(t *testing.T) {
 				apihelper.NewJsonPatch("add", "/metadata/labels", nfdv1alpha1.FeatureLabelNs+"/feature-2", mockLabels["feature-2"]),
 			}
 
-			mockMaster.config.LabelWhiteList.Regexp = *regexp.MustCompile("^f.*2$")
+			mockMaster.args.LabelWhiteList.Regexp = *regexp.MustCompile("^f.*2$")
 			mockHelper.On("GetClient").Return(mockClient, nil)
 			mockHelper.On("GetNode", mockClient, workerName).Return(mockNode, nil)
-			mockHelper.On("PatchNodeStatus", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedStatusPatches))).Return(nil)
 			mockHelper.On("PatchNode", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedPatches))).Return(nil)
+			mockHelper.On("PatchNodeStatus", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedStatusPatches))).Return(nil)
 			_, err := mockMaster.SetLabels(mockCtx, mockReq)
 			Convey("Error is nil", func() {
 				So(err, ShouldBeNil)
@@ -361,8 +357,7 @@ func TestSetLabels(t *testing.T) {
 			instance := "foo"
 			vendorFeatureLabel := "vendor." + nfdv1alpha1.FeatureLabelNs + "/feature-4"
 			vendorProfileLabel := "vendor." + nfdv1alpha1.ProfileLabelNs + "/feature-5"
-			mockLabels := map[string]string{
-				"feature-1":                      "val-1",
+			mockLabels := map[string]string{"feature-1": "val-1",
 				"valid.ns/feature-2":             "val-2",
 				"random.denied.ns/feature-3":     "val-3",
 				"kubernetes.io/feature-4":        "val-4",
@@ -383,12 +378,12 @@ func TestSetLabels(t *testing.T) {
 
 			mockMaster.deniedNs.normal = map[string]struct{}{"random.denied.ns": {}}
 			mockMaster.deniedNs.wildcard = map[string]struct{}{"kubernetes.io": {}}
-			mockMaster.config.ExtraLabelNs = map[string]struct{}{"valid.ns": {}}
+			mockMaster.args.ExtraLabelNs = map[string]struct{}{"valid.ns": {}}
 			mockMaster.args.Instance = instance
 			mockHelper.On("GetClient").Return(mockClient, nil)
 			mockHelper.On("GetNode", mockClient, workerName).Return(mockNode, nil)
-			mockHelper.On("PatchNodeStatus", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedStatusPatches))).Return(nil)
 			mockHelper.On("PatchNode", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedPatches))).Return(nil)
+			mockHelper.On("PatchNodeStatus", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedStatusPatches))).Return(nil)
 			mockReq := &labeler.SetLabelsRequest{NodeName: workerName, NfdVersion: workerVer, Labels: mockLabels}
 			_, err := mockMaster.SetLabels(mockCtx, mockReq)
 			Convey("Error is nil", func() {
@@ -409,11 +404,11 @@ func TestSetLabels(t *testing.T) {
 				apihelper.NewJsonPatch("add", "/status/capacity", nfdv1alpha1.FeatureLabelNs+"/feature-3", mockLabels["feature-3"]),
 			}
 
-			mockMaster.config.ResourceLabels = map[string]struct{}{"feature-3": {}, "feature-1": {}}
+			mockMaster.args.ResourceLabels = map[string]struct{}{"feature-3": {}, "feature-1": {}}
 			mockHelper.On("GetClient").Return(mockClient, nil)
 			mockHelper.On("GetNode", mockClient, workerName).Return(mockNode, nil)
-			mockHelper.On("PatchNodeStatus", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedStatusPatches))).Return(nil)
 			mockHelper.On("PatchNode", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedPatches))).Return(nil)
+			mockHelper.On("PatchNodeStatus", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedStatusPatches))).Return(nil)
 			_, err := mockMaster.SetLabels(mockCtx, mockReq)
 			Convey("Error is nil", func() {
 				So(err, ShouldBeNil)
@@ -429,7 +424,7 @@ func TestSetLabels(t *testing.T) {
 			})
 		})
 
-		mockMaster.config.NoPublish = true
+		mockMaster.args.NoPublish = true
 		Convey("With '-no-publish'", func() {
 			_, err := mockMaster.SetLabels(mockCtx, mockReq)
 			Convey("Operation should succeed", func() {
@@ -518,182 +513,6 @@ func TestRemoveLabelsWithPrefix(t *testing.T) {
 	})
 }
 
-func TestConfigParse(t *testing.T) {
-	Convey("When parsing configuration", t, func() {
-		m, err := NewNfdMaster(&Args{})
-		So(err, ShouldBeNil)
-		master := m.(*nfdMaster)
-		overrides := `{"noPublish": true, "enableTaints": true, "extraLabelNs": ["added.ns.io","added.kubernetes.io"], "denyLabelNs": ["denied.ns.io","denied.kubernetes.io"], "resourceLabels": ["vendor-1.com/feature-1","vendor-2.io/feature-2"], "labelWhiteList": "foo"}`
-
-		Convey("and no core cmdline flags have been specified", func() {
-			So(master.configure("non-existing-file", overrides), ShouldBeNil)
-			Convey("overrides should be in effect", func() {
-				So(master.config.NoPublish, ShouldResemble, true)
-				So(master.config.EnableTaints, ShouldResemble, true)
-				So(master.config.ExtraLabelNs, ShouldResemble, utils.StringSetVal{"added.ns.io": struct{}{}, "added.kubernetes.io": struct{}{}})
-				So(master.config.DenyLabelNs, ShouldResemble, utils.StringSetVal{"denied.ns.io": struct{}{}, "denied.kubernetes.io": struct{}{}})
-				So(master.config.ResourceLabels, ShouldResemble, utils.StringSetVal{"vendor-1.com/feature-1": struct{}{}, "vendor-2.io/feature-2": struct{}{}})
-				So(master.config.LabelWhiteList.String(), ShouldEqual, "foo")
-			})
-		})
-		Convey("and a non-accessible file, but cmdline flags and some overrides are specified", func() {
-			master.args = Args{Overrides: ConfigOverrideArgs{
-				ExtraLabelNs: &utils.StringSetVal{"override.added.ns.io": struct{}{}},
-				DenyLabelNs:  &utils.StringSetVal{"override.denied.ns.io": struct{}{}}}}
-			So(master.configure("non-existing-file", overrides), ShouldBeNil)
-
-			Convey("cmdline flags should be in effect instead overrides", func() {
-				So(master.config.ExtraLabelNs, ShouldResemble, utils.StringSetVal{"override.added.ns.io": struct{}{}})
-				So(master.config.DenyLabelNs, ShouldResemble, utils.StringSetVal{"override.denied.ns.io": struct{}{}})
-			})
-			Convey("overrides should take effect", func() {
-				So(master.config.NoPublish, ShouldBeTrue)
-				So(master.config.EnableTaints, ShouldBeTrue)
-			})
-		})
-		// Create a temporary config file
-		f, err := os.CreateTemp("", "nfd-test-")
-		defer os.Remove(f.Name())
-		So(err, ShouldBeNil)
-		_, err = f.WriteString(`
-noPublish: true
-denyLabelNs: ["denied.ns.io","denied.kubernetes.io"]
-resourceLabels: ["vendor-1.com/feature-1","vendor-2.io/feature-2"]
-enableTaints: false
-labelWhiteList: "foo"
-`)
-		f.Close()
-		So(err, ShouldBeNil)
-
-		Convey("and a proper config file is specified", func() {
-			master.args = Args{Overrides: ConfigOverrideArgs{ExtraLabelNs: &utils.StringSetVal{"override.added.ns.io": struct{}{}}}}
-			So(master.configure(f.Name(), ""), ShouldBeNil)
-			Convey("specified configuration should take effect", func() {
-				// Verify core config
-				So(master.config.NoPublish, ShouldBeTrue)
-				So(master.config.EnableTaints, ShouldBeFalse)
-				So(master.config.ExtraLabelNs, ShouldResemble, utils.StringSetVal{"override.added.ns.io": struct{}{}})
-				So(master.config.ResourceLabels, ShouldResemble, utils.StringSetVal{"vendor-1.com/feature-1": struct{}{}, "vendor-2.io/feature-2": struct{}{}}) // from cmdline
-				So(master.config.DenyLabelNs, ShouldResemble, utils.StringSetVal{"denied.ns.io": struct{}{}, "denied.kubernetes.io": struct{}{}})
-				So(master.config.LabelWhiteList.String(), ShouldEqual, "foo")
-			})
-		})
-
-		Convey("and a proper config file and overrides are given", func() {
-			master.args = Args{Overrides: ConfigOverrideArgs{DenyLabelNs: &utils.StringSetVal{"denied.ns.io": struct{}{}}}}
-			overrides := `{"extraLabelNs": ["added.ns.io"], "noPublish": true}`
-			So(master.configure(f.Name(), overrides), ShouldBeNil)
-
-			Convey("overrides should take precedence over the config file", func() {
-				// Verify core config
-				So(master.config.ExtraLabelNs, ShouldResemble, utils.StringSetVal{"added.ns.io": struct{}{}}) // from overrides
-				So(master.config.DenyLabelNs, ShouldResemble, utils.StringSetVal{"denied.ns.io": struct{}{}}) // from cmdline
-			})
-		})
-	})
-}
-
-func TestDynamicConfig(t *testing.T) {
-	Convey("When running nfd-master", t, func() {
-		tmpDir, err := os.MkdirTemp("", "*.nfd-test")
-		So(err, ShouldBeNil)
-		defer os.RemoveAll(tmpDir)
-
-		// Create (temporary) dir for config
-		configDir := filepath.Join(tmpDir, "subdir-1", "subdir-2", "master.conf")
-		err = os.MkdirAll(configDir, 0755)
-		So(err, ShouldBeNil)
-
-		// Create config file
-		configFile := filepath.Join(configDir, "master.conf")
-
-		writeConfig := func(data string) {
-			f, err := os.Create(configFile)
-			So(err, ShouldBeNil)
-			_, err = f.WriteString(data)
-			So(err, ShouldBeNil)
-			err = f.Close()
-			So(err, ShouldBeNil)
-		}
-		writeConfig(`
-extraLabelNs: ["added.ns.io"]
-`)
-
-		noPublish := true
-		m, err := NewNfdMaster(&Args{
-			ConfigFile: configFile,
-			Overrides: ConfigOverrideArgs{
-				NoPublish: &noPublish,
-			},
-		})
-		So(err, ShouldBeNil)
-		master := m.(*nfdMaster)
-
-		Convey("config file updates should take effect", func() {
-			go func() { _ = m.Run() }()
-			defer m.Stop()
-			// Check initial config
-			time.Sleep(10 * time.Second)
-			So(func() interface{} { return master.config.ExtraLabelNs },
-				withTimeout, 2*time.Second, ShouldResemble, utils.StringSetVal{"added.ns.io": struct{}{}})
-
-			// Update config and verify the effect
-			writeConfig(`
-extraLabelNs: ["override.ns.io"]
-`)
-			So(func() interface{} { return master.config.ExtraLabelNs },
-				withTimeout, 2*time.Second, ShouldResemble, utils.StringSetVal{"override.ns.io": struct{}{}})
-
-			// Removing config file should get back our defaults
-			err = os.RemoveAll(tmpDir)
-			So(err, ShouldBeNil)
-			So(func() interface{} { return master.config.ExtraLabelNs },
-				withTimeout, 2*time.Second, ShouldResemble, utils.StringSetVal{})
-
-			// Re-creating config dir and file should change the config
-			err = os.MkdirAll(configDir, 0755)
-			So(err, ShouldBeNil)
-			writeConfig(`
-extraLabelNs: ["another.override.ns"]
-`)
-			So(func() interface{} { return master.config.ExtraLabelNs },
-				withTimeout, 2*time.Second, ShouldResemble, utils.StringSetVal{"another.override.ns": struct{}{}})
-		})
-	})
-}
-
-// withTimeout is a custom assertion for polling a value asynchronously
-// actual is a function for getting the actual value
-// expected[0] is a time.Duration value specifying the timeout
-// expected[1] is  the "real" assertion function to be called
-// expected[2:] are the arguments for the "real" assertion function
-func withTimeout(actual interface{}, expected ...interface{}) string {
-	getter, ok := actual.(func() interface{})
-	if !ok {
-		return "not getterFunc"
-	}
-	t, ok := expected[0].(time.Duration)
-	if !ok {
-		return "not time.Duration"
-	}
-	f, ok := expected[1].(func(interface{}, ...interface{}) string)
-	if !ok {
-		return "not an assert func"
-	}
-	timeout := time.After(t)
-	for {
-		result := f(getter(), expected[2:]...)
-		if result == "" {
-			return ""
-		}
-		select {
-		case <-timeout:
-			return result
-		case <-time.After(10 * time.Millisecond):
-		}
-	}
-}
-
 func jsonPatchMatcher(expected []apihelper.JsonPatch) func([]apihelper.JsonPatch) bool {
 	return func(actual []apihelper.JsonPatch) bool {
 		// We don't care about modifying the original slices
diff --git a/pkg/nfd-master/nfd-master_test.go b/pkg/nfd-master/nfd-master_test.go
index b15721601..a2cca826a 100644
--- a/pkg/nfd-master/nfd-master_test.go
+++ b/pkg/nfd-master/nfd-master_test.go
@@ -35,11 +35,5 @@ func TestNewNfdMaster(t *testing.T) {
 				So(err3, ShouldNotBeNil)
 			})
 		})
-		Convey("When -config is supplied", func() {
-			_, err := m.NewNfdMaster(&m.Args{CertFile: "crt", KeyFile: "key", CaFile: "ca", ConfigFile: "master-config.yaml"})
-			Convey("An error should not be returned", func() {
-				So(err, ShouldBeNil)
-			})
-		})
 	})
 }
diff --git a/pkg/nfd-worker/nfd-worker_test.go b/pkg/nfd-worker/nfd-worker_test.go
index 4a910338c..b80aa27b3 100644
--- a/pkg/nfd-worker/nfd-worker_test.go
+++ b/pkg/nfd-worker/nfd-worker_test.go
@@ -38,12 +38,9 @@ type testContext struct {
 
 func setupTest(args *master.Args) testContext {
 	// Fixed port and no-publish, for convenience
-	publish := true
-	args.Overrides = master.ConfigOverrideArgs{
-		NoPublish:      &publish,
-		LabelWhiteList: &utils.RegexpVal{Regexp: *regexp.MustCompile("")},
-	}
+	args.NoPublish = true
 	args.Port = 8192
+	args.LabelWhiteList.Regexp = *regexp.MustCompile("")
 	m, err := master.NewNfdMaster(args)
 	if err != nil {
 		fmt.Printf("Test setup failed: %v\n", err)
diff --git a/scripts/test-infra/verify.sh b/scripts/test-infra/verify.sh
index 1df24e518..938be4fb4 100755
--- a/scripts/test-infra/verify.sh
+++ b/scripts/test-infra/verify.sh
@@ -11,6 +11,10 @@ kubectl="$gobinpath/kubectl"
 curl -L https://dl.k8s.io/release/v1.22.1/bin/linux/amd64/kubectl -o "$kubectl"
 chmod 755 "$kubectl"
 
+curl https://keybase.io/codecovsecurity/pgp_keys.asc | gpg --no-default-keyring --keyring trustedkeys.gpg --import
+curl -Os https://uploader.codecov.io/latest/linux/codecov
+chmod +x codecov
+
 # Run verify steps
 echo "Checking gofmt"
 make gofmt-verify
@@ -24,6 +28,9 @@ make helm-lint
 echo "Running unit tests"
 make test
 
+# Upload coverage report
+./codecov -t ${CODECOV_TOKEN}
+
 # Check that repo is clean
 if ! git diff --quiet; then
     echo "Repository is dirty!"
diff --git a/test/e2e/data/nodefeaturerule-3-updated.yaml b/test/e2e/data/nodefeaturerule-3-updated.yaml
index 4e88315cb..8b1778978 100644
--- a/test/e2e/data/nodefeaturerule-3-updated.yaml
+++ b/test/e2e/data/nodefeaturerule-3-updated.yaml
@@ -8,18 +8,11 @@ spec:
     - name: "e2e-taint-test-1"
       taints:
         - effect: PreferNoSchedule
-          key: "feature.node.kubernetes.io/fake-special-node"
+          key: "nfd.node.kubernetes.io/fake-special-node"
           value: "exists"
         - effect: NoExecute
-          key: "feature.node.kubernetes.io/foo"
+          key: "nfd.node.kubernetes.io/foo"
           value: "true"
-        # The following taints should be filtered out by nfd-master
-        - effect: PreferNoSchedule
-          key: "kubernetes.io/denied-1"
-        - effect: PreferNoSchedule
-          key: "node.kubernetes.io/denied-2"
-        - effect: PreferNoSchedule
-          key: "unprefixed-taint"
       matchFeatures:
         - feature: "fake.attribute"
           matchExpressions:
@@ -30,7 +23,7 @@ spec:
     - name: "e2e-taint-test-2"
       taints:
         - effect: PreferNoSchedule
-          key: "feature.node.kubernetes.io/fake-cpu"
+          key: "nfd.node.kubernetes.io/fake-cpu"
           value: "true"
       matchFeatures:
         - feature: "fake.attribute"
diff --git a/test/e2e/data/nodefeaturerule-3.yaml b/test/e2e/data/nodefeaturerule-3.yaml
index 767ee8194..b9701cb19 100644
--- a/test/e2e/data/nodefeaturerule-3.yaml
+++ b/test/e2e/data/nodefeaturerule-3.yaml
@@ -8,13 +8,13 @@ spec:
     - name: "e2e-taint-test-1"
       taints:
         - effect: PreferNoSchedule
-          key: "feature.node.kubernetes.io/fake-special-node"
+          key: "nfd.node.kubernetes.io/fake-special-node"
           value: "exists"
         - effect: NoExecute
-          key: "feature.node.kubernetes.io/fake-dedicated-node"
+          key: "nfd.node.kubernetes.io/fake-dedicated-node"
           value: "true"
         - effect: "NoExecute"
-          key: "feature.node.kubernetes.io/performance-optimized-node"
+          key: "nfd.node.kubernetes.io/performance-optimized-node"
           value: "true"
       matchFeatures:
         - feature: "fake.attribute"
@@ -26,7 +26,7 @@ spec:
     - name: "e2e-taint-test-2"
       taints:
         - effect: PreferNoSchedule
-          key: "feature.node.kubernetes.io/fake-special-cpu"
+          key: "nfd.node.kubernetes.io/fake-special-cpu"
           value: "true"
       matchFeatures:
         - feature: "fake.attribute"
diff --git a/test/e2e/data/nodefeaturerule-4.yaml b/test/e2e/data/nodefeaturerule-4.yaml
deleted file mode 100644
index 3aa8b5c89..000000000
--- a/test/e2e/data/nodefeaturerule-4.yaml
+++ /dev/null
@@ -1,32 +0,0 @@
-apiVersion: nfd.k8s-sigs.io/v1alpha1
-kind: NodeFeatureRule
-metadata:
-  name: e2e-extened-resource-test
-spec:
-  rules:
-    - name: "e2e no ns rule"
-      extendedResources:
-        nons: "123"
-      matchFeatures:
-        - feature: "fake.attribute"
-          matchExpressions:
-            "attr_1": {op: IsTrue}
-            "attr_2": {op: IsFalse}
-
-    - name: "e2e Dynamic rule"
-      extendedResources:
-        vendor.io/dynamic: "@fake.attribute.attr_3"
-      matchFeatures:
-        - feature: "fake.attribute"
-          matchExpressions:
-            "attr_3": {op: Exists}
-
-    - name: "e2e static rule"
-      extendedResources:
-        vendor.io/static: "123"
-      matchFeatures:
-
-    - name: "e2e not allowed rule"
-      extendedResources:
-        bad.kubernetes.io/malo: "999"
-      matchFeatures:
diff --git a/test/e2e/node_feature_discovery_test.go b/test/e2e/node_feature_discovery_test.go
index 8138be344..b06302e0c 100644
--- a/test/e2e/node_feature_discovery_test.go
+++ b/test/e2e/node_feature_discovery_test.go
@@ -31,7 +31,6 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 	extclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
-	resourcev1 "k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	clientset "k8s.io/client-go/kubernetes"
 	taintutils "k8s.io/kubernetes/pkg/util/taints"
@@ -49,99 +48,90 @@ import (
 	testpod "sigs.k8s.io/node-feature-discovery/test/e2e/utils/pod"
 )
 
+var (
+	testTolerations = []corev1.Toleration{
+		{
+			Key:    "nfd.node.kubernetes.io/fake-special-node",
+			Value:  "exists",
+			Effect: "NoExecute",
+		},
+		{
+			Key:    "nfd.node.kubernetes.io/fake-dedicated-node",
+			Value:  "true",
+			Effect: "NoExecute",
+		},
+		{
+			Key:    "nfd.node.kubernetes.io/performance-optimized-node",
+			Value:  "true",
+			Effect: "NoExecute",
+		},
+		{
+			Key:    "nfd.node.kubernetes.io/foo",
+			Value:  "true",
+			Effect: "NoExecute",
+		},
+	}
+)
+
+const TestTaintNs = "nfd.node.kubernetes.io"
+
 // cleanupNode deletes all NFD-related metadata from the Node object, i.e.
 // labels and annotations
 func cleanupNode(cs clientset.Interface) {
-	// Per-node cleanup function
-	cleanup := func(nodeName string) error {
-		node, err := cs.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{})
-		Expect(err).NotTo(HaveOccurred())
-
-		update := false
-		updateStatus := false
-		// Gather info about all NFD-managed node assets outside the default prefix
-		nfdLabels := map[string]struct{}{}
-		for _, name := range strings.Split(node.Annotations[nfdv1alpha1.FeatureLabelsAnnotation], ",") {
-			if strings.Contains(name, "/") {
-				nfdLabels[name] = struct{}{}
-			}
-		}
-		nfdERs := map[string]struct{}{}
-		for _, name := range strings.Split(node.Annotations[nfdv1alpha1.ExtendedResourceAnnotation], ",") {
-			if strings.Contains(name, "/") {
-				nfdERs[name] = struct{}{}
-			}
-		}
-
-		// Remove labels
-		for key := range node.Labels {
-			_, ok := nfdLabels[key]
-			if ok || strings.HasPrefix(key, nfdv1alpha1.FeatureLabelNs) {
-				delete(node.Labels, key)
-				update = true
-			}
-		}
+	nodeList, err := cs.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
+	Expect(err).NotTo(HaveOccurred())
 
-		// Remove annotations
-		for key := range node.Annotations {
-			if strings.HasPrefix(key, nfdv1alpha1.AnnotationNs) {
-				delete(node.Annotations, key)
-				update = true
+	for _, n := range nodeList.Items {
+		var err error
+		var node *corev1.Node
+		for retry := 0; retry < 5; retry++ {
+			node, err = cs.CoreV1().Nodes().Get(context.TODO(), n.Name, metav1.GetOptions{})
+			Expect(err).NotTo(HaveOccurred())
+
+			update := false
+			// Remove labels
+			for key := range node.Labels {
+				if strings.HasPrefix(key, nfdv1alpha1.FeatureLabelNs) {
+					delete(node.Labels, key)
+					update = true
+				}
 			}
-		}
 
-		// Remove taints
-		for _, taint := range node.Spec.Taints {
-			if strings.HasPrefix(taint.Key, nfdv1alpha1.TaintNs) {
-				newTaints, removed := taintutils.DeleteTaint(node.Spec.Taints, &taint)
-				if removed {
-					node.Spec.Taints = newTaints
+			// Remove annotations
+			for key := range node.Annotations {
+				if strings.HasPrefix(key, nfdv1alpha1.AnnotationNs) {
+					delete(node.Annotations, key)
 					update = true
 				}
 			}
-		}
 
-		// Remove extended resources
-		for key := range node.Status.Capacity {
-			// We check for FeatureLabelNs as -resource-labels can create ERs there
-			_, ok := nfdERs[string(key)]
-			if ok || strings.HasPrefix(string(key), nfdv1alpha1.FeatureLabelNs) {
-				delete(node.Status.Capacity, key)
-				delete(node.Status.Allocatable, key)
-				updateStatus = true
+			// Remove taints
+			for _, taint := range node.Spec.Taints {
+				if strings.HasPrefix(taint.Key, TestTaintNs) {
+					newTaints, removed := taintutils.DeleteTaint(node.Spec.Taints, &taint)
+					if removed {
+						node.Spec.Taints = newTaints
+						update = true
+					}
+				}
 			}
-		}
 
-		if updateStatus {
-			By("Deleting NFD extended resources from node " + nodeName)
-			if _, err := cs.CoreV1().Nodes().UpdateStatus(context.TODO(), node, metav1.UpdateOptions{}); err != nil {
-				return err
+			if !update {
+				break
 			}
-		}
 
-		if update {
 			By("Deleting NFD labels, annotations and taints from node " + node.Name)
-			if _, err := cs.CoreV1().Nodes().Update(context.TODO(), node, metav1.UpdateOptions{}); err != nil {
-				return err
-			}
-		}
-		return nil
-	}
-
-	// Cleanup all nodes
-	nodeList, err := cs.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{})
-	Expect(err).NotTo(HaveOccurred())
-
-	for _, n := range nodeList.Items {
-		var err error
-		for retry := 0; retry < 5; retry++ {
-			if err = cleanup(n.Name); err == nil {
+			_, err = cs.CoreV1().Nodes().Update(context.TODO(), node, metav1.UpdateOptions{})
+			if err != nil {
+				time.Sleep(100 * time.Millisecond)
+			} else {
 				break
 			}
-			time.Sleep(100 * time.Millisecond)
+
 		}
 		Expect(err).NotTo(HaveOccurred())
 	}
+
 }
 
 func cleanupCRs(cli *nfdclient.Clientset, namespace string) {
@@ -179,10 +169,9 @@ var _ = SIGDescribe("NFD master and worker", func() {
 
 		Context("when deploying a single nfd-master pod", Ordered, func() {
 			var (
-				crds                   []*apiextensionsv1.CustomResourceDefinition
-				extClient              *extclient.Clientset
-				nfdClient              *nfdclient.Clientset
-				extraMasterPodSpecOpts []testpod.SpecOption
+				crds      []*apiextensionsv1.CustomResourceDefinition
+				extClient *extclient.Clientset
+				nfdClient *nfdclient.Clientset
 			)
 
 			checkNodeFeatureObject := func(name string) {
@@ -214,7 +203,7 @@ var _ = SIGDescribe("NFD master and worker", func() {
 				}
 			})
 
-			JustBeforeEach(func() {
+			BeforeEach(func() {
 				// Drop the pod security admission label as nfd-worker needs host mounts
 				if _, ok := f.Namespace.Labels[admissionapi.EnforceLevelLabel]; ok {
 					e2elog.Logf("Deleting %s label from the test namespace", admissionapi.EnforceLevelLabel)
@@ -227,16 +216,20 @@ var _ = SIGDescribe("NFD master and worker", func() {
 				Expect(err).NotTo(HaveOccurred())
 
 				// Remove pre-existing stale annotations and labels etc and CRDs
-				cleanupCRs(nfdClient, f.Namespace.Name)
 				cleanupNode(f.ClientSet)
+				cleanupCRs(nfdClient, f.Namespace.Name)
 
 				// Launch nfd-master
 				By("Creating nfd master pod and nfd-master service")
 				podSpecOpts := createPodSpecOpts(
-					append(extraMasterPodSpecOpts,
-						testpod.SpecWithContainerImage(dockerImage()),
-					)...)
-
+					testpod.SpecWithContainerImage(dockerImage()),
+					testpod.SpecWithTolerations(testTolerations),
+					testpod.SpecWithContainerExtraArgs("-enable-taints"),
+					testpod.SpecWithContainerExtraArgs(
+						"-deny-label-ns=*.denied.ns,random.unwanted.ns,*.vendor.io",
+						"-extra-label-ns=custom.vendor.io",
+					),
+				)
 				masterPod := e2epod.NewPodClient(f).CreateSync(testpod.NFDMaster(podSpecOpts...))
 
 				// Create nfd-master service
@@ -264,7 +257,6 @@ var _ = SIGDescribe("NFD master and worker", func() {
 
 				cleanupNode(f.ClientSet)
 				cleanupCRs(nfdClient, f.Namespace.Name)
-				extraMasterPodSpecOpts = nil
 			})
 
 			//
@@ -272,6 +264,7 @@ var _ = SIGDescribe("NFD master and worker", func() {
 			//
 			Context("and a single worker pod with fake source enabled", func() {
 				It("it should decorate the node with the fake feature labels", func() {
+
 					fakeFeatureLabels := map[string]string{
 						nfdv1alpha1.FeatureLabelNs + "/fake-fakefeature1": "true",
 						nfdv1alpha1.FeatureLabelNs + "/fake-fakefeature2": "true",
@@ -284,6 +277,7 @@ var _ = SIGDescribe("NFD master and worker", func() {
 						testpod.SpecWithRestartPolicy(corev1.RestartPolicyNever),
 						testpod.SpecWithContainerImage(dockerImage()),
 						testpod.SpecWithContainerExtraArgs("-oneshot", "-label-sources=fake"),
+						testpod.SpecWithTolerations(testTolerations),
 					)
 					workerPod := testpod.NFDWorker(podSpecOpts...)
 					workerPod, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).Create(context.TODO(), workerPod, metav1.CreateOptions{})
@@ -335,6 +329,7 @@ var _ = SIGDescribe("NFD master and worker", func() {
 					By("Creating nfd-worker daemonset")
 					podSpecOpts := createPodSpecOpts(
 						testpod.SpecWithContainerImage(dockerImage()),
+						testpod.SpecWithTolerations(testTolerations),
 					)
 					workerDS := testds.NFDWorker(podSpecOpts...)
 					workerDS, err = f.ClientSet.AppsV1().DaemonSets(f.Namespace.Name).Create(context.TODO(), workerDS, metav1.CreateOptions{})
@@ -466,6 +461,7 @@ var _ = SIGDescribe("NFD master and worker", func() {
 						testpod.SpecWithContainerImage(dockerImage()),
 						testpod.SpecWithConfigMap(cm1.Name, filepath.Join(custom.Directory, "cm1")),
 						testpod.SpecWithConfigMap(cm2.Name, filepath.Join(custom.Directory, "cm2")),
+						testpod.SpecWithTolerations(testTolerations),
 					)
 					workerDS := testds.NFDWorker(podSpecOpts...)
 
@@ -512,14 +508,6 @@ var _ = SIGDescribe("NFD master and worker", func() {
 			// Test NodeFeature
 			//
 			Context("and NodeFeature objects deployed", func() {
-				BeforeEach(func() {
-					extraMasterPodSpecOpts = []testpod.SpecOption{
-						testpod.SpecWithContainerExtraArgs(
-							"-deny-label-ns=*.denied.ns,random.unwanted.ns,*.vendor.io",
-							"-extra-label-ns=custom.vendor.io",
-						),
-					}
-				})
 				It("labels from the NodeFeature objects should be created", func() {
 					if !useNodeFeatureApi {
 						Skip("NodeFeature API not enabled")
@@ -668,34 +656,6 @@ var _ = SIGDescribe("NFD master and worker", func() {
 			// Test NodeFeatureRule
 			//
 			Context("and nfd-worker and NodeFeatureRules objects deployed", func() {
-				testTolerations := []corev1.Toleration{
-					{
-						Key:    "feature.node.kubernetes.io/fake-special-node",
-						Value:  "exists",
-						Effect: "NoExecute",
-					},
-					{
-						Key:    "feature.node.kubernetes.io/fake-dedicated-node",
-						Value:  "true",
-						Effect: "NoExecute",
-					},
-					{
-						Key:    "feature.node.kubernetes.io/performance-optimized-node",
-						Value:  "true",
-						Effect: "NoExecute",
-					},
-					{
-						Key:    "feature.node.kubernetes.io/foo",
-						Value:  "true",
-						Effect: "NoExecute",
-					},
-				}
-				BeforeEach(func() {
-					extraMasterPodSpecOpts = []testpod.SpecOption{
-						testpod.SpecWithContainerExtraArgs("-enable-taints"),
-						testpod.SpecWithTolerations(testTolerations),
-					}
-				})
 				It("custom labels from the NodeFeatureRule rules should be created", func() {
 					nodes, err := getNonControlPlaneNodes(f.ClientSet)
 					Expect(err).NotTo(HaveOccurred())
@@ -765,150 +725,52 @@ core:
 					By("Verifying node taints and annotation from NodeFeatureRules #3")
 					expectedTaints := []corev1.Taint{
 						{
-							Key:    "feature.node.kubernetes.io/fake-special-node",
+							Key:    "nfd.node.kubernetes.io/fake-special-node",
 							Value:  "exists",
 							Effect: "PreferNoSchedule",
 						},
 						{
-							Key:    "feature.node.kubernetes.io/fake-dedicated-node",
+							Key:    "nfd.node.kubernetes.io/fake-dedicated-node",
 							Value:  "true",
 							Effect: "NoExecute",
 						},
 						{
-							Key:    "feature.node.kubernetes.io/performance-optimized-node",
+							Key:    "nfd.node.kubernetes.io/performance-optimized-node",
 							Value:  "true",
 							Effect: "NoExecute",
 						},
 					}
 					expectedAnnotation := map[string]string{
-						"nfd.node.kubernetes.io/taints": "feature.node.kubernetes.io/fake-special-node=exists:PreferNoSchedule,feature.node.kubernetes.io/fake-dedicated-node=true:NoExecute,feature.node.kubernetes.io/performance-optimized-node=true:NoExecute"}
-					Expect(waitForNfdNodeTaints(f.ClientSet, expectedTaints, nodes)).NotTo(HaveOccurred())
+						"nfd.node.kubernetes.io/taints": "nfd.node.kubernetes.io/fake-special-node=exists:PreferNoSchedule,nfd.node.kubernetes.io/fake-dedicated-node=true:NoExecute,nfd.node.kubernetes.io/performance-optimized-node=true:NoExecute"}
+					Expect(waitForNfdNodeTaints(f.ClientSet, expectedTaints)).NotTo(HaveOccurred())
 					Expect(waitForNfdNodeAnnotations(f.ClientSet, expectedAnnotation)).NotTo(HaveOccurred())
 
 					By("Re-applying NodeFeatureRules #3 with updated taints")
 					Expect(testutils.UpdateNodeFeatureRulesFromFile(nfdClient, "nodefeaturerule-3-updated.yaml")).NotTo(HaveOccurred())
 					expectedTaintsUpdated := []corev1.Taint{
 						{
-							Key:    "feature.node.kubernetes.io/fake-special-node",
+							Key:    "nfd.node.kubernetes.io/fake-special-node",
 							Value:  "exists",
 							Effect: "PreferNoSchedule",
 						},
 						{
-							Key:    "feature.node.kubernetes.io/foo",
+							Key:    "nfd.node.kubernetes.io/foo",
 							Value:  "true",
 							Effect: "NoExecute",
 						},
 					}
 					expectedAnnotationUpdated := map[string]string{
-						"nfd.node.kubernetes.io/taints": "feature.node.kubernetes.io/fake-special-node=exists:PreferNoSchedule,feature.node.kubernetes.io/foo=true:NoExecute"}
+						"nfd.node.kubernetes.io/taints": "nfd.node.kubernetes.io/fake-special-node=exists:PreferNoSchedule,nfd.node.kubernetes.io/foo=true:NoExecute"}
 
 					By("Verifying updated node taints and annotation from NodeFeatureRules #3")
-					Expect(waitForNfdNodeTaints(f.ClientSet, expectedTaintsUpdated, nodes)).NotTo(HaveOccurred())
+					Expect(waitForNfdNodeTaints(f.ClientSet, expectedTaintsUpdated)).NotTo(HaveOccurred())
 					Expect(waitForNfdNodeAnnotations(f.ClientSet, expectedAnnotationUpdated)).NotTo(HaveOccurred())
 
-					By("Deleting NodeFeatureRule object")
-					err = nfdClient.NfdV1alpha1().NodeFeatureRules().Delete(context.TODO(), "e2e-test-3", metav1.DeleteOptions{})
-					Expect(err).NotTo(HaveOccurred())
-
-					expectedERAnnotation := map[string]string{
-						"nfd.node.kubernetes.io/extended-resources": "nons,vendor.io/dynamic,vendor.io/static"}
-
-					expectedCapacity := corev1.ResourceList{
-						"feature.node.kubernetes.io/nons": resourcev1.MustParse("123"),
-						"vendor.io/dynamic":               resourcev1.MustParse("10"),
-						"vendor.io/static":                resourcev1.MustParse("123"),
-					}
-
-					By("Creating NodeFeatureRules #4")
-					Expect(testutils.CreateNodeFeatureRulesFromFile(nfdClient, "nodefeaturerule-4.yaml")).NotTo(HaveOccurred())
-
-					By("Verifying node annotations from NodeFeatureRules #4")
-					Expect(waitForNfdNodeAnnotations(f.ClientSet, expectedERAnnotation)).NotTo(HaveOccurred())
-
-					By("Verfiying node status capacity from NodeFeatureRules #4")
-					Expect(waitForCapacity(f.ClientSet, expectedCapacity, nodes)).NotTo(HaveOccurred())
-
-					By("Deleting NodeFeatureRule object")
-					err = nfdClient.NfdV1alpha1().NodeFeatureRules().Delete(context.TODO(), "e2e-extened-resource-test", metav1.DeleteOptions{})
-					Expect(err).NotTo(HaveOccurred())
-
-					By("Verfiying node status capacity from NodeFeatureRules #4")
-					Expect(waitForCapacity(f.ClientSet, nil, nodes)).NotTo(HaveOccurred())
-
 					By("Deleting nfd-worker daemonset")
 					err = f.ClientSet.AppsV1().DaemonSets(f.Namespace.Name).Delete(context.TODO(), workerDS.Name, metav1.DeleteOptions{})
 					Expect(err).NotTo(HaveOccurred())
 				})
 			})
-
-			Context("and check whether master config passed successfully or not", func() {
-				BeforeEach(func() {
-					extraMasterPodSpecOpts = []testpod.SpecOption{
-						testpod.SpecWithConfigMap("nfd-master-conf", "/etc/kubernetes/node-feature-discovery"),
-					}
-					cm := testutils.NewConfigMap("nfd-master-conf", "nfd-master.conf", `
-denyLabelNs: ["*.denied.ns","random.unwanted.ns"]
-`)
-					_, err := f.ClientSet.CoreV1().ConfigMaps(f.Namespace.Name).Create(context.TODO(), cm, metav1.CreateOptions{})
-					Expect(err).NotTo(HaveOccurred())
-				})
-				It("master configuration should take place", func() {
-					// deploy node feature object
-					if !useNodeFeatureApi {
-						Skip("NodeFeature API not enabled")
-					}
-
-					nodes, err := getNonControlPlaneNodes(f.ClientSet)
-					Expect(err).NotTo(HaveOccurred())
-
-					targetNodeName := nodes[0].Name
-					Expect(targetNodeName).ToNot(BeEmpty(), "No suitable worker node found")
-
-					// Apply Node Feature object
-					By("Create NodeFeature object")
-					nodeFeatures, err := testutils.CreateOrUpdateNodeFeaturesFromFile(nfdClient, "nodefeature-3.yaml", f.Namespace.Name, targetNodeName)
-					Expect(err).NotTo(HaveOccurred())
-
-					// Verify that denied label was not added
-					By("Verifying that denied labels were not added")
-					expectedLabels := map[string]k8sLabels{
-						targetNodeName: {
-							nfdv1alpha1.FeatureLabelNs + "/e2e-nodefeature-test-4": "obj-4",
-							"custom.vendor.io/e2e-nodefeature-test-3":              "vendor-ns",
-						},
-					}
-					Expect(checkForNodeLabels(
-						f.ClientSet,
-						expectedLabels,
-						nodes,
-					)).NotTo(HaveOccurred())
-					By("Deleting NodeFeature object")
-					err = nfdClient.NfdV1alpha1().NodeFeatures(f.Namespace.Name).Delete(context.TODO(), nodeFeatures[0], metav1.DeleteOptions{})
-					Expect(err).NotTo(HaveOccurred())
-
-					// TODO: Find a better way to handle the timeout that happens to reflect the configmap changes
-					Skip("Testing the master dynamic configuration")
-					// Verify that config changes were applied
-					By("Updating the master config")
-					Expect(testutils.UpdateConfigMap(f.ClientSet, "nfd-master-conf", f.Namespace.Name, "nfd-master.conf", `
-denyLabelNs: []
-`))
-					By("Verifying that denied labels were removed")
-					expectedLabels = map[string]k8sLabels{
-						targetNodeName: {
-							nfdv1alpha1.FeatureLabelNs + "/e2e-nodefeature-test-4": "obj-4",
-							"custom.vendor.io/e2e-nodefeature-test-3":              "vendor-ns",
-							"random.denied.ns/e2e-nodefeature-test-1":              "denied-ns",
-							"random.unwanted.ns/e2e-nodefeature-test-2":            "unwanted-ns",
-						},
-					}
-					Expect(checkForNodeLabels(
-						f.ClientSet,
-						expectedLabels,
-						nodes,
-					)).NotTo(HaveOccurred())
-				})
-			})
 		})
 	}
 
@@ -923,42 +785,6 @@ denyLabelNs: []
 
 })
 
-// simplePoll is a simple and stupid re-try loop
-func simplePoll(poll func() error, wait time.Duration) error {
-	var err error
-	for retry := 0; retry < 3; retry++ {
-		if err = poll(); err == nil {
-			return nil
-		}
-		time.Sleep(wait * time.Second)
-	}
-	return err
-}
-
-// waitForCapacity waits for the capacity to be updated in the node status
-func waitForCapacity(cli clientset.Interface, expectedNewERs corev1.ResourceList, oldNodes []corev1.Node) error {
-	poll := func() error {
-		nodes, err := getNonControlPlaneNodes(cli)
-		if err != nil {
-			return err
-		}
-		for _, node := range nodes {
-			oldNode := getNode(oldNodes, node.Name)
-			expected := oldNode.Status.DeepCopy().Capacity
-			for k, v := range expectedNewERs {
-				expected[k] = v
-			}
-			capacity := node.Status.Capacity
-			if !cmp.Equal(expected, capacity) {
-				return fmt.Errorf("node %q capacity does not match expected, diff (expected vs. received): %s", node.Name, cmp.Diff(expected, capacity))
-			}
-		}
-		return nil
-	}
-
-	return simplePoll(poll, 10)
-}
-
 // waitForNfdNodeAnnotations waits for node to be annotated as expected.
 func waitForNfdNodeAnnotations(cli clientset.Interface, expected map[string]string) error {
 	poll := func() error {
@@ -976,7 +802,15 @@ func waitForNfdNodeAnnotations(cli clientset.Interface, expected map[string]stri
 		return nil
 	}
 
-	return simplePoll(poll, 2)
+	// Simple and stupid re-try loop
+	var err error
+	for retry := 0; retry < 3; retry++ {
+		if err = poll(); err == nil {
+			return nil
+		}
+		time.Sleep(2 * time.Second)
+	}
+	return err
 }
 
 type k8sLabels map[string]string
@@ -998,7 +832,7 @@ func checkForNodeLabels(cli clientset.Interface, expectedNewLabels map[string]k8
 				}
 			}
 
-			oldLabels := getNode(oldNodes, node.Name).Labels
+			oldLabels := getNodeLabels(oldNodes, node.Name)
 			expectedNewLabels := maps.Clone(oldLabels)
 			maps.Copy(expectedNewLabels, nodeExpected)
 
@@ -1009,21 +843,29 @@ func checkForNodeLabels(cli clientset.Interface, expectedNewLabels map[string]k8
 		return nil
 	}
 
-	return simplePoll(poll, 3)
+	// Simple and stupid re-try loop
+	var err error
+	for retry := 0; retry < 3; retry++ {
+		if err = poll(); err == nil {
+			return nil
+		}
+		time.Sleep(2 * time.Second)
+	}
+	return err
 }
 
 // waitForNfdNodeTaints waits for node to be tainted as expected.
-func waitForNfdNodeTaints(cli clientset.Interface, expectedNewTaints []corev1.Taint, oldNodes []corev1.Node) error {
+func waitForNfdNodeTaints(cli clientset.Interface, expected []corev1.Taint) error {
 	poll := func() error {
 		nodes, err := getNonControlPlaneNodes(cli)
 		if err != nil {
 			return err
 		}
 		for _, node := range nodes {
-			oldNode := getNode(oldNodes, node.Name)
-			expected := oldNode.Spec.DeepCopy().Taints
-			expected = append(expected, expectedNewTaints...)
-			taints := node.Spec.Taints
+			taints := nfdTaints(node.Spec.Taints)
+			if err != nil {
+				return fmt.Errorf("failed to fetch nfd owned taints for node: %s", node.Name)
+			}
 			if !cmp.Equal(expected, taints) {
 				return fmt.Errorf("node %q taints do not match expected, diff (expected vs. received): %s", node.Name, cmp.Diff(expected, taints))
 			}
@@ -1031,7 +873,27 @@ func waitForNfdNodeTaints(cli clientset.Interface, expectedNewTaints []corev1.Ta
 		return nil
 	}
 
-	return simplePoll(poll, 10)
+	// Simple and stupid re-try loop
+	var err error
+	for retry := 0; retry < 3; retry++ {
+		if err = poll(); err == nil {
+			return nil
+		}
+		time.Sleep(10 * time.Second)
+	}
+	return err
+}
+
+// nfdTaints returns taints that are owned by the nfd.
+func nfdTaints(taints []corev1.Taint) []corev1.Taint {
+	nfdTaints := []corev1.Taint{}
+	for _, taint := range taints {
+		if strings.HasPrefix(taint.Key, TestTaintNs) {
+			nfdTaints = append(nfdTaints, taint)
+		}
+	}
+
+	return nfdTaints
 }
 
 // getNonControlPlaneNodes gets the nodes that are not tainted for exclusive control-plane usage
@@ -1061,11 +923,11 @@ func getNonControlPlaneNodes(cli clientset.Interface) ([]corev1.Node, error) {
 	return out, nil
 }
 
-func getNode(nodes []corev1.Node, nodeName string) corev1.Node {
+func getNodeLabels(nodes []corev1.Node, nodeName string) map[string]string {
 	for _, node := range nodes {
 		if node.Name == nodeName {
-			return node
+			return node.Labels
 		}
 	}
-	return corev1.Node{}
+	return nil
 }
diff --git a/test/e2e/utils/configmap.go b/test/e2e/utils/configmap.go
index 90885b798..192d11023 100644
--- a/test/e2e/utils/configmap.go
+++ b/test/e2e/utils/configmap.go
@@ -17,12 +17,8 @@ limitations under the License.
 package utils
 
 import (
-	"context"
-	"fmt"
-
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	clientset "k8s.io/client-go/kubernetes"
 )
 
 // CreateConfigMap is a helper for creating a simple ConfigMap object with one key.
@@ -34,17 +30,3 @@ func NewConfigMap(name, key, data string) *corev1.ConfigMap {
 		Data: map[string]string{key: data},
 	}
 }
-
-// UpdateConfigMap is a helper for updating a ConfigMap object.
-func UpdateConfigMap(c clientset.Interface, name, namespace, key, data string) error {
-	cm, err := c.CoreV1().ConfigMaps(namespace).Get(context.TODO(), name, metav1.GetOptions{})
-	if err != nil {
-		return fmt.Errorf("configmap %s is not found", name)
-	}
-	cm.Data[key] = data
-	_, err = c.CoreV1().ConfigMaps(namespace).Update(context.TODO(), cm, metav1.UpdateOptions{})
-	if err != nil {
-		return fmt.Errorf("error while updating configmap with name %s", name)
-	}
-	return nil
-}
diff --git a/test/e2e/utils/crd.go b/test/e2e/utils/crd.go
index 0d57659e7..6546f312a 100644
--- a/test/e2e/utils/crd.go
+++ b/test/e2e/utils/crd.go
@@ -23,14 +23,12 @@ import (
 	"os"
 	"path/filepath"
 	"runtime"
-	"time"
 
 	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 	extclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
 	"k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	apiruntime "k8s.io/apimachinery/pkg/runtime"
-	"k8s.io/apimachinery/pkg/util/wait"
 	"k8s.io/client-go/kubernetes/scheme"
 	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
 	nfdclientset "sigs.k8s.io/node-feature-discovery/pkg/generated/clientset/versioned"
@@ -51,23 +49,8 @@ func CreateNfdCRDs(cli extclient.Interface) ([]*apiextensionsv1.CustomResourceDe
 		// Delete existing CRD (if any) with this we also get rid of stale objects
 		err = cli.ApiextensionsV1().CustomResourceDefinitions().Delete(context.TODO(), crd.Name, metav1.DeleteOptions{})
 		if err != nil && !errors.IsNotFound(err) {
-			return nil, fmt.Errorf("failed to delete %q CRD: %w", crd.Name, err)
-		} else if err == nil {
-			// Wait for CRD deletion to complete before trying to re-create it
-			err = wait.Poll(1*time.Second, 1*time.Minute, func() (bool, error) {
-				_, err = cli.ApiextensionsV1().CustomResourceDefinitions().Get(context.TODO(), crd.Name, metav1.GetOptions{})
-				if err == nil {
-					return false, nil
-				} else if errors.IsNotFound(err) {
-					return true, nil
-				}
-				return false, err
-			})
-			if err != nil {
-				return nil, fmt.Errorf("timed out waiting for %q CRD to be deleted: %w", crd.Name, err)
-			}
+			return nil, fmt.Errorf("failed to delete NodeFeatureRule CRD: %w", err)
 		}
-
 		newCRDs[i], err = cli.ApiextensionsV1().CustomResourceDefinitions().Create(context.TODO(), crd, metav1.CreateOptions{})
 		if err != nil {
 			return nil, err
diff --git a/test/e2e/utils/rbac.go b/test/e2e/utils/rbac.go
index 3ec0180dd..e71db751e 100644
--- a/test/e2e/utils/rbac.go
+++ b/test/e2e/utils/rbac.go
@@ -141,7 +141,7 @@ func createClusterRoleMaster(cs clientset.Interface) (*rbacv1.ClusterRole, error
 		Rules: []rbacv1.PolicyRule{
 			{
 				APIGroups: []string{""},
-				Resources: []string{"nodes", "nodes/status"},
+				Resources: []string{"nodes"},
 				Verbs:     []string{"get", "list", "patch", "update"},
 			},
 			{