Skip to content

Commit 3ac1ae2

Browse files
Rohith-arm64rohithnarasimha
authored andcommitted
feat(commands/edit/add): add support for 'kustomize edit add configuration' command
Add a new subcommand 'kustomize edit add configuration' to programmatically add configuration file references to kustomization.yaml files. This brings configurations support in line with other 'kustomize edit add' subcommands (generators, transformers, validators). Features: - Support for single and multiple configuration file paths - Glob pattern expansion (e.g., ./configs/*.yaml) - Duplicate detection with user logging - Idempotent operation Related to #5987
1 parent 17a06a7 commit 3ac1ae2

File tree

3 files changed

+178
-0
lines changed

3 files changed

+178
-0
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright 2025 The Kubernetes Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package add
5+
6+
import (
7+
"errors"
8+
"log"
9+
"slices"
10+
11+
"github.com/spf13/cobra"
12+
"sigs.k8s.io/kustomize/kustomize/v5/commands/internal/kustfile"
13+
"sigs.k8s.io/kustomize/kustomize/v5/commands/internal/util"
14+
"sigs.k8s.io/kustomize/kyaml/filesys"
15+
)
16+
17+
type addConfigurationOptions struct {
18+
configurationFilePaths []string
19+
}
20+
21+
// newCmdAddConfiguration adds the name of a file containing a configuration
22+
// to the kustomization file.
23+
func newCmdAddConfiguration(fSys filesys.FileSystem) *cobra.Command {
24+
var o addConfigurationOptions
25+
cmd := &cobra.Command{
26+
Use: "configuration",
27+
Short: "Add the name of a file containing a configuration to the kustomization file",
28+
Long: `Add the name of a file containing a configuration (e.g., a Kubernetes configuration resource)
29+
to the kustomization file. Configurations are used to define custom transformer specifications
30+
for CRDs and other resource types.`,
31+
Example: `
32+
# Adds a configuration file to the kustomization
33+
kustomize edit add configuration <filepath>
34+
35+
# Adds multiple configuration files
36+
kustomize edit add configuration <filepath1>,<filepath2>`,
37+
RunE: func(cmd *cobra.Command, args []string) error {
38+
err := o.Validate(fSys, args)
39+
if err != nil {
40+
return err
41+
}
42+
return o.RunAddConfiguration(fSys)
43+
},
44+
}
45+
return cmd
46+
}
47+
48+
// Validate validates add configuration command.
49+
func (o *addConfigurationOptions) Validate(fSys filesys.FileSystem, args []string) error {
50+
if len(args) == 0 {
51+
return errors.New("must specify a yaml file which contains a configuration resource")
52+
}
53+
var err error
54+
o.configurationFilePaths, err = util.GlobPatterns(fSys, args)
55+
return err
56+
}
57+
58+
// RunAddConfiguration runs add configuration command (do real work).
59+
func (o *addConfigurationOptions) RunAddConfiguration(fSys filesys.FileSystem) error {
60+
if len(o.configurationFilePaths) == 0 {
61+
return nil
62+
}
63+
mf, err := kustfile.NewKustomizationFile(fSys)
64+
if err != nil {
65+
return err
66+
}
67+
m, err := mf.Read()
68+
if err != nil {
69+
return err
70+
}
71+
for _, c := range o.configurationFilePaths {
72+
if slices.Contains(m.Configurations, c) {
73+
log.Printf("configuration %s already in kustomization file", c)
74+
continue
75+
}
76+
m.Configurations = append(m.Configurations, c)
77+
}
78+
return mf.Write(m)
79+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright 2025 The Kubernetes Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package add
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
11+
testutils_test "sigs.k8s.io/kustomize/kustomize/v5/commands/internal/testutils"
12+
"sigs.k8s.io/kustomize/kyaml/filesys"
13+
)
14+
15+
func TestAddConfiguration(t *testing.T) {
16+
fSys := filesys.MakeEmptyDirInMemory()
17+
testutils_test.WriteTestKustomization(fSys)
18+
19+
cmd := newCmdAddConfiguration(fSys)
20+
21+
if cmd == nil {
22+
t.Fatal("Expected cmd to not be nil")
23+
}
24+
25+
if cmd.Use != "configuration" {
26+
t.Fatalf("Expected Use to be 'configuration', got '%s'", cmd.Use)
27+
}
28+
29+
if cmd.Short == "" {
30+
t.Fatal("Expected Short to not be empty")
31+
}
32+
}
33+
34+
func TestAddConfigurationHappyPath(t *testing.T) {
35+
fSys := filesys.MakeEmptyDirInMemory()
36+
err := fSys.WriteFile("config1.yaml", []byte("apiVersion: v1\nkind: Config"))
37+
require.NoError(t, err)
38+
err = fSys.WriteFile("config2.yaml", []byte("apiVersion: v1\nkind: Config"))
39+
require.NoError(t, err)
40+
testutils_test.WriteTestKustomization(fSys)
41+
42+
cmd := newCmdAddConfiguration(fSys)
43+
args := []string{"config1.yaml", "config2.yaml"}
44+
require.NoError(t, cmd.RunE(cmd, args))
45+
46+
content, err := testutils_test.ReadTestKustomization(fSys)
47+
require.NoError(t, err)
48+
assert.Contains(t, string(content), "config1.yaml")
49+
assert.Contains(t, string(content), "config2.yaml")
50+
}
51+
52+
func TestAddConfigurationDuplicate(t *testing.T) {
53+
fSys := filesys.MakeEmptyDirInMemory()
54+
err := fSys.WriteFile("config.yaml", []byte("apiVersion: v1\nkind: Config"))
55+
require.NoError(t, err)
56+
testutils_test.WriteTestKustomization(fSys)
57+
58+
cmd := newCmdAddConfiguration(fSys)
59+
60+
// First addition
61+
args := []string{"config.yaml"}
62+
require.NoError(t, cmd.RunE(cmd, args))
63+
64+
content, err := testutils_test.ReadTestKustomization(fSys)
65+
require.NoError(t, err)
66+
assert.Contains(t, string(content), "config.yaml")
67+
68+
// Second addition (should skip duplicate)
69+
require.NoError(t, cmd.RunE(cmd, args))
70+
71+
content, err = testutils_test.ReadTestKustomization(fSys)
72+
require.NoError(t, err)
73+
74+
// Count occurrences - should only appear once
75+
count := 0
76+
data := string(content)
77+
for i := 0; i < len(data); {
78+
if idx := len(data[i:]); idx > 0 {
79+
if len(data) >= i+11 {
80+
if data[i:i+11] == "config.yaml" {
81+
count++
82+
i += 11
83+
} else {
84+
i++
85+
}
86+
} else {
87+
break
88+
}
89+
}
90+
}
91+
assert.Equal(t, 1, count, "config.yaml should appear exactly once")
92+
}

kustomize/commands/edit/add/all.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ func NewCmdAdd(
4747
4848
# Adds a transformer configuration to the kustomization
4949
kustomize edit add transformer <filepath>
50+
51+
# Adds a configuration file to the kustomization
52+
kustomize edit add configuration <filepath>
53+
54+
# Adds a generator configuration to the kustomization
55+
kustomize edit add generator <filepath>
5056
`,
5157
Args: cobra.MinimumNArgs(1),
5258
}
@@ -61,6 +67,7 @@ func NewCmdAdd(
6167
newCmdAddLabel(fSys, ldr.Validator().MakeLabelValidator()),
6268
newCmdAddAnnotation(fSys, ldr.Validator().MakeAnnotationValidator()),
6369
newCmdAddTransformer(fSys),
70+
newCmdAddConfiguration(fSys),
6471
newCmdAddGenerator(fSys),
6572
)
6673
return c

0 commit comments

Comments
 (0)