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..e4aef55 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,6 +1,6 @@ namespace: cisco name: catalystwan -version: 0.2.2 +version: 0.3.0 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/pyproject.toml b/pyproject.toml index e2f4ed0..efa396d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ readme = "README.md" python = "^3.10" ansible-core = "2.16.6" ansible = "9.4.0" -catalystwan = "v0.35.5dev0" +catalystwan = "v0.35.5dev3" flake8 = "5.0.4" black = "24.3.0" pre-commit = "3.7" diff --git a/requirements.txt b/requirements.txt index ad231e6..be3cf01 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,7 +7,7 @@ args==0.1.0 ; python_version >= "3.10" and python_version < "4.0" attrs==21.4.0 ; python_version >= "3.10" and python_version < "4.0" black==24.3.0 ; python_version >= "3.10" and python_version < "4.0" bracex==2.5 ; python_version >= "3.10" and python_version < "4.0" and platform_system != "Windows" -catalystwan==0.34.0.dev5 ; python_version >= "3.10" and python_version < "4.0" +catalystwan==0.35.5dev3 ; python_version >= "3.10" and python_version < "4.0" certifi==2024.7.4 ; python_version >= "3.10" and python_version < "4.0" cffi==1.17.0 ; python_version >= "3.10" and python_version < "4.0" and platform_python_implementation != "PyPy" cfgv==3.4.0 ; python_version >= "3.10" and python_version < "4.0" diff --git a/roles/administration_settings/tasks/main.yml b/roles/administration_settings/tasks/main.yml index 814864b..fa66a3d 100644 --- a/roles/administration_settings/tasks/main.yml +++ b/roles/administration_settings/tasks/main.yml @@ -40,3 +40,5 @@ loop_control: loop_var: device_item label: "hostname: {{ device_item.hostname }}, device_ip: {{ device_item.system_ip }}" + retries: 12 + delay: 10 diff --git a/roles/cluster/tasks/main.yml b/roles/cluster/tasks/main.yml index 1aa34fd..1a9c13f 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 }}" @@ -19,11 +20,14 @@ url: "{{ (vmanage_instances | first).mgmt_public_ip }}" username: "{{ (vmanage_instances | first).admin_username }}" password: "{{ (vmanage_instances | first).admin_password }}" + retries: 12 + delay: 10 - 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 +41,5 @@ loop_control: loop_var: vmanage when: vmanage.cluster_private_ip is defined + retries: 36 + 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: