From 0edab58f071e5ddba0473c663a25d3d9ad2224cf Mon Sep 17 00:00:00 2001 From: przsus <101723670+przsus@users.noreply.github.com> Date: Tue, 22 Oct 2024 09:24:05 +0200 Subject: [PATCH] fixes for cluster configuration --- .gitignore | 1 + galaxy.yml | 2 +- .../tests/test_module_cluster_management.yml | 9 +++- plugins/module_utils/vmanage_module.py | 18 +------ plugins/modules/cluster_management.py | 50 ++++++++++++------- roles/cluster/tasks/main.yml | 8 ++- roles/health_checks/tasks/main.yml | 1 + roles/onboarding_controllers/tasks/main.yml | 4 +- 8 files changed, 51 insertions(+), 42 deletions(-) diff --git a/.gitignore b/.gitignore index 4bfb996..f00e1e7 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ playbooks/tests/response* playbooks/tests/backup playbooks/tests/templates playbooks/tests/templates_export +.idea diff --git a/galaxy.yml b/galaxy.yml index a74d8e4..fd82918 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ namespace: cisco name: catalystwan -version: 0.2.2 +version: 0.2.3 readme: README.md authors: - Arkadiusz Cichon diff --git a/playbooks/tests/test_module_cluster_management.yml b/playbooks/tests/test_module_cluster_management.yml index 9d9f876..b6f2d0c 100644 --- a/playbooks/tests/test_module_cluster_management.yml +++ b/playbooks/tests/test_module_cluster_management.yml @@ -12,7 +12,8 @@ cisco.catalystwan.cluster_management: wait_until_configured_seconds: 300 vmanage_id: "0" - device_ip: "{{ (vmanage_instances | first).cluster_private_ip }}" + system_ip: "{{ (vmanage_instances | first).system_ip }}" + cluster_ip: "{{ (vmanage_instances | first).cluster_private_ip }}" username: "{{ (vmanage_instances | first).admin_username }}" password: "{{ (vmanage_instances | first).admin_password }}" persona: "{{ (vmanage_instances | first).persona }}" @@ -27,7 +28,8 @@ - name: Add remaining instances to cluster cisco.catalystwan.cluster_management: wait_until_configured_seconds: 1800 - device_ip: "{{ vmanage.cluster_private_ip }}" + system_ip: "{{ vmanage.system_ip }}" + cluster_ip: "{{ vmanage.cluster_private_ip }}" username: "{{ vmanage.admin_username }}" password: "{{ vmanage.admin_password }}" gen_csr: false @@ -42,3 +44,6 @@ loop: "{{ vmanage_instances[1:] }}" loop_control: loop_var: vmanage + when: vmanage.cluster_private_ip is defined + retries: 180 + delay: 10 diff --git a/plugins/module_utils/vmanage_module.py b/plugins/module_utils/vmanage_module.py index 03eaeb8..319af1b 100644 --- a/plugins/module_utils/vmanage_module.py +++ b/plugins/module_utils/vmanage_module.py @@ -176,8 +176,6 @@ def send_request_safely( send_func: Callable, response_key: str = None, fail_on_exception: bool = True, - num_retries: int = 0, - retry_interval_seconds: int = 1, **kwargs: Any, ) -> None: """ @@ -196,20 +194,8 @@ def send_request_safely( result.response[f"{response_key}"] = response result.changed = True - except (ManagerHTTPError, ManagerRequestException) as ex: - if num_retries: - time.sleep(retry_interval_seconds) - self.send_request_safely( - result, - action_name, - send_func, - response_key, - fail_on_exception, - num_retries - 1, - retry_interval_seconds, - **kwargs, - ) - elif fail_on_exception: + except ManagerHTTPError as ex: + if fail_on_exception: self.fail_json( msg=f"Could not perform '{action_name}' action.\nManager error: {ex.info}", exception=traceback.format_exc(), diff --git a/plugins/modules/cluster_management.py b/plugins/modules/cluster_management.py index fdde065..8766e76 100644 --- a/plugins/modules/cluster_management.py +++ b/plugins/modules/cluster_management.py @@ -21,9 +21,13 @@ description: - Optional ID of vManage to edit. Don't set when adding new vManage instances to cluster. type: str - device_ip: + system_ip: description: - - Added/edited device IP address. + - Device system IP address. + type: str + cluster_ip: + description: + - Added/edited device cluster IP address. type: str username: description: @@ -79,7 +83,8 @@ cisco.catalystwan.cluster_management: wait_until_configured_seconds: 300 vmanage_id: "0" - device_ip: "1.1.1.1" + system_ip: "100.100.100.100" + cluster_ip: "1.1.1.1" username: "username" password: "password" # pragma: allowlist secret persona: "COMPUTE_AND_DATA" @@ -91,7 +96,8 @@ - name: "Add vManage to cluster" cisco.catalystwan.cluster_management: wait_until_configured_seconds: 300 - device_ip: "2.2.2.2" + system_ip: "100.100.100.100" + cluster_ip: "2.2.2.2" username: "username" password: "password" # pragma: allowlist secret gen_csr: false @@ -102,9 +108,9 @@ """ import time -from typing import Optional +from typing import List, Optional -from catalystwan.endpoints.cluster_management import VManageSetup +from catalystwan.endpoints.cluster_management import ConnectedDevice, VManageSetup from catalystwan.exceptions import ManagerRequestException from ..module_utils.result import ModuleResult @@ -127,12 +133,19 @@ def get_connected_devices(module, device_ip): return None -def wait_for_connected_devices(module, device_ip, timeout) -> Optional[str]: +def is_device_connected_to_cluster(module, system_ip, cluster_ip): + connected_devices: List[ConnectedDevice] = get_connected_devices(module, cluster_ip) + for device in connected_devices: + if device["device_id"] == system_ip: + return True + return False + + +def wait_for_connected_device(module, system_ip, cluster_ip, timeout) -> Optional[str]: start = time.time() while True: try: - connected_devices = get_connected_devices(module, device_ip) - if connected_devices: + if is_device_connected_to_cluster(module, system_ip, cluster_ip): return None if (time.time() - start) > timeout: return f"reached timeout of {timeout}s" @@ -147,7 +160,8 @@ def run_module(): module_args = dict( wait_until_configured_seconds=dict(type="int", default=0), vmanage_id=dict(type=str), - device_ip=dict(type=str, required=True), + system_ip=dict(type=str, required=True), + cluster_ip=dict(type=str, required=True), username=dict(type=str, required=True), password=dict(type=str, no_log=True, required=True), gen_csr=dict(type=bool, aliases=["genCSR"]), @@ -167,20 +181,21 @@ def run_module(): ) module = AnsibleCatalystwanModule(argument_spec=module_args, session_reconnect_retries=180) + module.session.request_timeout = 60 result = ModuleResult() vmanage_id = module.params.get("vmanage_id") - device_ip = module.params.get("device_ip") + system_ip = module.params.get("system_ip") + cluster_ip = module.params.get("cluster_ip") - connected_devices = get_connected_devices(module, device_ip) - if connected_devices: + if is_device_connected_to_cluster(module, system_ip, cluster_ip): result.changed = False - result.msg = f"Device {device_ip} already configured" + result.msg = f"Device {cluster_ip} already configured" module.exit_json(**result.model_dump(mode="json")) payload = VManageSetup( vmanage_id=vmanage_id, - device_ip=device_ip, + device_ip=cluster_ip, username=module.params.get("username"), password=module.params.get("password"), persona=module.params.get("persona"), @@ -196,21 +211,18 @@ def run_module(): response_key="edit_vmanage", ) else: - module.session.request_timeout = 60 module.send_request_safely( result, action_name="Cluster Management: Add vManage", send_func=module.session.endpoints.cluster_management.add_vmanage, payload=payload, response_key="add_vmanage", - num_retries=30, - retry_interval_seconds=10, ) if result.changed: wait_until_configured_seconds = module.params.get("wait_until_configured_seconds") if wait_until_configured_seconds: - error_msg = wait_for_connected_devices(module, device_ip, wait_until_configured_seconds) + error_msg = wait_for_connected_device(module, system_ip, cluster_ip, wait_until_configured_seconds) if error_msg: module.fail_json(msg=f"Error during vManage configuration: {error_msg}") result.msg = "Successfully updated requested vManage configuration." diff --git a/roles/cluster/tasks/main.yml b/roles/cluster/tasks/main.yml index 1aa34fd..cfe417c 100644 --- a/roles/cluster/tasks/main.yml +++ b/roles/cluster/tasks/main.yml @@ -10,7 +10,8 @@ cisco.catalystwan.cluster_management: wait_until_configured_seconds: 300 vmanage_id: "0" - device_ip: "{{ (vmanage_instances | first).cluster_private_ip }}" + system_ip: "{{ (vmanage_instances | first).system_ip }}" + cluster_ip: "{{ (vmanage_instances | first).cluster_private_ip }}" username: "{{ (vmanage_instances | first).admin_username }}" password: "{{ (vmanage_instances | first).admin_password }}" persona: "{{ (vmanage_instances | first).persona }}" @@ -23,7 +24,8 @@ - name: Add remaining instances to cluster cisco.catalystwan.cluster_management: wait_until_configured_seconds: 1800 - device_ip: "{{ vmanage.cluster_private_ip }}" + system_ip: "{{ vmanage.system_ip }}" + cluster_ip: "{{ vmanage.cluster_private_ip }}" username: "{{ vmanage.admin_username }}" password: "{{ vmanage.admin_password }}" gen_csr: false @@ -37,3 +39,5 @@ loop_control: loop_var: vmanage when: vmanage.cluster_private_ip is defined + retries: 180 + delay: 10 diff --git a/roles/health_checks/tasks/main.yml b/roles/health_checks/tasks/main.yml index 65d1628..90dbd60 100644 --- a/roles/health_checks/tasks/main.yml +++ b/roles/health_checks/tasks/main.yml @@ -13,6 +13,7 @@ url: "{{ (vmanage_instances | first).mgmt_public_ip }}" username: "{{ (vmanage_instances | first).admin_username }}" password: "{{ (vmanage_instances | first).admin_password }}" + retries: 20 - name: "Health check: orchestrator connections - verifies if all have state up" cisco.catalystwan.health_checks: diff --git a/roles/onboarding_controllers/tasks/main.yml b/roles/onboarding_controllers/tasks/main.yml index 6024f78..cbfb8ab 100644 --- a/roles/onboarding_controllers/tasks/main.yml +++ b/roles/onboarding_controllers/tasks/main.yml @@ -21,7 +21,7 @@ - name: Add vSmart devices cisco.catalystwan.devices_controllers: - device_ip: "{{ device_item.transport_public_ip }}" + device_ip: "{{ device_item.mgmt_public_ip }}" username: "{{ device_item.admin_username }}" password: "{{ device_item.admin_password }}" hostname: "{{ device_item.hostname }}" @@ -39,7 +39,7 @@ - name: Add vBond devices cisco.catalystwan.devices_controllers: - device_ip: "{{ device_item.transport_public_ip }}" + device_ip: "{{ device_item.mgmt_public_ip }}" username: "{{ device_item.admin_username }}" password: "{{ device_item.admin_password }}" hostname: "{{ device_item.hostname }}"