Merge pull request #63807 from lalyos/kubeadm-consistent-generated-manifest

Automatic merge from submit-queue (batch tested with PRs 63492, 62379, 61984, 63805, 63807). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Sort arguments before joining them, for reproducible return string

**What this PR does / why we need it**:

This PR makes kubeadm static pod manifest generation consistent. Right now when `kubeadm init` is called repeatedly, the generated pod manifest files under /etc/kubernetes/manifest/ are changing. Its really hard to test how a configuration change effects the manifest files.

The current implementation is ranging over a map[string]string which will be happening in a random order, generating different pod manifests even without changing any configuration.

The suggested solution makes pom manifest generation idempotent. It opens up integration test possibilities, like testing whole yaml result of `kubeadm alpha phase controlplane`.

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #

**Special notes for your reviewer**:

**Release note**:
```release-note
NONE
```

/sig cluster-lifecycle
/assign @luxas
This commit is contained in:
Kubernetes Submit Queue 2018-05-14 17:11:26 -07:00 committed by GitHub
commit ab180d808e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 10 deletions

View File

@ -18,17 +18,32 @@ package util
import (
"fmt"
"sort"
"strings"
)
// BuildArgumentListFromMap takes two string-string maps, one with the base arguments and one with optional override arguments
// BuildArgumentListFromMap takes two string-string maps, one with the base arguments and one
// with optional override arguments. In the return list override arguments will precede base
// arguments
func BuildArgumentListFromMap(baseArguments map[string]string, overrideArguments map[string]string) []string {
var command []string
for k, v := range overrideArguments {
var keys []string
for k := range overrideArguments {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
v := overrideArguments[k]
// values of "" are allowed as well
command = append(command, fmt.Sprintf("--%s=%s", k, v))
}
for k, v := range baseArguments {
keys = []string{}
for k := range baseArguments {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
v := baseArguments[k]
if _, overrideExists := overrideArguments[k]; !overrideExists {
command = append(command, fmt.Sprintf("--%s=%s", k, v))
}

View File

@ -39,8 +39,8 @@ func TestBuildArgumentListFromMap(t *testing.T) {
},
expected: []string{
"--admission-control=NamespaceLifecycle,LimitRanger",
"--insecure-bind-address=127.0.0.1",
"--allow-privileged=true",
"--insecure-bind-address=127.0.0.1",
},
},
{ // add an argument that is not in base
@ -53,8 +53,8 @@ func TestBuildArgumentListFromMap(t *testing.T) {
},
expected: []string{
"--admission-control=NamespaceLifecycle,LimitRanger",
"--insecure-bind-address=127.0.0.1",
"--allow-privileged=true",
"--insecure-bind-address=127.0.0.1",
},
},
{ // allow empty strings in base
@ -68,8 +68,8 @@ func TestBuildArgumentListFromMap(t *testing.T) {
},
expected: []string{
"--admission-control=NamespaceLifecycle,LimitRanger",
"--insecure-bind-address=127.0.0.1",
"--allow-privileged=true",
"--insecure-bind-address=127.0.0.1",
"--something-that-allows-empty-string=",
},
},
@ -85,17 +85,15 @@ func TestBuildArgumentListFromMap(t *testing.T) {
},
expected: []string{
"--admission-control=NamespaceLifecycle,LimitRanger",
"--insecure-bind-address=127.0.0.1",
"--allow-privileged=true",
"--something-that-allows-empty-string=",
"--allow-privileged=true",
"--insecure-bind-address=127.0.0.1",
},
},
}
for _, rt := range tests {
actual := BuildArgumentListFromMap(rt.base, rt.overrides)
sort.Strings(actual)
sort.Strings(rt.expected)
if !reflect.DeepEqual(actual, rt.expected) {
t.Errorf("failed BuildArgumentListFromMap:\nexpected:\n%v\nsaw:\n%v", rt.expected, actual)
}