From 81b35402068df2ebaddc3b1919e1eb3af4b226a9 Mon Sep 17 00:00:00 2001 From: "Lubomir I. Ivanov" Date: Wed, 15 Jun 2022 13:34:22 +0300 Subject: [PATCH] kubeadm: ensure kubelet patch results are in YAML Once we patch a kubelet configuration file, the patched output is in JSON. Make sure it's converted back to YAML, given the kubelet config in the cluster and on disk is always in YAML. Add unit test for the new function applyKubeletConfigPatches() --- cmd/kubeadm/app/phases/kubelet/config.go | 38 +++++++++++++------ cmd/kubeadm/app/phases/kubelet/config_test.go | 31 +++++++++++++++ 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/cmd/kubeadm/app/phases/kubelet/config.go b/cmd/kubeadm/app/phases/kubelet/config.go index 0d5f6c33a45..3236edb58b6 100644 --- a/cmd/kubeadm/app/phases/kubelet/config.go +++ b/cmd/kubeadm/app/phases/kubelet/config.go @@ -29,6 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" clientset "k8s.io/client-go/kubernetes" kubeletconfig "k8s.io/kubelet/config/v1beta1" + "sigs.k8s.io/yaml" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" "k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs" @@ -56,20 +57,10 @@ func WriteConfigToDisk(cfg *kubeadmapi.ClusterConfiguration, kubeletDir, patches // Apply patches to the KubeletConfiguration if len(patchesDir) != 0 { - patchManager, err := patches.GetPatchManagerForPath(patchesDir, patches.KnownTargets(), output) + kubeletBytes, err = applyKubeletConfigPatches(kubeletBytes, patchesDir, output) if err != nil { - return err + return errors.Wrap(err, "could not apply patches to the KubeletConfiguration") } - - patchTarget := &patches.PatchTarget{ - Name: patches.KubeletConfiguration, - StrategicMergePatchObject: kubeletconfig.KubeletConfiguration{}, - Data: kubeletBytes, - } - if err := patchManager.ApplyPatchesToTarget(patchTarget); err != nil { - return err - } - kubeletBytes = patchTarget.Data } return writeConfigBytesToDisk(kubeletBytes, kubeletDir) @@ -172,3 +163,26 @@ func writeConfigBytesToDisk(b []byte, kubeletDir string) error { } return nil } + +// applyKubeletConfigPatches reads patches from a directory and applies them over the input kubeletBytes +func applyKubeletConfigPatches(kubeletBytes []byte, patchesDir string, output io.Writer) ([]byte, error) { + patchManager, err := patches.GetPatchManagerForPath(patchesDir, patches.KnownTargets(), output) + if err != nil { + return nil, err + } + + patchTarget := &patches.PatchTarget{ + Name: patches.KubeletConfiguration, + StrategicMergePatchObject: kubeletconfig.KubeletConfiguration{}, + Data: kubeletBytes, + } + if err := patchManager.ApplyPatchesToTarget(patchTarget); err != nil { + return nil, err + } + + kubeletBytes, err = yaml.JSONToYAML(patchTarget.Data) + if err != nil { + return nil, err + } + return kubeletBytes, nil +} diff --git a/cmd/kubeadm/app/phases/kubelet/config_test.go b/cmd/kubeadm/app/phases/kubelet/config_test.go index 00ce6acd83e..29ea72ef99d 100644 --- a/cmd/kubeadm/app/phases/kubelet/config_test.go +++ b/cmd/kubeadm/app/phases/kubelet/config_test.go @@ -17,6 +17,10 @@ limitations under the License. package kubelet import ( + "bytes" + "io/ioutil" + "os" + "path/filepath" "testing" v1 "k8s.io/api/core/v1" @@ -72,3 +76,30 @@ func TestCreateConfigMapRBACRules(t *testing.T) { t.Errorf("createConfigMapRBACRules: unexpected error %v", err) } } + +func TestApplyKubeletConfigPatches(t *testing.T) { + var ( + input = []byte("bar: 0\nfoo: 0\n") + patch = []byte("bar: 1\n") + expectedOutput = []byte("bar: 1\nfoo: 0\n") + ) + + dir, err := ioutil.TempDir("", "patches") + if err != nil { + t.Fatalf("could not create temp dir: %v", err) + } + defer os.RemoveAll(dir) + + if err := ioutil.WriteFile(filepath.Join(dir, "kubeletconfiguration.yaml"), patch, 0644); err != nil { + t.Fatalf("could not write patch file: %v", err) + } + + output, err := applyKubeletConfigPatches(input, dir, ioutil.Discard) + if err != nil { + t.Fatalf("could not apply patch: %v", err) + } + + if !bytes.Equal(output, expectedOutput) { + t.Fatalf("expected output:\n%s\ngot\n%s\n", expectedOutput, output) + } +}