Repository: kubernetes-sigs/node-feature-discovery
Pull request #930 (2022-10-21 08:15:14)

Bump Kubernetes to v1.25.3

k8s-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubernetes-sigs/node-feature-discovery/pull/930#" title="Author self-approved">fmuyassarov</a>*
**Once this PR has been reviewed and has the lgtm label**, please assign marquiz for approval by writing `/assign @marquiz` in a comment. For more information see [the Kubernetes Code Review Process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process).

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubernetes-sigs%2Fnode-feature-discovery).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/kubernetes-sigs/node-feature-discovery/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["marquiz"]} -->
netlify[bot]: ### <span aria-hidden="true">👷</span> Deploy Preview for *kubernetes-sigs-nfd* processing.


|  Name | Link |
|---------------------------------|------------------------|
|<span aria-hidden="true">🔨</span> Latest commit | 3017267efbdc5ecd7c581fe668f124d31d3e47bd |
|<span aria-hidden="true">🔍</span> Latest deploy log | https://app.netlify.com/sites/kubernetes-sigs-nfd/deploys/63525514039f9d0008041c14 |
marquiz: Thanks @fmuyassarov. I'd suggest to bump all k8s packages, too, and possible other deps as well. To keep everything in sync
fmuyassarov: > Thanks @fmuyassarov. I'd suggest to bump all k8s packages, too, and possible other deps as well. To keep everything in sync

done
marquiz: Sorry, a small nit on the commit message: I'd change it to smth like `Bump Kubernetes to v1.25.3` as k8s is the "main dependency" of ours with which we kind of try to sync other deps with. Ginkgo and gomega (and others) could be mentioned in the commit msg body. WDYT?

Patch:
diff --git a/go.mod b/go.mod
index 34c7b315f..074e4dae8 100644
--- a/go.mod
+++ b/go.mod
@@ -11,23 +11,23 @@ require (
 	github.com/jaypipes/ghw v0.8.1-0.20210827132705-c7224150a17e
 	github.com/k8stopologyawareschedwg/noderesourcetopology-api v0.0.12
 	github.com/klauspost/cpuid/v2 v2.1.0
-	github.com/onsi/ginkgo/v2 v2.1.4
-	github.com/onsi/gomega v1.19.0
+	github.com/onsi/ginkgo/v2 v2.3.1
+	github.com/onsi/gomega v1.22.1
 	github.com/smartystreets/assertions v1.2.0
 	github.com/smartystreets/goconvey v1.6.4
-	github.com/stretchr/testify v1.7.0
+	github.com/stretchr/testify v1.8.0
 	github.com/vektra/errors v0.0.0-20140903201135-c64d83aba85a
 	golang.org/x/net v0.0.0-20220722155237-a158d28d115b
 	google.golang.org/grpc v1.47.0
 	google.golang.org/protobuf v1.28.0
-	k8s.io/api v0.25.0
-	k8s.io/apiextensions-apiserver v0.25.0
-	k8s.io/apimachinery v0.25.0
-	k8s.io/client-go v0.25.0
+	k8s.io/api v0.25.3
+	k8s.io/apiextensions-apiserver v0.25.3
+	k8s.io/apimachinery v0.25.3
+	k8s.io/client-go v0.25.3
 	k8s.io/klog/v2 v2.70.1
-	k8s.io/kubectl v0.25.0
-	k8s.io/kubelet v0.25.0
-	k8s.io/kubernetes v1.25.0
+	k8s.io/kubectl v0.25.3
+	k8s.io/kubelet v0.25.3
+	k8s.io/kubernetes v1.25.3
 	k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed
 	sigs.k8s.io/yaml v1.2.0
 )
