Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kubeadm: Retire MarshalClusterConfigurationToBytes #79220

Merged
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 0 additions & 2 deletions cmd/kubeadm/app/util/config/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ func MarshalKubeadmConfigObject(obj runtime.Object) ([]byte, error) {
switch internalcfg := obj.(type) {
case *kubeadmapi.InitConfiguration:
return MarshalInitConfigurationToBytes(internalcfg, kubeadmapiv1beta2.SchemeGroupVersion)
case *kubeadmapi.ClusterConfiguration:
return MarshalClusterConfigurationToBytes(internalcfg, kubeadmapiv1beta2.SchemeGroupVersion)
default:
return kubeadmutil.MarshalToYamlForCodecs(obj, kubeadmapiv1beta2.SchemeGroupVersion, kubeadmscheme.Codecs)
}
Expand Down
61 changes: 1 addition & 60 deletions cmd/kubeadm/app/util/config/initconfiguration.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ import (
"fmt"
"io/ioutil"
"net"
"reflect"
"sort"
"strconv"

"github.com/pkg/errors"
Expand Down Expand Up @@ -342,68 +340,11 @@ func MarshalInitConfigurationToBytes(cfg *kubeadmapi.InitConfiguration, gv schem
// Exception: If the specified groupversion is targeting the internal type, don't print embedded ClusterConfiguration contents
// This is mostly used for unit testing. In a real scenario the internal version of the API is never marshalled as-is.
if gv.Version != runtime.APIVersionInternal {
clusterbytes, err := MarshalClusterConfigurationToBytes(&cfg.ClusterConfiguration, gv)
clusterbytes, err := kubeadmutil.MarshalToYamlForCodecs(&cfg.ClusterConfiguration, gv, kubeadmscheme.Codecs)
if err != nil {
return []byte{}, err
}
allFiles = append(allFiles, clusterbytes)
}
return bytes.Join(allFiles, []byte(kubeadmconstants.YAMLDocumentSeparator)), nil
}

// MarshalClusterConfigurationToBytes marshals the internal ClusterConfiguration object to bytes. It writes the embedded
// ComponentConfiguration objects out as separate YAML documents
func MarshalClusterConfigurationToBytes(clustercfg *kubeadmapi.ClusterConfiguration, gv schema.GroupVersion) ([]byte, error) {
clusterbytes, err := kubeadmutil.MarshalToYamlForCodecs(clustercfg, gv, kubeadmscheme.Codecs)
if err != nil {
return []byte{}, err
}
allFiles := [][]byte{clusterbytes}
componentConfigContent := map[string][]byte{}
defaultedcfg := defaultedInternalConfig()

for kind, registration := range componentconfigs.Known {
// If the ComponentConfig struct for the current registration is nil, skip it when marshalling
realobj, ok := registration.GetFromInternalConfig(clustercfg)
if !ok {
continue
}

defaultedobj, ok := registration.GetFromInternalConfig(defaultedcfg)
// Invalid: The caller asked to not print the componentconfigs if defaulted, but defaultComponentConfigs() wasn't able to create default objects to use for reference
if !ok {
return []byte{}, errors.New("couldn't create a default componentconfig object")
}

// If the real ComponentConfig object differs from the default, print it out. If not, there's no need to print it out, so skip it
if !reflect.DeepEqual(realobj, defaultedobj) {
contentBytes, err := registration.Marshal(realobj)
if err != nil {
return []byte{}, err
}
componentConfigContent[string(kind)] = contentBytes
}
}

// Sort the ComponentConfig files by kind when marshalling
sortedComponentConfigFiles := consistentOrderByteSlice(componentConfigContent)
allFiles = append(allFiles, sortedComponentConfigFiles...)
return bytes.Join(allFiles, []byte(kubeadmconstants.YAMLDocumentSeparator)), nil
}

// consistentOrderByteSlice takes a map of a string key and a byte slice, and returns a byte slice of byte slices
// with consistent ordering, where the keys in the map determine the ordering of the return value. This has to be
// done as the order of a for...range loop over a map in go is undeterministic, and could otherwise lead to flakes
// in e.g. unit tests when marshalling content with a random order
func consistentOrderByteSlice(content map[string][]byte) [][]byte {
keys := []string{}
sortedContent := [][]byte{}
for key := range content {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
sortedContent = append(sortedContent, content[key])
}
return sortedContent
}
90 changes: 0 additions & 90 deletions cmd/kubeadm/app/util/config/initconfiguration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"io/ioutil"
"os"
"path/filepath"
"reflect"
"testing"

"github.com/pmezard/go-difflib/difflib"
Expand Down Expand Up @@ -199,95 +198,6 @@ func TestInitConfigurationMarshallingFromFile(t *testing.T) {
}
*/

func TestConsistentOrderByteSlice(t *testing.T) {
var (
aKind = "Akind"
aFile = []byte(`
kind: Akind
apiVersion: foo.k8s.io/v1
`)
aaKind = "Aakind"
aaFile = []byte(`
kind: Aakind
apiVersion: foo.k8s.io/v1
`)
abKind = "Abkind"
abFile = []byte(`
kind: Abkind
apiVersion: foo.k8s.io/v1
`)
)
var tests = []struct {
name string
in map[string][]byte
expected [][]byte
}{
{
name: "a_aa_ab",
in: map[string][]byte{
aKind: aFile,
aaKind: aaFile,
abKind: abFile,
},
expected: [][]byte{aaFile, abFile, aFile},
},
{
name: "a_ab_aa",
in: map[string][]byte{
aKind: aFile,
abKind: abFile,
aaKind: aaFile,
},
expected: [][]byte{aaFile, abFile, aFile},
},
{
name: "aa_a_ab",
in: map[string][]byte{
aaKind: aaFile,
aKind: aFile,
abKind: abFile,
},
expected: [][]byte{aaFile, abFile, aFile},
},
{
name: "aa_ab_a",
in: map[string][]byte{
aaKind: aaFile,
abKind: abFile,
aKind: aFile,
},
expected: [][]byte{aaFile, abFile, aFile},
},
{
name: "ab_a_aa",
in: map[string][]byte{
abKind: abFile,
aKind: aFile,
aaKind: aaFile,
},
expected: [][]byte{aaFile, abFile, aFile},
},
{
name: "ab_aa_a",
in: map[string][]byte{
abKind: abFile,
aaKind: aaFile,
aKind: aFile,
},
expected: [][]byte{aaFile, abFile, aFile},
},
}

for _, rt := range tests {
t.Run(rt.name, func(t2 *testing.T) {
actual := consistentOrderByteSlice(rt.in)
if !reflect.DeepEqual(rt.expected, actual) {
t2.Errorf("the expected and actual output differs.\n\texpected: %s\n\tout: %s\n", rt.expected, actual)
}
})
}
}

func TestDefaultTaintsMarshaling(t *testing.T) {
tests := []struct {
desc string
Expand Down