1
0
Fork 0
mirror of https://github.com/kubernetes-sigs/node-feature-discovery.git synced 2025-03-14 20:56:42 +00:00

apis/nfd: move annotation and label consts from nfd-master

Move consts related to NFD annotations and labels from nfd-master to the
api. Makes them more logically accessible for clients.
This commit is contained in:
Markus Lehtonen 2022-08-16 21:39:11 +03:00
parent 906aad6717
commit c1e6b41e56
4 changed files with 137 additions and 119 deletions

View file

@ -0,0 +1,46 @@
/*
Copyright 2022 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 v1alpha1
const (
// FeatureLabelNs is the (default) namespace for feature labels.
FeatureLabelNs = "feature.node.kubernetes.io"
// FeatureLabelSubNsSuffix is the suffix for allowed feature label sub-namespaces.
FeatureLabelSubNsSuffix = "." + FeatureLabelNs
// ProfileLabelNs is the namespace for profile labels.
ProfileLabelNs = "profile.node.kubernetes.io"
// ProfileLabelSubNsSuffix is the suffix for allowed profile label sub-namespaces.
ProfileLabelSubNsSuffix = "." + ProfileLabelNs
// AnnotationNs namespace for all NFD-related annotations.
AnnotationNs = "nfd.node.kubernetes.io"
// ExtendedResourceAnnotation is the annotation that holds all extended resources managed by NFD.
ExtendedResourceAnnotation = AnnotationNs + "/extended-resources"
// FeatureLabelsAnnotation is the annotation that holds all feature labels managed by NFD.
FeatureLabelsAnnotation = AnnotationNs + "/feature-labels"
// MasterVersionAnnotation is the annotation that holds the version of nfd-master running on the node
MasterVersionAnnotation = AnnotationNs + "/master.version"
// WorkerVersionAnnotation is the annotation that holds the version of nfd-worker running on the node
WorkerVersionAnnotation = AnnotationNs + "/worker.version"
)

View file

@ -17,7 +17,6 @@ limitations under the License.
package nfdmaster
import (
"path"
"regexp"
"sort"
"strings"
@ -33,6 +32,7 @@ import (
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sclient "k8s.io/client-go/kubernetes"
"sigs.k8s.io/node-feature-discovery/pkg/apihelper"
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
"sigs.k8s.io/node-feature-discovery/pkg/labeler"
"sigs.k8s.io/node-feature-discovery/pkg/utils"
"sigs.k8s.io/node-feature-discovery/pkg/version"
@ -54,32 +54,31 @@ func newMockNode() *api.Node {
func newMockMaster(apihelper apihelper.APIHelpers) *nfdMaster {
return &nfdMaster{
nodeName: mockNodeName,
annotationNs: AnnotationNsBase,
args: Args{LabelWhiteList: utils.RegexpVal{Regexp: *regexp.MustCompile("")}},
apihelper: apihelper,
nodeName: mockNodeName,
args: Args{LabelWhiteList: utils.RegexpVal{Regexp: *regexp.MustCompile("")}},
apihelper: apihelper,
}
}
func TestUpdateNodeFeatures(t *testing.T) {
Convey("When I update the node using fake client", t, func() {
fakeFeatureLabels := map[string]string{
FeatureLabelNs + "/source-feature.1": "1",
FeatureLabelNs + "/source-feature.2": "2",
FeatureLabelNs + "/source-feature.3": "val3",
ProfileLabelNs + "/profile-a": "val4"}
nfdv1alpha1.FeatureLabelNs + "/source-feature.1": "1",
nfdv1alpha1.FeatureLabelNs + "/source-feature.2": "2",
nfdv1alpha1.FeatureLabelNs + "/source-feature.3": "val3",
nfdv1alpha1.ProfileLabelNs + "/profile-a": "val4"}
fakeAnnotations := map[string]string{"my-annotation": "my-val"}
fakeExtResources := ExtendedResources{FeatureLabelNs + "/source-feature.1": "1", FeatureLabelNs + "/source-feature.2": "2"}
fakeExtResources := ExtendedResources{nfdv1alpha1.FeatureLabelNs + "/source-feature.1": "1", nfdv1alpha1.FeatureLabelNs + "/source-feature.2": "2"}
fakeFeatureLabelNames := make([]string, 0, len(fakeFeatureLabels))
for k := range fakeFeatureLabels {
fakeFeatureLabelNames = append(fakeFeatureLabelNames, strings.TrimPrefix(k, FeatureLabelNs+"/"))
fakeFeatureLabelNames = append(fakeFeatureLabelNames, strings.TrimPrefix(k, nfdv1alpha1.FeatureLabelNs+"/"))
}
sort.Strings(fakeFeatureLabelNames)
fakeExtResourceNames := make([]string, 0, len(fakeExtResources))
for k := range fakeExtResources {
fakeExtResourceNames = append(fakeExtResourceNames, strings.TrimPrefix(k, FeatureLabelNs+"/"))
fakeExtResourceNames = append(fakeExtResourceNames, strings.TrimPrefix(k, nfdv1alpha1.FeatureLabelNs+"/"))
}
sort.Strings(fakeExtResourceNames)
@ -88,15 +87,15 @@ func TestUpdateNodeFeatures(t *testing.T) {
mockClient := &k8sclient.Clientset{}
// Mock node with old features
mockNode := newMockNode()
mockNode.Labels[FeatureLabelNs+"/old-feature"] = "old-value"
mockNode.Annotations[AnnotationNsBase+"/feature-labels"] = "old-feature"
mockNode.Labels[nfdv1alpha1.FeatureLabelNs+"/old-feature"] = "old-value"
mockNode.Annotations[nfdv1alpha1.AnnotationNs+"/feature-labels"] = "old-feature"
Convey("When I successfully update the node with feature labels", func() {
// Create a list of expected node metadata patches
metadataPatches := []apihelper.JsonPatch{
apihelper.NewJsonPatch("replace", "/metadata/annotations", AnnotationNsBase+"/feature-labels", strings.Join(fakeFeatureLabelNames, ",")),
apihelper.NewJsonPatch("add", "/metadata/annotations", AnnotationNsBase+"/extended-resources", strings.Join(fakeExtResourceNames, ",")),
apihelper.NewJsonPatch("remove", "/metadata/labels", FeatureLabelNs+"/old-feature", ""),
apihelper.NewJsonPatch("replace", "/metadata/annotations", nfdv1alpha1.AnnotationNs+"/feature-labels", strings.Join(fakeFeatureLabelNames, ",")),
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.AnnotationNs+"/extended-resources", strings.Join(fakeExtResourceNames, ",")),
apihelper.NewJsonPatch("remove", "/metadata/labels", nfdv1alpha1.FeatureLabelNs+"/old-feature", ""),
}
for k, v := range fakeFeatureLabels {
metadataPatches = append(metadataPatches, apihelper.NewJsonPatch("add", "/metadata/labels", k, v))
@ -176,7 +175,7 @@ func TestUpdateMasterNode(t *testing.T) {
mockNode := newMockNode()
Convey("When update operation succeeds", func() {
expectedPatches := []apihelper.JsonPatch{
apihelper.NewJsonPatch("add", "/metadata/annotations", AnnotationNsBase+"/master.version", version.Get())}
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.AnnotationNs+"/master.version", version.Get())}
mockHelper.On("GetClient").Return(mockClient, nil)
mockHelper.On("GetNode", mockClient, mockNodeName).Return(mockNode, nil)
mockHelper.On("PatchNode", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedPatches))).Return(nil)
@ -239,8 +238,8 @@ func TestAddingExtResources(t *testing.T) {
Convey("When the resource already exists", func() {
mockNode := newMockNode()
mockNode.Status.Capacity[api.ResourceName(FeatureLabelNs+"/feature-1")] = *resource.NewQuantity(1, resource.BinarySI)
mockResourceLabels := ExtendedResources{FeatureLabelNs + "/feature-1": "1"}
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)
})
@ -264,28 +263,28 @@ func TestRemovingExtResources(t *testing.T) {
mockMaster := newMockMaster(nil)
Convey("When none are removed", func() {
mockNode := newMockNode()
mockResourceLabels := ExtendedResources{FeatureLabelNs + "/feature-1": "1", FeatureLabelNs + "/feature-2": "2"}
mockNode.Annotations[AnnotationNsBase+"/extended-resources"] = "feature-1,feature-2"
mockNode.Status.Capacity[api.ResourceName(FeatureLabelNs+"/feature-1")] = *resource.NewQuantity(1, resource.BinarySI)
mockNode.Status.Capacity[api.ResourceName(FeatureLabelNs+"/feature-2")] = *resource.NewQuantity(2, resource.BinarySI)
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[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)
})
Convey("When the related label is gone", func() {
mockNode := newMockNode()
mockResourceLabels := ExtendedResources{FeatureLabelNs + "/feature-4": "", FeatureLabelNs + "/feature-2": "2"}
mockNode.Annotations[AnnotationNsBase+"/extended-resources"] = "feature-4,feature-2"
mockNode.Status.Capacity[api.ResourceName(FeatureLabelNs+"/feature-4")] = *resource.NewQuantity(4, resource.BinarySI)
mockNode.Status.Capacity[api.ResourceName(FeatureLabelNs+"/feature-2")] = *resource.NewQuantity(2, resource.BinarySI)
mockResourceLabels := ExtendedResources{nfdv1alpha1.FeatureLabelNs + "/feature-4": "", nfdv1alpha1.FeatureLabelNs + "/feature-2": "2"}
mockNode.Annotations[nfdv1alpha1.AnnotationNs+"/extended-resources"] = "feature-4,feature-2"
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[api.ResourceName(FeatureLabelNs+"/feature-1")] = *resource.NewQuantity(1, resource.BinarySI)
mockNode.Status.Capacity[api.ResourceName(FeatureLabelNs+"/feature-2")] = *resource.NewQuantity(2, resource.BinarySI)
mockResourceLabels := ExtendedResources{FeatureLabelNs + "/feature-2": "2"}
mockNode.Annotations[AnnotationNsBase+"/extended-resources"] = "feature-1,feature-2"
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)
So(len(patches), ShouldBeGreaterThan, 0)
})
@ -313,17 +312,14 @@ func TestSetLabels(t *testing.T) {
expectedStatusPatches := []apihelper.JsonPatch{}
wvAnnotation := path.Join(AnnotationNsBase, workerVersionAnnotation)
flAnnotation := path.Join(AnnotationNsBase, featureLabelAnnotation)
erAnnotation := path.Join(AnnotationNsBase, extendedResourceAnnotation)
Convey("When node update succeeds", func() {
expectedPatches := []apihelper.JsonPatch{
apihelper.NewJsonPatch("add", "/metadata/annotations", wvAnnotation, workerVer),
apihelper.NewJsonPatch("add", "/metadata/annotations", flAnnotation, strings.Join(mockLabelNames, ",")),
apihelper.NewJsonPatch("add", "/metadata/annotations", erAnnotation, ""),
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.WorkerVersionAnnotation, workerVer),
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.FeatureLabelsAnnotation, strings.Join(mockLabelNames, ",")),
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.ExtendedResourceAnnotation, ""),
}
for k, v := range mockLabels {
expectedPatches = append(expectedPatches, apihelper.NewJsonPatch("add", "/metadata/labels", FeatureLabelNs+"/"+k, v))
expectedPatches = append(expectedPatches, apihelper.NewJsonPatch("add", "/metadata/labels", nfdv1alpha1.FeatureLabelNs+"/"+k, v))
}
mockHelper.On("GetClient").Return(mockClient, nil)
@ -338,10 +334,10 @@ func TestSetLabels(t *testing.T) {
Convey("When -label-whitelist is specified", func() {
expectedPatches := []apihelper.JsonPatch{
apihelper.NewJsonPatch("add", "/metadata/annotations", wvAnnotation, workerVer),
apihelper.NewJsonPatch("add", "/metadata/annotations", flAnnotation, "feature-2"),
apihelper.NewJsonPatch("add", "/metadata/annotations", erAnnotation, ""),
apihelper.NewJsonPatch("add", "/metadata/labels", FeatureLabelNs+"/feature-2", mockLabels["feature-2"]),
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.WorkerVersionAnnotation, workerVer),
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.FeatureLabelsAnnotation, "feature-2"),
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.ExtendedResourceAnnotation, ""),
apihelper.NewJsonPatch("add", "/metadata/labels", nfdv1alpha1.FeatureLabelNs+"/feature-2", mockLabels["feature-2"]),
}
mockMaster.args.LabelWhiteList.Regexp = *regexp.MustCompile("^f.*2$")
@ -358,27 +354,27 @@ func TestSetLabels(t *testing.T) {
Convey("When -extra-label-ns and -instance are specified", func() {
// In the gRPC request the label names may omit the default ns
instance := "foo"
vendorFeatureLabel := "vendor." + FeatureLabelNs + "/feature-4"
vendorProfileLabel := "vendor." + ProfileLabelNs + "/feature-5"
vendorFeatureLabel := "vendor." + nfdv1alpha1.FeatureLabelNs + "/feature-4"
vendorProfileLabel := "vendor." + nfdv1alpha1.ProfileLabelNs + "/feature-5"
mockLabels := map[string]string{"feature-1": "val-1",
"valid.ns/feature-2": "val-2",
"invalid.ns/feature-3": "val-3",
vendorFeatureLabel: " val-4",
vendorProfileLabel: " val-5"}
expectedPatches := []apihelper.JsonPatch{
apihelper.NewJsonPatch("add", "/metadata/annotations", instance+"."+wvAnnotation, workerVer),
apihelper.NewJsonPatch("add", "/metadata/annotations", instance+"."+nfdv1alpha1.WorkerVersionAnnotation, workerVer),
apihelper.NewJsonPatch("add", "/metadata/annotations",
instance+"."+flAnnotation,
instance+"."+nfdv1alpha1.FeatureLabelsAnnotation,
"feature-1,valid.ns/feature-2,"+vendorFeatureLabel+","+vendorProfileLabel),
apihelper.NewJsonPatch("add", "/metadata/annotations", instance+"."+erAnnotation, ""),
apihelper.NewJsonPatch("add", "/metadata/labels", FeatureLabelNs+"/feature-1", mockLabels["feature-1"]),
apihelper.NewJsonPatch("add", "/metadata/annotations", instance+"."+nfdv1alpha1.ExtendedResourceAnnotation, ""),
apihelper.NewJsonPatch("add", "/metadata/labels", nfdv1alpha1.FeatureLabelNs+"/feature-1", mockLabels["feature-1"]),
apihelper.NewJsonPatch("add", "/metadata/labels", "valid.ns/feature-2", mockLabels["valid.ns/feature-2"]),
apihelper.NewJsonPatch("add", "/metadata/labels", vendorFeatureLabel, mockLabels[vendorFeatureLabel]),
apihelper.NewJsonPatch("add", "/metadata/labels", vendorProfileLabel, mockLabels[vendorProfileLabel]),
}
mockMaster.args.ExtraLabelNs = map[string]struct{}{"valid.ns": {}}
mockMaster.annotationNs = instance + "." + AnnotationNsBase
mockMaster.args.Instance = instance
mockHelper.On("GetClient").Return(mockClient, nil)
mockHelper.On("GetNode", mockClient, workerName).Return(mockNode, nil)
mockHelper.On("PatchNode", mockClient, mockNodeName, mock.MatchedBy(jsonPatchMatcher(expectedPatches))).Return(nil)
@ -388,19 +384,19 @@ func TestSetLabels(t *testing.T) {
Convey("Error is nil", func() {
So(err, ShouldBeNil)
})
mockMaster.annotationNs = AnnotationNsBase
mockMaster.args.Instance = ""
})
Convey("When -resource-labels is specified", func() {
expectedPatches := []apihelper.JsonPatch{
apihelper.NewJsonPatch("add", "/metadata/annotations", wvAnnotation, workerVer),
apihelper.NewJsonPatch("add", "/metadata/annotations", flAnnotation, "feature-2"),
apihelper.NewJsonPatch("add", "/metadata/annotations", erAnnotation, "feature-1,feature-3"),
apihelper.NewJsonPatch("add", "/metadata/labels", FeatureLabelNs+"/feature-2", mockLabels["feature-2"]),
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.WorkerVersionAnnotation, workerVer),
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.FeatureLabelsAnnotation, "feature-2"),
apihelper.NewJsonPatch("add", "/metadata/annotations", nfdv1alpha1.ExtendedResourceAnnotation, "feature-1,feature-3"),
apihelper.NewJsonPatch("add", "/metadata/labels", nfdv1alpha1.FeatureLabelNs+"/feature-2", mockLabels["feature-2"]),
}
expectedStatusPatches := []apihelper.JsonPatch{
apihelper.NewJsonPatch("add", "/status/capacity", FeatureLabelNs+"/feature-1", mockLabels["feature-1"]),
apihelper.NewJsonPatch("add", "/status/capacity", FeatureLabelNs+"/feature-3", mockLabels["feature-3"]),
apihelper.NewJsonPatch("add", "/status/capacity", nfdv1alpha1.FeatureLabelNs+"/feature-1", mockLabels["feature-1"]),
apihelper.NewJsonPatch("add", "/status/capacity", nfdv1alpha1.FeatureLabelNs+"/feature-3", mockLabels["feature-3"]),
}
mockMaster.args.ResourceLabels = map[string]struct{}{"feature-3": {}, "feature-1": {}}

View file

@ -52,29 +52,6 @@ import (
"sigs.k8s.io/node-feature-discovery/pkg/version"
)
const (
// FeatureLabelNs is the namespace for feature labels
FeatureLabelNs = "feature.node.kubernetes.io"
// FeatureLabelSubNsSuffix is the suffix for allowed feature label sub-namespaces
FeatureLabelSubNsSuffix = "." + FeatureLabelNs
// ProfileLabelNs is the namespace for profile labels
ProfileLabelNs = "profile.node.kubernetes.io"
// ProfileLabelSubNsSuffix is the suffix for allowed profile label sub-namespaces
ProfileLabelSubNsSuffix = "." + ProfileLabelNs
// AnnotationNsBase namespace for all NFD-related annotations
AnnotationNsBase = "nfd.node.kubernetes.io"
// NFD Annotations
extendedResourceAnnotation = "extended-resources"
featureLabelAnnotation = "feature-labels"
masterVersionAnnotation = "master.version"
workerVersionAnnotation = "worker.version"
)
// Labels are a Kubernetes representation of discovered features.
type Labels map[string]string
@ -110,14 +87,13 @@ type NfdMaster interface {
type nfdMaster struct {
*nfdController
args Args
nodeName string
annotationNs string
server *grpc.Server
stop chan struct{}
ready chan bool
apihelper apihelper.APIHelpers
kubeconfig *restclient.Config
args Args
nodeName string
server *grpc.Server
stop chan struct{}
ready chan bool
apihelper apihelper.APIHelpers
kubeconfig *restclient.Config
}
// NewNfdMaster creates a new NfdMaster server instance.
@ -128,15 +104,12 @@ func NewNfdMaster(args *Args) (NfdMaster, error) {
stop: make(chan struct{}, 1),
}
if args.Instance == "" {
nfd.annotationNs = AnnotationNsBase
} else {
if args.Instance != "" {
if ok, _ := regexp.MatchString(`^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$`, args.Instance); !ok {
return nfd, fmt.Errorf("invalid -instance %q: instance name "+
"must start and end with an alphanumeric character and may only contain "+
"alphanumerics, `-`, `_` or `.`", args.Instance)
}
nfd.annotationNs = args.Instance + "." + AnnotationNsBase
}
// Check TLS related args
@ -311,7 +284,7 @@ func (m *nfdMaster) prune() error {
return err
}
for a := range node.Annotations {
if strings.HasPrefix(a, m.annotationNs) {
if strings.HasPrefix(a, m.instanceAnnotation(nfdv1alpha1.AnnotationNs)) {
delete(node.Annotations, a)
}
}
@ -337,7 +310,7 @@ func (m *nfdMaster) updateMasterNode() error {
// Advertise NFD version as an annotation
p := createPatches(nil,
node.Annotations,
Annotations{m.annotationName(masterVersionAnnotation): version.Get()},
Annotations{m.instanceAnnotation(nfdv1alpha1.MasterVersionAnnotation): version.Get()},
"/metadata/annotations")
err = m.apihelper.PatchNode(cli, node.Name, p)
if err != nil {
@ -356,13 +329,13 @@ func filterFeatureLabels(labels Labels, extraLabelNs map[string]struct{}, labelW
for label, value := range labels {
// Add possibly missing default ns
label := addNs(label, FeatureLabelNs)
label := addNs(label, nfdv1alpha1.FeatureLabelNs)
ns, name := splitNs(label)
// Check label namespace, filter out if ns is not whitelisted
if ns != FeatureLabelNs && ns != ProfileLabelNs &&
!strings.HasSuffix(ns, FeatureLabelSubNsSuffix) && !strings.HasSuffix(ns, ProfileLabelSubNsSuffix) {
if ns != nfdv1alpha1.FeatureLabelNs && ns != nfdv1alpha1.ProfileLabelNs &&
!strings.HasSuffix(ns, nfdv1alpha1.FeatureLabelSubNsSuffix) && !strings.HasSuffix(ns, nfdv1alpha1.ProfileLabelSubNsSuffix) {
if _, ok := extraLabelNs[ns]; !ok {
klog.Errorf("Namespace %q is not allowed. Ignoring label %q\n", ns, label)
continue
@ -381,7 +354,7 @@ func filterFeatureLabels(labels Labels, extraLabelNs map[string]struct{}, labelW
extendedResources := ExtendedResources{}
for extendedResourceName := range extendedResourceNames {
// Add possibly missing default ns
extendedResourceName = addNs(extendedResourceName, FeatureLabelNs)
extendedResourceName = addNs(extendedResourceName, nfdv1alpha1.FeatureLabelNs)
if value, ok := outLabels[extendedResourceName]; ok {
if _, err := strconv.Atoi(value); err != nil {
klog.Errorf("bad label value (%s: %s) encountered for extended resource: %s", extendedResourceName, value, err.Error())
@ -437,7 +410,7 @@ func (m *nfdMaster) SetLabels(c context.Context, r *pb.SetLabelsRequest) (*pb.Se
if !m.args.NoPublish {
// Advertise NFD worker version as an annotation
annotations := Annotations{m.annotationName(workerVersionAnnotation): r.NfdVersion}
annotations := Annotations{m.instanceAnnotation(nfdv1alpha1.WorkerVersionAnnotation): r.NfdVersion}
err := m.updateNodeFeatures(r.NodeName, labels, annotations, extendedResources)
if err != nil {
@ -561,22 +534,22 @@ func (m *nfdMaster) updateNodeFeatures(nodeName string, labels Labels, annotatio
labelKeys := make([]string, 0, len(labels))
for key := range labels {
// Drop the ns part for labels in the default ns
labelKeys = append(labelKeys, strings.TrimPrefix(key, FeatureLabelNs+"/"))
labelKeys = append(labelKeys, strings.TrimPrefix(key, nfdv1alpha1.FeatureLabelNs+"/"))
}
sort.Strings(labelKeys)
annotations[m.annotationName(featureLabelAnnotation)] = strings.Join(labelKeys, ",")
annotations[m.instanceAnnotation(nfdv1alpha1.FeatureLabelsAnnotation)] = strings.Join(labelKeys, ",")
// Store names of extended resources in an annotation
extendedResourceKeys := make([]string, 0, len(extendedResources))
for key := range extendedResources {
// Drop the ns part if in the default ns
extendedResourceKeys = append(extendedResourceKeys, strings.TrimPrefix(key, FeatureLabelNs+"/"))
extendedResourceKeys = append(extendedResourceKeys, strings.TrimPrefix(key, nfdv1alpha1.FeatureLabelNs+"/"))
}
sort.Strings(extendedResourceKeys)
annotations[m.annotationName(extendedResourceAnnotation)] = strings.Join(extendedResourceKeys, ",")
annotations[m.instanceAnnotation(nfdv1alpha1.ExtendedResourceAnnotation)] = strings.Join(extendedResourceKeys, ",")
// Create JSON patches for changes in labels and annotations
oldLabels := stringToNsNames(node.Annotations[m.annotationName(featureLabelAnnotation)], FeatureLabelNs)
oldLabels := stringToNsNames(node.Annotations[m.instanceAnnotation(nfdv1alpha1.FeatureLabelsAnnotation)], nfdv1alpha1.FeatureLabelNs)
patches := createPatches(oldLabels, node.Labels, labels, "/metadata/labels")
patches = append(patches, createPatches(nil, node.Annotations, annotations, "/metadata/annotations")...)
@ -602,10 +575,6 @@ func (m *nfdMaster) updateNodeFeatures(nodeName string, labels Labels, annotatio
return err
}
func (m *nfdMaster) annotationName(name string) string {
return path.Join(m.annotationNs, name)
}
func (m *nfdMaster) getKubeconfig() (*restclient.Config, error) {
var err error
if m.kubeconfig == nil {
@ -647,7 +616,7 @@ func (m *nfdMaster) createExtendedResourcePatches(n *api.Node, extendedResources
patches := []apihelper.JsonPatch{}
// Form a list of namespaced resource names managed by us
oldResources := stringToNsNames(n.Annotations[m.annotationName(extendedResourceAnnotation)], FeatureLabelNs)
oldResources := stringToNsNames(n.Annotations[m.instanceAnnotation(nfdv1alpha1.ExtendedResourceAnnotation)], nfdv1alpha1.FeatureLabelNs)
// figure out which resources to remove
for _, resource := range oldResources {
@ -762,3 +731,10 @@ func (m *nfdMaster) updateCR(hostname string, tmpolicy []string, topoUpdaterZone
utils.KlogDump(2, "CR instance updated resTopo:", " ", nrtUpdated)
return nil
}
func (m *nfdMaster) instanceAnnotation(name string) string {
if m.args.Instance == "" {
return name
}
return m.args.Instance + "." + name
}

View file

@ -36,7 +36,7 @@ import (
e2enetwork "k8s.io/kubernetes/test/e2e/framework/network"
e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
master "sigs.k8s.io/node-feature-discovery/pkg/nfd-master"
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
"sigs.k8s.io/node-feature-discovery/source/custom"
testutils "sigs.k8s.io/node-feature-discovery/test/e2e/utils"
)
@ -62,7 +62,7 @@ func cleanupNode(cs clientset.Interface) {
update := false
// Remove labels
for key := range node.Labels {
if strings.HasPrefix(key, master.FeatureLabelNs) {
if strings.HasPrefix(key, nfdv1alpha1.FeatureLabelNs) {
delete(node.Labels, key)
update = true
}
@ -70,7 +70,7 @@ func cleanupNode(cs clientset.Interface) {
// Remove annotations
for key := range node.Annotations {
if strings.HasPrefix(key, master.AnnotationNsBase) {
if strings.HasPrefix(key, nfdv1alpha1.AnnotationNs) {
delete(node.Annotations, key)
update = true
}
@ -126,7 +126,7 @@ var _ = SIGDescribe("Node Feature Discovery", func() {
// Node running nfd-master should have master version annotation
masterPodNode, err := f.ClientSet.CoreV1().Nodes().Get(context.TODO(), masterPod.Spec.NodeName, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred())
Expect(masterPodNode.Annotations).To(HaveKey(master.AnnotationNsBase + "/master.version"))
Expect(masterPodNode.Annotations).To(HaveKey(nfdv1alpha1.AnnotationNs + "/master.version"))
By("Waiting for the nfd-master service to be up")
Expect(e2enetwork.WaitForService(f.ClientSet, f.Namespace.Name, nfdSvc.ObjectMeta.Name, true, time.Second, 10*time.Second)).NotTo(HaveOccurred())
@ -145,9 +145,9 @@ var _ = SIGDescribe("Node Feature Discovery", func() {
It("it should decorate the node with the fake feature labels", func() {
fakeFeatureLabels := map[string]string{
master.FeatureLabelNs + "/fake-fakefeature1": "true",
master.FeatureLabelNs + "/fake-fakefeature2": "true",
master.FeatureLabelNs + "/fake-fakefeature3": "true",
nfdv1alpha1.FeatureLabelNs + "/fake-fakefeature1": "true",
nfdv1alpha1.FeatureLabelNs + "/fake-fakefeature2": "true",
nfdv1alpha1.FeatureLabelNs + "/fake-fakefeature3": "true",
}
// Launch nfd-worker
@ -171,7 +171,7 @@ var _ = SIGDescribe("Node Feature Discovery", func() {
// Check that there are no unexpected NFD labels
for k := range node.Labels {
if strings.HasPrefix(k, master.FeatureLabelNs) {
if strings.HasPrefix(k, nfdv1alpha1.FeatureLabelNs) {
Expect(fakeFeatureLabels).Should(HaveKey(k))
}
}
@ -226,7 +226,7 @@ var _ = SIGDescribe("Node Feature Discovery", func() {
Expect(node.Labels).To(HaveKey(k))
}
for k := range node.Labels {
if strings.HasPrefix(k, master.FeatureLabelNs) {
if strings.HasPrefix(k, nfdv1alpha1.FeatureLabelNs) {
if _, ok := nodeConf.ExpectedLabelValues[k]; ok {
continue
}
@ -247,7 +247,7 @@ var _ = SIGDescribe("Node Feature Discovery", func() {
Expect(node.Annotations).To(HaveKey(k))
}
for k := range node.Annotations {
if strings.HasPrefix(k, master.AnnotationNsBase) {
if strings.HasPrefix(k, nfdv1alpha1.AnnotationNs) {
if _, ok := nodeConf.ExpectedAnnotationValues[k]; ok {
continue
}