diff --git a/tests/e2e/config/config.go b/tests/e2e/config/config.go index c6591c99f4..cd4e5bedf5 100644 --- a/tests/e2e/config/config.go +++ b/tests/e2e/config/config.go @@ -161,6 +161,7 @@ type TestData struct { SSHUser string `yaml:"sshUser"` IPAM string `yaml:"ipam"` VMVpc string `yaml:"vmVpc"` + VMTpm string `yaml:"vmTpm"` } type StorageClass struct { diff --git a/tests/e2e/config/reusable.go b/tests/e2e/config/reusable.go index d47e4d6ee8..7655b7aa75 100644 --- a/tests/e2e/config/reusable.go +++ b/tests/e2e/config/reusable.go @@ -24,7 +24,7 @@ import ( // ReusableEnv defines an environment variable used to reuse resources created previously. // By default, it retains all resources created during the e2e test after its completion (no cleanup by default in this mode). -// Use the `WITH_POST_CLEANUP=yes` environment variable to clean up resources created or used during the test. +// Use the `POST_CLEANUP=yes` environment variable to clean up resources created or used during the test. // // When a test starts, it will reuse existing virtual machines created earlier, if they exist. // If no virtual machines were found, they will be created. diff --git a/tests/e2e/default_config.yaml b/tests/e2e/default_config.yaml index 2e57ad2376..9af11a4c45 100644 --- a/tests/e2e/default_config.yaml +++ b/tests/e2e/default_config.yaml @@ -41,6 +41,7 @@ testData: sshKey: "/tmp/testdata/sshkeys/id_ed" sshUser: "cloud" vmVpc: "/tmp/testdata/vm-vpc" + vmTpm: "/tmp/testdata/vm-tpm" logFilter: - "pattern to exclude" - "validation failed for data source objectref" # Err. diff --git a/tests/e2e/testdata/vm-tpm/kustomization.yaml b/tests/e2e/testdata/vm-tpm/kustomization.yaml new file mode 100644 index 0000000000..698a4f7b5f --- /dev/null +++ b/tests/e2e/testdata/vm-tpm/kustomization.yaml @@ -0,0 +1,15 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: test-vm-tpm +namePrefix: tpm- +resources: + - ns.yaml + - vi + - vm +configurations: + - transformer.yaml +labels: + - includeSelectors: true + pairs: + id: pr-number-or-commit-hash + testcase: vm-check-tpm diff --git a/tests/e2e/testdata/vm-tpm/ns.yaml b/tests/e2e/testdata/vm-tpm/ns.yaml new file mode 100644 index 0000000000..5efde875b6 --- /dev/null +++ b/tests/e2e/testdata/vm-tpm/ns.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: default diff --git a/tests/e2e/testdata/vm-tpm/transformer.yaml b/tests/e2e/testdata/vm-tpm/transformer.yaml new file mode 100644 index 0000000000..e827a19238 --- /dev/null +++ b/tests/e2e/testdata/vm-tpm/transformer.yaml @@ -0,0 +1,52 @@ +namespace: + - kind: ClusterVirtualImage + path: spec/dataSource/objectRef/namespace +nameReference: + - kind: VirtualImage + version: v1alpha2 # optional + fieldSpecs: + - path: spec/dataSource/objectRef/name + kind: ClusterVirtualImage + - path: spec/dataSource/objectRef/name + kind: VirtualImage + - path: spec/dataSource/objectRef/name + kind: VirtualDisk + - path: spec/blockDeviceRefs/name + kind: VirtualMachine + - kind: ClusterVirtualImage + version: v1alpha2 # optional + fieldSpecs: + - path: spec/dataSource/objectRef/name + kind: ClusterVirtualImage + - path: spec/dataSource/objectRef/name + kind: VirtualImage + - path: spec/dataSource/objectRef/name + kind: VirtualDisk + - path: spec/blockDeviceRefs/name + kind: VirtualMachine + - kind: VirtualDisk + version: v1alpha2 # optional + fieldSpecs: + - path: spec/blockDeviceRefs/name + kind: VirtualMachine + - path: spec/blockDeviceRef/name + kind: VirtualMachineBlockDeviceAttachment + - kind: Secret + fieldSpecs: + - path: spec/provisioning/userDataRef/name + kind: VirtualMachine + - kind: VirtualMachineIPAddress + version: v1alpha2 + fieldSpecs: + - path: spec/virtualMachineIPAddressName + kind: VirtualMachine + - kind: VirtualMachine + version: v1alpha2 + fieldSpecs: + - path: spec/virtualMachineName + kind: VirtualMachineBlockDeviceAttachment + - kind: VirtualMachineClass + version: v1alpha2 + fieldSpecs: + - path: spec/virtualMachineClassName + kind: VirtualMachine diff --git a/tests/e2e/testdata/vm-tpm/vi/kustomization.yaml b/tests/e2e/testdata/vm-tpm/vi/kustomization.yaml new file mode 100644 index 0000000000..ab4c840d7f --- /dev/null +++ b/tests/e2e/testdata/vm-tpm/vi/kustomization.yaml @@ -0,0 +1,4 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - vi-debian-http.yaml diff --git a/tests/e2e/testdata/vm-tpm/vi/vi-debian-http.yaml b/tests/e2e/testdata/vm-tpm/vi/vi-debian-http.yaml new file mode 100644 index 0000000000..bb4f113882 --- /dev/null +++ b/tests/e2e/testdata/vm-tpm/vi/vi-debian-http.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: virtualization.deckhouse.io/v1alpha2 +kind: VirtualImage +metadata: + name: vi-debian-http +spec: + storage: ContainerRegistry + dataSource: + type: HTTP + http: + url: https://89d64382-20df-4581-8cc7-80df331f67fa.selstorage.ru/debian/debian-12-generic-amd64-20250814-2204.qcow2 diff --git a/tests/e2e/testdata/vm-tpm/vm/base/cfg/cloud-config.yaml b/tests/e2e/testdata/vm-tpm/vm/base/cfg/cloud-config.yaml new file mode 100644 index 0000000000..6e666300cb --- /dev/null +++ b/tests/e2e/testdata/vm-tpm/vm/base/cfg/cloud-config.yaml @@ -0,0 +1,16 @@ +#cloud-config +ssh_pwauth: True +users: + - name: cloud + passwd: "$6$rounds=4096$saltsalt$fPmUsbjAuA7mnQNTajQM6ClhesyG0.yyQhvahas02ejfMAq1ykBo1RquzS0R6GgdIDlvS.kbUwDablGZKZcTP/" + shell: /bin/bash + sudo: ALL=(ALL) NOPASSWD:ALL + lock_passwd: False + ssh_authorized_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFxcXHmwaGnJ8scJaEN5RzklBPZpVSic4GdaAsKjQoeA your_email@example.com +packages: + - qemu-guest-agent + - tpm2-tools +runcmd: + - systemctl enable qemu-guest-agent --now + - chown -R cloud:cloud /home/cloud diff --git a/tests/e2e/testdata/vm-tpm/vm/base/kustomization.yaml b/tests/e2e/testdata/vm-tpm/vm/base/kustomization.yaml new file mode 100644 index 0000000000..162dc1dc63 --- /dev/null +++ b/tests/e2e/testdata/vm-tpm/vm/base/kustomization.yaml @@ -0,0 +1,13 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./vmclass-discovery.yaml + - ./vd-root.yaml + - ./vm.yaml +generatorOptions: + disableNameSuffixHash: true +secretGenerator: + - name: cloud-init + files: + - userData=./cfg/cloud-config.yaml + type: provisioning.virtualization.deckhouse.io/cloud-init diff --git a/tests/e2e/testdata/vm-tpm/vm/base/vd-root.yaml b/tests/e2e/testdata/vm-tpm/vm/base/vd-root.yaml new file mode 100644 index 0000000000..ec166d1644 --- /dev/null +++ b/tests/e2e/testdata/vm-tpm/vm/base/vd-root.yaml @@ -0,0 +1,12 @@ +apiVersion: virtualization.deckhouse.io/v1alpha2 +kind: VirtualDisk +metadata: + name: vd-root +spec: + dataSource: + type: ObjectRef + objectRef: + kind: VirtualImage + name: vi-debian-http + persistentVolumeClaim: + size: 4Gi diff --git a/tests/e2e/testdata/vm-tpm/vm/base/vm.yaml b/tests/e2e/testdata/vm-tpm/vm/base/vm.yaml new file mode 100644 index 0000000000..b43ab4d583 --- /dev/null +++ b/tests/e2e/testdata/vm-tpm/vm/base/vm.yaml @@ -0,0 +1,21 @@ +apiVersion: virtualization.deckhouse.io/v1alpha2 +kind: VirtualMachine +metadata: + name: vm +spec: + cpu: + cores: 1 + memory: + size: 512Mi + virtualMachineClassName: discovery + provisioning: + type: UserDataRef + userDataRef: + kind: Secret + name: cloud-init + blockDeviceRefs: + - kind: VirtualDisk + name: vd-root + bootloader: EFI + disruptions: + restartApprovalMode: Automatic diff --git a/tests/e2e/testdata/vm-tpm/vm/base/vmclass-discovery.yaml b/tests/e2e/testdata/vm-tpm/vm/base/vmclass-discovery.yaml new file mode 100644 index 0000000000..46d5c14320 --- /dev/null +++ b/tests/e2e/testdata/vm-tpm/vm/base/vmclass-discovery.yaml @@ -0,0 +1,16 @@ +apiVersion: virtualization.deckhouse.io/v1alpha2 +kind: VirtualMachineClass +metadata: + name: discovery +spec: + cpu: + discovery: + nodeSelector: + matchExpressions: + - key: node-role.kubernetes.io/control-plane + operator: DoesNotExist + type: Discovery + sizingPolicies: + - cores: + max: 320 + min: 1 diff --git a/tests/e2e/testdata/vm-tpm/vm/kustomization.yaml b/tests/e2e/testdata/vm-tpm/vm/kustomization.yaml new file mode 100644 index 0000000000..27685ba222 --- /dev/null +++ b/tests/e2e/testdata/vm-tpm/vm/kustomization.yaml @@ -0,0 +1,4 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - overlays/vm-tpm diff --git a/tests/e2e/testdata/vm-tpm/vm/overlays/vm-tpm/kustomization.yaml b/tests/e2e/testdata/vm-tpm/vm/overlays/vm-tpm/kustomization.yaml new file mode 100644 index 0000000000..c5fcb42e09 --- /dev/null +++ b/tests/e2e/testdata/vm-tpm/vm/overlays/vm-tpm/kustomization.yaml @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +nameSuffix: -check-tpm +resources: + - ../../base +patches: + - path: vm.yaml + target: + kind: VirtualMachine + name: vm diff --git a/tests/e2e/testdata/vm-tpm/vm/overlays/vm-tpm/vm.yaml b/tests/e2e/testdata/vm-tpm/vm/overlays/vm-tpm/vm.yaml new file mode 100644 index 0000000000..3feeb88239 --- /dev/null +++ b/tests/e2e/testdata/vm-tpm/vm/overlays/vm-tpm/vm.yaml @@ -0,0 +1,6 @@ +apiVersion: virtualization.deckhouse.io/v1alpha2 +kind: VirtualMachine +metadata: + name: vm +spec: + osType: Windows diff --git a/tests/e2e/vm_tpm_test.go b/tests/e2e/vm_tpm_test.go new file mode 100644 index 0000000000..16c66dfd13 --- /dev/null +++ b/tests/e2e/vm_tpm_test.go @@ -0,0 +1,75 @@ +/* +Copyright 2024 Flant JSC + +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. +*/ + +package e2e + +import ( + "fmt" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/deckhouse/virtualization/tests/e2e/config" + "github.com/deckhouse/virtualization/tests/e2e/ginkgoutil" + kc "github.com/deckhouse/virtualization/tests/e2e/kubectl" +) + +var _ = Describe("VMCheckTPM", ginkgoutil.CommonE2ETestDecorators(), func() { + testCaseLabel := map[string]string{"testcase": "vm-check-tpm"} + var ( + ns string + vmName = fmt.Sprintf("%s-vm-check-tpm", namePrefix) + ) + BeforeAll(func() { + kustomization := fmt.Sprintf("%s/%s", conf.TestData.VMTpm, "kustomization.yaml") + var err error + ns, err = kustomize.GetNamespace(kustomization) + Expect(err).NotTo(HaveOccurred(), "%w", err) + }) + + It("checks if tpm exists in VM", func() { + By("checks if vm already exists in cluster. Reusable flag.", func() { + if config.IsReusable() { + res := kubectl.List(kc.ResourceVM, kc.GetOptions{ + Labels: testCaseLabel, + Namespace: ns, + Output: "jsonpath='{.items[*].metadata.name}'", + }) + Expect(res.Error()).NotTo(HaveOccurred(), res.StdErr()) + + if res.StdOut() != "" { + return + } + } + + CreateNamespace(ns) + res := kubectl.Apply(kc.ApplyOptions{ + Filename: []string{conf.TestData.VMTpm}, + FilenameOption: kc.Kustomize, + }) + Expect(res.Error()).NotTo(HaveOccurred(), res.StdErr()) + }) + + By("waits qemu agent to be ready") + WaitVMAgentReady(kc.WaitOptions{ + Labels: testCaseLabel, + Namespace: ns, + Timeout: MaxWaitTimeout, + }) + By("checks from OS that VM has tpm module version 2.0") + CheckResultSSHCommand(ns, vmName, `sudo tpm2_getcap properties-fixed | grep -A2 TPM2_PT_FAMILY_INDICATOR | grep value | awk -F"\"" "{print \$2}"`, "2.0") + }) +})