1/*
2Copyright 2019 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 gci
18
19import (
20	"os"
21	"strconv"
22	"strings"
23	"testing"
24)
25
26type kubeAPIServeETCDEnv struct {
27	KubeHome               string
28	KubeAPIServerRunAsUser string
29	ETCDServers            string
30	ETCDServersOverride    string
31	CAKey                  string
32	CACert                 string
33	CACertPath             string
34	APIServerKey           string
35	APIServerCert          string
36	APIServerCertPath      string
37	APIServerKeyPath       string
38	ETCDKey                string
39	ETCDCert               string
40	StorageBackend         string
41	StorageMediaType       string
42	CompactionInterval     string
43}
44
45func TestServerOverride(t *testing.T) {
46	testCases := []struct {
47		desc string
48		env  kubeAPIServeETCDEnv
49		want []string
50	}{
51		{
52			desc: "ETCD-SERVERS is not set - default override",
53			want: []string{
54				"--etcd-servers-overrides=/events#http://127.0.0.1:4002",
55			},
56		},
57		{
58			desc: "ETCD-SERVERS and ETCD_SERVERS_OVERRIDES are set",
59			env: kubeAPIServeETCDEnv{
60				ETCDServers:         "ETCDServers",
61				ETCDServersOverride: "ETCDServersOverrides",
62			},
63			want: []string{
64				"--etcd-servers-overrides=ETCDServersOverrides",
65			},
66		},
67	}
68
69	for _, tc := range testCases {
70		t.Run(tc.desc, func(t *testing.T) {
71			c := newManifestTestCase(t, kubeAPIServerManifestFileName, kubeAPIServerStartFuncName, nil)
72			defer c.tearDown()
73			tc.env.KubeHome = c.kubeHome
74			tc.env.KubeAPIServerRunAsUser = strconv.Itoa(os.Getuid())
75
76			c.mustInvokeFunc(
77				tc.env,
78				[]string{"configure-helper.sh", kubeAPIServerConfigScriptName},
79				"etcd.template",
80				"testdata/kube-apiserver/base.template",
81				"testdata/kube-apiserver/etcd.template",
82			)
83			c.mustLoadPodFromManifest()
84
85			execArgs := strings.Join(c.pod.Spec.Containers[0].Command, " ")
86			for _, f := range tc.want {
87				if !strings.Contains(execArgs, f) {
88					t.Fatalf("Got %q, want it to contain %q", execArgs, f)
89				}
90			}
91		})
92	}
93}
94
95func TestStorageOptions(t *testing.T) {
96	testCases := []struct {
97		desc     string
98		env      kubeAPIServeETCDEnv
99		want     []string
100		dontWant []string
101	}{
102		{
103			desc: "storage options are supplied",
104			env: kubeAPIServeETCDEnv{
105				StorageBackend:     "StorageBackend",
106				StorageMediaType:   "StorageMediaType",
107				CompactionInterval: "1s",
108			},
109			want: []string{
110				"--storage-backend=StorageBackend",
111				"--storage-media-type=StorageMediaType",
112				"--etcd-compaction-interval=1s",
113			},
114		},
115		{
116			desc: "storage options are not supplied",
117			env:  kubeAPIServeETCDEnv{},
118			dontWant: []string{
119				"--storage-backend",
120				"--storage-media-type",
121				"--etcd-compaction-interval",
122			},
123		},
124	}
125
126	for _, tc := range testCases {
127		t.Run(tc.desc, func(t *testing.T) {
128			c := newManifestTestCase(t, kubeAPIServerManifestFileName, kubeAPIServerStartFuncName, nil)
129			defer c.tearDown()
130			tc.env.KubeHome = c.kubeHome
131			tc.env.KubeAPIServerRunAsUser = strconv.Itoa(os.Getuid())
132
133			c.mustInvokeFunc(
134				tc.env,
135				[]string{"configure-helper.sh", kubeAPIServerConfigScriptName},
136				"etcd.template",
137				"testdata/kube-apiserver/base.template",
138				"testdata/kube-apiserver/etcd.template",
139			)
140			c.mustLoadPodFromManifest()
141
142			execArgs := strings.Join(c.pod.Spec.Containers[0].Command, " ")
143			for _, f := range tc.want {
144				if !strings.Contains(execArgs, f) {
145					t.Fatalf("Got %q, want it to contain %q", execArgs, f)
146				}
147			}
148
149			for _, f := range tc.dontWant {
150				if strings.Contains(execArgs, f) {
151					t.Fatalf("Got %q, but it was not expected it to contain %q", execArgs, f)
152				}
153			}
154		})
155	}
156}
157
158func TestTLSFlags(t *testing.T) {
159	testCases := []struct {
160		desc string
161		env  kubeAPIServeETCDEnv
162		want []string
163	}{
164		{
165			desc: "mTLS enabled",
166			env: kubeAPIServeETCDEnv{
167				CAKey:             "CAKey",
168				CACert:            "CACert",
169				CACertPath:        "CACertPath",
170				APIServerKey:      "APIServerKey",
171				APIServerCert:     "APIServerCert",
172				ETCDKey:           "ETCDKey",
173				ETCDCert:          "ETCDCert",
174				ETCDServers:       "https://127.0.0.1:2379",
175				APIServerKeyPath:  "APIServerKeyPath",
176				APIServerCertPath: "APIServerCertPath",
177			},
178			want: []string{
179				"--etcd-servers=https://127.0.0.1:2379",
180				"--etcd-cafile=CACertPath",
181				"--etcd-certfile=APIServerCertPath",
182				"--etcd-keyfile=APIServerKeyPath",
183			},
184		},
185		{
186			desc: "mTLS disabled",
187			want: []string{"--etcd-servers=http://127.0.0.1:2379"},
188		},
189	}
190
191	for _, tc := range testCases {
192		t.Run(tc.desc, func(t *testing.T) {
193			c := newManifestTestCase(t, kubeAPIServerManifestFileName, kubeAPIServerStartFuncName, nil)
194			defer c.tearDown()
195			tc.env.KubeHome = c.kubeHome
196			tc.env.KubeAPIServerRunAsUser = strconv.Itoa(os.Getuid())
197
198			c.mustInvokeFunc(
199				tc.env,
200				[]string{"configure-helper.sh", kubeAPIServerConfigScriptName},
201				"etcd.template",
202				"testdata/kube-apiserver/base.template",
203				"testdata/kube-apiserver/etcd.template",
204			)
205			c.mustLoadPodFromManifest()
206
207			execArgs := strings.Join(c.pod.Spec.Containers[0].Command, " ")
208			for _, f := range tc.want {
209				if !strings.Contains(execArgs, f) {
210					t.Fatalf("Got %q, want it to contain %q", execArgs, f)
211				}
212			}
213		})
214	}
215}
216