...
1#!/usr/bin/env bash
2
3# Copyright 2018 The Kubernetes Authors.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17set -o errexit
18set -o nounset
19set -o pipefail
20
21run_kubectl_config_set_tests() {
22 set -o nounset
23 set -o errexit
24
25 create_and_use_new_namespace
26 kube::log::status "Testing kubectl(v1:config set)"
27
28 kubectl config set-cluster test-cluster --server="https://does-not-work"
29
30 # Get the api cert and add a comment to avoid flag parsing problems
31 cert_data=$(echo "#Comment" && cat "${TMPDIR:-/tmp}/apiserver.crt")
32
33 kubectl config set clusters.test-cluster.certificate-authority-data "$cert_data" --set-raw-bytes
34 r_written=$(kubectl config view --raw -o jsonpath='{.clusters[?(@.name == "test-cluster")].cluster.certificate-authority-data}')
35
36 encoded=$(echo -n "$cert_data" | base64)
37 kubectl config set clusters.test-cluster.certificate-authority-data "$encoded"
38 e_written=$(kubectl config view --raw -o jsonpath='{.clusters[?(@.name == "test-cluster")].cluster.certificate-authority-data}')
39
40 test "$e_written" == "$r_written"
41
42 set +o nounset
43 set +o errexit
44}
45
46run_kubectl_config_set_cluster_tests() {
47 set -o nounset
48 set -o errexit
49
50 create_and_use_new_namespace
51 kube::log::status "Testing kubectl config set-cluster"
52
53 ca_file="${TMPDIR:-/tmp}/apiserver.crt"
54 ca_data=$(base64 -w0 "$ca_file")
55
56 # Set cert file
57 kubectl config set-cluster test-cluster-1 --certificate-authority "$ca_file"
58 expected="$ca_file"
59 actual=$(kubectl config view --raw -o jsonpath='{.clusters[?(@.name == "test-cluster-1")].cluster.certificate-authority}')
60 if [ "$expected" != "$actual" ]; then
61 kube::log::error "Certificate authority did not match the expected value (expected=$expected, actual=$actual)"
62 exit 1
63 fi
64
65 # Embed cert from file
66 kubectl config set-cluster test-cluster-2 --embed-certs --certificate-authority "$ca_file"
67 expected="$ca_data"
68 actual=$(kubectl config view --raw -o jsonpath='{.clusters[?(@.name == "test-cluster-2")].cluster.certificate-authority-data}')
69 if [ "$expected" != "$actual" ]; then
70 kube::log::error "Certificate authority embedded from file did not match the expected value (expected=$expected, actual=$actual)"
71 exit 1
72 fi
73
74 # Embed cert using process substitution
75 kubectl config set-cluster test-cluster-3 --embed-certs --certificate-authority <(cat "$ca_file")
76 expected="$ca_data"
77 actual=$(kubectl config view --raw -o jsonpath='{.clusters[?(@.name == "test-cluster-3")].cluster.certificate-authority-data}')
78 if [ "$expected" != "$actual" ]; then
79 kube::log::error "Certificate authority embedded using process substitution did not match the expected value (expected=$expected, actual=$actual)"
80 exit 1
81 fi
82
83 set +o nounset
84 set +o errexit
85}
86
87run_kubectl_config_set_credentials_tests() {
88 set -o nounset
89 set -o errexit
90
91 create_and_use_new_namespace
92 kube::log::status "Testing kubectl config set-credentials"
93
94 cert_file="${TMPDIR:-/tmp}/test-client-certificate.crt"
95 key_file="${TMPDIR:-/tmp}/test-client-key.crt"
96
97 cat << EOF > "$cert_file"
98-----BEGIN CERTIFICATE-----
99MIIDazCCAlOgAwIBAgIUdSrvuXs0Bft9Ao/AFnC7fNBqD+owDQYJKoZIhvcNAQEL
100BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
101GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA1MTExODMyNDJaFw0yMTA1
102MTExODMyNDJaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
103HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
104AQUAA4IBDwAwggEKAoIBAQCrS5/kYM3TjdFw4OYMdSOys0+4aHPgtXqePWrn1pBP
105W9D1yhjI/JS1/uPAWLi+1nnn0PBMCbqo+ZEsRIlSAABJE4fVbRPg+AuBPDdlCex5
106QfKNi3vwp0Gy756SKTNZmIx42I9in0WeocCDliTEM2KsawCrVzuE3gwcHHkOnmLX
107DEc4bajkQxcaJITG3hsJ2Cm5OBMLPwrsq/77VzOdC12r9j8+w0f7lCJfOm2ui7rm
108Vl76V2Nits6U0ZrF1yzYtVQ1iWqCnOudPPf3jyc7KcSetGwozgoydkcqfUS9iMs9
1092OV3v17GX6+sd8zY8tA95d/Vj6yU/l03GI9V6X9LXHSTAgMBAAGjUzBRMB0GA1Ud
110DgQWBBQo2BKDxo4XI5FJDj9ZUuDst9ck7DAfBgNVHSMEGDAWgBQo2BKDxo4XI5FJ
111Dj9ZUuDst9ck7DAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAL
112LjJ5k5kNdOUXFL2XhKO8w25tpkjd71vD3vKvPIN0Q5BgVmu5Bg476/WPBnSMvTVU
113QYLQR5aGMLPdWuiSJnwO0BChKjOHaoCnP6D3cs2xP9hLBGoENaXMJRM4ZvFBRbES
114Q6iTfq4OBPh5yCDDrjlppjhSnqaZuksmFnPFHLB/km003w8fgCD3VhmC2UFscl2K
115nHaxK6uzIxisyE84ZDZYhjnPPib1wXGL8yu1dq0cbktE5+xJ2FHQkBJ6qaujkgV0
116jpuWE9zk3CImFRkzPEwTF+3s5eP2XTIyWbtJGvJMmO0kHFx2PqCiAkdFldPKfrRh
117M007Wf15dtkqyLNkzOxv
118-----END CERTIFICATE-----
119EOF
120
121 cat << EOF > "$key_file"
122-----BEGIN PRIVATE KEY-----
123MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCrS5/kYM3TjdFw
1244OYMdSOys0+4aHPgtXqePWrn1pBPW9D1yhjI/JS1/uPAWLi+1nnn0PBMCbqo+ZEs
125RIlSAABJE4fVbRPg+AuBPDdlCex5QfKNi3vwp0Gy756SKTNZmIx42I9in0WeocCD
126liTEM2KsawCrVzuE3gwcHHkOnmLXDEc4bajkQxcaJITG3hsJ2Cm5OBMLPwrsq/77
127VzOdC12r9j8+w0f7lCJfOm2ui7rmVl76V2Nits6U0ZrF1yzYtVQ1iWqCnOudPPf3
128jyc7KcSetGwozgoydkcqfUS9iMs92OV3v17GX6+sd8zY8tA95d/Vj6yU/l03GI9V
1296X9LXHSTAgMBAAECggEASKlTsfS+WrcV2OQNscse0XbuojLstK1GzkkPSDjkDkXM
130ZfbMfLVn/6uXwMfh1lH0dDlVNWwLGhKDWlvYREhr1pPKUuZqQEv31WJNvTZwcR9g
131XFqGwJayb8zlXurLNX5YWArFB/i394p1t1vBTNjfSnQ5XHUscjgeuu35DBJzqvSA
132mh1nDUBFIMC4ruPzD7OMI7rXBN02PbfTBpoL8MGoesW0S/BFQciMS07rELL2hFih
133zZPJE+E6h3GMoSPAzqx+ubSkhMbxb/xQQSw4gfp8zii2SMuq8Ith9xaGhdj1TuaX
134NqZahgSRe7bbgYyHWHXYbd7gQa4fxxoT7Qyh0cSKwQKBgQDZP0yYcFfNADFfnw62
135eWgNHnfPsOTYa/gAXdKgueUekT+linGvAUQtdXxnLoVMiLXSVxaJbW1rAP0avJt8
136EJiTdtTXkKqTqwtfbUP/bmxjYNExvGfIOpJbDsCX+kwpCoWzHupXeQlZn7UDEmKR
137l0DWUVzqNnhO0WWaM9J4MD4BjwKBgQDJ2elu8h7V/U/0dr2e4GG1/Xoa1nIcct8C
138rn0cG2GJ6UxN9Rr/brrLZuBewlhul9VjGtcmD7ZvEEsR4EUHUguvheAg90rpAqSE
139c6LOYdGAsUa21iuVLPKPMFwd4MhtrP2JcwHO+oqlUK4939TlZEtyiMWsMJGuugh1
140nrudZ9LSvQKBgBFG83R8Gr928HZGVAk3BotkjOq7irebfpGo5INbxVj0/DbSF9Bv
141LVjgKxCZpog7pxofSu+LAFSuM3LY5RSszTWNEchC/Q3ZYIIqUmoSAhS1Mm3eKfLG
142lbUgKzjq8vuglpl0L/bc7V1vUhn4cFZbzRA+UEFgK5k5Ffd5f5eHXqcJAoGBAJmA
143hVwg9sBHfnlrn3JmMwiCdkxYjrkBxoS0i2JHlFqbt7KFVn2wCI/McY6+fx/Dibxv
144WfSQ+Gzn2B8FDZmulEJsLfED/szKfLBZfBM1Imya5CsBHm24m9G2tibmnaWCa+EO
145O+7aa3uiqo9VXAMCzbmRN7plyTQ2N16zUvw2S4aFAoGARoPL2cJ+7HHcnc4SzKm4
146Su5nLwVPj+IJUwI5SRsRdnUKqo4gaX54p/u/TlA6fm7esRqPu5LK0oIyItVP7wmT
147nUCUFtnE53Rm2QT+BlYg7CewkaRiUHgQR31RDsQP8XtQouy0Si2jG53QLtBm+b7D
148zpqQAUELuiSK67vTd+D96ss=
149-----END PRIVATE KEY-----
150EOF
151
152 cert_data=$(base64 -w0 "$cert_file")
153 key_data=$(base64 -w0 "$key_file")
154
155 # Set client certificate and client key files
156 kubectl config set-credentials user1 --client-certificate="$cert_file" --client-key="$key_file"
157 expected="$cert_file"
158 actual=$(kubectl config view --raw -o jsonpath='{.users[?(@.name == "user1")].user.client-certificate}')
159 if [ "$expected" != "$actual" ]; then
160 kube::log::error "Client certificate did not match the expected value (expected=$expected, actual=$actual)"
161 exit 1
162 fi
163 expected="$key_file"
164 actual=$(kubectl config view --raw -o jsonpath='{.users[?(@.name == "user1")].user.client-key}')
165 if [ "$expected" != "$actual" ]; then
166 kube::log::error "Client key did not match the expected value (expected=$expected, actual=$actual)"
167 exit 1
168 fi
169
170 # Embed client certificate and client key from files
171 kubectl config set-credentials user2 --client-certificate="$cert_file" --client-key="$key_file" --embed-certs=true
172 expected="$cert_data"
173 actual=$(kubectl config view --raw -o jsonpath='{.users[?(@.name == "user2")].user.client-certificate-data}')
174 if [ "$expected" != "$actual" ]; then
175 kube::log::error "Client certificate data embedded from file did not match the expected value (expected=$expected, actual=$actual)"
176 exit 1
177 fi
178 expected="$key_data"
179 actual=$(kubectl config view --raw -o jsonpath='{.users[?(@.name == "user2")].user.client-key-data}')
180 if [ "$expected" != "$actual" ]; then
181 kube::log::error "Client key data embedded from file did not match the expected value (expected=$expected, actual=$actual)"
182 exit 1
183 fi
184
185 # Embed client certificate and client key using process substitution
186 kubectl config set-credentials user3 --client-certificate=<(cat "$cert_file") --client-key=<(cat "$key_file") --embed-certs=true
187 expected="$cert_data"
188 actual=$(kubectl config view --raw -o jsonpath='{.users[?(@.name == "user3")].user.client-certificate-data}')
189 if [ "$expected" != "$actual" ]; then
190 kube::log::error "Client certificate data embedded using process substitution did not match the expected value (expected=$expected, actual=$actual)"
191 exit 1
192 fi
193 expected="$key_data"
194 actual=$(kubectl config view --raw -o jsonpath='{.users[?(@.name == "user3")].user.client-key-data}')
195 if [ "$expected" != "$actual" ]; then
196 kube::log::error "Client key data embedded using process substitution did not match the expected value (expected=$expected, actual=$actual)"
197 exit 1
198 fi
199
200 set +o nounset
201 set +o errexit
202}
203
204run_client_config_tests() {
205 set -o nounset
206 set -o errexit
207
208 create_and_use_new_namespace
209 kube::log::status "Testing client config"
210
211 # Command
212 # Pre-condition: kubeconfig "missing" is not a file or directory
213 output_message=$(! kubectl get pod --context="" --kubeconfig=missing 2>&1)
214 kube::test::if_has_string "${output_message}" "missing: no such file or directory"
215
216 # Pre-condition: kubeconfig "missing" is not a file or directory
217 # Command
218 output_message=$(! kubectl get pod --user="" --kubeconfig=missing 2>&1)
219 # Post-condition: --user contains a valid / empty value, missing config file returns error
220 kube::test::if_has_string "${output_message}" "missing: no such file or directory"
221 # Command
222 output_message=$(! kubectl get pod --cluster="" --kubeconfig=missing 2>&1)
223 # Post-condition: --cluster contains a "valid" value, missing config file returns error
224 kube::test::if_has_string "${output_message}" "missing: no such file or directory"
225
226 # Pre-condition: context "missing-context" does not exist
227 # Command
228 output_message=$(! kubectl get pod --context="missing-context" 2>&1)
229 kube::test::if_has_string "${output_message}" 'context was not found for specified context: missing-context'
230 # Post-condition: invalid or missing context returns error
231
232 # Pre-condition: cluster "missing-cluster" does not exist
233 # Command
234 output_message=$(! kubectl get pod --cluster="missing-cluster" 2>&1)
235 kube::test::if_has_string "${output_message}" 'no server found for cluster "missing-cluster"'
236 # Post-condition: invalid or missing cluster returns error
237
238 # Pre-condition: user "missing-user" does not exist
239 # Command
240 output_message=$(! kubectl get pod --user="missing-user" 2>&1)
241 kube::test::if_has_string "${output_message}" 'auth info "missing-user" does not exist'
242 # Post-condition: invalid or missing user returns error
243
244 # test invalid config
245 kubectl config view | sed -E "s/apiVersion: .*/apiVersion: v-1/g" > "${TMPDIR:-/tmp}"/newconfig.yaml
246 output_message=$(! "${THIS_PLATFORM_BIN}/kubectl" get pods --context="" --user="" --kubeconfig="${TMPDIR:-/tmp}"/newconfig.yaml 2>&1)
247 kube::test::if_has_string "${output_message}" "error loading config file"
248
249 output_message=$(! kubectl get pod --kubeconfig=missing-config 2>&1)
250 kube::test::if_has_string "${output_message}" 'no such file or directory'
251
252 set +o nounset
253 set +o errexit
254}
255
256run_kubeconfig_impersonate_tests() {
257 set -o nounset
258 set -o errexit
259
260 kube::log::status "Testing config with impersonation"
261
262 # copy the existing kubeconfig over and add a new user entry for the admin user impersonating a different user.
263 kubectl config view --raw > "${TMPDIR:-/tmp}"/impersonateconfig.yaml
264 cat << EOF >> "${TMPDIR:-/tmp}"/impersonateconfig.yaml
265users:
266- name: admin-as-userb
267 user:
268 # token defined in hack/testdata/auth-tokens.csv
269 token: admin-token
270 # impersonated user
271 as: userb
272 as-uid: abc123
273 as-groups:
274 - group2
275 - group1
276 as-user-extra:
277 foo:
278 - bar
279 - baz
280- name: as-uid-without-as
281 user:
282 # token defined in hack/testdata/auth-tokens.csv
283 token: admin-token
284 # impersonated uid
285 as-uid: abc123
286EOF
287
288 kubectl create -f hack/testdata/csr.yml --kubeconfig "${TMPDIR:-/tmp}"/impersonateconfig.yaml --user admin-as-userb
289 kube::test::get_object_assert 'csr/foo' '{{.spec.username}}' 'userb'
290 kube::test::get_object_assert 'csr/foo' '{{.spec.uid}}' 'abc123'
291 kube::test::get_object_assert 'csr/foo' '{{range .spec.groups}}{{.}} {{end}}' 'group2 group1 system:authenticated '
292 kube::test::get_object_assert 'csr/foo' '{{len .spec.extra}}' '1'
293 kube::test::get_object_assert 'csr/foo' '{{range .spec.extra.foo}}{{.}} {{end}}' 'bar baz '
294 kubectl delete -f hack/testdata/csr.yml
295
296 output_message=$(! kubectl get pods --kubeconfig "${TMPDIR:-/tmp}"/impersonateconfig.yaml --user as-uid-without-as 2>&1)
297 kube::test::if_has_string "${output_message}" 'without impersonating a user'
298
299 set +o nounset
300 set +o errexit
301}
View as plain text