From 3623d9205efba2d02106e9135f82f7ed8be985d8 Mon Sep 17 00:00:00 2001 From: Sean Sullivan Date: Tue, 21 Jan 2020 15:18:22 -0800 Subject: [PATCH] Adds new helper function retrieveGroupingLabel() --- cmd/kubectl/kubectlcobra/grouping.go | 30 ++++++++--- cmd/kubectl/kubectlcobra/grouping_test.go | 65 ++++++++++++++++++++++- 2 files changed, 87 insertions(+), 8 deletions(-) diff --git a/cmd/kubectl/kubectlcobra/grouping.go b/cmd/kubectl/kubectlcobra/grouping.go index 2f50881bc..c9e9cd090 100644 --- a/cmd/kubectl/kubectlcobra/grouping.go +++ b/cmd/kubectl/kubectlcobra/grouping.go @@ -22,6 +22,26 @@ const ( GroupingHash = "kustomize.config.k8s.io/inventory-hash" ) +// retrieveGroupingLabel returns the string value of the GroupingLabel +// for the passed object. Returns error if the passed object is nil or +// is not a grouping object. +func retrieveGroupingLabel(obj runtime.Object) (string, error) { + var groupingLabel string + if obj == nil { + return "", fmt.Errorf("Grouping object is nil.\n") + } + accessor, err := meta.Accessor(obj) + if err != nil { + return "", err + } + labels := accessor.GetLabels() + groupingLabel, exists := labels[GroupingLabel] + if !exists { + return "", fmt.Errorf("Grouping label does not exist for grouping object: %s\n", GroupingLabel) + } + return strings.TrimSpace(groupingLabel), nil +} + // isGroupingObject returns true if the passed object has the // grouping label. // TODO(seans3): Check type is ConfigMap. @@ -29,13 +49,9 @@ func isGroupingObject(obj runtime.Object) bool { if obj == nil { return false } - accessor, err := meta.Accessor(obj) - if err == nil { - labels := accessor.GetLabels() - _, exists := labels[GroupingLabel] - if exists { - return true - } + groupingLabel, err := retrieveGroupingLabel(obj) + if err == nil && len(groupingLabel) > 0 { + return true } return false } diff --git a/cmd/kubectl/kubectlcobra/grouping_test.go b/cmd/kubectl/kubectlcobra/grouping_test.go index f2cca5ad8..7b0786f23 100644 --- a/cmd/kubectl/kubectlcobra/grouping_test.go +++ b/cmd/kubectl/kubectlcobra/grouping_test.go @@ -22,6 +22,8 @@ var pod1Name = "pod-1" var pod2Name = "pod-2" var pod3Name = "pod-3" +var testGroupingLabel = "test-app-label" + var groupingObj = unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": "v1", @@ -30,7 +32,7 @@ var groupingObj = unstructured.Unstructured{ "name": groupingObjName, "namespace": testNamespace, "labels": map[string]interface{}{ - GroupingLabel: "true", + GroupingLabel: testGroupingLabel, }, }, }, @@ -109,6 +111,67 @@ var nilInfo = &resource.Info{ Object: nil, } +var groupingObjLabelWithSpace = unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "v1", + "kind": "ConfigMap", + "metadata": map[string]interface{}{ + "name": groupingObjName, + "namespace": testNamespace, + "labels": map[string]interface{}{ + GroupingLabel: "\tgrouping-label ", + }, + }, + }, +} + +func TestRetrieveGroupingLabel(t *testing.T) { + tests := []struct { + obj runtime.Object + groupingLabel string + isError bool + }{ + // Nil grouping object throws error. + { + obj: nil, + groupingLabel: "", + isError: true, + }, + // Pod is not a grouping object. + { + obj: &pod2, + groupingLabel: "", + isError: true, + }, + // Retrieves label without preceding/trailing whitespace. + { + obj: &groupingObjLabelWithSpace, + groupingLabel: "grouping-label", + isError: false, + }, + { + obj: &groupingObj, + groupingLabel: testGroupingLabel, + isError: false, + }, + } + + for _, test := range tests { + actual, err := retrieveGroupingLabel(test.obj) + if test.isError && err == nil { + t.Errorf("Did not receive expected error.\n") + } + if !test.isError { + if err != nil { + t.Fatalf("Received unexpected error: %s\n", err) + } + if test.groupingLabel != actual { + t.Errorf("Expected grouping label (%s), got (%s)\n", test.groupingLabel, actual) + } + } + } +} + func TestIsGroupingObject(t *testing.T) { tests := []struct { obj runtime.Object