add kustomize edit remove component command

This commit is contained in:
Hamza
2026-03-04 16:28:10 +01:00
parent 09b04840a1
commit c07b901856
3 changed files with 204 additions and 0 deletions

View File

@@ -28,6 +28,10 @@ func NewCmdRemove(
# Removes one or more secret from the kustomization file
kustomize edit remove secret {name1},{name2}
# Removes one or more components from the kustomization file
kustomize edit remove component {filepath} {filepath}
kustomize edit remove component {pattern}
# Removes one or more patches from the kustomization file
kustomize edit remove patch --path {filepath} --group {target group name} --version {target version}
@@ -46,6 +50,7 @@ func NewCmdRemove(
newCmdRemoveConfigMap(fSys),
newCmdRemoveSecret(fSys),
newCmdRemoveResource(fSys),
newCmdRemoveComponent(fSys),
newCmdRemoveLabel(fSys, v.MakeLabelNameValidator()),
newCmdRemoveAnnotation(fSys, v.MakeAnnotationNameValidator()),
newCmdRemovePatch(fSys),

View File

@@ -0,0 +1,88 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package remove
import (
"errors"
"fmt"
"slices"
"github.com/spf13/cobra"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/kustomize/v5/commands/internal/kustfile"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
type removeComponentOptions struct {
componentFilePaths []string
}
// newCmdRemoveComponent remove the name of a file containing a component to the kustomization file.
func newCmdRemoveComponent(fSys filesys.FileSystem) *cobra.Command {
var o removeComponentOptions
cmd := &cobra.Command{
Use: "component",
Short: "Removes one or more components from " +
konfig.DefaultKustomizationFileName(),
Example: `
remove component ../../components/component1
remove component ../../components/component1 ../../components/component2
remove component ../../components/component*
`,
RunE: func(cmd *cobra.Command, args []string) error {
err := o.Validate(args)
if err != nil {
return err
}
return o.RunRemoveComponent(fSys)
},
}
return cmd
}
// Validate validates removeComponent command.
func (o *removeComponentOptions) Validate(args []string) error {
if len(args) == 0 {
return errors.New("must specify a component file")
}
o.componentFilePaths = args
return nil
}
// RunRemoveComponent runs Component command (do real work).
func (o *removeComponentOptions) RunRemoveComponent(fSys filesys.FileSystem) error {
mf, err := kustfile.NewKustomizationFile(fSys)
if err != nil {
return fmt.Errorf("failed to read kustomization file: %w", err)
}
m, err := mf.Read()
if err != nil {
return fmt.Errorf("failed to read kustomization file content: %w", err)
}
components, err := globPatterns(m.Components, o.componentFilePaths)
if err != nil {
return err
}
if len(components) == 0 {
return nil
}
newComponents := make([]string, 0, len(m.Components))
for _, component := range m.Components {
if slices.Contains(components, component) {
continue
}
newComponents = append(newComponents, component)
}
m.Components = newComponents
if err := mf.Write(m); err != nil {
return fmt.Errorf("failed to write kustomization file: %w", err)
}
return nil
}

View File

@@ -0,0 +1,111 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package remove
import (
"errors"
"testing"
testutils_test "sigs.k8s.io/kustomize/kustomize/v5/commands/internal/testutils"
)
func TestRemoveComponents(t *testing.T) {
testCases := []testutils_test.RemoveTestCase{
{
Description: "remove components",
Given: testutils_test.RemoveTestGivenValues{
Items: []string{
"../../components/component1",
"../../components/component2",
"../../components/component3",
},
RemoveArgs: []string{"../../components/component2"},
},
Expected: testutils_test.RemoveTestExpectedValues{
Items: []string{
"../../components/component1",
"../../components/component3",
},
Deleted: []string{
"../../components/component2",
},
},
},
{
Description: "remove component with pattern",
Given: testutils_test.RemoveTestGivenValues{
Items: []string{
"../../component/component1",
"../../component/component2",
"../../component/component3",
"../../component/do_not_delete",
},
RemoveArgs: []string{"../../component/component*"},
},
Expected: testutils_test.RemoveTestExpectedValues{
Items: []string{
"../../component/do_not_delete",
},
Deleted: []string{
"../../component/component1",
"../../component/component2",
"../../component/component3",
},
},
},
{
Description: "nothing found to remove",
Given: testutils_test.RemoveTestGivenValues{
Items: []string{
"component/component1",
"component/component2",
"component/component3",
},
RemoveArgs: []string{"component/component4"},
},
Expected: testutils_test.RemoveTestExpectedValues{
Items: []string{
"component/component1",
"component/component2",
"component/component3",
},
},
},
{
Description: "no arguments",
Given: testutils_test.RemoveTestGivenValues{},
Expected: testutils_test.RemoveTestExpectedValues{
Err: errors.New("must specify a component file"),
},
},
{
Description: "remove with multiple pattern arguments",
Given: testutils_test.RemoveTestGivenValues{
Items: []string{
"foo/component1",
"bar/component2",
"do_not_delete",
"component3",
},
RemoveArgs: []string{
"foo/*",
"bar/*",
"compo*",
},
},
Expected: testutils_test.RemoveTestExpectedValues{
Items: []string{
"do_not_delete",
},
Deleted: []string{
"foo/component1",
"bar/component2",
"component3",
},
},
},
}
testutils_test.ExecuteRemoveTestCases(t, testCases, "components", newCmdRemoveComponent)
}