From 34d49ae42359aad5de086ceae62e9a750a0fee11 Mon Sep 17 00:00:00 2001 From: natasha41575 Date: Tue, 25 Jan 2022 12:12:50 -0800 Subject: [PATCH] new commands kustomize edit set buildmetadata and kustomize edit remove buildmetadata --- kustomize/commands/edit/remove/all.go | 1 + .../edit/remove/removebuildmetadata.go | 87 +++++++++++++++++++ .../edit/remove/removebuildmetadata_test.go | 48 ++++++++++ kustomize/commands/edit/set/all.go | 1 + .../commands/edit/set/setbuildmetadata.go | 82 +++++++++++++++++ .../edit/set/setbuildmetadata_test.go | 85 ++++++++++++++++++ 6 files changed, 304 insertions(+) create mode 100644 kustomize/commands/edit/remove/removebuildmetadata.go create mode 100644 kustomize/commands/edit/remove/removebuildmetadata_test.go create mode 100644 kustomize/commands/edit/set/setbuildmetadata.go create mode 100644 kustomize/commands/edit/set/setbuildmetadata_test.go diff --git a/kustomize/commands/edit/remove/all.go b/kustomize/commands/edit/remove/all.go index 4629b489032..14db55ea1a2 100644 --- a/kustomize/commands/edit/remove/all.go +++ b/kustomize/commands/edit/remove/all.go @@ -42,6 +42,7 @@ func NewCmdRemove( newCmdRemoveAnnotation(fSys, v.MakeAnnotationNameValidator()), newCmdRemovePatch(fSys), newCmdRemoveTransformer(fSys), + newCmdRemoveBuildMetadata(fSys), ) return c } diff --git a/kustomize/commands/edit/remove/removebuildmetadata.go b/kustomize/commands/edit/remove/removebuildmetadata.go new file mode 100644 index 00000000000..99e815249a7 --- /dev/null +++ b/kustomize/commands/edit/remove/removebuildmetadata.go @@ -0,0 +1,87 @@ +// Copyright 2022 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package remove + +import ( + "errors" + "fmt" + "strings" + + "github.com/spf13/cobra" + "sigs.k8s.io/kustomize/api/types" + "sigs.k8s.io/kustomize/kustomize/v4/commands/internal/kustfile" + "sigs.k8s.io/kustomize/kyaml/filesys" +) + +type removeBuildMetadataOptions struct { + buildMetadataOptions []string +} + +// newCmdRemoveBuildMetadata removes options to the kustomization's buildMetada field. +func newCmdRemoveBuildMetadata(fSys filesys.FileSystem) *cobra.Command { + var o removeBuildMetadataOptions + + cmd := &cobra.Command{ + Use: "buildmetadata", + Short: "Removes one or more buildMetadata options to the kustomization.yaml in the current directory", + Long: `Removes one or more buildMetadata options to the kustomization.yaml in the current directory. +The following options are valid: + - originAnnotations + - transformerAnnotations + - managedByLabel +originAnnotations will remove the annotation config.kubernetes.io/origin to each resource, describing where +each resource originated from. +transformerAnnotations will remove the annotation alpha.config.kubernetes.io/transformations to each resource, +describing the transformers that have acted upon the resource. +managedByLabel will remove the label app.kubernetes.io/managed-by to each resource, describing which version +of kustomize managed the resource.`, + Example: ` + remove buildmetadata {option1},{option2}`, + RunE: func(cmd *cobra.Command, args []string) error { + err := o.Validate(args) + if err != nil { + return err + } + return o.RunRemoveBuildMetadata(fSys) + }, + } + return cmd +} + +// Validate validates removeBuildMetadata command. +func (o *removeBuildMetadataOptions) Validate(args []string) error { + if len(args) == 0 { + return errors.New("must specify a buildMetadata option") + } + if len(args) > 1 { + return fmt.Errorf("too many arguments: %s; to provide multiple buildMetadata options, please separate options by comma", args) + } + o.buildMetadataOptions = strings.Split(args[0], ",") + for _, opt := range o.buildMetadataOptions { + if !kustfile.StringInSlice(opt, types.BuildMetadataOptions) { + return fmt.Errorf("invalid buildMetadata option: %s", opt) + } + } + return nil +} + +// RunRemoveBuildMetadata runs removeBuildMetadata command (do real work). +func (o *removeBuildMetadataOptions) RunRemoveBuildMetadata(fSys filesys.FileSystem) error { + mf, err := kustfile.NewKustomizationFile(fSys) + if err != nil { + return err + } + m, err := mf.Read() + if err != nil { + return err + } + var newOptions []string + for _, opt := range m.BuildMetadata { + if !kustfile.StringInSlice(opt, o.buildMetadataOptions) { + newOptions = append(newOptions, opt) + } + } + m.BuildMetadata = newOptions + return mf.Write(m) +} diff --git a/kustomize/commands/edit/remove/removebuildmetadata_test.go b/kustomize/commands/edit/remove/removebuildmetadata_test.go new file mode 100644 index 00000000000..5452a0db613 --- /dev/null +++ b/kustomize/commands/edit/remove/removebuildmetadata_test.go @@ -0,0 +1,48 @@ +// Copyright 2022 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package remove + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "sigs.k8s.io/kustomize/api/types" + testutils_test "sigs.k8s.io/kustomize/kustomize/v4/commands/internal/testutils" + "sigs.k8s.io/kustomize/kyaml/filesys" +) + +func TestRemoveBuildMetadataHappyPath(t *testing.T) { + fSys := filesys.MakeFsInMemory() + testutils_test.WriteTestKustomizationWith(fSys, + []byte(`buildMetadata: [originAnnotations, transformerAnnotations, managedByLabel]`)) + cmd := newCmdRemoveBuildMetadata(fSys) + args := []string{strings.Join(types.BuildMetadataOptions, ",")} + assert.NoError(t, cmd.RunE(cmd, args)) + content, err := testutils_test.ReadTestKustomization(fSys) + assert.NoError(t, err) + for _, opt := range types.BuildMetadataOptions { + assert.NotContains(t, string(content), opt) + } +} + +func TestRemoveBuildMetadataInvalidArg(t *testing.T) { + fSys := filesys.MakeFsInMemory() + testutils_test.WriteTestKustomization(fSys) + cmd := newCmdRemoveBuildMetadata(fSys) + args := []string{"invalid_option"} + err := cmd.RunE(cmd, args) + assert.Error(t, err) + assert.Equal(t, "invalid buildMetadata option: invalid_option", err.Error()) +} + +func TestRemoveBuildMetadataTooManyArgs(t *testing.T) { + fSys := filesys.MakeFsInMemory() + testutils_test.WriteTestKustomization(fSys) + cmd := newCmdRemoveBuildMetadata(fSys) + args := []string{"option1", "option2"} + err := cmd.RunE(cmd, args) + assert.Error(t, err) + assert.Equal(t, "too many arguments: [option1 option2]; to provide multiple buildMetadata options, please separate options by comma", err.Error()) +} diff --git a/kustomize/commands/edit/set/all.go b/kustomize/commands/edit/set/all.go index e04f64c1d7e..1f62d62a315 100644 --- a/kustomize/commands/edit/set/all.go +++ b/kustomize/commands/edit/set/all.go @@ -30,6 +30,7 @@ func NewCmdSet(fSys filesys.FileSystem, ldr ifc.KvLoader, v ifc.Validator) *cobr newCmdSetNameSuffix(fSys), newCmdSetNamespace(fSys, v), newCmdSetImage(fSys), + newCmdSetBuildMetadata(fSys), newCmdSetReplicas(fSys), newCmdSetLabel(fSys, ldr.Validator().MakeLabelValidator()), newCmdSetAnnotation(fSys, ldr.Validator().MakeAnnotationValidator()), diff --git a/kustomize/commands/edit/set/setbuildmetadata.go b/kustomize/commands/edit/set/setbuildmetadata.go new file mode 100644 index 00000000000..71c220a32a3 --- /dev/null +++ b/kustomize/commands/edit/set/setbuildmetadata.go @@ -0,0 +1,82 @@ +// Copyright 2022 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package set + +import ( + "errors" + "fmt" + "strings" + + "github.com/spf13/cobra" + "sigs.k8s.io/kustomize/api/types" + "sigs.k8s.io/kustomize/kustomize/v4/commands/internal/kustfile" + "sigs.k8s.io/kustomize/kyaml/filesys" +) + +type setBuildMetadataOptions struct { + buildMetadataOptions []string +} + +// newCmdSetBuildMetadata sets options in the kustomization's buildMetada field. +func newCmdSetBuildMetadata(fSys filesys.FileSystem) *cobra.Command { + var o setBuildMetadataOptions + + cmd := &cobra.Command{ + Use: "buildmetadata", + Short: "Sets one or more buildMetadata options to the kustomization.yaml in the current directory", + Long: `Sets one or more buildMetadata options to the kustomization.yaml in the current directory. +Existing options in the buildMetadata field will be replaced entirely by the new options set by this command. +The following options are valid: + - originAnnotations + - transformerAnnotations + - managedByLabel +originAnnotations will add the annotation config.kubernetes.io/origin to each resource, describing where +each resource originated from. +transformerAnnotations will add the annotation alpha.config.kubernetes.io/transformations to each resource, +describing the transformers that have acted upon the resource. +managedByLabel will add the label app.kubernetes.io/managed-by to each resource, describing which version +of kustomize managed the resource.`, + Example: ` + set buildmetadata {option1},{option2}`, + RunE: func(cmd *cobra.Command, args []string) error { + err := o.Validate(args) + if err != nil { + return err + } + return o.RunSetBuildMetadata(fSys) + }, + } + return cmd +} + +// Validate validates setBuildMetadata command. +func (o *setBuildMetadataOptions) Validate(args []string) error { + if len(args) == 0 { + return errors.New("must specify a buildMetadata option") + } + if len(args) > 1 { + return fmt.Errorf("too many arguments: %s; to provide multiple buildMetadata options, please separate options by comma", args) + } + o.buildMetadataOptions = strings.Split(args[0], ",") + for _, opt := range o.buildMetadataOptions { + if !kustfile.StringInSlice(opt, types.BuildMetadataOptions) { + return fmt.Errorf("invalid buildMetadata option: %s", opt) + } + } + return nil +} + +// RunSetBuildMetadata runs setBuildMetadata command (do real work). +func (o *setBuildMetadataOptions) RunSetBuildMetadata(fSys filesys.FileSystem) error { + mf, err := kustfile.NewKustomizationFile(fSys) + if err != nil { + return err + } + m, err := mf.Read() + if err != nil { + return err + } + m.BuildMetadata = o.buildMetadataOptions + return mf.Write(m) +} diff --git a/kustomize/commands/edit/set/setbuildmetadata_test.go b/kustomize/commands/edit/set/setbuildmetadata_test.go new file mode 100644 index 00000000000..c8c1698a4b5 --- /dev/null +++ b/kustomize/commands/edit/set/setbuildmetadata_test.go @@ -0,0 +1,85 @@ +// Copyright 2022 The Kubernetes Authors. +// SPDX-License-Identifier: Apache-2.0 + +package set + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "sigs.k8s.io/kustomize/api/types" + testutils_test "sigs.k8s.io/kustomize/kustomize/v4/commands/internal/testutils" + "sigs.k8s.io/kustomize/kyaml/filesys" +) + +func TestSetBuildMetadataHappyPath(t *testing.T) { + fSys := filesys.MakeFsInMemory() + testutils_test.WriteTestKustomization(fSys) + cmd := newCmdSetBuildMetadata(fSys) + args := []string{strings.Join(types.BuildMetadataOptions, ",")} + assert.NoError(t, cmd.RunE(cmd, args)) + content, err := testutils_test.ReadTestKustomization(fSys) + assert.NoError(t, err) + for _, opt := range types.BuildMetadataOptions { + assert.Contains(t, string(content), opt) + } +} + +func TestSetBuildMetadataAlreadyThere(t *testing.T) { + fSys := filesys.MakeFsInMemory() + testutils_test.WriteTestKustomization(fSys) + cmd := newCmdSetBuildMetadata(fSys) + args := []string{strings.Join(types.BuildMetadataOptions, ",")} + assert.NoError(t, cmd.RunE(cmd, args)) + err := cmd.RunE(cmd, args) + assert.NoError(t, cmd.RunE(cmd, args)) + content, err := testutils_test.ReadTestKustomization(fSys) + assert.NoError(t, err) + for _, opt := range types.BuildMetadataOptions { + assert.Contains(t, string(content), opt) + } +} + +func TestSetBuildMetadataInvalidArg(t *testing.T) { + fSys := filesys.MakeFsInMemory() + testutils_test.WriteTestKustomization(fSys) + cmd := newCmdSetBuildMetadata(fSys) + args := []string{"invalid_option"} + err := cmd.RunE(cmd, args) + assert.Error(t, err) + assert.Equal(t, "invalid buildMetadata option: invalid_option", err.Error()) +} + +func TestSetBuildMetadataTooManyArgs(t *testing.T) { + fSys := filesys.MakeFsInMemory() + testutils_test.WriteTestKustomization(fSys) + cmd := newCmdSetBuildMetadata(fSys) + args := []string{"option1", "option2"} + err := cmd.RunE(cmd, args) + assert.Error(t, err) + assert.Equal(t, "too many arguments: [option1 option2]; to provide multiple buildMetadata options, please separate options by comma", err.Error()) +} + +func TestSetBuildMetadataForRemovingValue(t *testing.T) { + fSys := filesys.MakeFsInMemory() + testutils_test.WriteTestKustomization(fSys) + cmd := newCmdSetBuildMetadata(fSys) + args := []string{strings.Join(types.BuildMetadataOptions, ",")} + assert.NoError(t, cmd.RunE(cmd, args)) + content, err := testutils_test.ReadTestKustomization(fSys) + assert.NoError(t, err) + for _, opt := range types.BuildMetadataOptions { + assert.Contains(t, string(content), opt) + } + + args2 := []string{types.BuildMetadataOptions[0]} + assert.NoError(t, cmd.RunE(cmd, args2)) + content, err = testutils_test.ReadTestKustomization(fSys) + assert.NoError(t, err) + + // ensure that the entire field was reset + assert.Contains(t, string(content), types.BuildMetadataOptions[0]) + assert.NotContains(t, string(content), types.BuildMetadataOptions[1]) + assert.NotContains(t, string(content), types.BuildMetadataOptions[2]) +}