mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-12 20:57:20 +00:00
kubeadm: Fix omitempty in v1beta2
There are a couple of problems with regards to the `omitempty` in v1beta1: - It is not applied to certain fields. This makes emitting YAML configuration files in v1beta1 config format verbose by both kubeadm and third party Go lang tools. Certain fields, that were never given an explicit value would show up in the marshalled YAML document. This can cause confusion and even misconfiguration. - It can be used in inappropriate places. In this case it's used for fields, that need to be always serialized. The only one such field at the moment is `NodeRegistrationOptions.Taints`. If the `Taints` field is nil, then it's defaulted to a slice containing a single control plane node taint. If it's an empty slice, no taints are applied, thus, the cluster behaves differently. With that in mind, a Go program, that uses v1beta1 with `omitempty` on the `Taints` field has no way to specify an explicit empty slice of taints, as this would get lost after marshalling to YAML. To fix these issues the following is done in this change: - A whole bunch of additional omitemptys are placed at many fields in v1beta2. - `omitempty` is removed from `NodeRegistrationOptions.Taints` - A test, that verifies the ability to specify empty slice value for `Taints` is included. Signed-off-by: Rostislav M. Georgiev <rostislavg@vmware.com>
This commit is contained in:
@@ -68,6 +68,7 @@ go_test(
|
||||
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
|
||||
"//vendor/github.com/lithammer/dedent:go_default_library",
|
||||
"//vendor/github.com/pmezard/go-difflib/difflib:go_default_library",
|
||||
"//vendor/sigs.k8s.io/yaml:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
@@ -26,7 +26,11 @@ import (
|
||||
|
||||
"github.com/pmezard/go-difflib/difflib"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
func diff(expected, actual []byte) string {
|
||||
@@ -283,3 +287,80 @@ apiVersion: foo.k8s.io/v1
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultTaintsMarshaling(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
cfg kubeadmapiv1beta2.InitConfiguration
|
||||
expectedTaintCnt int
|
||||
}{
|
||||
{
|
||||
desc: "Uninitialized nodeRegistration field produces a single taint (the master one)",
|
||||
cfg: kubeadmapiv1beta2.InitConfiguration{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "kubeadm.k8s.io/v1beta2",
|
||||
Kind: constants.InitConfigurationKind,
|
||||
},
|
||||
},
|
||||
expectedTaintCnt: 1,
|
||||
},
|
||||
{
|
||||
desc: "Uninitialized taints field produces a single taint (the master one)",
|
||||
cfg: kubeadmapiv1beta2.InitConfiguration{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "kubeadm.k8s.io/v1beta2",
|
||||
Kind: constants.InitConfigurationKind,
|
||||
},
|
||||
NodeRegistration: kubeadmapiv1beta2.NodeRegistrationOptions{},
|
||||
},
|
||||
expectedTaintCnt: 1,
|
||||
},
|
||||
{
|
||||
desc: "Forsing taints to an empty slice produces no taints",
|
||||
cfg: kubeadmapiv1beta2.InitConfiguration{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "kubeadm.k8s.io/v1beta2",
|
||||
Kind: constants.InitConfigurationKind,
|
||||
},
|
||||
NodeRegistration: kubeadmapiv1beta2.NodeRegistrationOptions{
|
||||
Taints: []v1.Taint{},
|
||||
},
|
||||
},
|
||||
expectedTaintCnt: 0,
|
||||
},
|
||||
{
|
||||
desc: "Custom taints are used",
|
||||
cfg: kubeadmapiv1beta2.InitConfiguration{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
APIVersion: "kubeadm.k8s.io/v1beta2",
|
||||
Kind: constants.InitConfigurationKind,
|
||||
},
|
||||
NodeRegistration: kubeadmapiv1beta2.NodeRegistrationOptions{
|
||||
Taints: []v1.Taint{
|
||||
{Key: "taint1"},
|
||||
{Key: "taint2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedTaintCnt: 2,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
b, err := yaml.Marshal(tc.cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error while marshalling to YAML: %v", err)
|
||||
}
|
||||
|
||||
cfg, err := BytesToInitConfiguration(b)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error of BytesToInitConfiguration: %v\nconfig: %s", err, string(b))
|
||||
}
|
||||
|
||||
if tc.expectedTaintCnt != len(cfg.NodeRegistration.Taints) {
|
||||
t.Fatalf("unexpected taints count\nexpected: %d\ngot: %d\ntaints: %v", tc.expectedTaintCnt, len(cfg.NodeRegistration.Taints), cfg.NodeRegistration.Taints)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -11,3 +11,4 @@ kind: JoinConfiguration
|
||||
nodeRegistration:
|
||||
criSocket: /var/run/dockershim.sock
|
||||
name: thegopher
|
||||
taints: null
|
||||
|
Reference in New Issue
Block a user