@@ -136,7 +136,7 @@ require (
 	github.com/sirupsen/logrus v1.8.1 // indirect
 	github.com/spf13/cobra v1.4.0 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
-	github.com/stretchr/objx v0.2.0 // indirect
+	github.com/stretchr/objx v0.4.0 // indirect
 	github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
 	github.com/vishvananda/netlink v1.1.0 // indirect
 	github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae // indirect
@@ -189,7 +189,7 @@ require (
 	k8s.io/legacy-cloud-providers v0.0.0 // indirect
 	k8s.io/mount-utils v0.25.0 // indirect
 	k8s.io/pod-security-admission v0.0.0 // indirect
-	sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32 // indirect
+	sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.33 // indirect
 	sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
 	sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
 )
diff --git a/go.sum b/go.sum
index cd1d1afd1..84056b467 100644
--- a/go.sum
+++ b/go.sum
@@ -311,7 +311,7 @@ github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
 github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
 github.com/google/cadvisor v0.45.0 h1:bXQze1sd8srZiQwiQ19Qaq/AoMIZS8YceBXrIaEvkX0=
 github.com/google/cadvisor v0.45.0/go.mod h1:vsMT3Uv2XjQ8M7WUtKARV74mU/HN64C4XtM1bJhUKcU=
-github.com/google/cel-go v0.12.4 h1:YINKfuHZ8n72tPOqSPZBwGiDpew2CJS48mdM5W8LZQU=
+github.com/google/cel-go v0.12.5 h1:DmzaiSgoaqGCjtpPQWl26/gND+yRpim56H1jCVev6d8=
 github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
 github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -499,13 +499,15 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
 github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
 github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
-github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY=
 github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU=
+github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8=
+github.com/onsi/ginkgo/v2 v2.3.1/go.mod h1:Sv4yQXwG5VmF7tm3Q5Z+RWUpPo24LF1mpnz2crUb8Ys=
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
-github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
 github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
+github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI=
+github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
 github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
 github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
@@ -600,15 +602,17 @@ github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ai
 github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
-github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -689,8 +693,8 @@ go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee33
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
 go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
+go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
 go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
@@ -732,7 +736,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu
 golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
 golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
 golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
@@ -986,7 +989,6 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
-golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1224,8 +1226,8 @@ k8s.io/kubectl v0.25.0 h1:/Wn1cFqo8ik3iee1EvpxYre3bkWsGLXzLQI6uCCAkQc=
 k8s.io/kubectl v0.25.0/go.mod h1:n16ULWsOl2jmQpzt2o7Dud1t4o0+Y186ICb4O+GwKAU=
 k8s.io/kubelet v0.25.0 h1:eTS5B1u1o63ndExAHKLJytzz/GBy86ROcxYtu0VK3RA=
 k8s.io/kubelet v0.25.0/go.mod h1:J6aQxrZdSsGPrskYrhZdEn6PCnGha+GNvF0g9aWfQnw=
-k8s.io/kubernetes v1.25.0 h1:NwTRyLrdXTORd5V7DLlUltxDbl/KZjYDiRgwI+pBYGE=
-k8s.io/kubernetes v1.25.0/go.mod h1:UdtILd5Zg1vGZvShiO1EYOqmjzM2kZOG1hzwQnM5JxY=
+k8s.io/kubernetes v1.25.3 h1:Ljx/Ew9+dt7rN9ob3V+N/aoDy7nDSbmr35IbYGRTyqE=
+k8s.io/kubernetes v1.25.3/go.mod h1:lvEY+3iJhh+sGIK1LorGkI56rW0eLGsfalnp68wQwYU=
 k8s.io/legacy-cloud-providers v0.25.0 h1:c+boKaCw/2ZzvA8/XgTIeDrGUJJ2Ucy+jLJFf02+huE=
 k8s.io/legacy-cloud-providers v0.25.0/go.mod h1:bnmUgHHeBmK3M9JgQzu+ne6UCUVURDzkpF0Y7VeypVE=
 k8s.io/metrics v0.25.0 h1:z/tyqXUCxvmFsKIO7GH6ulvogYvGp+pDmlz5ANSQVPE=
@@ -1241,8 +1243,8 @@ k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
 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.32 h1:2WjukG7txtEsbXsSKWtTibCdsyYAhcu6KFnttyDdZOQ=
-sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.32/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw=
+sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.33 h1:LYqFq+6Cj2D0gFfrJvL7iElD4ET6ir3VDdhDdTK7rgc=
+sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.33/go.mod h1:soWkSNf2tZC7aMibXEqVhCd73GOY5fJikn8qbdzemB0=
 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/feature.go b/pkg/api/feature/feature.go
similarity index 99%
rename from pkg/apis/nfd/v1alpha1/feature.go
rename to pkg/api/feature/feature.go
index b54117cfe..bd23af277 100644
--- a/pkg/apis/nfd/v1alpha1/feature.go
+++ b/pkg/api/feature/feature.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package v1alpha1
+package feature
 
 // NewDomainFeatures creates a new instance of Features, initializing specified
 // features to empty values
diff --git a/pkg/api/feature/generate.sh b/pkg/api/feature/generate.sh
new file mode 100755
index 000000000..a9785cafe
--- /dev/null
+++ b/pkg/api/feature/generate.sh
@@ -0,0 +1,16 @@
+#!/bin/sh -ex
+
+# go-to-protobuf seems unable to run in the package directory -> move to parent dir
+cd ..
+go-to-protobuf \
+   --output-base=. \
+   --go-header-file ../../hack/boilerplate.go.txt \
+   --proto-import ../../vendor \
+   --packages ./feature=feature \
+   --keep-gogoproto=false \
+   --apimachinery-packages "-k8s.io/apimachinery/pkg/util/intstr"
+cd -
+
+# Mangle the go_package option to comply with newer versions protoc-gen-go
+sed s',go_package =.*,go_package = "sigs.k8s.io/node-feature-discovery/pkg/api/feature";,' \
+    -i generated.proto
diff --git a/pkg/apis/nfd/v1alpha1/generated.pb.go b/pkg/api/feature/generated.pb.go
similarity index 90%
rename from pkg/apis/nfd/v1alpha1/generated.pb.go
rename to pkg/api/feature/generated.pb.go
index f9f41ac6a..642c1b4c2 100644
--- a/pkg/apis/nfd/v1alpha1/generated.pb.go
+++ b/pkg/api/feature/generated.pb.go
@@ -15,9 +15,9 @@ limitations under the License.
 */
 
 // Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1/generated.proto
+// source: feature/generated.proto
 
-package v1alpha1
+package feature
 
 import (
 	fmt "fmt"
@@ -46,7 +46,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 func (m *AttributeFeatureSet) Reset()      { *m = AttributeFeatureSet{} }
 func (*AttributeFeatureSet) ProtoMessage() {}
 func (*AttributeFeatureSet) Descriptor() ([]byte, []int) {
-	return fileDescriptor_6f67d44e41cfe439, []int{0}
+	return fileDescriptor_870e6eafce4d2482, []int{0}
 }
 func (m *AttributeFeatureSet) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -74,7 +74,7 @@ var xxx_messageInfo_AttributeFeatureSet proto.InternalMessageInfo
 func (m *DomainFeatures) Reset()      { *m = DomainFeatures{} }
 func (*DomainFeatures) ProtoMessage() {}
 func (*DomainFeatures) Descriptor() ([]byte, []int) {
-	return fileDescriptor_6f67d44e41cfe439, []int{1}
+	return fileDescriptor_870e6eafce4d2482, []int{1}
 }
 func (m *DomainFeatures) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -102,7 +102,7 @@ var xxx_messageInfo_DomainFeatures proto.InternalMessageInfo
 func (m *FlagFeatureSet) Reset()      { *m = FlagFeatureSet{} }
 func (*FlagFeatureSet) ProtoMessage() {}
 func (*FlagFeatureSet) Descriptor() ([]byte, []int) {
-	return fileDescriptor_6f67d44e41cfe439, []int{2}
+	return fileDescriptor_870e6eafce4d2482, []int{2}
 }
 func (m *FlagFeatureSet) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -130,7 +130,7 @@ var xxx_messageInfo_FlagFeatureSet proto.InternalMessageInfo
 func (m *InstanceFeature) Reset()      { *m = InstanceFeature{} }
 func (*InstanceFeature) ProtoMessage() {}
 func (*InstanceFeature) Descriptor() ([]byte, []int) {
-	return fileDescriptor_6f67d44e41cfe439, []int{3}
+	return fileDescriptor_870e6eafce4d2482, []int{3}
 }
 func (m *InstanceFeature) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -158,7 +158,7 @@ var xxx_messageInfo_InstanceFeature proto.InternalMessageInfo
 func (m *InstanceFeatureSet) Reset()      { *m = InstanceFeatureSet{} }
 func (*InstanceFeatureSet) ProtoMessage() {}
 func (*InstanceFeatureSet) Descriptor() ([]byte, []int) {
-	return fileDescriptor_6f67d44e41cfe439, []int{4}
+	return fileDescriptor_870e6eafce4d2482, []int{4}
 }
 func (m *InstanceFeatureSet) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -186,7 +186,7 @@ var xxx_messageInfo_InstanceFeatureSet proto.InternalMessageInfo
 func (m *Nil) Reset()      { *m = Nil{} }
 func (*Nil) ProtoMessage() {}
 func (*Nil) Descriptor() ([]byte, []int) {
-	return fileDescriptor_6f67d44e41cfe439, []int{5}
+	return fileDescriptor_870e6eafce4d2482, []int{5}
 }
 func (m *Nil) XXX_Unmarshal(b []byte) error {
 	return m.Unmarshal(b)
@@ -212,61 +212,56 @@ func (m *Nil) XXX_DiscardUnknown() {
 var xxx_messageInfo_Nil proto.InternalMessageInfo
 
 func init() {
-	proto.RegisterType((*AttributeFeatureSet)(nil), "v1alpha1.AttributeFeatureSet")
-	proto.RegisterMapType((map[string]string)(nil), "v1alpha1.AttributeFeatureSet.ElementsEntry")
-	proto.RegisterType((*DomainFeatures)(nil), "v1alpha1.DomainFeatures")
-	proto.RegisterMapType((map[string]FlagFeatureSet)(nil), "v1alpha1.DomainFeatures.FlagsEntry")
-	proto.RegisterMapType((map[string]InstanceFeatureSet)(nil), "v1alpha1.DomainFeatures.InstancesEntry")
-	proto.RegisterMapType((map[string]AttributeFeatureSet)(nil), "v1alpha1.DomainFeatures.VattributesEntry")
-	proto.RegisterType((*FlagFeatureSet)(nil), "v1alpha1.FlagFeatureSet")
-	proto.RegisterMapType((map[string]Nil)(nil), "v1alpha1.FlagFeatureSet.ElementsEntry")
-	proto.RegisterType((*InstanceFeature)(nil), "v1alpha1.InstanceFeature")
-	proto.RegisterMapType((map[string]string)(nil), "v1alpha1.InstanceFeature.AttributesEntry")
-	proto.RegisterType((*InstanceFeatureSet)(nil), "v1alpha1.InstanceFeatureSet")
-	proto.RegisterType((*Nil)(nil), "v1alpha1.Nil")
+	proto.RegisterType((*AttributeFeatureSet)(nil), "feature.AttributeFeatureSet")
+	proto.RegisterMapType((map[string]string)(nil), "feature.AttributeFeatureSet.ElementsEntry")
+	proto.RegisterType((*DomainFeatures)(nil), "feature.DomainFeatures")
+	proto.RegisterMapType((map[string]FlagFeatureSet)(nil), "feature.DomainFeatures.FlagsEntry")
+	proto.RegisterMapType((map[string]InstanceFeatureSet)(nil), "feature.DomainFeatures.InstancesEntry")
+	proto.RegisterMapType((map[string]AttributeFeatureSet)(nil), "feature.DomainFeatures.VattributesEntry")
+	proto.RegisterType((*FlagFeatureSet)(nil), "feature.FlagFeatureSet")
+	proto.RegisterMapType((map[string]Nil)(nil), "feature.FlagFeatureSet.ElementsEntry")
+	proto.RegisterType((*InstanceFeature)(nil), "feature.InstanceFeature")
+	proto.RegisterMapType((map[string]string)(nil), "feature.InstanceFeature.AttributesEntry")
+	proto.RegisterType((*InstanceFeatureSet)(nil), "feature.InstanceFeatureSet")
+	proto.RegisterType((*Nil)(nil), "feature.Nil")
 }
 
-func init() {
-	proto.RegisterFile("sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1/generated.proto", fileDescriptor_6f67d44e41cfe439)
-}
+func init() { proto.RegisterFile("feature/generated.proto", fileDescriptor_870e6eafce4d2482) }
 
-var fileDescriptor_6f67d44e41cfe439 = []byte{
-	// 546 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x94, 0xcf, 0x6e, 0xd3, 0x40,
-	0x10, 0xc6, 0xb3, 0x4d, 0x23, 0x25, 0x13, 0x25, 0x0d, 0x0b, 0x07, 0x13, 0x81, 0x5b, 0xa5, 0x12,
-	0x14, 0xa1, 0xd8, 0x6a, 0xb8, 0x44, 0x20, 0x0e, 0xad, 0x68, 0x29, 0x1c, 0x7a, 0x30, 0x08, 0x41,
-	0xa5, 0x80, 0x36, 0xc9, 0xc6, 0x5d, 0xc5, 0xb1, 0x23, 0xef, 0x3a, 0x52, 0x6e, 0x3c, 0x02, 0x0f,
-	0xc1, 0x15, 0x21, 0xf1, 0x14, 0x39, 0xf6, 0xd8, 0x53, 0x45, 0xcc, 0x8b, 0xa0, 0xf8, 0x4f, 0x6c,
-	0x27, 0x76, 0x2a, 0xb8, 0xed, 0x4e, 0xbe, 0xf9, 0xcd, 0xcc, 0xb7, 0x13, 0xc3, 0x19, 0x67, 0x3a,
-	0x57, 0x86, 0x6d, 0xae, 0x30, 0x4b, 0x35, 0xad, 0x3e, 0x6d, 0x0e, 0x28, 0x11, 0x8e, 0x4d, 0x9b,
-	0x7d, 0xc6, 0x7b, 0xd6, 0x84, 0xda, 0x53, 0x75, 0x3c, 0xd4, 0x55, 0x32, 0x66, 0x5c, 0x35, 0x07,
-	0x7d, 0x75, 0x72, 0x48, 0x8c, 0xf1, 0x25, 0x39, 0x54, 0x75, 0x6a, 0x52, 0x9b, 0x08, 0xda, 0x57,
-	0xc6, 0xb6, 0x25, 0x2c, 0x5c, 0x0c, 0x7f, 0xa9, 0x37, 0x75, 0x26, 0x2e, 0x9d, 0xae, 0xd2, 0xb3,
-	0x46, 0xaa, 0x6e, 0xe9, 0x96, 0xea, 0x09, 0xba, 0xce, 0xc0, 0xbb, 0x79, 0x17, 0xef, 0xe4, 0x27,
-	0x36, 0x7e, 0x20, 0xb8, 0x7b, 0x24, 0x84, 0xcd, 0xba, 0x8e, 0xa0, 0xa7, 0x7e, 0xf5, 0x77, 0x54,
-	0xe0, 0x4f, 0x50, 0xa4, 0x06, 0x1d, 0x51, 0x53, 0x70, 0x09, 0xed, 0xe5, 0x0f, 0xca, 0xad, 0xa7,
-	0x4a, 0x58, 0x43, 0x49, 0x49, 0x50, 0x4e, 0x02, 0xf5, 0x89, 0x29, 0xec, 0xe9, 0x71, 0x6d, 0x76,
-	0xb3, 0x9b, 0x73, 0x6f, 0x76, 0x8b, 0x61, 0x58, 0x5b, 0xe2, 0xea, 0x2f, 0xa0, 0x92, 0x10, 0xe3,
-	0x1a, 0xe4, 0x87, 0x74, 0x2a, 0xa1, 0x3d, 0x74, 0x50, 0xd2, 0x16, 0x47, 0x7c, 0x0f, 0x0a, 0x13,
-	0x62, 0x38, 0x54, 0xda, 0xf2, 0x62, 0xfe, 0xe5, 0xf9, 0x56, 0x1b, 0x35, 0xbe, 0x6f, 0x43, 0xf5,
-	0x95, 0x35, 0x22, 0xcc, 0x0c, 0x6a, 0x73, 0x7c, 0x06, 0x85, 0x81, 0x41, 0x74, 0x2e, 0x6d, 0x79,
-	0x7d, 0xee, 0x47, 0x7d, 0x26, 0x85, 0xca, 0xe9, 0x42, 0xe5, 0xf7, 0x57, 0x09, 0xfa, 0x2b, 0x78,
-	0x31, 0xcd, 0x07, 0xe0, 0x2f, 0x50, 0x9e, 0x90, 0x70, 0x36, 0x2e, 0xe5, 0x3d, 0xde, 0x93, 0x4c,
-	0xde, 0x87, 0x48, 0xeb, 0x53, 0x71, 0x40, 0x85, 0xa5, 0x41, 0x5c, 0x8b, 0x13, 0xf1, 0x47, 0x28,
-	0x31, 0x93, 0x0b, 0x62, 0xf6, 0x28, 0x97, 0xb6, 0x3d, 0xfc, 0xe3, 0x4c, 0xfc, 0x9b, 0x50, 0xe9,
-	0xc3, 0xef, 0x04, 0xf0, 0xd2, 0x32, 0xae, 0x45, 0xb0, 0xba, 0x06, 0x10, 0x8d, 0x97, 0xe2, 0xa8,
-	0x12, 0x77, 0xb4, 0xdc, 0x92, 0xa2, 0xaa, 0x8b, 0xb4, 0xe8, 0x1d, 0x63, 0x5e, 0xd7, 0x3b, 0x50,
-	0x5b, 0x1d, 0x31, 0x85, 0xfc, 0x2c, 0x49, 0x7e, 0xb8, 0x71, 0x4d, 0xe2, 0xf8, 0x0b, 0xa8, 0x26,
-	0x47, 0x4c, 0x81, 0xb7, 0x92, 0xf0, 0x07, 0x11, 0x3c, 0x4c, 0x4d, 0x65, 0x37, 0x7e, 0x21, 0xa8,
-	0x26, 0x07, 0xc3, 0xef, 0xd7, 0x36, 0xfa, 0x51, 0x96, 0x09, 0xff, 0xb0, 0xcc, 0x6f, 0x6f, 0x5f,
-	0xe6, 0xfd, 0xe4, 0x0c, 0x95, 0xa8, 0xea, 0x39, 0x33, 0xe2, 0x4d, 0xff, 0x44, 0xb0, 0xb3, 0x32,
-	0x16, 0xee, 0x00, 0xc4, 0x36, 0x12, 0xad, 0x6e, 0xe4, 0x8a, 0x3c, 0xb2, 0x7c, 0xc3, 0x46, 0xc6,
-	0x80, 0xf5, 0x97, 0xb0, 0x73, 0x74, 0xeb, 0x0b, 0x67, 0xff, 0x1b, 0x3b, 0x80, 0xd7, 0xdf, 0x01,
-	0xbf, 0x5e, 0x73, 0xfa, 0x7e, 0x66, 0xc7, 0x9b, 0xcc, 0x6d, 0x14, 0x20, 0x7f, 0xce, 0x8c, 0xe3,
-	0xcf, 0xb3, 0xb9, 0x9c, 0xbb, 0x9a, 0xcb, 0xb9, 0xeb, 0xb9, 0x9c, 0xfb, 0xea, 0xca, 0x68, 0xe6,
-	0xca, 0xe8, 0xca, 0x95, 0xd1, 0xb5, 0x2b, 0xa3, 0xdf, 0xae, 0x8c, 0xbe, 0xfd, 0x91, 0x73, 0x17,
-	0xed, 0xff, 0xfd, 0x98, 0xfe, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x75, 0x9e, 0xef, 0x0b, 0x87, 0x05,
-	0x00, 0x00,
+var fileDescriptor_870e6eafce4d2482 = []byte{
+	// 501 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0xdd, 0x6a, 0xd4, 0x40,
+	0x14, 0xc7, 0x33, 0xbb, 0x2e, 0x36, 0x67, 0xed, 0x76, 0x1d, 0x85, 0x86, 0x28, 0xd3, 0x12, 0x50,
+	0x16, 0xa1, 0x09, 0xee, 0x95, 0x28, 0x5e, 0xb4, 0xd8, 0x95, 0xde, 0x14, 0x4c, 0xc1, 0x2f, 0x16,
+	0x21, 0x5b, 0x67, 0x63, 0x30, 0x9b, 0x48, 0x32, 0x29, 0xf4, 0xce, 0x47, 0xf0, 0x09, 0x7c, 0x02,
+	0x11, 0x1f, 0x63, 0x2f, 0x7b, 0xd9, 0xab, 0xe2, 0xc6, 0x17, 0x91, 0x9d, 0x4c, 0x3e, 0x37, 0xd9,
+	0xd2, 0xbb, 0xcc, 0x99, 0xff, 0xf9, 0x9d, 0x73, 0xfe, 0x73, 0x02, 0xdb, 0x53, 0x6a, 0xb1, 0x28,
+	0xa0, 0x86, 0x4d, 0x3d, 0x1a, 0x58, 0x8c, 0x7e, 0xd6, 0xbf, 0x05, 0x3e, 0xf3, 0xf1, 0x6d, 0x71,
+	0xa1, 0xee, 0xd9, 0x0e, 0xfb, 0x12, 0x4d, 0xf4, 0x53, 0x7f, 0x66, 0xd8, 0xbe, 0xed, 0x1b, 0xfc,
+	0x7e, 0x12, 0x4d, 0xf9, 0x89, 0x1f, 0xf8, 0x57, 0x92, 0xa7, 0xfd, 0x42, 0x70, 0x6f, 0x9f, 0xb1,
+	0xc0, 0x99, 0x44, 0x8c, 0x8e, 0x12, 0xc6, 0x09, 0x65, 0xf8, 0x3d, 0x6c, 0x50, 0x97, 0xce, 0xa8,
+	0xc7, 0x42, 0x05, 0xed, 0xb6, 0x07, 0xdd, 0xe1, 0x13, 0x5d, 0x94, 0xd0, 0x6b, 0xf4, 0xfa, 0xa1,
+	0x10, 0x1f, 0x7a, 0x2c, 0x38, 0x3f, 0xe8, 0xcf, 0xaf, 0x76, 0xa4, 0xf8, 0x6a, 0x67, 0x23, 0x0d,
+	0x9b, 0x19, 0x4d, 0x7d, 0x01, 0x9b, 0x25, 0x31, 0xee, 0x43, 0xfb, 0x2b, 0x3d, 0x57, 0xd0, 0x2e,
+	0x1a, 0xc8, 0xe6, 0xf2, 0x13, 0xdf, 0x87, 0xce, 0x99, 0xe5, 0x46, 0x54, 0x69, 0xf1, 0x58, 0x72,
+	0x78, 0xde, 0x7a, 0x86, 0xb4, 0x9f, 0xb7, 0xa0, 0xf7, 0xca, 0x9f, 0x59, 0x8e, 0x27, 0x6a, 0x87,
+	0xf8, 0x35, 0x74, 0xa6, 0xae, 0x65, 0xa7, 0x6d, 0x6a, 0x59, 0x9b, 0x65, 0x9d, 0x3e, 0x5a, 0x8a,
+	0x92, 0xf6, 0x36, 0x45, 0x7b, 0x1d, 0x1e, 0x33, 0x93, 0x7c, 0xfc, 0x09, 0xba, 0x67, 0x56, 0x3a,
+	0x5a, 0xa8, 0xb4, 0x38, 0x6e, 0xd0, 0x84, 0x7b, 0x9b, 0x4b, 0x13, 0x28, 0x16, 0x50, 0xc8, 0xec,
+	0x09, 0xcd, 0x22, 0x10, 0xbf, 0x03, 0xd9, 0xf1, 0x42, 0x66, 0x79, 0xa7, 0x34, 0x54, 0xda, 0x9c,
+	0xfe, 0xb8, 0x89, 0x7e, 0x94, 0x0a, 0x13, 0xf6, 0x5d, 0xc1, 0x96, 0xb3, 0xb8, 0x99, 0xb3, 0xd4,
+	0x37, 0x00, 0xf9, 0x70, 0x35, 0x76, 0xee, 0x15, 0xed, 0xec, 0x0e, 0xb7, 0xb3, 0xa2, 0xcb, 0xac,
+	0xfc, 0x0d, 0x0b, 0x3e, 0xab, 0x63, 0xe8, 0x57, 0x07, 0xac, 0x01, 0x0f, 0xcb, 0xe0, 0x87, 0xeb,
+	0x36, 0xa4, 0x48, 0xff, 0x00, 0xbd, 0xf2, 0x80, 0x35, 0xec, 0xa7, 0x65, 0xf6, 0x83, 0x8c, 0x9d,
+	0x66, 0xd6, 0xa2, 0xb5, 0x3f, 0x08, 0x7a, 0xe5, 0xb1, 0xf0, 0xc9, 0xca, 0x2a, 0x3f, 0x6a, 0x70,
+	0xe0, 0x06, 0x5b, 0x7c, 0x74, 0xfd, 0x16, 0x6b, 0xe5, 0x09, 0xee, 0x64, 0x45, 0x8f, 0x1d, 0xb7,
+	0xd8, 0xf2, 0x6f, 0x04, 0x5b, 0x95, 0xa1, 0xf0, 0x18, 0xa0, 0xb0, 0x8a, 0xa8, 0xb2, 0x8a, 0x15,
+	0x75, 0x6e, 0xf7, 0x9a, 0x55, 0x2c, 0xf0, 0xd4, 0x97, 0xb0, 0xb5, 0x7f, 0xed, 0xe3, 0x36, 0xff,
+	0x84, 0x63, 0xc0, 0xab, 0x8f, 0x80, 0x47, 0x2b, 0x36, 0x2b, 0x4d, 0x0d, 0xaf, 0x73, 0x56, 0xeb,
+	0x40, 0xfb, 0xd8, 0x71, 0x0f, 0x8c, 0xf9, 0x82, 0x48, 0x17, 0x0b, 0x22, 0x5d, 0x2e, 0x88, 0xf4,
+	0x3d, 0x26, 0x68, 0x1e, 0x13, 0x74, 0x11, 0x13, 0x74, 0x19, 0x13, 0xf4, 0x37, 0x26, 0xe8, 0xc7,
+	0x3f, 0x22, 0x7d, 0x94, 0x75, 0x43, 0xd4, 0xf8, 0x1f, 0x00, 0x00, 0xff, 0xff, 0x3a, 0x32, 0x3a,
+	0xd7, 0x1b, 0x05, 0x00, 0x00,
 }
 
 func (m *AttributeFeatureSet) Marshal() (dAtA []byte, err error) {
@@ -362,7 +357,7 @@ func (m *DomainFeatures) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 			dAtA[i] = 0xa
 			i = encodeVarintGenerated(dAtA, i, uint64(baseI-i))
 			i--
-			dAtA[i] = 0x22
+			dAtA[i] = 0x1a
 		}
 	}
 	if len(m.Attributes) > 0 {
@@ -391,7 +386,7 @@ func (m *DomainFeatures) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 			dAtA[i] = 0xa
 			i = encodeVarintGenerated(dAtA, i, uint64(baseI-i))
 			i--
-			dAtA[i] = 0x1a
+			dAtA[i] = 0x12
 		}
 	}
 	if len(m.Flags) > 0 {
@@ -420,7 +415,7 @@ func (m *DomainFeatures) MarshalToSizedBuffer(dAtA []byte) (int, error) {
 			dAtA[i] = 0xa
 			i = encodeVarintGenerated(dAtA, i, uint64(baseI-i))
 			i--
-			dAtA[i] = 0x12
+			dAtA[i] = 0xa
 		}
 	}
 	return len(dAtA) - i, nil
@@ -1054,7 +1049,7 @@ func (m *DomainFeatures) Unmarshal(dAtA []byte) error {
 			return fmt.Errorf("proto: DomainFeatures: illegal tag %d (wire type %d)", fieldNum, wire)
 		}
 		switch fieldNum {
-		case 2:
+		case 1:
 			if wireType != 2 {
 				return fmt.Errorf("proto: wrong wireType = %d for field Flags", wireType)
 			}
@@ -1183,7 +1178,7 @@ func (m *DomainFeatures) Unmarshal(dAtA []byte) error {
 			}
 			m.Flags[mapkey] = *mapvalue
 			iNdEx = postIndex
-		case 3:
+		case 2:
 			if wireType != 2 {
 				return fmt.Errorf("proto: wrong wireType = %d for field Attributes", wireType)
 			}
@@ -1312,7 +1307,7 @@ func (m *DomainFeatures) Unmarshal(dAtA []byte) error {
 			}
 			m.Attributes[mapkey] = *mapvalue
 			iNdEx = postIndex
-		case 4:
+		case 3:
 			if wireType != 2 {
 				return fmt.Errorf("proto: wrong wireType = %d for field Instances", wireType)
 			}
diff --git a/pkg/apis/nfd/v1alpha1/generated.proto b/pkg/api/feature/generated.proto
similarity index 80%
rename from pkg/apis/nfd/v1alpha1/generated.proto
rename to pkg/api/feature/generated.proto
index 6cb1fc8e0..810414854 100644
--- a/pkg/apis/nfd/v1alpha1/generated.proto
+++ b/pkg/api/feature/generated.proto
@@ -19,53 +19,41 @@ limitations under the License.
 
 syntax = "proto2";
 
-package v1alpha1;
+package feature;
 
 // Package-wide variables from generator "generated".
-option go_package = "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1";
+option go_package = "sigs.k8s.io/node-feature-discovery/pkg/api/feature";
 
 // AttributeFeatureSet is a set of features having string value.
-//
-// +protobuf=true
 message AttributeFeatureSet {
   map<string, string> elements = 1;
 }
 
 // DomainFeatures is the collection of all discovered features of one domain.
-//
-// +protobuf=true
 message DomainFeatures {
-  map<string, FlagFeatureSet> flags = 2;
+  map<string, FlagFeatureSet> flags = 1;
 
-  map<string, AttributeFeatureSet> vattributes = 3;
+  map<string, AttributeFeatureSet> vattributes = 2;
 
-  map<string, InstanceFeatureSet> instances = 4;
+  map<string, InstanceFeatureSet> instances = 3;
 }
 
 // FlagFeatureSet is a set of simple features only containing names without values.
-//
-// +protobuf=true
 message FlagFeatureSet {
   map<string, Nil> elements = 1;
 }
 
 // InstanceFeature represents one instance of a complex features, e.g. a device.
-//
-// +protobuf=true
 message InstanceFeature {
   map<string, string> attributes = 1;
 }
 
 // InstanceFeatureSet is a set of features each of which is an instance having multiple attributes.
-//
-// +protobuf=true
 message InstanceFeatureSet {
   repeated InstanceFeature elements = 1;
 }
 
 // Nil is a dummy empty struct for protobuf compatibility
-//
-// +protobuf=true
 message Nil {
 }
 
diff --git a/pkg/api/feature/types.go b/pkg/api/feature/types.go
new file mode 100644
index 000000000..505081414
--- /dev/null
+++ b/pkg/api/feature/types.go
@@ -0,0 +1,53 @@
+/*
+Copyright 2021 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package feature
+
+//go:generate ./generate.sh
+
+// Features is a collection of all features of the system, arranged by domain.
+// +protobuf
+type Features map[string]*DomainFeatures
+
+// DomainFeatures is the collection of all discovered features of one domain.
+type DomainFeatures struct {
+	Flags      map[string]FlagFeatureSet      `protobuf:"bytes,1,rep,name=flags"`
+	Attributes map[string]AttributeFeatureSet `protobuf:"bytes,2,rep,name=vattributes"`
+	Instances  map[string]InstanceFeatureSet  `protobuf:"bytes,3,rep,name=instances"`
+}
+
+// FlagFeatureSet is a set of simple features only containing names without values.
+type FlagFeatureSet struct {
+	Elements map[string]Nil `protobuf:"bytes,1,rep,name=elements"`
+}
+
+// AttributeFeatureSet is a set of features having string value.
+type AttributeFeatureSet struct {
+	Elements map[string]string `protobuf:"bytes,1,rep,name=elements"`
+}
+
+// InstanceFeatureSet is a set of features each of which is an instance having multiple attributes.
+type InstanceFeatureSet struct {
+	Elements []InstanceFeature `protobuf:"bytes,1,rep,name=elements"`
+}
+
+// InstanceFeature represents one instance of a complex features, e.g. a device.
+type InstanceFeature struct {
+	Attributes map[string]string `protobuf:"bytes,1,rep,name=attributes"`
+}
+
+// Nil is a dummy empty struct for protobuf compatibility
+type Nil struct{}
diff --git a/pkg/apihelper/apihelpers.go b/pkg/apihelper/apihelpers.go
index b067e539b..bfcdec6a7 100644
--- a/pkg/apihelper/apihelpers.go
+++ b/pkg/apihelper/apihelpers.go
@@ -20,7 +20,7 @@ package apihelper
 
 import (
 	topologyclientset "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/generated/clientset/versioned"
-	corev1 "k8s.io/api/core/v1"
+	api "k8s.io/api/core/v1"
 	k8sclient "k8s.io/client-go/kubernetes"
 )
 
@@ -30,13 +30,13 @@ type APIHelpers interface {
 	GetClient() (*k8sclient.Clientset, error)
 
 	// GetNode returns the Kubernetes node on which this container is running.
-	GetNode(*k8sclient.Clientset, string) (*corev1.Node, error)
+	GetNode(*k8sclient.Clientset, string) (*api.Node, error)
 
 	// GetNodes returns all the nodes in the cluster
-	GetNodes(*k8sclient.Clientset) (*corev1.NodeList, error)
+	GetNodes(*k8sclient.Clientset) (*api.NodeList, error)
 
 	// UpdateNode updates the node via the API server using a client.
-	UpdateNode(*k8sclient.Clientset, *corev1.Node) error
+	UpdateNode(*k8sclient.Clientset, *api.Node) error
 
 	// PatchNode updates the node object via the API server using a client.
 	PatchNode(*k8sclient.Clientset, string, []JsonPatch) error
@@ -48,5 +48,5 @@ type APIHelpers interface {
 	GetTopologyClient() (*topologyclientset.Clientset, error)
 
 	// GetPod returns the Kubernetes pod in a namepace with a name.
-	GetPod(*k8sclient.Clientset, string, string) (*corev1.Pod, error)
+	GetPod(*k8sclient.Clientset, string, string) (*api.Pod, error)
 }
diff --git a/pkg/apihelper/k8shelpers.go b/pkg/apihelper/k8shelpers.go
index ee9838fa6..823826330 100644
--- a/pkg/apihelper/k8shelpers.go
+++ b/pkg/apihelper/k8shelpers.go
@@ -21,7 +21,7 @@ import (
 	"encoding/json"
 
 	topologyclientset "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/generated/clientset/versioned"
-	corev1 "k8s.io/api/core/v1"
+	api "k8s.io/api/core/v1"
 	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
 	k8sclient "k8s.io/client-go/kubernetes"
@@ -52,7 +52,7 @@ func (h K8sHelpers) GetTopologyClient() (*topologyclientset.Clientset, error) {
 }
 
 // GetNode retrieves one node object.
-func (h K8sHelpers) GetNode(cli *k8sclient.Clientset, nodeName string) (*corev1.Node, error) {
+func (h K8sHelpers) GetNode(cli *k8sclient.Clientset, nodeName string) (*api.Node, error) {
 	// Get the node object using node name
 	node, err := cli.CoreV1().Nodes().Get(context.TODO(), nodeName, meta_v1.GetOptions{})
 	if err != nil {
@@ -63,12 +63,12 @@ func (h K8sHelpers) GetNode(cli *k8sclient.Clientset, nodeName string) (*corev1.
 }
 
 // GetNodes retrieves all the node objects.
-func (h K8sHelpers) GetNodes(cli *k8sclient.Clientset) (*corev1.NodeList, error) {
+func (h K8sHelpers) GetNodes(cli *k8sclient.Clientset) (*api.NodeList, error) {
 	return cli.CoreV1().Nodes().List(context.TODO(), meta_v1.ListOptions{})
 }
 
 // UpdateNode sends updated node object to the apiserver
-func (h K8sHelpers) UpdateNode(c *k8sclient.Clientset, n *corev1.Node) error {
+func (h K8sHelpers) UpdateNode(c *k8sclient.Clientset, n *api.Node) error {
 	// Send the updated node to the apiserver.
 	_, err := c.CoreV1().Nodes().Update(context.TODO(), n, meta_v1.UpdateOptions{})
 	if err != nil {
@@ -101,7 +101,7 @@ func (h K8sHelpers) PatchNodeStatus(c *k8sclient.Clientset, nodeName string, pat
 
 }
 
-func (h K8sHelpers) GetPod(cli *k8sclient.Clientset, namespace string, podName string) (*corev1.Pod, error) {
+func (h K8sHelpers) GetPod(cli *k8sclient.Clientset, namespace string, podName string) (*api.Pod, error) {
 	// Get the node object using pod name
 	pod, err := cli.CoreV1().Pods(namespace).Get(context.TODO(), podName, meta_v1.GetOptions{})
 	if err != nil {
diff --git a/pkg/apihelper/mock_APIHelpers.go b/pkg/apihelper/mock_APIHelpers.go
index 0f0fd895c..7e677339f 100644
--- a/pkg/apihelper/mock_APIHelpers.go
+++ b/pkg/apihelper/mock_APIHelpers.go
@@ -6,7 +6,7 @@ import (
 	mock "github.com/stretchr/testify/mock"
 	kubernetes "k8s.io/client-go/kubernetes"
 
-	corev1 "k8s.io/api/core/v1"
+	v1 "k8s.io/api/core/v1"
 
 	versioned "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/generated/clientset/versioned"
 )
@@ -40,15 +40,15 @@ func (_m *MockAPIHelpers) GetClient() (*kubernetes.Clientset, error) {
 }
 
 // GetNode provides a mock function with given fields: _a0, _a1
-func (_m *MockAPIHelpers) GetNode(_a0 *kubernetes.Clientset, _a1 string) (*corev1.Node, error) {
+func (_m *MockAPIHelpers) GetNode(_a0 *kubernetes.Clientset, _a1 string) (*v1.Node, error) {
 	ret := _m.Called(_a0, _a1)
 
-	var r0 *corev1.Node
-	if rf, ok := ret.Get(0).(func(*kubernetes.Clientset, string) *corev1.Node); ok {
+	var r0 *v1.Node
+	if rf, ok := ret.Get(0).(func(*kubernetes.Clientset, string) *v1.Node); ok {
 		r0 = rf(_a0, _a1)
 	} else {
 		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*corev1.Node)
+			r0 = ret.Get(0).(*v1.Node)
 		}
 	}
 
@@ -63,15 +63,15 @@ func (_m *MockAPIHelpers) GetNode(_a0 *kubernetes.Clientset, _a1 string) (*corev
 }
 
 // GetNodes provides a mock function with given fields: _a0
-func (_m *MockAPIHelpers) GetNodes(_a0 *kubernetes.Clientset) (*corev1.NodeList, error) {
+func (_m *MockAPIHelpers) GetNodes(_a0 *kubernetes.Clientset) (*v1.NodeList, error) {
 	ret := _m.Called(_a0)
 
-	var r0 *corev1.NodeList
-	if rf, ok := ret.Get(0).(func(*kubernetes.Clientset) *corev1.NodeList); ok {
+	var r0 *v1.NodeList
+	if rf, ok := ret.Get(0).(func(*kubernetes.Clientset) *v1.NodeList); ok {
 		r0 = rf(_a0)
 	} else {
 		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*corev1.NodeList)
+			r0 = ret.Get(0).(*v1.NodeList)
 		}
 	}
 
@@ -86,15 +86,15 @@ func (_m *MockAPIHelpers) GetNodes(_a0 *kubernetes.Clientset) (*corev1.NodeList,
 }
 
 // GetPod provides a mock function with given fields: _a0, _a1, _a2
-func (_m *MockAPIHelpers) GetPod(_a0 *kubernetes.Clientset, _a1 string, _a2 string) (*corev1.Pod, error) {
+func (_m *MockAPIHelpers) GetPod(_a0 *kubernetes.Clientset, _a1 string, _a2 string) (*v1.Pod, error) {
 	ret := _m.Called(_a0, _a1, _a2)
 
-	var r0 *corev1.Pod
-	if rf, ok := ret.Get(0).(func(*kubernetes.Clientset, string, string) *corev1.Pod); ok {
+	var r0 *v1.Pod
+	if rf, ok := ret.Get(0).(func(*kubernetes.Clientset, string, string) *v1.Pod); ok {
 		r0 = rf(_a0, _a1, _a2)
 	} else {
 		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*corev1.Pod)
+			r0 = ret.Get(0).(*v1.Pod)
 		}
 	}
 
@@ -160,11 +160,11 @@ func (_m *MockAPIHelpers) PatchNodeStatus(_a0 *kubernetes.Clientset, _a1 string,
 }
 
 // UpdateNode provides a mock function with given fields: _a0, _a1
-func (_m *MockAPIHelpers) UpdateNode(_a0 *kubernetes.Clientset, _a1 *corev1.Node) error {
+func (_m *MockAPIHelpers) UpdateNode(_a0 *kubernetes.Clientset, _a1 *v1.Node) error {
 	ret := _m.Called(_a0, _a1)
 
 	var r0 error
-	if rf, ok := ret.Get(0).(func(*kubernetes.Clientset, *corev1.Node) error); ok {
+	if rf, ok := ret.Get(0).(func(*kubernetes.Clientset, *v1.Node) error); ok {
 		r0 = rf(_a0, _a1)
 	} else {
 		r0 = ret.Error(0)
diff --git a/pkg/apis/nfd/v1alpha1/doc.go b/pkg/apis/nfd/v1alpha1/doc.go
index 17b8fc585..32b425965 100644
--- a/pkg/apis/nfd/v1alpha1/doc.go
+++ b/pkg/apis/nfd/v1alpha1/doc.go
@@ -19,5 +19,3 @@ limitations under the License.
 // +kubebuilder:object:generate=true
 // +groupName=nfd.k8s-sigs.io
 package v1alpha1
-
-//go:generate ./generate.sh
diff --git a/pkg/apis/nfd/v1alpha1/expression.go b/pkg/apis/nfd/v1alpha1/expression.go
index 47108ab22..50534bbe4 100644
--- a/pkg/apis/nfd/v1alpha1/expression.go
+++ b/pkg/apis/nfd/v1alpha1/expression.go
@@ -25,20 +25,22 @@ import (
 	"strings"
 
 	"k8s.io/klog/v2"
+
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 )
 
 var matchOps = map[MatchOp]struct{}{
-	MatchAny:          {},
-	MatchIn:           {},
-	MatchNotIn:        {},
-	MatchInRegexp:     {},
-	MatchExists:       {},
-	MatchDoesNotExist: {},
-	MatchGt:           {},
-	MatchLt:           {},
-	MatchGtLt:         {},
-	MatchIsTrue:       {},
-	MatchIsFalse:      {},
+	MatchAny:          struct{}{},
+	MatchIn:           struct{}{},
+	MatchNotIn:        struct{}{},
+	MatchInRegexp:     struct{}{},
+	MatchExists:       struct{}{},
+	MatchDoesNotExist: struct{}{},
+	MatchGt:           struct{}{},
+	MatchLt:           struct{}{},
+	MatchGtLt:         struct{}{},
+	MatchIsTrue:       struct{}{},
+	MatchIsFalse:      struct{}{},
 }
 
 type valueRegexpCache []*regexp.Regexp
@@ -78,44 +80,44 @@ func (m *MatchExpression) Validate() error {
 	switch m.Op {
 	case MatchExists, MatchDoesNotExist, MatchIsTrue, MatchIsFalse, MatchAny:
 		if len(m.Value) != 0 {
-			return fmt.Errorf("value must be empty for Op %q (have %v)", m.Op, m.Value)
+			return fmt.Errorf("Value must be empty for Op %q (have %v)", m.Op, m.Value)
 		}
 	case MatchGt, MatchLt:
 		if len(m.Value) != 1 {
-			return fmt.Errorf("value must contain exactly one element for Op %q (have %v)", m.Op, m.Value)
+			return fmt.Errorf("Value must contain exactly one element for Op %q (have %v)", m.Op, m.Value)
 		}
 		if _, err := strconv.Atoi(m.Value[0]); err != nil {
-			return fmt.Errorf("value must be an integer for Op %q (have %v)", m.Op, m.Value[0])
+			return fmt.Errorf("Value must be an integer for Op %q (have %v)", m.Op, m.Value[0])
 		}
 	case MatchGtLt:
 		if len(m.Value) != 2 {
-			return fmt.Errorf("value must contain exactly two elements for Op %q (have %v)", m.Op, m.Value)
+			return fmt.Errorf("Value must contain exactly two elements for Op %q (have %v)", m.Op, m.Value)
 		}
 		var err error
 		v := make([]int, 2)
 		for i := 0; i < 2; i++ {
 			if v[i], err = strconv.Atoi(m.Value[i]); err != nil {
-				return fmt.Errorf("value must contain integers for Op %q (have %v)", m.Op, m.Value)
+				return fmt.Errorf("Value must contain integers for Op %q (have %v)", m.Op, m.Value)
 			}
 		}
 		if v[0] >= v[1] {
-			return fmt.Errorf("value[0] must be less than Value[1] for Op %q (have %v)", m.Op, m.Value)
+			return fmt.Errorf("Value[0] must be less than Value[1] for Op %q (have %v)", m.Op, m.Value)
 		}
 	case MatchInRegexp:
 		if len(m.Value) == 0 {
-			return fmt.Errorf("value must be non-empty for Op %q", m.Op)
+			return fmt.Errorf("Value must be non-empty for Op %q", m.Op)
 		}
 		m.valueRe = make([]*regexp.Regexp, len(m.Value))
 		for i, v := range m.Value {
 			re, err := regexp.Compile(v)
 			if err != nil {
-				return fmt.Errorf("value must only contain valid regexps for Op %q (have %v)", m.Op, m.Value)
+				return fmt.Errorf("Value must only contain valid regexps for Op %q (have %v)", m.Op, m.Value)
 			}
 			m.valueRe[i] = re
 		}
 	default:
 		if len(m.Value) == 0 {
-			return fmt.Errorf("value must be non-empty for Op %q", m.Op)
+			return fmt.Errorf("Value must be non-empty for Op %q", m.Op)
 		}
 	}
 	return nil
@@ -195,7 +197,7 @@ func (m *MatchExpression) Match(valid bool, value interface{}) (bool, error) {
 }
 
 // MatchKeys evaluates the MatchExpression against a set of keys.
-func (m *MatchExpression) MatchKeys(name string, keys map[string]Nil) (bool, error) {
+func (m *MatchExpression) MatchKeys(name string, keys map[string]feature.Nil) (bool, error) {
 	matched := false
 
 	_, ok := keys[name]
@@ -301,7 +303,7 @@ func (m *MatchExpression) UnmarshalJSON(data []byte) error {
 }
 
 // MatchKeys evaluates the MatchExpressionSet against a set of keys.
-func (m *MatchExpressionSet) MatchKeys(keys map[string]Nil) (bool, error) {
+func (m *MatchExpressionSet) MatchKeys(keys map[string]feature.Nil) (bool, error) {
 	matched, _, err := m.MatchGetKeys(keys)
 	return matched, err
 }
@@ -316,7 +318,7 @@ type MatchedKey struct {
 // empty MatchExpressionSet returns all existing keys are returned. Note that
 // an empty MatchExpressionSet and an empty set of keys returns an empty slice
 // which is not nil and is treated as a match.
-func (m *MatchExpressionSet) MatchGetKeys(keys map[string]Nil) (bool, []MatchedKey, error) {
+func (m *MatchExpressionSet) MatchGetKeys(keys map[string]feature.Nil) (bool, []MatchedKey, error) {
 	ret := make([]MatchedKey, 0, len(*m))
 
 	for n, e := range *m {
@@ -372,7 +374,7 @@ func (m *MatchExpressionSet) MatchGetValues(values map[string]string) (bool, []M
 // MatchInstances evaluates the MatchExpressionSet against a set of instance
 // features, each of which is an individual set of key-value pairs
 // (attributes).
-func (m *MatchExpressionSet) MatchInstances(instances []InstanceFeature) (bool, error) {
+func (m *MatchExpressionSet) MatchInstances(instances []feature.InstanceFeature) (bool, error) {
 	v, err := m.MatchGetInstances(instances)
 	return len(v) > 0, err
 }
@@ -384,7 +386,7 @@ type MatchedInstance map[string]string
 // features, each of which is an individual set of key-value pairs
 // (attributes). A slice containing all matching instances is returned. An
 // empty (non-nil) slice is returned if no matching instances were found.
-func (m *MatchExpressionSet) MatchGetInstances(instances []InstanceFeature) ([]MatchedInstance, error) {
+func (m *MatchExpressionSet) MatchGetInstances(instances []feature.InstanceFeature) ([]MatchedInstance, error) {
 	ret := []MatchedInstance{}
 
 	for _, i := range instances {
diff --git a/pkg/apis/nfd/v1alpha1/generate.sh b/pkg/apis/nfd/v1alpha1/generate.sh
deleted file mode 100755
index d4fe85392..000000000
--- a/pkg/apis/nfd/v1alpha1/generate.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh -ex
-
-go-to-protobuf \
-   --output-base=. \
-   --go-header-file ../../../../hack/boilerplate.go.txt \
-   --proto-import ../../../../vendor/ \
-   --packages +sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1=v1alpha1 \
-   --keep-gogoproto=false \
-   --apimachinery-packages "-k8s.io/apimachinery/pkg/util/intstr"
-
-mv sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1/* .
-rm -rf sigs.k8s.io
diff --git a/pkg/apis/nfd/v1alpha1/rule.go b/pkg/apis/nfd/v1alpha1/rule.go
index ab0f6f913..1ed930269 100644
--- a/pkg/apis/nfd/v1alpha1/rule.go
+++ b/pkg/apis/nfd/v1alpha1/rule.go
@@ -24,6 +24,7 @@ import (
 
 	"k8s.io/klog/v2"
 
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils"
 )
 
@@ -35,7 +36,7 @@ type RuleOutput struct {
 }
 
 // Execute the rule against a set of input features.
-func (r *Rule) Execute(features Features) (RuleOutput, error) {
+func (r *Rule) Execute(features feature.Features) (RuleOutput, error) {
 	labels := make(map[string]string)
 	vars := make(map[string]string)
 
@@ -149,11 +150,11 @@ type matchedFeatures map[string]domainMatchedFeatures
 
 type domainMatchedFeatures map[string]interface{}
 
-func (e *MatchAnyElem) match(features map[string]*DomainFeatures) (bool, matchedFeatures, error) {
+func (e *MatchAnyElem) match(features map[string]*feature.DomainFeatures) (bool, matchedFeatures, error) {
 	return e.MatchFeatures.match(features)
 }
 
-func (m *FeatureMatcher) match(features map[string]*DomainFeatures) (bool, matchedFeatures, error) {
+func (m *FeatureMatcher) match(features map[string]*feature.DomainFeatures) (bool, matchedFeatures, error) {
 	matches := make(matchedFeatures, len(*m))
 
 	// Logical AND over the terms
diff --git a/pkg/apis/nfd/v1alpha1/types.go b/pkg/apis/nfd/v1alpha1/types.go
index 4c3606b2f..1e486768d 100644
--- a/pkg/apis/nfd/v1alpha1/types.go
+++ b/pkg/apis/nfd/v1alpha1/types.go
@@ -20,53 +20,6 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
-// Features is a collection of all features of the system, arranged by domain.
-//
-// +protobuf=true
-type Features map[string]*DomainFeatures
-
-// DomainFeatures is the collection of all discovered features of one domain.
-//
-// +protobuf=true
-type DomainFeatures struct {
-	Flags      map[string]FlagFeatureSet      `json:"flags" protobuf:"bytes,2,rep,name=flags"`
-	Attributes map[string]AttributeFeatureSet `json:"attributes" protobuf:"bytes,3,rep,name=vattributes"`
-	Instances  map[string]InstanceFeatureSet  `json:"instances" protobuf:"bytes,4,rep,name=instances"`
-}
-
-// FlagFeatureSet is a set of simple features only containing names without values.
-//
-// +protobuf=true
-type FlagFeatureSet struct {
-	Elements map[string]Nil `json:"elements" protobuf:"bytes,1,rep,name=elements"`
-}
-
-// AttributeFeatureSet is a set of features having string value.
-//
-// +protobuf=true
-type AttributeFeatureSet struct {
-	Elements map[string]string `json:"elements" protobuf:"bytes,1,rep,name=elements"`
-}
-
-// InstanceFeatureSet is a set of features each of which is an instance having multiple attributes.
-//
-// +protobuf=true
-type InstanceFeatureSet struct {
-	Elements []InstanceFeature `json:"elements" protobuf:"bytes,1,rep,name=elements"`
-}
-
-// InstanceFeature represents one instance of a complex features, e.g. a device.
-//
-// +protobuf=true
-type InstanceFeature struct {
-	Attributes map[string]string `json:"attributes" protobuf:"bytes,1,rep,name=attributes"`
-}
-
-// Nil is a dummy empty struct for protobuf compatibility
-//
-// +protobuf=true
-type Nil struct{}
-
 // NodeFeatureRuleList contains a list of NodeFeatureRule objects.
 // +kubebuilder:object:root=true
 // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
diff --git a/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go
index fb932ba67..ff8f19f12 100644
--- a/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go
+++ b/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go
@@ -9,64 +9,6 @@ import (
 	"k8s.io/apimachinery/pkg/runtime"
 )
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *AttributeFeatureSet) DeepCopyInto(out *AttributeFeatureSet) {
-	*out = *in
-	if in.Elements != nil {
-		in, out := &in.Elements, &out.Elements
-		*out = make(map[string]string, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AttributeFeatureSet.
-func (in *AttributeFeatureSet) DeepCopy() *AttributeFeatureSet {
-	if in == nil {
-		return nil
-	}
-	out := new(AttributeFeatureSet)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *DomainFeatures) DeepCopyInto(out *DomainFeatures) {
-	*out = *in
-	if in.Flags != nil {
-		in, out := &in.Flags, &out.Flags
-		*out = make(map[string]FlagFeatureSet, len(*in))
-		for key, val := range *in {
-			(*out)[key] = *val.DeepCopy()
-		}
-	}
-	if in.Attributes != nil {
-		in, out := &in.Attributes, &out.Attributes
-		*out = make(map[string]AttributeFeatureSet, len(*in))
-		for key, val := range *in {
-			(*out)[key] = *val.DeepCopy()
-		}
-	}
-	if in.Instances != nil {
-		in, out := &in.Instances, &out.Instances
-		*out = make(map[string]InstanceFeatureSet, len(*in))
-		for key, val := range *in {
-			(*out)[key] = *val.DeepCopy()
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DomainFeatures.
-func (in *DomainFeatures) DeepCopy() *DomainFeatures {
-	if in == nil {
-		return nil
-	}
-	out := new(DomainFeatures)
-	in.DeepCopyInto(out)
-	return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in FeatureMatcher) DeepCopyInto(out *FeatureMatcher) {
 	{
@@ -118,101 +60,6 @@ func (in *FeatureMatcherTerm) DeepCopy() *FeatureMatcherTerm {
 	return out
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in Features) DeepCopyInto(out *Features) {
-	{
-		in := &in
-		*out = make(Features, len(*in))
-		for key, val := range *in {
-			var outVal *DomainFeatures
-			if val == nil {
-				(*out)[key] = nil
-			} else {
-				in, out := &val, &outVal
-				*out = new(DomainFeatures)
-				(*in).DeepCopyInto(*out)
-			}
-			(*out)[key] = outVal
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Features.
-func (in Features) DeepCopy() Features {
-	if in == nil {
-		return nil
-	}
-	out := new(Features)
-	in.DeepCopyInto(out)
-	return *out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *FlagFeatureSet) DeepCopyInto(out *FlagFeatureSet) {
-	*out = *in
-	if in.Elements != nil {
-		in, out := &in.Elements, &out.Elements
-		*out = make(map[string]Nil, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlagFeatureSet.
-func (in *FlagFeatureSet) DeepCopy() *FlagFeatureSet {
-	if in == nil {
-		return nil
-	}
-	out := new(FlagFeatureSet)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *InstanceFeature) DeepCopyInto(out *InstanceFeature) {
-	*out = *in
-	if in.Attributes != nil {
-		in, out := &in.Attributes, &out.Attributes
-		*out = make(map[string]string, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceFeature.
-func (in *InstanceFeature) DeepCopy() *InstanceFeature {
-	if in == nil {
-		return nil
-	}
-	out := new(InstanceFeature)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *InstanceFeatureSet) DeepCopyInto(out *InstanceFeatureSet) {
-	*out = *in
-	if in.Elements != nil {
-		in, out := &in.Elements, &out.Elements
-		*out = make([]InstanceFeature, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceFeatureSet.
-func (in *InstanceFeatureSet) DeepCopy() *InstanceFeatureSet {
-	if in == nil {
-		return nil
-	}
-	out := new(InstanceFeatureSet)
-	in.DeepCopyInto(out)
-	return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *MatchAnyElem) DeepCopyInto(out *MatchAnyElem) {
 	*out = *in
@@ -355,21 +202,6 @@ func (in *MatchedValue) DeepCopy() *MatchedValue {
 	return out
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *Nil) DeepCopyInto(out *Nil) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Nil.
-func (in *Nil) DeepCopy() *Nil {
-	if in == nil {
-		return nil
-	}
-	out := new(Nil)
-	in.DeepCopyInto(out)
-	return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *NodeFeatureRule) DeepCopyInto(out *NodeFeatureRule) {
 	*out = *in
diff --git a/pkg/labeler/labeler.pb.go b/pkg/labeler/labeler.pb.go
index 68b2d8141..c167403ca 100644
--- a/pkg/labeler/labeler.pb.go
+++ b/pkg/labeler/labeler.pb.go
@@ -30,7 +30,7 @@ import (
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
 	reflect "reflect"
-	v1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
+	feature "sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	sync "sync"
 )
 
@@ -50,10 +50,10 @@ type SetLabelsRequest struct {
 	sizeCache     protoimpl.SizeCache
 	unknownFields protoimpl.UnknownFields
 
-	NfdVersion string                              `protobuf:"bytes,1,opt,name=nfd_version,json=nfdVersion,proto3" json:"nfd_version,omitempty"`
-	NodeName   string                              `protobuf:"bytes,2,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"`
-	Labels     map[string]string                   `protobuf:"bytes,3,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
-	Features   map[string]*v1alpha1.DomainFeatures `protobuf:"bytes,4,rep,name=features,proto3" json:"features,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	NfdVersion string                             `protobuf:"bytes,1,opt,name=nfd_version,json=nfdVersion,proto3" json:"nfd_version,omitempty"`
+	NodeName   string                             `protobuf:"bytes,2,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"`
+	Labels     map[string]string                  `protobuf:"bytes,3,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	Features   map[string]*feature.DomainFeatures `protobuf:"bytes,4,rep,name=features,proto3" json:"features,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
 }
 
 func (x *SetLabelsRequest) Reset() {
@@ -109,7 +109,7 @@ func (x *SetLabelsRequest) GetLabels() map[string]string {
 	return nil
 }
 
-func (x *SetLabelsRequest) GetFeatures() map[string]*v1alpha1.DomainFeatures {
+func (x *SetLabelsRequest) GetFeatures() map[string]*feature.DomainFeatures {
 	if x != nil {
 		return x.Features
 	}
@@ -158,42 +158,41 @@ var File_labeler_proto protoreflect.FileDescriptor
 
 var file_labeler_proto_rawDesc = []byte{
 	0x0a, 0x0d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
-	0x07, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x1a, 0x25, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70,
-	0x69, 0x73, 0x2f, 0x6e, 0x66, 0x64, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f,
-	0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22,
-	0xe6, 0x02, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x66, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x73,
-	0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x66, 0x64, 0x56, 0x65,
-	0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61,
-	0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61,
-	0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03,
-	0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x74,
-	0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61,
-	0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c,
-	0x73, 0x12, 0x43, 0x0a, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x04, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65,
-	0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46,
-	0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x66, 0x65,
-	0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73,
-	0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
-	0x01, 0x1a, 0x55, 0x0a, 0x0d, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x45, 0x6e, 0x74,
-	0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x44,
-	0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x05, 0x76,
-	0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x10, 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x4c,
-	0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x32, 0x4c, 0x0a, 0x07, 0x4c, 0x61,
-	0x62, 0x65, 0x6c, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x09, 0x53, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65,
-	0x6c, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x74,
-	0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e,
+	0x07, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x1a, 0x1f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70,
+	0x69, 0x2f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61,
+	0x74, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe5, 0x02, 0x0a, 0x10, 0x53, 0x65,
+	0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f,
+	0x0a, 0x0b, 0x6e, 0x66, 0x64, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0a, 0x6e, 0x66, 0x64, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
+	0x1b, 0x0a, 0x09, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x08, 0x6e, 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3d, 0x0a, 0x06,
+	0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6c,
+	0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e,
+	0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x43, 0x0a, 0x08, 0x66,
+	0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e,
 	0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c,
-	0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x30, 0x5a, 0x2e, 0x73, 0x69, 0x67, 0x73,
-	0x2e, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2d, 0x66, 0x65, 0x61,
-	0x74, 0x75, 0x72, 0x65, 0x2d, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2f, 0x70,
-	0x6b, 0x67, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x33,
+	0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65,
+	0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73,
+	0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
+	0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
+	0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x54, 0x0a, 0x0d, 0x46,
+	0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
+	0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d,
+	0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e,
+	0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2e, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x46, 0x65,
+	0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
+	0x01, 0x22, 0x10, 0x0a, 0x0e, 0x53, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65,
+	0x70, 0x6c, 0x79, 0x32, 0x4c, 0x0a, 0x07, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72, 0x12, 0x41,
+	0x0a, 0x09, 0x53, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x19, 0x2e, 0x6c, 0x61,
+	0x62, 0x65, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x65, 0x72,
+	0x2e, 0x53, 0x65, 0x74, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22,
+	0x00, 0x42, 0x30, 0x5a, 0x2e, 0x73, 0x69, 0x67, 0x73, 0x2e, 0x6b, 0x38, 0x73, 0x2e, 0x69, 0x6f,
+	0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x2d, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2d, 0x64, 0x69,
+	0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x79, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6c, 0x61, 0x62, 0x65,
+	0x6c, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -210,16 +209,16 @@ func file_labeler_proto_rawDescGZIP() []byte {
 
 var file_labeler_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
 var file_labeler_proto_goTypes = []interface{}{
-	(*SetLabelsRequest)(nil),        // 0: labeler.SetLabelsRequest
-	(*SetLabelsReply)(nil),          // 1: labeler.SetLabelsReply
-	nil,                             // 2: labeler.SetLabelsRequest.LabelsEntry
-	nil,                             // 3: labeler.SetLabelsRequest.FeaturesEntry
-	(*v1alpha1.DomainFeatures)(nil), // 4: v1alpha1.DomainFeatures
+	(*SetLabelsRequest)(nil),       // 0: labeler.SetLabelsRequest
+	(*SetLabelsReply)(nil),         // 1: labeler.SetLabelsReply
+	nil,                            // 2: labeler.SetLabelsRequest.LabelsEntry
+	nil,                            // 3: labeler.SetLabelsRequest.FeaturesEntry
+	(*feature.DomainFeatures)(nil), // 4: feature.DomainFeatures
 }
 var file_labeler_proto_depIdxs = []int32{
 	2, // 0: labeler.SetLabelsRequest.labels:type_name -> labeler.SetLabelsRequest.LabelsEntry
 	3, // 1: labeler.SetLabelsRequest.features:type_name -> labeler.SetLabelsRequest.FeaturesEntry
-	4, // 2: labeler.SetLabelsRequest.FeaturesEntry.value:type_name -> v1alpha1.DomainFeatures
+	4, // 2: labeler.SetLabelsRequest.FeaturesEntry.value:type_name -> feature.DomainFeatures
 	0, // 3: labeler.Labeler.SetLabels:input_type -> labeler.SetLabelsRequest
 	1, // 4: labeler.Labeler.SetLabels:output_type -> labeler.SetLabelsReply
 	4, // [4:5] is the sub-list for method output_type
diff --git a/pkg/labeler/labeler.proto b/pkg/labeler/labeler.proto
index e0119103d..6448e6044 100644
--- a/pkg/labeler/labeler.proto
+++ b/pkg/labeler/labeler.proto
@@ -18,7 +18,7 @@ syntax = "proto3";
 
 option go_package = "sigs.k8s.io/node-feature-discovery/pkg/labeler";
 
-import "pkg/apis/nfd/v1alpha1/generated.proto";
+import "pkg/api/feature/generated.proto";
 
 package labeler;
 
@@ -30,7 +30,7 @@ message SetLabelsRequest {
     string nfd_version = 1;
     string node_name = 2;
     map<string, string> labels = 3;
-    map<string, v1alpha1.DomainFeatures> features = 4;
+    map<string, feature.DomainFeatures> features = 4;
 }
 
 message SetLabelsReply {
diff --git a/pkg/nfd-client/topology-updater/nfd-topology-updater.go b/pkg/nfd-client/topology-updater/nfd-topology-updater.go
index baa8f378e..2e43e5117 100644
--- a/pkg/nfd-client/topology-updater/nfd-topology-updater.go
+++ b/pkg/nfd-client/topology-updater/nfd-topology-updater.go
@@ -126,15 +126,15 @@ func (w *nfdTopologyUpdater) Run() error {
 		return err
 	}
 
-	crTrigger := time.NewTicker(w.resourcemonitorArgs.SleepInterval)
+	crTrigger := time.After(0)
 	for {
 		select {
-		case <-crTrigger.C:
-			klog.Infof("Scanning")
+		case <-crTrigger:
+			klog.Infof("Scanning\n")
 			podResources, err := resScan.Scan()
 			utils.KlogDump(1, "podResources are", "  ", podResources)
 			if err != nil {
-				klog.Warningf("Scan failed: %v", err)
+				klog.Warningf("Scan failed: %v\n", err)
 				continue
 			}
 			zones = resAggr.Aggregate(podResources)
@@ -147,6 +147,10 @@ func (w *nfdTopologyUpdater) Run() error {
 				return nil
 			}
 
+			if w.resourcemonitorArgs.SleepInterval > 0 {
+				crTrigger = time.After(w.resourcemonitorArgs.SleepInterval)
+			}
+
 		case <-w.certWatch.Events:
 			klog.Infof("TLS certificate update, renewing connection to nfd-master")
 			w.Disconnect()
diff --git a/pkg/nfd-client/worker/nfd-worker.go b/pkg/nfd-client/worker/nfd-worker.go
index f97fade42..e80d954b6 100644
--- a/pkg/nfd-client/worker/nfd-worker.go
+++ b/pkg/nfd-client/worker/nfd-worker.go
@@ -31,7 +31,7 @@ import (
 	"k8s.io/klog/v2"
 	"sigs.k8s.io/yaml"
 
-	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	pb "sigs.k8s.io/node-feature-discovery/pkg/labeler"
 	clientcommon "sigs.k8s.io/node-feature-discovery/pkg/nfd-client"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils"
@@ -533,8 +533,8 @@ func getFeatureLabels(source source.LabelSource, labelWhiteList regexp.Regexp) (
 }
 
 // getFeatures returns raw features from all feature sources
-func getFeatures() map[string]*nfdv1alpha1.DomainFeatures {
-	features := make(map[string]*nfdv1alpha1.DomainFeatures)
+func getFeatures() map[string]*feature.DomainFeatures {
+	features := make(map[string]*feature.DomainFeatures)
 
 	for name, src := range source.GetAllFeatureSources() {
 		features[name] = src.GetFeatures()
diff --git a/pkg/nfd-master/nfd-master.go b/pkg/nfd-master/nfd-master.go
index 812aa3baf..fa7751d56 100644
--- a/pkg/nfd-master/nfd-master.go
+++ b/pkg/nfd-master/nfd-master.go
@@ -36,13 +36,14 @@ import (
 	"google.golang.org/grpc/health"
 	"google.golang.org/grpc/health/grpc_health_v1"
 	"google.golang.org/grpc/peer"
-	corev1 "k8s.io/api/core/v1"
+	api "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
 	restclient "k8s.io/client-go/rest"
 	"k8s.io/klog/v2"
 
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	"sigs.k8s.io/node-feature-discovery/pkg/apihelper"
 	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
 	pb "sigs.k8s.io/node-feature-discovery/pkg/labeler"
@@ -522,8 +523,8 @@ func (m *nfdMaster) crLabels(r *pb.SetLabelsRequest) map[string]string {
 			}
 
 			// Feed back rule output to features map for subsequent rules to match
-			nfdv1alpha1.InsertAttributeFeatures(r.Features, nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Labels)
-			nfdv1alpha1.InsertAttributeFeatures(r.Features, nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Vars)
+			feature.InsertAttributeFeatures(r.Features, nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Labels)
+			feature.InsertAttributeFeatures(r.Features, nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Vars)
 		}
 	}
 
@@ -627,7 +628,7 @@ func createPatches(removeKeys []string, oldItems map[string]string, newItems map
 
 // createExtendedResourcePatches returns a slice of operations to perform on
 // the node status
-func (m *nfdMaster) createExtendedResourcePatches(n *corev1.Node, extendedResources ExtendedResources) []apihelper.JsonPatch {
+func (m *nfdMaster) createExtendedResourcePatches(n *api.Node, extendedResources ExtendedResources) []apihelper.JsonPatch {
 	patches := []apihelper.JsonPatch{}
 
 	// Form a list of namespaced resource names managed by us
@@ -635,7 +636,7 @@ func (m *nfdMaster) createExtendedResourcePatches(n *corev1.Node, extendedResour
 
 	// figure out which resources to remove
 	for _, resource := range oldResources {
-		if _, ok := n.Status.Capacity[corev1.ResourceName(resource)]; ok {
+		if _, ok := n.Status.Capacity[api.ResourceName(resource)]; ok {
 			// check if the ext resource is still needed
 			if _, extResNeeded := extendedResources[resource]; !extResNeeded {
 				patches = append(patches, apihelper.NewJsonPatch("remove", "/status/capacity", resource, ""))
@@ -647,7 +648,7 @@ func (m *nfdMaster) createExtendedResourcePatches(n *corev1.Node, extendedResour
 	// figure out which resources to replace and which to add
 	for resource, value := range extendedResources {
 		// check if the extended resource already exists with the same capacity in the node
-		if quantity, ok := n.Status.Capacity[corev1.ResourceName(resource)]; ok {
+		if quantity, ok := n.Status.Capacity[api.ResourceName(resource)]; ok {
 			val, _ := quantity.AsInt64()
 			if strconv.FormatInt(val, 10) != value {
 				patches = append(patches, apihelper.NewJsonPatch("replace", "/status/capacity", resource, value))
diff --git a/pkg/resourcemonitor/noderesourcesaggregator.go b/pkg/resourcemonitor/noderesourcesaggregator.go
index 8b08c33ae..862f002db 100644
--- a/pkg/resourcemonitor/noderesourcesaggregator.go
+++ b/pkg/resourcemonitor/noderesourcesaggregator.go
@@ -25,7 +25,7 @@ import (
 
 	"github.com/jaypipes/ghw"
 	topologyv1alpha1 "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/apis/topology/v1alpha1"
-	corev1 "k8s.io/api/core/v1"
+	v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	"k8s.io/klog/v2"
 	podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1"
@@ -40,7 +40,7 @@ const (
 )
 
 type nodeResources struct {
-	perNUMAAllocatable map[int]map[corev1.ResourceName]int64
+	perNUMAAllocatable map[int]map[v1.ResourceName]int64
 	// mapping: resourceName -> resourceID -> nodeID
 	resourceID2NUMAID              map[string]map[string]int
 	topo                           *ghw.TopologyInfo
@@ -102,11 +102,11 @@ func NewResourcesAggregatorFromData(topo *ghw.TopologyInfo, resp *podresourcesap
 
 // Aggregate provides the mapping (numa zone name) -> Zone from the given PodResources.
 func (noderesourceData *nodeResources) Aggregate(podResData []PodResources) topologyv1alpha1.ZoneList {
-	perNuma := make(map[int]map[corev1.ResourceName]*resourceData)
+	perNuma := make(map[int]map[v1.ResourceName]*resourceData)
 	for nodeID := range noderesourceData.topo.Nodes {
 		nodeRes, ok := noderesourceData.perNUMAAllocatable[nodeID]
 		if ok {
-			perNuma[nodeID] = make(map[corev1.ResourceName]*resourceData)
+			perNuma[nodeID] = make(map[v1.ResourceName]*resourceData)
 			for resName, allocatable := range nodeRes {
 				switch {
 				case resName == "cpu":
@@ -115,7 +115,7 @@ func (noderesourceData *nodeResources) Aggregate(podResData []PodResources) topo
 						available:   allocatable,
 						capacity:    allocatable + int64(len(noderesourceData.reservedCPUIDPerNUMA[nodeID])),
 					}
-				case resName == corev1.ResourceMemory, strings.HasPrefix(string(resName), corev1.ResourceHugePagesPrefix):
+				case resName == v1.ResourceMemory, strings.HasPrefix(string(resName), v1.ResourceHugePagesPrefix):
 					var capacity int64
 					if _, ok := noderesourceData.memoryResourcesCapacityPerNUMA[nodeID]; !ok {
 						capacity = allocatable
@@ -141,7 +141,7 @@ func (noderesourceData *nodeResources) Aggregate(podResData []PodResources) topo
 			// NUMA node doesn't have any allocatable resources, but yet it exists in the topology
 			// thus all its CPUs are reserved
 		} else {
-			perNuma[nodeID] = make(map[corev1.ResourceName]*resourceData)
+			perNuma[nodeID] = make(map[v1.ResourceName]*resourceData)
 			perNuma[nodeID]["cpu"] = &resourceData{
 				allocatable: int64(0),
 				available:   int64(0),
@@ -153,7 +153,7 @@ func (noderesourceData *nodeResources) Aggregate(podResData []PodResources) topo
 	for _, podRes := range podResData {
 		for _, contRes := range podRes.Containers {
 			for _, res := range contRes.Resources {
-				if res.Name == corev1.ResourceMemory || strings.HasPrefix(string(res.Name), corev1.ResourceHugePagesPrefix) {
+				if res.Name == v1.ResourceMemory || strings.HasPrefix(string(res.Name), v1.ResourceHugePagesPrefix) {
 					noderesourceData.updateMemoryAvailable(perNuma, res)
 					continue
 				}
@@ -218,7 +218,7 @@ func getContainerDevicesFromAllocatableResources(availRes *podresourcesapi.Alloc
 
 	for nodeID, cpuList := range cpusPerNuma {
 		contDevs = append(contDevs, &podresourcesapi.ContainerDevices{
-			ResourceName: string(corev1.ResourceCPU),
+			ResourceName: string(v1.ResourceCPU),
 			DeviceIds:    cpuList,
 			Topology: &podresourcesapi.TopologyInfo{
 				Nodes: []*podresourcesapi.NUMANode{
@@ -233,7 +233,7 @@ func getContainerDevicesFromAllocatableResources(availRes *podresourcesapi.Alloc
 
 // updateAvailable computes the actually available resources.
 // This function assumes the available resources are initialized to be equal to the allocatable.
-func (noderesourceData *nodeResources) updateAvailable(numaData map[int]map[corev1.ResourceName]*resourceData, ri ResourceInfo) {
+func (noderesourceData *nodeResources) updateAvailable(numaData map[int]map[v1.ResourceName]*resourceData, ri ResourceInfo) {
 	for _, resID := range ri.Data {
 		resName := string(ri.Name)
 		resMap, ok := noderesourceData.resourceID2NUMAID[resName]
@@ -263,8 +263,8 @@ func makeZoneName(nodeID int) string {
 // makeNodeAllocatable computes the node allocatable as mapping (NUMA node ID) -> Resource -> Allocatable (amount, int).
 // The computation is done assuming all the resources to represent the allocatable for are represented on a slice
 // of ContainerDevices. No special treatment is done for CPU IDs. See getContainerDevicesFromAllocatableResources.
-func makeNodeAllocatable(devices []*podresourcesapi.ContainerDevices, memoryBlocks []*podresourcesapi.ContainerMemory) map[int]map[corev1.ResourceName]int64 {
-	perNUMAAllocatable := make(map[int]map[corev1.ResourceName]int64)
+func makeNodeAllocatable(devices []*podresourcesapi.ContainerDevices, memoryBlocks []*podresourcesapi.ContainerMemory) map[int]map[v1.ResourceName]int64 {
+	perNUMAAllocatable := make(map[int]map[v1.ResourceName]int64)
 	// initialize with the capacities
 	for _, device := range devices {
 		resourceName := device.GetResourceName()
@@ -272,15 +272,15 @@ func makeNodeAllocatable(devices []*podresourcesapi.ContainerDevices, memoryBloc
 			nodeID := int(node.GetID())
 			nodeRes, ok := perNUMAAllocatable[nodeID]
 			if !ok {
-				nodeRes = make(map[corev1.ResourceName]int64)
+				nodeRes = make(map[v1.ResourceName]int64)
 			}
-			nodeRes[corev1.ResourceName(resourceName)] += int64(len(device.GetDeviceIds()))
+			nodeRes[v1.ResourceName(resourceName)] += int64(len(device.GetDeviceIds()))
 			perNUMAAllocatable[nodeID] = nodeRes
 		}
 	}
 
 	for _, block := range memoryBlocks {
-		memoryType := corev1.ResourceName(block.GetMemoryType())
+		memoryType := v1.ResourceName(block.GetMemoryType())
 
 		blockTopology := block.GetTopology()
 		if blockTopology == nil {
@@ -290,7 +290,7 @@ func makeNodeAllocatable(devices []*podresourcesapi.ContainerDevices, memoryBloc
 		for _, node := range blockTopology.GetNodes() {
 			nodeID := int(node.GetID())
 			if _, ok := perNUMAAllocatable[nodeID]; !ok {
-				perNUMAAllocatable[nodeID] = make(map[corev1.ResourceName]int64)
+				perNUMAAllocatable[nodeID] = make(map[v1.ResourceName]int64)
 			}
 
 			if _, ok := perNUMAAllocatable[nodeID][memoryType]; !ok {
@@ -402,7 +402,7 @@ func getCPUs(devices []*podresourcesapi.ContainerDevices) map[string]int {
 
 // updateMemoryAvailable computes the actual amount of the available memory.
 // This function assumes the available resources are initialized to be equal to the capacity.
-func (noderesourceData *nodeResources) updateMemoryAvailable(numaData map[int]map[corev1.ResourceName]*resourceData, ri ResourceInfo) {
+func (noderesourceData *nodeResources) updateMemoryAvailable(numaData map[int]map[v1.ResourceName]*resourceData, ri ResourceInfo) {
 	if len(ri.NumaNodeIds) == 0 {
 		klog.Warningf("no NUMA nodes information is available for device %q", ri.Name)
 		return
@@ -469,7 +469,7 @@ func getMemoryResourcesCapacity() (utils.NumaMemoryResources, error) {
 	capacity := make(utils.NumaMemoryResources)
 	for numaID, resources := range memoryResources {
 		if _, ok := capacity[numaID]; !ok {
-			capacity[numaID] = map[corev1.ResourceName]int64{}
+			capacity[numaID] = map[v1.ResourceName]int64{}
 		}
 
 		for resourceName, value := range resources {
diff --git a/pkg/resourcemonitor/podresourcesscanner.go b/pkg/resourcemonitor/podresourcesscanner.go
index a42801efc..4c8b4acc1 100644
--- a/pkg/resourcemonitor/podresourcesscanner.go
+++ b/pkg/resourcemonitor/podresourcesscanner.go
@@ -21,7 +21,7 @@ import (
 	"fmt"
 	"strconv"
 
-	corev1 "k8s.io/api/core/v1"
+	v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	"k8s.io/klog/v2"
 	podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1"
@@ -75,13 +75,13 @@ func (resMon *PodResourcesScanner) isWatchable(podNamespace string, podName stri
 // hasExclusiveCPUs returns true if a guaranteed pod is allocated exclusive CPUs else returns false.
 // In isWatchable() function we check for the pod QoS and proceed if it is guaranteed (i.e. request == limit)
 // and hence we only check for request in the function below.
-func hasExclusiveCPUs(pod *corev1.Pod) bool {
+func hasExclusiveCPUs(pod *v1.Pod) bool {
 	var totalCPU int64
 	var cpuQuantity resource.Quantity
 	for _, container := range pod.Spec.InitContainers {
 
 		var ok bool
-		if cpuQuantity, ok = container.Resources.Requests[corev1.ResourceCPU]; !ok {
+		if cpuQuantity, ok = container.Resources.Requests[v1.ResourceCPU]; !ok {
 			continue
 		}
 		totalCPU += cpuQuantity.Value()
@@ -92,7 +92,7 @@ func hasExclusiveCPUs(pod *corev1.Pod) bool {
 	}
 	for _, container := range pod.Spec.Containers {
 		var ok bool
-		if cpuQuantity, ok = container.Resources.Requests[corev1.ResourceCPU]; !ok {
+		if cpuQuantity, ok = container.Resources.Requests[v1.ResourceCPU]; !ok {
 			continue
 		}
 		totalCPU += cpuQuantity.Value()
@@ -107,8 +107,8 @@ func hasExclusiveCPUs(pod *corev1.Pod) bool {
 }
 
 // hasIntegralCPUs returns true if a container in pod is requesting integral CPUs else returns false
-func hasIntegralCPUs(pod *corev1.Pod, container *corev1.Container) bool {
-	cpuQuantity := container.Resources.Requests[corev1.ResourceCPU]
+func hasIntegralCPUs(pod *v1.Pod, container *v1.Container) bool {
+	cpuQuantity := container.Resources.Requests[v1.ResourceCPU]
 	return cpuQuantity.Value()*1000 == cpuQuantity.MilliValue()
 }
 
@@ -155,7 +155,7 @@ func (resMon *PodResourcesScanner) Scan() ([]PodResources, error) {
 					}
 					contRes.Resources = []ResourceInfo{
 						{
-							Name: corev1.ResourceCPU,
+							Name: v1.ResourceCPU,
 							Data: resCPUs,
 						},
 					}
@@ -165,7 +165,7 @@ func (resMon *PodResourcesScanner) Scan() ([]PodResources, error) {
 			for _, device := range container.GetDevices() {
 				numaNodesIDs := getNumaNodeIds(device.GetTopology())
 				contRes.Resources = append(contRes.Resources, ResourceInfo{
-					Name:        corev1.ResourceName(device.ResourceName),
+					Name:        v1.ResourceName(device.ResourceName),
 					Data:        device.DeviceIds,
 					NumaNodeIds: numaNodesIDs,
 				})
@@ -178,7 +178,7 @@ func (resMon *PodResourcesScanner) Scan() ([]PodResources, error) {
 
 				topology := getNumaNodeIds(block.GetTopology())
 				contRes.Resources = append(contRes.Resources, ResourceInfo{
-					Name:        corev1.ResourceName(block.MemoryType),
+					Name:        v1.ResourceName(block.MemoryType),
 					Data:        []string{fmt.Sprintf("%d", block.GetSize_())},
 					NumaNodeIds: topology,
 				})
diff --git a/pkg/utils/memory_resources.go b/pkg/utils/memory_resources.go
index fa2eea0ca..350955e96 100644
--- a/pkg/utils/memory_resources.go
+++ b/pkg/utils/memory_resources.go
@@ -23,7 +23,7 @@ import (
 	"strconv"
 	"strings"
 
-	corev1 "k8s.io/api/core/v1"
+	v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	"k8s.io/klog/v2"
 	resourcehelper "k8s.io/kubernetes/pkg/apis/core/helper"
@@ -40,7 +40,7 @@ var (
 type NumaMemoryResources map[int]MemoryResourceInfo
 
 // MemoryResourceInfo holds information of memory resources per resource type.
-type MemoryResourceInfo map[corev1.ResourceName]int64
+type MemoryResourceInfo map[v1.ResourceName]int64
 
 // GetNumaMemoryResources returns total amount of memory and hugepages under NUMA nodes
 func GetNumaMemoryResources() (NumaMemoryResources, error) {
@@ -64,7 +64,7 @@ func GetNumaMemoryResources() (NumaMemoryResources, error) {
 		if err != nil {
 			return nil, err
 		}
-		info[corev1.ResourceMemory] = nodeTotalMemory
+		info[v1.ResourceMemory] = nodeTotalMemory
 
 		// Get hugepages
 		hugepageBytes, err := getHugepagesBytes(filepath.Join(sysBusNodeBasepath, numaNode, "hugepages"))
@@ -112,7 +112,7 @@ func getHugepagesBytes(path string) (MemoryResourceInfo, error) {
 		}
 
 		size, _ := q.AsInt64()
-		name := corev1.ResourceName(resourcehelper.HugePageResourceName(q))
+		name := v1.ResourceName(resourcehelper.HugePageResourceName(q))
 		hugepagesBytes[name] = nr * size
 	}
 
diff --git a/source/cpu/cpu.go b/source/cpu/cpu.go
index b2db7d8e0..62d14af30 100644
--- a/source/cpu/cpu.go
+++ b/source/cpu/cpu.go
@@ -24,7 +24,7 @@ import (
 
 	"github.com/klauspost/cpuid/v2"
 
-	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils/hostpath"
 	"sigs.k8s.io/node-feature-discovery/source"
@@ -102,7 +102,7 @@ type keyFilter struct {
 type cpuSource struct {
 	config      *Config
 	cpuidFilter *keyFilter
-	features    *nfdv1alpha1.DomainFeatures
+	features    *feature.DomainFeatures
 }
 
 // Singleton source instance
@@ -197,20 +197,20 @@ func (s *cpuSource) GetLabels() (source.FeatureLabels, error) {
 
 // Discover method of the FeatureSource Interface
 func (s *cpuSource) Discover() error {
-	s.features = nfdv1alpha1.NewDomainFeatures()
+	s.features = feature.NewDomainFeatures()
 
 	// Detect CPUID
-	s.features.Flags[CpuidFeature] = nfdv1alpha1.NewFlagFeatures(getCpuidFlags()...)
+	s.features.Flags[CpuidFeature] = feature.NewFlagFeatures(getCpuidFlags()...)
 
 	// Detect CPU model
-	s.features.Attributes[Cpumodel] = nfdv1alpha1.NewAttributeFeatures(getCPUModel())
+	s.features.Attributes[Cpumodel] = feature.NewAttributeFeatures(getCPUModel())
 
 	// Detect cstate configuration
 	cstate, err := detectCstate()
 	if err != nil {
 		klog.Errorf("failed to detect cstate: %v", err)
 	} else {
-		s.features.Attributes[CstateFeature] = nfdv1alpha1.NewAttributeFeatures(cstate)
+		s.features.Attributes[CstateFeature] = feature.NewAttributeFeatures(cstate)
 	}
 
 	// Detect pstate features
@@ -218,33 +218,33 @@ func (s *cpuSource) Discover() error {
 	if err != nil {
 		klog.Error(err)
 	}
-	s.features.Attributes[PstateFeature] = nfdv1alpha1.NewAttributeFeatures(pstate)
+	s.features.Attributes[PstateFeature] = feature.NewAttributeFeatures(pstate)
 
 	// Detect RDT features
-	s.features.Flags[RdtFeature] = nfdv1alpha1.NewFlagFeatures(discoverRDT()...)
+	s.features.Flags[RdtFeature] = feature.NewFlagFeatures(discoverRDT()...)
 
 	// Detect SGX features
-	s.features.Attributes[SecurityFeature] = nfdv1alpha1.NewAttributeFeatures(discoverSecurity())
+	s.features.Attributes[SecurityFeature] = feature.NewAttributeFeatures(discoverSecurity())
 
 	// Detect SGX features
 	//
 	// DEPRECATED in v0.12: will be removed in the future
 	if val, ok := s.features.Attributes[SecurityFeature].Elements["sgx.enabled"]; ok {
-		s.features.Attributes[SgxFeature] = nfdv1alpha1.NewAttributeFeatures(map[string]string{"enabled": val})
+		s.features.Attributes[SgxFeature] = feature.NewAttributeFeatures(map[string]string{"enabled": val})
 	}
 
 	// Detect Secure Execution features
 	//
 	// DEPRECATED in v0.12: will be removed in the future
 	if val, ok := s.features.Attributes[SecurityFeature].Elements["se.enabled"]; ok {
-		s.features.Attributes[SeFeature] = nfdv1alpha1.NewAttributeFeatures(map[string]string{"enabled": val})
+		s.features.Attributes[SeFeature] = feature.NewAttributeFeatures(map[string]string{"enabled": val})
 	}
 
 	// Detect SST features
-	s.features.Attributes[SstFeature] = nfdv1alpha1.NewAttributeFeatures(discoverSST())
+	s.features.Attributes[SstFeature] = feature.NewAttributeFeatures(discoverSST())
 
 	// Detect hyper-threading
-	s.features.Attributes[TopologyFeature] = nfdv1alpha1.NewAttributeFeatures(discoverTopology())
+	s.features.Attributes[TopologyFeature] = feature.NewAttributeFeatures(discoverTopology())
 
 	utils.KlogDump(3, "discovered cpu features:", "  ", s.features)
 
@@ -252,9 +252,9 @@ func (s *cpuSource) Discover() error {
 }
 
 // GetFeatures method of the FeatureSource Interface
-func (s *cpuSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
+func (s *cpuSource) GetFeatures() *feature.DomainFeatures {
 	if s.features == nil {
-		s.features = nfdv1alpha1.NewDomainFeatures()
+		s.features = feature.NewDomainFeatures()
 	}
 	return s.features
 }
diff --git a/source/cpu/cpuid_arm.go b/source/cpu/cpuid_arm.go
index 214986a21..6a142e913 100644
--- a/source/cpu/cpuid_arm.go
+++ b/source/cpu/cpuid_arm.go
@@ -26,10 +26,7 @@ unsigned long gethwcap() {
 */
 import "C"
 
-/*
-all special features for arm should be defined here; canonical list:
-https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm/include/uapi/asm/hwcap.h
-*/
+/* all special features for arm should be defined here */
 const (
 	/* extension instructions */
 	CPU_ARM_FEATURE_SWP = 1 << iota
@@ -98,8 +95,8 @@ func getCpuidFlags() []string {
 	hwcap := uint64(C.gethwcap())
 	for i := uint(0); i < 64; i++ {
 		key := uint64(1 << i)
-		val, ok := flagNames_arm[key]
-		if hwcap&key != 0 && ok {
+		val := flagNames_arm[key]
+		if hwcap&key != 0 {
 			r = append(r, val)
 		}
 	}
diff --git a/source/cpu/cpuid_arm64.go b/source/cpu/cpuid_arm64.go
index c8d6a91a0..e4175ae49 100644
--- a/source/cpu/cpuid_arm64.go
+++ b/source/cpu/cpuid_arm64.go
@@ -23,16 +23,10 @@ package cpu
 unsigned long gethwcap() {
 	return getauxval(AT_HWCAP);
 }
-unsigned long gethwcap2() {
-	return getauxval(AT_HWCAP2);
-}
 */
 import "C"
 
-/*
-all special features for arm64 should be defined here; canonical list:
-https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/include/uapi/asm/hwcap.h
-*/
+/* all special features for arm64 should be defined here */
 const (
 	/* extension instructions */
 	CPU_ARM64_FEATURE_FP = 1 << iota
@@ -58,53 +52,6 @@ const (
 	CPU_ARM64_FEATURE_ASIMDDP
 	CPU_ARM64_FEATURE_SHA512
 	CPU_ARM64_FEATURE_SVE
-	CPU_ARM64_FEATURE_ASIMDFHM
-	CPU_ARM64_FEATURE_DIT
-	CPU_ARM64_FEATURE_USCAT
-	CPU_ARM64_FEATURE_ILRCPC
-	CPU_ARM64_FEATURE_FLAGM
-	CPU_ARM64_FEATURE_SSBS
-	CPU_ARM64_FEATURE_SB
-	CPU_ARM64_FEATURE_PACA
-	CPU_ARM64_FEATURE_PACG
-)
-
-const (
-	/* extension instructions */
-	CPU_ARM64_FEATURE2_DCPODP = 1 << iota
-	CPU_ARM64_FEATURE2_SVE2
-	CPU_ARM64_FEATURE2_SVEAES
-	CPU_ARM64_FEATURE2_SVEPMULL
-	CPU_ARM64_FEATURE2_SVEBITPERM
-	CPU_ARM64_FEATURE2_SVESHA3
-	CPU_ARM64_FEATURE2_SVESM4
-	CPU_ARM64_FEATURE2_FLAGM2
-	CPU_ARM64_FEATURE2_FRINT
-	CPU_ARM64_FEATURE2_SVEI8MM
-	CPU_ARM64_FEATURE2_SVEF32MM
-	CPU_ARM64_FEATURE2_SVEF64MM
-	CPU_ARM64_FEATURE2_SVEBF16
-	CPU_ARM64_FEATURE2_I8MM
-	CPU_ARM64_FEATURE2_BF16
-	CPU_ARM64_FEATURE2_DGH
-	CPU_ARM64_FEATURE2_RNG
-	CPU_ARM64_FEATURE2_BTI
-	CPU_ARM64_FEATURE2_MTE
-	CPU_ARM64_FEATURE2_ECV
-	CPU_ARM64_FEATURE2_AFP
-	CPU_ARM64_FEATURE2_RPRES
-	CPU_ARM64_FEATURE2_MTE3
-	CPU_ARM64_FEATURE2_SME
-	CPU_ARM64_FEATURE2_SME_I16I64
-	CPU_ARM64_FEATURE2_SME_F64F64
-	CPU_ARM64_FEATURE2_SME_I8I32
-	CPU_ARM64_FEATURE2_SME_F16F32
-	CPU_ARM64_FEATURE2_SME_B16F32
-	CPU_ARM64_FEATURE2_SME_F32F32
-	CPU_ARM64_FEATURE2_SME_FA64
-	CPU_ARM64_FEATURE2_WFXT
-	CPU_ARM64_FEATURE2_EBF16
-	CPU_ARM64_FEATURE2_SVE_EBF16
 )
 
 var flagNames_arm64 = map[uint64]string{
@@ -131,69 +78,15 @@ var flagNames_arm64 = map[uint64]string{
 	CPU_ARM64_FEATURE_ASIMDDP:  "ASIMDDP",
 	CPU_ARM64_FEATURE_SHA512:   "SHA512",
 	CPU_ARM64_FEATURE_SVE:      "SVE",
-	CPU_ARM64_FEATURE_ASIMDFHM: "ASIMDFHM",
-	CPU_ARM64_FEATURE_DIT:      "DIT",
-	CPU_ARM64_FEATURE_USCAT:    "USCAT",
-	CPU_ARM64_FEATURE_ILRCPC:   "ILRCPC",
-	CPU_ARM64_FEATURE_FLAGM:    "FLAGM",
-	CPU_ARM64_FEATURE_SSBS:     "SSBS",
-	CPU_ARM64_FEATURE_SB:       "SB",
-	CPU_ARM64_FEATURE_PACA:     "PACA",
-	CPU_ARM64_FEATURE_PACG:     "PACG",
-}
-
-var flag2Names_arm64 = map[uint64]string{
-	CPU_ARM64_FEATURE2_DCPODP:     "DCPODP",
-	CPU_ARM64_FEATURE2_SVE2:       "SVE2",
-	CPU_ARM64_FEATURE2_SVEAES:     "SVEAES",
-	CPU_ARM64_FEATURE2_SVEPMULL:   "SVEPMULL",
-	CPU_ARM64_FEATURE2_SVEBITPERM: "SVEBITPERM",
-	CPU_ARM64_FEATURE2_SVESHA3:    "SVESHA3",
-	CPU_ARM64_FEATURE2_SVESM4:     "SVESM4",
-	CPU_ARM64_FEATURE2_FLAGM2:     "FLAGM2",
-	CPU_ARM64_FEATURE2_FRINT:      "FRINT",
-	CPU_ARM64_FEATURE2_SVEI8MM:    "SVEI8MM",
-	CPU_ARM64_FEATURE2_SVEF32MM:   "SVEF32MM",
-	CPU_ARM64_FEATURE2_SVEF64MM:   "SVEF64MM",
-	CPU_ARM64_FEATURE2_SVEBF16:    "SVEBF16",
-	CPU_ARM64_FEATURE2_I8MM:       "I8MM",
-	CPU_ARM64_FEATURE2_BF16:       "BF16",
-	CPU_ARM64_FEATURE2_DGH:        "DGH",
-	CPU_ARM64_FEATURE2_RNG:        "RNG",
-	CPU_ARM64_FEATURE2_BTI:        "BTI",
-	CPU_ARM64_FEATURE2_MTE:        "MTE",
-	CPU_ARM64_FEATURE2_ECV:        "ECV",
-	CPU_ARM64_FEATURE2_AFP:        "AFP",
-	CPU_ARM64_FEATURE2_RPRES:      "RPRES",
-	CPU_ARM64_FEATURE2_MTE3:       "MTE3",
-	CPU_ARM64_FEATURE2_SME:        "SME",
-	CPU_ARM64_FEATURE2_SME_I16I64: "SMEI16I64",
-	CPU_ARM64_FEATURE2_SME_F64F64: "SMEF64F64",
-	CPU_ARM64_FEATURE2_SME_I8I32:  "SMEI8I32",
-	CPU_ARM64_FEATURE2_SME_F16F32: "SMEF16F32",
-	CPU_ARM64_FEATURE2_SME_B16F32: "SMEB16F32",
-	CPU_ARM64_FEATURE2_SME_F32F32: "SMEF32F32",
-	CPU_ARM64_FEATURE2_SME_FA64:   "SMEFA64",
-	CPU_ARM64_FEATURE2_WFXT:       "WFXT",
-	CPU_ARM64_FEATURE2_EBF16:      "EBF16",
-	CPU_ARM64_FEATURE2_SVE_EBF16:  "SVEEBF16",
 }
 
 func getCpuidFlags() []string {
 	r := make([]string, 0, 20)
 	hwcap := uint64(C.gethwcap())
-	hwcap2 := uint64(C.gethwcap2())
-	for i := uint(0); i < 64; i++ {
-		key := uint64(1 << i)
-		val, ok := flagNames_arm64[key]
-		if hwcap&key != 0 && ok {
-			r = append(r, val)
-		}
-	}
 	for i := uint(0); i < 64; i++ {
 		key := uint64(1 << i)
-		val, ok := flag2Names_arm64[key]
-		if hwcap2&key != 0 && ok {
+		val := flagNames_arm64[key]
+		if hwcap&key != 0 {
 			r = append(r, val)
 		}
 	}
diff --git a/source/cpu/cpuid_ppc64le.go b/source/cpu/cpuid_ppc64le.go
index 9466e74f2..307739717 100644
--- a/source/cpu/cpuid_ppc64le.go
+++ b/source/cpu/cpuid_ppc64le.go
@@ -28,10 +28,7 @@ unsigned long gethwcap2() {
 */
 import "C"
 
-/*
-all special features for ppc64le should be defined here; canonical list:
-https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/powerpc/include/uapi/asm/cputable.h
-*/
+/* all special features for ppc64le should be defined here */
 const (
 	/* AT_HWCAP features */
 	PPC_FEATURE_32                     = 0x80000000 /* 32-bit mode. */
@@ -80,8 +77,6 @@ const (
 	PPC_FEATURE2_DARN           = 0x00200000 /* darn instruction.  */
 	PPC_FEATURE2_SCV            = 0x00100000 /* scv syscall.  */
 	PPC_FEATURE2_HTM_NO_SUSPEND = 0x00080000 /* TM without suspended state.  */
-	PPC_FEATURE2_ARCH_3_1       = 0x00040000 /* ISA 3.1 */
-	PPC_FEATURE2_MMA            = 0x00020000 /* Matrix Multiply Assist */
 )
 
 var flagNames_ppc64le = map[uint64]string{
@@ -129,8 +124,6 @@ var flag2Names_ppc64le = map[uint64]string{
 	PPC_FEATURE2_DARN:           "DARN",
 	PPC_FEATURE2_SCV:            "SCV",
 	PPC_FEATURE2_HTM_NO_SUSPEND: "HTM-NO-SUSPEND",
-	PPC_FEATURE2_ARCH_3_1:       "ARCH_3_1",
-	PPC_FEATURE2_MMA:            "MMA",
 }
 
 func getCpuidFlags() []string {
@@ -139,15 +132,15 @@ func getCpuidFlags() []string {
 	hwcap2 := uint64(C.gethwcap2())
 	for i := uint(0); i < 64; i++ {
 		key := uint64(1 << i)
-		val, ok := flagNames_ppc64le[key]
-		if hwcap&key != 0 && ok {
+		val := flagNames_ppc64le[key]
+		if hwcap&key != 0 {
 			r = append(r, val)
 		}
 	}
 	for i := uint(0); i < 64; i++ {
 		key := uint64(1 << i)
-		val, ok := flag2Names_ppc64le[key]
-		if hwcap2&key != 0 && ok {
+		val := flag2Names_ppc64le[key]
+		if hwcap2&key != 0 {
 			r = append(r, val)
 		}
 	}
diff --git a/source/cpu/cpuid_s390x.go b/source/cpu/cpuid_s390x.go
index ab35c6b6b..339761834 100644
--- a/source/cpu/cpuid_s390x.go
+++ b/source/cpu/cpuid_s390x.go
@@ -25,11 +25,7 @@ unsigned long gethwcap() {
 */
 import "C"
 
-/*
-all special features for s390x should be defined here; canonical list:
-https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/s390/include/asm/elf.h
-http://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/s390/bits/hwcap.h;hb=HEAD
-*/
+/* all special features for s390x should be defined here */
 const (
 	/* AT_HWCAP features */
 	HWCAP_S390_ESAN3     = 1
@@ -51,10 +47,10 @@ const (
 	HWCAP_S390_VXRS_PDE  = 65536
 	HWCAP_S390_SORT      = 131072
 	HWCAP_S390_DFLT      = 262144
-	HWCAP_S390_VXRS_PDE2 = 524288
-	HWCAP_S390_NNPA      = 1048576
-	HWCAP_S390_PCI_MIO   = 2097152
-	HWCAP_S390_SIE       = 4194304
+	HWCAP_NR_VXRS_PDE2   = 524288
+	HWCAP_NR_NNPA        = 1048576
+	HWCAP_NR_PCI_MIO     = 2097152
+	HWCAP_NR_SIE         = 4194304
 )
 
 var flagNames_s390x = map[uint64]string{
@@ -77,10 +73,10 @@ var flagNames_s390x = map[uint64]string{
 	HWCAP_S390_VXRS_PDE:  "VXP",
 	HWCAP_S390_SORT:      "SORT",
 	HWCAP_S390_DFLT:      "DFLT",
-	HWCAP_S390_VXRS_PDE2: "VXP2",
-	HWCAP_S390_NNPA:      "NNPA",
-	HWCAP_S390_PCI_MIO:   "PCIMIO",
-	HWCAP_S390_SIE:       "SIE",
+	HWCAP_NR_VXRS_PDE2:   "VXP2",
+	HWCAP_NR_NNPA:        "NNPA",
+	HWCAP_NR_PCI_MIO:     "PCIMIO",
+	HWCAP_NR_SIE:         "SIE",
 }
 
 func getCpuidFlags() []string {
@@ -88,8 +84,8 @@ func getCpuidFlags() []string {
 	hwcap := uint64(C.gethwcap())
 	for i := uint(0); i < 64; i++ {
 		key := uint64(1 << i)
-		val, ok := flagNames_s390x[key]
-		if hwcap&key != 0 && ok {
+		val := flagNames_s390x[key]
+		if hwcap&key != 0 {
 			r = append(r, val)
 		}
 	}
diff --git a/source/custom/custom.go b/source/custom/custom.go
index 80e374060..9b2484e95 100644
--- a/source/custom/custom.go
+++ b/source/custom/custom.go
@@ -25,6 +25,7 @@ import (
 	"k8s.io/klog/v2"
 	"sigs.k8s.io/yaml"
 
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils"
 	"sigs.k8s.io/node-feature-discovery/source"
@@ -107,7 +108,7 @@ func (s *customSource) Priority() int { return 10 }
 // GetLabels method of the LabelSource interface
 func (s *customSource) GetLabels() (source.FeatureLabels, error) {
 	// Get raw features from all sources
-	domainFeatures := make(map[string]*nfdv1alpha1.DomainFeatures)
+	domainFeatures := make(map[string]*feature.DomainFeatures)
 	for n, s := range source.GetAllFeatureSources() {
 		domainFeatures[n] = s.GetFeatures()
 	}
@@ -128,13 +129,13 @@ func (s *customSource) GetLabels() (source.FeatureLabels, error) {
 			labels[n] = v
 		}
 		// Feed back rule output to features map for subsequent rules to match
-		nfdv1alpha1.InsertAttributeFeatures(domainFeatures, nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Labels)
-		nfdv1alpha1.InsertAttributeFeatures(domainFeatures, nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Vars)
+		feature.InsertAttributeFeatures(domainFeatures, nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Labels)
+		feature.InsertAttributeFeatures(domainFeatures, nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Vars)
 	}
 	return labels, nil
 }
 
-func (r *CustomRule) execute(features map[string]*nfdv1alpha1.DomainFeatures) (nfdv1alpha1.RuleOutput, error) {
+func (r *CustomRule) execute(features map[string]*feature.DomainFeatures) (nfdv1alpha1.RuleOutput, error) {
 	if r.LegacyRule != nil {
 		ruleOut, err := r.LegacyRule.execute(features)
 		if err != nil {
@@ -154,7 +155,7 @@ func (r *CustomRule) execute(features map[string]*nfdv1alpha1.DomainFeatures) (n
 	return nfdv1alpha1.RuleOutput{}, fmt.Errorf("BUG: an empty rule, this really should not happen")
 }
 
-func (r *LegacyRule) execute(features map[string]*nfdv1alpha1.DomainFeatures) (map[string]string, error) {
+func (r *LegacyRule) execute(features map[string]*feature.DomainFeatures) (map[string]string, error) {
 	if len(r.MatchOn) > 0 {
 		// Logical OR over the legacy rules
 		matched := false
diff --git a/source/fake/fake.go b/source/fake/fake.go
index 9a155f6aa..d1d71393c 100644
--- a/source/fake/fake.go
+++ b/source/fake/fake.go
@@ -19,7 +19,7 @@ package fake
 import (
 	"fmt"
 
-	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils"
 	"sigs.k8s.io/node-feature-discovery/source"
 )
@@ -84,7 +84,7 @@ func newDefaultConfig() *Config {
 // fakeSource implements the FeatureSource, LabelSource and ConfigurableSource interfaces.
 type fakeSource struct {
 	config   *Config
-	features *nfdv1alpha1.DomainFeatures
+	features *feature.DomainFeatures
 }
 
 // Singleton source instance
@@ -116,16 +116,16 @@ func (s *fakeSource) SetConfig(conf source.Config) {
 
 // Discover method of the FeatureSource interface
 func (s *fakeSource) Discover() error {
-	s.features = nfdv1alpha1.NewDomainFeatures()
+	s.features = feature.NewDomainFeatures()
 
-	s.features.Flags[FlagFeature] = nfdv1alpha1.NewFlagFeatures(s.config.FlagFeatures...)
-	s.features.Attributes[AttributeFeature] = nfdv1alpha1.NewAttributeFeatures(s.config.AttributeFeatures)
+	s.features.Flags[FlagFeature] = feature.NewFlagFeatures(s.config.FlagFeatures...)
+	s.features.Attributes[AttributeFeature] = feature.NewAttributeFeatures(s.config.AttributeFeatures)
 
-	instances := make([]nfdv1alpha1.InstanceFeature, len(s.config.InstanceFeatures))
+	instances := make([]feature.InstanceFeature, len(s.config.InstanceFeatures))
 	for i, instanceAttributes := range s.config.InstanceFeatures {
-		instances[i] = *nfdv1alpha1.NewInstanceFeature(instanceAttributes)
+		instances[i] = *feature.NewInstanceFeature(instanceAttributes)
 	}
-	s.features.Instances[InstanceFeature] = nfdv1alpha1.NewInstanceFeatures(instances)
+	s.features.Instances[InstanceFeature] = feature.NewInstanceFeatures(instances)
 
 	utils.KlogDump(3, "discovered fake features:", "  ", s.features)
 
@@ -133,9 +133,9 @@ func (s *fakeSource) Discover() error {
 }
 
 // GetFeatures method of the FeatureSource Interface.
-func (s *fakeSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
+func (s *fakeSource) GetFeatures() *feature.DomainFeatures {
 	if s.features == nil {
-		s.features = nfdv1alpha1.NewDomainFeatures()
+		s.features = feature.NewDomainFeatures()
 	}
 	return s.features
 }
diff --git a/source/kernel/kernel.go b/source/kernel/kernel.go
index a96041104..f2299e240 100644
--- a/source/kernel/kernel.go
+++ b/source/kernel/kernel.go
@@ -21,7 +21,7 @@ import (
 
 	"k8s.io/klog/v2"
 
-	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils"
 	"sigs.k8s.io/node-feature-discovery/source"
 )
@@ -58,7 +58,7 @@ func newDefaultConfig() *Config {
 // kernelSource implements the FeatureSource, LabelSource and ConfigurableSource interfaces.
 type kernelSource struct {
 	config   *Config
-	features *nfdv1alpha1.DomainFeatures
+	features *feature.DomainFeatures
 	// legacyKconfig contains mangled kconfig values used for
 	// kernel.config-<flag> labels and legacy kConfig custom rules.
 	legacyKconfig map[string]string
@@ -117,13 +117,13 @@ func (s *kernelSource) GetLabels() (source.FeatureLabels, error) {
 
 // Discover method of the FeatureSource interface
 func (s *kernelSource) Discover() error {
-	s.features = nfdv1alpha1.NewDomainFeatures()
+	s.features = feature.NewDomainFeatures()
 
 	// Read kernel version
 	if version, err := parseVersion(); err != nil {
 		klog.Errorf("failed to get kernel version: %s", err)
 	} else {
-		s.features.Attributes[VersionFeature] = nfdv1alpha1.NewAttributeFeatures(version)
+		s.features.Attributes[VersionFeature] = feature.NewAttributeFeatures(version)
 	}
 
 	// Read kconfig
@@ -131,20 +131,20 @@ func (s *kernelSource) Discover() error {
 		s.legacyKconfig = nil
 		klog.Errorf("failed to read kconfig: %s", err)
 	} else {
-		s.features.Attributes[ConfigFeature] = nfdv1alpha1.NewAttributeFeatures(realKconfig)
+		s.features.Attributes[ConfigFeature] = feature.NewAttributeFeatures(realKconfig)
 		s.legacyKconfig = legacyKconfig
 	}
 
 	if kmods, err := getLoadedModules(); err != nil {
 		klog.Errorf("failed to get loaded kernel modules: %v", err)
 	} else {
-		s.features.Flags[LoadedModuleFeature] = nfdv1alpha1.NewFlagFeatures(kmods...)
+		s.features.Flags[LoadedModuleFeature] = feature.NewFlagFeatures(kmods...)
 	}
 
 	if selinux, err := SelinuxEnabled(); err != nil {
 		klog.Warning(err)
 	} else {
-		s.features.Attributes[SelinuxFeature] = nfdv1alpha1.NewAttributeFeatures(nil)
+		s.features.Attributes[SelinuxFeature] = feature.NewAttributeFeatures(nil)
 		s.features.Attributes[SelinuxFeature].Elements["enabled"] = strconv.FormatBool(selinux)
 	}
 
@@ -153,9 +153,9 @@ func (s *kernelSource) Discover() error {
 	return nil
 }
 
-func (s *kernelSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
+func (s *kernelSource) GetFeatures() *feature.DomainFeatures {
 	if s.features == nil {
-		s.features = nfdv1alpha1.NewDomainFeatures()
+		s.features = feature.NewDomainFeatures()
 	}
 	return s.features
 }
diff --git a/source/local/local.go b/source/local/local.go
index 2187d0b27..99ce32339 100644
--- a/source/local/local.go
+++ b/source/local/local.go
@@ -26,7 +26,7 @@ import (
 
 	"k8s.io/klog/v2"
 
-	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils"
 	"sigs.k8s.io/node-feature-discovery/source"
 )
@@ -45,7 +45,7 @@ var (
 
 // localSource implements the FeatureSource and LabelSource interfaces.
 type localSource struct {
-	features *nfdv1alpha1.DomainFeatures
+	features *feature.DomainFeatures
 	config   *Config
 }
 
@@ -103,7 +103,7 @@ func newDefaultConfig() *Config {
 
 // Discover method of the FeatureSource interface
 func (s *localSource) Discover() error {
-	s.features = nfdv1alpha1.NewDomainFeatures()
+	s.features = feature.NewDomainFeatures()
 
 	featuresFromFiles, err := getFeaturesFromFiles()
 	if err != nil {
@@ -129,7 +129,7 @@ func (s *localSource) Discover() error {
 		}
 	}
 
-	s.features.Attributes[LabelFeature] = nfdv1alpha1.NewAttributeFeatures(featuresFromFiles)
+	s.features.Attributes[LabelFeature] = feature.NewAttributeFeatures(featuresFromFiles)
 
 	utils.KlogDump(3, "discovered local features:", "  ", s.features)
 
@@ -137,9 +137,9 @@ func (s *localSource) Discover() error {
 }
 
 // GetFeatures method of the FeatureSource Interface
-func (s *localSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
+func (s *localSource) GetFeatures() *feature.DomainFeatures {
 	if s.features == nil {
-		s.features = nfdv1alpha1.NewDomainFeatures()
+		s.features = feature.NewDomainFeatures()
 	}
 	return s.features
 }
diff --git a/source/memory/memory.go b/source/memory/memory.go
index c9390fd7c..0155da214 100644
--- a/source/memory/memory.go
+++ b/source/memory/memory.go
@@ -25,7 +25,7 @@ import (
 
 	"k8s.io/klog/v2"
 
-	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils/hostpath"
 	"sigs.k8s.io/node-feature-discovery/source"
@@ -42,7 +42,7 @@ const NumaFeature = "numa"
 
 // memorySource implements the FeatureSource and LabelSource interfaces.
 type memorySource struct {
-	features *nfdv1alpha1.DomainFeatures
+	features *feature.DomainFeatures
 }
 
 // Singleton source instance
@@ -84,20 +84,20 @@ func (s *memorySource) GetLabels() (source.FeatureLabels, error) {
 
 // Discover method of the FeatureSource interface
 func (s *memorySource) Discover() error {
-	s.features = nfdv1alpha1.NewDomainFeatures()
+	s.features = feature.NewDomainFeatures()
 
 	// Detect NUMA
 	if numa, err := detectNuma(); err != nil {
 		klog.Errorf("failed to detect NUMA nodes: %v", err)
 	} else {
-		s.features.Attributes[NumaFeature] = nfdv1alpha1.AttributeFeatureSet{Elements: numa}
+		s.features.Attributes[NumaFeature] = feature.AttributeFeatureSet{Elements: numa}
 	}
 
 	// Detect NVDIMM
 	if nv, err := detectNv(); err != nil {
 		klog.Errorf("failed to detect nvdimm devices: %v", err)
 	} else {
-		s.features.Instances[NvFeature] = nfdv1alpha1.InstanceFeatureSet{Elements: nv}
+		s.features.Instances[NvFeature] = feature.InstanceFeatureSet{Elements: nv}
 	}
 
 	utils.KlogDump(3, "discovered memory features:", "  ", s.features)
@@ -106,9 +106,9 @@ func (s *memorySource) Discover() error {
 }
 
 // GetFeatures method of the FeatureSource Interface.
-func (s *memorySource) GetFeatures() *nfdv1alpha1.DomainFeatures {
+func (s *memorySource) GetFeatures() *feature.DomainFeatures {
 	if s.features == nil {
-		s.features = nfdv1alpha1.NewDomainFeatures()
+		s.features = feature.NewDomainFeatures()
 	}
 	return s.features
 }
@@ -129,9 +129,9 @@ func detectNuma() (map[string]string, error) {
 }
 
 // detectNv detects NVDIMM devices
-func detectNv() ([]nfdv1alpha1.InstanceFeature, error) {
+func detectNv() ([]feature.InstanceFeature, error) {
 	sysfsBasePath := hostpath.SysfsDir.Path("bus/nd/devices")
-	info := make([]nfdv1alpha1.InstanceFeature, 0)
+	info := make([]feature.InstanceFeature, 0)
 
 	devices, err := os.ReadDir(sysfsBasePath)
 	if os.IsNotExist(err) {
@@ -153,7 +153,7 @@ func detectNv() ([]nfdv1alpha1.InstanceFeature, error) {
 // ndDevAttrs is the list of sysfs files (under each nd device) that we're trying to read
 var ndDevAttrs = []string{"devtype", "mode"}
 
-func readNdDeviceInfo(path string) nfdv1alpha1.InstanceFeature {
+func readNdDeviceInfo(path string) feature.InstanceFeature {
 	attrs := map[string]string{"name": filepath.Base(path)}
 	for _, attrName := range ndDevAttrs {
 		data, err := os.ReadFile(filepath.Join(path, attrName))
@@ -163,7 +163,7 @@ func readNdDeviceInfo(path string) nfdv1alpha1.InstanceFeature {
 		}
 		attrs[attrName] = strings.TrimSpace(string(data))
 	}
-	return *nfdv1alpha1.NewInstanceFeature(attrs)
+	return *feature.NewInstanceFeature(attrs)
 }
 
 func init() {
diff --git a/source/network/network.go b/source/network/network.go
index c906c1d61..7a36150b8 100644
--- a/source/network/network.go
+++ b/source/network/network.go
@@ -25,7 +25,7 @@ import (
 
 	"k8s.io/klog/v2"
 
-	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils/hostpath"
 	"sigs.k8s.io/node-feature-discovery/source"
@@ -40,7 +40,7 @@ const sysfsBaseDir = "class/net"
 
 // networkSource implements the FeatureSource and LabelSource interfaces.
 type networkSource struct {
-	features *nfdv1alpha1.DomainFeatures
+	features *feature.DomainFeatures
 }
 
 // Singleton source instance
@@ -91,13 +91,13 @@ func (s *networkSource) GetLabels() (source.FeatureLabels, error) {
 
 // Discover method of the FeatureSource interface.
 func (s *networkSource) Discover() error {
-	s.features = nfdv1alpha1.NewDomainFeatures()
+	s.features = feature.NewDomainFeatures()
 
 	devs, err := detectNetDevices()
 	if err != nil {
 		return fmt.Errorf("failed to detect network devices: %w", err)
 	}
-	s.features.Instances[DeviceFeature] = nfdv1alpha1.InstanceFeatureSet{Elements: devs}
+	s.features.Instances[DeviceFeature] = feature.InstanceFeatureSet{Elements: devs}
 
 	utils.KlogDump(3, "discovered network features:", "  ", s.features)
 
@@ -105,14 +105,14 @@ func (s *networkSource) Discover() error {
 }
 
 // GetFeatures method of the FeatureSource Interface.
-func (s *networkSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
+func (s *networkSource) GetFeatures() *feature.DomainFeatures {
 	if s.features == nil {
-		s.features = nfdv1alpha1.NewDomainFeatures()
+		s.features = feature.NewDomainFeatures()
 	}
 	return s.features
 }
 
-func detectNetDevices() ([]nfdv1alpha1.InstanceFeature, error) {
+func detectNetDevices() ([]feature.InstanceFeature, error) {
 	sysfsBasePath := hostpath.SysfsDir.Path(sysfsBaseDir)
 
 	ifaces, err := os.ReadDir(sysfsBasePath)
@@ -121,7 +121,7 @@ func detectNetDevices() ([]nfdv1alpha1.InstanceFeature, error) {
 	}
 
 	// Iterate over devices
-	info := make([]nfdv1alpha1.InstanceFeature, 0, len(ifaces))
+	info := make([]feature.InstanceFeature, 0, len(ifaces))
 	for _, iface := range ifaces {
 		name := iface.Name()
 		if _, err := os.Stat(filepath.Join(sysfsBasePath, name, "device")); err == nil {
@@ -134,7 +134,7 @@ func detectNetDevices() ([]nfdv1alpha1.InstanceFeature, error) {
 	return info, nil
 }
 
-func readIfaceInfo(path string) nfdv1alpha1.InstanceFeature {
+func readIfaceInfo(path string) feature.InstanceFeature {
 	attrs := map[string]string{"name": filepath.Base(path)}
 	for _, attrName := range ifaceAttrs {
 		data, err := os.ReadFile(filepath.Join(path, attrName))
@@ -158,7 +158,7 @@ func readIfaceInfo(path string) nfdv1alpha1.InstanceFeature {
 		attrs[attrName] = strings.TrimSpace(string(data))
 	}
 
-	return *nfdv1alpha1.NewInstanceFeature(attrs)
+	return *feature.NewInstanceFeature(attrs)
 
 }
 
diff --git a/source/pci/pci.go b/source/pci/pci.go
index 93fd0bdcd..b7a0f58c4 100644
--- a/source/pci/pci.go
+++ b/source/pci/pci.go
@@ -22,7 +22,7 @@ import (
 
 	"k8s.io/klog/v2"
 
-	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils"
 	"sigs.k8s.io/node-feature-discovery/source"
 )
@@ -50,7 +50,7 @@ func newDefaultConfig() *Config {
 // pciSource implements the FeatureSource, LabelSource and ConfigurableSource interfaces.
 type pciSource struct {
 	config   *Config
-	features *nfdv1alpha1.DomainFeatures
+	features *feature.DomainFeatures
 }
 
 // Singleton source instance
@@ -140,13 +140,13 @@ func (s *pciSource) GetLabels() (source.FeatureLabels, error) {
 
 // Discover method of the FeatureSource interface
 func (s *pciSource) Discover() error {
-	s.features = nfdv1alpha1.NewDomainFeatures()
+	s.features = feature.NewDomainFeatures()
 
 	devs, err := detectPci()
 	if err != nil {
 		return fmt.Errorf("failed to detect PCI devices: %s", err.Error())
 	}
-	s.features.Instances[DeviceFeature] = nfdv1alpha1.NewInstanceFeatures(devs)
+	s.features.Instances[DeviceFeature] = feature.NewInstanceFeatures(devs)
 
 	utils.KlogDump(3, "discovered pci features:", "  ", s.features)
 
@@ -154,9 +154,9 @@ func (s *pciSource) Discover() error {
 }
 
 // GetFeatures method of the FeatureSource Interface
-func (s *pciSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
+func (s *pciSource) GetFeatures() *feature.DomainFeatures {
 	if s.features == nil {
-		s.features = nfdv1alpha1.NewDomainFeatures()
+		s.features = feature.NewDomainFeatures()
 	}
 	return s.features
 }
diff --git a/source/pci/utils.go b/source/pci/utils.go
index d9a370217..0c7b1af72 100644
--- a/source/pci/utils.go
+++ b/source/pci/utils.go
@@ -24,7 +24,7 @@ import (
 
 	"k8s.io/klog/v2"
 
-	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils/hostpath"
 )
 
@@ -50,7 +50,7 @@ func readSinglePciAttribute(devPath string, attrName string) (string, error) {
 }
 
 // Read information of one PCI device
-func readPciDevInfo(devPath string) (*nfdv1alpha1.InstanceFeature, error) {
+func readPciDevInfo(devPath string) (*feature.InstanceFeature, error) {
 	attrs := make(map[string]string)
 	for _, attr := range mandatoryDevAttrs {
 		attrVal, err := readSinglePciAttribute(devPath, attr)
@@ -65,12 +65,12 @@ func readPciDevInfo(devPath string) (*nfdv1alpha1.InstanceFeature, error) {
 			attrs[attr] = attrVal
 		}
 	}
-	return nfdv1alpha1.NewInstanceFeature(attrs), nil
+	return feature.NewInstanceFeature(attrs), nil
 }
 
 // detectPci detects available PCI devices and retrieves their device attributes.
 // An error is returned if reading any of the mandatory attributes fails.
-func detectPci() ([]nfdv1alpha1.InstanceFeature, error) {
+func detectPci() ([]feature.InstanceFeature, error) {
 	sysfsBasePath := hostpath.SysfsDir.Path("bus/pci/devices")
 
 	devices, err := os.ReadDir(sysfsBasePath)
@@ -79,7 +79,7 @@ func detectPci() ([]nfdv1alpha1.InstanceFeature, error) {
 	}
 
 	// Iterate over devices
-	devInfo := make([]nfdv1alpha1.InstanceFeature, 0, len(devices))
+	devInfo := make([]feature.InstanceFeature, 0, len(devices))
 	for _, device := range devices {
 		info, err := readPciDevInfo(filepath.Join(sysfsBasePath, device.Name()))
 		if err != nil {
diff --git a/source/source.go b/source/source.go
index 2f0eb6dc8..44a725ba8 100644
--- a/source/source.go
+++ b/source/source.go
@@ -21,7 +21,7 @@ package source
 import (
 	"fmt"
 
-	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 )
 
 // Source is the base interface for all other source interfaces
@@ -38,7 +38,7 @@ type FeatureSource interface {
 	Discover() error
 
 	// GetFeatures returns discovered features in raw form
-	GetFeatures() *nfdv1alpha1.DomainFeatures
+	GetFeatures() *feature.DomainFeatures
 }
 
 // LabelSource represents a source of node feature labels
diff --git a/source/storage/storage.go b/source/storage/storage.go
index e0b107b43..e04a8e361 100644
--- a/source/storage/storage.go
+++ b/source/storage/storage.go
@@ -24,7 +24,7 @@ import (
 
 	"k8s.io/klog/v2"
 
-	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils/hostpath"
 	"sigs.k8s.io/node-feature-discovery/source"
@@ -37,7 +37,7 @@ const BlockFeature = "block"
 
 // storageSource implements the FeatureSource and LabelSource interfaces.
 type storageSource struct {
-	features *nfdv1alpha1.DomainFeatures
+	features *feature.DomainFeatures
 }
 
 // Singleton source instance
@@ -73,13 +73,13 @@ func (s *storageSource) GetLabels() (source.FeatureLabels, error) {
 
 // Discover method of the FeatureSource interface
 func (s *storageSource) Discover() error {
-	s.features = nfdv1alpha1.NewDomainFeatures()
+	s.features = feature.NewDomainFeatures()
 
 	devs, err := detectBlock()
 	if err != nil {
 		return fmt.Errorf("failed to detect block devices: %w", err)
 	}
-	s.features.Instances[BlockFeature] = nfdv1alpha1.InstanceFeatureSet{Elements: devs}
+	s.features.Instances[BlockFeature] = feature.InstanceFeatureSet{Elements: devs}
 
 	utils.KlogDump(3, "discovered storage features:", "  ", s.features)
 
@@ -87,14 +87,14 @@ func (s *storageSource) Discover() error {
 }
 
 // GetFeatures method of the FeatureSource Interface.
-func (s *storageSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
+func (s *storageSource) GetFeatures() *feature.DomainFeatures {
 	if s.features == nil {
-		s.features = nfdv1alpha1.NewDomainFeatures()
+		s.features = feature.NewDomainFeatures()
 	}
 	return s.features
 }
 
-func detectBlock() ([]nfdv1alpha1.InstanceFeature, error) {
+func detectBlock() ([]feature.InstanceFeature, error) {
 	sysfsBasePath := hostpath.SysfsDir.Path("block")
 
 	blockdevices, err := os.ReadDir(sysfsBasePath)
@@ -103,7 +103,7 @@ func detectBlock() ([]nfdv1alpha1.InstanceFeature, error) {
 	}
 
 	// Iterate over devices
-	info := make([]nfdv1alpha1.InstanceFeature, 0, len(blockdevices))
+	info := make([]feature.InstanceFeature, 0, len(blockdevices))
 	for _, device := range blockdevices {
 		info = append(info, *readBlockDevQueueInfo(filepath.Join(sysfsBasePath, device.Name())))
 	}
@@ -111,7 +111,7 @@ func detectBlock() ([]nfdv1alpha1.InstanceFeature, error) {
 	return info, nil
 }
 
-func readBlockDevQueueInfo(path string) *nfdv1alpha1.InstanceFeature {
+func readBlockDevQueueInfo(path string) *feature.InstanceFeature {
 	attrs := map[string]string{"name": filepath.Base(path)}
 	for _, attrName := range queueAttrs {
 		data, err := os.ReadFile(filepath.Join(path, "queue", attrName))
@@ -121,7 +121,7 @@ func readBlockDevQueueInfo(path string) *nfdv1alpha1.InstanceFeature {
 		}
 		attrs[attrName] = strings.TrimSpace(string(data))
 	}
-	return nfdv1alpha1.NewInstanceFeature(attrs)
+	return feature.NewInstanceFeature(attrs)
 }
 
 func init() {
diff --git a/source/system/system.go b/source/system/system.go
index 304c9ed74..8f437bbd3 100644
--- a/source/system/system.go
+++ b/source/system/system.go
@@ -24,7 +24,7 @@ import (
 
 	"k8s.io/klog/v2"
 
-	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils/hostpath"
 	"sigs.k8s.io/node-feature-discovery/source"
@@ -47,7 +47,7 @@ const (
 
 // systemSource implements the FeatureSource and LabelSource interfaces.
 type systemSource struct {
-	features *nfdv1alpha1.DomainFeatures
+	features *feature.DomainFeatures
 }
 
 // Singleton source instance
@@ -78,10 +78,10 @@ func (s *systemSource) GetLabels() (source.FeatureLabels, error) {
 
 // Discover method of the FeatureSource interface
 func (s *systemSource) Discover() error {
-	s.features = nfdv1alpha1.NewDomainFeatures()
+	s.features = feature.NewDomainFeatures()
 
 	// Get node name
-	s.features.Attributes[NameFeature] = nfdv1alpha1.NewAttributeFeatures(nil)
+	s.features.Attributes[NameFeature] = feature.NewAttributeFeatures(nil)
 	s.features.Attributes[NameFeature].Elements["nodename"] = os.Getenv("NODE_NAME")
 
 	// Get os-release information
@@ -89,7 +89,7 @@ func (s *systemSource) Discover() error {
 	if err != nil {
 		klog.Errorf("failed to get os-release: %s", err)
 	} else {
-		s.features.Attributes[OsReleaseFeature] = nfdv1alpha1.NewAttributeFeatures(release)
+		s.features.Attributes[OsReleaseFeature] = feature.NewAttributeFeatures(release)
 
 		if v, ok := release["VERSION_ID"]; ok {
 			versionComponents := splitVersion(v)
@@ -107,9 +107,9 @@ func (s *systemSource) Discover() error {
 }
 
 // GetFeatures method of the FeatureSource Interface
-func (s *systemSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
+func (s *systemSource) GetFeatures() *feature.DomainFeatures {
 	if s.features == nil {
-		s.features = nfdv1alpha1.NewDomainFeatures()
+		s.features = feature.NewDomainFeatures()
 	}
 	return s.features
 }
diff --git a/source/usb/usb.go b/source/usb/usb.go
index fd8a10dbc..200f3b236 100644
--- a/source/usb/usb.go
+++ b/source/usb/usb.go
@@ -22,7 +22,7 @@ import (
 
 	"k8s.io/klog/v2"
 
-	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	"sigs.k8s.io/node-feature-discovery/pkg/utils"
 	"sigs.k8s.io/node-feature-discovery/source"
 )
@@ -53,7 +53,7 @@ func defaultDeviceLabelFields() []string { return []string{"class", "vendor", "d
 // usbSource implements the LabelSource and ConfigurableSource interfaces.
 type usbSource struct {
 	config   *Config
-	features *nfdv1alpha1.DomainFeatures
+	features *feature.DomainFeatures
 }
 
 // Singleton source instance
@@ -139,13 +139,13 @@ func (s *usbSource) GetLabels() (source.FeatureLabels, error) {
 
 // Discover method of the FeatureSource interface
 func (s *usbSource) Discover() error {
-	s.features = nfdv1alpha1.NewDomainFeatures()
+	s.features = feature.NewDomainFeatures()
 
 	devs, err := detectUsb()
 	if err != nil {
 		return fmt.Errorf("failed to detect USB devices: %s", err.Error())
 	}
-	s.features.Instances[DeviceFeature] = nfdv1alpha1.NewInstanceFeatures(devs)
+	s.features.Instances[DeviceFeature] = feature.NewInstanceFeatures(devs)
 
 	utils.KlogDump(3, "discovered usb features:", "  ", s.features)
 
@@ -153,9 +153,9 @@ func (s *usbSource) Discover() error {
 }
 
 // GetFeatures method of the FeatureSource Interface
-func (s *usbSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
+func (s *usbSource) GetFeatures() *feature.DomainFeatures {
 	if s.features == nil {
-		s.features = nfdv1alpha1.NewDomainFeatures()
+		s.features = feature.NewDomainFeatures()
 	}
 	return s.features
 }
diff --git a/source/usb/utils.go b/source/usb/utils.go
index c7772f885..38a5dbe35 100644
--- a/source/usb/utils.go
+++ b/source/usb/utils.go
@@ -25,7 +25,7 @@ import (
 
 	"k8s.io/klog/v2"
 
-	nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 )
 
 var devAttrs = []string{"class", "vendor", "device", "serial"}
@@ -57,8 +57,8 @@ func readSingleUsbAttribute(devPath string, attrName string) (string, error) {
 }
 
 // Read information of one USB device
-func readUsbDevInfo(devPath string) ([]nfdv1alpha1.InstanceFeature, error) {
-	instances := make([]nfdv1alpha1.InstanceFeature, 0)
+func readUsbDevInfo(devPath string) ([]feature.InstanceFeature, error) {
+	instances := make([]feature.InstanceFeature, 0)
 	attrs := make(map[string]string)
 
 	for _, attr := range devAttrs {
@@ -71,7 +71,7 @@ func readUsbDevInfo(devPath string) ([]nfdv1alpha1.InstanceFeature, error) {
 	// USB devices encode their class information either at the device or the interface level. If the device class
 	// is set, return as-is.
 	if attrs["class"] != "00" {
-		instances = append(instances, *nfdv1alpha1.NewInstanceFeature(attrs))
+		instances = append(instances, *feature.NewInstanceFeature(attrs))
 	} else {
 		// Otherwise, if a 00 is presented at the device level, descend to the interface level.
 		interfaces, err := filepath.Glob(devPath + "/*/bInterfaceClass")
@@ -94,7 +94,7 @@ func readUsbDevInfo(devPath string) ([]nfdv1alpha1.InstanceFeature, error) {
 			}
 			subdevAttrs["class"] = attrVal
 
-			instances = append(instances, *nfdv1alpha1.NewInstanceFeature(subdevAttrs))
+			instances = append(instances, *feature.NewInstanceFeature(subdevAttrs))
 		}
 	}
 
@@ -102,7 +102,7 @@ func readUsbDevInfo(devPath string) ([]nfdv1alpha1.InstanceFeature, error) {
 }
 
 // detectUsb detects available USB devices and retrieves their device attributes.
-func detectUsb() ([]nfdv1alpha1.InstanceFeature, error) {
+func detectUsb() ([]feature.InstanceFeature, error) {
 	// Unlike PCI, the USB sysfs interface includes entries not just for
 	// devices. We work around this by globbing anything that includes a
 	// valid product ID.
@@ -113,7 +113,7 @@ func detectUsb() ([]nfdv1alpha1.InstanceFeature, error) {
 	}
 
 	// Iterate over devices
-	devInfo := make([]nfdv1alpha1.InstanceFeature, 0)
+	devInfo := make([]feature.InstanceFeature, 0)
 	for _, devPath := range devPaths {
 		devs, err := readUsbDevInfo(filepath.Dir(devPath))
 		if err != nil {


Test patch:
diff --git a/pkg/apis/nfd/v1alpha1/expression_test.go b/pkg/apis/nfd/v1alpha1/expression_test.go
index aeb5f3638..6dcd5f3e9 100644
--- a/pkg/apis/nfd/v1alpha1/expression_test.go
+++ b/pkg/apis/nfd/v1alpha1/expression_test.go
@@ -22,6 +22,7 @@ import (
 	"github.com/stretchr/testify/assert"
 	"sigs.k8s.io/yaml"
 
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 	api "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
 )
 
@@ -181,7 +182,7 @@ func TestMatch(t *testing.T) {
 
 func TestMatchKeys(t *testing.T) {
 	type V = api.MatchValue
-	type I = map[string]api.Nil
+	type I = map[string]feature.Nil
 	type TC struct {
 		op     api.MatchOp
 		values V
@@ -289,7 +290,7 @@ func TestMatchValues(t *testing.T) {
 }
 
 func TestMESMatchKeys(t *testing.T) {
-	type I = map[string]api.Nil
+	type I = map[string]feature.Nil
 	type MK = api.MatchedKey
 	type O = []MK
 	type TC struct {
@@ -412,7 +413,7 @@ baz: { op: Gt, value: ["10"] }
 }
 
 func TestMESMatchInstances(t *testing.T) {
-	type I = api.InstanceFeature
+	type I = feature.InstanceFeature
 	type MI = api.MatchedInstance
 	type O = []MI
 	type A = map[string]string
diff --git a/pkg/apis/nfd/v1alpha1/rule_test.go b/pkg/apis/nfd/v1alpha1/rule_test.go
index b19c2b633..35ec25b96 100644
--- a/pkg/apis/nfd/v1alpha1/rule_test.go
+++ b/pkg/apis/nfd/v1alpha1/rule_test.go
@@ -20,10 +20,11 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"sigs.k8s.io/node-feature-discovery/pkg/api/feature"
 )
 
 func TestRule(t *testing.T) {
-	f := map[string]*DomainFeatures{}
+	f := map[string]*feature.DomainFeatures{}
 	r1 := Rule{Labels: map[string]string{"label-1": "", "label-2": "true"}}
 	r2 := Rule{
 		Labels: map[string]string{"label-1": "label-val-1"},
@@ -47,7 +48,7 @@ func TestRule(t *testing.T) {
 	assert.Error(t, err, "matching against a missing domain should have returned an error")
 
 	// Test empty domain
-	d := NewDomainFeatures()
+	d := feature.NewDomainFeatures()
 	f["domain-1"] = d
 
 	m, err = r1.Execute(f)
@@ -59,9 +60,9 @@ func TestRule(t *testing.T) {
 	assert.Error(t, err, "matching against a missing feature type should have returned an error")
 
 	// Test empty feature sets
-	d.Flags["kf-1"] = NewFlagFeatures()
-	d.Attributes["vf-1"] = NewAttributeFeatures(nil)
-	d.Instances["if-1"] = NewInstanceFeatures(nil)
+	d.Flags["kf-1"] = feature.NewFlagFeatures()
+	d.Attributes["vf-1"] = feature.NewAttributeFeatures(nil)
+	d.Instances["if-1"] = feature.NewInstanceFeatures(nil)
 
 	m, err = r1.Execute(f)
 	assert.Nilf(t, err, "unexpected error: %v", err)
@@ -72,10 +73,10 @@ func TestRule(t *testing.T) {
 	assert.Nil(t, m.Labels, "unexpected match")
 
 	// Test non-empty feature sets
-	d.Flags["kf-1"].Elements["key-x"] = Nil{}
+	d.Flags["kf-1"].Elements["key-x"] = feature.Nil{}
 	d.Attributes["vf-1"].Elements["key-1"] = "val-x"
-	d.Instances["if-1"] = NewInstanceFeatures([]InstanceFeature{
-		*NewInstanceFeature(map[string]string{"attr-1": "val-x"})})
+	d.Instances["if-1"] = feature.NewInstanceFeatures([]feature.InstanceFeature{
+		*feature.NewInstanceFeature(map[string]string{"attr-1": "val-x"})})
 
 	m, err = r1.Execute(f)
 	assert.Nilf(t, err, "unexpected error: %v", err)
@@ -97,7 +98,7 @@ func TestRule(t *testing.T) {
 	assert.Nilf(t, err, "unexpected error: %v", err)
 	assert.Nil(t, m.Labels, "keys should not have matched")
 
-	d.Flags["kf-1"].Elements["key-1"] = Nil{}
+	d.Flags["kf-1"].Elements["key-1"] = feature.Nil{}
 	m, err = r2.Execute(f)
 	assert.Nilf(t, err, "unexpected error: %v", err)
 	assert.Equal(t, r2.Labels, m.Labels, "keys should have matched")
@@ -174,7 +175,7 @@ func TestRule(t *testing.T) {
 
 	// Test MatchAny
 	r5.MatchAny = []MatchAnyElem{
-		{
+		MatchAnyElem{
 			MatchFeatures: FeatureMatcher{
 				FeatureMatcherTerm{
 					Feature: "domain-1.kf-1",
@@ -207,19 +208,19 @@ func TestRule(t *testing.T) {
 }
 
 func TestTemplating(t *testing.T) {
-	f := map[string]*DomainFeatures{
-		"domain_1": &DomainFeatures{
-			Flags: map[string]FlagFeatureSet{
-				"kf_1": FlagFeatureSet{
-					Elements: map[string]Nil{
-						"key-a": {},
-						"key-b": {},
-						"key-c": {},
+	f := map[string]*feature.DomainFeatures{
+		"domain_1": &feature.DomainFeatures{
+			Flags: map[string]feature.FlagFeatureSet{
+				"kf_1": feature.FlagFeatureSet{
+					Elements: map[string]feature.Nil{
+						"key-a": feature.Nil{},
+						"key-b": feature.Nil{},
+						"key-c": feature.Nil{},
 					},
 				},
 			},
-			Attributes: map[string]AttributeFeatureSet{
-				"vf_1": AttributeFeatureSet{
+			Attributes: map[string]feature.AttributeFeatureSet{
+				"vf_1": feature.AttributeFeatureSet{
 					Elements: map[string]string{
 						"key-1": "val-1",
 						"keu-2": "val-2",
@@ -227,22 +228,22 @@ func TestTemplating(t *testing.T) {
 					},
 				},
 			},
-			Instances: map[string]InstanceFeatureSet{
-				"if_1": InstanceFeatureSet{
-					Elements: []InstanceFeature{
-						{
+			Instances: map[string]feature.InstanceFeatureSet{
+				"if_1": feature.InstanceFeatureSet{
+					Elements: []feature.InstanceFeature{
+						feature.InstanceFeature{
 							Attributes: map[string]string{
 								"attr-1": "1",
 								"attr-2": "val-2",
 							},
 						},
-						{
+						feature.InstanceFeature{
 							Attributes: map[string]string{
 								"attr-1": "10",
 								"attr-2": "val-20",
 							},
 						},
-						{
+						feature.InstanceFeature{
 							Attributes: map[string]string{
 								"attr-1": "100",
 								"attr-2": "val-200",
diff --git a/pkg/nfd-master/nfd-master-internal_test.go b/pkg/nfd-master/nfd-master-internal_test.go
index eae019cff..dbdb98360 100644
--- a/pkg/nfd-master/nfd-master-internal_test.go
+++ b/pkg/nfd-master/nfd-master-internal_test.go
@@ -27,7 +27,7 @@ import (
 	"github.com/stretchr/testify/mock"
 	"github.com/vektra/errors"
 	"golang.org/x/net/context"
-	corev1 "k8s.io/api/core/v1"
+	api "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	k8sclient "k8s.io/client-go/kubernetes"
@@ -43,12 +43,12 @@ const (
 	mockNodeName = "mock-node"
 )
 
-func newMockNode() *corev1.Node {
-	n := corev1.Node{}
+func newMockNode() *api.Node {
+	n := api.Node{}
 	n.Name = mockNodeName
 	n.Labels = map[string]string{}
 	n.Annotations = map[string]string{}
-	n.Status.Capacity = corev1.ResourceList{}
+	n.Status.Capacity = api.ResourceList{}
 	return &n
 }
 
@@ -238,7 +238,7 @@ func TestAddingExtResources(t *testing.T) {
 
 		Convey("When the resource already exists", func() {
 			mockNode := newMockNode()
-			mockNode.Status.Capacity[corev1.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-1")] = *resource.NewQuantity(1, resource.BinarySI)
+			mockNode.Status.Capacity[api.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-1")] = *resource.NewQuantity(1, resource.BinarySI)
 			mockResourceLabels := ExtendedResources{nfdv1alpha1.FeatureLabelNs + "/feature-1": "1"}
 			patches := mockMaster.createExtendedResourcePatches(mockNode, mockResourceLabels)
 			So(len(patches), ShouldEqual, 0)
@@ -246,7 +246,7 @@ func TestAddingExtResources(t *testing.T) {
 
 		Convey("When the resource already exists but its capacity has changed", func() {
 			mockNode := newMockNode()
-			mockNode.Status.Capacity[corev1.ResourceName("feature-1")] = *resource.NewQuantity(2, resource.BinarySI)
+			mockNode.Status.Capacity[api.ResourceName("feature-1")] = *resource.NewQuantity(2, resource.BinarySI)
 			mockResourceLabels := ExtendedResources{"feature-1": "1"}
 			expectedPatches := []apihelper.JsonPatch{
 				apihelper.NewJsonPatch("replace", "/status/capacity", "feature-1", "1"),
@@ -265,8 +265,8 @@ func TestRemovingExtResources(t *testing.T) {
 			mockNode := newMockNode()
 			mockResourceLabels := ExtendedResources{nfdv1alpha1.FeatureLabelNs + "/feature-1": "1", nfdv1alpha1.FeatureLabelNs + "/feature-2": "2"}
 			mockNode.Annotations[nfdv1alpha1.AnnotationNs+"/extended-resources"] = "feature-1,feature-2"
-			mockNode.Status.Capacity[corev1.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-1")] = *resource.NewQuantity(1, resource.BinarySI)
-			mockNode.Status.Capacity[corev1.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-2")] = *resource.NewQuantity(2, resource.BinarySI)
+			mockNode.Status.Capacity[api.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-1")] = *resource.NewQuantity(1, resource.BinarySI)
+			mockNode.Status.Capacity[api.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-2")] = *resource.NewQuantity(2, resource.BinarySI)
 			patches := mockMaster.createExtendedResourcePatches(mockNode, mockResourceLabels)
 			So(len(patches), ShouldEqual, 0)
 		})
@@ -274,15 +274,15 @@ func TestRemovingExtResources(t *testing.T) {
 			mockNode := newMockNode()
 			mockResourceLabels := ExtendedResources{nfdv1alpha1.FeatureLabelNs + "/feature-4": "", nfdv1alpha1.FeatureLabelNs + "/feature-2": "2"}
 			mockNode.Annotations[nfdv1alpha1.AnnotationNs+"/extended-resources"] = "feature-4,feature-2"
-			mockNode.Status.Capacity[corev1.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-4")] = *resource.NewQuantity(4, resource.BinarySI)
-			mockNode.Status.Capacity[corev1.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-2")] = *resource.NewQuantity(2, resource.BinarySI)
+			mockNode.Status.Capacity[api.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-4")] = *resource.NewQuantity(4, resource.BinarySI)
+			mockNode.Status.Capacity[api.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-2")] = *resource.NewQuantity(2, resource.BinarySI)
 			patches := mockMaster.createExtendedResourcePatches(mockNode, mockResourceLabels)
 			So(len(patches), ShouldBeGreaterThan, 0)
 		})
 		Convey("When the extended resource is no longer wanted", func() {
 			mockNode := newMockNode()
-			mockNode.Status.Capacity[corev1.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-1")] = *resource.NewQuantity(1, resource.BinarySI)
-			mockNode.Status.Capacity[corev1.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-2")] = *resource.NewQuantity(2, resource.BinarySI)
+			mockNode.Status.Capacity[api.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-1")] = *resource.NewQuantity(1, resource.BinarySI)
+			mockNode.Status.Capacity[api.ResourceName(nfdv1alpha1.FeatureLabelNs+"/feature-2")] = *resource.NewQuantity(2, resource.BinarySI)
 			mockResourceLabels := ExtendedResources{nfdv1alpha1.FeatureLabelNs + "/feature-2": "2"}
 			mockNode.Annotations[nfdv1alpha1.AnnotationNs+"/extended-resources"] = "feature-1,feature-2"
 			patches := mockMaster.createExtendedResourcePatches(mockNode, mockResourceLabels)
@@ -475,7 +475,7 @@ func TestCreatePatches(t *testing.T) {
 
 func TestRemoveLabelsWithPrefix(t *testing.T) {
 	Convey("When removing labels", t, func() {
-		n := &corev1.Node{
+		n := &api.Node{
 			ObjectMeta: meta_v1.ObjectMeta{
 				Labels: map[string]string{
 					"single-label": "123",
@@ -531,7 +531,7 @@ func sortJsonPatches(p []apihelper.JsonPatch) []apihelper.JsonPatch {
 }
 
 // Remove any labels having the given prefix
-func removeLabelsWithPrefix(n *corev1.Node, search string) []apihelper.JsonPatch {
+func removeLabelsWithPrefix(n *api.Node, search string) []apihelper.JsonPatch {
 	var p []apihelper.JsonPatch
 
 	for k := range n.Labels {
diff --git a/pkg/utils/memory_resources_test.go b/pkg/utils/memory_resources_test.go
index 030149bac..9f1f4b063 100644
--- a/pkg/utils/memory_resources_test.go
+++ b/pkg/utils/memory_resources_test.go
@@ -22,7 +22,7 @@ import (
 	"path/filepath"
 	"testing"
 
-	corev1 "k8s.io/api/core/v1"
+	v1 "k8s.io/api/core/v1"
 )
 
 const (
@@ -109,11 +109,11 @@ func TestGetMemoryResourceCounters(t *testing.T) {
 	}
 
 	if memoryCounters[0]["memory"] != 32718644*1024 {
-		t.Errorf("found unexpected amount of memory under the NUMA node 0: %d", memoryCounters[0][corev1.ResourceMemory])
+		t.Errorf("found unexpected amount of memory under the NUMA node 0: %d", memoryCounters[0][v1.ResourceMemory])
 	}
 
 	if memoryCounters[1]["memory"] != 32718644*1024 {
-		t.Errorf("found unexpected amount of memory under the NUMA node 1: %d", memoryCounters[0][corev1.ResourceMemory])
+		t.Errorf("found unexpected amount of memory under the NUMA node 1: %d", memoryCounters[0][v1.ResourceMemory])
 	}
 }
 
diff --git a/test/e2e/node_feature_discovery.go b/test/e2e/node_feature_discovery.go
index 141215445..9a1c1e8ab 100644
--- a/test/e2e/node_feature_discovery.go
+++ b/test/e2e/node_feature_discovery.go
@@ -28,7 +28,7 @@ import (
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
 
-	corev1 "k8s.io/api/core/v1"
+	v1 "k8s.io/api/core/v1"
 	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 	extclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -58,7 +58,7 @@ func cleanupNode(cs clientset.Interface) {
 
 	for _, n := range nodeList.Items {
 		var err error
-		var node *corev1.Node
+		var node *v1.Node
 		for retry := 0; retry < 5; retry++ {
 			node, err = cs.CoreV1().Nodes().Get(context.TODO(), n.Name, metav1.GetOptions{})
 			Expect(err).NotTo(HaveOccurred())
@@ -102,7 +102,7 @@ var _ = SIGDescribe("Node Feature Discovery", func() {
 	f := framework.NewDefaultFramework("node-feature-discovery")
 
 	Context("when deploying a single nfd-master pod", func() {
-		var masterPod *corev1.Pod
+		var masterPod *v1.Pod
 
 		BeforeEach(func() {
 			err := testutils.ConfigureRBAC(f.ClientSet, f.Namespace.Name)
@@ -313,7 +313,7 @@ var _ = SIGDescribe("Node Feature Discovery", func() {
   - nodename:
     - ` + targetNodeName
 
-				cm1 := &corev1.ConfigMap{
+				cm1 := &v1.ConfigMap{
 					ObjectMeta: metav1.ObjectMeta{
 						Name: "custom-config-extra-" + string(uuid.NewUUID()),
 					},
@@ -334,7 +334,7 @@ var _ = SIGDescribe("Node Feature Discovery", func() {
   - nodename:
     - "thisNameShouldNeverMatch"`
 
-				cm2 := &corev1.ConfigMap{
+				cm2 := &v1.ConfigMap{
 					ObjectMeta: metav1.ObjectMeta{
 						Name: "custom-config-extra-" + string(uuid.NewUUID()),
 					},
@@ -350,21 +350,21 @@ var _ = SIGDescribe("Node Feature Discovery", func() {
 				volumeName1 := "custom-configs-extra1"
 				volumeName2 := "custom-configs-extra2"
 				workerDS.Spec.Template.Spec.Volumes = append(workerDS.Spec.Template.Spec.Volumes,
-					corev1.Volume{
+					v1.Volume{
 						Name: volumeName1,
-						VolumeSource: corev1.VolumeSource{
-							ConfigMap: &corev1.ConfigMapVolumeSource{
-								LocalObjectReference: corev1.LocalObjectReference{
+						VolumeSource: v1.VolumeSource{
+							ConfigMap: &v1.ConfigMapVolumeSource{
+								LocalObjectReference: v1.LocalObjectReference{
 									Name: cm1.Name,
 								},
 							},
 						},
 					},
-					corev1.Volume{
+					v1.Volume{
 						Name: volumeName2,
-						VolumeSource: corev1.VolumeSource{
-							ConfigMap: &corev1.ConfigMapVolumeSource{
-								LocalObjectReference: corev1.LocalObjectReference{
+						VolumeSource: v1.VolumeSource{
+							ConfigMap: &v1.ConfigMapVolumeSource{
+								LocalObjectReference: v1.LocalObjectReference{
 									Name: cm2.Name,
 								},
 							},
@@ -372,12 +372,12 @@ var _ = SIGDescribe("Node Feature Discovery", func() {
 					},
 				)
 				workerDS.Spec.Template.Spec.Containers[0].VolumeMounts = append(workerDS.Spec.Template.Spec.Containers[0].VolumeMounts,
-					corev1.VolumeMount{
+					v1.VolumeMount{
 						Name:      volumeName1,
 						ReadOnly:  true,
 						MountPath: filepath.Join(custom.Directory, "cm1"),
 					},
-					corev1.VolumeMount{
+					v1.VolumeMount{
 						Name:      volumeName2,
 						ReadOnly:  true,
 						MountPath: filepath.Join(custom.Directory, "cm2"),
diff --git a/test/e2e/topology_updater.go b/test/e2e/topology_updater.go
index 266625be2..c3173cc2e 100644
--- a/test/e2e/topology_updater.go
+++ b/test/e2e/topology_updater.go
@@ -27,7 +27,7 @@ import (
 	"github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/apis/topology/v1alpha1"
 	topologyclientset "github.com/k8stopologyawareschedwg/noderesourcetopology-api/pkg/generated/clientset/versioned"
 
-	corev1 "k8s.io/api/core/v1"
+	v1 "k8s.io/api/core/v1"
 	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 	extclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -45,8 +45,8 @@ var _ = SIGDescribe("Node Feature Discovery topology updater", func() {
 		extClient           *extclient.Clientset
 		topologyClient      *topologyclientset.Clientset
 		crd                 *apiextensionsv1.CustomResourceDefinition
-		topologyUpdaterNode *corev1.Node
-		workerNodes         []corev1.Node
+		topologyUpdaterNode *v1.Node
+		workerNodes         []v1.Node
 		kubeletConfig       *kubeletconfig.KubeletConfiguration
 	)
 
@@ -124,7 +124,7 @@ var _ = SIGDescribe("Node Feature Discovery topology updater", func() {
 			By("creating a pod consuming resources from the shared, non-exclusive CPU pool (best-effort QoS)")
 			sleeperPod := testutils.BestEffortSleeperPod()
 
-			podMap := make(map[string]*corev1.Pod)
+			podMap := make(map[string]*v1.Pod)
 			pod := f.PodClient().CreateSync(sleeperPod)
 			podMap[pod.Name] = pod
 			defer testutils.DeletePodsAsync(f, podMap)
@@ -164,7 +164,7 @@ var _ = SIGDescribe("Node Feature Discovery topology updater", func() {
 			By("creating a pod consuming resources from the shared, non-exclusive CPU pool (guaranteed QoS, nonintegral request)")
 			sleeperPod := testutils.GuaranteedSleeperPod("500m")
 
-			podMap := make(map[string]*corev1.Pod)
+			podMap := make(map[string]*v1.Pod)
 			pod := f.PodClient().CreateSync(sleeperPod)
 			podMap[pod.Name] = pod
 			defer testutils.DeletePodsAsync(f, podMap)
@@ -210,7 +210,7 @@ var _ = SIGDescribe("Node Feature Discovery topology updater", func() {
 			By("creating a pod consuming exclusive CPUs")
 			sleeperPod := testutils.GuaranteedSleeperPod("1000m")
 
-			podMap := make(map[string]*corev1.Pod)
+			podMap := make(map[string]*v1.Pod)
 			pod := f.PodClient().CreateSync(sleeperPod)
 			podMap[pod.Name] = pod
 			defer testutils.DeletePodsAsync(f, podMap)
@@ -253,7 +253,7 @@ var _ = SIGDescribe("Node Feature Discovery topology updater", func() {
 })
 
 // lessAllocatableResources specialize CompareAllocatableResources for this specific e2e use case.
-func lessAllocatableResources(expected, got map[string]corev1.ResourceList) (string, string, bool) {
+func lessAllocatableResources(expected, got map[string]v1.ResourceList) (string, string, bool) {
 	zoneName, resName, cmp, ok := testutils.CompareAllocatableResources(expected, got)
 	if !ok {
 		framework.Logf("-> cmp failed (not ok)")
diff --git a/test/e2e/utils/node.go b/test/e2e/utils/node.go
index 421fbbac8..c0e4c3c80 100644
--- a/test/e2e/utils/node.go
+++ b/test/e2e/utils/node.go
@@ -20,7 +20,7 @@ import (
 	"context"
 	"fmt"
 
-	corev1 "k8s.io/api/core/v1"
+	v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
@@ -40,12 +40,12 @@ const (
 )
 
 // GetWorkerNodes returns all nodes labeled as worker
-func GetWorkerNodes(f *framework.Framework) ([]corev1.Node, error) {
+func GetWorkerNodes(f *framework.Framework) ([]v1.Node, error) {
 	return GetNodesByRole(f, RoleWorker)
 }
 
 // GetByRole returns all nodes with the specified role
-func GetNodesByRole(f *framework.Framework, role string) ([]corev1.Node, error) {
+func GetNodesByRole(f *framework.Framework, role string) ([]v1.Node, error) {
 	selector, err := labels.Parse(fmt.Sprintf("%s/%s=", LabelRole, role))
 	if err != nil {
 		return nil, err
@@ -54,7 +54,7 @@ func GetNodesByRole(f *framework.Framework, role string) ([]corev1.Node, error)
 }
 
 // GetBySelector returns all nodes with the specified selector
-func GetNodesBySelector(f *framework.Framework, selector labels.Selector) ([]corev1.Node, error) {
+func GetNodesBySelector(f *framework.Framework, selector labels.Selector) ([]v1.Node, error) {
 	nodes, err := f.ClientSet.CoreV1().Nodes().List(context.TODO(), metav1.ListOptions{LabelSelector: selector.String()})
 	if err != nil {
 		return nil, err
@@ -63,13 +63,13 @@ func GetNodesBySelector(f *framework.Framework, selector labels.Selector) ([]cor
 }
 
 // FilterNodesWithEnoughCores returns all nodes with at least the amount of given CPU allocatable
-func FilterNodesWithEnoughCores(nodes []corev1.Node, cpuAmount string) ([]corev1.Node, error) {
+func FilterNodesWithEnoughCores(nodes []v1.Node, cpuAmount string) ([]v1.Node, error) {
 	requestCpu := resource.MustParse(cpuAmount)
 	framework.Logf("checking request %v on %d nodes", requestCpu, len(nodes))
 
-	resNodes := []corev1.Node{}
+	resNodes := []v1.Node{}
 	for _, node := range nodes {
-		availCpu, ok := node.Status.Allocatable[corev1.ResourceCPU]
+		availCpu, ok := node.Status.Allocatable[v1.ResourceCPU]
 		if !ok || availCpu.IsZero() {
 			return nil, fmt.Errorf("node %q has no allocatable CPU", node.Name)
 		}
diff --git a/test/e2e/utils/noderesourcetopology.go b/test/e2e/utils/noderesourcetopology.go
index 7ff6988e6..565126c5e 100644
--- a/test/e2e/utils/noderesourcetopology.go
+++ b/test/e2e/utils/noderesourcetopology.go
@@ -30,7 +30,7 @@ import (
 	"github.com/onsi/gomega"
 	"sigs.k8s.io/node-feature-discovery/pkg/topologypolicy"
 
-	corev1 "k8s.io/api/core/v1"
+	v1 "k8s.io/api/core/v1"
 	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 	extclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
 	"k8s.io/apimachinery/pkg/api/errors"
@@ -109,15 +109,15 @@ func GetNodeTopology(topologyClient *topologyclientset.Clientset, nodeName strin
 }
 
 // AllocatableResourceListFromNodeResourceTopology extract the map zone:allocatableResources from the given NodeResourceTopology instance.
-func AllocatableResourceListFromNodeResourceTopology(nodeTopo *v1alpha1.NodeResourceTopology) map[string]corev1.ResourceList {
-	allocRes := make(map[string]corev1.ResourceList)
+func AllocatableResourceListFromNodeResourceTopology(nodeTopo *v1alpha1.NodeResourceTopology) map[string]v1.ResourceList {
+	allocRes := make(map[string]v1.ResourceList)
 	for _, zone := range nodeTopo.Zones {
 		if zone.Type != "Node" {
 			continue
 		}
-		resList := make(corev1.ResourceList)
+		resList := make(v1.ResourceList)
 		for _, res := range zone.Resources {
-			resList[corev1.ResourceName(res.Name)] = res.Allocatable.DeepCopy()
+			resList[v1.ResourceName(res.Name)] = res.Allocatable.DeepCopy()
 		}
 		if len(resList) == 0 {
 			continue
@@ -131,7 +131,7 @@ func AllocatableResourceListFromNodeResourceTopology(nodeTopo *v1alpha1.NodeReso
 // and informs the caller if the maps are equal. Here `equal` means the same zoneNames with the same resources, where the resources are equal if they have
 // the same resources with the same quantities. Returns the name of the different zone, the name of the different resources within the zone,
 // the comparison result (same semantic as strings.Compare) and a boolean that reports if the resourceLists are consistent. See `CompareResourceList`.
-func CompareAllocatableResources(expected, got map[string]corev1.ResourceList) (string, string, int, bool) {
+func CompareAllocatableResources(expected, got map[string]v1.ResourceList) (string, string, int, bool) {
 	if len(got) != len(expected) {
 		framework.Logf("-> expected=%v (len=%d) got=%v (len=%d)", expected, len(expected), got, len(got))
 		return "", "", 0, false
@@ -153,7 +153,7 @@ func CompareAllocatableResources(expected, got map[string]corev1.ResourceList) (
 // the comparison result (same semantic as strings.Compare) and a boolean that reports if the resourceLists are consistent.
 // The ResourceLists are consistent only if the represent the same resource set (all the resources listed in one are
 // also present in the another; no ResourceList is a superset nor a subset of the other)
-func CompareResourceList(expected, got corev1.ResourceList) (string, int, bool) {
+func CompareResourceList(expected, got v1.ResourceList) (string, int, bool) {
 	if len(got) != len(expected) {
 		framework.Logf("-> expected=%v (len=%d) got=%v (len=%d)", expected, len(expected), got, len(got))
 		return "", 0, false
diff --git a/test/e2e/utils/pod.go b/test/e2e/utils/pod.go
index d156c9bba..456597c3d 100644
--- a/test/e2e/utils/pod.go
+++ b/test/e2e/utils/pod.go
@@ -25,7 +25,7 @@ import (
 	"github.com/onsi/ginkgo/v2"
 
 	appsv1 "k8s.io/api/apps/v1"
-	corev1 "k8s.io/api/core/v1"
+	v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
@@ -44,23 +44,23 @@ const (
 )
 
 // GuarenteedSleeperPod makes a Guaranteed QoS class Pod object which long enough forever but requires `cpuLimit` exclusive CPUs.
-func GuaranteedSleeperPod(cpuLimit string) *corev1.Pod {
-	return &corev1.Pod{
+func GuaranteedSleeperPod(cpuLimit string) *v1.Pod {
+	return &v1.Pod{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: "sleeper-gu-pod",
 		},
-		Spec: corev1.PodSpec{
-			RestartPolicy: corev1.RestartPolicyNever,
-			Containers: []corev1.Container{
-				{
+		Spec: v1.PodSpec{
+			RestartPolicy: v1.RestartPolicyNever,
+			Containers: []v1.Container{
+				v1.Container{
 					Name:  "sleeper-gu-cnt",
 					Image: PauseImage,
-					Resources: corev1.ResourceRequirements{
-						Limits: corev1.ResourceList{
+					Resources: v1.ResourceRequirements{
+						Limits: v1.ResourceList{
 							// we use 1 core because that's the minimal meaningful quantity
-							corev1.ResourceName(corev1.ResourceCPU): resource.MustParse(cpuLimit),
+							v1.ResourceName(v1.ResourceCPU): resource.MustParse(cpuLimit),
 							// any random reasonable amount is fine
-							corev1.ResourceName(corev1.ResourceMemory): resource.MustParse("100Mi"),
+							v1.ResourceName(v1.ResourceMemory): resource.MustParse("100Mi"),
 						},
 					},
 				},
@@ -70,15 +70,15 @@ func GuaranteedSleeperPod(cpuLimit string) *corev1.Pod {
 }
 
 // BestEffortSleeperPod makes a Best Effort QoS class Pod object which sleeps long enough
-func BestEffortSleeperPod() *corev1.Pod {
-	return &corev1.Pod{
+func BestEffortSleeperPod() *v1.Pod {
+	return &v1.Pod{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: "sleeper-be-pod",
 		},
-		Spec: corev1.PodSpec{
-			RestartPolicy: corev1.RestartPolicyNever,
-			Containers: []corev1.Container{
-				{
+		Spec: v1.PodSpec{
+			RestartPolicy: v1.RestartPolicyNever,
+			Containers: []v1.Container{
+				v1.Container{
 					Name:  "sleeper-be-cnt",
 					Image: PauseImage,
 				},
@@ -88,7 +88,7 @@ func BestEffortSleeperPod() *corev1.Pod {
 }
 
 // DeletePodsAsync concurrently deletes all the pods in the given name:pod_object mapping. Returns when the longer operation ends.
-func DeletePodsAsync(f *framework.Framework, podMap map[string]*corev1.Pod) {
+func DeletePodsAsync(f *framework.Framework, podMap map[string]*v1.Pod) {
 	var wg sync.WaitGroup
 	for _, pod := range podMap {
 		wg.Add(1)
@@ -112,24 +112,24 @@ func DeletePodSyncByName(f *framework.Framework, podName string) {
 }
 
 // NFDMasterPod provide NFD master pod definition
-func NFDMasterPod(image string, onMasterNode bool) *corev1.Pod {
-	p := &corev1.Pod{
+func NFDMasterPod(image string, onMasterNode bool) *v1.Pod {
+	p := &v1.Pod{
 		ObjectMeta: metav1.ObjectMeta{
 			GenerateName: "nfd-master-",
 			Labels:       map[string]string{"name": "nfd-master-e2e"},
 		},
-		Spec: corev1.PodSpec{
-			Containers: []corev1.Container{
+		Spec: v1.PodSpec{
+			Containers: []v1.Container{
 				{
 					Name:            "node-feature-discovery",
 					Image:           image,
 					ImagePullPolicy: pullPolicy(),
 					Command:         []string{"nfd-master"},
-					Env: []corev1.EnvVar{
+					Env: []v1.EnvVar{
 						{
 							Name: "NODE_NAME",
-							ValueFrom: &corev1.EnvVarSource{
-								FieldRef: &corev1.ObjectFieldSelector{
+							ValueFrom: &v1.EnvVarSource{
+								FieldRef: &v1.ObjectFieldSelector{
 									FieldPath: "spec.nodeName",
 								},
 							},
@@ -138,17 +138,17 @@ func NFDMasterPod(image string, onMasterNode bool) *corev1.Pod {
 				},
 			},
 			ServiceAccountName: "nfd-master-e2e",
-			RestartPolicy:      corev1.RestartPolicyNever,
+			RestartPolicy:      v1.RestartPolicyNever,
 		},
 	}
 	if onMasterNode {
 		p.Spec.NodeSelector = map[string]string{"node-role.kubernetes.io/master": ""}
-		p.Spec.Tolerations = []corev1.Toleration{
+		p.Spec.Tolerations = []v1.Toleration{
 			{
 				Key:      "node-role.kubernetes.io/master",
-				Operator: corev1.TolerationOpEqual,
+				Operator: v1.TolerationOpEqual,
 				Value:    "",
-				Effect:   corev1.TaintEffectNoSchedule,
+				Effect:   v1.TaintEffectNoSchedule,
 			},
 		}
 	}
@@ -156,15 +156,15 @@ func NFDMasterPod(image string, onMasterNode bool) *corev1.Pod {
 }
 
 // NFDWorkerPod provides NFD worker pod definition
-func NFDWorkerPod(image string, extraArgs []string) *corev1.Pod {
-	p := &corev1.Pod{
+func NFDWorkerPod(image string, extraArgs []string) *v1.Pod {
+	p := &v1.Pod{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: "nfd-worker-" + string(uuid.NewUUID()),
 		},
 		Spec: *nfdWorkerPodSpec(image, extraArgs),
 	}
 
-	p.Spec.RestartPolicy = corev1.RestartPolicyNever
+	p.Spec.RestartPolicy = v1.RestartPolicyNever
 
 	return p
 }
@@ -182,7 +182,7 @@ func NFDTopologyUpdaterDaemonSet(kc KubeletConfig, image string, extraArgs []str
 }
 
 // newDaemonSet provide the new daemon set
-func newDaemonSet(name string, podSpec *corev1.PodSpec) *appsv1.DaemonSet {
+func newDaemonSet(name string, podSpec *v1.PodSpec) *appsv1.DaemonSet {
 	return &appsv1.DaemonSet{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: name + "-" + string(uuid.NewUUID()),
@@ -191,7 +191,7 @@ func newDaemonSet(name string, podSpec *corev1.PodSpec) *appsv1.DaemonSet {
 			Selector: &metav1.LabelSelector{
 				MatchLabels: map[string]string{"name": name},
 			},
-			Template: corev1.PodTemplateSpec{
+			Template: v1.PodTemplateSpec{
 				ObjectMeta: metav1.ObjectMeta{
 					Labels: map[string]string{"name": name},
 				},
@@ -202,26 +202,26 @@ func newDaemonSet(name string, podSpec *corev1.PodSpec) *appsv1.DaemonSet {
 	}
 }
 
-func nfdWorkerPodSpec(image string, extraArgs []string) *corev1.PodSpec {
-	return &corev1.PodSpec{
-		Containers: []corev1.Container{
+func nfdWorkerPodSpec(image string, extraArgs []string) *v1.PodSpec {
+	return &v1.PodSpec{
+		Containers: []v1.Container{
 			{
 				Name:            "node-feature-discovery",
 				Image:           image,
 				ImagePullPolicy: pullPolicy(),
 				Command:         []string{"nfd-worker"},
 				Args:            append([]string{"-server=nfd-master-e2e:8080"}, extraArgs...),
-				Env: []corev1.EnvVar{
+				Env: []v1.EnvVar{
 					{
 						Name: "NODE_NAME",
-						ValueFrom: &corev1.EnvVarSource{
-							FieldRef: &corev1.ObjectFieldSelector{
+						ValueFrom: &v1.EnvVarSource{
+							FieldRef: &v1.ObjectFieldSelector{
 								FieldPath: "spec.nodeName",
 							},
 						},
 					},
 				},
-				VolumeMounts: []corev1.VolumeMount{
+				VolumeMounts: []v1.VolumeMount{
 					{
 						Name:      "host-boot",
 						MountPath: "/host-boot",
@@ -251,50 +251,50 @@ func nfdWorkerPodSpec(image string, extraArgs []string) *corev1.PodSpec {
 			},
 		},
 		ServiceAccountName: "nfd-master-e2e",
-		DNSPolicy:          corev1.DNSClusterFirstWithHostNet,
-		Volumes: []corev1.Volume{
+		DNSPolicy:          v1.DNSClusterFirstWithHostNet,
+		Volumes: []v1.Volume{
 			{
 				Name: "host-boot",
-				VolumeSource: corev1.VolumeSource{
-					HostPath: &corev1.HostPathVolumeSource{
+				VolumeSource: v1.VolumeSource{
+					HostPath: &v1.HostPathVolumeSource{
 						Path: "/boot",
-						Type: newHostPathType(corev1.HostPathDirectory),
+						Type: newHostPathType(v1.HostPathDirectory),
 					},
 				},
 			},
 			{
 				Name: "host-os-release",
-				VolumeSource: corev1.VolumeSource{
-					HostPath: &corev1.HostPathVolumeSource{
+				VolumeSource: v1.VolumeSource{
+					HostPath: &v1.HostPathVolumeSource{
 						Path: "/etc/os-release",
-						Type: newHostPathType(corev1.HostPathFile),
+						Type: newHostPathType(v1.HostPathFile),
 					},
 				},
 			},
 			{
 				Name: "host-sys",
-				VolumeSource: corev1.VolumeSource{
-					HostPath: &corev1.HostPathVolumeSource{
+				VolumeSource: v1.VolumeSource{
+					HostPath: &v1.HostPathVolumeSource{
 						Path: "/sys",
-						Type: newHostPathType(corev1.HostPathDirectory),
+						Type: newHostPathType(v1.HostPathDirectory),
 					},
 				},
 			},
 			{
 				Name: "host-usr-lib",
-				VolumeSource: corev1.VolumeSource{
-					HostPath: &corev1.HostPathVolumeSource{
+				VolumeSource: v1.VolumeSource{
+					HostPath: &v1.HostPathVolumeSource{
 						Path: "/usr/lib",
-						Type: newHostPathType(corev1.HostPathDirectory),
+						Type: newHostPathType(v1.HostPathDirectory),
 					},
 				},
 			},
 			{
 				Name: "host-usr-src",
-				VolumeSource: corev1.VolumeSource{
-					HostPath: &corev1.HostPathVolumeSource{
+				VolumeSource: v1.VolumeSource{
+					HostPath: &v1.HostPathVolumeSource{
 						Path: "/usr/src",
-						Type: newHostPathType(corev1.HostPathDirectory),
+						Type: newHostPathType(v1.HostPathDirectory),
 					},
 				},
 			},
@@ -302,9 +302,9 @@ func nfdWorkerPodSpec(image string, extraArgs []string) *corev1.PodSpec {
 	}
 }
 
-func nfdTopologyUpdaterPodSpec(kc KubeletConfig, image string, extraArgs []string) *corev1.PodSpec {
-	return &corev1.PodSpec{
-		Containers: []corev1.Container{
+func nfdTopologyUpdaterPodSpec(kc KubeletConfig, image string, extraArgs []string) *v1.PodSpec {
+	return &v1.PodSpec{
+		Containers: []v1.Container{
 			{
 				Name:            "node-topology-updater",
 				Image:           image,
@@ -317,25 +317,25 @@ func nfdTopologyUpdaterPodSpec(kc KubeletConfig, image string, extraArgs []strin
 					"--watch-namespace=rte",
 					"--server=nfd-master-e2e:8080",
 				}, extraArgs...),
-				Env: []corev1.EnvVar{
+				Env: []v1.EnvVar{
 					{
 						Name: "NODE_NAME",
-						ValueFrom: &corev1.EnvVarSource{
-							FieldRef: &corev1.ObjectFieldSelector{
+						ValueFrom: &v1.EnvVarSource{
+							FieldRef: &v1.ObjectFieldSelector{
 								FieldPath: "spec.nodeName",
 							},
 						},
 					},
 				},
-				SecurityContext: &corev1.SecurityContext{
-					Capabilities: &corev1.Capabilities{
-						Drop: []corev1.Capability{"ALL"},
+				SecurityContext: &v1.SecurityContext{
+					Capabilities: &v1.Capabilities{
+						Drop: []v1.Capability{"ALL"},
 					},
 					RunAsUser:                pointer.Int64Ptr(0),
 					ReadOnlyRootFilesystem:   pointer.BoolPtr(true),
 					AllowPrivilegeEscalation: pointer.BoolPtr(false),
 				},
-				VolumeMounts: []corev1.VolumeMount{
+				VolumeMounts: []v1.VolumeMount{
 					{
 						Name:      "kubelet-podresources-conf",
 						MountPath: "/podresources/config.yaml",
@@ -352,32 +352,32 @@ func nfdTopologyUpdaterPodSpec(kc KubeletConfig, image string, extraArgs []strin
 			},
 		},
 		ServiceAccountName: "nfd-topology-updater-e2e",
-		DNSPolicy:          corev1.DNSClusterFirstWithHostNet,
-		Volumes: []corev1.Volume{
+		DNSPolicy:          v1.DNSClusterFirstWithHostNet,
+		Volumes: []v1.Volume{
 			{
 				Name: "kubelet-podresources-conf",
-				VolumeSource: corev1.VolumeSource{
-					HostPath: &corev1.HostPathVolumeSource{
+				VolumeSource: v1.VolumeSource{
+					HostPath: &v1.HostPathVolumeSource{
 						Path: kc.ConfigPath,
-						Type: newHostPathType(corev1.HostPathFile),
+						Type: newHostPathType(v1.HostPathFile),
 					},
 				},
 			},
 			{
 				Name: "kubelet-podresources-sock",
-				VolumeSource: corev1.VolumeSource{
-					HostPath: &corev1.HostPathVolumeSource{
+				VolumeSource: v1.VolumeSource{
+					HostPath: &v1.HostPathVolumeSource{
 						Path: kc.PodResourcesSocketPath,
-						Type: newHostPathType(corev1.HostPathSocket),
+						Type: newHostPathType(v1.HostPathSocket),
 					},
 				},
 			},
 			{
 				Name: "host-sys",
-				VolumeSource: corev1.VolumeSource{
-					HostPath: &corev1.HostPathVolumeSource{
+				VolumeSource: v1.VolumeSource{
+					HostPath: &v1.HostPathVolumeSource{
 						Path: "/sys",
-						Type: newHostPathType(corev1.HostPathDirectory),
+						Type: newHostPathType(v1.HostPathDirectory),
 					},
 				},
 			},
@@ -385,8 +385,8 @@ func nfdTopologyUpdaterPodSpec(kc KubeletConfig, image string, extraArgs []strin
 	}
 }
 
-func newHostPathType(typ corev1.HostPathType) *corev1.HostPathType {
-	hostPathType := new(corev1.HostPathType)
+func newHostPathType(typ v1.HostPathType) *v1.HostPathType {
+	hostPathType := new(v1.HostPathType)
 	*hostPathType = typ
 	return hostPathType
 }
@@ -412,9 +412,9 @@ func WaitForPodsReady(c clientset.Interface, ns, name string, minReadySeconds in
 	})
 }
 
-func pullPolicy() corev1.PullPolicy {
+func pullPolicy() v1.PullPolicy {
 	if *pullIfNotPresent {
-		return corev1.PullIfNotPresent
+		return v1.PullIfNotPresent
 	}
-	return corev1.PullAlways
+	return v1.PullAlways
 }
diff --git a/test/e2e/utils/rbac.go b/test/e2e/utils/rbac.go
index 14add8009..655c00493 100644
--- a/test/e2e/utils/rbac.go
+++ b/test/e2e/utils/rbac.go
@@ -20,7 +20,7 @@ import (
 	"context"
 	"flag"
 
-	corev1 "k8s.io/api/core/v1"
+	v1 "k8s.io/api/core/v1"
 	rbacv1 "k8s.io/api/rbac/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	clientset "k8s.io/client-go/kubernetes"
@@ -95,8 +95,8 @@ func DeconfigureRBAC(cs clientset.Interface, ns string) error {
 }
 
 // Configure service account required by NFD Master
-func createServiceAccountMaster(cs clientset.Interface, ns string) (*corev1.ServiceAccount, error) {
-	sa := &corev1.ServiceAccount{
+func createServiceAccountMaster(cs clientset.Interface, ns string) (*v1.ServiceAccount, error) {
+	sa := &v1.ServiceAccount{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      "nfd-master-e2e",
 			Namespace: ns,
@@ -106,8 +106,8 @@ func createServiceAccountMaster(cs clientset.Interface, ns string) (*corev1.Serv
 }
 
 // Configure service account required by NFD MTopology Updater
-func createServiceAccountTopologyUpdater(cs clientset.Interface, ns string) (*corev1.ServiceAccount, error) {
-	sa := &corev1.ServiceAccount{
+func createServiceAccountTopologyUpdater(cs clientset.Interface, ns string) (*v1.ServiceAccount, error) {
+	sa := &v1.ServiceAccount{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      "nfd-topology-updater-e2e",
 			Namespace: ns,
diff --git a/test/e2e/utils/service.go b/test/e2e/utils/service.go
index 5ada5ff45..a851cbf54 100644
--- a/test/e2e/utils/service.go
+++ b/test/e2e/utils/service.go
@@ -19,26 +19,26 @@ package utils
 import (
 	"context"
 
-	corev1 "k8s.io/api/core/v1"
+	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	clientset "k8s.io/client-go/kubernetes"
 )
 
 // CreateService creates nfd-master Service
-func CreateService(cs clientset.Interface, ns string) (*corev1.Service, error) {
-	svc := &corev1.Service{
+func CreateService(cs clientset.Interface, ns string) (*v1.Service, error) {
+	svc := &v1.Service{
 		ObjectMeta: metav1.ObjectMeta{
 			Name: "nfd-master-e2e",
 		},
-		Spec: corev1.ServiceSpec{
+		Spec: v1.ServiceSpec{
 			Selector: map[string]string{"name": "nfd-master-e2e"},
-			Ports: []corev1.ServicePort{
+			Ports: []v1.ServicePort{
 				{
-					Protocol: corev1.ProtocolTCP,
+					Protocol: v1.ProtocolTCP,
 					Port:     8080,
 				},
 			},
-			Type: corev1.ServiceTypeClusterIP,
+			Type: v1.ServiceTypeClusterIP,
 		},
 	}
 	return cs.CoreV1().Services(ns).Create(context.TODO(), svc, metav1.CreateOptions{})