Skip to content
Closed
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
62 changes: 52 additions & 10 deletions kustomize/commands/edit/add/addmetadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@ func (k kindOfAdd) String() string {
}

type addMetadataOptions struct {
force bool
metadata map[string]string
mapValidator func(map[string]string) error
kind kindOfAdd
force bool
includeSelectors bool
metadata map[string]string
mapValidator func(map[string]string) error
kind kindOfAdd
}

// newCmdAddAnnotation adds one or more commonAnnotations to the kustomization file.
Expand Down Expand Up @@ -68,16 +69,27 @@ func newCmdAddLabel(fSys filesys.FileSystem, v func(map[string]string) error) *c
o.mapValidator = v
cmd := &cobra.Command{
Use: "label",
Short: "Adds one or more commonLabels to " +
Short: "Adds one or more labels or commonLabels to " +
konfig.DefaultKustomizationFileName(),
Example: `
add label {labelKey1:labelValue1} {labelKey2:labelValue2}`,
# Add commonLabels (default)
add label {labelKey1:labelValue1} {labelKey2:labelValue2}

# Add commonLabels
add label --include-selectors=true {labelKey1:labelValue1} {labelKey2:labelValue2}

# Add labels
add label --include-selectors=false {labelKey1:labelValue1} {labelKey2:labelValue2}
`,
RunE: func(cmd *cobra.Command, args []string) error {
return o.runE(args, fSys, o.addLabels)
},
}
cmd.Flags().BoolVarP(&o.force, "force", "f", false,
"overwrite commonLabel if it already exists",
"overwrite label or commonLabel if it already exists",
)
cmd.Flags().BoolVarP(&o.includeSelectors, "include-selectors", "s", true,
"include label in selectors",
)
return cmd
}
Expand Down Expand Up @@ -127,10 +139,17 @@ func (o *addMetadataOptions) addAnnotations(m *types.Kustomization) error {
}

func (o *addMetadataOptions) addLabels(m *types.Kustomization) error {
if m.CommonLabels == nil {
m.CommonLabels = make(map[string]string)
if o.includeSelectors {
if m.CommonLabels == nil {
m.CommonLabels = make(map[string]string)
}
return o.writeToMap(m.CommonLabels, label)
} else {
if m.Labels == nil {
m.Labels = make([]types.Label, 0)
}
return o.writeToLabelsSlice(&m.Labels)
}
return o.writeToMap(m.CommonLabels, label)
}

func (o *addMetadataOptions) writeToMap(m map[string]string, kind kindOfAdd) error {
Expand All @@ -142,3 +161,26 @@ func (o *addMetadataOptions) writeToMap(m map[string]string, kind kindOfAdd) err
}
return nil
}

func (o *addMetadataOptions) writeToLabelsSlice(klabels *[]types.Label) error {
for k, v := range o.metadata {
isPresent := false
for _, kl := range *klabels {
if _, isPresent = kl.Pairs[k]; isPresent && !o.force {
return fmt.Errorf("%s %s already in kustomization file", label, k)
} else if isPresent && o.force {
kl.Pairs[k] = v
break
}
}
if !isPresent {
*klabels = append(*klabels, types.Label{
Pairs: map[string]string{
k: v,
},
IncludeSelectors: o.includeSelectors,
})
}
}
return nil
}
32 changes: 32 additions & 0 deletions kustomize/commands/edit/add/addmetadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ func TestAddAnnotationForce(t *testing.T) {
func TestRunAddLabel(t *testing.T) {
var o addMetadataOptions
o.metadata = map[string]string{"owls": "cute", "otters": "adorable"}
o.includeSelectors = true

m := makeKustomization(t)
assert.NoError(t, o.addLabels(m))
Expand Down Expand Up @@ -274,3 +275,34 @@ func TestAddLabelForce(t *testing.T) {
assert.NoError(t, cmd.RunE(cmd, args))
v.VerifyCall()
}

func TestAddLabelNoSelector(t *testing.T) {
fSys := filesys.MakeFsInMemory()
testutils_test.WriteTestKustomization(fSys)
v := valtest_test.MakeHappyMapValidator(t)
cmd := newCmdAddLabel(fSys, v.Validator)
err := cmd.Flag("include-selectors").Value.Set("false")
require.NoError(t, err)
args := []string{"key:foo"}
assert.NoError(t, cmd.RunE(cmd, args))
v.VerifyCall()
// trying to add the same label again should not work
args = []string{"key:bar"}
v = valtest_test.MakeHappyMapValidator(t)
cmd = newCmdAddLabel(fSys, v.Validator)
err = cmd.Flag("include-selectors").Value.Set("false")
require.NoError(t, err)
err = cmd.RunE(cmd, args)
v.VerifyCall()
assert.Error(t, err)
assert.Equal(t, "label key already in kustomization file", err.Error())
// but trying to add it with --force should
v = valtest_test.MakeHappyMapValidator(t)
cmd = newCmdAddLabel(fSys, v.Validator)
err = cmd.Flag("include-selectors").Value.Set("false")
require.NoError(t, err)
err = cmd.Flag("force").Value.Set("true")
require.NoError(t, err)
assert.NoError(t, cmd.RunE(cmd, args))
v.VerifyCall()
}
2 changes: 1 addition & 1 deletion kustomize/commands/edit/add/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func NewCmdAdd(
kustomize edit add base <filepath>
kustomize edit add base <filepath1>,<filepath2>,<filepath3>

# Adds one or more commonLabels to the kustomization
# Adds one or more labels or commonLabels to the kustomization
kustomize edit add label {labelKey1:labelValue1},{labelKey2:labelValue2}

# Adds one or more commonAnnotations to the kustomization
Expand Down
3 changes: 3 additions & 0 deletions kustomize/commands/edit/set/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ func NewCmdSet(fSys filesys.FileSystem, ldr ifc.KvLoader, v ifc.Validator) *cobr

# Sets the namesuffix field
kustomize edit set namesuffix <suffix-value>

# Sets the labels or commonLabels field
kustomize edit set label {labelKey1:labelValue1} {labelKey2:labelValue2}
`,
Args: cobra.MinimumNArgs(1),
}
Expand Down
54 changes: 47 additions & 7 deletions kustomize/commands/edit/set/setlabel.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import (
)

type setLabelOptions struct {
metadata map[string]string
mapValidator func(map[string]string) error
metadata map[string]string
mapValidator func(map[string]string) error
includeSelectors bool
}

// newCmdSetLabel sets one or more commonLabels to the kustomization file.
Expand All @@ -25,14 +26,25 @@ func newCmdSetLabel(fSys filesys.FileSystem, v func(map[string]string) error) *c
o.mapValidator = v
cmd := &cobra.Command{
Use: "label",
Short: "Sets one or more commonLabels in " +
Short: "Sets one or more labels or commonLabels in " +
konfig.DefaultKustomizationFileName(),
Example: `
set label {labelKey1:labelValue1} {labelKey2:labelValue2}`,
# Set commonLabels (default)
set label {labelKey1:labelValue1} {labelKey2:labelValue2}

# Set commonLabels
set label --include-selectors=true {labelKey1:labelValue1} {labelKey2:labelValue2}

# Set labels
set label --include-selectors=false {labelKey1:labelValue1} {labelKey2:labelValue2}
`,
RunE: func(cmd *cobra.Command, args []string) error {
return o.runE(args, fSys, o.setLabels)
},
}
cmd.Flags().BoolVarP(&o.includeSelectors, "include-selectors", "s", true,
"include label in selectors",
)
return cmd
}

Expand Down Expand Up @@ -74,10 +86,17 @@ func (o *setLabelOptions) validateAndParse(args []string) error {
}

func (o *setLabelOptions) setLabels(m *types.Kustomization) error {
if m.CommonLabels == nil {
m.CommonLabels = make(map[string]string)
if o.includeSelectors {
if m.CommonLabels == nil {
m.CommonLabels = make(map[string]string)
}
return o.writeToMap(m.CommonLabels)
} else {
if m.Labels == nil {
m.Labels = make([]types.Label, 0)
}
return o.writeToLabelsSlice(&m.Labels)
}
return o.writeToMap(m.CommonLabels)
}

func (o *setLabelOptions) writeToMap(m map[string]string) error {
Expand All @@ -86,3 +105,24 @@ func (o *setLabelOptions) writeToMap(m map[string]string) error {
}
return nil
}

func (o *setLabelOptions) writeToLabelsSlice(klabels *[]types.Label) error {
for k, v := range o.metadata {
isPresent := false
for _, kl := range *klabels {
if _, isPresent = kl.Pairs[k]; isPresent {
kl.Pairs[k] = v
break
}
}
if !isPresent {
*klabels = append(*klabels, types.Label{
Pairs: map[string]string{
k: v,
},
IncludeSelectors: o.includeSelectors,
})
}
}
return nil
}
69 changes: 68 additions & 1 deletion kustomize/commands/edit/set/setlabel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package set

import (
"reflect"
"testing"

valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
Expand All @@ -28,26 +29,92 @@ func makeKustomization(t *testing.T) *types.Kustomization {
return m
}

func TestRunSetLabel(t *testing.T) {
func TestRunSetLabels(t *testing.T) {
var o setLabelOptions
o.includeSelectors = true
o.metadata = map[string]string{"owls": "cute", "otters": "adorable"}

m := makeKustomization(t)
err := o.setLabels(m)
if err != nil {
t.Errorf("unexpected error: could not write to kustomization file")
}

// assert content
expectedContent := map[string]string{"app": "helloworld", "owls": "cute", "otters": "adorable"}
if !reflect.DeepEqual(m.CommonLabels, expectedContent) {
t.Log("m.CommonLabels", m.CommonLabels)
t.Log("expectedContent", expectedContent)
t.Errorf("commonLabels does not contain expected content")
}

// adding the same test input should work
err = o.setLabels(m)
if err != nil {
t.Errorf("unexpected error: could not write to kustomization file")
}
// adding new labels should work
o.metadata = map[string]string{"new": "label", "owls": "not cute"}
err = o.setLabels(m)
if err != nil {
t.Errorf("unexpected error: could not write to kustomization file")
}
}

func TestRunSetLabelsNoSelector(t *testing.T) {
var o setLabelOptions
o.includeSelectors = false
o.metadata = map[string]string{"owls": "cute", "otters": "adorable"}

m := makeKustomization(t)
err := o.setLabels(m)
if err != nil {
t.Errorf("unexpected error: could not write to kustomization file")
}

// assert content
expectedContent := make([]types.Label, 2)
expectedContent[0] = types.Label{Pairs: map[string]string{"owls": "cute"}, IncludeSelectors: false}
expectedContent[1] = types.Label{Pairs: map[string]string{"otters": "adorable"}, IncludeSelectors: false}
if !reflect.DeepEqual(m.Labels, expectedContent) {
t.Log("m.Labels", m.Labels)
t.Log("expectedContent", expectedContent)
t.Errorf("labels does not contain expected content")
}

// adding the same test input should work
err = o.setLabels(m)
if err != nil {
t.Errorf("unexpected error: could not write to kustomization file")
}

// assert content
expectedContent2 := make([]types.Label, 2)
expectedContent2[0] = types.Label{Pairs: map[string]string{"owls": "cute"}, IncludeSelectors: false}
expectedContent2[1] = types.Label{Pairs: map[string]string{"otters": "adorable"}, IncludeSelectors: false}
if !reflect.DeepEqual(m.Labels, expectedContent2) {
t.Log("m.Labels", m.Labels)
t.Log("expectedContent", expectedContent2)
t.Errorf("labels does not contain expected content")
}

// adding new labels should work
o.metadata = map[string]string{"new": "label", "owls": "not cute"}
err = o.setLabels(m)
if err != nil {
t.Errorf("unexpected error: could not write to kustomization file")
}

// assert content
expectedContent3 := make([]types.Label, 3)
expectedContent3[0] = types.Label{Pairs: map[string]string{"owls": "not cute"}, IncludeSelectors: false}
expectedContent3[1] = types.Label{Pairs: map[string]string{"otters": "adorable"}, IncludeSelectors: false}
expectedContent3[2] = types.Label{Pairs: map[string]string{"new": "label"}, IncludeSelectors: false}
if !reflect.DeepEqual(m.Labels, expectedContent3) {
t.Log("m.Labels", m.Labels)
t.Log("expectedContent", expectedContent3)
t.Errorf("labels does not contain expected content")
}
}

func TestSetLabelNoArgs(t *testing.T) {
Expand Down