mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-13 18:10:59 +00:00
fix: handle empty namespace as default
Update the namespace handling in the edit add configmap and secret commands to handle the empty namespace and the default namespace in the same way. Before this change, if a configmap/secret was created using kustomize edit add where one command was issued with default as the namespace and the other without a namespace specified it would create two separate configmap generators, and then kustomize build would fail if merge was not the strategy for either.
This commit is contained in:
41
go.work.sum
41
go.work.sum
@@ -118,6 +118,7 @@ github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI
|
||||
github.com/hashicorp/mdns v1.0.0 h1:WhIgCr5a7AaVH6jPUwjtRuuE7/RDufnUvzIr48smyxs=
|
||||
github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M=
|
||||
github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c=
|
||||
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
|
||||
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
@@ -201,6 +202,7 @@ go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
|
||||
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
|
||||
@@ -208,21 +210,56 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
|
||||
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
|
||||
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
|
||||
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
gomodules.xyz/jsonpatch/v2 v2.0.1 h1:xyiBuvkD2g5n7cYzx6u2sxQvsAy4QJsZFCzGVdzOXZ0=
|
||||
gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485 h1:OB/uP/Puiu5vS5QMRPrXCDWUPb+kt8f1KW8oQzFejQw=
|
||||
gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e h1:jRyg0XfpwWlhEV8mDfdNGBeSJM2fuyh9Yjrnd8kF2Ts=
|
||||
google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w=
|
||||
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368 h1:Et6SkiuvnBn+SgrSYXs/BrUpGB4mbdwt4R3vaPIlicA=
|
||||
google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25 h1:Ev7yu1/f6+d+b3pi5vPdRPc6nNtP1umSfcWiEfRqv6I=
|
||||
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI=
|
||||
gopkg.in/square/go-jose.v2 v2.2.2 h1:orlkJ3myw8CN1nVQHBFfloD+L3egixIa4FvUP6RosSA=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
|
||||
k8s.io/apiserver v0.17.0 h1:XhUix+FKFDcBygWkQNp7wKKvZL030QUlH1o8vFeSgZA=
|
||||
k8s.io/code-generator v0.17.0 h1:y+KWtDWNqlJzJu/kUy8goJZO0X71PGIpAHLX8a0JYk0=
|
||||
k8s.io/component-base v0.17.0 h1:BnDFcmBDq+RPpxXjmuYnZXb59XNN9CaFrX8ba9+3xrA=
|
||||
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c h1:GohjlNKauSai7gN4wsJkeZ3WAJx4Sh+oT/b5IYn5suA=
|
||||
k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
|
||||
modernc.org/cc v1.0.0 h1:nPibNuDEx6tvYrUAtvDTTw98rx5juGsa5zuDnKwEEQQ=
|
||||
modernc.org/golex v1.0.0 h1:wWpDlbK8ejRfSyi0frMyhilD3JBvtcx2AdGDnU+JtsE=
|
||||
modernc.org/mathutil v1.0.0 h1:93vKjrJopTPrtTNpZ8XIovER7iCIH1QU7wNbOQXC60I=
|
||||
modernc.org/strutil v1.0.0 h1:XVFtQwFVwc02Wk+0L/Z/zDDXO81r5Lhe6iMKmGX3KhE=
|
||||
modernc.org/xc v1.0.0 h1:7ccXrupWZIS3twbUGrtKmHS2DXY6xegFua+6O3xgAFU=
|
||||
rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE=
|
||||
rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY=
|
||||
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
|
||||
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU=
|
||||
|
||||
@@ -148,7 +148,7 @@ func addConfigMap(
|
||||
|
||||
func findOrMakeConfigMapArgs(m *types.Kustomization, name, namespace string) *types.ConfigMapArgs {
|
||||
for i, v := range m.ConfigMapGenerator {
|
||||
if name == v.Name && namespace == v.Namespace {
|
||||
if name == v.Name && util.NamespaceEqual(v.Namespace, namespace) {
|
||||
return &m.ConfigMapGenerator[i]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ const (
|
||||
|
||||
func TestNewAddConfigMapIsNotNil(t *testing.T) {
|
||||
fSys := filesys.MakeFsInMemory()
|
||||
assert.NotNil(t, newCmdAddConfigMap(
|
||||
require.NotNil(t, newCmdAddConfigMap(
|
||||
fSys,
|
||||
kv.NewLoader(
|
||||
loader.NewFileLoaderAtCwd(fSys),
|
||||
@@ -41,15 +41,14 @@ func TestMakeConfigMapArgs(t *testing.T) {
|
||||
NamePrefix: "test-name-prefix",
|
||||
}
|
||||
|
||||
if len(kustomization.ConfigMapGenerator) != 0 {
|
||||
t.Fatal("Initial kustomization should not have any configmaps")
|
||||
}
|
||||
require.Len(t, kustomization.ConfigMapGenerator, 0, "Initial kustomization should not have any configmaps")
|
||||
|
||||
args := findOrMakeConfigMapArgs(kustomization, cmName, configMapNamespace)
|
||||
assert.NotNil(t, args)
|
||||
assert.Equal(t, 1, len(kustomization.ConfigMapGenerator))
|
||||
assert.Equal(t, &kustomization.ConfigMapGenerator[len(kustomization.ConfigMapGenerator)-1], args)
|
||||
assert.Equal(t, args, findOrMakeConfigMapArgs(kustomization, cmName, configMapNamespace))
|
||||
assert.Equal(t, 1, len(kustomization.ConfigMapGenerator))
|
||||
require.NotNil(t, args)
|
||||
require.Equal(t, 1, len(kustomization.ConfigMapGenerator))
|
||||
require.Equal(t, &kustomization.ConfigMapGenerator[len(kustomization.ConfigMapGenerator)-1], args)
|
||||
require.Equal(t, args, findOrMakeConfigMapArgs(kustomization, cmName, configMapNamespace))
|
||||
require.Equal(t, 1, len(kustomization.ConfigMapGenerator))
|
||||
}
|
||||
|
||||
func TestMergeFlagsIntoConfigMapArgs_LiteralSources(t *testing.T) {
|
||||
@@ -352,3 +351,143 @@ func TestEditAddConfigMapWithFileSource(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestEditAddConfigMapNamespaced tests situations regarding namespacing. For example, it
|
||||
// verifies that the empty namespace and the default namespace are treated the
|
||||
// same when adding a configmap to a kustomization file.
|
||||
func TestEditAddConfigMapNamespaced(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
configMapName string
|
||||
configMapNamespace string
|
||||
literalSources []string
|
||||
initialArgs string
|
||||
expectedResult []types.ConfigMapArgs
|
||||
expectedSliceLength int
|
||||
}{
|
||||
{
|
||||
name: "adds new key to configmap when default namespace matches empty",
|
||||
configMapName: "test-cm",
|
||||
configMapNamespace: "default",
|
||||
literalSources: []string{"key1=value1"},
|
||||
initialArgs: `---
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
configMapGenerator:
|
||||
- literals:
|
||||
- key=value
|
||||
name: test-cm
|
||||
`,
|
||||
expectedResult: []types.ConfigMapArgs{
|
||||
{
|
||||
GeneratorArgs: types.GeneratorArgs{
|
||||
Namespace: "",
|
||||
Name: "test-cm",
|
||||
KvPairSources: types.KvPairSources{
|
||||
LiteralSources: []string{"key=value", "key1=value1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedSliceLength: 1,
|
||||
},
|
||||
{
|
||||
name: "adds new key to configmap when empty namespace matches default",
|
||||
configMapName: "test-cm",
|
||||
configMapNamespace: "",
|
||||
literalSources: []string{"key1=value1"},
|
||||
initialArgs: `---
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
configMapGenerator:
|
||||
- literals:
|
||||
- key=value
|
||||
name: test-cm
|
||||
namespace: default
|
||||
`,
|
||||
expectedResult: []types.ConfigMapArgs{
|
||||
{
|
||||
GeneratorArgs: types.GeneratorArgs{
|
||||
Namespace: "default",
|
||||
Name: "test-cm",
|
||||
KvPairSources: types.KvPairSources{
|
||||
LiteralSources: []string{"key=value", "key1=value1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedSliceLength: 1,
|
||||
},
|
||||
{
|
||||
name: "creates a new generator when namespaces don't match",
|
||||
configMapName: "test-cm",
|
||||
configMapNamespace: "",
|
||||
literalSources: []string{"key1=value1"},
|
||||
initialArgs: `---
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
configMapGenerator:
|
||||
- literals:
|
||||
- key=value
|
||||
name: test-cm
|
||||
namespace: ns1
|
||||
`,
|
||||
expectedResult: []types.ConfigMapArgs{
|
||||
{
|
||||
GeneratorArgs: types.GeneratorArgs{
|
||||
Namespace: "ns1",
|
||||
Name: "test-cm",
|
||||
KvPairSources: types.KvPairSources{
|
||||
LiteralSources: []string{"key=value"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
GeneratorArgs: types.GeneratorArgs{
|
||||
Namespace: "",
|
||||
Name: "test-cm",
|
||||
KvPairSources: types.KvPairSources{
|
||||
LiteralSources: []string{"key1=value1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedSliceLength: 2,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
fSys := filesys.MakeEmptyDirInMemory()
|
||||
testutils_test.WriteTestKustomizationWith(fSys, []byte(tc.initialArgs))
|
||||
|
||||
pvd := provider.NewDefaultDepProvider()
|
||||
ldr := kv.NewLoader(loader.NewFileLoaderAtCwd(fSys), pvd.GetFieldValidator())
|
||||
|
||||
args := []string{
|
||||
tc.configMapName,
|
||||
fmt.Sprintf(util.FlagFormat, util.NamespaceFlag, tc.configMapNamespace),
|
||||
}
|
||||
|
||||
for _, source := range tc.literalSources {
|
||||
args = append(args, fmt.Sprintf(util.FlagFormat, util.FromLiteralFlag, source))
|
||||
}
|
||||
|
||||
cmd := newCmdAddConfigMap(fSys, ldr, pvd.GetResourceFactory())
|
||||
cmd.SetArgs(args)
|
||||
require.NoError(t, cmd.Execute())
|
||||
|
||||
_, err := testutils_test.ReadTestKustomization(fSys)
|
||||
require.NoError(t, err)
|
||||
|
||||
mf, err := kustfile.NewKustomizationFile(fSys)
|
||||
require.NoError(t, err)
|
||||
|
||||
kustomization, err := mf.Read()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, kustomization.ConfigMapGenerator, tc.expectedSliceLength)
|
||||
require.ElementsMatch(t, tc.expectedResult, kustomization.ConfigMapGenerator)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ func addSecret(
|
||||
|
||||
func findOrMakeSecretArgs(m *types.Kustomization, name, namespace, secretType string) *types.SecretArgs {
|
||||
for i, v := range m.SecretGenerator {
|
||||
if name == v.Name && namespace == v.Namespace {
|
||||
if name == v.Name && util.NamespaceEqual(v.Namespace, namespace) {
|
||||
return &m.SecretGenerator[i]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"sigs.k8s.io/kustomize/api/ifc"
|
||||
"sigs.k8s.io/kustomize/api/kv"
|
||||
"sigs.k8s.io/kustomize/api/pkg/loader"
|
||||
"sigs.k8s.io/kustomize/api/provider"
|
||||
@@ -237,3 +238,150 @@ func TestEditAddSecretWithFileSource(t *testing.T) {
|
||||
require.Equal(t, secretName, newSecretGenerator.Name)
|
||||
require.Contains(t, newSecretGenerator.FileSources, fileSource)
|
||||
}
|
||||
|
||||
// TestEditAddSecretNamespaced tests situations regarding namespacing. For example, it
|
||||
// verifies that the empty namespace and the default namespace are treated the
|
||||
// same when adding a configmap to a kustomization file.
|
||||
func TestEditAddSecretNamespaced(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
secretName string
|
||||
secretNamespace string
|
||||
literalSources []string
|
||||
initialArgs string
|
||||
expectedResult []types.SecretArgs
|
||||
expectedSliceLength int
|
||||
}{
|
||||
{
|
||||
name: "adds new key to secret when default namespace matches empty",
|
||||
secretName: "test-secret",
|
||||
secretNamespace: "default",
|
||||
literalSources: []string{"key1=value1"},
|
||||
initialArgs: `---
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
secretGenerator:
|
||||
- literals:
|
||||
- key=value
|
||||
name: test-secret
|
||||
type: Opaque
|
||||
`,
|
||||
expectedResult: []types.SecretArgs{
|
||||
{
|
||||
GeneratorArgs: types.GeneratorArgs{
|
||||
Namespace: "",
|
||||
Name: "test-secret",
|
||||
KvPairSources: types.KvPairSources{
|
||||
LiteralSources: []string{"key=value", "key1=value1"},
|
||||
},
|
||||
},
|
||||
Type: ifc.SecretTypeOpaque,
|
||||
},
|
||||
},
|
||||
expectedSliceLength: 1,
|
||||
},
|
||||
{
|
||||
name: "adds new key to secret when empty namespace matches default",
|
||||
secretName: "test-secret",
|
||||
secretNamespace: "",
|
||||
literalSources: []string{"key1=value1"},
|
||||
initialArgs: `---
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
secretGenerator:
|
||||
- literals:
|
||||
- key=value
|
||||
name: test-secret
|
||||
namespace: default
|
||||
type: Opaque
|
||||
`,
|
||||
expectedResult: []types.SecretArgs{
|
||||
{
|
||||
GeneratorArgs: types.GeneratorArgs{
|
||||
Namespace: "default",
|
||||
Name: "test-secret",
|
||||
KvPairSources: types.KvPairSources{
|
||||
LiteralSources: []string{"key=value", "key1=value1"},
|
||||
},
|
||||
},
|
||||
Type: ifc.SecretTypeOpaque,
|
||||
},
|
||||
},
|
||||
expectedSliceLength: 1,
|
||||
},
|
||||
{
|
||||
name: "creates a new generator when namespaces don't match",
|
||||
secretName: "test-secret",
|
||||
secretNamespace: "",
|
||||
literalSources: []string{"key1=value1"},
|
||||
initialArgs: `---
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
secretGenerator:
|
||||
- literals:
|
||||
- key=value
|
||||
name: test-secret
|
||||
namespace: ns1
|
||||
type: Opaque
|
||||
`,
|
||||
expectedResult: []types.SecretArgs{
|
||||
{
|
||||
GeneratorArgs: types.GeneratorArgs{
|
||||
Namespace: "ns1",
|
||||
Name: "test-secret",
|
||||
KvPairSources: types.KvPairSources{
|
||||
LiteralSources: []string{"key=value"},
|
||||
},
|
||||
},
|
||||
Type: ifc.SecretTypeOpaque,
|
||||
},
|
||||
{
|
||||
GeneratorArgs: types.GeneratorArgs{
|
||||
Namespace: "",
|
||||
Name: "test-secret",
|
||||
KvPairSources: types.KvPairSources{
|
||||
LiteralSources: []string{"key1=value1"},
|
||||
},
|
||||
},
|
||||
Type: ifc.SecretTypeOpaque,
|
||||
},
|
||||
},
|
||||
expectedSliceLength: 2,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
fSys := filesys.MakeEmptyDirInMemory()
|
||||
testutils_test.WriteTestKustomizationWith(fSys, []byte(tc.initialArgs))
|
||||
|
||||
pvd := provider.NewDefaultDepProvider()
|
||||
ldr := kv.NewLoader(loader.NewFileLoaderAtCwd(fSys), pvd.GetFieldValidator())
|
||||
|
||||
args := []string{
|
||||
tc.secretName,
|
||||
fmt.Sprintf(util.FlagFormat, util.NamespaceFlag, tc.secretNamespace),
|
||||
}
|
||||
|
||||
for _, source := range tc.literalSources {
|
||||
args = append(args, fmt.Sprintf(util.FlagFormat, util.FromLiteralFlag, source))
|
||||
}
|
||||
|
||||
cmd := newCmdAddSecret(fSys, ldr, pvd.GetResourceFactory())
|
||||
cmd.SetArgs(args)
|
||||
require.NoError(t, cmd.Execute())
|
||||
|
||||
_, err := testutils_test.ReadTestKustomization(fSys)
|
||||
require.NoError(t, err)
|
||||
|
||||
mf, err := kustfile.NewKustomizationFile(fSys)
|
||||
require.NoError(t, err)
|
||||
|
||||
kustomization, err := mf.Read()
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, kustomization.SecretGenerator, tc.expectedSliceLength)
|
||||
require.ElementsMatch(t, tc.expectedResult, kustomization.SecretGenerator)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ import (
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
)
|
||||
|
||||
// DefaultNamespace is the default namespace name in Kubernetes.
|
||||
const DefaultNamespace = "default"
|
||||
|
||||
// GlobPatterns accepts a slice of glob strings and returns the set of
|
||||
// matching file paths.
|
||||
func GlobPatterns(fSys filesys.FileSystem, patterns []string) ([]string, error) {
|
||||
@@ -30,7 +33,7 @@ func GlobPatterns(fSys filesys.FileSystem, patterns []string) ([]string, error)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GlobPatterns accepts a slice of glob strings and returns the set of matching file paths.
|
||||
// GlobPatternsWithLoader accepts a slice of glob strings and returns the set of matching file paths.
|
||||
// If validation is skipped, then it will return the patterns as provided.
|
||||
// Otherwise, It will try to load the files from the filesystem.
|
||||
// If files are not found in the filesystem, it will try to load from remote.
|
||||
@@ -109,3 +112,18 @@ func trimQuotes(s string) string {
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// NamespaceEqual checks if two namespaces are the same. It considers the empty namespace and the default namespace to
|
||||
// be the same. As such, when one namespace is the empty string ('""') and the other namespace is "default", this function
|
||||
// will return true.
|
||||
func NamespaceEqual(namespace string, otherNamespace string) bool {
|
||||
if "" == namespace {
|
||||
namespace = DefaultNamespace
|
||||
}
|
||||
|
||||
if "" == otherNamespace {
|
||||
otherNamespace = DefaultNamespace
|
||||
}
|
||||
|
||||
return namespace == otherNamespace
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2019 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package util
|
||||
package util_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"sigs.k8s.io/kustomize/api/ifc"
|
||||
. "sigs.k8s.io/kustomize/kustomize/v5/commands/internal/util"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
)
|
||||
|
||||
@@ -86,6 +87,58 @@ func TestGlobPatternsWithLoaderRemoteFile(t *testing.T) {
|
||||
require.Equal(t, invalidURL, resources[0], "incorrect resources")
|
||||
}
|
||||
|
||||
func TestNamespaceEqual(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
namespace1 string
|
||||
namespace2 string
|
||||
want func(require.TestingT, bool, ...interface{})
|
||||
}{
|
||||
{
|
||||
name: "succeeds when namespaces are the same",
|
||||
namespace1: "ns1",
|
||||
namespace2: "ns1",
|
||||
want: require.True,
|
||||
},
|
||||
{
|
||||
name: "succeeds when namespaces are default and empty string",
|
||||
namespace1: "",
|
||||
namespace2: DefaultNamespace,
|
||||
want: require.True,
|
||||
},
|
||||
{
|
||||
name: "succeeds when namespaces are empty string and default",
|
||||
namespace1: DefaultNamespace,
|
||||
namespace2: "",
|
||||
want: require.True,
|
||||
},
|
||||
{
|
||||
name: "fails when namespaces are not the same",
|
||||
namespace1: "ns1",
|
||||
namespace2: "ns2",
|
||||
want: require.False,
|
||||
},
|
||||
{
|
||||
name: "fails when one is empty and other is different from default",
|
||||
namespace1: "",
|
||||
namespace2: "ns1",
|
||||
want: require.False,
|
||||
},
|
||||
{
|
||||
name: "fails when one is different from default and other is empty",
|
||||
namespace1: "ns1",
|
||||
namespace2: "",
|
||||
want: require.False,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
tc.want(t, NamespaceEqual(tc.namespace1, tc.namespace2))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type fakeLoader struct {
|
||||
path string
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ require (
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/xlab/treeprint v1.2.0 // indirect
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/evanphx/json-patch.v5 v5.6.0 // indirect
|
||||
|
||||
@@ -66,6 +66,8 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
|
||||
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
||||
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
||||
Reference in New Issue
Block a user