Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion topo/node/drivenets/drivenets.go
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,16 @@ func (n *Node) CreateConfig(ctx context.Context) (*corev1.Volume, error) {
data = v.Data
}
if data == nil {
return nil, nil
// No startup config was supplied. If the controller-managed Pod
// will nevertheless mount a config ConfigMap (because ConfigPath
// + ConfigFile are populated - typically by cdnosDefaults), we
// must still create an empty ConfigMap so the mount succeeds.
// Otherwise the Pod sits forever in PodInitializing with
// `configmap "<name>-config" not found`.
if pb.Config.GetConfigPath() == "" || pb.Config.GetConfigFile() == "" {
return nil, nil
}
data = []byte{}
}
cm := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Expand Down
78 changes: 78 additions & 0 deletions topo/node/drivenets/drivenets_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package drivenets

import (
"context"
"testing"

"github.com/openconfig/gnmi/errdiff"
tpb "github.com/openconfig/kne/proto/topo"
"github.com/openconfig/kne/topo/node"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
)

func TestNew(t *testing.T) {
Expand Down Expand Up @@ -108,6 +112,80 @@ func TestCdnosDefaults(t *testing.T) {
}
}

// TestCreateConfig_NoDataButPathDefaulted verifies that an empty ConfigMap
// is still created when no startup data is supplied but cdnosDefaults has
// populated ConfigPath/ConfigFile. Without this, the controller-created Pod
// would block forever in PodInitializing on a missing ConfigMap mount.
func TestCreateConfig_NoDataButPathDefaulted(t *testing.T) {
pb := cdnosDefaults(&tpb.Node{Name: "n1"})
if pb.Config.GetConfigPath() == "" || pb.Config.GetConfigFile() == "" {
t.Fatalf("preconditions: cdnosDefaults should populate ConfigPath and ConfigFile")
}
if pb.Config.GetConfigData() != nil {
t.Fatalf("preconditions: cdnosDefaults should not set startup config data")
}

kc := fake.NewSimpleClientset()
n := &Node{Impl: &node.Impl{
Proto: pb,
KubeClient: kc,
Namespace: "ns1",
}}

vol, err := n.CreateConfig(context.Background())
if err != nil {
t.Fatalf("CreateConfig returned unexpected error: %v", err)
}
if vol == nil {
t.Fatalf("CreateConfig returned nil volume; controller mount would fail")
}
cm, err := kc.CoreV1().ConfigMaps("ns1").Get(context.Background(), "n1-config", metav1.GetOptions{})
if err != nil {
t.Fatalf("expected ConfigMap n1-config to exist: %v", err)
}
if _, ok := cm.Data[pb.Config.GetConfigFile()]; !ok {
t.Errorf("ConfigMap missing key %q; have keys: %v", pb.Config.GetConfigFile(), keys(cm.Data))
}
}

// TestCreateConfig_NoDataAndNoPath verifies the explicit "no config mount"
// path: when neither ConfigPath nor ConfigFile is set, no ConfigMap is
// created.
func TestCreateConfig_NoDataAndNoPath(t *testing.T) {
pb := &tpb.Node{
Name: "n2",
Config: &tpb.Config{}, // empty: no Path, no File, no Data
}
kc := fake.NewSimpleClientset()
n := &Node{Impl: &node.Impl{
Proto: pb,
KubeClient: kc,
Namespace: "ns1",
}}
vol, err := n.CreateConfig(context.Background())
if err != nil {
t.Fatalf("CreateConfig returned unexpected error: %v", err)
}
if vol != nil {
t.Errorf("expected nil volume when no config is requested, got %+v", vol)
}
cms, _ := kc.CoreV1().ConfigMaps("ns1").List(context.Background(), metav1.ListOptions{})
if len(cms.Items) != 0 {
t.Errorf("expected zero ConfigMaps, found %d", len(cms.Items))
}
}

func keys(m map[string]string) []string {
out := make([]string, 0, len(m))
for k := range m {
out = append(out, k)
}
return out
}

// dummy var keeps corev1 imported even if the rest of the file doesn't use it.
var _ = corev1.ConfigMap{}

func TestDefaultNodeConstraints(t *testing.T) {
n := &Node{}
constraints := n.DefaultNodeConstraints()
Expand Down
Loading