k8s.io/kubernetes@v1.29.3/test/cmd/kubeconfig.sh (about) 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 17 set -o errexit 18 set -o nounset 19 set -o pipefail 20 21 run_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 46 run_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 87 run_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----- 99 MIIDazCCAlOgAwIBAgIUdSrvuXs0Bft9Ao/AFnC7fNBqD+owDQYJKoZIhvcNAQEL 100 BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM 101 GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDA1MTExODMyNDJaFw0yMTA1 102 MTExODMyNDJaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw 103 HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB 104 AQUAA4IBDwAwggEKAoIBAQCrS5/kYM3TjdFw4OYMdSOys0+4aHPgtXqePWrn1pBP 105 W9D1yhjI/JS1/uPAWLi+1nnn0PBMCbqo+ZEsRIlSAABJE4fVbRPg+AuBPDdlCex5 106 QfKNi3vwp0Gy756SKTNZmIx42I9in0WeocCDliTEM2KsawCrVzuE3gwcHHkOnmLX 107 DEc4bajkQxcaJITG3hsJ2Cm5OBMLPwrsq/77VzOdC12r9j8+w0f7lCJfOm2ui7rm 108 Vl76V2Nits6U0ZrF1yzYtVQ1iWqCnOudPPf3jyc7KcSetGwozgoydkcqfUS9iMs9 109 2OV3v17GX6+sd8zY8tA95d/Vj6yU/l03GI9V6X9LXHSTAgMBAAGjUzBRMB0GA1Ud 110 DgQWBBQo2BKDxo4XI5FJDj9ZUuDst9ck7DAfBgNVHSMEGDAWgBQo2BKDxo4XI5FJ 111 Dj9ZUuDst9ck7DAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAL 112 LjJ5k5kNdOUXFL2XhKO8w25tpkjd71vD3vKvPIN0Q5BgVmu5Bg476/WPBnSMvTVU 113 QYLQR5aGMLPdWuiSJnwO0BChKjOHaoCnP6D3cs2xP9hLBGoENaXMJRM4ZvFBRbES 114 Q6iTfq4OBPh5yCDDrjlppjhSnqaZuksmFnPFHLB/km003w8fgCD3VhmC2UFscl2K 115 nHaxK6uzIxisyE84ZDZYhjnPPib1wXGL8yu1dq0cbktE5+xJ2FHQkBJ6qaujkgV0 116 jpuWE9zk3CImFRkzPEwTF+3s5eP2XTIyWbtJGvJMmO0kHFx2PqCiAkdFldPKfrRh 117 M007Wf15dtkqyLNkzOxv 118 -----END CERTIFICATE----- 119 EOF 120 121 cat << EOF > "$key_file" 122 -----BEGIN PRIVATE KEY----- 123 MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCrS5/kYM3TjdFw 124 4OYMdSOys0+4aHPgtXqePWrn1pBPW9D1yhjI/JS1/uPAWLi+1nnn0PBMCbqo+ZEs 125 RIlSAABJE4fVbRPg+AuBPDdlCex5QfKNi3vwp0Gy756SKTNZmIx42I9in0WeocCD 126 liTEM2KsawCrVzuE3gwcHHkOnmLXDEc4bajkQxcaJITG3hsJ2Cm5OBMLPwrsq/77 127 VzOdC12r9j8+w0f7lCJfOm2ui7rmVl76V2Nits6U0ZrF1yzYtVQ1iWqCnOudPPf3 128 jyc7KcSetGwozgoydkcqfUS9iMs92OV3v17GX6+sd8zY8tA95d/Vj6yU/l03GI9V 129 6X9LXHSTAgMBAAECggEASKlTsfS+WrcV2OQNscse0XbuojLstK1GzkkPSDjkDkXM 130 ZfbMfLVn/6uXwMfh1lH0dDlVNWwLGhKDWlvYREhr1pPKUuZqQEv31WJNvTZwcR9g 131 XFqGwJayb8zlXurLNX5YWArFB/i394p1t1vBTNjfSnQ5XHUscjgeuu35DBJzqvSA 132 mh1nDUBFIMC4ruPzD7OMI7rXBN02PbfTBpoL8MGoesW0S/BFQciMS07rELL2hFih 133 zZPJE+E6h3GMoSPAzqx+ubSkhMbxb/xQQSw4gfp8zii2SMuq8Ith9xaGhdj1TuaX 134 NqZahgSRe7bbgYyHWHXYbd7gQa4fxxoT7Qyh0cSKwQKBgQDZP0yYcFfNADFfnw62 135 eWgNHnfPsOTYa/gAXdKgueUekT+linGvAUQtdXxnLoVMiLXSVxaJbW1rAP0avJt8 136 EJiTdtTXkKqTqwtfbUP/bmxjYNExvGfIOpJbDsCX+kwpCoWzHupXeQlZn7UDEmKR 137 l0DWUVzqNnhO0WWaM9J4MD4BjwKBgQDJ2elu8h7V/U/0dr2e4GG1/Xoa1nIcct8C 138 rn0cG2GJ6UxN9Rr/brrLZuBewlhul9VjGtcmD7ZvEEsR4EUHUguvheAg90rpAqSE 139 c6LOYdGAsUa21iuVLPKPMFwd4MhtrP2JcwHO+oqlUK4939TlZEtyiMWsMJGuugh1 140 nrudZ9LSvQKBgBFG83R8Gr928HZGVAk3BotkjOq7irebfpGo5INbxVj0/DbSF9Bv 141 LVjgKxCZpog7pxofSu+LAFSuM3LY5RSszTWNEchC/Q3ZYIIqUmoSAhS1Mm3eKfLG 142 lbUgKzjq8vuglpl0L/bc7V1vUhn4cFZbzRA+UEFgK5k5Ffd5f5eHXqcJAoGBAJmA 143 hVwg9sBHfnlrn3JmMwiCdkxYjrkBxoS0i2JHlFqbt7KFVn2wCI/McY6+fx/Dibxv 144 WfSQ+Gzn2B8FDZmulEJsLfED/szKfLBZfBM1Imya5CsBHm24m9G2tibmnaWCa+EO 145 O+7aa3uiqo9VXAMCzbmRN7plyTQ2N16zUvw2S4aFAoGARoPL2cJ+7HHcnc4SzKm4 146 Su5nLwVPj+IJUwI5SRsRdnUKqo4gaX54p/u/TlA6fm7esRqPu5LK0oIyItVP7wmT 147 nUCUFtnE53Rm2QT+BlYg7CewkaRiUHgQR31RDsQP8XtQouy0Si2jG53QLtBm+b7D 148 zpqQAUELuiSK67vTd+D96ss= 149 -----END PRIVATE KEY----- 150 EOF 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 204 run_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=$(! "${KUBE_OUTPUT_HOSTBIN}/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 256 run_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 265 users: 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 286 EOF 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 }