mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
Merge pull request #6037 from rohithnarasimha/feat/add-configuration-command
feat: add support for 'kustomize edit add configuration' command
This commit is contained in:
86
kustomize/commands/edit/add/addconfiguration.go
Normal file
86
kustomize/commands/edit/add/addconfiguration.go
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright 2025 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package add
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"slices"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"sigs.k8s.io/kustomize/kustomize/v5/commands/internal/kustfile"
|
||||
"sigs.k8s.io/kustomize/kustomize/v5/commands/internal/util"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
)
|
||||
|
||||
type addConfigurationOptions struct {
|
||||
configurationFilePaths []string
|
||||
}
|
||||
|
||||
// newCmdAddConfiguration adds the name of a file containing a configuration
|
||||
// to the kustomization file.
|
||||
func newCmdAddConfiguration(fSys filesys.FileSystem) *cobra.Command {
|
||||
var o addConfigurationOptions
|
||||
cmd := &cobra.Command{
|
||||
Use: "configuration",
|
||||
Short: "Add the name of a file containing a configuration to the kustomization file",
|
||||
Long: `Add the name of a file containing a configuration (e.g., a Kubernetes configuration resource)
|
||||
to the kustomization file. Configurations are used to define custom transformer specifications
|
||||
for CRDs and other resource types.`,
|
||||
Example: `
|
||||
# Adds a configuration file to the kustomization
|
||||
kustomize edit add configuration <filepath>
|
||||
|
||||
# Adds multiple configuration files
|
||||
kustomize edit add configuration <filepath1>,<filepath2>`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
err := o.Validate(fSys, args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return o.RunAddConfiguration(fSys)
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
// Validate validates add configuration command.
|
||||
func (o *addConfigurationOptions) Validate(fSys filesys.FileSystem, args []string) error {
|
||||
if len(args) == 0 {
|
||||
return errors.New("must specify a yaml file which contains a configuration resource")
|
||||
}
|
||||
var err error
|
||||
o.configurationFilePaths, err = util.GlobPatterns(fSys, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("glob patterns: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RunAddConfiguration runs add configuration command (do real work).
|
||||
func (o *addConfigurationOptions) RunAddConfiguration(fSys filesys.FileSystem) error {
|
||||
if len(o.configurationFilePaths) == 0 {
|
||||
return nil
|
||||
}
|
||||
mf, err := kustfile.NewKustomizationFile(fSys)
|
||||
if err != nil {
|
||||
return fmt.Errorf("new kustomization file: %w", err)
|
||||
}
|
||||
m, err := mf.Read()
|
||||
if err != nil {
|
||||
return fmt.Errorf("read kustomization: %w", err)
|
||||
}
|
||||
for _, c := range o.configurationFilePaths {
|
||||
if slices.Contains(m.Configurations, c) {
|
||||
log.Printf("configuration %s already in kustomization file", c)
|
||||
continue
|
||||
}
|
||||
m.Configurations = append(m.Configurations, c)
|
||||
}
|
||||
if err := mf.Write(m); err != nil {
|
||||
return fmt.Errorf("write kustomization: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
78
kustomize/commands/edit/add/addconfiguration_test.go
Normal file
78
kustomize/commands/edit/add/addconfiguration_test.go
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright 2025 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package add
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
testutils_test "sigs.k8s.io/kustomize/kustomize/v5/commands/internal/testutils"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
)
|
||||
|
||||
func TestAddConfiguration(t *testing.T) {
|
||||
fSys := filesys.MakeEmptyDirInMemory()
|
||||
testutils_test.WriteTestKustomization(fSys)
|
||||
|
||||
cmd := newCmdAddConfiguration(fSys)
|
||||
|
||||
if cmd == nil {
|
||||
t.Fatal("Expected cmd to not be nil")
|
||||
}
|
||||
|
||||
if cmd.Use != "configuration" {
|
||||
t.Fatalf("Expected Use to be 'configuration', got '%s'", cmd.Use)
|
||||
}
|
||||
|
||||
if cmd.Short == "" {
|
||||
t.Fatal("Expected Short to not be empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddConfigurationHappyPath(t *testing.T) {
|
||||
fSys := filesys.MakeEmptyDirInMemory()
|
||||
err := fSys.WriteFile("config1.yaml", []byte("apiVersion: v1\nkind: Config"))
|
||||
require.NoError(t, err)
|
||||
err = fSys.WriteFile("config2.yaml", []byte("apiVersion: v1\nkind: Config"))
|
||||
require.NoError(t, err)
|
||||
testutils_test.WriteTestKustomization(fSys)
|
||||
|
||||
cmd := newCmdAddConfiguration(fSys)
|
||||
args := []string{"config1.yaml", "config2.yaml"}
|
||||
require.NoError(t, cmd.RunE(cmd, args))
|
||||
|
||||
content, err := testutils_test.ReadTestKustomization(fSys)
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, string(content), "config1.yaml")
|
||||
assert.Contains(t, string(content), "config2.yaml")
|
||||
}
|
||||
|
||||
func TestAddConfigurationDuplicate(t *testing.T) {
|
||||
fSys := filesys.MakeEmptyDirInMemory()
|
||||
err := fSys.WriteFile("config.yaml", []byte("apiVersion: v1\nkind: Config"))
|
||||
require.NoError(t, err)
|
||||
testutils_test.WriteTestKustomization(fSys)
|
||||
|
||||
cmd := newCmdAddConfiguration(fSys)
|
||||
|
||||
// First addition
|
||||
args := []string{"config.yaml"}
|
||||
require.NoError(t, cmd.RunE(cmd, args))
|
||||
|
||||
content, err := testutils_test.ReadTestKustomization(fSys)
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, string(content), "config.yaml")
|
||||
|
||||
// Second addition (should skip duplicate)
|
||||
require.NoError(t, cmd.RunE(cmd, args))
|
||||
|
||||
content, err = testutils_test.ReadTestKustomization(fSys)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Count occurrences - should only appear once
|
||||
count := strings.Count(string(content), "config.yaml")
|
||||
assert.Equal(t, 1, count, "config.yaml should appear exactly once")
|
||||
}
|
||||
@@ -47,6 +47,12 @@ func NewCmdAdd(
|
||||
|
||||
# Adds a transformer configuration to the kustomization
|
||||
kustomize edit add transformer <filepath>
|
||||
|
||||
# Adds a configuration file to the kustomization
|
||||
kustomize edit add configuration <filepath>
|
||||
|
||||
# Adds a generator configuration to the kustomization
|
||||
kustomize edit add generator <filepath>
|
||||
`,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
}
|
||||
@@ -61,6 +67,7 @@ func NewCmdAdd(
|
||||
newCmdAddLabel(fSys, ldr.Validator().MakeLabelValidator()),
|
||||
newCmdAddAnnotation(fSys, ldr.Validator().MakeAnnotationValidator()),
|
||||
newCmdAddTransformer(fSys),
|
||||
newCmdAddConfiguration(fSys),
|
||||
newCmdAddGenerator(fSys),
|
||||
)
|
||||
return c
|
||||
|
||||
Reference in New Issue
Block a user