Skip to content

Commit

Permalink
Mm feature/add lookup tests (#529)
Browse files Browse the repository at this point in the history
SUMMARY
Including a playbook that can be used to test the lookup plugins. Its designed to be run manually and needs inputs from a specific environment.
Once automated testing is set up, this test can be modified to require less inputs from the user
Also included a bugfix which was found while testing. Lookng up the contents of a datacenter would raise an exception instead of returning the correct results
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
Lookup plugins

Reviewed-by: Anna Savina
Reviewed-by: Danielle Barda
  • Loading branch information
mikemorency authored Sep 12, 2024
1 parent 1887490 commit fab0aff
Show file tree
Hide file tree
Showing 10 changed files with 158 additions and 15 deletions.
1 change: 1 addition & 0 deletions .ansible-lint
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ exclude_paths:
- meta/runtime.yml
- tests/integration
- tests/sanity
- tests/manual
- modules.yaml
- config

Expand Down
6 changes: 6 additions & 0 deletions changelogs/fragments/529-manual-test-play-for-lookups.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
trivial:
- tests - added manual test playbook for lookup plugins

bugfixes:
- lookup - fixed issue where searching for datacenter contents would throw an exception instead of returning expected results
12 changes: 7 additions & 5 deletions config/copy_old_return_blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def read_version_added(old_module_file_path):
lines = f.readlines()

for line in lines:
if line.startswith('version_added:'):
if line.startswith("version_added:"):
return line

return None
Expand All @@ -45,13 +45,15 @@ def format_new_content(module_file_path, example_and_return_blocks, version_adde

with open(GALAXY_PATH, "r") as f:
_galaxy_contents = yaml.safe_load(f)
default_version = _galaxy_contents['version']
default_version = _galaxy_contents["version"]

new_content = []
added_content = False
open_block = False
for line in lines:
if example_and_return_blocks and (line.startswith('EXAMPLES = r"""') or line.startswith('RETURN = r"""')):
if example_and_return_blocks and (
line.startswith('EXAMPLES = r"""') or line.startswith('RETURN = r"""')
):
open_block = True
if not added_content:
new_content += example_and_return_blocks
Expand All @@ -62,11 +64,11 @@ def format_new_content(module_file_path, example_and_return_blocks, version_adde
open_block = False
continue

if line.startswith('version_added'):
if line.startswith("version_added"):
if version_added:
new_content += [version_added]
else:
new_content += [f'version_added: {default_version}\n']
new_content += [f"version_added: {default_version}\n"]
continue

new_content += [line]
Expand Down
20 changes: 10 additions & 10 deletions plugins/plugin_utils/lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,6 @@ async def search_for_object_moid_top_down(self):
path_parts = [_part for _part in object_path.split("/") if _part]

for index, path_part in enumerate(path_parts):
if not self.active_filters.get("datacenters"):
datacenter_moid = await self.get_object_moid_by_name_and_type(
path_part, "datacenter"
)
if self.object_type == "datacenter" or not datacenter_moid:
return datacenter_moid
self.active_filters["datacenters"] = datacenter_moid
continue

if index == len(path_parts) - 1:
# were at the end of the object path. Either return the object, or return
# all of the objects it contains (for example, the children inside of a folder)
Expand All @@ -153,7 +144,9 @@ async def search_for_object_moid_top_down(self):
await self.process_intermediate_path_part(path_part)
continue

raise Exception("here4")
raise AnsibleLookupError(
"No objects could be found due to an invalid search path"
)

async def process_intermediate_path_part(self, intermediate_object_name):
"""
Expand All @@ -171,6 +164,13 @@ async def process_intermediate_path_part(self, intermediate_object_name):
Returns:
str or None, a single MoID or none if nothing was found
"""
if not self.active_filters.get("datacenter"):
result = await self.get_object_moid_by_name_and_type(
intermediate_object_name, "datacenter"
)
self.active_filters["datacenters"] = result
return result

if self.object_type == "vm":
result = await self.get_object_moid_by_name_and_type(
intermediate_object_name, "resource_pool"
Expand Down
14 changes: 14 additions & 0 deletions tests/manual/init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
# shellcheck disable=SC2155,SC2086

export DEFAULT_COLLECTIONS_PATH="$ANSIBLE_COLLECTIONS_PATH/ansible_collections"

# Check if the variable is already set (e.g., in CI)
if [ -z "$ANSIBLE_COLLECTIONS_PATH" ]; then
# If not, use base collections path
ANSIBLE_COLLECTIONS_PATH="$DEFAULT_COLLECTIONS_PATH"
fi

echo "ANSIBLE_COLLECTIONS_PATH: $ANSIBLE_COLLECTIONS_PATH"
BASE_DIR=$(dirname "$(realpath "${BASH_SOURCE[0]}")")
export ANSIBLE_ROLES_PATH=${BASE_DIR}
6 changes: 6 additions & 0 deletions tests/manual/vmware_lookup/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
This test is temporary until automated testing can be put in place.

To run:

1. Create a `vars.yml` in this directory with variables specific to your environment. Possible variables to set can be found in `vmware_lookup/defaults/main.yml`, plus `vcenter_hostname`, `vcenter_username`, `vcenter_password`. Alternatively, you can set the authentication variables as env vars. For example, `VCENTER_HOSTNAME`, `VCENTER_USERNAME`, `VCENTER_PASSWORD`
2. Run `./runme.sh`
15 changes: 15 additions & 0 deletions tests/manual/vmware_lookup/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
vcenter_cluster: MyCluster
vcenter_datacenter: MyDatacenter
vcenter_resource_pool: MyResourcePool
vcenter_esxi_host: MyESXiHost
vcenter_vm: MyVM
vcenter_datastore: MyDatastore
vcenter_vm_folder: MyVmFolder
vcenter_nested_network: MyNetworkFolder/MyNetwork

connection_args:
vcenter_hostname: "{{ vcenter_hostname | default(lookup('ansible.builtin.env', 'VCENTER_HOSTNAME')) }}"
vcenter_username: "{{ vcenter_username | default(lookup('ansible.builtin.env', 'VCENTER_USERNAME')) }}"
vcenter_password: "{{ vcenter_password | default(lookup('ansible.builtin.env', 'VCENTER_PASSWORD')) }}"
vcenter_validate_certs: false
16 changes: 16 additions & 0 deletions tests/manual/vmware_lookup/run.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
- hosts: localhost
gather_facts: no

tasks:
- name: Import Custom Vars If Found
ansible.builtin.include_vars:
file: "{{ playbook_dir }}/vars.yml"
failed_when: false
tags:
- eco-vcenter-ci

- name: Import vmware_lookup role
ansible.builtin.import_role:
name: vmware_lookup
tags:
- eco-vcenter-ci
18 changes: 18 additions & 0 deletions tests/manual/vmware_lookup/runme.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
source ../init.sh

# Generates a string starting with 'test-' followed by 4 random lowercase characters
TINY_PREFIX="test-$(uuidgen | tr -d '-' | cut -c1-4 | tr '[:upper:]' '[:lower:]')"

# Extract the ansible_tags from integration_config.yml
# ANSIBLE_TAGS=$(awk '/ansible_tags/ {print $2}' ../../integration_config.yml)
ANSIBLE_TAGS="eco-vcenter-ci"

# Check if the ANSIBLE_TAGS variable is set
if [[ -n "$ANSIBLE_TAGS" ]]; then
echo "ANSIBLE_TAGS is set to: $ANSIBLE_TAGS"
exec ansible-playbook run.yml --tags "$ANSIBLE_TAGS" --extra-vars "tiny_prefix=$TINY_PREFIX"
else
echo "ANSIBLE_TAGS is not set for Eco vCenter. Running on simulator."
exec ansible-playbook run.yml --tags integration-ci
fi
65 changes: 65 additions & 0 deletions tests/manual/vmware_lookup/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
- name: Lookup Datacenter
ansible.builtin.assert:
that: lookup('vmware.vmware_rest.datacenter_moid', '/' + vcenter_datacenter, **connection_args)

- name: Lookup Clusters In Datacenter
ansible.builtin.assert:
that: lookup('vmware.vmware_rest.cluster_moid', '/' + vcenter_datacenter + '/', **connection_args)

- name: Lookup Datastores In Datacenter
ansible.builtin.assert:
that: lookup('vmware.vmware_rest.datastore_moid', '/' + vcenter_datacenter + '/', **connection_args)

- name: Lookup Cluster
ansible.builtin.assert:
that: lookup('vmware.vmware_rest.cluster_moid', '/' + vcenter_datacenter + '/' + vcenter_cluster, **connection_args)

- name: Lookup Datastores
ansible.builtin.assert:
that: lookup('vmware.vmware_rest.datastore_moid', '/' + vcenter_datacenter + '/' + item, **connection_args)
loop:
- "{{ vcenter_datastore }}"
- "{{ vcenter_esxi_host }}/{{ vcenter_datastore }}"
- "{{ vcenter_esxi_host }}/"

- name: Lookup Folders
ansible.builtin.assert:
that: lookup('vmware.vmware_rest.folder_moid', '/' + vcenter_datacenter + '/' + item, **connection_args)
loop:
- vm/{{ vcenter_vm_folder }}
- "{{ vcenter_vm_folder }}"

- name: Lookup Networks
ansible.builtin.assert:
that: lookup('vmware.vmware_rest.network_moid', '/' + vcenter_datacenter + '/' + item, **connection_args)
loop:
- Management Network
- vMotion
- "{{ vcenter_nested_network | dirname }}/"
- "{{ vcenter_nested_network }}"

- name: Lookup Hosts
ansible.builtin.assert:
that: lookup('vmware.vmware_rest.host_moid', '/' + vcenter_datacenter + '/' + item, **connection_args)
loop:
- "{{ vcenter_esxi_host }}"
- "{{ vcenter_cluster }}/"
- "{{ vcenter_cluster }}/{{ vcenter_esxi_host }}"

- name: Lookup VMs
ansible.builtin.assert:
that: lookup('vmware.vmware_rest.vm_moid', '/' + vcenter_datacenter + '/' + item, **connection_args)
loop:
- "{{ vcenter_esxi_host }}/"
- vCLS/
- "{{ vcenter_vm }}"
- "{{ vcenter_resource_pool }}/"

- name: Lookup Resource Pools
ansible.builtin.assert:
that: lookup('vmware.vmware_rest.resource_pool_moid', '/' + vcenter_datacenter + '/' + item, **connection_args)
loop:
- "{{ vcenter_resource_pool }}"
- "{{ vcenter_resource_pool }}/"
- "{{ vcenter_cluster }}/"

0 comments on commit fab0aff

Please sign in to comment.