Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set VM primary NIC MAC address at env_setup or deploy_vm #454

Merged
merged 4 commits into from
Apr 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions common/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
* vm_remove_network_adapter.yml: Remove network adapter from VM
* vm_configure_network_adapter.yml: Reconfig VM network adapter connection settings
* vm_wait_network_connected.yml: Wait for network adapter to be connected
* vm_test_nic.yml: Check if given network adapter is connectable through ssh
* vm_get_network_facts.yml: Get VM network adapters info
* vm_get_netadapter_number.yml: Get VM network adapters number with different types

Expand Down Expand Up @@ -82,7 +81,6 @@
### Tasks for getting VM IP
* vm_get_ip.yml: Get VM IP address by calling vm_get_ip_from_vmtools.yml
* vm_get_ip_from_vmtools.yml: Get VM IP address from VMware Tools guestinfo
* vm_get_primary_nic.yml: Get VM connectable network adapter MAC/IP address
* vm_get_ip_from_notools.yml: Get VM IP address when there is no VMware Tools installed
* vm_get_world_id.yml: Get VM world ID on ESXi host
* vm_get_ip_esxcli.yml: Get VM IP address on ESXi host by esxcli command
Expand Down
34 changes: 23 additions & 11 deletions common/vm_get_ip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,42 @@
# SPDX-License-Identifier: BSD-2-Clause
---
# Get VM IP Address using esxcli command or from VMware Tools guestinfo
- name: Initialize VM guest IP address variable
# Parameter:
# vm_primary_nic_mac: The VM's primary network adapter MAC address
# Return:
# vm_guest_ip: The VM's guest IPv4 address
#
- name: "Check vm_primary_nic_mac is set for VM '{{ vm_name }}'"
ansible.builtin.assert:
that:
- vm_primary_nic_mac is defined
- vm_primary_nic_mac
fail_msg: "Parameter 'vm_primary_nic_mac' must be set for getting VM's guest IPv4 address."

- name: "Initialize VM guest IP address variable"
ansible.builtin.set_fact:
vm_guest_ip: ""

# Get VM power status
- include_tasks: vm_get_power_state.yml
- name: "Get VM power status"
include_tasks: vm_get_power_state.yml

# Power on VM when VM power status is not poweredOn
- include_tasks: vm_set_power_state.yml
- name: "Power on VM"
include_tasks: vm_set_power_state.yml
vars:
vm_power_state_set: 'powered-on'
when: vm_power_state_get != "poweredOn"

# Get VMware tools status
- include_tasks: vm_get_vmtools_status.yml
- name: "Get VMware Tools status"
include_tasks: vm_get_vmtools_status.yml

# Get VM IP address when VMware tools is installed
- include_tasks: vm_get_ip_from_vmtools.yml
- name: "Get VM IP address when VMware Tools is running"
include_tasks: vm_get_ip_from_vmtools.yml
when:
- vmtools_is_running is defined
- vmtools_is_running | bool

# Get VM IP address when VMware tools not installed or not get from VMware tools
- include_tasks: vm_get_ip_from_notools.yml
- name: "Get VM IP address when VMware Tools is not installed or not running"
include_tasks: vm_get_ip_from_notools.yml
when: >
(vmtools_is_installed is undefined) or
(not vmtools_is_installed | bool) or
Expand Down
134 changes: 32 additions & 102 deletions common/vm_get_ip_esxcli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,111 +16,41 @@
- vm_world_id
fail_msg: "Can not get VM IP address by esxcli command if VM world ID is not defined or empty."

- name: "Initialize the fact for finding VM primary network adapter"
- name: "Set facts for getting primary network adapter IPv4 address for VM '{{ vm_name }}'"
ansible.builtin.set_fact:
find_primary_nic: false

- block:
# Wait for network adapters ready after VM power-on/reset
- include_tasks: vm_wait_network_connected.yml

- name: "Initialize the connected network adapter number for VM '{{ vm_name }}'"
ansible.builtin.set_fact:
vm_connected_nic_number: 0

- include_tasks: vm_get_network_facts.yml

- name: "Get connected network adapter number form VM '{{ vm_name }}'"
ansible.builtin.set_fact:
vm_connected_nic_number: "{{ vm_network_adapters | dict2items | selectattr('value.connected', 'equalto', true) | length }}"

- name: "VM '{{ vm_name }}' has {{ vm_connected_nic_number }} network adapter(s) connected"
ansible.builtin.assert:
that:
- vm_connected_nic_number | int >= 1
fail_msg: "Not found connected network adapter on VM '{{ vm_name }}'"

- name: "VM '{{ vm_name }}' has more than one network adapter connected. Need to find the primary NIC."
ansible.builtin.set_fact:
find_primary_nic: true
when: vm_connected_nic_number | int > 1
when: (router_vm_name is undefined) or (vm_name != router_vm_name)

# Deployed router VM can only get 1 valid IP even though it has 2 network adapteres
- block:
- name: "Wait for getting VM '{{ vm_name }}' IP address on ESXi '{{ esxi_hostname }}'"
ansible.builtin.shell: esxcli network vm port list -w '{{ vm_world_id }}' | awk '/IP Address/ {print $3}' | sed '/0.0.0.0/d' | sed '/^169.254./d'
delegate_to: "{{ esxi_hostname }}"
register: get_vm_ip_esxcli
until:
- get_vm_ip_esxcli is defined
- get_vm_ip_esxcli.stdout is defined
- get_vm_ip_esxcli.stdout
retries: "{{ ((vm_get_ip_timeout | default(300) | int) / 5) | int }}"
delay: 5
failed_when: false
changed_when: false

- name: "Set fact of VM guest IP with primary IP"
ansible.builtin.set_fact:
vm_guest_ip: "{% for ip in get_vm_ip_esxcli.stdout_lines %}{% if ip %}{{ ip.strip('\"') }}{% endif %}{% endfor %}"
when: not find_primary_nic

# Wait for target VM's all IP obtained
- block:
- name: "Initialize VM's primary MAC address for VM '{{ vm_name }}'"
ansible.builtin.set_fact:
vm_primary_mac: ""
when: vm_primary_mac is undefined

- name: "Initialize esxcli command for VM '{{ vm_name }}'"
ansible.builtin.set_fact:
esxcli_cmd: "esxcli network vm port list -w '{{ vm_world_id }}' | awk '/MAC Address|IP Address/ {key=$3; getline; print key \",\" $3;}'"

# If vm_primary_mac has been found, we can only wait for the IP of the primary mac
- name: "Set esxcli command with filter of MAC address {{ vm_primary_mac }} for VM '{{ vm_name }}'"
ansible.builtin.set_fact:
esxcli_cmd: "esxcli network vm port list -w '{{ vm_world_id }}' | awk '/MAC Address|IP Address/ {key=$3; getline; print key \",\" $3;}' | grep '{{ vm_primary_mac }}'"
when:
- vm_primary_mac is defined
- vm_primary_mac

- name: "Wait for getting VM '{{ vm_name }}' IP address on ESXi '{{ esxi_hostname }}'"
ansible.builtin.shell: "{{ esxcli_cmd }}"
delegate_to: "{{ esxi_hostname }}"
register: get_vm_ip_esxcli
until:
- get_vm_ip_esxcli is defined
- get_vm_ip_esxcli.stdout is defined
- get_vm_ip_esxcli.stdout
- not "'0.0.0.0' in get_vm_ip_esxcli.stdout"
- not "',169.254.' in get_vm_ip_esxcli.stdout"
retries: "{{ ((vm_get_ip_timeout | default(300) | int) / 5) | int }}"
delay: 5
failed_when: false
changed_when: false

- name: "Set fact of the VM IP info from esxcli command"
ansible.builtin.set_fact:
vm_ip_esxcli: "{{ get_vm_ip_esxcli.stdout_lines }}"
- name: "Print VM IP address got from esxcli command"
ansible.builtin.debug: var=vm_ip_esxcli

- name: "Initialize the fact of VM network interfaces for VM '{{ vm_name }}'"
ansible.builtin.set_fact:
vm_guest_mac_ipv4: {}
- name: "Set the fact of valid MAC address and IP address for VM '{{ vm_name }}'"
ansible.builtin.set_fact:
vm_guest_mac_ipv4: "{{ vm_guest_mac_ipv4 |combine({item.split(',')[0]:item.split(',')[1]}) }}"
when: item.split(',') | length == 2 and item.split(',')[1] != '0.0.0.0'
with_items: "{{ vm_ip_esxcli }}"
vm_guest_mac_ipv4: "{{ {vm_primary_nic_mac: ''} }}"
esxcli_cmd: "esxcli network vm port list -w '{{ vm_world_id }}' | awk '/MAC Address|IP Address/ {key=$3; getline; print key \": \" $3;}' | grep '{{ vm_primary_nic_mac }}'"

- name: "Wait for getting VM '{{ vm_name }}' primary IP address on ESXi '{{ esxi_hostname }}'"
ansible.builtin.shell: "{{ esxcli_cmd }}"
delegate_to: "{{ esxi_hostname }}"
register: get_vm_ip_esxcli
until:
- get_vm_ip_esxcli.stdout is defined
- get_vm_ip_esxcli.stdout
- (get_vm_ip_esxcli.stdout | from_yaml)[vm_primary_nic_mac] is defined
- (get_vm_ip_esxcli.stdout | from_yaml)[vm_primary_nic_mac] != '0.0.0.0'
- (get_vm_ip_esxcli.stdout | from_yaml)[vm_primary_nic_mac] is not match('^169.254.')
retries: "{{ ((vm_get_ip_timeout | default(300) | int) / 5) | int }}"
delay: 5
ignore_errors: true
changed_when: false

- name: "Set the fact of primary MAC address and IP address for VM '{{ vm_name }}'"
ansible.builtin.set_fact:
vm_guest_mac_ipv4: "{{ get_vm_ip_esxcli.stdout | from_yaml }}"
when:
- get_vm_ip_esxcli.stdout is defined
- get_vm_ip_esxcli.stdout
- get_vm_ip_esxcli.stdout | from_yaml
- (get_vm_ip_esxcli.stdout | from_yaml)[vm_primary_nic_mac] is defined

- include_tasks: vm_get_primary_nic.yml
- name: "Print the fact of primary MAC and IPv4 address for VM '{{ vm_name }}'"
ansible.builtin.debug: var=vm_guest_mac_ipv4

- name: "Set fact of VM guest IP with primary IP for VM '{{ vm_name }}'"
ansible.builtin.set_fact:
vm_guest_ip: "{{ vm_primary_ip }}"
when: find_primary_nic is defined and find_primary_nic
- name: "Set fact of VM guest IP with primary IP for VM '{{ vm_name }}'"
ansible.builtin.set_fact:
vm_guest_ip: "{{ vm_guest_mac_ipv4[vm_primary_nic_mac] }}"

- ansible.builtin.debug:
msg: "Get VM '{{ vm_name }}' IP address using esxcli command: {{ vm_guest_ip }}"
35 changes: 27 additions & 8 deletions common/vm_get_ip_from_notools.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
# Copyright 2021-2023 VMware, Inc.
# SPDX-License-Identifier: BSD-2-Clause
---
# Get VM IP address when there is no VMware tools installed in VM
# Get VM IP address when there is no VMware Tools installed in VM
# Parameter:
# vm_primary_nic_mac: The VM's primary network adapter MAC address
# Return:
# vm_guest_ip: The VM's guest IPv4 address
#
- name: "Check vm_primary_nic_mac is set for VM '{{ vm_name }}'"
ansible.builtin.assert:
that:
- vm_primary_nic_mac is defined
- vm_primary_nic_mac
fail_msg: "Parameter 'vm_primary_nic_mac' must be set for getting VM's guest IPv4 address."

- name: "Initialize VM world ID and VM IP address for '{{ vm_name }}'"
ansible.builtin.set_fact:
vm_world_id: ""
Expand All @@ -17,14 +29,20 @@

