Skip to content

Commit 8709ccc

Browse files
committed
nfd-master: parse kubeconfig even with NoPublish set
Don't try to be too smart when kubeconfig is needed. In practice, the nfd-master really doesn't work anymore (with the NodeFeature API enabled) without a kubeconfig set. This patch fixes crashes happening when NoPublish is enabled, e.g. in listing all nodes in the nfd api handler and in getting single node objects in the node updater pool. This patch changes the kubeconfig parsing to happen at the creation of the nfd-master instance. We don't need to do that at reconfigure time as none of the dynamic config options affect it. Unit tests are adjusted, accordingly.
1 parent 8f5830f commit 8709ccc

File tree

4 files changed

+47
-34
lines changed

4 files changed

+47
-34
lines changed

pkg/nfd-master/nfd-master-internal_test.go

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import (
4040
fakecorev1client "k8s.io/client-go/kubernetes/typed/core/v1/fake"
4141
clienttesting "k8s.io/client-go/testing"
4242
"k8s.io/client-go/tools/cache"
43-
"k8s.io/klog/v2"
4443

4544
nfdv1alpha1 "sigs.k8s.io/node-feature-discovery/pkg/apis/nfd/v1alpha1"
4645
"sigs.k8s.io/node-feature-discovery/pkg/features"
@@ -115,6 +114,7 @@ func newFakeMaster(opts ...NfdMasterOption) *nfdMaster {
115114
defaultOpts := []NfdMasterOption{
116115
withNodeName(testNodeName),
117116
withConfig(&NFDConfig{}),
117+
WithKubernetesClient(fakeclient.NewSimpleClientset()),
118118
}
119119
m, err := NewNfdMaster(append(defaultOpts, opts...)...)
120120
if err != nil {
@@ -664,6 +664,10 @@ leaderElection:
664664

665665
func TestDynamicConfig(t *testing.T) {
666666
Convey("When running nfd-master", t, func() {
667+
// Add feature gates as running nfd-master depends on that
668+
err := features.NFDMutableFeatureGate.Add(features.DefaultNFDFeatureGates)
669+
So(err, ShouldBeNil)
670+
667671
tmpDir, err := os.MkdirTemp("", "*.nfd-test")
668672
So(err, ShouldBeNil)
669673
defer os.RemoveAll(tmpDir)
@@ -674,7 +678,7 @@ func TestDynamicConfig(t *testing.T) {
674678
So(err, ShouldBeNil)
675679

676680
// Create config file
677-
configFile := filepath.Join(configDir, "master.conf")
681+
configFile := filepath.Clean(filepath.Join(configDir, "master.conf"))
678682

679683
writeConfig := func(data string) {
680684
f, err := os.Create(configFile)
@@ -685,25 +689,22 @@ func TestDynamicConfig(t *testing.T) {
685689
So(err, ShouldBeNil)
686690
}
687691
writeConfig(`
692+
klog:
693+
v: "4"
688694
extraLabelNs: ["added.ns.io"]
689695
`)
690696

691-
noPublish := true
692-
// Add FeatureGates flag
693-
if err := features.NFDMutableFeatureGate.Add(features.DefaultNFDFeatureGates); err != nil {
694-
klog.ErrorS(err, "failed to add default feature gates")
695-
os.Exit(1)
696-
}
697-
_ = features.NFDMutableFeatureGate.OverrideDefault(features.NodeFeatureAPI, false)
698-
master := newFakeMaster(WithArgs(&Args{
699-
ConfigFile: configFile,
700-
Overrides: ConfigOverrideArgs{
701-
NoPublish: &noPublish,
702-
},
703-
}))
697+
master := newFakeMaster(
698+
WithArgs(&Args{ConfigFile: configFile}),
699+
WithKubernetesClient(fakeclient.NewSimpleClientset(newTestNode())))
704700

705701
Convey("config file updates should take effect", func() {
706-
go func() { _ = master.Run() }()
702+
go func() {
703+
Convey("nfd-master should exit gracefully", t, func() {
704+
err = master.Run()
705+
So(err, ShouldBeNil)
706+
})
707+
}()
707708
defer master.Stop()
708709
// Check initial config
709710
time.Sleep(10 * time.Second)

pkg/nfd-master/nfd-master.go

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,19 @@ func NewNfdMaster(opts ...NfdMasterOption) (NfdMaster, error) {
194194
nfd.configFilePath = filepath.Clean(nfd.args.ConfigFile)
195195
}
196196

197+
// k8sClient might've been set via opts by tests
198+
if nfd.k8sClient == nil {
199+
kubeconfig, err := utils.GetKubeconfig(nfd.args.Kubeconfig)
200+
if err != nil {
201+
return nfd, err
202+
}
203+
cli, err := k8sclient.NewForConfig(kubeconfig)
204+
if err != nil {
205+
return nfd, err
206+
}
207+
nfd.k8sClient = cli
208+
}
209+
197210
nfd.nodeUpdaterPool = newNodeUpdaterPool(nfd)
198211

199212
return nfd, nil
@@ -770,10 +783,6 @@ func (m *nfdMaster) nfdAPIUpdateOneNode(node *corev1.Node) error {
770783
return objs[i].Namespace < objs[j].Namespace
771784
})
772785

773-
if m.config.NoPublish {
774-
return nil
775-
}
776-
777786
klog.V(1).InfoS("processing of node initiated by NodeFeature API", "nodeName", node.Name)
778787

779788
features := nfdv1alpha1.NewNodeFeatureSpec()
@@ -875,6 +884,11 @@ func (m *nfdMaster) refreshNodeFeatures(node *corev1.Node, labels map[string]str
875884
taints = filterTaints(crTaints)
876885
}
877886

887+
if m.config.NoPublish {
888+
klog.V(1).InfoS("node update skipped, NoPublish=true", "nodeName", node.Name)
889+
return nil
890+
}
891+
878892
err := m.updateNodeObject(node, labels, annotations, extendedResources, taints)
879893
if err != nil {
880894
klog.ErrorS(err, "failed to update node", "nodeName", node.Name)
@@ -1250,18 +1264,6 @@ func (m *nfdMaster) configure(filepath string, overrides string) error {
12501264
return err
12511265
}
12521266

1253-
if !c.NoPublish {
1254-
kubeconfig, err := utils.GetKubeconfig(m.args.Kubeconfig)
1255-
if err != nil {
1256-
return err
1257-
}
1258-
cli, err := k8sclient.NewForConfig(kubeconfig)
1259-
if err != nil {
1260-
return err
1261-
}
1262-
m.k8sClient = cli
1263-
}
1264-
12651267
// Pre-process DenyLabelNS into 2 lists: one for normal ns, and the other for wildcard ns
12661268
normalDeniedNs, wildcardDeniedNs := preProcessDeniedNamespaces(c.DenyLabelNs)
12671269
m.deniedNs.normal = normalDeniedNs

pkg/nfd-master/nfd-master_test.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"testing"
2121

2222
. "github.com/smartystreets/goconvey/convey"
23+
fakeclient "k8s.io/client-go/kubernetes/fake"
2324
m "sigs.k8s.io/node-feature-discovery/pkg/nfd-master"
2425
)
2526

@@ -36,7 +37,13 @@ func TestNewNfdMaster(t *testing.T) {
3637
})
3738
})
3839
Convey("When -config is supplied", func() {
39-
_, err := m.NewNfdMaster(m.WithArgs(&m.Args{CertFile: "crt", KeyFile: "key", CaFile: "ca", ConfigFile: "master-config.yaml"}))
40+
_, err := m.NewNfdMaster(
41+
m.WithArgs(&m.Args{
42+
CertFile: "crt",
43+
KeyFile: "key",
44+
CaFile: "ca",
45+
ConfigFile: "master-config.yaml"}),
46+
m.WithKubernetesClient(fakeclient.NewSimpleClientset()))
4047
Convey("An error should not be returned", func() {
4148
So(err, ShouldBeNil)
4249
})

pkg/nfd-worker/nfd-worker_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"time"
2525

2626
. "github.com/smartystreets/goconvey/convey"
27+
fakeclient "k8s.io/client-go/kubernetes/fake"
2728
"k8s.io/klog/v2"
2829

2930
"sigs.k8s.io/node-feature-discovery/pkg/features"
@@ -52,7 +53,9 @@ func setupTest(args *master.Args) testContext {
5253
os.Exit(1)
5354
}
5455
_ = features.NFDMutableFeatureGate.OverrideDefault(features.NodeFeatureAPI, false)
55-
m, err := master.NewNfdMaster(master.WithArgs(args))
56+
m, err := master.NewNfdMaster(
57+
master.WithArgs(args),
58+
master.WithKubernetesClient(fakeclient.NewSimpleClientset()))
5659
if err != nil {
5760
fmt.Printf("Test setup failed: %v\n", err)
5861
os.Exit(1)

0 commit comments

Comments
 (0)