Merge pull request #79220 from rosti/fix-MarshalClusterConfigurationToBytes

kubeadm: Retire MarshalClusterConfigurationToBytes
This commit is contained in:
Kubernetes Prow Robot 2019-06-24 08:01:58 -07:00 committed by GitHub
commit d1f342fb59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 1 additions and 152 deletions

View File

@ -41,8 +41,6 @@ func MarshalKubeadmConfigObject(obj runtime.Object) ([]byte, error) {
switch internalcfg := obj.(type) { switch internalcfg := obj.(type) {
case *kubeadmapi.InitConfiguration: case *kubeadmapi.InitConfiguration:
return MarshalInitConfigurationToBytes(internalcfg, kubeadmapiv1beta2.SchemeGroupVersion) return MarshalInitConfigurationToBytes(internalcfg, kubeadmapiv1beta2.SchemeGroupVersion)
case *kubeadmapi.ClusterConfiguration:
return MarshalClusterConfigurationToBytes(internalcfg, kubeadmapiv1beta2.SchemeGroupVersion)
default: default:
return kubeadmutil.MarshalToYamlForCodecs(obj, kubeadmapiv1beta2.SchemeGroupVersion, kubeadmscheme.Codecs) return kubeadmutil.MarshalToYamlForCodecs(obj, kubeadmapiv1beta2.SchemeGroupVersion, kubeadmscheme.Codecs)
} }

View File

@ -21,8 +21,6 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net" "net"
"reflect"
"sort"
"strconv" "strconv"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -342,7 +340,7 @@ func MarshalInitConfigurationToBytes(cfg *kubeadmapi.InitConfiguration, gv schem
// Exception: If the specified groupversion is targeting the internal type, don't print embedded ClusterConfiguration contents // 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. // 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 { if gv.Version != runtime.APIVersionInternal {
clusterbytes, err := MarshalClusterConfigurationToBytes(&cfg.ClusterConfiguration, gv) clusterbytes, err := kubeadmutil.MarshalToYamlForCodecs(&cfg.ClusterConfiguration, gv, kubeadmscheme.Codecs)
if err != nil { if err != nil {
return []byte{}, err return []byte{}, err
} }
@ -350,60 +348,3 @@ func MarshalInitConfigurationToBytes(cfg *kubeadmapi.InitConfiguration, gv schem
} }
return bytes.Join(allFiles, []byte(kubeadmconstants.YAMLDocumentSeparator)), nil 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
}

View File

@ -21,7 +21,6 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"reflect"
"testing" "testing"
"github.com/pmezard/go-difflib/difflib" "github.com/pmezard/go-difflib/difflib"
@ -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) { func TestDefaultTaintsMarshaling(t *testing.T) {
tests := []struct { tests := []struct {
desc string desc string