# When not get vm_world_id and VM original power status is power on,
# power off and power on VM to try again
- block:
- include_tasks: vm_set_power_state.yml
- name: "Reset VM to get VM world ID"
block:
- name: "Power off VM"
include_tasks: vm_set_power_state.yml
vars:
vm_power_state_set: 'powered-off'
- include_tasks: vm_set_power_state.yml

- name: "Power on VM"
include_tasks: vm_set_power_state.yml
vars:
vm_power_state_set: 'powered-on'
- include_tasks: vm_get_world_id.yml

- name: "Get VM word ID after reset"
include_tasks: vm_get_world_id.yml
when: not vm_world_id

# Fail after VM power off and power on still not get vm world ID
Expand All @@ -34,7 +52,8 @@
- vm_world_id
fail_msg: "Failed to get VM world ID after power off and power on VM."

# Get VM IP address via esxcli command by VM world ID
- include_tasks: vm_get_ip_esxcli.yml
- name: Display the VM IP address got via esxcli command
- name: "Get VM IP address via esxcli command by VM world ID"
include_tasks: vm_get_ip_esxcli.yml

- name: "Display the VM IP address got via esxcli command"
ansible.builtin.debug: var=vm_guest_ip
35 changes: 20 additions & 15 deletions common/vm_get_ip_from_vmtools.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
# Copyright 2021-2023 VMware, Inc.
# SPDX-License-Identifier: BSD-2-Clause
---
# Get VM IPv4 address through VMware Tools while VM is powered on
# Get VM IP address from VM's guest info collected by VMware Tools
# Parameter:
# vm_primary_nic_mac: The VM's primary network adapter MAC address
# Return:
# vm_guest_ip: The VM's guest IPv4 address
#
- name: "Check vm_primary_nic_mac is set for VM '{{ vm_name }}'"
ansible.builtin.assert:
that:
- vm_primary_nic_mac is defined
- vm_primary_nic_mac
fail_msg: "Parameter 'vm_primary_nic_mac' must be set for getting VM's guest IPv4 address."

- name: "Initialize VM guest IP/IP list variables"
ansible.builtin.set_fact:
vm_guest_ip: ""
vm_guest_all_ip: []
vm_guest_mac_ipv4: {}

- name: "Initialize VM's primary MAC address"
ansible.builtin.set_fact:
vm_primary_mac: ""
when: vm_primary_mac is undefined

- name: "Wait for VM's guest IP address"
include_tasks: vm_wait_guest_ip.yml

Expand All @@ -38,17 +45,15 @@
- item.ipAddress | ansible.utils.ipv4 | length == 1
with_items: "{{ vm_guest_net }}"

# Get VM primary NIC
- name: "Get VM primary network adapter by testing connection"
include_tasks: vm_get_primary_nic.yml
- name: "Print the fact of MAC and IPv4 addresses for VM '{{ vm_name }}'"
ansible.builtin.debug: var=vm_guest_mac_ipv4

# If VM only has 1 IP, vm_primary_ip should be equal to vm_guest_ip
# If VM has more than 1 IP, the IP in guest info might not be able to connected,
# then we need to update it with vm_primary_ip because vm_primary_ip is the connectable IP.
- name: "Set fact of VM guest IP with primary IP"
- name: "Set fact of VM guest IPv4 address with primary network adapter's IPv4 address"
ansible.builtin.set_fact:
vm_guest_ip: "{{ vm_primary_ip }}"
when: vm_guest_ip != vm_primary_ip
vm_guest_ip: "{{ vm_guest_mac_ipv4[vm_primary_nic_mac] }}"
when:
- vm_guest_mac_ipv4[vm_primary_nic_mac] is defined
- vm_guest_mac_ipv4[vm_primary_nic_mac]

- name: "Display VM's guest IP addresses retrieved by VMware Tools"
ansible.builtin.debug:
Expand Down
62 changes: 0 additions & 62 deletions common/vm_get_primary_nic.yml

This file was deleted.

Loading