diff --git a/source/custom/rules/nodename_rule.go b/source/custom/rules/nodename_rule.go index 02199a095..f1a9af18a 100644 --- a/source/custom/rules/nodename_rule.go +++ b/source/custom/rules/nodename_rule.go @@ -17,14 +17,13 @@ limitations under the License. package rules import ( - "os" + "fmt" "regexp" "k8s.io/klog/v2" -) -var ( - nodeName = os.Getenv("NODE_NAME") + "sigs.k8s.io/node-feature-discovery/source" + "sigs.k8s.io/node-feature-discovery/source/system" ) // NodenameRule matches on nodenames configured in a ConfigMap @@ -34,6 +33,11 @@ type NodenameRule []string var _ Rule = NodenameRule{} func (n NodenameRule) Match() (bool, error) { + nodeName, ok := source.GetFeatureSource("system").GetFeatures().Values[system.NameFeature].Elements["nodename"] + if !ok { + return false, fmt.Errorf("node name not available") + } + for _, nodenamePattern := range n { klog.V(1).Infof("matchNodename %s", nodenamePattern) match, err := regexp.MatchString(nodenamePattern, nodeName) diff --git a/source/system/system.go b/source/system/system.go index 44939720e..4404c8ab2 100644 --- a/source/system/system.go +++ b/source/system/system.go @@ -24,23 +24,35 @@ import ( "k8s.io/klog/v2" + "sigs.k8s.io/node-feature-discovery/pkg/api/feature" + "sigs.k8s.io/node-feature-discovery/pkg/utils" "sigs.k8s.io/node-feature-discovery/source" ) var osReleaseFields = [...]string{ "ID", "VERSION_ID", + "VERSION_ID.major", + "VERSION_ID.minor", } const Name = "system" -// systemSource implements the LabelSource interface. -type systemSource struct{} +const ( + OsReleaseFeature = "osrelease" + NameFeature = "name" +) + +// systemSource implements the FeatureSource and LabelSource interfaces. +type systemSource struct { + features *feature.DomainFeatures +} // Singleton source instance var ( src systemSource - _ source.LabelSource = &src + _ source.FeatureSource = &src + _ source.LabelSource = &src ) func (s *systemSource) Name() string { return Name } @@ -50,29 +62,54 @@ func (s *systemSource) Priority() int { return 0 } // GetLabels method of the LabelSource interface func (s *systemSource) GetLabels() (source.FeatureLabels, error) { - features := source.FeatureLabels{} + labels := source.FeatureLabels{} + features := s.GetFeatures() + for _, key := range osReleaseFields { + if value, exists := features.Values[OsReleaseFeature].Elements[key]; exists { + feature := "os_release." + key + labels[feature] = value + } + } + return labels, nil +} + +// Discover method of the FeatureSource interface +func (s *systemSource) Discover() error { + s.features = feature.NewDomainFeatures() + + // Get node name + s.features.Values[NameFeature] = feature.NewValueFeatures(nil) + s.features.Values[NameFeature].Elements["nodename"] = os.Getenv("NODE_NAME") + + // Get os-release information release, err := parseOSRelease() if err != nil { klog.Errorf("failed to get os-release: %s", err) } else { - for _, key := range osReleaseFields { - if value, exists := release[key]; exists { - feature := "os_release." + key - features[feature] = value + s.features.Values[OsReleaseFeature] = feature.NewValueFeatures(release) - if key == "VERSION_ID" { - versionComponents := splitVersion(value) - for subKey, subValue := range versionComponents { - if subValue != "" { - features[feature+"."+subKey] = subValue - } - } + if v, ok := release["VERSION_ID"]; ok { + versionComponents := splitVersion(v) + for subKey, subValue := range versionComponents { + if subValue != "" { + s.features.Values[OsReleaseFeature].Elements["VERSION_ID."+subKey] = subValue } } } } - return features, nil + + utils.KlogDump(3, "discovered system features:", " ", s.features) + + return nil +} + +// GetFeatures method of the FeatureSource Interface +func (s *systemSource) GetFeatures() *feature.DomainFeatures { + if s.features == nil { + s.features = feature.NewDomainFeatures() + } + return s.features } // Read and parse os-release file diff --git a/source/system/system_test.go b/source/system/system_test.go new file mode 100644 index 000000000..58b0c1a1d --- /dev/null +++ b/source/system/system_test.go @@ -0,0 +1,36 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package system + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "sigs.k8s.io/node-feature-discovery/pkg/api/feature" +) + +func TestSystemSource(t *testing.T) { + assert.Equal(t, src.Name(), Name) + + // Check that GetLabels works with empty features + src.features = feature.NewDomainFeatures() + l, err := src.GetLabels() + + assert.Nil(t, err, err) + assert.Empty(t, l) + +}