diff --git a/deployment/base/nfd-crds/cr-sample.yaml b/deployment/base/nfd-crds/cr-sample.yaml index dad9405d08..51192cf515 100644 --- a/deployment/base/nfd-crds/cr-sample.yaml +++ b/deployment/base/nfd-crds/cr-sample.yaml @@ -88,6 +88,13 @@ spec: vendor: {op: In, value: ["8086"]} class: {op: In, value: ["02"]} + - name: "avx wildcard rule" + labels: + "my-avx-feature": "true" + matchFeatures: + - feature: cpu.cpuid + matchName: {op: InRegexp, value: ["^AVX512"]} + # The following features demonstreate label templating capabilities - name: "my system template feature" labelsTemplate: | @@ -137,3 +144,11 @@ spec: matchExpressions: my.kernel.feature: {op: IsTrue} my.dummy.var: {op: Gt, value: ["0"]} + + - name: "kconfig template rule" + labelsTemplate: | + {{ range .kernel.config }}kconfig-{{ .Name }}={{ .Value }} + {{ end }} + matchFeatures: + - feature: kernel.config + matchName: {op: In, value: ["SWAP", "X86", "ARM"]} diff --git a/deployment/base/nfd-crds/nodefeaturerule-crd.yaml b/deployment/base/nfd-crds/nodefeaturerule-crd.yaml index cd9b48bf46..705bae85cc 100644 --- a/deployment/base/nfd-crds/nodefeaturerule-crd.yaml +++ b/deployment/base/nfd-crds/nodefeaturerule-crd.yaml @@ -70,6 +70,8 @@ spec: in the feature set. properties: feature: + description: Feature is the name of the feature + set to match against. type: string matchExpressions: additionalProperties: @@ -114,13 +116,46 @@ spec: required: - op type: object - description: MatchExpressionSet contains a set of - MatchExpressions, each of which is evaluated against - a set of input values. + description: MatchExpressions is the set of per-element + expressions evaluated. These match against the + value of the specified elements. + type: object + matchName: + description: MatchName in an expression that is + matched against the name of each element in the + feature set. + properties: + op: + description: Op is the operator to be applied. + enum: + - In + - NotIn + - InRegexp + - Exists + - DoesNotExist + - Gt + - Lt + - GtLt + - IsTrue + - IsFalse + type: string + value: + description: Value is the list of values that + the operand evaluates the input against. Value + should be empty if the operator is Exists, + DoesNotExist, IsTrue or IsFalse. Value should + contain exactly one element if the operator + is Gt or Lt and exactly two elements if the + operator is GtLt. In other cases Value should + contain at least one element. + items: + type: string + type: array + required: + - op type: object required: - feature - - matchExpressions type: object type: array required: @@ -136,6 +171,8 @@ spec: are evaluated against each element in the feature set. properties: feature: + description: Feature is the name of the feature set to + match against. type: string matchExpressions: additionalProperties: @@ -177,12 +214,44 @@ spec: required: - op type: object - description: MatchExpressionSet contains a set of MatchExpressions, - each of which is evaluated against a set of input values. + description: MatchExpressions is the set of per-element + expressions evaluated. These match against the value + of the specified elements. + type: object + matchName: + description: MatchName in an expression that is matched + against the name of each element in the feature set. + properties: + op: + description: Op is the operator to be applied. + enum: + - In + - NotIn + - InRegexp + - Exists + - DoesNotExist + - Gt + - Lt + - GtLt + - IsTrue + - IsFalse + type: string + value: + description: Value is the list of values that the + operand evaluates the input against. Value should + be empty if the operator is Exists, DoesNotExist, + IsTrue or IsFalse. Value should contain exactly + one element if the operator is Gt or Lt and exactly + two elements if the operator is GtLt. In other cases + Value should contain at least one element. + items: + type: string + type: array + required: + - op type: object required: - feature - - matchExpressions type: object type: array name: diff --git a/deployment/components/worker-config/nfd-worker.conf.example b/deployment/components/worker-config/nfd-worker.conf.example index eb5030bd5e..0cfb8aa057 100644 --- a/deployment/components/worker-config/nfd-worker.conf.example +++ b/deployment/components/worker-config/nfd-worker.conf.example @@ -171,6 +171,13 @@ # vendor: {op: In, value: ["8086"]} # class: {op: In, value: ["02"]} # +# - name: "avx wildcard rule" +# labels: +# "my-avx-feature": "true" +# matchFeatures: +# - feature: cpu.cpuid +# matchName: {op: InRegexp, value: ["^AVX512"]} +# # # The following features demonstreate label templating capabilities # - name: "my template rule" # labelsTemplate: | @@ -221,3 +228,10 @@ # my.kernel.feature: {op: IsTrue} # my.dummy.var: {op: Gt, value: ["0"]} # +# - name: "kconfig template rule" +# labelsTemplate: | +# {{ range .kernel.config }}kconfig-{{ .Name }}={{ .Value }} +# {{ end }} +# matchFeatures: +# - feature: kernel.config +# matchName: {op: In, value: ["SWAP", "X86", "ARM"]} diff --git a/deployment/helm/node-feature-discovery/manifests/nodefeaturerule-crd.yaml b/deployment/helm/node-feature-discovery/manifests/nodefeaturerule-crd.yaml index cd9b48bf46..705bae85cc 100644 --- a/deployment/helm/node-feature-discovery/manifests/nodefeaturerule-crd.yaml +++ b/deployment/helm/node-feature-discovery/manifests/nodefeaturerule-crd.yaml @@ -70,6 +70,8 @@ spec: in the feature set. properties: feature: + description: Feature is the name of the feature + set to match against. type: string matchExpressions: additionalProperties: @@ -114,13 +116,46 @@ spec: required: - op type: object - description: MatchExpressionSet contains a set of - MatchExpressions, each of which is evaluated against - a set of input values. + description: MatchExpressions is the set of per-element + expressions evaluated. These match against the + value of the specified elements. + type: object + matchName: + description: MatchName in an expression that is + matched against the name of each element in the + feature set. + properties: + op: + description: Op is the operator to be applied. + enum: + - In + - NotIn + - InRegexp + - Exists + - DoesNotExist + - Gt + - Lt + - GtLt + - IsTrue + - IsFalse + type: string + value: + description: Value is the list of values that + the operand evaluates the input against. Value + should be empty if the operator is Exists, + DoesNotExist, IsTrue or IsFalse. Value should + contain exactly one element if the operator + is Gt or Lt and exactly two elements if the + operator is GtLt. In other cases Value should + contain at least one element. + items: + type: string + type: array + required: + - op type: object required: - feature - - matchExpressions type: object type: array required: @@ -136,6 +171,8 @@ spec: are evaluated against each element in the feature set. properties: feature: + description: Feature is the name of the feature set to + match against. type: string matchExpressions: additionalProperties: @@ -177,12 +214,44 @@ spec: required: - op type: object - description: MatchExpressionSet contains a set of MatchExpressions, - each of which is evaluated against a set of input values. + description: MatchExpressions is the set of per-element + expressions evaluated. These match against the value + of the specified elements. + type: object + matchName: + description: MatchName in an expression that is matched + against the name of each element in the feature set. + properties: + op: + description: Op is the operator to be applied. + enum: + - In + - NotIn + - InRegexp + - Exists + - DoesNotExist + - Gt + - Lt + - GtLt + - IsTrue + - IsFalse + type: string + value: + description: Value is the list of values that the + operand evaluates the input against. Value should + be empty if the operator is Exists, DoesNotExist, + IsTrue or IsFalse. Value should contain exactly + one element if the operator is Gt or Lt and exactly + two elements if the operator is GtLt. In other cases + Value should contain at least one element. + items: + type: string + type: array + required: + - op type: object required: - feature - - matchExpressions type: object type: array name: diff --git a/deployment/helm/node-feature-discovery/values.yaml b/deployment/helm/node-feature-discovery/values.yaml index 466c75dbbc..0fec891eed 100644 --- a/deployment/helm/node-feature-discovery/values.yaml +++ b/deployment/helm/node-feature-discovery/values.yaml @@ -264,6 +264,13 @@ worker: # vendor: {op: In, value: ["8086"]} # class: {op: In, value: ["02"]} # + # - name: "avx wildcard rule" + # labels: + # "my-avx-feature": "true" + # matchFeatures: + # - feature: cpu.cpuid + # matchName: {op: InRegexp, value: ["^AVX512"]} + # # # The following features demonstreate label templating capabilities # - name: "my template rule" # labelsTemplate: | @@ -314,6 +321,13 @@ worker: # my.kernel.feature: {op: IsTrue} # my.dummy.var: {op: Gt, value: ["0"]} # + # - name: "kconfig template rule" + # labelsTemplate: | + # {{ range .kernel.config }}kconfig-{{ .Name }}={{ .Value }} + # {{ end }} + # matchFeatures: + # - feature: kernel.config + # matchName: {op: In, value: ["SWAP", "X86", "ARM"]} ### daemonsetAnnotations: {} diff --git a/pkg/api/feature/generated.pb.go b/pkg/api/feature/generated.pb.go index 33df143ccd..cfe7c772bd 100644 --- a/pkg/api/feature/generated.pb.go +++ b/pkg/api/feature/generated.pb.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/api/feature/generated.proto b/pkg/api/feature/generated.proto index c3ae18b332..9ab6b7ad4b 100644 --- a/pkg/api/feature/generated.proto +++ b/pkg/api/feature/generated.proto @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/apis/nfd/v1alpha1/expression.go b/pkg/apis/nfd/v1alpha1/expression.go index 41a032b405..330eb2bcea 100644 --- a/pkg/apis/nfd/v1alpha1/expression.go +++ b/pkg/apis/nfd/v1alpha1/expression.go @@ -270,6 +270,93 @@ func (m *MatchExpression) MatchValues(name string, values map[string]string) (bo return matched, nil } +// MatchKeyNames evaluates the MatchExpression against names of a set of key features. +func (m *MatchExpression) MatchKeyNames(keys map[string]feature.Nil) (bool, []MatchedKey, error) { + ret := []MatchedKey{} + + for k := range keys { + if match, err := m.Match(true, k); err != nil { + return false, nil, err + } else if match { + ret = append(ret, MatchedKey{Name: k}) + } + } + // Sort for reproducible output + sort.Slice(ret, func(i, j int) bool { return ret[i].Name < ret[j].Name }) + + if klog.V(3).Enabled() { + mk := make([]string, len(ret)) + for i, v := range ret { + mk[i] = v.Name + } + + k := make([]string, 0, len(keys)) + for n := range keys { + k = append(k, n) + } + sort.Strings(k) + + if len(keys) < 10 || klog.V(4).Enabled() { + klog.Infof("matched names %s when matching %q %q against %s", strings.Join(mk, ", "), m.Op, m.Value, strings.Join(k, " ")) + } else { + klog.Infof("matched names %s when matching %q %q against %s... (list truncated)", strings.Join(mk, ", "), m.Op, m.Value, strings.Join(k[0:10], ", ")) + } + } + + return true, ret, nil +} + +// MatchValueNames evaluates the MatchExpression against names of a set of value features. +func (m *MatchExpression) MatchValueNames(values map[string]string) (bool, []MatchedValue, error) { + ret := []MatchedValue{} + + for k, v := range values { + if match, err := m.Match(true, k); err != nil { + return false, nil, err + } else if match { + ret = append(ret, MatchedValue{Name: k, Value: v}) + } + } + // Sort for reproducible output + sort.Slice(ret, func(i, j int) bool { return ret[i].Name < ret[j].Name }) + + if klog.V(3).Enabled() { + mk := make([]string, len(ret)) + for i, v := range ret { + mk[i] = v.Name + } + + k := make([]string, 0, len(values)) + for n := range values { + k = append(k, n) + } + sort.Strings(k) + + if len(values) < 10 || klog.V(4).Enabled() { + klog.Infof("matched names %s when matching %q %q against %s", strings.Join(mk, ", "), m.Op, m.Value, strings.Join(k, " ")) + } else { + klog.Infof("matched names %s when matching %q %q against %s... (list truncated)", strings.Join(mk, ", "), m.Op, m.Value, strings.Join(k[0:10], ", ")) + } + } + + return true, ret, nil +} + +// MatchInstanceAttributeNames evaluates the MatchExpression against a set of +// instance features, matching against the names of their attributes. +func (m *MatchExpression) MatchInstanceAttributeNames(instances []feature.InstanceFeature) ([]MatchedInstance, error) { + ret := []MatchedInstance{} + + for _, i := range instances { + if match, _, err := m.MatchValueNames(i.Attributes); err != nil { + return nil, err + } else if match { + ret = append(ret, i.Attributes) + } + } + return ret, nil +} + // matchExpression is a helper type for unmarshalling MatchExpression type matchExpression MatchExpression diff --git a/pkg/apis/nfd/v1alpha1/rule.go b/pkg/apis/nfd/v1alpha1/rule.go index 267680326f..7c908793eb 100644 --- a/pkg/apis/nfd/v1alpha1/rule.go +++ b/pkg/apis/nfd/v1alpha1/rule.go @@ -174,22 +174,49 @@ func (m *FeatureMatcher) match(features map[string]*feature.DomainFeatures) (boo matches[domain] = make(domainMatchedFeatures) } - var isMatch bool + var isMatch = true var err error if f, ok := domainFeatures.Keys[featureName]; ok { - m, v, e := term.MatchExpressions.MatchGetKeys(f.Elements) - isMatch = m - err = e + var v []MatchedKey + if term.MatchExpressions != nil { + isMatch, v, err = term.MatchExpressions.MatchGetKeys(f.Elements) + } + + if err == nil && isMatch && term.MatchName != nil { + mTmp, vTmp, e := term.MatchName.MatchKeyNames(f.Elements) + isMatch = mTmp + err = e + v = append(v, vTmp...) + } + matches[domain][featureName] = v } else if f, ok := domainFeatures.Values[featureName]; ok { - m, v, e := term.MatchExpressions.MatchGetValues(f.Elements) - isMatch = m - err = e + var v []MatchedValue + if term.MatchExpressions != nil { + isMatch, v, err = term.MatchExpressions.MatchGetValues(f.Elements) + } + + if err == nil && isMatch && term.MatchName != nil { + mTmp, vTmp, e := term.MatchName.MatchValueNames(f.Elements) + isMatch = mTmp + err = e + v = append(v, vTmp...) + } + matches[domain][featureName] = v } else if f, ok := domainFeatures.Instances[featureName]; ok { - v, e := term.MatchExpressions.MatchGetInstances(f.Elements) - isMatch = len(v) > 0 - err = e + var v []MatchedInstance + if term.MatchExpressions != nil { + v, err = term.MatchExpressions.MatchGetInstances(f.Elements) + isMatch = len(v) > 0 + } + + if err == nil && isMatch && term.MatchName != nil { + vTmp, e := term.MatchName.MatchInstanceAttributeNames(f.Elements) + isMatch = len(vTmp) > 0 + err = e + v = append(v, vTmp...) + } matches[domain][featureName] = v } else { return false, nil, fmt.Errorf("%q feature of source/domain %q not available", featureName, domain) diff --git a/pkg/apis/nfd/v1alpha1/rule_test.go b/pkg/apis/nfd/v1alpha1/rule_test.go index 87d9c7b3b0..e534eda6af 100644 --- a/pkg/apis/nfd/v1alpha1/rule_test.go +++ b/pkg/apis/nfd/v1alpha1/rule_test.go @@ -32,7 +32,7 @@ func TestRule(t *testing.T) { MatchFeatures: FeatureMatcher{ FeatureMatcherTerm{ Feature: "domain-1.kf-1", - MatchExpressions: MatchExpressionSet{ + MatchExpressions: &MatchExpressionSet{ Expressions: Expressions{"key-1": MustCreateMatchExpression(MatchExists)}, }, }, @@ -86,7 +86,7 @@ func TestRule(t *testing.T) { r1.MatchFeatures = FeatureMatcher{ FeatureMatcherTerm{ Feature: "domain-1.kf-1", - MatchExpressions: MatchExpressionSet{}, + MatchExpressions: &MatchExpressionSet{}, }, } m, err = r1.Execute(f) @@ -110,7 +110,7 @@ func TestRule(t *testing.T) { MatchFeatures: FeatureMatcher{ FeatureMatcherTerm{ Feature: "domain-1.vf-1", - MatchExpressions: MatchExpressionSet{ + MatchExpressions: &MatchExpressionSet{ Expressions: Expressions{"key-1": MustCreateMatchExpression(MatchIn, "val-1")}, }, }, @@ -131,7 +131,7 @@ func TestRule(t *testing.T) { MatchFeatures: FeatureMatcher{ FeatureMatcherTerm{ Feature: "domain-1.if-1", - MatchExpressions: MatchExpressionSet{ + MatchExpressions: &MatchExpressionSet{ Expressions: Expressions{"attr-1": MustCreateMatchExpression(MatchIn, "val-1")}, }, }, @@ -152,13 +152,13 @@ func TestRule(t *testing.T) { MatchFeatures: FeatureMatcher{ FeatureMatcherTerm{ Feature: "domain-1.vf-1", - MatchExpressions: MatchExpressionSet{ + MatchExpressions: &MatchExpressionSet{ Expressions: Expressions{"key-1": MustCreateMatchExpression(MatchIn, "val-x")}, }, }, FeatureMatcherTerm{ Feature: "domain-1.if-1", - MatchExpressions: MatchExpressionSet{ + MatchExpressions: &MatchExpressionSet{ Expressions: Expressions{"attr-1": MustCreateMatchExpression(MatchIn, "val-1")}, }, }, @@ -179,7 +179,7 @@ func TestRule(t *testing.T) { MatchFeatures: FeatureMatcher{ FeatureMatcherTerm{ Feature: "domain-1.kf-1", - MatchExpressions: MatchExpressionSet{ + MatchExpressions: &MatchExpressionSet{ Expressions: Expressions{"key-na": MustCreateMatchExpression(MatchExists)}, }, }, @@ -195,7 +195,7 @@ func TestRule(t *testing.T) { MatchFeatures: FeatureMatcher{ FeatureMatcherTerm{ Feature: "domain-1.kf-1", - MatchExpressions: MatchExpressionSet{ + MatchExpressions: &MatchExpressionSet{ Expressions: Expressions{"key-1": MustCreateMatchExpression(MatchExists)}, }, }, @@ -225,6 +225,7 @@ func TestTemplating(t *testing.T) { "key-1": "val-1", "keu-2": "val-2", "key-3": "val-3", + "key-4": "val-4", }, }, }, @@ -275,7 +276,7 @@ var-2= MatchFeatures: FeatureMatcher{ FeatureMatcherTerm{ Feature: "domain_1.kf_1", - MatchExpressions: MatchExpressionSet{Expressions: Expressions{ + MatchExpressions: &MatchExpressionSet{Expressions: Expressions{ "key-a": MustCreateMatchExpression(MatchExists), "key-c": MustCreateMatchExpression(MatchExists), "foo": MustCreateMatchExpression(MatchDoesNotExist), @@ -284,7 +285,7 @@ var-2= }, FeatureMatcherTerm{ Feature: "domain_1.vf_1", - MatchExpressions: MatchExpressionSet{Expressions: Expressions{ + MatchExpressions: &MatchExpressionSet{Expressions: Expressions{ "key-1": MustCreateMatchExpression(MatchIn, "val-1", "val-2"), "bar": MustCreateMatchExpression(MatchDoesNotExist), }, @@ -292,7 +293,7 @@ var-2= }, FeatureMatcherTerm{ Feature: "domain_1.if_1", - MatchExpressions: MatchExpressionSet{Expressions: Expressions{ + MatchExpressions: &MatchExpressionSet{Expressions: Expressions{ "attr-1": MustCreateMatchExpression(MatchLt, "100"), }, }, @@ -337,7 +338,7 @@ var-2= // Use a simple empty matchexpression set to match anything. FeatureMatcherTerm{ Feature: "domain_1.kf_1", - MatchExpressions: MatchExpressionSet{Expressions: Expressions{ + MatchExpressions: &MatchExpressionSet{Expressions: Expressions{ "key-a": MustCreateMatchExpression(MatchExists), }, }, @@ -379,4 +380,29 @@ var-2= _, err = r2.Execute(f) assert.Error(t, err) + // + // Test matchName + // + r3 := Rule{ + LabelsTemplate: "{{range .domain_1.vf_1}}{{.Name}}={{.Value}}\n{{end}}", + MatchFeatures: FeatureMatcher{ + FeatureMatcherTerm{ + Feature: "domain_1.vf_1", + MatchExpressions: &MatchExpressionSet{Expressions: Expressions{ + "key-5": MustCreateMatchExpression(MatchDoesNotExist), + }, + }, + MatchName: MustCreateMatchExpression(MatchIn, "key-1", "key-4"), + }, + }, + } + expectedLabels = map[string]string{ + "key-1": "val-1", + "key-4": "val-4", + "key-5": "", + } + + m, err = r3.Execute(f) + assert.Nilf(t, err, "unexpected error: %v", err) + assert.Equal(t, expectedLabels, m.Labels, "instances should have matched") } diff --git a/pkg/apis/nfd/v1alpha1/types.go b/pkg/apis/nfd/v1alpha1/types.go index b8982b49e7..6dd4f3c2ea 100644 --- a/pkg/apis/nfd/v1alpha1/types.go +++ b/pkg/apis/nfd/v1alpha1/types.go @@ -105,8 +105,16 @@ type FeatureMatcher []FeatureMatcherTerm // requirements (specified as MatchExpressions) are evaluated against each // element in the feature set. type FeatureMatcherTerm struct { - Feature string `json:"feature"` - MatchExpressions MatchExpressionSet `json:"matchExpressions"` + // Feature is the name of the feature set to match against. + Feature string `json:"feature"` + // MatchExpressions is the set of per-element expressions evaluated. These + // match against the value of the specified elements. + // +optional + MatchExpressions *MatchExpressionSet `json:"matchExpressions"` + // MatchName in an expression that is matched against the name of each + // element in the feature set. + // +optional + MatchName *MatchExpression `json:"matchName"` } // MatchExpressionSet contains a set of MatchExpressions, each of which is @@ -199,3 +207,7 @@ const ( // output of preceding rules. RuleBackrefFeature = "matched" ) + +// MatchAllNames is a special key in MatchExpressionSet to use field names +// (keys from the input) instead of values when matching. +const MatchAllNames = "*" diff --git a/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go index ece20769ab..7ee365e35e 100644 --- a/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/nfd/v1alpha1/zz_generated.deepcopy.go @@ -62,7 +62,16 @@ func (in FeatureMatcher) DeepCopy() FeatureMatcher { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *FeatureMatcherTerm) DeepCopyInto(out *FeatureMatcherTerm) { *out = *in - in.MatchExpressions.DeepCopyInto(&out.MatchExpressions) + if in.MatchExpressions != nil { + in, out := &in.MatchExpressions, &out.MatchExpressions + *out = new(MatchExpressionSet) + (*in).DeepCopyInto(*out) + } + if in.MatchName != nil { + in, out := &in.MatchName, &out.MatchName + *out = new(MatchExpression) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FeatureMatcherTerm. diff --git a/pkg/generated/clientset/versioned/clientset.go b/pkg/generated/clientset/versioned/clientset.go index 58f0e461cc..75330a9d95 100644 --- a/pkg/generated/clientset/versioned/clientset.go +++ b/pkg/generated/clientset/versioned/clientset.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/clientset/versioned/doc.go b/pkg/generated/clientset/versioned/doc.go index 92576525fa..ab7539cb9f 100644 --- a/pkg/generated/clientset/versioned/doc.go +++ b/pkg/generated/clientset/versioned/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/clientset/versioned/fake/clientset_generated.go b/pkg/generated/clientset/versioned/fake/clientset_generated.go index dd33f2a04d..9ba9e83904 100644 --- a/pkg/generated/clientset/versioned/fake/clientset_generated.go +++ b/pkg/generated/clientset/versioned/fake/clientset_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/clientset/versioned/fake/doc.go b/pkg/generated/clientset/versioned/fake/doc.go index 4b91eb6a64..7d98eabcc8 100644 --- a/pkg/generated/clientset/versioned/fake/doc.go +++ b/pkg/generated/clientset/versioned/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/clientset/versioned/fake/register.go b/pkg/generated/clientset/versioned/fake/register.go index a7846e07af..cdc746791a 100644 --- a/pkg/generated/clientset/versioned/fake/register.go +++ b/pkg/generated/clientset/versioned/fake/register.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/clientset/versioned/scheme/doc.go b/pkg/generated/clientset/versioned/scheme/doc.go index 6dc5e6530d..288d3794dc 100644 --- a/pkg/generated/clientset/versioned/scheme/doc.go +++ b/pkg/generated/clientset/versioned/scheme/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/clientset/versioned/scheme/register.go b/pkg/generated/clientset/versioned/scheme/register.go index cfac0d743c..b455617b6f 100644 --- a/pkg/generated/clientset/versioned/scheme/register.go +++ b/pkg/generated/clientset/versioned/scheme/register.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/doc.go b/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/doc.go index be4e7e92b5..5362dda2ff 100644 --- a/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/doc.go +++ b/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/fake/doc.go b/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/fake/doc.go index 43eec078a4..dd9e9e4c8f 100644 --- a/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/fake/doc.go +++ b/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nfd_client.go b/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nfd_client.go index 8bf3fc196a..7133268330 100644 --- a/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nfd_client.go +++ b/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nfd_client.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeaturerule.go b/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeaturerule.go index 7710634ef1..b4afd87f99 100644 --- a/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeaturerule.go +++ b/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/fake/fake_nodefeaturerule.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/generated_expansion.go b/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/generated_expansion.go index 965bc1eff4..8807cd64dd 100644 --- a/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/generated_expansion.go +++ b/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/generated_expansion.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/nfd_client.go b/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/nfd_client.go index 1858451d17..653f75df21 100644 --- a/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/nfd_client.go +++ b/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/nfd_client.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturerule.go b/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturerule.go index 176e7410b3..d7d4428adf 100644 --- a/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturerule.go +++ b/pkg/generated/clientset/versioned/typed/nfd/v1alpha1/nodefeaturerule.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/informers/externalversions/factory.go b/pkg/generated/informers/externalversions/factory.go index 5a65015deb..e64a77d356 100644 --- a/pkg/generated/informers/externalversions/factory.go +++ b/pkg/generated/informers/externalversions/factory.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/informers/externalversions/generic.go b/pkg/generated/informers/externalversions/generic.go index 18dd6de9bc..453de7f151 100644 --- a/pkg/generated/informers/externalversions/generic.go +++ b/pkg/generated/informers/externalversions/generic.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go b/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go index f63a11b79c..0b862ce98d 100644 --- a/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/informers/externalversions/nfd/interface.go b/pkg/generated/informers/externalversions/nfd/interface.go index a7d35dca09..8130adf7d8 100644 --- a/pkg/generated/informers/externalversions/nfd/interface.go +++ b/pkg/generated/informers/externalversions/nfd/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/informers/externalversions/nfd/v1alpha1/interface.go b/pkg/generated/informers/externalversions/nfd/v1alpha1/interface.go index 6c8c39d324..5f476d8873 100644 --- a/pkg/generated/informers/externalversions/nfd/v1alpha1/interface.go +++ b/pkg/generated/informers/externalversions/nfd/v1alpha1/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/informers/externalversions/nfd/v1alpha1/nodefeaturerule.go b/pkg/generated/informers/externalversions/nfd/v1alpha1/nodefeaturerule.go index bb3b23c9e9..6879a711d9 100644 --- a/pkg/generated/informers/externalversions/nfd/v1alpha1/nodefeaturerule.go +++ b/pkg/generated/informers/externalversions/nfd/v1alpha1/nodefeaturerule.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/listers/nfd/v1alpha1/expansion_generated.go b/pkg/generated/listers/nfd/v1alpha1/expansion_generated.go index 64eee10f91..a072a4f4ae 100644 --- a/pkg/generated/listers/nfd/v1alpha1/expansion_generated.go +++ b/pkg/generated/listers/nfd/v1alpha1/expansion_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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. diff --git a/pkg/generated/listers/nfd/v1alpha1/nodefeaturerule.go b/pkg/generated/listers/nfd/v1alpha1/nodefeaturerule.go index 68e37951d8..e214509134 100644 --- a/pkg/generated/listers/nfd/v1alpha1/nodefeaturerule.go +++ b/pkg/generated/listers/nfd/v1alpha1/nodefeaturerule.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Kubernetes Authors. +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.