Skip to content

Commit 72b0fd1

Browse files
authored
Merge pull request #6037 from rohithnarasimha/feat/add-configuration-command
feat: add support for 'kustomize edit add configuration' command
2 parents 80f63ae + 1af74f2 commit 72b0fd1

3 files changed

Lines changed: 171 additions & 0 deletions

File tree

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

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)