From 6f715436c6df38d926d0a4182bbf20e8c007ea00 Mon Sep 17 00:00:00 2001 From: Yahoon Yao Date: Mon, 9 Sep 2024 23:39:19 +0800 Subject: [PATCH] dynamically get the nodeport host (#4158) Greetings, This is an update to the example doc of [`Using Kubevirt`](https://ansible.readthedocs.io/projects/molecule/examples/kubevirt). The purpose is to **dynamically** get the NodePort host to replace the hardcoded hostname that is used for the VM SSH connection. **The problem we solved** By fetching the `hostname` dynamically, we avoid using a pre-defined host for the VM SSH connection, that will reduce the the potential failures by the connection problem with the host. In this update, the hostname for the SSH connection is fetched dynamically, which is the K8S node where the VM is running. I get this tested in our environment with @jangel97 Thanks. Co-authored-by: Hong Yao --- docs/examples/kubevirt.md | 7 +++++-- .../test_command/molecule/kubevirt/destroy.yml | 2 +- .../test_command/molecule/kubevirt/molecule.yml | 2 -- .../molecule/kubevirt/tasks/create_vm.yml | 13 +++++++++++++ .../kubevirt/tasks/create_vm_dictionary.yml | 4 ++-- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/docs/examples/kubevirt.md b/docs/examples/kubevirt.md index 0a12ec3d2b..1a520d2af3 100644 --- a/docs/examples/kubevirt.md +++ b/docs/examples/kubevirt.md @@ -40,6 +40,9 @@ rules: - apiGroups: [""] resources: ["services"] verbs: ["get", "list", "watch", "create", "delete", "patch", "edit"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding @@ -67,6 +70,7 @@ You will need to substitute the following placeholders: - This example is using ephemeral VMs, which enhance the speed of VM creation and cleanup. However, it is important to note that any data in the system will not be retained if the VM is rebooted. - You don't need to worry about setting up SSH keys. The `create.yml` Ansible playbook takes care of configuring a temporary SSH key. +- The hostname for SSH connection to the VM is fetched dynamically, which is the K8S node where the VM is running. ## Config playbook @@ -74,10 +78,9 @@ You will need to substitute the following placeholders: {!tests/fixtures/integration/test_command/molecule/kubevirt/molecule.yml!} ``` -Please, replace the following parameters: +Please, replace the following parameter: - ``: This should be replaced with the namespace in Kubernetes where you intend to create the KubeVirt VMs. -- ``: Change this to the fully qualified domain name (FQDN) of the Kubernetes node that Ansible will attempt to SSH into via the Service NodePort. ```yaml title="requirements.yml" {!tests/fixtures/integration/test_command/molecule/kubevirt/requirements.yml!} diff --git a/tests/fixtures/integration/test_command/molecule/kubevirt/destroy.yml b/tests/fixtures/integration/test_command/molecule/kubevirt/destroy.yml index 36e84ed015..fd359e0190 100644 --- a/tests/fixtures/integration/test_command/molecule/kubevirt/destroy.yml +++ b/tests/fixtures/integration/test_command/molecule/kubevirt/destroy.yml @@ -14,7 +14,7 @@ loop_control: loop_var: vm - - name: Delete VM Instance in KubeVirt + - name: Delete NodePort Service in KubeVirt kubernetes.core.k8s: state: absent kind: Service diff --git a/tests/fixtures/integration/test_command/molecule/kubevirt/molecule.yml b/tests/fixtures/integration/test_command/molecule/kubevirt/molecule.yml index 0edfba1508..a2ec83b39d 100644 --- a/tests/fixtures/integration/test_command/molecule/kubevirt/molecule.yml +++ b/tests/fixtures/integration/test_command/molecule/kubevirt/molecule.yml @@ -10,7 +10,6 @@ platforms: namespace: ssh_service: type: NodePort - nodeport_host: ansible_user: cloud-user memory: 1Gi - name: rhel8 @@ -18,7 +17,6 @@ platforms: namespace: ssh_service: type: NodePort - nodeport_host: ansible_user: cloud-user memory: 1Gi provisioner: diff --git a/tests/fixtures/integration/test_command/molecule/kubevirt/tasks/create_vm.yml b/tests/fixtures/integration/test_command/molecule/kubevirt/tasks/create_vm.yml index 840e49cff8..88ed0e0e9c 100644 --- a/tests/fixtures/integration/test_command/molecule/kubevirt/tasks/create_vm.yml +++ b/tests/fixtures/integration/test_command/molecule/kubevirt/tasks/create_vm.yml @@ -57,3 +57,16 @@ - [ sudo, yum, install, -y, qemu-guest-agent ] # Installs qemu-guest-agent - [ sudo, systemctl, start, qemu-guest-agent ] # Starts qemu-guest-agent name: cloudinitdisk + +- name: Fetch VM pod info + kubernetes.core.k8s_info: + api_version: v1 + kind: Pod + label_selectors: + - "vm.kubevirt.io/name={{ vm.name }}" + namespace: "{{ vm.namespace }}" + register: vm_pod_info + +- name: Extract the nodename from the VM pod info + ansible.builtin.set_fact: + nodeport_host: "{{ vm_pod_info.resources | map(attribute='spec.nodeName') | list | first }}" diff --git a/tests/fixtures/integration/test_command/molecule/kubevirt/tasks/create_vm_dictionary.yml b/tests/fixtures/integration/test_command/molecule/kubevirt/tasks/create_vm_dictionary.yml index 986df50533..143cb6acd5 100644 --- a/tests/fixtures/integration/test_command/molecule/kubevirt/tasks/create_vm_dictionary.yml +++ b/tests/fixtures/integration/test_command/molecule/kubevirt/tasks/create_vm_dictionary.yml @@ -17,8 +17,8 @@ {{ molecule_systems | default({}) | combine({ vm.name: { - 'ansible_user': 'cloud-user', - 'ansible_host': vm.ssh_service.nodeport_host, + 'ansible_user': vm.ansible_user, + 'ansible_host': nodeport_host, 'ansible_ssh_port': ssh_service_address, 'ansible_ssh_private_key_file': temporary_ssh_key_path }