mirror of
https://github.com/kubernetes-sigs/node-feature-discovery.git
synced 2025-03-15 04:57:56 +00:00
apis/nfd: flatten the structure of features data type
Flatten the data structure that stores features, dropping the "domain" level from the data model. That extra level of hierarchy brought little benefit but just caused some extra complexity, instead. The new structure nicely matches what we have in the NodeFeatureRule object (the matchFeatures field of uses the same flat structure with the "feature" field having a value <domain>.<feature>, e.g. "kernel.version"). This is pre-work for introducing a new "node feature" CRD that contains the raw feature data. It makes the life of both users and developers easier when both CRDs, plus our internal code, handle feature data in a similar flat structure.
This commit is contained in:
parent
cab617c42e
commit
b907d07d7e
22 changed files with 221 additions and 208 deletions
|
@ -16,10 +16,10 @@ limitations under the License.
|
||||||
|
|
||||||
package v1alpha1
|
package v1alpha1
|
||||||
|
|
||||||
// NewDomainFeatures creates a new instance of Features, initializing specified
|
// NewFeatures creates a new instance of Features, initializing all feature
|
||||||
// features to empty values
|
// types (flags, attributes and instances) to empty values.
|
||||||
func NewDomainFeatures() *DomainFeatures {
|
func NewFeatures() *Features {
|
||||||
return &DomainFeatures{
|
return &Features{
|
||||||
Flags: make(map[string]FlagFeatureSet),
|
Flags: make(map[string]FlagFeatureSet),
|
||||||
Attributes: make(map[string]AttributeFeatureSet),
|
Attributes: make(map[string]AttributeFeatureSet),
|
||||||
Instances: make(map[string]InstanceFeatureSet)}
|
Instances: make(map[string]InstanceFeatureSet)}
|
||||||
|
@ -56,16 +56,29 @@ func NewInstanceFeature(attrs map[string]string) *InstanceFeature {
|
||||||
}
|
}
|
||||||
|
|
||||||
// InsertAttributeFeatures inserts new values into a specific feature.
|
// InsertAttributeFeatures inserts new values into a specific feature.
|
||||||
func InsertAttributeFeatures(f Features, domain, feature string, values map[string]string) {
|
func (f *Features) InsertAttributeFeatures(domain, feature string, values map[string]string) {
|
||||||
if _, ok := f[domain]; !ok {
|
key := domain + "." + feature
|
||||||
f[domain] = NewDomainFeatures()
|
if _, ok := f.Attributes[key]; !ok {
|
||||||
}
|
f.Attributes[key] = NewAttributeFeatures(values)
|
||||||
if _, ok := f[domain].Attributes[feature]; !ok {
|
|
||||||
f[domain].Attributes[feature] = NewAttributeFeatures(values)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range values {
|
for k, v := range values {
|
||||||
f[domain].Attributes[feature].Elements[k] = v
|
f.Attributes[key].Elements[k] = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Exists returns a non-empty string if a feature exists. The return value is
|
||||||
|
// the type of the feautre, i.e. "flag", "attribute" or "instance".
|
||||||
|
func (f *Features) Exists(name string) string {
|
||||||
|
if _, ok := f.Flags[name]; ok {
|
||||||
|
return "flag"
|
||||||
|
}
|
||||||
|
if _, ok := f.Attributes[name]; ok {
|
||||||
|
return "attribute"
|
||||||
|
}
|
||||||
|
if _, ok := f.Instances[name]; ok {
|
||||||
|
return "instance"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
|
@ -71,15 +71,15 @@ func (m *AttributeFeatureSet) XXX_DiscardUnknown() {
|
||||||
|
|
||||||
var xxx_messageInfo_AttributeFeatureSet proto.InternalMessageInfo
|
var xxx_messageInfo_AttributeFeatureSet proto.InternalMessageInfo
|
||||||
|
|
||||||
func (m *DomainFeatures) Reset() { *m = DomainFeatures{} }
|
func (m *Features) Reset() { *m = Features{} }
|
||||||
func (*DomainFeatures) ProtoMessage() {}
|
func (*Features) ProtoMessage() {}
|
||||||
func (*DomainFeatures) Descriptor() ([]byte, []int) {
|
func (*Features) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_6f67d44e41cfe439, []int{1}
|
return fileDescriptor_6f67d44e41cfe439, []int{1}
|
||||||
}
|
}
|
||||||
func (m *DomainFeatures) XXX_Unmarshal(b []byte) error {
|
func (m *Features) XXX_Unmarshal(b []byte) error {
|
||||||
return m.Unmarshal(b)
|
return m.Unmarshal(b)
|
||||||
}
|
}
|
||||||
func (m *DomainFeatures) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
func (m *Features) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||||
b = b[:cap(b)]
|
b = b[:cap(b)]
|
||||||
n, err := m.MarshalToSizedBuffer(b)
|
n, err := m.MarshalToSizedBuffer(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -87,13 +87,13 @@ func (m *DomainFeatures) XXX_Marshal(b []byte, deterministic bool) ([]byte, erro
|
||||||
}
|
}
|
||||||
return b[:n], nil
|
return b[:n], nil
|
||||||
}
|
}
|
||||||
func (m *DomainFeatures) XXX_Merge(src proto.Message) {
|
func (m *Features) XXX_Merge(src proto.Message) {
|
||||||
xxx_messageInfo_DomainFeatures.Merge(m, src)
|
xxx_messageInfo_DomainFeatures.Merge(m, src)
|
||||||
}
|
}
|
||||||
func (m *DomainFeatures) XXX_Size() int {
|
func (m *Features) XXX_Size() int {
|
||||||
return m.Size()
|
return m.Size()
|
||||||
}
|
}
|
||||||
func (m *DomainFeatures) XXX_DiscardUnknown() {
|
func (m *Features) XXX_DiscardUnknown() {
|
||||||
xxx_messageInfo_DomainFeatures.DiscardUnknown(m)
|
xxx_messageInfo_DomainFeatures.DiscardUnknown(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ var xxx_messageInfo_Nil proto.InternalMessageInfo
|
||||||
func init() {
|
func init() {
|
||||||
proto.RegisterType((*AttributeFeatureSet)(nil), "v1alpha1.AttributeFeatureSet")
|
proto.RegisterType((*AttributeFeatureSet)(nil), "v1alpha1.AttributeFeatureSet")
|
||||||
proto.RegisterMapType((map[string]string)(nil), "v1alpha1.AttributeFeatureSet.ElementsEntry")
|
proto.RegisterMapType((map[string]string)(nil), "v1alpha1.AttributeFeatureSet.ElementsEntry")
|
||||||
proto.RegisterType((*DomainFeatures)(nil), "v1alpha1.DomainFeatures")
|
proto.RegisterType((*Features)(nil), "v1alpha1.DomainFeatures")
|
||||||
proto.RegisterMapType((map[string]FlagFeatureSet)(nil), "v1alpha1.DomainFeatures.FlagsEntry")
|
proto.RegisterMapType((map[string]FlagFeatureSet)(nil), "v1alpha1.DomainFeatures.FlagsEntry")
|
||||||
proto.RegisterMapType((map[string]InstanceFeatureSet)(nil), "v1alpha1.DomainFeatures.InstancesEntry")
|
proto.RegisterMapType((map[string]InstanceFeatureSet)(nil), "v1alpha1.DomainFeatures.InstancesEntry")
|
||||||
proto.RegisterMapType((map[string]AttributeFeatureSet)(nil), "v1alpha1.DomainFeatures.VattributesEntry")
|
proto.RegisterMapType((map[string]AttributeFeatureSet)(nil), "v1alpha1.DomainFeatures.VattributesEntry")
|
||||||
|
@ -316,7 +316,7 @@ func (m *AttributeFeatureSet) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||||
return len(dAtA) - i, nil
|
return len(dAtA) - i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *DomainFeatures) Marshal() (dAtA []byte, err error) {
|
func (m *Features) Marshal() (dAtA []byte, err error) {
|
||||||
size := m.Size()
|
size := m.Size()
|
||||||
dAtA = make([]byte, size)
|
dAtA = make([]byte, size)
|
||||||
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
n, err := m.MarshalToSizedBuffer(dAtA[:size])
|
||||||
|
@ -326,12 +326,12 @@ func (m *DomainFeatures) Marshal() (dAtA []byte, err error) {
|
||||||
return dAtA[:n], nil
|
return dAtA[:n], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *DomainFeatures) MarshalTo(dAtA []byte) (int, error) {
|
func (m *Features) MarshalTo(dAtA []byte) (int, error) {
|
||||||
size := m.Size()
|
size := m.Size()
|
||||||
return m.MarshalToSizedBuffer(dAtA[:size])
|
return m.MarshalToSizedBuffer(dAtA[:size])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *DomainFeatures) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
func (m *Features) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||||
i := len(dAtA)
|
i := len(dAtA)
|
||||||
_ = i
|
_ = i
|
||||||
var l int
|
var l int
|
||||||
|
@ -613,7 +613,7 @@ func (m *AttributeFeatureSet) Size() (n int) {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *DomainFeatures) Size() (n int) {
|
func (m *Features) Size() (n int) {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -734,7 +734,7 @@ func (this *AttributeFeatureSet) String() string {
|
||||||
}, "")
|
}, "")
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
func (this *DomainFeatures) String() string {
|
func (this *Features) String() string {
|
||||||
if this == nil {
|
if this == nil {
|
||||||
return "nil"
|
return "nil"
|
||||||
}
|
}
|
||||||
|
@ -1025,7 +1025,7 @@ func (m *AttributeFeatureSet) Unmarshal(dAtA []byte) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func (m *DomainFeatures) Unmarshal(dAtA []byte) error {
|
func (m *Features) Unmarshal(dAtA []byte) error {
|
||||||
l := len(dAtA)
|
l := len(dAtA)
|
||||||
iNdEx := 0
|
iNdEx := 0
|
||||||
for iNdEx < l {
|
for iNdEx < l {
|
||||||
|
|
|
@ -35,7 +35,7 @@ type RuleOutput struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute the rule against a set of input features.
|
// Execute the rule against a set of input features.
|
||||||
func (r *Rule) Execute(features Features) (RuleOutput, error) {
|
func (r *Rule) Execute(features *Features) (RuleOutput, error) {
|
||||||
labels := make(map[string]string)
|
labels := make(map[string]string)
|
||||||
vars := make(map[string]string)
|
vars := make(map[string]string)
|
||||||
|
|
||||||
|
@ -145,55 +145,39 @@ func (r *Rule) executeVarsTemplate(in matchedFeatures, out map[string]string) er
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type matchedFeatures map[string]domainMatchedFeatures
|
type matchedFeatures map[string]interface{}
|
||||||
|
|
||||||
type domainMatchedFeatures map[string]interface{}
|
func (e *MatchAnyElem) match(features *Features) (bool, matchedFeatures, error) {
|
||||||
|
|
||||||
func (e *MatchAnyElem) match(features map[string]*DomainFeatures) (bool, matchedFeatures, error) {
|
|
||||||
return e.MatchFeatures.match(features)
|
return e.MatchFeatures.match(features)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *FeatureMatcher) match(features map[string]*DomainFeatures) (bool, matchedFeatures, error) {
|
func (m *FeatureMatcher) match(features *Features) (bool, matchedFeatures, error) {
|
||||||
matches := make(matchedFeatures, len(*m))
|
matches := make(matchedFeatures, len(*m))
|
||||||
|
|
||||||
// Logical AND over the terms
|
// Logical AND over the terms
|
||||||
for _, term := range *m {
|
for _, term := range *m {
|
||||||
split := strings.SplitN(term.Feature, ".", 2)
|
|
||||||
if len(split) != 2 {
|
|
||||||
return false, nil, fmt.Errorf("invalid feature %q: must be <domain>.<feature>", term.Feature)
|
|
||||||
}
|
|
||||||
domain := split[0]
|
|
||||||
// Ignore case
|
// Ignore case
|
||||||
featureName := strings.ToLower(split[1])
|
featureName := strings.ToLower(term.Feature)
|
||||||
|
|
||||||
domainFeatures, ok := features[domain]
|
|
||||||
if !ok {
|
|
||||||
return false, nil, fmt.Errorf("unknown feature source/domain %q", domain)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, ok := matches[domain]; !ok {
|
|
||||||
matches[domain] = make(domainMatchedFeatures)
|
|
||||||
}
|
|
||||||
|
|
||||||
var isMatch bool
|
var isMatch bool
|
||||||
var err error
|
var err error
|
||||||
if f, ok := domainFeatures.Flags[featureName]; ok {
|
if f, ok := features.Flags[featureName]; ok {
|
||||||
m, v, e := term.MatchExpressions.MatchGetKeys(f.Elements)
|
m, v, e := term.MatchExpressions.MatchGetKeys(f.Elements)
|
||||||
isMatch = m
|
isMatch = m
|
||||||
err = e
|
err = e
|
||||||
matches[domain][featureName] = v
|
matches[featureName] = v
|
||||||
} else if f, ok := domainFeatures.Attributes[featureName]; ok {
|
} else if f, ok := features.Attributes[featureName]; ok {
|
||||||
m, v, e := term.MatchExpressions.MatchGetValues(f.Elements)
|
m, v, e := term.MatchExpressions.MatchGetValues(f.Elements)
|
||||||
isMatch = m
|
isMatch = m
|
||||||
err = e
|
err = e
|
||||||
matches[domain][featureName] = v
|
matches[featureName] = v
|
||||||
} else if f, ok := domainFeatures.Instances[featureName]; ok {
|
} else if f, ok := features.Instances[featureName]; ok {
|
||||||
v, e := term.MatchExpressions.MatchGetInstances(f.Elements)
|
v, e := term.MatchExpressions.MatchGetInstances(f.Elements)
|
||||||
isMatch = len(v) > 0
|
isMatch = len(v) > 0
|
||||||
err = e
|
err = e
|
||||||
matches[domain][featureName] = v
|
matches[featureName] = v
|
||||||
} else {
|
} else {
|
||||||
return false, nil, fmt.Errorf("%q feature of source/domain %q not available", featureName, domain)
|
return false, nil, fmt.Errorf("feature %q not available", featureName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -23,14 +23,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRule(t *testing.T) {
|
func TestRule(t *testing.T) {
|
||||||
f := map[string]*DomainFeatures{}
|
f := &Features{}
|
||||||
r1 := Rule{Labels: map[string]string{"label-1": "", "label-2": "true"}}
|
r1 := Rule{Labels: map[string]string{"label-1": "", "label-2": "true"}}
|
||||||
r2 := Rule{
|
r2 := Rule{
|
||||||
Labels: map[string]string{"label-1": "label-val-1"},
|
Labels: map[string]string{"label-1": "label-val-1"},
|
||||||
Vars: map[string]string{"var-1": "var-val-1"},
|
Vars: map[string]string{"var-1": "var-val-1"},
|
||||||
MatchFeatures: FeatureMatcher{
|
MatchFeatures: FeatureMatcher{
|
||||||
FeatureMatcherTerm{
|
FeatureMatcherTerm{
|
||||||
Feature: "domain-1.kf-1",
|
Feature: "kf-1",
|
||||||
MatchExpressions: MatchExpressionSet{
|
MatchExpressions: MatchExpressionSet{
|
||||||
"key-1": MustCreateMatchExpression(MatchExists),
|
"key-1": MustCreateMatchExpression(MatchExists),
|
||||||
},
|
},
|
||||||
|
@ -44,11 +44,10 @@ func TestRule(t *testing.T) {
|
||||||
assert.Equal(t, r1.Labels, m.Labels, "empty matcher should have matched empty features")
|
assert.Equal(t, r1.Labels, m.Labels, "empty matcher should have matched empty features")
|
||||||
|
|
||||||
_, err = r2.Execute(f)
|
_, err = r2.Execute(f)
|
||||||
assert.Error(t, err, "matching against a missing domain should have returned an error")
|
assert.Error(t, err, "matching against a missing feature should have returned an error")
|
||||||
|
|
||||||
// Test empty domain
|
// Test properly initialized empty features
|
||||||
d := NewDomainFeatures()
|
f = NewFeatures()
|
||||||
f["domain-1"] = d
|
|
||||||
|
|
||||||
m, err = r1.Execute(f)
|
m, err = r1.Execute(f)
|
||||||
assert.Nilf(t, err, "unexpected error: %v", err)
|
assert.Nilf(t, err, "unexpected error: %v", err)
|
||||||
|
@ -59,9 +58,9 @@ func TestRule(t *testing.T) {
|
||||||
assert.Error(t, err, "matching against a missing feature type should have returned an error")
|
assert.Error(t, err, "matching against a missing feature type should have returned an error")
|
||||||
|
|
||||||
// Test empty feature sets
|
// Test empty feature sets
|
||||||
d.Flags["kf-1"] = NewFlagFeatures()
|
f.Flags["kf-1"] = NewFlagFeatures()
|
||||||
d.Attributes["vf-1"] = NewAttributeFeatures(nil)
|
f.Attributes["vf-1"] = NewAttributeFeatures(nil)
|
||||||
d.Instances["if-1"] = NewInstanceFeatures(nil)
|
f.Instances["if-1"] = NewInstanceFeatures(nil)
|
||||||
|
|
||||||
m, err = r1.Execute(f)
|
m, err = r1.Execute(f)
|
||||||
assert.Nilf(t, err, "unexpected error: %v", err)
|
assert.Nilf(t, err, "unexpected error: %v", err)
|
||||||
|
@ -72,9 +71,9 @@ func TestRule(t *testing.T) {
|
||||||
assert.Nil(t, m.Labels, "unexpected match")
|
assert.Nil(t, m.Labels, "unexpected match")
|
||||||
|
|
||||||
// Test non-empty feature sets
|
// Test non-empty feature sets
|
||||||
d.Flags["kf-1"].Elements["key-x"] = Nil{}
|
f.Flags["kf-1"].Elements["key-x"] = Nil{}
|
||||||
d.Attributes["vf-1"].Elements["key-1"] = "val-x"
|
f.Attributes["vf-1"].Elements["key-1"] = "val-x"
|
||||||
d.Instances["if-1"] = NewInstanceFeatures([]InstanceFeature{
|
f.Instances["if-1"] = NewInstanceFeatures([]InstanceFeature{
|
||||||
*NewInstanceFeature(map[string]string{"attr-1": "val-x"})})
|
*NewInstanceFeature(map[string]string{"attr-1": "val-x"})})
|
||||||
|
|
||||||
m, err = r1.Execute(f)
|
m, err = r1.Execute(f)
|
||||||
|
@ -84,7 +83,7 @@ func TestRule(t *testing.T) {
|
||||||
// Test empty MatchExpressions
|
// Test empty MatchExpressions
|
||||||
r1.MatchFeatures = FeatureMatcher{
|
r1.MatchFeatures = FeatureMatcher{
|
||||||
FeatureMatcherTerm{
|
FeatureMatcherTerm{
|
||||||
Feature: "domain-1.kf-1",
|
Feature: "kf-1",
|
||||||
MatchExpressions: MatchExpressionSet{},
|
MatchExpressions: MatchExpressionSet{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -97,7 +96,7 @@ func TestRule(t *testing.T) {
|
||||||
assert.Nilf(t, err, "unexpected error: %v", err)
|
assert.Nilf(t, err, "unexpected error: %v", err)
|
||||||
assert.Nil(t, m.Labels, "keys should not have matched")
|
assert.Nil(t, m.Labels, "keys should not have matched")
|
||||||
|
|
||||||
d.Flags["kf-1"].Elements["key-1"] = Nil{}
|
f.Flags["kf-1"].Elements["key-1"] = Nil{}
|
||||||
m, err = r2.Execute(f)
|
m, err = r2.Execute(f)
|
||||||
assert.Nilf(t, err, "unexpected error: %v", err)
|
assert.Nilf(t, err, "unexpected error: %v", err)
|
||||||
assert.Equal(t, r2.Labels, m.Labels, "keys should have matched")
|
assert.Equal(t, r2.Labels, m.Labels, "keys should have matched")
|
||||||
|
@ -108,7 +107,7 @@ func TestRule(t *testing.T) {
|
||||||
Labels: map[string]string{"label-3": "label-val-3", "empty": ""},
|
Labels: map[string]string{"label-3": "label-val-3", "empty": ""},
|
||||||
MatchFeatures: FeatureMatcher{
|
MatchFeatures: FeatureMatcher{
|
||||||
FeatureMatcherTerm{
|
FeatureMatcherTerm{
|
||||||
Feature: "domain-1.vf-1",
|
Feature: "vf-1",
|
||||||
MatchExpressions: MatchExpressionSet{
|
MatchExpressions: MatchExpressionSet{
|
||||||
"key-1": MustCreateMatchExpression(MatchIn, "val-1"),
|
"key-1": MustCreateMatchExpression(MatchIn, "val-1"),
|
||||||
},
|
},
|
||||||
|
@ -119,7 +118,7 @@ func TestRule(t *testing.T) {
|
||||||
assert.Nilf(t, err, "unexpected error: %v", err)
|
assert.Nilf(t, err, "unexpected error: %v", err)
|
||||||
assert.Nil(t, m.Labels, "values should not have matched")
|
assert.Nil(t, m.Labels, "values should not have matched")
|
||||||
|
|
||||||
d.Attributes["vf-1"].Elements["key-1"] = "val-1"
|
f.Attributes["vf-1"].Elements["key-1"] = "val-1"
|
||||||
m, err = r3.Execute(f)
|
m, err = r3.Execute(f)
|
||||||
assert.Nilf(t, err, "unexpected error: %v", err)
|
assert.Nilf(t, err, "unexpected error: %v", err)
|
||||||
assert.Equal(t, r3.Labels, m.Labels, "values should have matched")
|
assert.Equal(t, r3.Labels, m.Labels, "values should have matched")
|
||||||
|
@ -129,7 +128,7 @@ func TestRule(t *testing.T) {
|
||||||
Labels: map[string]string{"label-4": "label-val-4"},
|
Labels: map[string]string{"label-4": "label-val-4"},
|
||||||
MatchFeatures: FeatureMatcher{
|
MatchFeatures: FeatureMatcher{
|
||||||
FeatureMatcherTerm{
|
FeatureMatcherTerm{
|
||||||
Feature: "domain-1.if-1",
|
Feature: "if-1",
|
||||||
MatchExpressions: MatchExpressionSet{
|
MatchExpressions: MatchExpressionSet{
|
||||||
"attr-1": MustCreateMatchExpression(MatchIn, "val-1"),
|
"attr-1": MustCreateMatchExpression(MatchIn, "val-1"),
|
||||||
},
|
},
|
||||||
|
@ -140,7 +139,7 @@ func TestRule(t *testing.T) {
|
||||||
assert.Nilf(t, err, "unexpected error: %v", err)
|
assert.Nilf(t, err, "unexpected error: %v", err)
|
||||||
assert.Nil(t, m.Labels, "instances should not have matched")
|
assert.Nil(t, m.Labels, "instances should not have matched")
|
||||||
|
|
||||||
d.Instances["if-1"].Elements[0].Attributes["attr-1"] = "val-1"
|
f.Instances["if-1"].Elements[0].Attributes["attr-1"] = "val-1"
|
||||||
m, err = r4.Execute(f)
|
m, err = r4.Execute(f)
|
||||||
assert.Nilf(t, err, "unexpected error: %v", err)
|
assert.Nilf(t, err, "unexpected error: %v", err)
|
||||||
assert.Equal(t, r4.Labels, m.Labels, "instances should have matched")
|
assert.Equal(t, r4.Labels, m.Labels, "instances should have matched")
|
||||||
|
@ -150,13 +149,13 @@ func TestRule(t *testing.T) {
|
||||||
Labels: map[string]string{"label-5": "label-val-5"},
|
Labels: map[string]string{"label-5": "label-val-5"},
|
||||||
MatchFeatures: FeatureMatcher{
|
MatchFeatures: FeatureMatcher{
|
||||||
FeatureMatcherTerm{
|
FeatureMatcherTerm{
|
||||||
Feature: "domain-1.vf-1",
|
Feature: "vf-1",
|
||||||
MatchExpressions: MatchExpressionSet{
|
MatchExpressions: MatchExpressionSet{
|
||||||
"key-1": MustCreateMatchExpression(MatchIn, "val-x"),
|
"key-1": MustCreateMatchExpression(MatchIn, "val-x"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
FeatureMatcherTerm{
|
FeatureMatcherTerm{
|
||||||
Feature: "domain-1.if-1",
|
Feature: "if-1",
|
||||||
MatchExpressions: MatchExpressionSet{
|
MatchExpressions: MatchExpressionSet{
|
||||||
"attr-1": MustCreateMatchExpression(MatchIn, "val-1"),
|
"attr-1": MustCreateMatchExpression(MatchIn, "val-1"),
|
||||||
},
|
},
|
||||||
|
@ -177,7 +176,7 @@ func TestRule(t *testing.T) {
|
||||||
{
|
{
|
||||||
MatchFeatures: FeatureMatcher{
|
MatchFeatures: FeatureMatcher{
|
||||||
FeatureMatcherTerm{
|
FeatureMatcherTerm{
|
||||||
Feature: "domain-1.kf-1",
|
Feature: "kf-1",
|
||||||
MatchExpressions: MatchExpressionSet{
|
MatchExpressions: MatchExpressionSet{
|
||||||
"key-na": MustCreateMatchExpression(MatchExists),
|
"key-na": MustCreateMatchExpression(MatchExists),
|
||||||
},
|
},
|
||||||
|
@ -193,7 +192,7 @@ func TestRule(t *testing.T) {
|
||||||
MatchAnyElem{
|
MatchAnyElem{
|
||||||
MatchFeatures: FeatureMatcher{
|
MatchFeatures: FeatureMatcher{
|
||||||
FeatureMatcherTerm{
|
FeatureMatcherTerm{
|
||||||
Feature: "domain-1.kf-1",
|
Feature: "kf-1",
|
||||||
MatchExpressions: MatchExpressionSet{
|
MatchExpressions: MatchExpressionSet{
|
||||||
"key-1": MustCreateMatchExpression(MatchExists),
|
"key-1": MustCreateMatchExpression(MatchExists),
|
||||||
},
|
},
|
||||||
|
@ -207,46 +206,44 @@ func TestRule(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTemplating(t *testing.T) {
|
func TestTemplating(t *testing.T) {
|
||||||
f := map[string]*DomainFeatures{
|
f := &Features{
|
||||||
"domain_1": &DomainFeatures{
|
Flags: map[string]FlagFeatureSet{
|
||||||
Flags: map[string]FlagFeatureSet{
|
"kf_1": {
|
||||||
"kf_1": FlagFeatureSet{
|
Elements: map[string]Nil{
|
||||||
Elements: map[string]Nil{
|
"key-a": {},
|
||||||
"key-a": {},
|
"key-b": {},
|
||||||
"key-b": {},
|
"key-c": {},
|
||||||
"key-c": {},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Attributes: map[string]AttributeFeatureSet{
|
},
|
||||||
"vf_1": AttributeFeatureSet{
|
Attributes: map[string]AttributeFeatureSet{
|
||||||
Elements: map[string]string{
|
"vf_1": {
|
||||||
"key-1": "val-1",
|
Elements: map[string]string{
|
||||||
"keu-2": "val-2",
|
"key-1": "val-1",
|
||||||
"key-3": "val-3",
|
"keu-2": "val-2",
|
||||||
},
|
"key-3": "val-3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Instances: map[string]InstanceFeatureSet{
|
},
|
||||||
"if_1": InstanceFeatureSet{
|
Instances: map[string]InstanceFeatureSet{
|
||||||
Elements: []InstanceFeature{
|
"if_1": {
|
||||||
{
|
Elements: []InstanceFeature{
|
||||||
Attributes: map[string]string{
|
{
|
||||||
"attr-1": "1",
|
Attributes: map[string]string{
|
||||||
"attr-2": "val-2",
|
"attr-1": "1",
|
||||||
},
|
"attr-2": "val-2",
|
||||||
},
|
},
|
||||||
{
|
},
|
||||||
Attributes: map[string]string{
|
{
|
||||||
"attr-1": "10",
|
Attributes: map[string]string{
|
||||||
"attr-2": "val-20",
|
"attr-1": "10",
|
||||||
},
|
"attr-2": "val-20",
|
||||||
},
|
},
|
||||||
{
|
},
|
||||||
Attributes: map[string]string{
|
{
|
||||||
"attr-1": "100",
|
Attributes: map[string]string{
|
||||||
"attr-2": "val-200",
|
"attr-1": "100",
|
||||||
},
|
"attr-2": "val-200",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -259,21 +256,21 @@ func TestTemplating(t *testing.T) {
|
||||||
LabelsTemplate: `
|
LabelsTemplate: `
|
||||||
label-1=will-be-overridden
|
label-1=will-be-overridden
|
||||||
label-2=
|
label-2=
|
||||||
{{range .domain_1.kf_1}}kf-{{.Name}}=present
|
{{range .kf_1}}kf-{{.Name}}=present
|
||||||
{{end}}
|
{{end}}
|
||||||
{{range .domain_1.vf_1}}vf-{{.Name}}=vf-{{.Value}}
|
{{range .vf_1}}vf-{{.Name}}=vf-{{.Value}}
|
||||||
{{end}}
|
{{end}}
|
||||||
{{range .domain_1.if_1}}if-{{index . "attr-1"}}_{{index . "attr-2"}}=present
|
{{range .if_1}}if-{{index . "attr-1"}}_{{index . "attr-2"}}=present
|
||||||
{{end}}`,
|
{{end}}`,
|
||||||
Vars: map[string]string{"var-1": "var-val-1"},
|
Vars: map[string]string{"var-1": "var-val-1"},
|
||||||
VarsTemplate: `
|
VarsTemplate: `
|
||||||
var-1=value-will-be-overridden-by-vars
|
var-1=value-will-be-overridden-by-vars
|
||||||
var-2=
|
var-2=
|
||||||
{{range .domain_1.kf_1}}kf-{{.Name}}=true
|
{{range .kf_1}}kf-{{.Name}}=true
|
||||||
{{end}}`,
|
{{end}}`,
|
||||||
MatchFeatures: FeatureMatcher{
|
MatchFeatures: FeatureMatcher{
|
||||||
FeatureMatcherTerm{
|
FeatureMatcherTerm{
|
||||||
Feature: "domain_1.kf_1",
|
Feature: "kf_1",
|
||||||
MatchExpressions: MatchExpressionSet{
|
MatchExpressions: MatchExpressionSet{
|
||||||
"key-a": MustCreateMatchExpression(MatchExists),
|
"key-a": MustCreateMatchExpression(MatchExists),
|
||||||
"key-c": MustCreateMatchExpression(MatchExists),
|
"key-c": MustCreateMatchExpression(MatchExists),
|
||||||
|
@ -281,14 +278,14 @@ var-2=
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
FeatureMatcherTerm{
|
FeatureMatcherTerm{
|
||||||
Feature: "domain_1.vf_1",
|
Feature: "vf_1",
|
||||||
MatchExpressions: MatchExpressionSet{
|
MatchExpressions: MatchExpressionSet{
|
||||||
"key-1": MustCreateMatchExpression(MatchIn, "val-1", "val-2"),
|
"key-1": MustCreateMatchExpression(MatchIn, "val-1", "val-2"),
|
||||||
"bar": MustCreateMatchExpression(MatchDoesNotExist),
|
"bar": MustCreateMatchExpression(MatchDoesNotExist),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
FeatureMatcherTerm{
|
FeatureMatcherTerm{
|
||||||
Feature: "domain_1.if_1",
|
Feature: "if_1",
|
||||||
MatchExpressions: MatchExpressionSet{
|
MatchExpressions: MatchExpressionSet{
|
||||||
"attr-1": MustCreateMatchExpression(MatchLt, "100"),
|
"attr-1": MustCreateMatchExpression(MatchLt, "100"),
|
||||||
},
|
},
|
||||||
|
@ -342,7 +339,7 @@ var-2=
|
||||||
// We need at least one matcher to match to execute the template.
|
// We need at least one matcher to match to execute the template.
|
||||||
// Use a simple empty matchexpression set to match anything.
|
// Use a simple empty matchexpression set to match anything.
|
||||||
FeatureMatcherTerm{
|
FeatureMatcherTerm{
|
||||||
Feature: "domain_1.kf_1",
|
Feature: "kf_1",
|
||||||
MatchExpressions: MatchExpressionSet{
|
MatchExpressions: MatchExpressionSet{
|
||||||
"key-a": MustCreateMatchExpression(MatchExists),
|
"key-a": MustCreateMatchExpression(MatchExists),
|
||||||
},
|
},
|
||||||
|
|
|
@ -20,18 +20,13 @@ import (
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Features is a collection of all features of the system, arranged by domain.
|
// Features is the collection of all discovered features.
|
||||||
//
|
//
|
||||||
// +protobuf=true
|
// +protobuf=true
|
||||||
type Features map[string]*DomainFeatures
|
type Features struct {
|
||||||
|
Flags map[string]FlagFeatureSet `json:"flags" protobuf:"bytes,1,rep,name=flags"`
|
||||||
// DomainFeatures is the collection of all discovered features of one domain.
|
Attributes map[string]AttributeFeatureSet `json:"attributes" protobuf:"bytes,2,rep,name=vattributes"`
|
||||||
//
|
Instances map[string]InstanceFeatureSet `json:"instances" protobuf:"bytes,3,rep,name=instances"`
|
||||||
// +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.
|
// FlagFeatureSet is a set of simple features only containing names without values.
|
||||||
|
|
|
@ -32,7 +32,7 @@ func (in *AttributeFeatureSet) DeepCopy() *AttributeFeatureSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *DomainFeatures) DeepCopyInto(out *DomainFeatures) {
|
func (in *Features) DeepCopyInto(out *Features) {
|
||||||
*out = *in
|
*out = *in
|
||||||
if in.Flags != nil {
|
if in.Flags != nil {
|
||||||
in, out := &in.Flags, &out.Flags
|
in, out := &in.Flags, &out.Flags
|
||||||
|
@ -58,11 +58,11 @@ func (in *DomainFeatures) DeepCopyInto(out *DomainFeatures) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DomainFeatures.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DomainFeatures.
|
||||||
func (in *DomainFeatures) DeepCopy() *DomainFeatures {
|
func (in *Features) DeepCopy() *Features {
|
||||||
if in == nil {
|
if in == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
out := new(DomainFeatures)
|
out := new(Features)
|
||||||
in.DeepCopyInto(out)
|
in.DeepCopyInto(out)
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
@ -119,17 +119,17 @@ func (in *FeatureMatcherTerm) DeepCopy() *FeatureMatcherTerm {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in Features) DeepCopyInto(out *Features) {
|
func (in FeaturesMap) DeepCopyInto(out *FeaturesMap) {
|
||||||
{
|
{
|
||||||
in := &in
|
in := &in
|
||||||
*out = make(Features, len(*in))
|
*out = make(FeaturesMap, len(*in))
|
||||||
for key, val := range *in {
|
for key, val := range *in {
|
||||||
var outVal *DomainFeatures
|
var outVal *Features
|
||||||
if val == nil {
|
if val == nil {
|
||||||
(*out)[key] = nil
|
(*out)[key] = nil
|
||||||
} else {
|
} else {
|
||||||
in, out := &val, &outVal
|
in, out := &val, &outVal
|
||||||
*out = new(DomainFeatures)
|
*out = new(Features)
|
||||||
(*in).DeepCopyInto(*out)
|
(*in).DeepCopyInto(*out)
|
||||||
}
|
}
|
||||||
(*out)[key] = outVal
|
(*out)[key] = outVal
|
||||||
|
@ -138,11 +138,11 @@ func (in Features) DeepCopyInto(out *Features) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Features.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Features.
|
||||||
func (in Features) DeepCopy() Features {
|
func (in FeaturesMap) DeepCopy() FeaturesMap {
|
||||||
if in == nil {
|
if in == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
out := new(Features)
|
out := new(FeaturesMap)
|
||||||
in.DeepCopyInto(out)
|
in.DeepCopyInto(out)
|
||||||
return *out
|
return *out
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ type SetLabelsRequest struct {
|
||||||
NfdVersion string `protobuf:"bytes,1,opt,name=nfd_version,json=nfdVersion,proto3" json:"nfd_version,omitempty"`
|
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"`
|
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"`
|
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"`
|
Features map[string]*v1alpha1.Features `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() {
|
func (x *SetLabelsRequest) Reset() {
|
||||||
|
@ -109,7 +109,7 @@ func (x *SetLabelsRequest) GetLabels() map[string]string {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *SetLabelsRequest) GetFeatures() map[string]*v1alpha1.DomainFeatures {
|
func (x *SetLabelsRequest) GetFeatures() map[string]*v1alpha1.Features {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Features
|
return x.Features
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ var file_labeler_proto_goTypes = []interface{}{
|
||||||
(*SetLabelsReply)(nil), // 1: labeler.SetLabelsReply
|
(*SetLabelsReply)(nil), // 1: labeler.SetLabelsReply
|
||||||
nil, // 2: labeler.SetLabelsRequest.LabelsEntry
|
nil, // 2: labeler.SetLabelsRequest.LabelsEntry
|
||||||
nil, // 3: labeler.SetLabelsRequest.FeaturesEntry
|
nil, // 3: labeler.SetLabelsRequest.FeaturesEntry
|
||||||
(*v1alpha1.DomainFeatures)(nil), // 4: v1alpha1.DomainFeatures
|
(*v1alpha1.Features)(nil), // 4: v1alpha1.DomainFeatures
|
||||||
}
|
}
|
||||||
var file_labeler_proto_depIdxs = []int32{
|
var file_labeler_proto_depIdxs = []int32{
|
||||||
2, // 0: labeler.SetLabelsRequest.labels:type_name -> labeler.SetLabelsRequest.LabelsEntry
|
2, // 0: labeler.SetLabelsRequest.labels:type_name -> labeler.SetLabelsRequest.LabelsEntry
|
||||||
|
|
|
@ -30,7 +30,7 @@ message SetLabelsRequest {
|
||||||
string nfd_version = 1;
|
string nfd_version = 1;
|
||||||
string node_name = 2;
|
string node_name = 2;
|
||||||
map<string, string> labels = 3;
|
map<string, string> labels = 3;
|
||||||
map<string, v1alpha1.DomainFeatures> features = 4;
|
v1alpha1.Features features = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SetLabelsReply {
|
message SetLabelsReply {
|
||||||
|
|
|
@ -31,7 +31,6 @@ import (
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
"sigs.k8s.io/yaml"
|
"sigs.k8s.io/yaml"
|
||||||
|
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
|
||||||
pb "sigs.k8s.io/node-feature-discovery/pkg/labeler"
|
pb "sigs.k8s.io/node-feature-discovery/pkg/labeler"
|
||||||
clientcommon "sigs.k8s.io/node-feature-discovery/pkg/nfd-client"
|
clientcommon "sigs.k8s.io/node-feature-discovery/pkg/nfd-client"
|
||||||
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
"sigs.k8s.io/node-feature-discovery/pkg/utils"
|
||||||
|
@ -532,17 +531,6 @@ func getFeatureLabels(source source.LabelSource, labelWhiteList regexp.Regexp) (
|
||||||
return labels, nil
|
return labels, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getFeatures returns raw features from all feature sources
|
|
||||||
func getFeatures() map[string]*nfdv1alpha1.DomainFeatures {
|
|
||||||
features := make(map[string]*nfdv1alpha1.DomainFeatures)
|
|
||||||
|
|
||||||
for name, src := range source.GetAllFeatureSources() {
|
|
||||||
features[name] = src.GetFeatures()
|
|
||||||
}
|
|
||||||
|
|
||||||
return features
|
|
||||||
}
|
|
||||||
|
|
||||||
// advertiseFeatureLabels advertises the feature labels to a Kubernetes node
|
// advertiseFeatureLabels advertises the feature labels to a Kubernetes node
|
||||||
// via the NFD server.
|
// via the NFD server.
|
||||||
func (w *nfdWorker) advertiseFeatureLabels(labels Labels) error {
|
func (w *nfdWorker) advertiseFeatureLabels(labels Labels) error {
|
||||||
|
@ -552,7 +540,7 @@ func (w *nfdWorker) advertiseFeatureLabels(labels Labels) error {
|
||||||
klog.Infof("sending labeling request to nfd-master")
|
klog.Infof("sending labeling request to nfd-master")
|
||||||
|
|
||||||
labelReq := pb.SetLabelsRequest{Labels: labels,
|
labelReq := pb.SetLabelsRequest{Labels: labels,
|
||||||
Features: getFeatures(),
|
Features: source.GetAllFeatures(),
|
||||||
NfdVersion: version.Get(),
|
NfdVersion: version.Get(),
|
||||||
NodeName: clientcommon.NodeName()}
|
NodeName: clientcommon.NodeName()}
|
||||||
|
|
||||||
|
|
|
@ -501,6 +501,9 @@ func (m *nfdMaster) crLabels(r *pb.SetLabelsRequest) map[string]string {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper struct for rule processing
|
||||||
|
features := r.GetFeatures()
|
||||||
|
|
||||||
// Process all rule CRs
|
// Process all rule CRs
|
||||||
for _, spec := range ruleSpecs {
|
for _, spec := range ruleSpecs {
|
||||||
switch {
|
switch {
|
||||||
|
@ -511,7 +514,7 @@ func (m *nfdMaster) crLabels(r *pb.SetLabelsRequest) map[string]string {
|
||||||
klog.Infof("executing NodeFeatureRule %q", spec.ObjectMeta.Name)
|
klog.Infof("executing NodeFeatureRule %q", spec.ObjectMeta.Name)
|
||||||
}
|
}
|
||||||
for _, rule := range spec.Spec.Rules {
|
for _, rule := range spec.Spec.Rules {
|
||||||
ruleOut, err := rule.Execute(r.Features)
|
ruleOut, err := rule.Execute(features)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf("failed to process Rule %q: %v", rule.Name, err)
|
klog.Errorf("failed to process Rule %q: %v", rule.Name, err)
|
||||||
continue
|
continue
|
||||||
|
@ -522,8 +525,8 @@ func (m *nfdMaster) crLabels(r *pb.SetLabelsRequest) map[string]string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Feed back rule output to features map for subsequent rules to match
|
// Feed back rule output to features map for subsequent rules to match
|
||||||
nfdv1alpha1.InsertAttributeFeatures(r.Features, nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Labels)
|
features.InsertAttributeFeatures(nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Labels)
|
||||||
nfdv1alpha1.InsertAttributeFeatures(r.Features, nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Vars)
|
features.InsertAttributeFeatures(nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Vars)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ type keyFilter struct {
|
||||||
type cpuSource struct {
|
type cpuSource struct {
|
||||||
config *Config
|
config *Config
|
||||||
cpuidFilter *keyFilter
|
cpuidFilter *keyFilter
|
||||||
features *nfdv1alpha1.DomainFeatures
|
features *nfdv1alpha1.Features
|
||||||
}
|
}
|
||||||
|
|
||||||
// Singleton source instance
|
// Singleton source instance
|
||||||
|
@ -197,7 +197,7 @@ func (s *cpuSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
|
|
||||||
// Discover method of the FeatureSource Interface
|
// Discover method of the FeatureSource Interface
|
||||||
func (s *cpuSource) Discover() error {
|
func (s *cpuSource) Discover() error {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
|
|
||||||
// Detect CPUID
|
// Detect CPUID
|
||||||
s.features.Flags[CpuidFeature] = nfdv1alpha1.NewFlagFeatures(getCpuidFlags()...)
|
s.features.Flags[CpuidFeature] = nfdv1alpha1.NewFlagFeatures(getCpuidFlags()...)
|
||||||
|
@ -252,9 +252,9 @@ func (s *cpuSource) Discover() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFeatures method of the FeatureSource Interface
|
// GetFeatures method of the FeatureSource Interface
|
||||||
func (s *cpuSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
|
func (s *cpuSource) GetFeatures() *nfdv1alpha1.Features {
|
||||||
if s.features == nil {
|
if s.features == nil {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
}
|
}
|
||||||
return s.features
|
return s.features
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,10 +107,7 @@ func (s *customSource) Priority() int { return 10 }
|
||||||
// GetLabels method of the LabelSource interface
|
// GetLabels method of the LabelSource interface
|
||||||
func (s *customSource) GetLabels() (source.FeatureLabels, error) {
|
func (s *customSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
// Get raw features from all sources
|
// Get raw features from all sources
|
||||||
domainFeatures := make(map[string]*nfdv1alpha1.DomainFeatures)
|
features := source.GetAllFeatures()
|
||||||
for n, s := range source.GetAllFeatureSources() {
|
|
||||||
domainFeatures[n] = s.GetFeatures()
|
|
||||||
}
|
|
||||||
|
|
||||||
labels := source.FeatureLabels{}
|
labels := source.FeatureLabels{}
|
||||||
allFeatureConfig := append(getStaticFeatureConfig(), *s.config...)
|
allFeatureConfig := append(getStaticFeatureConfig(), *s.config...)
|
||||||
|
@ -118,7 +115,7 @@ func (s *customSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
utils.KlogDump(2, "custom features configuration:", " ", allFeatureConfig)
|
utils.KlogDump(2, "custom features configuration:", " ", allFeatureConfig)
|
||||||
// Iterate over features
|
// Iterate over features
|
||||||
for _, rule := range allFeatureConfig {
|
for _, rule := range allFeatureConfig {
|
||||||
ruleOut, err := rule.execute(domainFeatures)
|
ruleOut, err := rule.execute(features)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Error(err)
|
klog.Error(err)
|
||||||
continue
|
continue
|
||||||
|
@ -128,15 +125,15 @@ func (s *customSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
labels[n] = v
|
labels[n] = v
|
||||||
}
|
}
|
||||||
// Feed back rule output to features map for subsequent rules to match
|
// Feed back rule output to features map for subsequent rules to match
|
||||||
nfdv1alpha1.InsertAttributeFeatures(domainFeatures, nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Labels)
|
features.InsertAttributeFeatures(nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Labels)
|
||||||
nfdv1alpha1.InsertAttributeFeatures(domainFeatures, nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Vars)
|
features.InsertAttributeFeatures(nfdv1alpha1.RuleBackrefDomain, nfdv1alpha1.RuleBackrefFeature, ruleOut.Vars)
|
||||||
}
|
}
|
||||||
return labels, nil
|
return labels, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *CustomRule) execute(features map[string]*nfdv1alpha1.DomainFeatures) (nfdv1alpha1.RuleOutput, error) {
|
func (r *CustomRule) execute(features *nfdv1alpha1.Features) (nfdv1alpha1.RuleOutput, error) {
|
||||||
if r.LegacyRule != nil {
|
if r.LegacyRule != nil {
|
||||||
ruleOut, err := r.LegacyRule.execute(features)
|
ruleOut, err := r.LegacyRule.execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nfdv1alpha1.RuleOutput{}, fmt.Errorf("failed to execute legacy rule %s: %w", r.LegacyRule.Name, err)
|
return nfdv1alpha1.RuleOutput{}, fmt.Errorf("failed to execute legacy rule %s: %w", r.LegacyRule.Name, err)
|
||||||
}
|
}
|
||||||
|
@ -154,7 +151,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")
|
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() (map[string]string, error) {
|
||||||
if len(r.MatchOn) > 0 {
|
if len(r.MatchOn) > 0 {
|
||||||
// Logical OR over the legacy rules
|
// Logical OR over the legacy rules
|
||||||
matched := false
|
matched := false
|
||||||
|
|
|
@ -84,7 +84,7 @@ func newDefaultConfig() *Config {
|
||||||
// fakeSource implements the FeatureSource, LabelSource and ConfigurableSource interfaces.
|
// fakeSource implements the FeatureSource, LabelSource and ConfigurableSource interfaces.
|
||||||
type fakeSource struct {
|
type fakeSource struct {
|
||||||
config *Config
|
config *Config
|
||||||
features *nfdv1alpha1.DomainFeatures
|
features *nfdv1alpha1.Features
|
||||||
}
|
}
|
||||||
|
|
||||||
// Singleton source instance
|
// Singleton source instance
|
||||||
|
@ -116,7 +116,7 @@ func (s *fakeSource) SetConfig(conf source.Config) {
|
||||||
|
|
||||||
// Discover method of the FeatureSource interface
|
// Discover method of the FeatureSource interface
|
||||||
func (s *fakeSource) Discover() error {
|
func (s *fakeSource) Discover() error {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
|
|
||||||
s.features.Flags[FlagFeature] = nfdv1alpha1.NewFlagFeatures(s.config.FlagFeatures...)
|
s.features.Flags[FlagFeature] = nfdv1alpha1.NewFlagFeatures(s.config.FlagFeatures...)
|
||||||
s.features.Attributes[AttributeFeature] = nfdv1alpha1.NewAttributeFeatures(s.config.AttributeFeatures)
|
s.features.Attributes[AttributeFeature] = nfdv1alpha1.NewAttributeFeatures(s.config.AttributeFeatures)
|
||||||
|
@ -133,9 +133,9 @@ func (s *fakeSource) Discover() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFeatures method of the FeatureSource Interface.
|
// GetFeatures method of the FeatureSource Interface.
|
||||||
func (s *fakeSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
|
func (s *fakeSource) GetFeatures() *nfdv1alpha1.Features {
|
||||||
if s.features == nil {
|
if s.features == nil {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
}
|
}
|
||||||
return s.features
|
return s.features
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ func newDefaultConfig() *Config {
|
||||||
// kernelSource implements the FeatureSource, LabelSource and ConfigurableSource interfaces.
|
// kernelSource implements the FeatureSource, LabelSource and ConfigurableSource interfaces.
|
||||||
type kernelSource struct {
|
type kernelSource struct {
|
||||||
config *Config
|
config *Config
|
||||||
features *nfdv1alpha1.DomainFeatures
|
features *nfdv1alpha1.Features
|
||||||
// legacyKconfig contains mangled kconfig values used for
|
// legacyKconfig contains mangled kconfig values used for
|
||||||
// kernel.config-<flag> labels and legacy kConfig custom rules.
|
// kernel.config-<flag> labels and legacy kConfig custom rules.
|
||||||
legacyKconfig map[string]string
|
legacyKconfig map[string]string
|
||||||
|
@ -117,7 +117,7 @@ func (s *kernelSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
|
|
||||||
// Discover method of the FeatureSource interface
|
// Discover method of the FeatureSource interface
|
||||||
func (s *kernelSource) Discover() error {
|
func (s *kernelSource) Discover() error {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
|
|
||||||
// Read kernel version
|
// Read kernel version
|
||||||
if version, err := parseVersion(); err != nil {
|
if version, err := parseVersion(); err != nil {
|
||||||
|
@ -153,9 +153,9 @@ func (s *kernelSource) Discover() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *kernelSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
|
func (s *kernelSource) GetFeatures() *nfdv1alpha1.Features {
|
||||||
if s.features == nil {
|
if s.features == nil {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
}
|
}
|
||||||
return s.features
|
return s.features
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ var (
|
||||||
|
|
||||||
// localSource implements the FeatureSource and LabelSource interfaces.
|
// localSource implements the FeatureSource and LabelSource interfaces.
|
||||||
type localSource struct {
|
type localSource struct {
|
||||||
features *nfdv1alpha1.DomainFeatures
|
features *nfdv1alpha1.Features
|
||||||
config *Config
|
config *Config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ func newDefaultConfig() *Config {
|
||||||
|
|
||||||
// Discover method of the FeatureSource interface
|
// Discover method of the FeatureSource interface
|
||||||
func (s *localSource) Discover() error {
|
func (s *localSource) Discover() error {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
|
|
||||||
featuresFromFiles, err := getFeaturesFromFiles()
|
featuresFromFiles, err := getFeaturesFromFiles()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -137,9 +137,9 @@ func (s *localSource) Discover() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFeatures method of the FeatureSource Interface
|
// GetFeatures method of the FeatureSource Interface
|
||||||
func (s *localSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
|
func (s *localSource) GetFeatures() *nfdv1alpha1.Features {
|
||||||
if s.features == nil {
|
if s.features == nil {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
}
|
}
|
||||||
return s.features
|
return s.features
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ const NumaFeature = "numa"
|
||||||
|
|
||||||
// memorySource implements the FeatureSource and LabelSource interfaces.
|
// memorySource implements the FeatureSource and LabelSource interfaces.
|
||||||
type memorySource struct {
|
type memorySource struct {
|
||||||
features *nfdv1alpha1.DomainFeatures
|
features *nfdv1alpha1.Features
|
||||||
}
|
}
|
||||||
|
|
||||||
// Singleton source instance
|
// Singleton source instance
|
||||||
|
@ -84,7 +84,7 @@ func (s *memorySource) GetLabels() (source.FeatureLabels, error) {
|
||||||
|
|
||||||
// Discover method of the FeatureSource interface
|
// Discover method of the FeatureSource interface
|
||||||
func (s *memorySource) Discover() error {
|
func (s *memorySource) Discover() error {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
|
|
||||||
// Detect NUMA
|
// Detect NUMA
|
||||||
if numa, err := detectNuma(); err != nil {
|
if numa, err := detectNuma(); err != nil {
|
||||||
|
@ -106,9 +106,9 @@ func (s *memorySource) Discover() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFeatures method of the FeatureSource Interface.
|
// GetFeatures method of the FeatureSource Interface.
|
||||||
func (s *memorySource) GetFeatures() *nfdv1alpha1.DomainFeatures {
|
func (s *memorySource) GetFeatures() *nfdv1alpha1.Features {
|
||||||
if s.features == nil {
|
if s.features == nil {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
}
|
}
|
||||||
return s.features
|
return s.features
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ const sysfsBaseDir = "class/net"
|
||||||
|
|
||||||
// networkSource implements the FeatureSource and LabelSource interfaces.
|
// networkSource implements the FeatureSource and LabelSource interfaces.
|
||||||
type networkSource struct {
|
type networkSource struct {
|
||||||
features *nfdv1alpha1.DomainFeatures
|
features *nfdv1alpha1.Features
|
||||||
}
|
}
|
||||||
|
|
||||||
// Singleton source instance
|
// Singleton source instance
|
||||||
|
@ -91,7 +91,7 @@ func (s *networkSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
|
|
||||||
// Discover method of the FeatureSource interface.
|
// Discover method of the FeatureSource interface.
|
||||||
func (s *networkSource) Discover() error {
|
func (s *networkSource) Discover() error {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
|
|
||||||
devs, err := detectNetDevices()
|
devs, err := detectNetDevices()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -105,9 +105,9 @@ func (s *networkSource) Discover() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFeatures method of the FeatureSource Interface.
|
// GetFeatures method of the FeatureSource Interface.
|
||||||
func (s *networkSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
|
func (s *networkSource) GetFeatures() *nfdv1alpha1.Features {
|
||||||
if s.features == nil {
|
if s.features == nil {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
}
|
}
|
||||||
return s.features
|
return s.features
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ func newDefaultConfig() *Config {
|
||||||
// pciSource implements the FeatureSource, LabelSource and ConfigurableSource interfaces.
|
// pciSource implements the FeatureSource, LabelSource and ConfigurableSource interfaces.
|
||||||
type pciSource struct {
|
type pciSource struct {
|
||||||
config *Config
|
config *Config
|
||||||
features *nfdv1alpha1.DomainFeatures
|
features *nfdv1alpha1.Features
|
||||||
}
|
}
|
||||||
|
|
||||||
// Singleton source instance
|
// Singleton source instance
|
||||||
|
@ -140,7 +140,7 @@ func (s *pciSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
|
|
||||||
// Discover method of the FeatureSource interface
|
// Discover method of the FeatureSource interface
|
||||||
func (s *pciSource) Discover() error {
|
func (s *pciSource) Discover() error {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
|
|
||||||
devs, err := detectPci()
|
devs, err := detectPci()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -154,9 +154,9 @@ func (s *pciSource) Discover() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFeatures method of the FeatureSource Interface
|
// GetFeatures method of the FeatureSource Interface
|
||||||
func (s *pciSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
|
func (s *pciSource) GetFeatures() *nfdv1alpha1.Features {
|
||||||
if s.features == nil {
|
if s.features == nil {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
}
|
}
|
||||||
return s.features
|
return s.features
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ package source
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -38,7 +40,7 @@ type FeatureSource interface {
|
||||||
Discover() error
|
Discover() error
|
||||||
|
|
||||||
// GetFeatures returns discovered features in raw form
|
// GetFeatures returns discovered features in raw form
|
||||||
GetFeatures() *nfdv1alpha1.DomainFeatures
|
GetFeatures() *nfdv1alpha1.Features
|
||||||
}
|
}
|
||||||
|
|
||||||
// LabelSource represents a source of node feature labels
|
// LabelSource represents a source of node feature labels
|
||||||
|
@ -154,3 +156,37 @@ func GetAllConfigurableSources() map[string]ConfigurableSource {
|
||||||
}
|
}
|
||||||
return all
|
return all
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetAllFeatures returns a combined set of all features from all feature
|
||||||
|
// sources.
|
||||||
|
func GetAllFeatures() *nfdv1alpha1.Features {
|
||||||
|
features := nfdv1alpha1.NewFeatures()
|
||||||
|
for n, s := range GetAllFeatureSources() {
|
||||||
|
f := s.GetFeatures()
|
||||||
|
for k, v := range f.Flags {
|
||||||
|
// Prefix feature with the name of the source
|
||||||
|
k = n + "." + k
|
||||||
|
if typ := features.Exists(k); typ != "" {
|
||||||
|
klog.Exitf("feature source %q returned flag feature %q which already exists (type %q)", n, k, typ)
|
||||||
|
}
|
||||||
|
features.Flags[k] = v
|
||||||
|
}
|
||||||
|
for k, v := range f.Attributes {
|
||||||
|
// Prefix feature with the name of the source
|
||||||
|
k = n + "." + k
|
||||||
|
if typ := features.Exists(k); typ != "" {
|
||||||
|
klog.Exitf("feature source %q returned attribute feature %q which already exists (type %q)", n, k, typ)
|
||||||
|
}
|
||||||
|
features.Attributes[k] = v
|
||||||
|
}
|
||||||
|
for k, v := range f.Instances {
|
||||||
|
// Prefix feature with the name of the source
|
||||||
|
k = n + "." + k
|
||||||
|
if typ := features.Exists(k); typ != "" {
|
||||||
|
klog.Exitf("feature source %q returned instance feature %q which already exists (type %q)", n, k, typ)
|
||||||
|
}
|
||||||
|
features.Instances[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return features
|
||||||
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ const BlockFeature = "block"
|
||||||
|
|
||||||
// storageSource implements the FeatureSource and LabelSource interfaces.
|
// storageSource implements the FeatureSource and LabelSource interfaces.
|
||||||
type storageSource struct {
|
type storageSource struct {
|
||||||
features *nfdv1alpha1.DomainFeatures
|
features *nfdv1alpha1.Features
|
||||||
}
|
}
|
||||||
|
|
||||||
// Singleton source instance
|
// Singleton source instance
|
||||||
|
@ -73,7 +73,7 @@ func (s *storageSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
|
|
||||||
// Discover method of the FeatureSource interface
|
// Discover method of the FeatureSource interface
|
||||||
func (s *storageSource) Discover() error {
|
func (s *storageSource) Discover() error {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
|
|
||||||
devs, err := detectBlock()
|
devs, err := detectBlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -87,9 +87,9 @@ func (s *storageSource) Discover() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFeatures method of the FeatureSource Interface.
|
// GetFeatures method of the FeatureSource Interface.
|
||||||
func (s *storageSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
|
func (s *storageSource) GetFeatures() *nfdv1alpha1.Features {
|
||||||
if s.features == nil {
|
if s.features == nil {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
}
|
}
|
||||||
return s.features
|
return s.features
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ const (
|
||||||
|
|
||||||
// systemSource implements the FeatureSource and LabelSource interfaces.
|
// systemSource implements the FeatureSource and LabelSource interfaces.
|
||||||
type systemSource struct {
|
type systemSource struct {
|
||||||
features *nfdv1alpha1.DomainFeatures
|
features *nfdv1alpha1.Features
|
||||||
}
|
}
|
||||||
|
|
||||||
// Singleton source instance
|
// Singleton source instance
|
||||||
|
@ -78,7 +78,7 @@ func (s *systemSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
|
|
||||||
// Discover method of the FeatureSource interface
|
// Discover method of the FeatureSource interface
|
||||||
func (s *systemSource) Discover() error {
|
func (s *systemSource) Discover() error {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
|
|
||||||
// Get node name
|
// Get node name
|
||||||
s.features.Attributes[NameFeature] = nfdv1alpha1.NewAttributeFeatures(nil)
|
s.features.Attributes[NameFeature] = nfdv1alpha1.NewAttributeFeatures(nil)
|
||||||
|
@ -107,9 +107,9 @@ func (s *systemSource) Discover() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFeatures method of the FeatureSource Interface
|
// GetFeatures method of the FeatureSource Interface
|
||||||
func (s *systemSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
|
func (s *systemSource) GetFeatures() *nfdv1alpha1.Features {
|
||||||
if s.features == nil {
|
if s.features == nil {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
}
|
}
|
||||||
return s.features
|
return s.features
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ func defaultDeviceLabelFields() []string { return []string{"class", "vendor", "d
|
||||||
// usbSource implements the LabelSource and ConfigurableSource interfaces.
|
// usbSource implements the LabelSource and ConfigurableSource interfaces.
|
||||||
type usbSource struct {
|
type usbSource struct {
|
||||||
config *Config
|
config *Config
|
||||||
features *nfdv1alpha1.DomainFeatures
|
features *nfdv1alpha1.Features
|
||||||
}
|
}
|
||||||
|
|
||||||
// Singleton source instance
|
// Singleton source instance
|
||||||
|
@ -139,7 +139,7 @@ func (s *usbSource) GetLabels() (source.FeatureLabels, error) {
|
||||||
|
|
||||||
// Discover method of the FeatureSource interface
|
// Discover method of the FeatureSource interface
|
||||||
func (s *usbSource) Discover() error {
|
func (s *usbSource) Discover() error {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
|
|
||||||
devs, err := detectUsb()
|
devs, err := detectUsb()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -153,9 +153,9 @@ func (s *usbSource) Discover() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFeatures method of the FeatureSource Interface
|
// GetFeatures method of the FeatureSource Interface
|
||||||
func (s *usbSource) GetFeatures() *nfdv1alpha1.DomainFeatures {
|
func (s *usbSource) GetFeatures() *nfdv1alpha1.Features {
|
||||||
if s.features == nil {
|
if s.features == nil {
|
||||||
s.features = nfdv1alpha1.NewDomainFeatures()
|
s.features = nfdv1alpha1.NewFeatures()
|
||||||
}
|
}
|
||||||
return s.features
|
return s.features
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue