Skip to content
This repository has been archived by the owner on Nov 17, 2021. It is now read-only.

[jjo] diff: handle empty config values #180

Merged
merged 4 commits into from
Dec 20, 2017
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions pkg/kubecfg/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,28 @@ func (c DiffCmd) Run(apiObjects []*unstructured.Unstructured, out io.Writer) err
return nil
}

// See also feature request for golang reflect pkg at
func isEmptyValue(i interface{}) bool {
switch v := i.(type) {
case []interface{}:
return len(v) == 0
case []string:
return len(v) == 0
case map[string]interface{}:
return len(v) == 0
case bool:
return !v
case float64:
return v == 0
case string:
return v == ""
case nil:
return true
default:
panic(fmt.Sprintf("Found unexpected type %T in json unmarshal (value=%v)", i, i))
}
}

func removeFields(config, live interface{}) interface{} {
switch c := config.(type) {
case map[string]interface{}:
Expand All @@ -118,6 +140,11 @@ func removeMapFields(config, live map[string]interface{}) map[string]interface{}
for k, v1 := range config {
v2, ok := live[k]
if !ok {
// Copy empty value from config, as API won't return them,
// see https://github.com/ksonnet/kubecfg/issues/179
if isEmptyValue(v1) {
result[k] = v1
}
continue
}
result[k] = removeFields(v1, v2)
Expand Down
12 changes: 12 additions & 0 deletions pkg/kubecfg/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ func TestRemoveMapFields(t *testing.T) {
}

func TestRemoveFields(t *testing.T) {
emptyVal := map[string]interface{}{
"args": map[string]interface{}{},
"volumes": []string{},
"stdin": false,
}
for _, tc := range []struct {
config, live, expected interface{}
}{
Expand All @@ -99,6 +104,13 @@ func TestRemoveFields(t *testing.T) {
live: "b",
expected: "b",
},
// Check we handle empty configs by copying them as if were live
// (API won't return them)
{
config: emptyVal,
live: map[string]interface{}{},
expected: emptyVal,
},

// Check we can handle combinations.
{
Expand Down