From a24b03c07cfb3df2e80950aa0a166b44d55d4621 Mon Sep 17 00:00:00 2001 From: Vibhu-gslab <109593615+Vibhu-gslab@users.noreply.github.com> Date: Tue, 15 Aug 2023 22:11:03 +0530 Subject: [PATCH] Test: Adding integration tests for cv_device_v3 (#621) * Test: Adding integration test for cv_device_v3 (move_device) * Adding tests for state absent (decommission_device) * Addressing review comments * Added tests for factory_reset and provisioning_reset * Added tests for attach and detach bundle and fixed counters for bundle_attached/bundle_detached * Added tests for apply/detach configlets * Added test for deploy_device * Fixing pylint issues * added back inventory file; revert of d346824e7dd8b716d3011c78d914351fe29b7202 * reapplying partial changes from d346824e7dd8b716d3011c78d914351fe29b7202 * Separating files and fixing review comments * Updating tests Some minor fix Updated tests * Fixing to clean up lab * Changing for dual_dc topology * minor nit * Adding terninattr for image bundle * Minor fixes while testing PR * Removing configlets from bundle playbook * Added comments --------- Co-authored-by: Shivani-chourasiya Co-authored-by: Sugetha Chandhrasekar --- .../cvp/molecule/cv_device_v3/converge.yml | 12 ++ .../cvp/molecule/cv_device_v3/molecule.yml | 25 +++ .../cv_device_v3/test_apply_detach_bundle.yml | 104 ++++++++++++ .../test_apply_detach_configlet.yml | 95 +++++++++++ ...ssion_factory_reset_provisioning_reset.yml | 139 +++++++++++++++ .../test_move_and_deploy_device.yml | 160 ++++++++++++++++++ .../cvp/plugins/module_utils/device_tools.py | 40 ++--- 7 files changed, 552 insertions(+), 23 deletions(-) create mode 100644 ansible_collections/arista/cvp/molecule/cv_device_v3/converge.yml create mode 100644 ansible_collections/arista/cvp/molecule/cv_device_v3/molecule.yml create mode 100644 ansible_collections/arista/cvp/molecule/cv_device_v3/test_apply_detach_bundle.yml create mode 100644 ansible_collections/arista/cvp/molecule/cv_device_v3/test_apply_detach_configlet.yml create mode 100644 ansible_collections/arista/cvp/molecule/cv_device_v3/test_decommission_factory_reset_provisioning_reset.yml create mode 100644 ansible_collections/arista/cvp/molecule/cv_device_v3/test_move_and_deploy_device.yml diff --git a/ansible_collections/arista/cvp/molecule/cv_device_v3/converge.yml b/ansible_collections/arista/cvp/molecule/cv_device_v3/converge.yml new file mode 100644 index 000000000..4a25bb4b7 --- /dev/null +++ b/ansible_collections/arista/cvp/molecule/cv_device_v3/converge.yml @@ -0,0 +1,12 @@ +--- +- name: Test cv_device_v3 module + import_playbook: test_move_and_deploy_device.yml + +- name: Test cv_device_v3 module + import_playbook: test_apply_detach_configlet.yml + +- name: Test cv_device_v3 module + import_playbook: test_apply_detach_bundle.yml + +- name: Test cv_device_v3 module + import_playbook: test_decommission_factory_reset_provisioning_reset.yml diff --git a/ansible_collections/arista/cvp/molecule/cv_device_v3/molecule.yml b/ansible_collections/arista/cvp/molecule/cv_device_v3/molecule.yml new file mode 100644 index 000000000..79248ffed --- /dev/null +++ b/ansible_collections/arista/cvp/molecule/cv_device_v3/molecule.yml @@ -0,0 +1,25 @@ +--- +scenario: + test_sequence: + - converge +driver: + name: delegated +platforms: + - name: dummy + managed: false +provisioner: + name: ansible + config_options: + defaults: + jinja2_extensions: 'jinja2.ext.loopcontrols,jinja2.ext.do,jinja2.ext.i18n' + gathering: explicit + command_warnings: False + remote_tmp: /tmp/.ansible-${USER}/tmp + stdout_callback: yaml + playbooks: + converge: converge.yml + ansible_args: + - --inventory + - ${MOLECULE_SCENARIO_DIRECTORY}/../../examples/inventory.yml +verifier: + name: ansible diff --git a/ansible_collections/arista/cvp/molecule/cv_device_v3/test_apply_detach_bundle.yml b/ansible_collections/arista/cvp/molecule/cv_device_v3/test_apply_detach_bundle.yml new file mode 100644 index 000000000..62387cdc6 --- /dev/null +++ b/ansible_collections/arista/cvp/molecule/cv_device_v3/test_apply_detach_bundle.yml @@ -0,0 +1,104 @@ +--- +- name: Test cv_device_v3 + hosts: CloudVision + connection: local + gather_facts: no + vars: + ansible_command_timeout: 1200 + ansible_connect_timeout: 600 + + DEVICE_NAME: s1-leaf1 + + IMAGE_NAME: "vEOS-lab.swi" + + EXTENSION_NAME: "TerminAttr-1.25.1-1.swix" + + BUNDLE_NAME: "Test_bundle" + + CVP_DEVICES_BUNDLE_ATTACHED: + - fqdn: "{{DEVICE_NAME}}" + parentContainerName: "{{CV_FACTS_V3_RESULT.data.cvp_devices[0].parentContainerName}}" + imageBundle: Test_bundle + + CVP_DEVICES_BUNDLE_DETACHED: + - fqdn: "{{DEVICE_NAME}}" + parentContainerName: "{{CV_FACTS_V3_RESULT.data.cvp_devices[0].parentContainerName}}" + + tasks: + - name: Collect devices facts from {{inventory_hostname}} + arista.cvp.cv_facts_v3: + facts: + - devices + regexp_filter: "{{DEVICE_NAME}}" + register: CV_FACTS_V3_RESULT + + - name: "Upload EOS image to {{inventory_hostname}}" + arista.cvp.cv_image_v3: + mode: image + action: add + image: "{{IMAGE_NAME}}" + + - name: "Upload TerminAttr image to {{inventory_hostname}}" + arista.cvp.cv_image_v3: + mode: image + action: add + image: "{{EXTENSION_NAME}}" + + - name: "Create bundle {{inventory_hostname}}" + arista.cvp.cv_image_v3: + mode: bundle + action: add + bundle_name: "{{BUNDLE_NAME}}" + image_list: + - "{{IMAGE_NAME}}" + - "{{EXTENSION_NAME}}" + + - name: "Attach bundle on {{inventory_hostname}}" + arista.cvp.cv_device_v3: + devices: '{{CVP_DEVICES_BUNDLE_ATTACHED}}' + state: present + apply_mode: strict + register: ATTACH_BUNDLE + + - name: "Check attach bundle" + assert: + that: + - ATTACH_BUNDLE.bundle_attached.changed == true + - ATTACH_BUNDLE.bundle_attached.bundle_attached_count == 1 + - ATTACH_BUNDLE.bundle_attached.bundle_attached_list != [] + - ATTACH_BUNDLE.bundle_attached.success == true + - ATTACH_BUNDLE.bundle_attached.taskIds != [] + + - name: Execute Task for attach_bundle + arista.cvp.cv_task_v3: + tasks: + - "{{item}}" + loop: "{{ATTACH_BUNDLE.taskIds}}" + + - name: Pause for 20 seconds to Execute Task + ansible.builtin.pause: + seconds: 20 + + - name: "Detach bundle on {{inventory_hostname}}" + arista.cvp.cv_device_v3: + devices: '{{CVP_DEVICES_BUNDLE_DETACHED}}' + state: present + apply_mode: strict + register: DETACH_BUNDLE + + - name: "Check detach bundle" + assert: + that: + - DETACH_BUNDLE.bundle_detached.changed == true + - DETACH_BUNDLE.bundle_detached.bundle_detached_count == 1 + - DETACH_BUNDLE.bundle_detached.bundle_detached_list != [] + - DETACH_BUNDLE.bundle_detached.success == true + + - name: "Delete bundle {{inventory_hostname}}" + arista.cvp.cv_image_v3: + mode: bundle + action: remove + bundle_name: "{{BUNDLE_NAME}}" + image_list: + - "{{IMAGE_NAME}}" + - "{{EXTENSION_NAME}}" diff --git a/ansible_collections/arista/cvp/molecule/cv_device_v3/test_apply_detach_configlet.yml b/ansible_collections/arista/cvp/molecule/cv_device_v3/test_apply_detach_configlet.yml new file mode 100644 index 000000000..417913b1c --- /dev/null +++ b/ansible_collections/arista/cvp/molecule/cv_device_v3/test_apply_detach_configlet.yml @@ -0,0 +1,95 @@ +--- +- name: Test cv_device_v3 + hosts: CloudVision + connection: local + gather_facts: no + vars: + DEVICE_NAME: s1-leaf1 + + CVP_CONFIGLETS: + configlet1: '! This is first configlet' + configlet2: '! This is second configlet' + + CVP_DEVICES_APPLY_CONFIGLET: + - fqdn: "{{DEVICE_NAME}}" + parentContainerName: "{{CV_FACTS_V3_RESULT.data.cvp_devices[0].parentContainerName}}" + configlets: + - 'configlet1' + - 'configlet2' + + CVP_DEVICES_DETACH_CONFIGLET: + - fqdn: "{{DEVICE_NAME}}" + parentContainerName: "{{CV_FACTS_V3_RESULT.data.cvp_devices[0].parentContainerName}}" + configlets: "{{CV_FACTS_V3_RESULT.data.cvp_devices[0].configlets}}" + + tasks: + - name: Collect devices facts from {{inventory_hostname}} + arista.cvp.cv_facts_v3: + facts: + - devices + regexp_filter: "{{DEVICE_NAME}}" + register: CV_FACTS_V3_RESULT + + - name: "Push config" + arista.cvp.cv_configlet_v3: + configlets: "{{CVP_CONFIGLETS}}" + state: present + + - name: "Apply configlet on {{inventory_hostname}}" + arista.cvp.cv_device_v3: + devices: '{{CVP_DEVICES_APPLY_CONFIGLET}}' + state: present + register: CV_DEVICE_V3_RESULT + + - name: "Check apply_configlet with apply_mode loose" + assert: + that: + - CV_DEVICE_V3_RESULT.changed == true + - CV_DEVICE_V3_RESULT.configlets_attached.changed == true + - CV_DEVICE_V3_RESULT.configlets_attached.configlets_attached_count == 2 + - CV_DEVICE_V3_RESULT.configlets_attached.configlets_attached_list == ["s1-leaf1_configlet_attached"] + - CV_DEVICE_V3_RESULT.configlets_attached.success == true + - CV_DEVICE_V3_RESULT.configlets_attached.taskIds != [] + + - name: "Apply same configlet again on {{inventory_hostname}}" + arista.cvp.cv_device_v3: + devices: '{{CVP_DEVICES_APPLY_CONFIGLET}}' + state: present + register: CV_DEVICE_V3_RESULT + + - name: "Check apply_configlet with same configlets" + assert: + that: + - CV_DEVICE_V3_RESULT.changed == false + - CV_DEVICE_V3_RESULT.configlets_attached.changed == false + - CV_DEVICE_V3_RESULT.configlets_attached.configlets_attached_count == 0 + - CV_DEVICE_V3_RESULT.configlets_attached.configlets_attached_list == [] + - CV_DEVICE_V3_RESULT.configlets_attached.success == false + - CV_DEVICE_V3_RESULT.configlets_attached.taskIds == [] + + - name: "Detach configlet from {{inventory_hostname}}" + arista.cvp.cv_device_v3: + devices: '{{CVP_DEVICES_DETACH_CONFIGLET}}' + state: present + apply_mode: strict + register: CV_DEVICE_V3_RESULT + + - name: Execute Task for detach configlet + arista.cvp.cv_task_v3: + tasks: + - "{{CV_DEVICE_V3_RESULT.taskIds[0]}}" + + - name: "Check detach_configlet with apply_mode strict" + assert: + that: + - CV_DEVICE_V3_RESULT.changed == true + - CV_DEVICE_V3_RESULT.configlets_detached.changed == true + - CV_DEVICE_V3_RESULT.configlets_detached.configlets_detached_count == 2 + - CV_DEVICE_V3_RESULT.configlets_detached.configlets_detached_list == ["s1-leaf1_configlet_removed - configlet1 - configlet2"] + - CV_DEVICE_V3_RESULT.configlets_detached.success == true + - CV_DEVICE_V3_RESULT.configlets_detached.taskIds != [] + + - name: "Delete config" + arista.cvp.cv_configlet_v3: + configlets: "{{CVP_CONFIGLETS}}" + state: absent diff --git a/ansible_collections/arista/cvp/molecule/cv_device_v3/test_decommission_factory_reset_provisioning_reset.yml b/ansible_collections/arista/cvp/molecule/cv_device_v3/test_decommission_factory_reset_provisioning_reset.yml new file mode 100644 index 000000000..45478ea61 --- /dev/null +++ b/ansible_collections/arista/cvp/molecule/cv_device_v3/test_decommission_factory_reset_provisioning_reset.yml @@ -0,0 +1,139 @@ +--- +- name: Test cv_device_v3 + hosts: CloudVision + connection: local + gather_facts: no + vars: + DEVICE_NAME: s1-leaf2 + + CVP_DEVICES_STATE_ABSENT: + - fqdn: "{{DEVICE_NAME}}" + parentContainerName: "" + + CVP_DEVICES_FACT0RY_RESET: + - fqdn: "{{DEVICE_NAME}}" + parentContainerName: "" + + CVP_DEVICES_PROVISIONING_RESET: + - fqdn: "{{DEVICE_NAME}}" + parentContainerName: "" + + CVP_DEVICES_VALIDATE_CONFIG: + - device_name: "{{DEVICE_NAME}}" + search_type: serialNumber + cvp_configlets: "{{CV_FACTS_V3_RESULT.data.cvp_devices[0].configlets}}" + + CVP_DEVICES_DEPLOY: + - fqdn: "{{DEVICE_NAME}}" + parentContainerName: "{{CV_FACTS_V3_RESULT.data.cvp_devices[0].parentContainerName}}" + configlets: "{{CV_FACTS_V3_RESULT.data.cvp_devices[0].configlets}}" + + tasks: + ###################################### + ## STATE PROVISIONING RESET ## + ###################################### + - name: Collect devices facts from {{inventory_hostname}} + arista.cvp.cv_facts_v3: + facts: + - devices + regexp_filter: "{{DEVICE_NAME}}" + register: CV_FACTS_V3_RESULT + + - name: Run CV_DEVICE_V3 With State Provisioning Reset + arista.cvp.cv_device_v3: + devices: '{{CVP_DEVICES_PROVISIONING_RESET}}' + state: provisioning_reset + register: PROVISIONING_RESET_RESULT + + # if we try to delete the same device again(already in undefined container), it does not raise any error and gives the same result + + - name: check provisioning reset + assert: + that: + - PROVISIONING_RESET_RESULT.devices_removed.changed == true + - PROVISIONING_RESET_RESULT.devices_removed.devices_removed_count == 1 + - PROVISIONING_RESET_RESULT.devices_removed. devices_removed_list == ['s1-leaf2_delete'] + - PROVISIONING_RESET_RESULT.devices_removed.success == true + - PROVISIONING_RESET_RESULT.devices_removed.taskIds is defined + - PROVISIONING_RESET_RESULT.failed == false + - PROVISIONING_RESET_RESULT.success == true + + - name: Validate configurations + arista.cvp.cv_validate_v3: + devices: "{{CVP_DEVICES_VALIDATE_CONFIG}}" + validate_mode: stop_on_error + register: CVP_DEVICES_RESULTS + + - name: "Deploy device on {{inventory_hostname}}" + arista.cvp.cv_device_v3: + devices: '{{CVP_DEVICES_DEPLOY}}' + state: present + register: CV_DEVICE_V3_RESULT + + - name: Execute Task for deploy_Device + arista.cvp.cv_task_v3: + tasks: + - "{{CV_DEVICE_V3_RESULT.devices_deployed.taskIds[0]}}" + when: CVP_DEVICES_RESULTS.success is true + + - name: Pause for 20 seconds to Execute Task + ansible.builtin.pause: + seconds: 20 + + ###################################### + ## STATE FACTORY RESET ## + ###################################### +# XXX: This test will fail with cEOS devices. Uncomment if running on vEOS devices +# - name: Run CV_DEVICE_V3 With State Factory reset +# arista.cvp.cv_device_v3: +# devices: '{{CVP_DEVICES_FACT0RY_RESET}}' +# state: factory_reset +# register: FACTORY_RESET_RESULT +# +# # it does not move device to undefined container, just creates a task on CVP +# +# - name: Check State Factory reset +# assert: +# that: +# - FACTORY_RESET_RESULT.devices_reset.changed == true +# - FACTORY_RESET_RESULT.devices_reset.devices_reset_count == 1 +# - FACTORY_RESET_RESULT.devices_reset.devices_reset_list == ['s1-leaf1_reset'] +# - FACTORY_RESET_RESULT.devices_reset.success == true +# - FACTORY_RESET_RESULT.devices_reset.taskIds is defined +# - FACTORY_RESET_RESULT.failed == false +# - FACTORY_RESET_RESULT.success == true +# +# - name: Execute Task for deploy_Device +# arista.cvp.cv_task_v3: +# tasks: +# - "{{FACTORY_RESET_RESULT.taskIds[0]}}" +# state: cancelled + + ###################################### + ## STATE ABSENT (DECOMMISSION) ## + ###################################### + - name: Run CV_DEVICE_V3 With State Absent + arista.cvp.cv_device_v3: + devices: '{{CVP_DEVICES_STATE_ABSENT}}' + state: absent + register: DECOMMISSION_DEVICE + - assert: + that: + - DECOMMISSION_DEVICE.devices_decommissioned.changed == true + - DECOMMISSION_DEVICE.devices_decommissioned.devices_decommissioned_count == 1 + - DECOMMISSION_DEVICE.devices_decommissioned.devices_decommissioned_list == ['s1-leaf2_delete'] + - DECOMMISSION_DEVICE.devices_decommissioned.success == true + - DECOMMISSION_DEVICE.devices_decommissioned.taskIds == [] + - DECOMMISSION_DEVICE.failed == false + + - name: Run CV_DEVICE_V3 With State Absent # when device does not exist in CVP + arista.cvp.cv_device_v3: + devices: '{{CVP_DEVICES_STATE_ABSENT}}' + state: absent + ignore_errors: yes + register: DECOMMISSION_DEVICE_ABSENT + - assert: + that: + - DECOMMISSION_DEVICE_ABSENT.changed == false + - DECOMMISSION_DEVICE_ABSENT.failed == true + - DECOMMISSION_DEVICE_ABSENT.msg == "Error - the following devices do not exist in CVP ['s1-leaf2'] but are defined in the playbook. Make sure that the devices are provisioned and defined with the full fqdn name (including the domain name) if needed." diff --git a/ansible_collections/arista/cvp/molecule/cv_device_v3/test_move_and_deploy_device.yml b/ansible_collections/arista/cvp/molecule/cv_device_v3/test_move_and_deploy_device.yml new file mode 100644 index 000000000..19e2e8c33 --- /dev/null +++ b/ansible_collections/arista/cvp/molecule/cv_device_v3/test_move_and_deploy_device.yml @@ -0,0 +1,160 @@ +--- +- name: Test cv_device_v3 + hosts: CloudVision + connection: local + gather_facts: no + vars: + ansible_command_timeout: 1200 + ansible_connect_timeout: 600 + + DEVICE_NAME: s1-leaf1 + + CONTAINER: + Test_Leaf: + parentContainerName: Tenant + + CVP_DEVICES_MOVE_DEVICE: + - fqdn: "{{DEVICE_NAME}}" + parentContainerName: "Test_Leaf" + + CVP_DEVICES_PARENT_CONTAINER_NONE: + - fqdn: "{{DEVICE_NAME}}" + parentContainerName: None + + CVP_DEVICES_PROVISIONING_RESET: + - fqdn: "{{DEVICE_NAME}}" + parentContainerName: "Test_Leaf" + + CVP_DEVICES_APPLY_CONFIGLET: + - fqdn: "{{DEVICE_NAME}}" + parentContainerName: "Undefined" + configlets: "{{CV_FACTS_V3_RESULT.data.cvp_devices[0].configlets}}" + + CVP_DEVICES_VALIDATE_CONFIG: + - device_name: "{{DEVICE_NAME}}" + search_type: serialNumber + cvp_configlets: "{{CV_FACTS_V3_RESULT.data.cvp_devices[0].configlets}}" + + CVP_DEVICES_DEPLOY: + - fqdn: "{{DEVICE_NAME}}" # device must be in undefined container + parentContainerName: "{{CV_FACTS_V3_RESULT.data.cvp_devices[0].parentContainerName}}" + configlets: "{{CV_FACTS_V3_RESULT.data.cvp_devices[0].configlets}}" + + CVP_DEVICES_DETACH_CONFIGLET: + - fqdn: "{{DEVICE_NAME}}" + parentContainerName: "{{CV_FACTS_V3_RESULT.data.cvp_devices[0].parentContainerName}}" + + tasks: + # Creating a container + - name: Build Container On {{inventory_hostname}} + arista.cvp.cv_container_v3: + topology: '{{CONTAINER}}' + + - name: Collect devices facts from {{inventory_hostname}} + arista.cvp.cv_facts_v3: + facts: + - devices + regexp_filter: "{{DEVICE_NAME}}" + register: CV_FACTS_V3_RESULT + + - name: Run CV_DEVICE_V3 To Move Device + arista.cvp.cv_device_v3: + devices: '{{CVP_DEVICES_MOVE_DEVICE}}' + state: present + register: MOVE_DEVICE_RUN + + - name: Pause for 10 seconds to Execute Task + ansible.builtin.pause: + seconds: 10 + + - name: Execute Task for deploy_Device + arista.cvp.cv_task_v3: + tasks: "{{MOVE_DEVICE_RUN.taskIds}}" + + - name: Check Move Device + assert: + that: + - "MOVE_DEVICE_RUN.devices_moved.changed == true" + - "MOVE_DEVICE_RUN.devices_moved.devices_moved_count == 1" + - "MOVE_DEVICE_RUN.devices_moved.devices_moved_list == ['s1-leaf1_to_Test_Leaf']" + - "MOVE_DEVICE_RUN.devices_moved.success == true" + - "MOVE_DEVICE_RUN.failed == false" + + - name: Run CV_DEVICE_V3 To Move Device With Parent Container None + arista.cvp.cv_device_v3: + devices: '{{CVP_DEVICES_PARENT_CONTAINER_NONE}}' + state: present + ignore_errors: yes + register: MOVE_DEVICE_NONE + + - name: Negative Test Check Move Device With Parent Container None + assert: + that: + - MOVE_DEVICE_NONE.msg == "The target container 'None' for the device 's1-leaf1' does not exist on CVP." + - MOVE_DEVICE_NONE.changed == false + - MOVE_DEVICE_NONE.failed == true + + - name: Run CV_DEVICE_V3 To Move Device With Parent Container Same + arista.cvp.cv_device_v3: + devices: '{{CVP_DEVICES_MOVE_DEVICE}}' + state: present + ignore_errors: yes + register: MOVE_DEVICE + + - name: Negative Test Check Move Device With Same Parent Container + assert: + that: + - MOVE_DEVICE.devices_moved.changed == false + - MOVE_DEVICE.devices_moved.devices_moved_count == 0 + - MOVE_DEVICE.devices_moved.devices_moved_list == [] + - MOVE_DEVICE.devices_moved.success == false + - MOVE_DEVICE.failed == false + - MOVE_DEVICE.taskIds: [] + + ################################ + # DEPLOY DEVICE ## + ################################ + + # moving device to undefined container + - name: Run CV_DEVICE_V3 With State Provisioning Reset + arista.cvp.cv_device_v3: + devices: '{{CVP_DEVICES_PROVISIONING_RESET}}' + state: provisioning_reset + register: PROVISIONING_RESET_RESULT + + - name: Pause for 10 seconds to Execute Task + ansible.builtin.pause: + seconds: 10 + + - name: Validate configurations + arista.cvp.cv_validate_v3: + devices: "{{CVP_DEVICES_VALIDATE_CONFIG}}" + validate_mode: stop_on_error + register: CVP_DEVICES_RESULTS + + - name: "Deploy device on {{inventory_hostname}}" + arista.cvp.cv_device_v3: + devices: '{{CVP_DEVICES_DEPLOY}}' + state: present + register: CV_DEVICE_V3_RESULT + + - name: "Check deploy_device" + assert: + that: + - CV_DEVICE_V3_RESULT.changed == true + - CV_DEVICE_V3_RESULT.devices_deployed.changed == true + - CV_DEVICE_V3_RESULT.devices_deployed.devices_deployed_count == 1 + - CV_DEVICE_V3_RESULT.devices_deployed.devices_deployed_list == ["s1-leaf1_deployed"] + - CV_DEVICE_V3_RESULT.devices_deployed.success == true + - CV_DEVICE_V3_RESULT.devices_deployed.taskIds != [] + + - name: Execute Task for deploy_Device + arista.cvp.cv_task_v3: + tasks: + - "{{CV_DEVICE_V3_RESULT.devices_deployed.taskIds[0]}}" + when: CVP_DEVICES_RESULTS.success is true + + - name: Remove Container + arista.cvp.cv_container_v3: + topology: '{{CONTAINER}}' + state: absent diff --git a/ansible_collections/arista/cvp/plugins/module_utils/device_tools.py b/ansible_collections/arista/cvp/plugins/module_utils/device_tools.py index 709814d1f..b3d9718e6 100644 --- a/ansible_collections/arista/cvp/plugins/module_utils/device_tools.py +++ b/ansible_collections/arista/cvp/plugins/module_utils/device_tools.py @@ -619,7 +619,7 @@ def __check_devices_exist(self, user_inventory: DeviceInventory): ) if list_non_existing_devices is not None and len(list_non_existing_devices) > 0: error_message = "Error - the following devices do not exist in CVP {0} but are defined in the playbook. \ - \nMake sure that the devices are provisioned and defined with the full fqdn name \ + Make sure that the devices are provisioned and defined with the full fqdn name \ (including the domain name) if needed.".format( str(list_non_existing_devices) ) @@ -1588,6 +1588,7 @@ def apply_bundle(self, user_inventory: DeviceInventory): result_data.changed = True result_data.success = True result_data.taskIds = resp["data"][Api.task.TASK_IDS] + result_data.add_entry(f"{device.image_bundle} apply to {device.fqdn}") results.append(result_data) @@ -1691,6 +1692,7 @@ def detach_bundle(self, user_inventory: DeviceInventory): result_data.changed = True result_data.success = True result_data.taskIds = resp["data"][Api.task.TASK_IDS] + result_data.add_entry(f"{device.image_bundle} detach from {device.fqdn}") results.append(result_data) @@ -1814,16 +1816,14 @@ def apply_configlets(self, user_inventory: DeviceInventory): result_data.changed = True result_data.success = True result_data.taskIds = resp["data"][Api.task.TASK_IDS] - result_data.add_entry( - "{0} adds {1}".format(device.fqdn, *device.configlets) - ) + for configlet in device.configlets: + result_data.add_entry( + "{0} adds {1}".format(device.fqdn, configlet) + ) MODULE_LOGGER.debug("CVP response is: %s", str(resp)) MODULE_LOGGER.info( "Reponse data is: %s", str(result_data.results) ) - result_data.add_entry( - "{0} to {1}".format(device.fqdn, *device.container) - ) else: result_data.name = result_data.name + " - nothing attached" results.append(result_data) @@ -1898,21 +1898,19 @@ def detach_configlets(self, user_inventory: DeviceInventory): str(catch_error), ) self.__ansible.fail_json( - msg="Error detaching configlets from device " - + device.fqdn - + ": " - + catch_error + msg=f"Error detaching configlets from device {device.fqdn}: {catch_error}" ) else: if resp["data"]["status"] == "success": result_data.changed = True result_data.success = True result_data.taskIds = resp["data"][Api.task.TASK_IDS] - result_data.add_entry( - "{} removes {}".format( - device.fqdn, *device.configlets + for configlet in configlets_to_remove: + result_data.add_entry( + "{0} removes {1}".format( + device.fqdn, configlet + ) ) - ) else: result_data.name = result_data.name + " - nothing detached" results.append(result_data) @@ -2054,13 +2052,11 @@ def deploy_device(self, user_inventory: DeviceInventory): ) except CvpApiError as error: self.__ansible.fail_json( - msg="Error to deploy device {} to container {}".format( - device.fqdn, *device.container - ) + msg=f"Error to deploy device {device.fqdn} to container {device.container}" ) MODULE_LOGGER.critical( - "Error deploying device {} : {}".format( - device.fqdn, *error + "Error deploying device {0} : {1}".format( + device.fqdn, error ) ) else: @@ -2209,9 +2205,7 @@ def reset_device(self, user_inventory: DeviceInventory): result_data.changed = True result_data.success = True result_data.taskIds = resp["data"][Api.task.TASK_IDS] - result_data.add_entry( - "{} resets {}".format(device.fqdn, *device.configlets) - ) + result_data.add_entry(f"{device.fqdn} resets {device.configlets}") results.append(result_data) return results