#!/usr/bin/env bash # Copyright 2016 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # This contains util code for testing kubectl. set -o errexit set -o nounset set -o pipefail # Set locale to ensure english responses from kubectl commands export LANG=C KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/../.. # Expects the following has already been done by whatever sources this script # source "${KUBE_ROOT}/hack/lib/init.sh" # source "${KUBE_ROOT}/hack/lib/test.sh" source "${KUBE_ROOT}/test/cmd/apply.sh" source "${KUBE_ROOT}/test/cmd/apps.sh" source "${KUBE_ROOT}/test/cmd/auth_whoami.sh" source "${KUBE_ROOT}/test/cmd/authentication.sh" source "${KUBE_ROOT}/test/cmd/authorization.sh" source "${KUBE_ROOT}/test/cmd/batch.sh" source "${KUBE_ROOT}/test/cmd/certificate.sh" source "${KUBE_ROOT}/test/cmd/convert.sh" source "${KUBE_ROOT}/test/cmd/core.sh" source "${KUBE_ROOT}/test/cmd/crd.sh" source "${KUBE_ROOT}/test/cmd/create.sh" source "${KUBE_ROOT}/test/cmd/debug.sh" source "${KUBE_ROOT}/test/cmd/delete.sh" source "${KUBE_ROOT}/test/cmd/diff.sh" source "${KUBE_ROOT}/test/cmd/discovery.sh" source "${KUBE_ROOT}/test/cmd/events.sh" source "${KUBE_ROOT}/test/cmd/exec.sh" source "${KUBE_ROOT}/test/cmd/generic-resources.sh" source "${KUBE_ROOT}/test/cmd/get.sh" source "${KUBE_ROOT}/test/cmd/help.sh" source "${KUBE_ROOT}/test/cmd/kubeconfig.sh" source "${KUBE_ROOT}/test/cmd/node-management.sh" source "${KUBE_ROOT}/test/cmd/plugins.sh" source "${KUBE_ROOT}/test/cmd/proxy.sh" source "${KUBE_ROOT}/test/cmd/rbac.sh" source "${KUBE_ROOT}/test/cmd/request-timeout.sh" source "${KUBE_ROOT}/test/cmd/results.sh" source "${KUBE_ROOT}/test/cmd/run.sh" source "${KUBE_ROOT}/test/cmd/save-config.sh" source "${KUBE_ROOT}/test/cmd/storage.sh" source "${KUBE_ROOT}/test/cmd/template-output.sh" source "${KUBE_ROOT}/test/cmd/version.sh" source "${KUBE_ROOT}/test/cmd/wait.sh" ETCD_HOST=${ETCD_HOST:-127.0.0.1} ETCD_PORT=${ETCD_PORT:-2379} SECURE_API_PORT=${SECURE_API_PORT:-6443} API_HOST=${API_HOST:-127.0.0.1} KUBELET_HEALTHZ_PORT=${KUBELET_HEALTHZ_PORT:-10248} SECURE_CTLRMGR_PORT=${SECURE_CTLRMGR_PORT:-10257} PROXY_HOST=127.0.0.1 # kubectl only serves on localhost. IMAGE_NGINX="registry.k8s.io/nginx:1.7.9" export IMAGE_DEPLOYMENT_R1="registry.k8s.io/nginx:test-cmd" # deployment-revision1.yaml export IMAGE_DEPLOYMENT_R2="$IMAGE_NGINX" # deployment-revision2.yaml export IMAGE_PERL="registry.k8s.io/perl" export IMAGE_PAUSE_V2="registry.k8s.io/pause:2.0" export IMAGE_DAEMONSET_R2="registry.k8s.io/pause:latest" export IMAGE_DAEMONSET_R2_2="registry.k8s.io/nginx:test-cmd" # rollingupdate-daemonset-rv2.yaml export IMAGE_STATEFULSET_R1="registry.k8s.io/nginx-slim:0.7" export IMAGE_STATEFULSET_R2="registry.k8s.io/nginx-slim:0.8" # Expose kubectl directly for readability PATH="${THIS_PLATFORM_BIN}":$PATH # Define variables for resource types to prevent typos. clusterroles="clusterroles" configmaps="configmaps" csr="csr" cronjob="cronjobs" deployments="deployments" namespaces="namespaces" nodes="nodes" persistentvolumeclaims="persistentvolumeclaims" persistentvolumes="persistentvolumes" pods="pods" podtemplates="podtemplates" replicasets="replicasets" replicationcontrollers="replicationcontrollers" roles="roles" secrets="secrets" selfsubjectreviews="selfsubjectreviews" serviceaccounts="serviceaccounts" services="services" statefulsets="statefulsets" storageclass="storageclass" subjectaccessreviews="subjectaccessreviews" customresourcedefinitions="customresourcedefinitions" daemonsets="daemonsets" controllerrevisions="controllerrevisions" job="jobs" # A junit-style XML test report will be generated in the directory specified by KUBE_JUNIT_REPORT_DIR, if set. # If KUBE_JUNIT_REPORT_DIR is unset, and ARTIFACTS is set, then use what is set in ARTIFACTS. if [[ -z "${KUBE_JUNIT_REPORT_DIR:-}" && -n "${ARTIFACTS:-}" ]]; then export KUBE_JUNIT_REPORT_DIR="${ARTIFACTS}" fi # include shell2junit library sh2ju="${KUBE_ROOT}/third_party/forked/shell2junit/sh2ju.sh" if [[ -f "${sh2ju}" ]]; then source "${sh2ju}" else echo "failed to find third_party/forked/shell2junit/sh2ju.sh" exit 1 fi # record_command runs the command and records its output/error messages in junit format # it expects the first to be the name of the command # Example: # record_command run_kubectl_tests # # WARNING: Variable changes in the command will NOT be effective after record_command returns. # This is because the command runs in subshell. function record_command() { set +o nounset set +o errexit local name="$1" local output="${KUBE_JUNIT_REPORT_DIR:-/tmp/junit-results}" echo "Recording: ${name}" echo "Running command: $*" juLog -output="${output}" -class="test-cmd" -name="${name}" "$@" local exitCode=$? if [[ ${exitCode} -ne 0 ]]; then # Record failures for any non-canary commands if [ "${name}" != "record_command_canary" ]; then echo "Error when running ${name}" foundError="${foundError}""${name}"", " fi elif [ "${name}" == "record_command_canary" ]; then # If the canary command passed, fail echo "record_command_canary succeeded unexpectedly" foundError="${foundError}""${name}"", " fi set -o nounset set -o errexit } # Ensure our record_command stack correctly propagates and detects errexit failures in invoked commands - see https://issue.k8s.io/84871 foundError="" function record_command_canary() { set -o nounset set -o errexit bogus-expected-to-fail set +o nounset set +o errexit } KUBE_JUNIT_REPORT_DIR=$(mktemp -d /tmp/record_command_canary.XXXXX) record_command record_command_canary if [[ -n "${foundError}" ]]; then echo "FAILED TESTS: record_command_canary" exit 1 fi # Stops the running kubectl proxy, if there is one. function stop-proxy() { [[ -n "${PROXY_PORT-}" ]] && kube::log::status "Stopping proxy on port ${PROXY_PORT}" [[ -n "${PROXY_PID-}" ]] && kill -9 "${PROXY_PID}" 1>&2 2>/dev/null [[ -n "${PROXY_PORT_FILE-}" ]] && rm -f "${PROXY_PORT_FILE}" PROXY_PID= PROXY_PORT= PROXY_PORT_FILE= } # Starts "kubect proxy" to test the client proxy. $1: api_prefix function start-proxy() { stop-proxy PROXY_PORT_FILE=$(mktemp proxy-port.out.XXXXX) kube::log::status "Starting kubectl proxy on random port; output file in ${PROXY_PORT_FILE}; args: ${1-}" if [ $# -eq 0 ]; then kubectl proxy --port=0 --www=. 1>"${PROXY_PORT_FILE}" 2>&1 & else kubectl proxy --port=0 --www=. --api-prefix="$1" 1>"${PROXY_PORT_FILE}" 2>&1 & fi PROXY_PID=$! PROXY_PORT= local attempts=0 while [[ -z ${PROXY_PORT} ]]; do if (( attempts > 9 )); then kill "${PROXY_PID}" kube::log::error_exit "Couldn't start proxy. Failed to read port after ${attempts} tries. Got: $(cat "${PROXY_PORT_FILE}")" fi sleep .5 kube::log::status "Attempt ${attempts} to read ${PROXY_PORT_FILE}..." PROXY_PORT=$(sed 's/.*Starting to serve on 127.0.0.1:\([0-9]*\)$/\1/'< "${PROXY_PORT_FILE}") attempts=$((attempts+1)) done kube::log::status "kubectl proxy running on port ${PROXY_PORT}" # We try checking kubectl proxy 30 times with 1s delays to avoid occasional # failures. if [ $# -eq 0 ]; then kube::util::wait_for_url "http://127.0.0.1:${PROXY_PORT}/healthz" "kubectl proxy" else kube::util::wait_for_url "http://127.0.0.1:${PROXY_PORT}/$1/healthz" "kubectl proxy --api-prefix=$1" fi } function cleanup() { stop-proxy [[ -n "${CTLRMGR_PID-}" ]] && kill -9 "${CTLRMGR_PID}" 1>&2 2>/dev/null [[ -n "${KUBELET_PID-}" ]] && kill -9 "${KUBELET_PID}" 1>&2 2>/dev/null [[ -n "${APISERVER_PID-}" ]] && kill -9 "${APISERVER_PID}" 1>&2 2>/dev/null kube::etcd::cleanup rm -rf "${KUBE_TEMP}" local junit_dir="${KUBE_JUNIT_REPORT_DIR:-/tmp/junit-results}" echo "junit report dir:" "${junit_dir}" kube::log::status "Clean up complete" } # Executes curl against the proxy. $1 is the path to use, $2 is the desired # return code. Prints a helpful message on failure. function check-curl-proxy-code() { local status local -r address=$1 local -r desired=$2 local -r full_address="${PROXY_HOST}:${PROXY_PORT}${address}" status=$(curl -w "%{http_code}" --silent --output /dev/null "${full_address}") if [ "${status}" == "${desired}" ]; then return 0 fi echo "For address ${full_address}, got ${status} but wanted ${desired}" return 1 } # TODO: Remove this function when we do the retry inside the kubectl commands. See #15333. function kubectl-with-retry() { ERROR_FILE="${KUBE_TEMP}/kubectl-error" preserve_err_file=${PRESERVE_ERR_FILE:-false} for count in {0..3}; do kubectl "$@" 2> "${ERROR_FILE}" || true if grep -q "the object has been modified" "${ERROR_FILE}"; then kube::log::status "retry $1, error: $(cat "${ERROR_FILE}")" rm "${ERROR_FILE}" sleep $((2**count)) else if [ "$preserve_err_file" != true ] ; then rm "${ERROR_FILE}" fi break fi done } # Waits for the pods with the given label to match the list of names. Don't call # this function unless you know the exact pod names, or expect no pods. # $1: label to match # $2: list of pod names sorted by name # Example invocation: # wait-for-pods-with-label "app=foo" "nginx-0nginx-1" function wait-for-pods-with-label() { local i for i in $(seq 1 10); do kubeout=$(kubectl get po -l "$1" --output=go-template --template='{{range.items}}{{.metadata.name}}{{end}}' --sort-by metadata.name "${kube_flags[@]}") if [[ $kubeout = "$2" ]]; then return fi echo Waiting for pods: "$2", found "$kubeout" sleep "$i" done kube::log::error_exit "Timeout waiting for pods with label $1" } # Code to be run before running the tests. setup() { kube::util::trap_add cleanup EXIT SIGINT kube::util::ensure-temp-dir # ensure ~/.kube/config isn't loaded by tests HOME="${KUBE_TEMP}" kube::etcd::start # Find a standard sed instance for use with edit scripts kube::util::ensure-gnu-sed kube::log::status "Building kubectl" make -C "${KUBE_ROOT}" WHAT="cmd/kubectl cmd/kubectl-convert" # Check kubectl kube::log::status "Running kubectl with no options" "${THIS_PLATFORM_BIN}/kubectl" # TODO: we need to note down the current default namespace and set back to this # namespace after the tests are done. CONTEXT="test" kubectl config set-credentials test-admin --token admin-token kubectl config set-cluster local --insecure-skip-tls-verify --server "https://127.0.0.1:${SECURE_API_PORT}" kubectl config set-context "${CONTEXT}" --user test-admin --cluster local kubectl config use-context "${CONTEXT}" kubectl config view kube::log::status "Setup complete" } # Generate a random namespace name, based on the current time (to make # debugging slightly easier) and a random number. Don't use `date +%N` # because that doesn't work on OSX. create_and_use_new_namespace() { local ns_name ns_name="namespace-$(date +%s)-${RANDOM}" kube::log::status "Creating namespace ${ns_name}" kubectl create namespace "${ns_name}" kubectl config set-context "${CONTEXT}" --namespace="${ns_name}" } # Runs all kubectl tests. # Requires an env var SUPPORTED_RESOURCES which is a comma separated list of # resources for which tests should be run. runTests() { foundError="" if [ -z "${SUPPORTED_RESOURCES:-}" ]; then echo "Need to set SUPPORTED_RESOURCES env var. It is a list of resources that are supported and hence should be tested. Set it to (*) to test all resources" exit 1 fi kube::log::status "Checking kubectl version" kubectl version kube_flags=( '-s' "https://127.0.0.1:${SECURE_API_PORT}" '--insecure-skip-tls-verify' ) kube_flags_without_token=( "${kube_flags[@]}" ) # token defined in hack/testdata/auth-tokens.csv kube_flags_with_token=( "${kube_flags_without_token[@]}" '--token=admin-token' ) if [[ -z "${ALLOW_SKEW:-}" ]]; then kube_flags+=('--match-server-version') kube_flags_with_token+=('--match-server-version') fi if kube::test::if_supports_resource "${nodes}" ; then [ "$(kubectl get nodes -o go-template='{{ .apiVersion }}' "${kube_flags[@]}")" == "v1" ] fi # Define helper variables for fields to prevent typos. # They will be used in some other files under test/cmd, # Let's export them as https://github.com/koalaman/shellcheck/wiki/SC2034 suggested. export id_field=".metadata.name" export labels_field=".metadata.labels" export annotations_field=".metadata.annotations" export service_selector_field=".spec.selector" export rc_replicas_field=".spec.replicas" export rc_status_replicas_field=".status.replicas" export rc_container_image_field=".spec.template.spec.containers" export rs_replicas_field=".spec.replicas" export port_field="(index .spec.ports 0).port" export port_name="(index .spec.ports 0).name" export second_port_field="(index .spec.ports 1).port" export second_port_name="(index .spec.ports 1).name" export image_field="(index .spec.containers 0).image" export pod_container_name_field="(index .spec.containers 0).name" export container_name_field="(index .spec.template.spec.containers 0).name" export hpa_min_field=".spec.minReplicas" export hpa_max_field=".spec.maxReplicas" export hpa_cpu_field="(index .spec.metrics 0).resource.target.averageUtilization" export template_labels=".spec.template.metadata.labels.name" export statefulset_replicas_field=".spec.replicas" export statefulset_observed_generation=".status.observedGeneration" export job_parallelism_field=".spec.parallelism" export deployment_replicas=".spec.replicas" export secret_data=".data" export secret_type=".type" export change_cause_annotation='.*kubernetes.io/change-cause.*' export pdb_min_available=".spec.minAvailable" export pdb_max_unavailable=".spec.maxUnavailable" export generation_field=".metadata.generation" export container_len="(len .spec.template.spec.containers)" export image_field0="(index .spec.template.spec.containers 0).image" export image_field1="(index .spec.template.spec.containers 1).image" # Make sure "default" namespace exists. if kube::test::if_supports_resource "${namespaces}" ; then output_message=$(kubectl get "${kube_flags[@]}" namespaces) if ! grep -q "default" <<< "${output_message}"; then # Create default namespace kubectl create "${kube_flags[@]}" ns default fi fi # Make sure "kubernetes" service exists. if kube::test::if_supports_resource "${services}" ; then # Attempt to create the kubernetes service, tolerating failure (since it might already exist) kubectl create "${kube_flags[@]}" -f hack/testdata/kubernetes-service.yaml || true # Require the service to exist (either we created it or the API server did) kubectl get "${kube_flags[@]}" -f hack/testdata/kubernetes-service.yaml fi cleanup_tests(){ kube::test::clear_all if [[ -n "${foundError}" ]]; then echo "FAILED TESTS: ""${foundError}" exit 1 fi } if [[ -n "${WHAT-}" ]]; then for pkg in ${WHAT} do # running of kubeadm is captured in hack/make-targets/test-cmd.sh if [[ "${pkg}" != "kubeadm" ]]; then record_command "run_${pkg}_tests" fi done cleanup_tests return fi ######################### # Kubectl version # ######################### record_command run_kubectl_version_tests ############################ # Kubectl result reporting # ############################ record_command run_kubectl_results_tests ####################### # kubectl config set # ####################### record_command run_kubectl_config_set_tests ############################## # kubectl config set-cluster # ############################## record_command run_kubectl_config_set_cluster_tests ################################## # kubectl config set-credentials # ################################## record_command run_kubectl_config_set_credentials_tests ####################### # kubectl local proxy # ####################### record_command run_kubectl_local_proxy_tests ######################### # RESTMapper evaluation # ######################### record_command run_RESTMapper_evaluation_tests # find all resources kubectl "${kube_flags[@]}" api-resources # find all namespaced resources that support list by name and get them kubectl "${kube_flags[@]}" api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl "${kube_flags[@]}" get -o name ################ # Cluster Role # ################ if kube::test::if_supports_resource "${clusterroles}" ; then record_command run_clusterroles_tests fi ######## # Role # ######## if kube::test::if_supports_resource "${roles}" ; then record_command run_role_tests fi ######################### # Assert short name # ######################### if kube::test::if_supports_resource "${customresourcedefinitions}" && kube::test::if_supports_resource "${pods}" && kube::test::if_supports_resource "${configmaps}" ; then record_command run_assert_short_name_tests fi ######################### # Assert singular name # ######################### if kube::test::if_supports_resource "${customresourcedefinitions}" && kube::test::if_supports_resource "${pods}" ; then record_command run_assert_singular_name_tests fi ######################### # Ambiguous short name # ######################### if kube::test::if_supports_resource "${customresourcedefinitions}" ; then record_command run_ambiguous_shortname_tests fi ######################### # Assert categories # ######################### ## test if a category is exported during discovery if kube::test::if_supports_resource "${pods}" ; then record_command run_assert_categories_tests fi ########################### # POD creation / deletion # ########################### if kube::test::if_supports_resource "${pods}" ; then record_command run_pod_tests fi if kube::test::if_supports_resource "${pods}" ; then record_command run_save_config_tests fi if kube::test::if_supports_resource "${pods}" ; then record_command run_kubectl_create_error_tests fi if kube::test::if_supports_resource "${pods}" ; then record_command run_kubectl_apply_tests record_command run_kubectl_server_side_apply_tests record_command run_kubectl_run_tests record_command run_kubectl_create_filter_tests fi if kube::test::if_supports_resource "${deployments}" ; then record_command run_kubectl_apply_deployments_tests fi ################ # Kubectl diff # ################ record_command run_kubectl_diff_tests record_command run_kubectl_diff_same_names ############### # Kubectl get # ############### if kube::test::if_supports_resource "${pods}" ; then record_command run_kubectl_get_tests fi ################ # Kubectl help # ################ record_command run_kubectl_help_tests ################## # Kubectl events # ################## if kube::test::if_supports_resource "${cronjob}" ; then record_command run_kubectl_events_tests fi ################ # Kubectl exec # ################ if kube::test::if_supports_resource "${pods}"; then record_command run_kubectl_exec_pod_tests if kube::test::if_supports_resource "${replicasets}" && kube::test::if_supports_resource "${configmaps}"; then record_command run_kubectl_exec_resource_name_tests fi fi ###################### # Create # ###################### if kube::test::if_supports_resource "${secrets}" ; then record_command run_create_secret_tests fi if kube::test::if_supports_resource "${deployments}"; then record_command run_kubectl_create_kustomization_directory_tests record_command run_kubectl_create_validate_tests fi ###################### # Convert # ###################### if kube::test::if_supports_resource "${deployments}"; then record_command run_convert_tests fi ###################### # Delete # ###################### if kube::test::if_supports_resource "${configmaps}" ; then record_command run_kubectl_delete_allnamespaces_tests fi ###################### # Delete --interactive # ###################### if kube::test::if_supports_resource "${configmaps}" ; then record_command run_kubectl_delete_interactive_tests fi ################## # Global timeout # ################## if kube::test::if_supports_resource "${pods}" ; then record_command run_kubectl_request_timeout_tests fi ##################################### # CustomResourceDefinitions # ##################################### # customresourcedefinitions cleanup after themselves. if kube::test::if_supports_resource "${customresourcedefinitions}" ; then record_command run_crd_tests fi ##################################### # Recursive Resources via directory # ##################################### if kube::test::if_supports_resource "${pods}" ; then record_command run_recursive_resources_tests fi ############## # Namespaces # ############## if kube::test::if_supports_resource "${namespaces}" ; then record_command run_namespace_tests fi ########### # Secrets # ########### if kube::test::if_supports_resource "${namespaces}" ; then if kube::test::if_supports_resource "${secrets}" ; then record_command run_secrets_test fi fi ###################### # ConfigMap # ###################### if kube::test::if_supports_resource "${namespaces}"; then if kube::test::if_supports_resource "${configmaps}" ; then record_command run_configmap_tests fi fi #################### # Client Config # #################### record_command run_client_config_tests #################### # Service Accounts # #################### if kube::test::if_supports_resource "${namespaces}" && kube::test::if_supports_resource "${serviceaccounts}" ; then record_command run_service_accounts_tests fi #################### # Job # #################### if kube::test::if_supports_resource "${job}" ; then record_command run_job_tests record_command run_create_job_tests fi ################# # Pod templates # ################# if kube::test::if_supports_resource "${podtemplates}" ; then record_command run_pod_templates_tests fi ############ # Services # ############ if kube::test::if_supports_resource "${services}" ; then record_command run_service_tests fi ################## # DaemonSets # ################## if kube::test::if_supports_resource "${daemonsets}" ; then record_command run_daemonset_tests if kube::test::if_supports_resource "${controllerrevisions}"; then record_command run_daemonset_history_tests fi fi ########################### # Replication controllers # ########################### if kube::test::if_supports_resource "${namespaces}" ; then if kube::test::if_supports_resource "${replicationcontrollers}" ; then record_command run_rc_tests fi fi ###################### # Deployments # ###################### if kube::test::if_supports_resource "${deployments}" ; then record_command run_deployment_tests fi ###################### # Replica Sets # ###################### if kube::test::if_supports_resource "${replicasets}" ; then record_command run_rs_tests fi ################# # Stateful Sets # ################# if kube::test::if_supports_resource "${statefulsets}" ; then record_command run_stateful_set_tests if kube::test::if_supports_resource "${controllerrevisions}"; then record_command run_statefulset_history_tests fi fi ###################### # Lists # ###################### if kube::test::if_supports_resource "${services}" ; then if kube::test::if_supports_resource "${deployments}" ; then record_command run_lists_tests fi fi ###################### # Multiple Resources # ###################### if kube::test::if_supports_resource "${services}" ; then if kube::test::if_supports_resource "${replicationcontrollers}" ; then record_command run_multi_resources_tests fi fi ###################### # Persistent Volumes # ###################### if kube::test::if_supports_resource "${persistentvolumes}" ; then record_command run_persistent_volumes_tests fi ############################ # Persistent Volume Claims # ############################ if kube::test::if_supports_resource "${persistentvolumeclaims}" ; then record_command run_persistent_volume_claims_tests fi ############################ # Storage Classes # ############################ if kube::test::if_supports_resource "${storageclass}" ; then record_command run_storage_class_tests fi ######### # Nodes # ######### if kube::test::if_supports_resource "${nodes}" ; then record_command run_nodes_tests fi ######################## # Authentication ######################## record_command run_exec_credentials_tests record_command run_exec_credentials_interactive_tests if kube::test::if_supports_resource "${selfsubjectreviews}" ; then record_command run_kubectl_auth_whoami_tests fi ######################## # authorization.k8s.io # ######################## if kube::test::if_supports_resource "${subjectaccessreviews}" ; then record_command run_authorization_tests fi # kubectl auth can-i # kube-apiserver is started with authorization mode AlwaysAllow, so kubectl can-i always returns yes if kube::test::if_supports_resource "${subjectaccessreviews}" ; then output_message=$(kubectl auth can-i '*' '*' 2>&1 "${kube_flags[@]}") kube::test::if_has_string "${output_message}" "yes" output_message=$(kubectl auth can-i get pods --subresource=log 2>&1 "${kube_flags[@]}") kube::test::if_has_string "${output_message}" "yes" output_message=$(kubectl auth can-i get invalid_resource 2>&1 "${kube_flags[@]}") kube::test::if_has_string "${output_message}" "the server doesn't have a resource type" output_message=$(kubectl auth can-i get /logs/ 2>&1 "${kube_flags[@]}") kube::test::if_has_string "${output_message}" "yes" output_message=$(! kubectl auth can-i get /logs/ --subresource=log 2>&1 "${kube_flags[@]}") kube::test::if_has_string "${output_message}" "subresource can not be used with NonResourceURL" output_message=$(kubectl auth can-i list jobs.batch/bar -n foo --quiet 2>&1 "${kube_flags[@]}") kube::test::if_empty_string "${output_message}" output_message=$(kubectl auth can-i get pods --subresource=log 2>&1 "${kube_flags[@]}"; echo $?) kube::test::if_has_string "${output_message}" '0' output_message=$(kubectl auth can-i get pods --subresource=log --quiet 2>&1 "${kube_flags[@]}"; echo $?) kube::test::if_has_string "${output_message}" '0' # kubectl auth can-i get '*' does not warn about namespaced scope or print an error output_message=$(kubectl auth can-i get '*' 2>&1 "${kube_flags[@]}") kube::test::if_has_not_string "${output_message}" "Warning" # kubectl auth can-i get foo does not print a namespaced warning message, and only prints a single lookup error output_message=$(kubectl auth can-i get foo 2>&1 "${kube_flags[@]}") kube::test::if_has_string "${output_message}" "Warning: the server doesn't have a resource type 'foo'" kube::test::if_has_not_string "${output_message}" "Warning: resource 'foo' is not namespace scoped" # kubectl auth can-i get pods does not print a namespaced warning message or a lookup error output_message=$(kubectl auth can-i get pods 2>&1 "${kube_flags[@]}") kube::test::if_has_not_string "${output_message}" "Warning" # kubectl auth can-i get nodes prints a namespaced warning message output_message=$(kubectl auth can-i get nodes 2>&1 "${kube_flags[@]}") kube::test::if_has_string "${output_message}" "Warning: resource 'nodes' is not namespace scoped" # kubectl auth can-i get nodes --all-namespaces does not print a namespaced warning message output_message=$(kubectl auth can-i get nodes --all-namespaces 2>&1 "${kube_flags[@]}") kube::test::if_has_not_string "${output_message}" "Warning: resource 'nodes' is not namespace scoped" fi # kubectl auth reconcile if kube::test::if_supports_resource "${clusterroles}" ; then # dry-run command kubectl auth reconcile --dry-run=client "${kube_flags[@]}" -f test/fixtures/pkg/kubectl/cmd/auth/rbac-resource-plus.yaml kube::test::get_object_assert 'rolebindings -n some-other-random -l test-cmd=auth' "{{range.items}}{{$id_field}}:{{end}}" '' kube::test::get_object_assert 'roles -n some-other-random -l test-cmd=auth' "{{range.items}}{{$id_field}}:{{end}}" '' kube::test::get_object_assert 'clusterrolebindings -l test-cmd=auth' "{{range.items}}{{$id_field}}:{{end}}" '' kube::test::get_object_assert 'clusterroles -l test-cmd=auth' "{{range.items}}{{$id_field}}:{{end}}" '' # command kubectl auth reconcile "${kube_flags[@]}" -f test/fixtures/pkg/kubectl/cmd/auth/rbac-resource-plus.yaml kube::test::get_object_assert 'rolebindings -n some-other-random -l test-cmd=auth' "{{range.items}}{{$id_field}}:{{end}}" 'testing-RB:' kube::test::get_object_assert 'roles -n some-other-random -l test-cmd=auth' "{{range.items}}{{$id_field}}:{{end}}" 'testing-R:' kube::test::get_object_assert 'clusterrolebindings -l test-cmd=auth' "{{range.items}}{{$id_field}}:{{end}}" 'testing-CRB:' kube::test::get_object_assert 'clusterroles -l test-cmd=auth' "{{range.items}}{{$id_field}}:{{end}}" 'testing-CR:' failure_message=$(! kubectl auth reconcile "${kube_flags[@]}" -f test/fixtures/pkg/kubectl/cmd/auth/rbac-v1beta1.yaml 2>&1 ) kube::test::if_has_string "${failure_message}" 'only rbac.authorization.k8s.io/v1 is supported' kubectl delete "${kube_flags[@]}" rolebindings,role,clusterroles,clusterrolebindings -n some-other-random -l test-cmd=auth fi ##################### # Retrieve multiple # ##################### if kube::test::if_supports_resource "${nodes}" ; then if kube::test::if_supports_resource "${services}" ; then record_command run_retrieve_multiple_tests fi fi ##################### # Resource aliasing # ##################### if kube::test::if_supports_resource "${services}" ; then if kube::test::if_supports_resource "${replicationcontrollers}" ; then record_command run_resource_aliasing_tests fi fi ########### # Explain # ########### if kube::test::if_supports_resource "${pods}" ; then record_command run_kubectl_explain_tests fi ############################## # CRD Deletion / Re-creation # ############################## if kube::test::if_supports_resource "${namespaces}" ; then record_command run_crd_deletion_recreation_tests fi ########### # Swagger # ########### record_command run_swagger_tests ##################### # Kubectl --sort-by # ##################### if kube::test::if_supports_resource "${pods}" ; then record_command run_kubectl_sort_by_tests fi ############################ # Kubectl --all-namespaces # ############################ if kube::test::if_supports_resource "${pods}" ; then if kube::test::if_supports_resource "${nodes}" ; then record_command run_kubectl_all_namespace_tests fi fi ############################ # Kubectl deprecated APIs # ############################ if kube::test::if_supports_resource "${customresourcedefinitions}" ; then record_command run_deprecated_api_tests fi ###################### # kubectl --template # ###################### if kube::test::if_supports_resource "${pods}" ; then record_command run_template_output_tests fi ################ # Certificates # ################ if kube::test::if_supports_resource "${csr}" ; then record_command run_certificates_tests fi ###################### # Cluster Management # ###################### if kube::test::if_supports_resource "${nodes}" ; then record_command run_cluster_management_tests fi ########### # Plugins # ########### record_command run_plugins_tests ################# # Impersonation # ################# record_command run_impersonation_tests #################### # kubectl wait # #################### record_command run_wait_tests #################### # kubectl debug # #################### if kube::test::if_supports_resource "${pods}" ; then record_command run_kubectl_debug_pod_tests record_command run_kubectl_debug_general_tests record_command run_kubectl_debug_baseline_tests record_command run_kubectl_debug_restricted_tests record_command run_kubectl_debug_netadmin_tests fi if kube::test::if_supports_resource "${nodes}" ; then record_command run_kubectl_debug_node_tests record_command run_kubectl_debug_general_node_tests record_command run_kubectl_debug_baseline_node_tests record_command run_kubectl_debug_restricted_node_tests record_command run_kubectl_debug_netadmin_node_tests fi cleanup_tests }