diff --git a/tests/integration/kubernetes/confidential_common.sh b/tests/integration/kubernetes/confidential_common.sh new file mode 100644 index 0000000000..4484e65beb --- /dev/null +++ b/tests/integration/kubernetes/confidential_common.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# Copyright 2022-2023 Advanced Micro Devices, Inc. +# Copyright 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +source "${BATS_TEST_DIRNAME}/tests_common.sh" + +function setup_unencrypted_confidential_pod() { + get_pod_config_dir + + export SSH_KEY_FILE="${pod_config_dir}/confidential/unencrypted/ssh/unencrypted" + + if [ -n "${PR_NUMBER}" ]; then + # Use correct address in pod yaml + sed -i "s/-nightly/-${PR_NUMBER}/" "${pod_config_dir}/pod-confidential-unencrypted.yaml" + fi + + # Set permissions on private key file + sudo chmod 600 "${SSH_KEY_FILE}" +} + +# This function relies on `KATA_HYPERVISOR` being an environment variable +# and returns the remote command to be executed to that specific hypervisor +# in order to identify whether the workload is running on a TEE environment +function get_remote_command_per_hypervisor() { + declare -A REMOTE_COMMAND_PER_HYPERVISOR + REMOTE_COMMAND_PER_HYPERVISOR[qemu-sev]="dmesg | grep \"Memory Encryption Features active:.*\(SEV$\|SEV \)\"" + + echo "${REMOTE_COMMAND_PER_HYPERVISOR[${KATA_HYPERVISOR}]}" +} diff --git a/tests/integration/kubernetes/k8s-confidential.bats b/tests/integration/kubernetes/k8s-confidential.bats new file mode 100644 index 0000000000..1a56fe34d1 --- /dev/null +++ b/tests/integration/kubernetes/k8s-confidential.bats @@ -0,0 +1,49 @@ +#!/usr/bin/env bats +# Copyright 2022-2023 Advanced Micro Devices, Inc. +# Copyright 2023 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +load "${BATS_TEST_DIRNAME}/../../common.bash" +load "${BATS_TEST_DIRNAME}/confidential_common.sh" +load "${BATS_TEST_DIRNAME}/tests_common.sh" + +setup() { + SUPPORTED_HYPERVISORS=("qemu-sev") + + # This check must be done with "${KATA_HYPERVISOR}" to avoid + # having substrings, like qemu, being matched with qemu-$something. + [[ " ${SUPPORTED_HYPERVISORS[*]} " =~ " ${KATA_HYPERVISOR} " ]] || skip "Test not supported for ${KATA_HYPERVISOR}." + + get_pod_config_dir + setup_unencrypted_confidential_pod +} + +@test "Test unencrypted confidential container launch success and verify that we are running in a secure enclave." { + # Start the service/deployment/pod + kubectl apply -f "${pod_config_dir}/pod-confidential-unencrypted.yaml" + + # Retrieve pod name, wait for it to come up, retrieve pod ip + pod_name=$(kubectl get pod -o wide | grep "confidential-unencrypted" | awk '{print $1;}') + + # Check pod creation + kubectl wait --for=condition=Ready --timeout=$timeout pod "${pod_name}" + + pod_ip=$(kubectl get pod -o wide | grep "confidential-unencrypted" | awk '{print $6;}') + + # Run the remote command + coco_enabled=$(ssh -i ${SSH_KEY_FILE} -o "StrictHostKeyChecking no" -o "PasswordAuthentication=no" root@${pod_ip} /bin/sh -c "$(get_remote_command_per_hypervisor)" || true) + + if [ -z "$coco_enabled" ]; then + >&2 echo -e "Confidential compute is expected but not enabled." + return 1 + fi +} + +teardown() { + [[ " ${SUPPORTED_HYPERVISORS[*]} " =~ " ${KATA_HYPERVISOR} " ]] || skip "Test not supported for ${KATA_HYPERVISOR}." + + kubectl describe "pod/${pod_name}" || true + kubectl delete -f "${pod_config_dir}/pod-confidential-unencrypted.yaml" || true +} diff --git a/tests/integration/kubernetes/run_kubernetes_tests.sh b/tests/integration/kubernetes/run_kubernetes_tests.sh index f8b635d220..3d963c6c3d 100644 --- a/tests/integration/kubernetes/run_kubernetes_tests.sh +++ b/tests/integration/kubernetes/run_kubernetes_tests.sh @@ -18,6 +18,7 @@ if [ -n "${K8S_TEST_UNION:-}" ]; then K8S_TEST_UNION=($K8S_TEST_UNION) else K8S_TEST_UNION=( \ + "k8s-confidential.bats" \ "k8s-attach-handlers.bats" \ "k8s-caps.bats" \ "k8s-configmap.bats" \ diff --git a/tests/integration/kubernetes/runtimeclass_workloads/pod-confidential-unencrypted.yaml b/tests/integration/kubernetes/runtimeclass_workloads/pod-confidential-unencrypted.yaml new file mode 100644 index 0000000000..591d86de87 --- /dev/null +++ b/tests/integration/kubernetes/runtimeclass_workloads/pod-confidential-unencrypted.yaml @@ -0,0 +1,33 @@ +# Copyright (c) 2023 Advanced Micro Devices, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# +kind: Service +apiVersion: v1 +metadata: + name: "confidential-unencrypted" +spec: + selector: + app: "confidential-unencrypted" + ports: + - port: 22 +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: "confidential-unencrypted" +spec: + selector: + matchLabels: + app: "confidential-unencrypted" + template: + metadata: + labels: + app: "confidential-unencrypted" + spec: + runtimeClassName: kata + containers: + - name: "confidential-unencrypted" + image: ghcr.io/kata-containers/test-images:unencrypted-nightly + imagePullPolicy: Always +