1/*
2Copyright 2018 The Kubernetes Authors.
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8    http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package configmapandsecret
18
19import (
20	"reflect"
21	"testing"
22
23	corev1 "k8s.io/api/core/v1"
24	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25	"sigs.k8s.io/kustomize/pkg/fs"
26	"sigs.k8s.io/kustomize/pkg/loader"
27	"sigs.k8s.io/kustomize/pkg/types"
28)
29
30func makeEnvSecret(name string) *corev1.Secret {
31	return &corev1.Secret{
32		TypeMeta: metav1.TypeMeta{
33			APIVersion: "v1",
34			Kind:       "Secret",
35		},
36		ObjectMeta: metav1.ObjectMeta{
37			Name: name,
38		},
39		Data: map[string][]byte{
40			"DB_PASSWORD": []byte("somepw"),
41			"DB_USERNAME": []byte("admin"),
42		},
43		Type: "Opaque",
44	}
45}
46
47func makeFileSecret(name string) *corev1.Secret {
48	return &corev1.Secret{
49		TypeMeta: metav1.TypeMeta{
50			APIVersion: "v1",
51			Kind:       "Secret",
52		},
53		ObjectMeta: metav1.ObjectMeta{
54			Name: name,
55		},
56		Data: map[string][]byte{
57			"app-init.ini": []byte(`FOO=bar
58BAR=baz
59`),
60		},
61		Type: "Opaque",
62	}
63}
64
65func makeLiteralSecret(name string) *corev1.Secret {
66	s := &corev1.Secret{
67		TypeMeta: metav1.TypeMeta{
68			APIVersion: "v1",
69			Kind:       "Secret",
70		},
71		ObjectMeta: metav1.ObjectMeta{
72			Name: name,
73		},
74		Data: map[string][]byte{
75			"a": []byte("x"),
76			"b": []byte("y"),
77		},
78		Type: "Opaque",
79	}
80	s.SetLabels(map[string]string{"foo": "bar"})
81	return s
82}
83
84func TestConstructSecret(t *testing.T) {
85	type testCase struct {
86		description string
87		input       types.SecretArgs
88		options     *types.GeneratorOptions
89		expected    *corev1.Secret
90	}
91
92	testCases := []testCase{
93		{
94			description: "construct secret from env",
95			input: types.SecretArgs{
96				GeneratorArgs: types.GeneratorArgs{
97					Name: "envSecret",
98					DataSources: types.DataSources{
99						EnvSource: "secret/app.env",
100					},
101				},
102			},
103			options:  nil,
104			expected: makeEnvSecret("envSecret"),
105		},
106		{
107			description: "construct secret from file",
108			input: types.SecretArgs{
109				GeneratorArgs: types.GeneratorArgs{
110					Name: "fileSecret",
111					DataSources: types.DataSources{
112						FileSources: []string{"secret/app-init.ini"},
113					},
114				},
115			},
116			options:  nil,
117			expected: makeFileSecret("fileSecret"),
118		},
119		{
120			description: "construct secret from literal",
121			input: types.SecretArgs{
122				GeneratorArgs: types.GeneratorArgs{
123					Name: "literalSecret",
124					DataSources: types.DataSources{
125						LiteralSources: []string{"a=x", "b=y"},
126					},
127				},
128			},
129			options: &types.GeneratorOptions{
130				Labels: map[string]string{
131					"foo": "bar",
132				},
133			},
134			expected: makeLiteralSecret("literalSecret"),
135		},
136	}
137
138	fSys := fs.MakeFakeFS()
139	fSys.WriteFile("/secret/app.env", []byte("DB_USERNAME=admin\nDB_PASSWORD=somepw\n"))
140	fSys.WriteFile("/secret/app-init.ini", []byte("FOO=bar\nBAR=baz\n"))
141	f := NewSecretFactory(loader.NewFileLoaderAtRoot(fSys))
142	for _, tc := range testCases {
143		cm, err := f.MakeSecret(&tc.input, tc.options)
144		if err != nil {
145			t.Fatalf("unexpected error: %v", err)
146		}
147		if !reflect.DeepEqual(*cm, *tc.expected) {
148			t.Fatalf("in testcase: %q updated:\n%#v\ndoesn't match expected:\n%#v\n", tc.description, *cm, tc.expected)
149		}
150	}
151}
152