From 0cb70cea5d90beebe33be83ee14b18c6d44e4c27 Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Tue, 23 Jan 2024 15:26:32 +0530 Subject: [PATCH 01/16] =?UTF-8?q?Handle=20provisioning=20of=20device=20if?= =?UTF-8?q?=20it=E2=80=99s=20not=20in=20managed=20state=20for=20longer=20t?= =?UTF-8?q?ime,=20make=20output=20msg=20more=20readable,=20device=20creden?= =?UTF-8?q?tial=20update=20without=20giving=20each=20parameter=20etc.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/modules/inventory_intent.py | 106 ++++++++++++++++++++++------ plugins/modules/swim_intent.py | 22 +++--- 2 files changed, 98 insertions(+), 30 deletions(-) diff --git a/plugins/modules/inventory_intent.py b/plugins/modules/inventory_intent.py index c1c5431085..710d43e31d 100644 --- a/plugins/modules/inventory_intent.py +++ b/plugins/modules/inventory_intent.py @@ -96,8 +96,9 @@ type: str snmp_priv_protocol: description: Device's snmp Private Protocol. Required for Adding Network, Compute, Third Party Devices. + Must be given in playbook if you are updating the device credentails. type: str - default: "CISCOAES128" + default: "AES128" snmp_ro_community: description: Device's snmp ROCommunity. Required for Adding V2C Devices. type: str @@ -697,7 +698,7 @@ def validate_input(self): 'snmp_auth_protocol': {'default': "SHA", 'type': 'str'}, 'snmp_mode': {'default': "AUTHPRIV", 'type': 'str'}, 'snmp_priv_passphrase': {'type': 'str'}, - 'snmp_priv_protocol': {'default': "CISCOAES128", 'type': 'str'}, + 'snmp_priv_protocol': {'default': "AES128", 'type': 'str'}, 'snmp_ro_community': {'default': "public", 'type': 'str'}, 'snmp_rw_community': {'default': "private", 'type': 'str'}, 'snmp_retry': {'default': 3, 'type': 'int'}, @@ -979,11 +980,11 @@ def decrypt_and_read_csv(self, response, password): self.status = "failed" return self - snmp_protocol = self.config[0].get('snmp_priv_protocol', 'CISCOAES128') + snmp_protocol = self.config[0].get('snmp_priv_protocol', 'AES128') encryption_dict = { - 'CISCOAES128': 'pyzipper.WZ_AES128', - 'CISCOAES192': 'pyzipper.WZ_AES192', - 'CISCOAES256': 'pyzipper.WZ_AES' + 'AES128': 'pyzipper.WZ_AES128', + 'AES192': 'pyzipper.WZ_AES192', + 'AES256': 'pyzipper.WZ_AES' } try: encryption_method = encryption_dict.get(snmp_protocol) @@ -1158,13 +1159,11 @@ def resync_devices(self): # Code for triggers the resync operation using the retrieved device IDs and force sync parameter. device_ips = self.config[0].get("ip_address", []) + device_in_dnac = self.device_exists_in_dnac() - if not device_ips: - self.msg = "Cannot perform the Resync operation as device's {0} are not present inCisco Catalyst Center".format(str(device_ips)) - self.status = "success" - self.result['changed'] = False - self.log(self.msg) - return self + for device_ip in device_ips: + if device_ip not in device_in_dnac: + device_ips.remove(device_ip) ap_devices = self.get_ap_devices(device_ips) self.log("AP Devices from the playbook input are: {0}".format(str(ap_devices))) @@ -1174,6 +1173,14 @@ def resync_devices(self): device_ips.remove(ap_ip) self.log("Following devices {0} are AP, so can't perform resync operation.".format(str(ap_devices))) + if not device_ips: + self.msg = "Cannot perform the Resync operation as device's {0} are not present in Cisco Catalyst Center".format(str(device_ips)) + self.status = "success" + self.result['changed'] = False + self.result['response'] = self.msg + self.log(self.msg) + return self + device_ids = self.get_device_ids(device_ips) try: force_sync = self.config[0].get("force_sync", False) @@ -1199,6 +1206,8 @@ def resync_devices(self): self.status = "success" self.result['changed'] = True self.result['response'] = execution_details + self.log("Device Resynced Successfully and Resynced devices are :" + str(device_ips)) + self.msg = "Device " + str(device_ips) + " Resynced Successfully !!" break elif execution_details.get("isError"): self.status = "failed" @@ -1209,8 +1218,6 @@ def resync_devices(self): self.msg = "Device Resynced get failed." self.log(self.msg) break - self.log("Device Resynced Successfully and Resynced devices are :" + str(device_ips)) - msg = "Device " + str(device_ips) + " Resynced Successfully !!" except Exception as e: error_message = "Error while Resyncing device in Cisco DNA Center - {0}".format(str(e)) @@ -1296,6 +1303,8 @@ def reboot_access_points(self): self.status = "success" self.result['changed'] = True self.result['response'] = execution_details + self.log("AP Devices Rebooted Successfully and Rebooted devices are :" + str(device_ips)) + self.msg = "Device " + str(device_ips) + " Rebooted Successfully !!" break elif execution_details.get("isError"): self.status = "failed" @@ -1306,9 +1315,6 @@ def reboot_access_points(self): self.msg = "AP Device Rebooting get failed" break - self.log("AP Devices Rebooted Successfully and Rebooted devices are :" + str(device_ips)) - self.msg = "Device " + str(device_ips) + " Rebooted Successfully !!" - return self def handle_successful_provisioning(self, device_ip, execution_details, device_type): @@ -1473,6 +1479,8 @@ def provisioned_wired_device(self): for device_ip in device_ips: try: provision_wired_params['deviceManagementIpAddress'] = device_ip + count = 1 + managed_flag = True # Check till device comes into managed state while True: @@ -1485,6 +1493,14 @@ def provisioned_wired_device(self): and response.get("hostname") ): break + count = count + 1 + if count > 200: + managed_flag = False + break + + if not managed_flag: + self.log("Device {0} not coming to managed state so cannot perform provisioning operation".format(device_ip)) + continue response = self.dnac._exec( family="sda", @@ -1656,6 +1672,13 @@ def provisioned_wireless_devices(self, device_ips): provision_count, already_provision_count = 0, 0 device_type = "Wireless" + device_in_dnac = self.device_exists_in_dnac() + device_ips = self.config[0]['ip_address'] + + for device_ip in device_ips: + if device_ip not in device_in_dnac: + device_ips.remove(device_ip) + for device_ip in device_ips: try: # Collect the device parameters from the playbook to perform wireless provisioing @@ -2072,7 +2095,7 @@ def check_credential_update(self): 'password': device_data['cli_password'], 'enable_password': device_data['cli_enable_password'], 'snmp_username': device_data['snmpv3_user_name'], - 'snmp_auth_protocol': device_data['snmpv3_auth_type'] + 'snmp_auth_protocol': device_data['snmpv3_auth_type'], } config = self.config[0] @@ -2213,13 +2236,54 @@ def get_diff_merged(self, config): if credential_update: # Update Device details and credentails + device_uuids = self.get_device_ids(device_to_update) + password = "Testing@123" + payload_params = {"deviceUuids": device_uuids, "password": password, "operationEnum": "0"} + response = self.trigger_export_api(payload_params) + self.check_return_status() + csv_reader = self.decrypt_and_read_csv(response, password) + self.check_return_status() + device_data = next(csv_reader, None) + playbook_params = self.want.get("device_params") + + csv_data_dict = { + 'cli_transport': device_data['protocol'], + 'username': device_data['cli_username'], + 'password': device_data['cli_password'], + 'enable_password': device_data['cli_enable_password'], + } + + if device_data['snmp_version'] == '3': + csv_data_dict['snmp_username'] = device_data['snmpv3_user_name'] + if device_data['snmpv3_privacy_password']: + csv_data_dict['snmp_auth_passphrase'] = device_data['snmpv3_auth_password'] + csv_data_dict['snmp_priv_passphrase'] = device_data['snmpv3_privacy_password'] + + device_key_mapping = { + 'username': 'userName', + 'cli_transport': 'cliTransport', + 'password': 'password', + 'enable_password': 'enablePassword', + 'snmp_username': 'snmpUserName' + } + device_update_key_list = ["username", "password", "enable_password", "cli_transport", "snmp_username"] + + for key in device_update_key_list: + mapped_key = device_key_mapping[key] + + if playbook_params[mapped_key] is None: + + if playbook_params['snmpMode'] == "AUTHPRIV": + playbook_params['snmpAuthPassphrase'] = csv_data_dict['snmp_auth_passphrase'] + playbook_params['snmpPrivPassphrase'] = csv_data_dict['snmp_priv_passphrase'] + playbook_params[mapped_key] = csv_data_dict[key] + try: - self.mandatory_parameter().check_return_status() response = self.dnac._exec( family="devices", function='sync_devices', op_modifies=True, - params=self.want.get("device_params"), + params=playbook_params, ) self.log(str(response)) @@ -2430,7 +2494,7 @@ def get_diff_merged(self, config): else: self.msg = "Device Addition get failed" self.log(self.msg) - self.result['msg'] = msg + self.result['msg'] = self.msg break except Exception as e: diff --git a/plugins/modules/swim_intent.py b/plugins/modules/swim_intent.py index 0996440b70..4152fdbe15 100644 --- a/plugins/modules/swim_intent.py +++ b/plugins/modules/swim_intent.py @@ -855,10 +855,10 @@ def get_diff_import(self): import_function = 'import_software_image_via_url' else: import_params = dict( - isThirdParty=self.want.get("local_import_details").get("is_third_party"), - thirdPartyVendor=self.want.get("local_import_details").get("third_party_vendor"), - thirdPartyImageFamily=self.want.get("local_import_details").get("third_party_image_family"), - thirdPartyApplicationType=self.want.get("local_import_details").get("third_party_application_type"), + is_third_party=self.want.get("local_import_details").get("is_third_party"), + third_party_vendor=self.want.get("local_import_details").get("third_party_vendor"), + third_party_image_family=self.want.get("local_import_details").get("third_party_image_family"), + third_party_application_type=self.want.get("local_import_details").get("third_party_application_type"), file_path=self.want.get("local_import_details").get("file_path"), ) import_function = 'import_local_software_image' @@ -874,9 +874,11 @@ def get_diff_import(self): task_details = {} task_id = response.get("response").get("taskId") + while (True): task_details = self.get_task_details(task_id) name = image_name.split('/')[-1] + if task_details and \ ("completed successfully" in task_details.get("progress").lower()): self.result['changed'] = True @@ -887,7 +889,7 @@ def get_diff_import(self): break if task_details and task_details.get("isError"): - if "already exists" in task_details.get("failureReason"): + if "already exists" in task_details.get("failureReason", ""): self.msg = "SWIM Image {0} already exists in the Cisco DNA Center".format(name) self.result['msg'] = self.msg self.log(self.msg) @@ -896,8 +898,9 @@ def get_diff_import(self): break else: self.status = "failed" - self.msg = task_details.get("failureReason") - self.result[response] = task_details + self.msg = task_details.get("failureReason", "SWIM Image {0} seems to be invalid".format(image_name)) + self.log(self.msg) + self.result['response'] = self.msg return self self.result['response'] = task_details if task_details else response @@ -910,9 +913,10 @@ def get_diff_import(self): return self except Exception as e: - self.log("Import Image details are not given in the playbook") self.status = "failed" - self.result['changed'] = False + self.msg = "Import Image details are not given in the playbook or Import Image API not triggered successfully." + self.log(self.msg) + self.result['response'] = self.msg return self From b1ba85f60f38130c1d988cba6541cdb14b46b6e5 Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Tue, 23 Jan 2024 22:31:47 +0530 Subject: [PATCH 02/16] add dnac_log_level in documenation and examples in swim and inventory and address review comments --- plugins/modules/inventory_intent.py | 105 ++++++++++++++++++++-------- plugins/modules/swim_intent.py | 12 +++- 2 files changed, 85 insertions(+), 32 deletions(-) diff --git a/plugins/modules/inventory_intent.py b/plugins/modules/inventory_intent.py index 710d43e31d..b1f4de79a2 100644 --- a/plugins/modules/inventory_intent.py +++ b/plugins/modules/inventory_intent.py @@ -28,6 +28,10 @@ description: Set to True to verify the Cisco DNA Center config after applying the playbook config. type: bool default: False + dnac_log_level: + description: Log levels are used to categorize the logs based on their severity. + type: str + default: INFO state: description: The state of Cisco DNA Center after module completion. type: str @@ -269,6 +273,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged config: @@ -309,6 +314,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged config: @@ -339,6 +345,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged config: @@ -355,6 +362,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged config: @@ -375,6 +383,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged config: @@ -400,6 +409,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged config: @@ -440,6 +450,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged config: @@ -457,6 +468,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged config: @@ -483,6 +495,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged config: @@ -502,6 +515,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged config: @@ -524,6 +538,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged config: @@ -543,6 +558,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged config: @@ -562,6 +578,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged config: @@ -579,6 +596,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: merged config: @@ -596,6 +614,7 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" dnac_log: False + dnac_log_level: "{{dnac_log_level}}" state: deleted config: - ip_address: @@ -611,6 +630,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: False state: deleted config: @@ -1159,29 +1179,30 @@ def resync_devices(self): # Code for triggers the resync operation using the retrieved device IDs and force sync parameter. device_ips = self.config[0].get("ip_address", []) + input_device_ips = device_ips.copy() device_in_dnac = self.device_exists_in_dnac() - for device_ip in device_ips: + for device_ip in input_device_ips: if device_ip not in device_in_dnac: - device_ips.remove(device_ip) + input_device_ips.remove(device_ip) - ap_devices = self.get_ap_devices(device_ips) + ap_devices = self.get_ap_devices(input_device_ips) self.log("AP Devices from the playbook input are: {0}".format(str(ap_devices))) if ap_devices: for ap_ip in ap_devices: - device_ips.remove(ap_ip) + input_device_ips.remove(ap_ip) self.log("Following devices {0} are AP, so can't perform resync operation.".format(str(ap_devices))) - if not device_ips: - self.msg = "Cannot perform the Resync operation as device's {0} are not present in Cisco Catalyst Center".format(str(device_ips)) + if not input_device_ips: + self.msg = "Cannot perform the Resync operation as the device(s) with IP(s) {0} are not present in Cisco Catalyst Center".format(str(device_ips)) self.status = "success" self.result['changed'] = False self.result['response'] = self.msg - self.log(self.msg) + self.log(self.msg, "INFO") return self - device_ids = self.get_device_ids(device_ips) + device_ids = self.get_device_ids(input_device_ips) try: force_sync = self.config[0].get("force_sync", False) resync_param_dict = { @@ -1206,8 +1227,8 @@ def resync_devices(self): self.status = "success" self.result['changed'] = True self.result['response'] = execution_details - self.log("Device Resynced Successfully and Resynced devices are :" + str(device_ips)) - self.msg = "Device " + str(device_ips) + " Resynced Successfully !!" + self.log("Device Resynced Successfully and Resynced devices are :" + str(input_device_ips)) + self.msg = "Device " + str(input_device_ips) + " Resynced Successfully !!" break elif execution_details.get("isError"): self.status = "failed" @@ -1240,14 +1261,16 @@ def reboot_access_points(self): """ device_ips = self.config[0].get("ip_address", []) - if device_ips: - ap_devices = self.get_ap_devices(device_ips) + input_device_ips = device_ips.copy() + + if input_device_ips: + ap_devices = self.get_ap_devices(input_device_ips) self.log("AP Devices from the playbook input are : {0}".format(str(ap_devices))) - for device_ip in device_ips: + for device_ip in input_device_ips: if device_ip not in ap_devices: - device_ips.remove(device_ip) + input_device_ips.remove(device_ip) - if not device_ips: + if not input_device_ips: self.msg = "No AP Devices IP given in the playbook so can't perform reboot operation" self.status = "success" self.result['changed'] = False @@ -1257,7 +1280,7 @@ def reboot_access_points(self): # Get and store the apEthernetMacAddress of given devices ap_mac_address_list = [] - for device_ip in device_ips: + for device_ip in input_device_ips: response = self.dnac._exec( family="devices", function='get_device_list', @@ -1303,8 +1326,8 @@ def reboot_access_points(self): self.status = "success" self.result['changed'] = True self.result['response'] = execution_details - self.log("AP Devices Rebooted Successfully and Rebooted devices are :" + str(device_ips)) - self.msg = "Device " + str(device_ips) + " Rebooted Successfully !!" + self.log("AP Devices rebooted successfully. Rebooted devices: {0}".format(str(input_device_ips)), "INFO") + self.msg = "AP Device(s) {0} successfully rebooted!".format(str(input_device_ips)) break elif execution_details.get("isError"): self.status = "failed" @@ -1457,15 +1480,16 @@ def provisioned_wired_device(self): site_name = self.config[0]['provision_wired_device']['site_name'] device_in_dnac = self.device_exists_in_dnac() device_ips = self.config[0]['ip_address'] + input_device_ips = device_ips.copy() - for device_ip in device_ips: + for device_ip in input_device_ips: if device_ip not in device_in_dnac: - device_ips.remove(device_ip) + input_device_ips.remove(device_ip) device_type = "Wired" provision_count, already_provision_count = 0, 0 - if not site_name and not device_ips: + if not site_name and not input_device_ips: self.status = "failed" self.msg = "Site/Devices are required for Provisioning of Wired Devices." self.log(self.msg) @@ -1476,7 +1500,7 @@ def provisioned_wired_device(self): 'siteNameHierarchy': site_name } - for device_ip in device_ips: + for device_ip in input_device_ips: try: provision_wired_params['deviceManagementIpAddress'] = device_ip count = 1 @@ -1499,7 +1523,8 @@ def provisioned_wired_device(self): break if not managed_flag: - self.log("Device {0} not coming to managed state so cannot perform provisioning operation".format(device_ip)) + self.log("Device {0} is not transitioning to the managed state, so provisioning operation cannot be performed." + .format(device_ip), 'warning') continue response = self.dnac._exec( @@ -1674,24 +1699,42 @@ def provisioned_wireless_devices(self, device_ips): device_in_dnac = self.device_exists_in_dnac() device_ips = self.config[0]['ip_address'] + input_device_ips = device_ips.copy() - for device_ip in device_ips: + for device_ip in input_device_ips: if device_ip not in device_in_dnac: - device_ips.remove(device_ip) + input_device_ips.remove(device_ip) - for device_ip in device_ips: + for device_ip in input_device_ips: try: # Collect the device parameters from the playbook to perform wireless provisioing self.get_wireless_param(device_ip).check_return_status() provisioning_params = self.wireless_param + count = 1 + managed_flag = True # Check till device comes into managed state while True: response = self.get_device_response(device_ip) self.log("Device is in {0} state waiting for Managed State.".format(response['managementState'])) - if response['managementState'] == "Managed": + + if ( + response.get('managementState') == "Managed" + and response.get('collectionStatus') == "Managed" + and response.get("hostname") + ): break + count = count + 1 + if count > 200: + managed_flag = False + break + + if not managed_flag: + self.log("Device {0} is not transitioning to the managed state, so provisioning operation cannot be performed." + .format(device_ip), 'warning') + continue + # Now we have provisioning_param so we can do wireless provisioning response = self.dnac_apply['exec']( family="wireless", @@ -2238,10 +2281,10 @@ def get_diff_merged(self, config): # Update Device details and credentails device_uuids = self.get_device_ids(device_to_update) password = "Testing@123" - payload_params = {"deviceUuids": device_uuids, "password": password, "operationEnum": "0"} - response = self.trigger_export_api(payload_params) + export_payload = {"deviceUuids": device_uuids, "password": password, "operationEnum": "0"} + export_response = self.trigger_export_api(export_payload) self.check_return_status() - csv_reader = self.decrypt_and_read_csv(response, password) + csv_reader = self.decrypt_and_read_csv(export_response, password) self.check_return_status() device_data = next(csv_reader, None) playbook_params = self.want.get("device_params") @@ -2272,7 +2315,6 @@ def get_diff_merged(self, config): mapped_key = device_key_mapping[key] if playbook_params[mapped_key] is None: - if playbook_params['snmpMode'] == "AUTHPRIV": playbook_params['snmpAuthPassphrase'] = csv_data_dict['snmp_auth_passphrase'] playbook_params['snmpPrivPassphrase'] = csv_data_dict['snmp_priv_passphrase'] @@ -2862,6 +2904,7 @@ def main(): 'dnac_verify': {'type': 'bool', 'default': 'True'}, 'dnac_version': {'type': 'str', 'default': '2.2.3.3'}, 'dnac_debug': {'type': 'bool', 'default': False}, + 'dnac_log_level': {'type': 'str', 'default': 'INFO'}, 'dnac_log': {'type': 'bool', 'default': False}, 'validate_response_schema': {'type': 'bool', 'default': True}, 'config_verify': {'type': 'bool', "default": False}, diff --git a/plugins/modules/swim_intent.py b/plugins/modules/swim_intent.py index 4152fdbe15..cd3d523d71 100644 --- a/plugins/modules/swim_intent.py +++ b/plugins/modules/swim_intent.py @@ -30,6 +30,10 @@ Rishita Chowdhary (@rishitachowdhary) Abhishek Maheshwari (@abmahesh) options: + dnac_log_level: + description: Log levels are used to categorize the logs based on their severity. + type: str + default: INFO state: description: The state of DNAC after module completion. type: str @@ -230,6 +234,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: True config: - import_image_details: @@ -269,6 +274,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: True config: - import_image_details: @@ -296,6 +302,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: True config: - tagging_details: @@ -315,6 +322,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: True config: - image_distribution_details: @@ -332,6 +340,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: True config: - image_activation_details: @@ -914,7 +923,7 @@ def get_diff_import(self): except Exception as e: self.status = "failed" - self.msg = "Import Image details are not given in the playbook or Import Image API not triggered successfully." + self.msg = "Import Image details are not provided in the playbook, or the Import Image API was not triggered successfully." self.log(self.msg) self.result['response'] = self.msg @@ -1277,6 +1286,7 @@ def main(): 'dnac_verify': {'type': 'bool', 'default': 'True'}, 'dnac_version': {'type': 'str', 'default': '2.2.3.3'}, 'dnac_debug': {'type': 'bool', 'default': False}, + 'dnac_log_level': {'type': 'str', 'default': 'INFO'}, 'dnac_log': {'type': 'bool', 'default': False}, 'validate_response_schema': {'type': 'bool', 'default': True}, 'config': {'required': True, 'type': 'list', 'elements': 'dict'}, From f27ea0ec46830a3f79162319e640fbe8fddc6bfc Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Wed, 24 Jan 2024 10:45:14 +0530 Subject: [PATCH 03/16] Modify dnac_log_level description in the documentation --- plugins/modules/inventory_intent.py | 3 ++- plugins/modules/swim_intent.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/modules/inventory_intent.py b/plugins/modules/inventory_intent.py index b1f4de79a2..e09571e3c0 100644 --- a/plugins/modules/inventory_intent.py +++ b/plugins/modules/inventory_intent.py @@ -29,7 +29,8 @@ type: bool default: False dnac_log_level: - description: Log levels are used to categorize the logs based on their severity. + description: Defines log levels to categorize logs by severity. + Choices - [DEBUG, , INFO, WARNING, CRITICAL, ERROR] type: str default: INFO state: diff --git a/plugins/modules/swim_intent.py b/plugins/modules/swim_intent.py index cd3d523d71..f617d30e43 100644 --- a/plugins/modules/swim_intent.py +++ b/plugins/modules/swim_intent.py @@ -31,7 +31,8 @@ Abhishek Maheshwari (@abmahesh) options: dnac_log_level: - description: Log levels are used to categorize the logs based on their severity. + description: Defines log levels to categorize logs by severity. + Choices - [DEBUG, , INFO, WARNING, CRITICAL, ERROR] type: str default: INFO state: From edd4465e1f1dda06d89a8f74a623ee74f2b17464 Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Wed, 24 Jan 2024 11:27:41 +0530 Subject: [PATCH 04/16] add backward compatiblity in site module for input varaible and add possible dnac log level options --- plugins/modules/inventory_intent.py | 2 +- plugins/modules/site_intent.py | 13 ++++++++++++- plugins/modules/swim_intent.py | 2 +- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/plugins/modules/inventory_intent.py b/plugins/modules/inventory_intent.py index e09571e3c0..0551d176ca 100644 --- a/plugins/modules/inventory_intent.py +++ b/plugins/modules/inventory_intent.py @@ -30,7 +30,7 @@ default: False dnac_log_level: description: Defines log levels to categorize logs by severity. - Choices - [DEBUG, , INFO, WARNING, CRITICAL, ERROR] + Options- [CRITICAL, ERROR, WARNING, DEBUG, INFO] type: str default: INFO state: diff --git a/plugins/modules/site_intent.py b/plugins/modules/site_intent.py index a76dc45b55..0cd932062c 100644 --- a/plugins/modules/site_intent.py +++ b/plugins/modules/site_intent.py @@ -29,6 +29,11 @@ description: Set to True to verify the Cisco DNA Center config after applying the playbook config. type: bool default: False + dnac_log_level: + description: Defines log levels to categorize logs by severity. + Options- [CRITICAL, ERROR, WARNING, DEBUG, INFO] + type: str + default: INFO state: description: The state of DNAC after module completion. type: str @@ -129,6 +134,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: "{{dnac_log}}" state: merged config: @@ -147,6 +153,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: "{{dnac_log}}" state: merged config: @@ -168,6 +175,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: "{{dnac_log}}" state: merged config: @@ -191,6 +199,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: "{{dnac_log}}" state: merged config: @@ -212,6 +221,7 @@ dnac_port: "{{dnac_port}}" dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" + dnac_log_level: "{{dnac_log_level}}" dnac_log: "{{dnac_log}}" state: deleted config: @@ -353,7 +363,7 @@ def validate_input(self): type=dict(required=False, type='str'), site=dict(required=True, type='dict'), ) - + self.config = self.camel_to_snake_case(self.config) # Validate site params valid_temp, invalid_params = validate_list_of_dicts( self.config, temp_spec @@ -1008,6 +1018,7 @@ def main(): 'dnac_verify': {'type': 'bool', 'default': 'True'}, 'dnac_version': {'type': 'str', 'default': '2.2.3.3'}, 'dnac_debug': {'type': 'bool', 'default': False}, + 'dnac_log_level': {'type': 'str', 'default': 'INFO'}, 'dnac_log': {'type': 'bool', 'default': False}, 'validate_response_schema': {'type': 'bool', 'default': True}, 'config_verify': {'type': 'bool', "default": False}, diff --git a/plugins/modules/swim_intent.py b/plugins/modules/swim_intent.py index f617d30e43..df517691ac 100644 --- a/plugins/modules/swim_intent.py +++ b/plugins/modules/swim_intent.py @@ -32,7 +32,7 @@ options: dnac_log_level: description: Defines log levels to categorize logs by severity. - Choices - [DEBUG, , INFO, WARNING, CRITICAL, ERROR] + Options- [CRITICAL, ERROR, WARNING, DEBUG, INFO] type: str default: INFO state: From 1d788698dcdb809ee65e19541a9b5d969cd551fa Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Wed, 24 Jan 2024 12:55:55 +0530 Subject: [PATCH 05/16] add check if import type not given in playbook --- plugins/modules/swim_intent.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/modules/swim_intent.py b/plugins/modules/swim_intent.py index df517691ac..28d88defae 100644 --- a/plugins/modules/swim_intent.py +++ b/plugins/modules/swim_intent.py @@ -819,6 +819,15 @@ def get_diff_import(self): try: import_type = self.want.get("import_type") + + if not import_type: + self.msg = "For Importig SWIM Image, details are not provided" + self.result['msg'] = self.msg + self.log(self.msg, "WARNING") + self.status = "success" + self.result['changed'] = False + return self + if import_type == "url": image_name = self.want.get("url_import_details").get("payload")[0].get("source_url") else: From 796d8a6d3432372f264391a147bdd02bc16df7db Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Wed, 24 Jan 2024 15:46:41 +0530 Subject: [PATCH 06/16] Add the log with critical level for which swim distribution/activation gets failed along with device ips in partial success scenario --- plugins/modules/swim_intent.py | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/plugins/modules/swim_intent.py b/plugins/modules/swim_intent.py index 28d88defae..219a161558 100644 --- a/plugins/modules/swim_intent.py +++ b/plugins/modules/swim_intent.py @@ -1004,6 +1004,38 @@ def get_diff_tagging(self): return self + def get_device_ip_from_id(self, device_id): + """ + Retrieve the management IP address of a device from Cisco DNA Center using its ID. + Args: + - self (object): An instance of a class used for interacting with Cisco DNA Center. + - device_id (str): The unique identifier of the device in Cisco DNA Center. + Returns: + str: The management IP address of the specified device. + Raises: + Exception: If there is an error while retrieving the response from Cisco DNA Center. + Description: + This method queries Cisco DNA Center for the device details based on its unique identifier (ID). + It uses the 'get_device_list' function in the 'devices' family, extracts the management IP address + from the response, and returns it. If any error occurs during the process, an exception is raised + with an appropriate error message logged. + """ + + try: + response = self.dnac._exec( + family="devices", + function='get_device_list', + params={"id": device_id} + ) + response = response.get('response')[0] + device_ip = response.get("managementIpAddress") + + return device_ip + except Exception as e: + error_message = "Error while getting the response of device from Cisco DNA Center - {0}".format(str(e)) + self.log(error_message, "ERROR") + raise Exception(error_message) + def get_diff_distribution(self): """ Get image distribution parameters from the playbook and trigger image distribution. @@ -1073,7 +1105,9 @@ def get_diff_distribution(self): self.log("List of device UUID's for Image Distribution " + str(device_uuid_list)) device_distribution_count = 0 + device_ips_list = [] for device_uuid in device_uuid_list: + device_management_ip = self.get_device_ip_from_id(device_uuid) distribution_params = dict( payload=[dict( deviceUuid=device_uuid, @@ -1106,6 +1140,7 @@ def get_diff_distribution(self): error_msg = "Image with Id {0} Distribution Failed".format(image_id) self.log(error_msg) self.result['response'] = task_details + device_ips_list.append(device_management_ip) break if device_distribution_count == 0: @@ -1119,6 +1154,7 @@ def get_diff_distribution(self): self.result['changed'] = True self.status = "success" self.msg = "Image with Id {0} Distributed and partially Successfull".format(image_id) + self.log("For Devices {0} Image Distribution gets Failed".format(str(device_ips_list)), "CRITICAL") self.result['msg'] = self.msg self.log(self.msg) @@ -1200,7 +1236,10 @@ def get_diff_activation(self): # if len(device_uuid_list) > 0: self.log("List of device UUID's for Image Activation" + str(device_uuid_list)) device_activation_count = 0 + device_ips_list = [] + for device_uuid in device_uuid_list: + device_management_ip = self.get_device_ip_from_id(device_uuid) payload = [dict( activateLowerImageVersion=activation_details.get("activate_lower_image_version"), deviceUpgradeMode=activation_details.get("device_upgrade_mode"), @@ -1239,6 +1278,7 @@ def get_diff_activation(self): if task_details.get("isError"): error_msg = "Image with Id {0} Activation Failed".format(image_id) self.result['response'] = task_details + device_ips_list.append(device_management_ip) break if device_activation_count == 0: @@ -1252,6 +1292,7 @@ def get_diff_activation(self): self.result['changed'] = True self.status = "success" msg = "Image with Id {0} Activated and partially Successfull".format(image_id) + self.log("For Devices {0} Image Activation gets Failed".format(str(device_ips_list)), "CRITICAL") self.result['msg'] = msg self.log(msg) From 89bcf1246911c22b92c247292405e181087f99fd Mon Sep 17 00:00:00 2001 From: Abhishek-121 Date: Wed, 24 Jan 2024 16:21:50 +0530 Subject: [PATCH 07/16] update documentation and log messages --- plugins/modules/inventory_intent.py | 4 ++-- plugins/modules/site_intent.py | 4 ++-- plugins/modules/swim_intent.py | 11 ++++++----- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/plugins/modules/inventory_intent.py b/plugins/modules/inventory_intent.py index 0551d176ca..6547aa9937 100644 --- a/plugins/modules/inventory_intent.py +++ b/plugins/modules/inventory_intent.py @@ -29,8 +29,8 @@ type: bool default: False dnac_log_level: - description: Defines log levels to categorize logs by severity. - Options- [CRITICAL, ERROR, WARNING, DEBUG, INFO] + description: Specifies the log level for Cisco Catalyst Center logging, categorizing logs by severity. + Options- [CRITICAL, ERROR, WARNING, INFO, DEBUG] type: str default: INFO state: diff --git a/plugins/modules/site_intent.py b/plugins/modules/site_intent.py index 0cd932062c..203a5ca896 100644 --- a/plugins/modules/site_intent.py +++ b/plugins/modules/site_intent.py @@ -30,8 +30,8 @@ type: bool default: False dnac_log_level: - description: Defines log levels to categorize logs by severity. - Options- [CRITICAL, ERROR, WARNING, DEBUG, INFO] + description: Specifies the log level for Cisco Catalyst Center logging, categorizing logs by severity. + Options- [CRITICAL, ERROR, WARNING, INFO, DEBUG] type: str default: INFO state: diff --git a/plugins/modules/swim_intent.py b/plugins/modules/swim_intent.py index 219a161558..a1f483999c 100644 --- a/plugins/modules/swim_intent.py +++ b/plugins/modules/swim_intent.py @@ -31,8 +31,8 @@ Abhishek Maheshwari (@abmahesh) options: dnac_log_level: - description: Defines log levels to categorize logs by severity. - Options- [CRITICAL, ERROR, WARNING, DEBUG, INFO] + description: Specifies the log level for Cisco Catalyst Center logging, categorizing logs by severity. + Options- [CRITICAL, ERROR, WARNING, INFO, DEBUG] type: str default: INFO state: @@ -821,7 +821,7 @@ def get_diff_import(self): import_type = self.want.get("import_type") if not import_type: - self.msg = "For Importig SWIM Image, details are not provided" + self.msg = "Error: Details required for importing SWIM image. Please provide the necessary information." self.result['msg'] = self.msg self.log(self.msg, "WARNING") self.status = "success" @@ -933,8 +933,9 @@ def get_diff_import(self): except Exception as e: self.status = "failed" - self.msg = "Import Image details are not provided in the playbook, or the Import Image API was not triggered successfully." - self.log(self.msg) + self.msg = """Error: Import image details are not provided in the playbook, or the Import Image API was not + triggered successfully. Please ensure the necessary details are provided and verify the status of the Import Image process.""" + self.log(self.msg, "ERROR") self.result['response'] = self.msg return self From 9d56ee712e705201a8cef7837430b75c7d3acb0e Mon Sep 17 00:00:00 2001 From: Madhan Date: Wed, 24 Jan 2024 16:34:38 +0530 Subject: [PATCH 08/16] Need to set the dnac log level if not present in playbook --- plugins/module_utils/dnac.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/module_utils/dnac.py b/plugins/module_utils/dnac.py index e6ada258f0..83c4e65728 100644 --- a/plugins/module_utils/dnac.py +++ b/plugins/module_utils/dnac.py @@ -64,7 +64,11 @@ def __init__(self, module): 'parsed': self.verify_diff_parsed } self.dnac_log = dnac_params.get("dnac_log") - self.dnac_log_level = dnac_params.get("dnac_log_level").upper() + + # Check if 'dnac_log_level' in the playbook params. If available, + # convert it to uppercase; otherwise, set it to 'INFO' + self.dnac_log_level = dnac_params.get("dnac_log_level", "INFO").upper() + log(str(dnac_params)) self.supported_states = ["merged", "deleted", "replaced", "overridden", "gathered", "rendered", "parsed"] self.result = {"changed": False, "diff": [], "response": [], "warnings": []} From 2202e599ddda3a2e9e432e96d771bb6920818bbe Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Wed, 24 Jan 2024 16:45:04 +0530 Subject: [PATCH 09/16] Set the logging levels for Device Credentails Intent module and Addressed the PR comments --- plugins/modules/device_credential_intent.py | 101 ++++++++++++-------- 1 file changed, 61 insertions(+), 40 deletions(-) diff --git a/plugins/modules/device_credential_intent.py b/plugins/modules/device_credential_intent.py index 0cd6b79170..b095ddb15d 100644 --- a/plugins/modules/device_credential_intent.py +++ b/plugins/modules/device_credential_intent.py @@ -25,6 +25,11 @@ author: Muthu Rakesh (@MUTHU-RAKESH-27) Madhan Sankaranarayanan (@madhansansel) options: + dnac_log_level: + description: Specifies the desired log level for Cisco Catalyst Center logging. + Options - [CRITICAL, ERROR, WARNING, INFO, DEBUG] + type: str + default: INFO config_verify: description: Set to True to verify the Cisco DNA Center after applying the playbook config. type: bool @@ -338,7 +343,9 @@ dnac_verify: "{{ dnac_verify }}" dnac_debug: "{{ dnac_debug }}" dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" state: merged + config_verify: True config: - global_credential_details: cli_credential: @@ -395,7 +402,9 @@ dnac_verify: "{{ dnac_verify }}" dnac_debug: "{{ dnac_debug }}" dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" state: merged + config_verify: True config: - global_credential_details: cli_credential: @@ -460,7 +469,9 @@ dnac_verify: "{{ dnac_verify }}" dnac_debug: "{{ dnac_debug }}" dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" state: merged + config_verify: True config: - global_credential_details: cli_credential: @@ -508,7 +519,9 @@ dnac_verify: "{{ dnac_verify }}" dnac_debug: "{{ dnac_debug }}" dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" state: merged + config_verify: True config: - global_credential_details: cli_credential: @@ -585,7 +598,9 @@ dnac_verify: "{{ dnac_verify }}" dnac_debug: "{{ dnac_debug }}" dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" state: merged + config_verify: True config: - global_credential_details: cli_credential: @@ -635,7 +650,9 @@ dnac_verify: "{{ dnac_verify }}" dnac_debug: "{{ dnac_debug }}" dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" state: merged + config_verify: True config: - assign_credentials_to_site: cli_credential: @@ -848,7 +865,7 @@ def validate_input(self): return self self.validated_config = valid_temp - self.log(str(valid_temp)) + self.log("Successfully validated playbook config params: {0}".format(valid_temp), "INFO") self.msg = "Successfully validated input from the playbook" self.status = "success" return self @@ -871,15 +888,15 @@ def get_site_id(self, site_name): function='get_site', params={"name": site_name}, ) - self.log(str(response)) + self.log("Received API response from 'get_site': {0}".format(response), "DEBUG") if not response: - self.log("Failed to get the site id from site name {0}".format(site_name)) + self.log("Failed to retrieve the site ID for the site name: {0}".format(site_name), "ERROR") return None _id = response.get("response")[0].get("id") - self.log("Site ID for the site name {0}".format(site_name) + str(_id)) + self.log("Site ID for the site name {0}: {1}".format(site_name, _id), "INFO") except Exception as exec: - self.log("Error while getting site_id from the site_name" + str(exec)) + self.log("Exception occurred while getting site_id from the site_name: {0}".format(exec), "CRITICAL") return None return _id @@ -901,9 +918,9 @@ def get_global_credentials_params(self): function='get_all_global_credentials_v2', ) global_credentials = global_credentials.get("response") - self.log("All Global Device Credentials Details " + str(global_credentials)) + self.log("All Global Device Credentials Details " + str(global_credentials), "DEBUG") except Exception as exec: - self.log("Error while getting global device credentials: " + str(exec)) + self.log("Exception occurred while getting global device credentials: {0}".format(exec), "CRITICAL") return None return global_credentials @@ -1452,7 +1469,8 @@ def get_have_device_credentials(self, CredentialDetails): snmpV3 = self.get_snmpV3_params(snmpV3Details) self.have.get("globalCredential").update({"snmpV3": snmpV3}) - self.log("Global Device Credential Details " + str(self.have.get("globalCredential"))) + self.log("Global Device Credential Details: {0}" + .format(self.have.get("globalCredential")), "DEBUG") self.msg = "Collected the Global Device Credential Details from the Cisco DNA Center" self.status = "success" return self @@ -1476,8 +1494,7 @@ def get_have(self, config): CredentialDetails = config.get("global_credential_details") self.get_have_device_credentials(CredentialDetails).check_return_status() - self.log("Credentials and Credentials Assigned to Site Details in Cisco DNA Center " + - str(self.have)) + self.log("Current State (have): " + str(self.have), "INFO") self.msg = "Successfully retrieved the details from the Cisco DNA Center" self.status = "success" return self @@ -1663,7 +1680,8 @@ def get_want_device_credentials(self, CredentialDetails): values = ["password", "description", "username", "id", "port"] have_httpsRead = self.have.get("globalCredential").get("httpsRead") for item in httpsRead: - self.log(str(self.have.get("globalCredential"))) + self.log("Global Credentials Details: {0}" + .format(self.have.get("globalCredential")), "DEBUG") if not have_httpsRead or have_httpsRead[have_httpsread_ptr] is None: if want.get("want_create").get("httpsRead") is None: want.get("want_create").update({"httpsRead": []}) @@ -1812,7 +1830,8 @@ def get_want_device_credentials(self, CredentialDetails): self.msg = "auth_password length should be greater than 8" self.status = "failed" return self - self.log(str(create_credential[create_snmpv3_ptr].get("snmpMode"))) + self.log("snmpMode: {0}".format(create_credential[create_snmpv3_ptr] + .get("snmpMode")), "DEBUG") if create_credential[create_snmpv3_ptr].get("snmpMode") == "AUTHPRIV": privs = ["privacy_password", "privacy_type"] key = { @@ -2115,7 +2134,7 @@ def get_want_assign_credentials(self, AssignCredentials): self.status = "failed" return self want.get("assign_credentials").update({"snmpV3Id": snmpV3Detail.get("id")}) - self.log("Assign Credentials to Site playbook values " + str(want)) + self.log("Desired State (want): {0}".format(want), "INFO") self.want.update(want) self.msg = "Collected the Credentials needed to be assigned from the Cisco DNA Center" self.status = "success" @@ -2144,7 +2163,7 @@ def get_want(self, config): AssignCredentials = config.get("assign_credentials_to_site") self.get_want_assign_credentials(AssignCredentials).check_return_status() - self.log("User details from the playbook " + str(self.want)) + self.log("Desired State (want): {0}".format(self.want), "INFO") self.msg = "Successfully retrieved details from the playbook" self.status = "success" return self @@ -2174,16 +2193,16 @@ def create_device_credentials(self): return self credential_params = want_create - self.log("Create Global Credential API input - " + str(credential_params)) + self.log("Creating Global Credential API input parameters: {0}".format(credential_params), "DEBUG") response = self.dnac._exec( family="discovery", function='create_global_credentials_v2', params=credential_params, ) - self.log(str(response)) + self.log("Received API response from 'create_global_credentials_v2': {0}".format(response), "DEBUG") validation_string = "global credential addition performed" self.check_task_response_status(response, validation_string).check_return_status() - self.log("Global Credential Created Successfully") + self.log("Global Credential Created Successfully", "INFO") result_global_credential.update({ "Creation": { "response": credential_params, @@ -2226,7 +2245,7 @@ def update_device_credentials(self): values = ["cliCredential", "snmpV2cRead", "snmpV2cWrite", "httpsRead", "httpsWrite", "snmpV3"] final_response = [] - self.log(str(want_update)) + self.log("Desired State for Updation: {0}".format(want_update), "DEBUG") while flag: flag = False credential_params = {} @@ -2242,11 +2261,11 @@ def update_device_credentials(self): function='update_global_credentials_v2', params=credential_params, ) - self.log(str(response)) + self.log("Received API response for 'update_global_credentials_v2': {0}".format(response), "DEBUG") validation_string = "global credential update performed" self.check_task_response_status(response, validation_string).check_return_status() - self.log("Update Device Credential API input - " + str(final_response)) - self.log("Global Device Credential Updated Successfully") + self.log("Updating Device Credential API input parameters: {0}".format(final_response), "DEBUG") + self.log("Global Device Credential Updated Successfully", "INFO") result_global_credential.update({ "Updation": { "response": final_response, @@ -2273,7 +2292,7 @@ def assign_credentials_to_site(self): result_assign_credential = self.result.get("response")[0].get("assignCredential") credential_params = self.want.get("assign_credentials") final_response = [] - self.log("Assign Device Credential to site API input - " + str(credential_params)) + self.log("Assigning Device Credential to site API input parameters: {0}".format(credential_params), "DEBUG") if not credential_params: result_assign_credential.update({ "No Assign Credentials": { @@ -2294,11 +2313,12 @@ def assign_credentials_to_site(self): function='assign_device_credential_to_site_v2', params=credential_params, ) - self.log(str(response)) + self.log("Response for API assign_device_credential_to_site_v2: " + + str(response), "DEBUG") validation_string = "desired common settings operation successful" self.check_task_response_status(response, validation_string).check_return_status() - self.log("Device Credential Assigned to site is Successfully") - self.log(str(final_response)) + self.log("Device Credential Assigned to site {0} is Successfully.".format(site_ids), "INFO") + self.log("Desired State for Assign Credentials to a Site: {0}".format(final_response), "DEBUG") result_assign_credential.update({ "Assign Credentials": { "response": final_response, @@ -2349,7 +2369,7 @@ def delete_device_credential(self, config): result_global_credential = self.result.get("response")[0].get("globalCredential") have_values = self.have.get("globalCredential") final_response = {} - self.log(str(have_values)) + self.log("Global Device Credentials to be Deleted: {0}".format(have_values), "DEBUG") credential_mapping = { "cliCredential": "cli_credential", "snmpV2cRead": "snmp_v2c_read", @@ -2363,9 +2383,9 @@ def delete_device_credential(self, config): final_response.update({item: []}) for value in have_values.get(item): if value is None: - self.log(str(item)) - self.log(str(config.get("global_credential_details") - .get(credential_mapping.get(item)))) + self.log("Credential Name: {0}".format(item), "DEBUG") + self.log("Credential Item: {0}".format(config.get("global_credential_details") + .get(credential_mapping.get(item))), "DEBUG") final_response.get(item).append( str(config.get("global_credential_details") .get(credential_mapping.get(item))[config_itr]) + " is not found." @@ -2377,14 +2397,14 @@ def delete_device_credential(self, config): function="delete_global_credential_v2", params={"id": _id}, ) - self.log(str(response)) + self.log("Received API response for 'delete_global_credential_v2': {0}".format(response), "DEBUG") validation_string = "global credential deleted successfully" self.check_task_response_status(response, validation_string).check_return_status() final_response.get(item).append(_id) config_itr = config_itr + 1 - self.log("Delete Device Credential API input - " + str(final_response)) - self.log("Global Device Credential Deleted Successfully") + self.log("Deleting Device Credential API input parameters: {0}".format(final_response), "DEBUG") + self.log("Successfully Deleted Global Device Credential.", "INFO") result_global_credential.update({ "Deletion": { "response": final_response, @@ -2425,11 +2445,11 @@ def verify_diff_merged(self, config): self """ - self.log(str("Entered the verify function.")) + self.log(str("Entered the verify function."), "DEBUG") self.get_have(config) self.get_want(config) - self.log("DNAC retrieved details: " + str(self.have)) - self.log("Playbook details: " + str(self.want)) + self.log("Current State (have): " + str(self.have), "INFO") + self.log("Desired State (want): " + str(self.want), "INFO") if config.get("global_credential_details") is not None: if self.want.get("want_create"): @@ -2461,11 +2481,11 @@ def verify_diff_merged(self, config): self.status = "failed" return self - self.log("Successfully validated Global Device Credential") + self.log("Successfully validated Global Device Credential", "INFO") self.result.get("response")[0].get("globalCredential").update({"Validation": "Success"}) if config.get("assign_credentials_to_site") is not None: - self.log("Successfully validated the Assign Device Credential to site") + self.log("Successfully validated the Assign Device Credential to Site", "INFO") self.result.get("response")[0].get("assignCredential").update({"Validation": "Success"}) self.msg = "Successfully validated the Global Device Credential and \ @@ -2487,8 +2507,8 @@ def verify_diff_deleted(self, config): """ self.get_have(config) - self.log("DNAC retrieved details: " + str(self.have)) - self.log("Playbook details: " + str(self.want)) + self.log("Current State (have): " + str(self.have), "INFO") + self.log("Desired State (want): " + str(self.want), "INFO") if config.get("global_credential_details") is not None: have_global_credential = self.have.get("globalCredential") @@ -2502,7 +2522,7 @@ def verify_diff_deleted(self, config): self.status = "failed" return self - self.log("Successfully validated absence of Global Device Credential.") + self.log("Successfully validated absence of Global Device Credential.", "INFO") self.result.get("response")[0].get("globalCredential").update({"Validation": "Success"}) self.msg = "Successfully validated the absence of Global Device Credential." @@ -2538,6 +2558,7 @@ def main(): "dnac_version": {"type": 'str', "default": '2.2.3.3'}, "dnac_debug": {"type": 'bool', "default": False}, "dnac_log": {"type": 'bool', "default": False}, + "dnac_log_level": {"type": "str", "default": "INFO"}, "config_verify": {"type": 'bool', "default": False}, "config": {"type": 'list', "required": True, "elements": 'dict'}, "state": {"default": 'merged', "choices": ['merged', 'deleted']}, From 3ee2bc3ea78903157f6dc9c8c31a873f04cf8639 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Wed, 24 Jan 2024 16:53:52 +0530 Subject: [PATCH 10/16] Addressed the PR comments --- plugins/modules/device_credential_intent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/modules/device_credential_intent.py b/plugins/modules/device_credential_intent.py index b095ddb15d..247f8daf6f 100644 --- a/plugins/modules/device_credential_intent.py +++ b/plugins/modules/device_credential_intent.py @@ -1830,7 +1830,7 @@ def get_want_device_credentials(self, CredentialDetails): self.msg = "auth_password length should be greater than 8" self.status = "failed" return self - self.log("snmpMode: {0}".format(create_credential[create_snmpv3_ptr] + self.log("snmp_mode: {0}".format(create_credential[create_snmpv3_ptr] .get("snmpMode")), "DEBUG") if create_credential[create_snmpv3_ptr].get("snmpMode") == "AUTHPRIV": privs = ["privacy_password", "privacy_type"] From c858e5368f0ca1389b13264e48a0baa35d79999a Mon Sep 17 00:00:00 2001 From: Madhan Date: Wed, 24 Jan 2024 17:04:39 +0530 Subject: [PATCH 11/16] Changes in changelogs and galaxy --- changelogs/changelog.yaml | 8 ++++++++ galaxy.yml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index a68a792af6..f030fe54a1 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -770,3 +770,11 @@ releases: minor_changes: - Introducing config_verify to verify the state operations in Catalyst Center in network settings and site intent module - Changes to support inventory and provisioning intent modules + 6.10.2: + release_date: "2024-01-24" + changes: + release_summary: Set dnac log level if it is not set in the playbook. + minor_changes: + - Set dnac log level if it is not set in the playbook. + - Handle provisioning of device if it’s not in managed state for longer. + - Set the logging levels for device credentails intent module. diff --git a/galaxy.yml b/galaxy.yml index 9ec2120a61..7f79631987 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -1,7 +1,7 @@ --- namespace: cisco name: dnac -version: 6.10.1 +version: 6.10.2 readme: README.md authors: - Rafael Campos From e6126d980af362130226f9bd657179f662b5fea3 Mon Sep 17 00:00:00 2001 From: Madhan Date: Wed, 24 Jan 2024 18:01:07 +0530 Subject: [PATCH 12/16] Changing Unicode quotes --- changelogs/changelog.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/changelog.yaml b/changelogs/changelog.yaml index f030fe54a1..4360b599ac 100644 --- a/changelogs/changelog.yaml +++ b/changelogs/changelog.yaml @@ -776,5 +776,5 @@ releases: release_summary: Set dnac log level if it is not set in the playbook. minor_changes: - Set dnac log level if it is not set in the playbook. - - Handle provisioning of device if it’s not in managed state for longer. + - Handle provisioning of device if it is not in managed state for longer. - Set the logging levels for device credentails intent module. From ce4694450e1d20ede55c5c92d8a2a4fc100e015b Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Wed, 24 Jan 2024 20:04:39 +0530 Subject: [PATCH 13/16] Set the logging levels, refactored the log statements and addressed the review comments --- plugins/modules/device_credential_intent.py | 55 +++--- plugins/modules/network_settings_intent.py | 188 +++++++++++--------- plugins/modules/template_intent.py | 134 ++++++++------ 3 files changed, 215 insertions(+), 162 deletions(-) diff --git a/plugins/modules/device_credential_intent.py b/plugins/modules/device_credential_intent.py index 247f8daf6f..43d4b0205e 100644 --- a/plugins/modules/device_credential_intent.py +++ b/plugins/modules/device_credential_intent.py @@ -890,13 +890,15 @@ def get_site_id(self, site_name): ) self.log("Received API response from 'get_site': {0}".format(response), "DEBUG") if not response: - self.log("Failed to retrieve the site ID for the site name: {0}".format(site_name), "ERROR") + self.log("Failed to retrieve the site ID for the site name: {0}" + .format(site_name), "ERROR") return None _id = response.get("response")[0].get("id") self.log("Site ID for the site name {0}: {1}".format(site_name, _id), "INFO") except Exception as exec: - self.log("Exception occurred while getting site_id from the site_name: {0}".format(exec), "CRITICAL") + self.log("Exception occurred while getting site_id from the site_name: {0}" + .format(exec), "CRITICAL") return None return _id @@ -918,9 +920,11 @@ def get_global_credentials_params(self): function='get_all_global_credentials_v2', ) global_credentials = global_credentials.get("response") - self.log("All Global Device Credentials Details " + str(global_credentials), "DEBUG") + self.log("All Global Device Credentials Details: {0}" + .format(global_credentials), "DEBUG") except Exception as exec: - self.log("Exception occurred while getting global device credentials: {0}".format(exec), "CRITICAL") + self.log("Exception occurred while getting global device credentials: {0}" + .format(exec), "CRITICAL") return None return global_credentials @@ -1494,7 +1498,7 @@ def get_have(self, config): CredentialDetails = config.get("global_credential_details") self.get_have_device_credentials(CredentialDetails).check_return_status() - self.log("Current State (have): " + str(self.have), "INFO") + self.log("Current State (have): {0}".format(self.have), "INFO") self.msg = "Successfully retrieved the details from the Cisco DNA Center" self.status = "success" return self @@ -1830,7 +1834,7 @@ def get_want_device_credentials(self, CredentialDetails): self.msg = "auth_password length should be greater than 8" self.status = "failed" return self - self.log("snmp_mode: {0}".format(create_credential[create_snmpv3_ptr] + self.log("snmpMode: {0}".format(create_credential[create_snmpv3_ptr] .get("snmpMode")), "DEBUG") if create_credential[create_snmpv3_ptr].get("snmpMode") == "AUTHPRIV": privs = ["privacy_password", "privacy_type"] @@ -2193,13 +2197,15 @@ def create_device_credentials(self): return self credential_params = want_create - self.log("Creating Global Credential API input parameters: {0}".format(credential_params), "DEBUG") + self.log("Creating Global Credential API input parameters: {0}" + .format(credential_params), "DEBUG") response = self.dnac._exec( family="discovery", function='create_global_credentials_v2', params=credential_params, ) - self.log("Received API response from 'create_global_credentials_v2': {0}".format(response), "DEBUG") + self.log("Received API response from 'create_global_credentials_v2': {0}" + .format(response), "DEBUG") validation_string = "global credential addition performed" self.check_task_response_status(response, validation_string).check_return_status() self.log("Global Credential Created Successfully", "INFO") @@ -2261,10 +2267,12 @@ def update_device_credentials(self): function='update_global_credentials_v2', params=credential_params, ) - self.log("Received API response for 'update_global_credentials_v2': {0}".format(response), "DEBUG") + self.log("Received API response for 'update_global_credentials_v2': {0}" + .format(response), "DEBUG") validation_string = "global credential update performed" self.check_task_response_status(response, validation_string).check_return_status() - self.log("Updating Device Credential API input parameters: {0}".format(final_response), "DEBUG") + self.log("Updating Device Credential API input parameters: {0}" + .format(final_response), "DEBUG") self.log("Global Device Credential Updated Successfully", "INFO") result_global_credential.update({ "Updation": { @@ -2292,7 +2300,8 @@ def assign_credentials_to_site(self): result_assign_credential = self.result.get("response")[0].get("assignCredential") credential_params = self.want.get("assign_credentials") final_response = [] - self.log("Assigning Device Credential to site API input parameters: {0}".format(credential_params), "DEBUG") + self.log("Assigning Device Credential to site API input parameters: {0}" + .format(credential_params), "DEBUG") if not credential_params: result_assign_credential.update({ "No Assign Credentials": { @@ -2313,12 +2322,14 @@ def assign_credentials_to_site(self): function='assign_device_credential_to_site_v2', params=credential_params, ) - self.log("Response for API assign_device_credential_to_site_v2: " + - str(response), "DEBUG") + self.log("Response for API assign_device_credential_to_site_v2: {0}" + .format(response), "DEBUG") validation_string = "desired common settings operation successful" self.check_task_response_status(response, validation_string).check_return_status() - self.log("Device Credential Assigned to site {0} is Successfully.".format(site_ids), "INFO") - self.log("Desired State for Assign Credentials to a Site: {0}".format(final_response), "DEBUG") + self.log("Device Credential Assigned to site {0} is Successfully." + .format(site_ids), "INFO") + self.log("Desired State for Assign Credentials to a Site: {0}" + .format(final_response), "DEBUG") result_assign_credential.update({ "Assign Credentials": { "response": final_response, @@ -2397,13 +2408,15 @@ def delete_device_credential(self, config): function="delete_global_credential_v2", params={"id": _id}, ) - self.log("Received API response for 'delete_global_credential_v2': {0}".format(response), "DEBUG") + self.log("Received API response for 'delete_global_credential_v2': {0}" + .format(response), "DEBUG") validation_string = "global credential deleted successfully" self.check_task_response_status(response, validation_string).check_return_status() final_response.get(item).append(_id) config_itr = config_itr + 1 - self.log("Deleting Device Credential API input parameters: {0}".format(final_response), "DEBUG") + self.log("Deleting Device Credential API input parameters: {0}" + .format(final_response), "DEBUG") self.log("Successfully Deleted Global Device Credential.", "INFO") result_global_credential.update({ "Deletion": { @@ -2448,8 +2461,8 @@ def verify_diff_merged(self, config): self.log(str("Entered the verify function."), "DEBUG") self.get_have(config) self.get_want(config) - self.log("Current State (have): " + str(self.have), "INFO") - self.log("Desired State (want): " + str(self.want), "INFO") + self.log("Current State (have): {0}".format(self.have), "INFO") + self.log("Desired State (want): {0}".format(self.want), "INFO") if config.get("global_credential_details") is not None: if self.want.get("want_create"): @@ -2507,8 +2520,8 @@ def verify_diff_deleted(self, config): """ self.get_have(config) - self.log("Current State (have): " + str(self.have), "INFO") - self.log("Desired State (want): " + str(self.want), "INFO") + self.log("Current State (have): {0}".format(self.have), "INFO") + self.log("Desired State (want): {0}".format(self.want), "INFO") if config.get("global_credential_details") is not None: have_global_credential = self.have.get("globalCredential") diff --git a/plugins/modules/network_settings_intent.py b/plugins/modules/network_settings_intent.py index a88b8151c3..4750a61b04 100644 --- a/plugins/modules/network_settings_intent.py +++ b/plugins/modules/network_settings_intent.py @@ -25,6 +25,11 @@ author: Muthu Rakesh (@MUTHU-RAKESH-27) Madhan Sankaranarayanan (@madhansansel) options: + dnac_log_level: + description: Specifies the desired log level for Cisco Catalyst Center logging. + Options - [CRITICAL, ERROR, WARNING, INFO, DEBUG] + type: str + default: INFO config_verify: description: Set to True to verify the Cisco DNA Center after applying the playbook config. type: bool @@ -308,7 +313,9 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" dnac_log: True + dnac_log_level: "{{ dnac_log_level }}" state: merged + config_verify: True config: - global_pool_details: settings: @@ -404,6 +411,7 @@ """ import copy +from multiprocessing.util import ForkAwareThreadLock from ansible.module_utils.basic import AnsibleModule from ansible_collections.cisco.dnac.plugins.module_utils.dnac import ( DnacBase, @@ -552,7 +560,7 @@ def validate_input(self): return self self.validated_config = valid_temp - self.log(str(valid_temp)) + self.log("Successfully validated playbook config params: {0}".format(valid_temp), "INFO") self.msg = "Successfully validated input from the playbook" self.status = "success" return self @@ -583,8 +591,8 @@ def requires_update(self, have, want, obj_params): current_obj = have requested_obj = want - self.log(str(current_obj)) - self.log(str(requested_obj)) + self.log("Current State (have): {0}".format(current_obj), "DEBUG") + self.log("Desired State (want): {0}".format(requested_obj), "DEBUG") return any(not dnac_compare_equality(current_obj.get(dnac_param), requested_obj.get(ansible_param)) @@ -631,7 +639,7 @@ def get_obj_params(self, get_object): else: raise ValueError("Unexpected value: {0}".format(get_object)) except Exception as msg: - self.log("Error message:" + msg) + self.log("Error message: {0}".format(msg), "CRITICAL") return obj_params @@ -653,15 +661,17 @@ def get_site_id(self, site_name): function='get_site', params={"name": site_name}, ) - self.log(str(response)) + self.log("Received API response from 'get_site': {0}".format(response), "DEBUG") if not response: - self.log("Failed to get the site id from site name {0}".format(site_name)) + self.log("Failed to retrieve the site ID for the site name: {0}" + .format(site_name), "ERROR") return None _id = response.get("response")[0].get("id") - self.log(str(_id)) - except Exception as e: - self.log("Error while getting site_id from the site_name") + self.log("Site ID: {0}".format(_id), "DEBUG") + except Exception as msg: + self.log("Exception occurred while retrieving site_id from the site_name: {0}" + .format(msg), "CRITICAL") return None return _id @@ -679,10 +689,10 @@ def get_global_pool_params(self, pool_info): """ if not pool_info: - self.log("Global Pool is empty") + self.log("Global Pool is empty", "INFO") return None - self.log(str(pool_info)) + self.log("Global Pool Details: {0}".format(pool_info), "DEBUG") global_pool = { "settings": { "ippool": [{ @@ -694,14 +704,14 @@ def get_global_pool_params(self, pool_info): }] } } - self.log(str(global_pool)) + self.log("Formated Global Pool Details: {0}".format(global_pool), "DEBUG") global_ippool = global_pool.get("settings").get("ippool")[0] if pool_info.get("ipv6") is False: global_ippool.update({"IpAddressSpace": "IPv4"}) else: global_ippool.update({"IpAddressSpace": "IPv6"}) - self.log(str(global_ippool.get("IpAddressSpace"))) + self.log("IpAddressSpace: {0}".format(global_ippool.get("IpAddressSpace")), "DEBUG") if not pool_info["gateways"]: global_ippool.update({"gateway": ""}) else: @@ -780,7 +790,7 @@ def get_reserve_pool_params(self, pool_info): else: reserve_pool.update({"ipv4GateWay": ""}) reserve_pool.update({"slaacSupport": True}) - self.log(str(reserve_pool)) + self.log("Formatted Reserve Pool Details: {0}".format(reserve_pool), "DEBUG") return reserve_pool def get_network_params(self, site_id): @@ -802,9 +812,10 @@ def get_network_params(self, site_id): function='get_network_v2', params={"site_id": site_id} ) - self.log(str(response)) + self.log("Received API response from 'get_network_v2': {0}".format(response), "DEBUG") if not isinstance(response, dict): - self.log("Error in getting network details - Response is not a dictionary") + self.log("Failed to retrieve the network details - " + "Response is not a dictionary", "ERROR") return None # Extract various network-related details from the response @@ -926,7 +937,7 @@ def get_network_params(self, site_id): } }) - self.log(str(network_details)) + self.log("Formatted playbook network details: {0}".format(network_details), "DEBUG") return network_details def global_pool_exists(self, name): @@ -953,21 +964,22 @@ def global_pool_exists(self, name): function="get_global_pool", ) if not isinstance(response, dict): - self.log("Error in getting global pool - Response is not a dictionary") + self.log("Failed to retrieve the global pool details - " + "Response is not a dictionary", "CRITICAL") return global_pool all_global_pool_details = response.get("response") global_pool_details = get_dict_result(all_global_pool_details, "ipPoolName", name) - self.log("Global Ippool Name : " + str(name)) - self.log(str(global_pool_details)) + self.log("Global Ippool Name: {0}".format(name), "DEBUG") + self.log("Global Pool Details: {0}".format(global_pool_details), "DEBUG") if not global_pool_details: - self.log("Global pool {0} does not exist".format(name)) + self.log("Global pool {0} does not exist".format(name), "INFO") return global_pool global_pool.update({"exists": True}) global_pool.update({"id": global_pool_details.get("id")}) global_pool["details"] = self.get_global_pool_params(global_pool_details) - self.log(str(global_pool)) + self.log("Formatted Global Pool Details: {0}".format(global_pool), "DEBUG") return global_pool def reserve_pool_exists(self, name, site_name): @@ -993,7 +1005,7 @@ def reserve_pool_exists(self, name, site_name): "success": True } site_id = self.get_site_id(site_name) - self.log(str(site_id)) + self.log("Site ID for the Site Name {0}: {1}".format(site_name, site_id), "DEBUG") if not site_id: reserve_pool.update({"success": False}) self.msg = "Failed to get the site id from the site name {0}".format(site_name) @@ -1014,15 +1026,16 @@ def reserve_pool_exists(self, name, site_name): all_reserve_pool_details = response.get("response") reserve_pool_details = get_dict_result(all_reserve_pool_details, "groupName", name) if not reserve_pool_details: - self.log("Reserve pool {0} does not exist in the site {1}".format(name, site_name)) + self.log("Reserve pool {0} does not exist in the site {1}" + .format(name, site_name), "DEBUG") return reserve_pool reserve_pool.update({"exists": True}) reserve_pool.update({"id": reserve_pool_details.get("id")}) reserve_pool.update({"details": self.get_reserve_pool_params(reserve_pool_details)}) - self.log("Reserved Pool Details " + str(reserve_pool.get("details"))) - self.log("Reserved Pool Id " + str(reserve_pool.get("id"))) + self.log("Reserved Pool Details: {0}".format(reserve_pool.get("details")), "DEBUG") + self.log("Reserved Pool Id: {0}".format(reserve_pool.get("id")), "DEBUG") return reserve_pool def get_have_global_pool(self, config): @@ -1064,7 +1077,7 @@ def get_have_global_pool(self, config): # If the Global Pool doesn't exist and a previous name is provided # Else try using the previous name global_pool = self.global_pool_exists(name) - self.log(str(global_pool)) + self.log("Global Pool Details: {0}".format(global_pool), "DEBUG") prev_name = global_pool_ippool[0].get("prev_name") if global_pool.get("exists") is False and \ prev_name is not None: @@ -1074,8 +1087,8 @@ def get_have_global_pool(self, config): self.status = "failed" return self - self.log("pool Exists: " + str(global_pool.get("exists")) + - "\n Current Site: " + str(global_pool.get("details"))) + self.log("Global Pool Exists: {0}".format(global_pool.get("exists")), "DEBUG") + self.log("Current Site: {0}".format(global_pool.get("details")), "DEBUG") self.have.update({"globalPool": global_pool}) self.msg = "Collecting the global pool details from the Cisco DNA Center" self.status = "success" @@ -1107,7 +1120,7 @@ def get_have_reserve_pool(self, config): return self site_name = reserve_pool_details.get("site_name") - self.log(str(site_name)) + self.log("Site Name: {0}".format(site_name), "DEBUG") if site_name is None: self.msg = "Missing parameter 'site_name' in reserve_pool_details" self.status = "failed" @@ -1118,7 +1131,7 @@ def get_have_reserve_pool(self, config): reserve_pool = self.reserve_pool_exists(name, site_name) if not reserve_pool.get("success"): return self.check_return_status() - self.log(str(reserve_pool)) + self.log("Reserve Pool Details: {0}".format(reserve_pool), "DEBUG") # If the Reserved Pool doesn't exist and a previous name is provided # Else try using the previous name @@ -1135,8 +1148,8 @@ def get_have_reserve_pool(self, config): self.status = "failed" return self - self.log("Reservation Exists: " + str(reserve_pool.get("exists")) + - "\n Reserved Pool: " + str(reserve_pool.get("details"))) + self.log("Reservation Exists: {0}".format(reserve_pool.get("exists")), "DEBUG") + self.log("Reserved Pool: {0}".format(reserve_pool.get("details")), "DEBUG") # If reserve pool exist, convert ipv6AddressSpace to the required format (boolean) if reserve_pool.get("exists"): @@ -1146,7 +1159,7 @@ def get_have_reserve_pool(self, config): else: reserve_pool_details.update({"ipv6AddressSpace": True}) - self.log(str(reserve_pool)) + self.log("Reserve Pool Details: {0}".format(reserve_pool), "DEBUG") self.have.update({"reservePool": reserve_pool}) self.msg = "Collecting the reserve pool details from the Cisco DNA Center" self.status = "success" @@ -1178,7 +1191,7 @@ def get_have_network(self, config): network["site_id"] = site_id network["net_details"] = self.get_network_params(site_id) - self.log("Network Details from the Cisco DNA Center " + str(network)) + self.log("Network Details from the Cisco DNA Center: {0}".format(network), "DEBUG") self.have.update({"network": network}) self.msg = "Collecting the network details from the Cisco DNA Center" self.status = "success" @@ -1206,7 +1219,7 @@ def get_have(self, config): if config.get("network_management_details") is not None: self.get_have_network(config).check_return_status() - self.log("Global Pool, Reserve Pool, Network Details in Cisco DNA Center " + str(self.have)) + self.log("Current State (have): {0}".format(self.have), "INFO") self.msg = "Successfully retrieved the details from the Cisco DNA Center" self.status = "success" return self @@ -1270,7 +1283,7 @@ def get_want_global_pool(self, global_ippool): if want_ippool.get(key) is None and have_ippool.get(key) is not None: want_ippool[key] = have_ippool[key] - self.log("Global Pool Playbook Details " + str(want_global)) + self.log("Global Pool Playbook Details: {0}".format(want_global), "DEBUG") self.want.update({"wantGlobal": want_global}) self.msg = "Collecting the global pool details from the playbook" self.status = "success" @@ -1334,7 +1347,7 @@ def get_want_reserve_pool(self, reserve_pool): self.status = "failed" return self - self.log("Reserve IP Pool Playbook Details " + str(want_reserve)) + self.log("Reserve IP Pool Playbook Details: {0}".format(want_reserve), "DEBUG") # If there are no existing Reserved Pool details, validate and set defaults if not self.have.get("reservePool").get("details"): @@ -1383,7 +1396,7 @@ def get_want_reserve_pool(self, reserve_pool): del want_reserve[key] self.want.update({"wantReserve": want_reserve}) - self.log(str(self.want)) + self.log("Desired State (want): {0}".format(self.want), "INFO") self.msg = "Collecting the reserve pool details from the playbook" self.status = "success" return self @@ -1417,7 +1430,7 @@ def get_want_network(self, network_management_details): } } want_network_settings = want_network.get("settings") - self.log(str(self.have)) + self.log("Current state (have): {0}".format(self.have), "DEBUG") if network_management_details.get("dhcp_server") is not None: want_network_settings.update({ "dhcpServer": network_management_details.get("dhcp_server") @@ -1620,7 +1633,7 @@ def get_want_network(self, network_management_details): else: del want_network_settings["clientAndEndpoint_aaa"] - self.log("Network Playbook Details " + str(want_network)) + self.log("Network Playbook Details: {0}".format(want_network), "DEBUG") self.want.update({"wantNetwork": want_network}) self.msg = "Collecting the network details from the playbook" self.status = "success" @@ -1650,7 +1663,7 @@ def get_want(self, config): .get("settings") self.get_want_network(network_management_details).check_return_status() - self.log("User details from the playbook " + str(self.want)) + self.log("Desired State (want): {0}".format(self.want), "INFO") self.msg = "Successfully retrieved details from the playbook" self.status = "success" return self @@ -1674,14 +1687,14 @@ def update_global_pool(self, config): # Check pool exist, if not create and return if not self.have.get("globalPool").get("exists"): pool_params = self.want.get("wantGlobal") - self.log(str(pool_params)) + self.log("Playbook Global Pool Details: {0}".format(pool_params), "DEBUG") response = self.dnac._exec( family="network_settings", function="create_global_pool", params=pool_params, ) self.check_execution_response_status(response).check_return_status() - self.log("Global Pool Created Successfully") + self.log("Successfully Created Global Pool.", "INFO") result_global_pool.get("response").get(name) \ .update({"globalPool Details": self.want.get("wantGlobal")}) result_global_pool.get("msg").update({name: "Global Pool Created Successfully"}) @@ -1690,7 +1703,7 @@ def update_global_pool(self, config): # Pool exists, check update is required if not self.requires_update(self.have.get("globalPool").get("details"), self.want.get("wantGlobal"), self.global_pool_obj_params): - self.log("Global pool doesn't requires an update") + self.log("Global pool doesn't requires an update", "INFO") result_global_pool.get("response").get(name).update({ "Cisco DNA Center params": self.have.get("globalPool").get("details").get("settings").get("ippool")[0] @@ -1701,15 +1714,15 @@ def update_global_pool(self, config): result_global_pool.get("msg").update({ name: "Global pool doesn't require an update" }) - self.log(str(self.result)) + self.log("Result: {0}".format(self.result), "DEBUG") return - self.log("Pool requires update") + self.log("Global Pool requires update", "DEBUG") # Pool Exists pool_params = copy.deepcopy(self.want.get("wantGlobal")) pool_params_ippool = pool_params.get("settings").get("ippool")[0] pool_params_ippool.update({"id": self.have.get("globalPool").get("id")}) - self.log(str(pool_params)) + self.log("Playbook Global Pool Details: {0}".format(pool_params), "DEBUG") keys_to_remove = ["IpAddressSpace", "ipPoolCidr", "type"] for key in keys_to_remove: del pool_params["settings"]["ippool"][0][key] @@ -1720,7 +1733,7 @@ def update_global_pool(self, config): if pool_params_ippool.get(key) is None: pool_params_ippool[key] = have_ippool.get(key) - self.log(str(pool_params)) + self.log("Playbook Global Pool Details: {0}".format(pool_params), "DEBUG") response = self.dnac._exec( family="network_settings", function="update_global_pool", @@ -1728,7 +1741,7 @@ def update_global_pool(self, config): ) self.check_execution_response_status(response).check_return_status() - self.log("Global Pool Updated Successfully") + self.log("Global Pool Updated Successfully", "INFO") result_global_pool.get("response").get(name) \ .update({"Id": self.have.get("globalPool").get("details").get("id")}) result_global_pool.get("msg").update({name: "Global Pool Updated Successfully"}) @@ -1750,26 +1763,27 @@ def update_reserve_pool(self, config): name = config.get("reserve_pool_details").get("name") result_reserve_pool = self.result.get("response")[1].get("reservePool") result_reserve_pool.get("response").update({name: {}}) - self.log("Reserve Pool Cisco DNA Center Details " + - str(self.have.get("reservePool").get("details"))) - self.log("Reserve Pool User Details " + - str(self.want.get("wantReserve"))) + self.log("Reserve Pool Cisco DNA Center Details: {0}" + .format(self.have.get("reservePool").get("details")), "DEBUG") + self.log("Reserve Pool User Details: {0}" + .format(self.want.get("wantReserve")), "DEBUG") # Check pool exist, if not create and return - self.log(str(self.want.get("wantReserve").get("ipv4GlobalPool"))) + self.log("ipv4_global_pool: {0}" + .format(self.want.get("wantReserve").get("ipv4GlobalPool")), "DEBUG") site_name = config.get("reserve_pool_details").get("site_name") reserve_params = self.want.get("wantReserve") site_id = self.get_site_id(site_name) reserve_params.update({"site_id": site_id}) if not self.have.get("reservePool").get("exists"): - self.log(str(reserve_params)) + self.log("Reserve Pool Playbook Details: {0}".format(reserve_params), "DEBUG") response = self.dnac._exec( family="network_settings", function="reserve_ip_subpool", params=reserve_params, ) self.check_execution_response_status(response).check_return_status() - self.log("Ip Subpool Reservation Created Successfully") + self.log("Ip Subpool Reservation Created Successfully", "INFO") result_reserve_pool.get("response").get(name) \ .update({"reservePool Details": self.want.get("wantReserve")}) result_reserve_pool.get("msg") \ @@ -1779,7 +1793,7 @@ def update_reserve_pool(self, config): # Check update is required if not self.requires_update(self.have.get("reservePool").get("details"), self.want.get("wantReserve"), self.reserve_pool_obj_params): - self.log("Reserved ip subpool doesn't require an update") + self.log("Reserved ip subpool doesn't require an update", "INFO") result_reserve_pool.get("response").get(name) \ .update({"Cisco DNA Center params": self.have.get("reservePool").get("details")}) result_reserve_pool.get("response").get(name) \ @@ -1788,10 +1802,11 @@ def update_reserve_pool(self, config): .update({name: "Reserve ip subpool doesn't require an update"}) return - self.log("Reserve ip pool requires an update") + self.log("Reserve ip pool requires an update", "DEBUG") # Pool Exists - self.log("Reserved Ip Pool Cisco DNA Center Details " + str(self.have.get("reservePool"))) - self.log("Reserved Ip Pool User Details" + str(self.want.get("wantReserve"))) + self.log("Reserved Ip Pool Cisco DNA Center Details: {0}" + .format(self.have.get("reservePool")), "DEBUG") + self.log("Reserved Ip Pool User Details: {0}".format(self.want.get("wantReserve")), "DEBUG") reserve_params.update({"id": self.have.get("reservePool").get("id")}) response = self.dnac._exec( family="network_settings", @@ -1799,7 +1814,7 @@ def update_reserve_pool(self, config): params=reserve_params, ) self.check_execution_response_status(response).check_return_status() - self.log("Reserved Ip Subpool Updated Successfully") + self.log("Reserved Ip Subpool Updated Successfully", "INFO") result_reserve_pool['msg'] = "Reserved Ip Subpool Updated Successfully" result_reserve_pool.get("response").get(name) \ .update({"Reservation details": self.have.get("reservePool").get("details")}) @@ -1825,7 +1840,7 @@ def update_network(self, config): if not self.requires_update(self.have.get("network").get("net_details"), self.want.get("wantNetwork"), self.network_obj_params): - self.log("Network doesn't require an update") + self.log("Network doesn't require an update", "INFO") result_network.get("response").get(site_name).update({ "Cisco DNA Center params": self.have.get("network") .get("net_details").get("settings") @@ -1833,9 +1848,9 @@ def update_network(self, config): result_network.get("msg").update({site_name: "Network doesn't require an update"}) return - self.log("Network requires update") - self.log("Network Cisco DNA Center Details" + str(self.have.get("network"))) - self.log("Network User Details" + str(self.want.get("wantNetwork"))) + self.log("Network requires update", "INFO") + self.log("Network Cisco DNA Center Details: {0}".format(self.have.get("network")), "DEBUG") + self.log("Network User Details: {0}".format(self.want.get("wantNetwork")), "DEBUG") net_params = copy.deepcopy(self.want.get("wantNetwork")) net_params.update({"site_id": self.have.get("network").get("site_id")}) @@ -1844,10 +1859,10 @@ def update_network(self, config): function='update_network_v2', params=net_params, ) - self.log(str(response)) + self.log("Received API response of 'update_network_v2': {0}".format(response), "DEBUG") validation_string = "desired common settings operation successful" self.check_task_response_status(response, validation_string).check_return_status() - self.log("Network has been changed Successfully") + self.log("Network has been changed Successfully", "INFO") result_network.get("msg") \ .update({site_name: "Network Updated successfully"}) result_network.get("response").get(site_name) \ @@ -1898,10 +1913,10 @@ def delete_reserve_pool(self, name): self.status = "success" return self - self.log("Reserved Ip Pool to be deleted " + - str(self.have.get("reservePool").get("name"))) + self.log("Reserved Ip Pool to be Deleted: {0}" + .format(self.have.get("reservePool").get("name")), "INFO") _id = self.have.get("reservePool").get("id") - self.log("Reserve pool {0} id ".format(name) + str(_id)) + self.log("Reserve pool {0} id: {1}".format(name, _id), "DEBUG") response = self.dnac._exec( family="network_settings", function="release_reserve_ip_subpool", @@ -1993,30 +2008,34 @@ def verify_diff_merged(self, config): """ self.get_have(config) - self.log(str(self.have)) - self.log(str(self.want)) + self.log("Current State (have): {0}".format(self.have), "INFO") + self.log("Requested State (want): {0}".format(self.want), "INFO") if config.get("global_pool_details") is not None: - self.log(str(self.want.get("wantGlobal"))) - self.log(str(self.have.get("globalPool").get("details"))) + self.log("want_global_pool Details: {0}" + .format(self.want.get("wantGlobal")), "DEBUG") + self.log("have_global_pool Details: {0}" + .format(self.have.get("globalPool").get("details")), "DEBUG") if self.requires_update(self.have.get("globalPool").get("details"), self.want.get("wantGlobal"), self.global_pool_obj_params): self.msg = "Global Pool Config is not applied to the DNAC" self.status = "failed" return self - self.log("Successfully validated Global Pool") + self.log("Successfully validated Global Pool", "INFO") self.result.get("response")[0].get("globalPool").update({"Validation": "Success"}) if config.get("reserve_pool_details") is not None: if self.requires_update(self.have.get("reservePool").get("details"), self.want.get("wantReserve"), self.reserve_pool_obj_params): - self.log(str(self.want.get("wantReserve"))) - self.log(str(self.have.get("reservePool").get("details"))) + self.log("want_reserve_pool Details: {0}" + .format(self.want.get("wantReserve")), "DEBUG") + self.log("have_reserve_pool Details: {0}" + .format(self.have.get("reservePool").get("details")), "DEBUG") self.msg = "Reserve Pool Config is not applied to the DNAC" self.status = "failed" return self - self.log("Successfully validated the Reserve Pool") + self.log("Successfully validated the Reserve Pool", "INFO") self.result.get("response")[1].get("reservePool").update({"Validation": "Success"}) if config.get("network_management_details") is not None: @@ -2026,7 +2045,7 @@ def verify_diff_merged(self, config): self.status = "failed" return self - self.log("Successfully validated the Network Functions") + self.log("Successfully validated the Network Functions", "INFO") self.result.get("response")[2].get("network").update({"Validation": "Success"}) self.msg = "Successfully validated the Global Pool, Reserve Pool \ @@ -2048,8 +2067,8 @@ def verify_diff_deleted(self, config): """ self.get_have(config) - self.log("DNAC retrieved details: " + str(self.have)) - self.log("Playbook details: " + str(self.want)) + self.log("Current State (have): {0}".format(self.have), "INFO") + self.log("Desired State (want): {0}".format(self.want), "INFO") if config.get("global_pool_details") is not None: global_pool_exists = self.have.get("globalPool").get("exists") if global_pool_exists: @@ -2057,7 +2076,7 @@ def verify_diff_deleted(self, config): self.status = "failed" return self - self.log("Successfully validated absence of Global Pool") + self.log("Successfully validated absence of Global Pool", "INFO") self.result.get("response")[0].get("globalPool").update({"Validation": "Success"}) if config.get("reserve_pool_details") is not None: @@ -2067,7 +2086,7 @@ def verify_diff_deleted(self, config): self.status = "failed" return self - self.log("Successfully validated the absence of Reserve Pool") + self.log("Successfully validated the absence of Reserve Pool", "INFO") self.result.get("response")[1].get("reservePool").update({"Validation": "Success"}) self.msg = "Successfully validated the absence of Global Pool/Reserve Pool" @@ -2103,6 +2122,7 @@ def main(): "dnac_version": {"type": 'str', "default": '2.2.3.3'}, "dnac_debug": {"type": 'bool', "default": False}, "dnac_log": {"type": 'bool', "default": False}, + "dnac_log_level": {"type": "str", "default": "INFO"}, "config_verify": {"type": 'bool', "default": False}, "config": {"type": 'list', "required": True, "elements": 'dict'}, "state": {"default": 'merged', "choices": ['merged', 'deleted']}, diff --git a/plugins/modules/template_intent.py b/plugins/modules/template_intent.py index 33448313a7..a30da9983e 100644 --- a/plugins/modules/template_intent.py +++ b/plugins/modules/template_intent.py @@ -30,6 +30,11 @@ Akash Bhaskaran (@akabhask) Muthu Rakesh (@MUTHU-RAKESH-27) options: + dnac_log_level: + description: Specifies the desired log level for Cisco Catalyst Center logging. + Options - [CRITICAL, ERROR, WARNING, INFO, DEBUG] + type: str + default: INFO config_verify: description: Set to True to verify the Cisco DNA Center after applying the playbook config. type: bool @@ -1137,7 +1142,9 @@ dnac_version: "{{dnac_version}}" dnac_debug: "{{dnac_debug}}" dnac_log: True + dnac_log_level: "{{dnac_log_level}}" state: merged + config_verify: True config: - configuration_templates: author: string @@ -1451,7 +1458,7 @@ def validate_input(self): return self self.validated_config = valid_temp - self.log(str(valid_temp)) + self.log("Successfully validated playbook config params: {0}".format(valid_temp), "INFO") self.msg = "Successfully validated input" self.status = "success" return self @@ -1600,9 +1607,9 @@ def get_template_info(self, template_params): templateParams = [] i = 0 - self.log(str(template_params)) + self.log("Template Params Details: {0}".format(template_params), "DEBUG") for item in template_params: - self.log(str(item)) + self.log("Template Params Items: {0}".format(item), "DEBUG") templateParams.append({}) binding = item.get("binding") if binding is not None: @@ -1682,11 +1689,11 @@ def get_template_info(self, template_params): templateParams[i].update({"required": required}) range = item.get("range") - self.log(str(range)) + self.log("Template Params Range List: {0}".format(range), "DEBUG") if range is not None: templateParams[i].update({"range": []}) _range = templateParams[i].get("range") - self.log(str(_range)) + self.log("Template Params Range: {0}".format(_range), "DEBUG") j = 0 for value in range: _range.append({}) @@ -1709,9 +1716,9 @@ def get_template_info(self, template_params): return self.check_return_status() j = j + 1 - self.log(str(templateParams)) + self.log("Template Params Details: {0}".format(templateParams), "DEBUG") selection = item.get("selection") - self.log(str(selection)) + self.log("Template Params Selection: {0}".format(selection), "DEBUG") if selection is not None: templateParams[i].update({"selection": {}}) _selection = templateParams[i].get("selection") @@ -1835,7 +1842,7 @@ def get_template_params(self, params): temp_params (dict) - Organized template parameters. """ - self.log(str(params)) + self.log("Template Params Playbook Details: {0}".format(params), "DEBUG") temp_params = { "tags": self.get_tags(params.get("template_tag")), "author": params.get("author"), @@ -1870,12 +1877,12 @@ def get_template_params(self, params): "version": params.get("version"), "project_id": params.get("project_id") } - self.log(str(temp_params)) + self.log("Formatted Template Params Details: {0}".format(temp_params), "DEBUG") copy_temp_params = copy.deepcopy(temp_params) for item in copy_temp_params: if temp_params[item] is None: del temp_params[item] - self.log(str(temp_params)) + self.log("Formatted Template Params Details: {0}".format(temp_params), "DEBUG") return temp_params def get_template(self, config): @@ -1898,7 +1905,7 @@ def get_template(self, config): if items: result = items - self.log(str(items)) + self.log("Received API response from 'get_template_details': {0}".format(items), "DEBUG") self.result['response'] = items return result @@ -1923,13 +1930,13 @@ def get_have_project(self, config): # Hence check the projectName retrieved from DNAC. if not (project_details and isinstance(project_details, list)): self.log("Project: {0} not found, need to create new project in DNAC" - .format(given_projectName)) + .format(given_projectName), "INFO") return None fetched_projectName = project_details[0].get('name') if fetched_projectName != given_projectName: self.log("Project {0} provided is not exact match in DNAC DB" - .format(given_projectName)) + .format(given_projectName), "INFO") return None template_available = project_details[0].get('templates') @@ -1965,7 +1972,8 @@ def get_have_template(self, config, template_available): templateName) # Check if specified template in playbook is available if not template_details: - self.log("Template {0} not found in project {1}".format(templateName, projectName)) + self.log("Template {0} not found in project {1}" + .format(templateName, projectName), "INFO") self.msg = "Template : {0} missing, new template to be created".format(templateName) self.status = "success" return self @@ -1991,12 +1999,12 @@ def get_have_template(self, config, template_available): have_template["template_found"] = template is not None \ and isinstance(template, dict) self.log("Template {0} is found and template " - "details are :{1}".format(templateName, str(template))) + "details are :{1}".format(templateName, str(template)), "INFO") # There are committed templates in the project but the # one specified in the playbook may not be committed self.log("Commit pending for template name {0}" - " is {1}".format(templateName, have_template.get('isCommitPending'))) + " is {1}".format(templateName, have_template.get('isCommitPending')), "INFO") self.have_template = have_template self.msg = "Successfully collected all template parameters from dnac for comparison" @@ -2061,7 +2069,7 @@ def get_want(self, config): want = {} configuration_templates = config.get("configuration_templates") - self.log(str(config)) + self.log("Playbook Details: {0}".format(config), "INFO") if configuration_templates: template_params = self.get_template_params(configuration_templates) project_params = self.get_project_params(configuration_templates) @@ -2094,12 +2102,12 @@ def create_project_or_template(self, is_create_project=False): creation_id = None created = False - self.log(str(self.want)) + self.log("Desired State (want): {0}".format(self.want), "INFO") template_params = self.want.get("template_params") project_params = self.want.get("project_params") if is_create_project: - self.log("entered") + self.log("Project Created.", "DEBUG") params_key = project_params name = "project: {0}".format(project_params.get('name')) validation_string = "Successfully created project" @@ -2117,28 +2125,28 @@ def create_project_or_template(self, is_create_project=False): params=params_key, ) if not isinstance(response, dict): - self.log("Response not in dictionary format.") + self.log("Response not in dictionary format.", "CRITICAL") return creation_id, created task_id = response.get("response").get("taskId") if not task_id: - self.log("Task id {0} not found".format(task_id)) + self.log("Task id {0} not found".format(task_id), "CRITICAL") return creation_id, created while not created: task_details = self.get_task_details(task_id) if not task_details: - self.log("Failed to get task details for taskid: {0}".format(task_id)) + self.log("Failed to get task details for taskid: {0}".format(task_id), "CRITICAL") return creation_id, created - self.log("task_details: {0}".format(task_details)) + self.log("task_details: {0}".format(task_details), "DEBUG") if task_details.get("isError"): - self.log("isError set to true for taskid: {0}".format(task_id)) + self.log("isError set to true for taskid: {0}".format(task_id), "ERROR") return creation_id, created if validation_string not in task_details.get("progress"): - self.log("progress set to {0} " - "for taskid: {1}".format(task_details.get('progress'), task_id)) + self.log("progress set to {0} for taskid: {1}" + .format(task_details.get('progress'), task_id), "DEBUG") continue task_details_data = task_details.get("data") @@ -2148,7 +2156,7 @@ def create_project_or_template(self, is_create_project=False): else: creation_id = value.get("templateId") if not creation_id: - self.log("data is not found for taskid: {0}".format(task_id)) + self.log("Data is not found for taskid: {0}".format(task_id), "DEBUG") continue created = True @@ -2158,7 +2166,7 @@ def create_project_or_template(self, is_create_project=False): template_params["projectId"] = creation_id template_params["project_id"] = creation_id - self.log("New {0} created with id {1}".format(name, creation_id)) + self.log("New {0} created with id {1}".format(name, creation_id), "DEBUG") return creation_id, created def requires_update(self): @@ -2175,13 +2183,13 @@ def requires_update(self): """ if self.have_template.get("isCommitPending"): - self.log("Template is in saved state and needs to be updated and committed") + self.log("Template is in saved state and needs to be updated and committed.", "DEBUG") return True current_obj = self.have_template.get("template") requested_obj = self.want.get("template_params") - self.log(str(current_obj)) - self.log(str(requested_obj)) + self.log("Current State (have): {0}".format(current_obj), "INFO") + self.log("Desired State (want): {0}".format(requested_obj), "INFO") obj_params = [ ("tags", "tags", ""), ("author", "author", ""), @@ -2295,19 +2303,24 @@ def get_export_template_values(self, export_values): function='get_projects_details' ) for values in export_values: - self.log(str(values.get("project_name"))) + project_name = values.get("project_name") + self.log("Project Name for Export Template: {0}".format(project_name), "DEBUG") template_details = template_details.get("response") - self.log(str(template_details)) + self.log("Template Details: {0}".format(template_details), "DEBUG") all_template_details = get_dict_result(template_details, "name", - values.get("project_name")) - self.log(str(all_template_details)) + project_name) + self.log("Template Details under the Project Name {0}: {1}" + .format(project_name, all_template_details), "DEBUG") all_template_details = all_template_details.get("templates") - self.log(str(all_template_details)) + self.log("Template Details under the Project Name {0}: {1}" + .format(project_name, all_template_details), "DEBUG") + template_name = values.get("template_name") template_detail = get_dict_result(all_template_details, "name", - values.get("template_name")) - self.log(str(template_detail)) + template_name) + self.log("Template Details with Template Name {0}: {1}" + .format(template_name, template_detail), "DEBUG") if template_detail is None: self.msg = "Invalid project_name and template_name in export" self.status = "failed" @@ -2336,7 +2349,7 @@ def update_configuration_templates(self, config): project_id, project_created = \ self.create_project_or_template(is_create_project=True) if project_created: - self.log("project created with projectId : {0}".format(project_id)) + self.log("project created with projectId: {0}".format(project_id), "DEBUG") else: self.status = "failed" self.msg = "Project creation failed" @@ -2344,8 +2357,8 @@ def update_configuration_templates(self, config): is_template_found = self.have_template.get("template_found") template_params = self.want.get("template_params") - self.log(str(template_params)) - self.log(str(self.have_template)) + self.log("Template Details in Playbook: {0}".format(template_params), "DEBUG") + self.log("Template Details in DNAC: {0}".format(self.have_template), "DEBUG") template_id = None template_updated = False self.validate_input_merge(is_template_found).check_return_status() @@ -2353,8 +2366,8 @@ def update_configuration_templates(self, config): if self.requires_update(): template_id = self.have_template.get("id") template_params.update({"id": template_id}) - self.log(str(self.have_template)) - self.log(str(self.want)) + self.log("Current State (have): {0}".format(self.have_template), "INFO") + self.log("Desired State (want): {0}".format(self.want), "INFO") response = self.dnac_apply['exec']( family="configuration_templates", function="update_template", @@ -2362,7 +2375,7 @@ def update_configuration_templates(self, config): op_modifies=True, ) template_updated = True - self.log("Updating Existing Template") + self.log("Updating Existing Template.", "INFO") else: # Template does not need update self.result.update({ @@ -2400,7 +2413,7 @@ def update_configuration_templates(self, config): self.result['changed'] = True self.result['msg'] = task_details.get('progress') self.result['diff'] = config.get("configuration_templates") - self.log(str(task_details)) + self.log("Task Details: {0}".format(task_details), "DEBUG") self.result['response'] = task_details if task_details else response if not self.result.get('msg'): @@ -2422,7 +2435,8 @@ def handle_export(self, config): export = config.get("export") if export: export_project = export.get("project") - self.log(str(export_project)) + self.log("Export Project Playbook Details: {0}" + .format(export_project), "DEBUG") if export_project: response = self.dnac._exec( family="configuration_templates", @@ -2438,7 +2452,8 @@ def handle_export(self, config): export_values = export.get("template") if export_values: self.get_export_template_values(export_values).check_return_status() - self.log(str(self.export_template)) + self.log("Export Template Playbook Details: {0}" + .format(self.export_template), "DEBUG") response = self.dnac._exec( family="configuration_templates", function='export_templates', @@ -2479,7 +2494,8 @@ def handle_import(self, config): # "payload": "{0}".format(payload) "payload": payload } - self.log(str(_import_project)) + self.log("Import Project Details from the Playbook: {0}" + .format(_import_project), "DEBUG") if _import_project: response = self.dnac._exec( family="configuration_templates", @@ -2506,7 +2522,8 @@ def handle_import(self, config): "projectName": _import_template.get("project_name"), "payload": self.get_template_params(payload) } - self.log(str(_import_template)) + self.log("Import Template Details from the Playbook: {0}" + .format(_import_template), "DEBUG") if _import_template: response = self.dnac._exec( family="configuration_templates", @@ -2583,7 +2600,7 @@ def delete_project_or_template(self, config, is_delete_project=False): self.result['msg'] = task_details.get('progress') self.result['diff'] = config.get("configuration_templates") - self.log(str(task_details)) + self.log("Task Details: {0}".format(task_details), "DEBUG") self.result['response'] = task_details if task_details else response if not self.result['msg']: self.result['msg'] = "Error while deleting {name} : " @@ -2626,7 +2643,8 @@ def get_diff_deleted(self, config): self.status = "failed" return self else: - self.log("Template Name is empty, deleting the project and associated templates") + self.log("Template Name is empty, deleting the project and " + "associated templates", "INFO") is_project_deletable = self.have_project.get("isDeletable") if is_project_deletable: self.delete_project_or_template(config, is_delete_project=True) @@ -2654,15 +2672,15 @@ def verify_diff_merged(self, config): if config.get("configuration_templates") is not None: is_template_available = self.get_have_project(config) - self.log(str(is_template_available)) + self.log("Template Availability: {0}".format(is_template_available), "INFO") if not is_template_available: self.msg = "Configuration Template config is not applied to the DNAC." self.status = "failed" return self self.get_have_template(config, is_template_available) - self.log("DNAC retrieved details: " + str(self.have_template.get("template"))) - self.log("Playbook details: " + str(self.want.get("template_params"))) + self.log("Current State (have): {0}".format(self.want.get("template_params")), "INFO") + self.log("Desired State (want): {0}".format(self.have_template.get("template")), "INFO") template_params = ["language", "name", "projectName", "softwareType", "softwareVariant", "templateContent"] for item in template_params: @@ -2670,6 +2688,7 @@ def verify_diff_merged(self, config): self.msg = " Configuration Template config is not applied to the DNAC." self.status = "failed" return self + self.log("Successfully validated the Template in the DNAC.", "INFO") self.result.get("response").update({"Validation": "Success"}) self.msg = "Successfully validated the Configuration Templates." @@ -2690,8 +2709,8 @@ def verify_diff_deleted(self, config): """ if config.get("configuration_templates") is not None: - self.log("DNAC retrieved details: " + str(self.have)) - self.log("Playbook details: " + str(self.want)) + self.log("Current State (have): {0}".format(self.have), "INFO") + self.log("Desired State (want): {0}".format(self.want), "INFO") template_list = self.dnac_apply['exec']( family="configuration_templates", function="gets_the_templates_available", @@ -2707,7 +2726,7 @@ def verify_diff_deleted(self, config): self.status = "failed" return self - self.log("Successfully validated absence of Template in the DNAC.") + self.log("Successfully validated absence of Template in the DNAC.", "INFO") self.result.get("response").update({"Validation": "Success"}) self.msg = "Successfully validated the absence of Template in the DNAC." @@ -2741,6 +2760,7 @@ def main(): 'dnac_version': {'type': 'str', 'default': '2.2.3.3'}, 'dnac_debug': {'type': 'bool', 'default': False}, 'dnac_log': {'type': 'bool', 'default': False}, + "dnac_log_level": {"type": "str", "default": "INFO"}, 'validate_response_schema': {'type': 'bool', 'default': True}, "config_verify": {"type": 'bool', "default": False}, 'config': {'required': True, 'type': 'list', 'elements': 'dict'}, From 8c29406a12f6f2cfd6833023314beb047dee8858 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Wed, 24 Jan 2024 20:12:22 +0530 Subject: [PATCH 14/16] Removing unused import statements --- plugins/modules/network_settings_intent.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/modules/network_settings_intent.py b/plugins/modules/network_settings_intent.py index 4750a61b04..fe86b97c7a 100644 --- a/plugins/modules/network_settings_intent.py +++ b/plugins/modules/network_settings_intent.py @@ -411,7 +411,6 @@ """ import copy -from multiprocessing.util import ForkAwareThreadLock from ansible.module_utils.basic import AnsibleModule from ansible_collections.cisco.dnac.plugins.module_utils.dnac import ( DnacBase, From 94b97e0d03d97ee3639b11dbb6dcb6cd84a262f7 Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Thu, 25 Jan 2024 14:42:13 +0530 Subject: [PATCH 15/16] Refactored the logs and addressed the PR comments --- plugins/modules/device_credential_intent.py | 38 +++--- plugins/modules/network_settings_intent.py | 128 +++++++++++--------- plugins/modules/template_intent.py | 84 +++++++------ 3 files changed, 132 insertions(+), 118 deletions(-) diff --git a/plugins/modules/device_credential_intent.py b/plugins/modules/device_credential_intent.py index 43d4b0205e..375a5d7972 100644 --- a/plugins/modules/device_credential_intent.py +++ b/plugins/modules/device_credential_intent.py @@ -920,7 +920,7 @@ def get_global_credentials_params(self): function='get_all_global_credentials_v2', ) global_credentials = global_credentials.get("response") - self.log("All Global Device Credentials Details: {0}" + self.log("All global device credentials details: {0}" .format(global_credentials), "DEBUG") except Exception as exec: self.log("Exception occurred while getting global device credentials: {0}" @@ -1473,7 +1473,7 @@ def get_have_device_credentials(self, CredentialDetails): snmpV3 = self.get_snmpV3_params(snmpV3Details) self.have.get("globalCredential").update({"snmpV3": snmpV3}) - self.log("Global Device Credential Details: {0}" + self.log("Global device credential details: {0}" .format(self.have.get("globalCredential")), "DEBUG") self.msg = "Collected the Global Device Credential Details from the Cisco DNA Center" self.status = "success" @@ -1684,7 +1684,7 @@ def get_want_device_credentials(self, CredentialDetails): values = ["password", "description", "username", "id", "port"] have_httpsRead = self.have.get("globalCredential").get("httpsRead") for item in httpsRead: - self.log("Global Credentials Details: {0}" + self.log("Global credentials details: {0}" .format(self.have.get("globalCredential")), "DEBUG") if not have_httpsRead or have_httpsRead[have_httpsread_ptr] is None: if want.get("want_create").get("httpsRead") is None: @@ -1834,7 +1834,7 @@ def get_want_device_credentials(self, CredentialDetails): self.msg = "auth_password length should be greater than 8" self.status = "failed" return self - self.log("snmpMode: {0}".format(create_credential[create_snmpv3_ptr] + self.log("snmp_mode: {0}".format(create_credential[create_snmpv3_ptr] .get("snmpMode")), "DEBUG") if create_credential[create_snmpv3_ptr].get("snmpMode") == "AUTHPRIV": privs = ["privacy_password", "privacy_type"] @@ -2197,7 +2197,7 @@ def create_device_credentials(self): return self credential_params = want_create - self.log("Creating Global Credential API input parameters: {0}" + self.log("Creating global credential API input parameters: {0}" .format(credential_params), "DEBUG") response = self.dnac._exec( family="discovery", @@ -2208,7 +2208,7 @@ def create_device_credentials(self): .format(response), "DEBUG") validation_string = "global credential addition performed" self.check_task_response_status(response, validation_string).check_return_status() - self.log("Global Credential Created Successfully", "INFO") + self.log("Global credential created successfully", "INFO") result_global_credential.update({ "Creation": { "response": credential_params, @@ -2251,7 +2251,7 @@ def update_device_credentials(self): values = ["cliCredential", "snmpV2cRead", "snmpV2cWrite", "httpsRead", "httpsWrite", "snmpV3"] final_response = [] - self.log("Desired State for Updation: {0}".format(want_update), "DEBUG") + self.log("Desired State for updation: {0}".format(want_update), "DEBUG") while flag: flag = False credential_params = {} @@ -2271,9 +2271,9 @@ def update_device_credentials(self): .format(response), "DEBUG") validation_string = "global credential update performed" self.check_task_response_status(response, validation_string).check_return_status() - self.log("Updating Device Credential API input parameters: {0}" + self.log("Updating device credential API input parameters: {0}" .format(final_response), "DEBUG") - self.log("Global Device Credential Updated Successfully", "INFO") + self.log("Global device credential updated successfully", "INFO") result_global_credential.update({ "Updation": { "response": final_response, @@ -2300,7 +2300,7 @@ def assign_credentials_to_site(self): result_assign_credential = self.result.get("response")[0].get("assignCredential") credential_params = self.want.get("assign_credentials") final_response = [] - self.log("Assigning Device Credential to site API input parameters: {0}" + self.log("Assigning device credential to site API input parameters: {0}" .format(credential_params), "DEBUG") if not credential_params: result_assign_credential.update({ @@ -2322,13 +2322,13 @@ def assign_credentials_to_site(self): function='assign_device_credential_to_site_v2', params=credential_params, ) - self.log("Response for API assign_device_credential_to_site_v2: {0}" + self.log("Received API response for 'assign_device_credential_to_site_v2': {0}" .format(response), "DEBUG") validation_string = "desired common settings operation successful" self.check_task_response_status(response, validation_string).check_return_status() - self.log("Device Credential Assigned to site {0} is Successfully." + self.log("Device credential assigned to site {0} is successfully." .format(site_ids), "INFO") - self.log("Desired State for Assign Credentials to a Site: {0}" + self.log("Desired State for assign credentials to a site: {0}" .format(final_response), "DEBUG") result_assign_credential.update({ "Assign Credentials": { @@ -2380,7 +2380,7 @@ def delete_device_credential(self, config): result_global_credential = self.result.get("response")[0].get("globalCredential") have_values = self.have.get("globalCredential") final_response = {} - self.log("Global Device Credentials to be Deleted: {0}".format(have_values), "DEBUG") + self.log("Global device credentials to be deleted: {0}".format(have_values), "DEBUG") credential_mapping = { "cliCredential": "cli_credential", "snmpV2cRead": "snmp_v2c_read", @@ -2415,9 +2415,9 @@ def delete_device_credential(self, config): final_response.get(item).append(_id) config_itr = config_itr + 1 - self.log("Deleting Device Credential API input parameters: {0}" + self.log("Deleting device credential API input parameters: {0}" .format(final_response), "DEBUG") - self.log("Successfully Deleted Global Device Credential.", "INFO") + self.log("Successfully deleted global device credential.", "INFO") result_global_credential.update({ "Deletion": { "response": final_response, @@ -2494,11 +2494,11 @@ def verify_diff_merged(self, config): self.status = "failed" return self - self.log("Successfully validated Global Device Credential", "INFO") + self.log("Successfully validated global device credential", "INFO") self.result.get("response")[0].get("globalCredential").update({"Validation": "Success"}) if config.get("assign_credentials_to_site") is not None: - self.log("Successfully validated the Assign Device Credential to Site", "INFO") + self.log("Successfully validated the assign device credential to site", "INFO") self.result.get("response")[0].get("assignCredential").update({"Validation": "Success"}) self.msg = "Successfully validated the Global Device Credential and \ @@ -2535,7 +2535,7 @@ def verify_diff_deleted(self, config): self.status = "failed" return self - self.log("Successfully validated absence of Global Device Credential.", "INFO") + self.log("Successfully validated absence of global device credential.", "INFO") self.result.get("response")[0].get("globalCredential").update({"Validation": "Success"}) self.msg = "Successfully validated the absence of Global Device Credential." diff --git a/plugins/modules/network_settings_intent.py b/plugins/modules/network_settings_intent.py index fe86b97c7a..384944e1f1 100644 --- a/plugins/modules/network_settings_intent.py +++ b/plugins/modules/network_settings_intent.py @@ -636,9 +636,10 @@ def get_obj_params(self, get_object): ("site_name", "site_name") ] else: - raise ValueError("Unexpected value: {0}".format(get_object)) + raise ValueError("Received an unexpected value for 'get_object': {0}" + .format(get_object)) except Exception as msg: - self.log("Error message: {0}".format(msg), "CRITICAL") + self.log("Received exception: {0}".format(msg), "CRITICAL") return obj_params @@ -703,14 +704,14 @@ def get_global_pool_params(self, pool_info): }] } } - self.log("Formated Global Pool Details: {0}".format(global_pool), "DEBUG") + self.log("Formated global pool details: {0}".format(global_pool), "DEBUG") global_ippool = global_pool.get("settings").get("ippool")[0] if pool_info.get("ipv6") is False: global_ippool.update({"IpAddressSpace": "IPv4"}) else: global_ippool.update({"IpAddressSpace": "IPv6"}) - self.log("IpAddressSpace: {0}".format(global_ippool.get("IpAddressSpace")), "DEBUG") + self.log("ip_address_space: {0}".format(global_ippool.get("IpAddressSpace")), "DEBUG") if not pool_info["gateways"]: global_ippool.update({"gateway": ""}) else: @@ -789,7 +790,7 @@ def get_reserve_pool_params(self, pool_info): else: reserve_pool.update({"ipv4GateWay": ""}) reserve_pool.update({"slaacSupport": True}) - self.log("Formatted Reserve Pool Details: {0}".format(reserve_pool), "DEBUG") + self.log("Formatted reserve pool details: {0}".format(reserve_pool), "DEBUG") return reserve_pool def get_network_params(self, site_id): @@ -969,8 +970,8 @@ def global_pool_exists(self, name): all_global_pool_details = response.get("response") global_pool_details = get_dict_result(all_global_pool_details, "ipPoolName", name) - self.log("Global Ippool Name: {0}".format(name), "DEBUG") - self.log("Global Pool Details: {0}".format(global_pool_details), "DEBUG") + self.log("Global ip pool name: {0}".format(name), "DEBUG") + self.log("Global pool details: {0}".format(global_pool_details), "DEBUG") if not global_pool_details: self.log("Global pool {0} does not exist".format(name), "INFO") return global_pool @@ -978,7 +979,7 @@ def global_pool_exists(self, name): global_pool.update({"id": global_pool_details.get("id")}) global_pool["details"] = self.get_global_pool_params(global_pool_details) - self.log("Formatted Global Pool Details: {0}".format(global_pool), "DEBUG") + self.log("Formatted global pool details: {0}".format(global_pool), "DEBUG") return global_pool def reserve_pool_exists(self, name, site_name): @@ -1004,7 +1005,7 @@ def reserve_pool_exists(self, name, site_name): "success": True } site_id = self.get_site_id(site_name) - self.log("Site ID for the Site Name {0}: {1}".format(site_name, site_id), "DEBUG") + self.log("Site ID for the site name {0}: {1}".format(site_name, site_id), "DEBUG") if not site_id: reserve_pool.update({"success": False}) self.msg = "Failed to get the site id from the site name {0}".format(site_name) @@ -1025,7 +1026,7 @@ def reserve_pool_exists(self, name, site_name): all_reserve_pool_details = response.get("response") reserve_pool_details = get_dict_result(all_reserve_pool_details, "groupName", name) if not reserve_pool_details: - self.log("Reserve pool {0} does not exist in the site {1}" + self.log("Reserved pool {0} does not exist in the site {1}" .format(name, site_name), "DEBUG") return reserve_pool @@ -1033,8 +1034,8 @@ def reserve_pool_exists(self, name, site_name): reserve_pool.update({"id": reserve_pool_details.get("id")}) reserve_pool.update({"details": self.get_reserve_pool_params(reserve_pool_details)}) - self.log("Reserved Pool Details: {0}".format(reserve_pool.get("details")), "DEBUG") - self.log("Reserved Pool Id: {0}".format(reserve_pool.get("id")), "DEBUG") + self.log("Reserved pool details: {0}".format(reserve_pool.get("details")), "DEBUG") + self.log("Reserved pool id: {0}".format(reserve_pool.get("id")), "DEBUG") return reserve_pool def get_have_global_pool(self, config): @@ -1076,7 +1077,7 @@ def get_have_global_pool(self, config): # If the Global Pool doesn't exist and a previous name is provided # Else try using the previous name global_pool = self.global_pool_exists(name) - self.log("Global Pool Details: {0}".format(global_pool), "DEBUG") + self.log("Global pool details: {0}".format(global_pool), "DEBUG") prev_name = global_pool_ippool[0].get("prev_name") if global_pool.get("exists") is False and \ prev_name is not None: @@ -1086,7 +1087,7 @@ def get_have_global_pool(self, config): self.status = "failed" return self - self.log("Global Pool Exists: {0}".format(global_pool.get("exists")), "DEBUG") + self.log("Global pool exists: {0}".format(global_pool.get("exists")), "DEBUG") self.log("Current Site: {0}".format(global_pool.get("details")), "DEBUG") self.have.update({"globalPool": global_pool}) self.msg = "Collecting the global pool details from the Cisco DNA Center" @@ -1130,7 +1131,7 @@ def get_have_reserve_pool(self, config): reserve_pool = self.reserve_pool_exists(name, site_name) if not reserve_pool.get("success"): return self.check_return_status() - self.log("Reserve Pool Details: {0}".format(reserve_pool), "DEBUG") + self.log("Reserved pool details: {0}".format(reserve_pool), "DEBUG") # If the Reserved Pool doesn't exist and a previous name is provided # Else try using the previous name @@ -1147,8 +1148,8 @@ def get_have_reserve_pool(self, config): self.status = "failed" return self - self.log("Reservation Exists: {0}".format(reserve_pool.get("exists")), "DEBUG") - self.log("Reserved Pool: {0}".format(reserve_pool.get("details")), "DEBUG") + self.log("Reserved pool exists: {0}".format(reserve_pool.get("exists")), "DEBUG") + self.log("Reserved pool: {0}".format(reserve_pool.get("details")), "DEBUG") # If reserve pool exist, convert ipv6AddressSpace to the required format (boolean) if reserve_pool.get("exists"): @@ -1158,7 +1159,7 @@ def get_have_reserve_pool(self, config): else: reserve_pool_details.update({"ipv6AddressSpace": True}) - self.log("Reserve Pool Details: {0}".format(reserve_pool), "DEBUG") + self.log("Reserved pool details: {0}".format(reserve_pool), "DEBUG") self.have.update({"reservePool": reserve_pool}) self.msg = "Collecting the reserve pool details from the Cisco DNA Center" self.status = "success" @@ -1190,7 +1191,7 @@ def get_have_network(self, config): network["site_id"] = site_id network["net_details"] = self.get_network_params(site_id) - self.log("Network Details from the Cisco DNA Center: {0}".format(network), "DEBUG") + self.log("Network details from the Catalyst Center: {0}".format(network), "DEBUG") self.have.update({"network": network}) self.msg = "Collecting the network details from the Cisco DNA Center" self.status = "success" @@ -1282,7 +1283,7 @@ def get_want_global_pool(self, global_ippool): if want_ippool.get(key) is None and have_ippool.get(key) is not None: want_ippool[key] = have_ippool[key] - self.log("Global Pool Playbook Details: {0}".format(want_global), "DEBUG") + self.log("Global pool playbook details: {0}".format(want_global), "DEBUG") self.want.update({"wantGlobal": want_global}) self.msg = "Collecting the global pool details from the playbook" self.status = "success" @@ -1346,7 +1347,7 @@ def get_want_reserve_pool(self, reserve_pool): self.status = "failed" return self - self.log("Reserve IP Pool Playbook Details: {0}".format(want_reserve), "DEBUG") + self.log("Reserved IP pool playbook details: {0}".format(want_reserve), "DEBUG") # If there are no existing Reserved Pool details, validate and set defaults if not self.have.get("reservePool").get("details"): @@ -1632,7 +1633,7 @@ def get_want_network(self, network_management_details): else: del want_network_settings["clientAndEndpoint_aaa"] - self.log("Network Playbook Details: {0}".format(want_network), "DEBUG") + self.log("Network playbook details: {0}".format(want_network), "DEBUG") self.want.update({"wantNetwork": want_network}) self.msg = "Collecting the network details from the playbook" self.status = "success" @@ -1686,14 +1687,14 @@ def update_global_pool(self, config): # Check pool exist, if not create and return if not self.have.get("globalPool").get("exists"): pool_params = self.want.get("wantGlobal") - self.log("Playbook Global Pool Details: {0}".format(pool_params), "DEBUG") + self.log("Desired State for global pool (want): {0}".format(pool_params), "DEBUG") response = self.dnac._exec( family="network_settings", function="create_global_pool", params=pool_params, ) self.check_execution_response_status(response).check_return_status() - self.log("Successfully Created Global Pool.", "INFO") + self.log("Successfully created global pool '{0}'.".format(name), "INFO") result_global_pool.get("response").get(name) \ .update({"globalPool Details": self.want.get("wantGlobal")}) result_global_pool.get("msg").update({name: "Global Pool Created Successfully"}) @@ -1702,7 +1703,7 @@ def update_global_pool(self, config): # Pool exists, check update is required if not self.requires_update(self.have.get("globalPool").get("details"), self.want.get("wantGlobal"), self.global_pool_obj_params): - self.log("Global pool doesn't requires an update", "INFO") + self.log("Global pool '{0}' doesn't require an update".format(name), "INFO") result_global_pool.get("response").get(name).update({ "Cisco DNA Center params": self.have.get("globalPool").get("details").get("settings").get("ippool")[0] @@ -1713,15 +1714,14 @@ def update_global_pool(self, config): result_global_pool.get("msg").update({ name: "Global pool doesn't require an update" }) - self.log("Result: {0}".format(self.result), "DEBUG") return - self.log("Global Pool requires update", "DEBUG") + self.log("Global pool requires update", "DEBUG") # Pool Exists pool_params = copy.deepcopy(self.want.get("wantGlobal")) pool_params_ippool = pool_params.get("settings").get("ippool")[0] pool_params_ippool.update({"id": self.have.get("globalPool").get("id")}) - self.log("Playbook Global Pool Details: {0}".format(pool_params), "DEBUG") + self.log("Desired State for global pool (want): {0}".format(pool_params), "DEBUG") keys_to_remove = ["IpAddressSpace", "ipPoolCidr", "type"] for key in keys_to_remove: del pool_params["settings"]["ippool"][0][key] @@ -1732,7 +1732,7 @@ def update_global_pool(self, config): if pool_params_ippool.get(key) is None: pool_params_ippool[key] = have_ippool.get(key) - self.log("Playbook Global Pool Details: {0}".format(pool_params), "DEBUG") + self.log("Desired global pool details (want): {0}".format(pool_params), "DEBUG") response = self.dnac._exec( family="network_settings", function="update_global_pool", @@ -1740,7 +1740,7 @@ def update_global_pool(self, config): ) self.check_execution_response_status(response).check_return_status() - self.log("Global Pool Updated Successfully", "INFO") + self.log("Global pool '{0}' updated successfully".format(name), "INFO") result_global_pool.get("response").get(name) \ .update({"Id": self.have.get("globalPool").get("details").get("id")}) result_global_pool.get("msg").update({name: "Global Pool Updated Successfully"}) @@ -1762,27 +1762,27 @@ def update_reserve_pool(self, config): name = config.get("reserve_pool_details").get("name") result_reserve_pool = self.result.get("response")[1].get("reservePool") result_reserve_pool.get("response").update({name: {}}) - self.log("Reserve Pool Cisco DNA Center Details: {0}" + self.log("Current reserved pool details in Catalyst Center: {0}" .format(self.have.get("reservePool").get("details")), "DEBUG") - self.log("Reserve Pool User Details: {0}" + self.log("Desired reserved pool details in Catalyst Center: {0}" .format(self.want.get("wantReserve")), "DEBUG") # Check pool exist, if not create and return - self.log("ipv4_global_pool: {0}" + self.log("Ipv4 global pool: {0}" .format(self.want.get("wantReserve").get("ipv4GlobalPool")), "DEBUG") site_name = config.get("reserve_pool_details").get("site_name") reserve_params = self.want.get("wantReserve") site_id = self.get_site_id(site_name) reserve_params.update({"site_id": site_id}) if not self.have.get("reservePool").get("exists"): - self.log("Reserve Pool Playbook Details: {0}".format(reserve_params), "DEBUG") + self.log("Desired reserved pool details (want): {0}".format(reserve_params), "DEBUG") response = self.dnac._exec( family="network_settings", function="reserve_ip_subpool", params=reserve_params, ) self.check_execution_response_status(response).check_return_status() - self.log("Ip Subpool Reservation Created Successfully", "INFO") + self.log("Successfully created IP subpool reservation '{0}'.".format(name), "INFO") result_reserve_pool.get("response").get(name) \ .update({"reservePool Details": self.want.get("wantReserve")}) result_reserve_pool.get("msg") \ @@ -1792,7 +1792,7 @@ def update_reserve_pool(self, config): # Check update is required if not self.requires_update(self.have.get("reservePool").get("details"), self.want.get("wantReserve"), self.reserve_pool_obj_params): - self.log("Reserved ip subpool doesn't require an update", "INFO") + self.log("Reserved ip subpool '{0}' doesn't require an update".format(name), "INFO") result_reserve_pool.get("response").get(name) \ .update({"Cisco DNA Center params": self.have.get("reservePool").get("details")}) result_reserve_pool.get("response").get(name) \ @@ -1801,11 +1801,12 @@ def update_reserve_pool(self, config): .update({name: "Reserve ip subpool doesn't require an update"}) return - self.log("Reserve ip pool requires an update", "DEBUG") + self.log("Reserved ip pool '{0}' requires an update".format(name), "DEBUG") # Pool Exists - self.log("Reserved Ip Pool Cisco DNA Center Details: {0}" - .format(self.have.get("reservePool")), "DEBUG") - self.log("Reserved Ip Pool User Details: {0}".format(self.want.get("wantReserve")), "DEBUG") + self.log("Current reserved ip pool '{0}' details in Catalyst Center: {1}" + .format(name, self.have.get("reservePool")), "DEBUG") + self.log("Desired reserved ip pool '{0}' details: {1}" + .format(name, self.want.get("wantReserve")), "DEBUG") reserve_params.update({"id": self.have.get("reservePool").get("id")}) response = self.dnac._exec( family="network_settings", @@ -1813,7 +1814,7 @@ def update_reserve_pool(self, config): params=reserve_params, ) self.check_execution_response_status(response).check_return_status() - self.log("Reserved Ip Subpool Updated Successfully", "INFO") + self.log("Reserved ip subpool '{0}' updated successfully.".format(name), "INFO") result_reserve_pool['msg'] = "Reserved Ip Subpool Updated Successfully" result_reserve_pool.get("response").get(name) \ .update({"Reservation details": self.have.get("reservePool").get("details")}) @@ -1839,7 +1840,7 @@ def update_network(self, config): if not self.requires_update(self.have.get("network").get("net_details"), self.want.get("wantNetwork"), self.network_obj_params): - self.log("Network doesn't require an update", "INFO") + self.log("Network in site '{0}' doesn't require an update.".format(site_name), "INFO") result_network.get("response").get(site_name).update({ "Cisco DNA Center params": self.have.get("network") .get("net_details").get("settings") @@ -1847,9 +1848,10 @@ def update_network(self, config): result_network.get("msg").update({site_name: "Network doesn't require an update"}) return - self.log("Network requires update", "INFO") - self.log("Network Cisco DNA Center Details: {0}".format(self.have.get("network")), "DEBUG") - self.log("Network User Details: {0}".format(self.want.get("wantNetwork")), "DEBUG") + self.log("Network in site '{0}' requires update.".format(site_name), "INFO") + self.log("Current State of network in Catalyst Center: {0}" + .format(self.have.get("network")), "DEBUG") + self.log("Desired State of network: {0}".format(self.want.get("wantNetwork")), "DEBUG") net_params = copy.deepcopy(self.want.get("wantNetwork")) net_params.update({"site_id": self.have.get("network").get("site_id")}) @@ -1861,7 +1863,7 @@ def update_network(self, config): self.log("Received API response of 'update_network_v2': {0}".format(response), "DEBUG") validation_string = "desired common settings operation successful" self.check_task_response_status(response, validation_string).check_return_status() - self.log("Network has been changed Successfully", "INFO") + self.log("Network has been changed successfully", "INFO") result_network.get("msg") \ .update({site_name: "Network Updated successfully"}) result_network.get("response").get(site_name) \ @@ -1912,10 +1914,10 @@ def delete_reserve_pool(self, name): self.status = "success" return self - self.log("Reserved Ip Pool to be Deleted: {0}" + self.log("Reserved IP pool scheduled for deletion: {0}" .format(self.have.get("reservePool").get("name")), "INFO") _id = self.have.get("reservePool").get("id") - self.log("Reserve pool {0} id: {1}".format(name, _id), "DEBUG") + self.log("Reserved pool {0} id: {1}".format(name, _id), "DEBUG") response = self.dnac._exec( family="network_settings", function="release_reserve_ip_subpool", @@ -1929,7 +1931,7 @@ def delete_reserve_pool(self, name): .update({"Execution Id": executionid}) result_reserve_pool.get("msg") \ .update({name: "Ip subpool reservation released successfully"}) - self.msg = "Reserve pool - {0} released successfully".format(name) + self.msg = "Reserved pool - {0} released successfully".format(name) self.status = "success" return self @@ -2010,9 +2012,9 @@ def verify_diff_merged(self, config): self.log("Current State (have): {0}".format(self.have), "INFO") self.log("Requested State (want): {0}".format(self.want), "INFO") if config.get("global_pool_details") is not None: - self.log("want_global_pool Details: {0}" + self.log("Desired State of global pool (want): {0}" .format(self.want.get("wantGlobal")), "DEBUG") - self.log("have_global_pool Details: {0}" + self.log("Current State of global pool (have): {0}" .format(self.have.get("globalPool").get("details")), "DEBUG") if self.requires_update(self.have.get("globalPool").get("details"), self.want.get("wantGlobal"), self.global_pool_obj_params): @@ -2020,21 +2022,23 @@ def verify_diff_merged(self, config): self.status = "failed" return self - self.log("Successfully validated Global Pool", "INFO") + self.log("Successfully validated global pool '{0}'.".format(self.want + .get("wantGlobal").get("settings").get("ippool")[0].get("ipPoolName")), "INFO") self.result.get("response")[0].get("globalPool").update({"Validation": "Success"}) if config.get("reserve_pool_details") is not None: if self.requires_update(self.have.get("reservePool").get("details"), self.want.get("wantReserve"), self.reserve_pool_obj_params): - self.log("want_reserve_pool Details: {0}" + self.log("Desired State for reserve pool (want): {0}" .format(self.want.get("wantReserve")), "DEBUG") - self.log("have_reserve_pool Details: {0}" + self.log("Current State for reserve pool (have): {0}" .format(self.have.get("reservePool").get("details")), "DEBUG") - self.msg = "Reserve Pool Config is not applied to the DNAC" + self.msg = "Reserved Pool Config is not applied to the DNAC" self.status = "failed" return self - self.log("Successfully validated the Reserve Pool", "INFO") + self.log("Successfully validated the reserve pool '{0}'." + .format(self.want.get("wantReserve").get("name")), "INFO") self.result.get("response")[1].get("reservePool").update({"Validation": "Success"}) if config.get("network_management_details") is not None: @@ -2044,7 +2048,8 @@ def verify_diff_merged(self, config): self.status = "failed" return self - self.log("Successfully validated the Network Functions", "INFO") + self.log("Successfully validated the network functions '{0}'." + .format(config.get("network_management_details").get("site_name")), "INFO") self.result.get("response")[2].get("network").update({"Validation": "Success"}) self.msg = "Successfully validated the Global Pool, Reserve Pool \ @@ -2075,17 +2080,20 @@ def verify_diff_deleted(self, config): self.status = "failed" return self - self.log("Successfully validated absence of Global Pool", "INFO") + self.log("Successfully validated absence of Global Pool '{0}'." + .format(config.get("global_pool_details") + .get("settings").get("ip_pool")[0].get("name")), "INFO") self.result.get("response")[0].get("globalPool").update({"Validation": "Success"}) if config.get("reserve_pool_details") is not None: reserve_pool_exists = self.have.get("reservePool").get("exists") if reserve_pool_exists: - self.msg = "Reserve Pool Config is not applied to the DNAC" + self.msg = "Reserved Pool Config is not applied to the DNAC" self.status = "failed" return self - self.log("Successfully validated the absence of Reserve Pool", "INFO") + self.log("Successfully validated the absence of Reserve Pool '{0}'." + .format(config.get("reserve_pool_details").get("name")), "INFO") self.result.get("response")[1].get("reservePool").update({"Validation": "Success"}) self.msg = "Successfully validated the absence of Global Pool/Reserve Pool" diff --git a/plugins/modules/template_intent.py b/plugins/modules/template_intent.py index a30da9983e..368d4270d3 100644 --- a/plugins/modules/template_intent.py +++ b/plugins/modules/template_intent.py @@ -1607,9 +1607,9 @@ def get_template_info(self, template_params): templateParams = [] i = 0 - self.log("Template Params Details: {0}".format(template_params), "DEBUG") + self.log("Template params details: {0}".format(template_params), "DEBUG") for item in template_params: - self.log("Template Params Items: {0}".format(item), "DEBUG") + self.log("Template Pprams items: {0}".format(item), "DEBUG") templateParams.append({}) binding = item.get("binding") if binding is not None: @@ -1689,11 +1689,11 @@ def get_template_info(self, template_params): templateParams[i].update({"required": required}) range = item.get("range") - self.log("Template Params Range List: {0}".format(range), "DEBUG") + self.log("Template params range list: {0}".format(range), "DEBUG") if range is not None: templateParams[i].update({"range": []}) _range = templateParams[i].get("range") - self.log("Template Params Range: {0}".format(_range), "DEBUG") + self.log("Template params range: {0}".format(_range), "DEBUG") j = 0 for value in range: _range.append({}) @@ -1716,9 +1716,9 @@ def get_template_info(self, template_params): return self.check_return_status() j = j + 1 - self.log("Template Params Details: {0}".format(templateParams), "DEBUG") + self.log("Template params details: {0}".format(templateParams), "DEBUG") selection = item.get("selection") - self.log("Template Params Selection: {0}".format(selection), "DEBUG") + self.log("Template params selection: {0}".format(selection), "DEBUG") if selection is not None: templateParams[i].update({"selection": {}}) _selection = templateParams[i].get("selection") @@ -1842,7 +1842,7 @@ def get_template_params(self, params): temp_params (dict) - Organized template parameters. """ - self.log("Template Params Playbook Details: {0}".format(params), "DEBUG") + self.log("Template params playbook details: {0}".format(params), "DEBUG") temp_params = { "tags": self.get_tags(params.get("template_tag")), "author": params.get("author"), @@ -1877,12 +1877,12 @@ def get_template_params(self, params): "version": params.get("version"), "project_id": params.get("project_id") } - self.log("Formatted Template Params Details: {0}".format(temp_params), "DEBUG") + self.log("Formatted template params details: {0}".format(temp_params), "DEBUG") copy_temp_params = copy.deepcopy(temp_params) for item in copy_temp_params: if temp_params[item] is None: del temp_params[item] - self.log("Formatted Template Params Details: {0}".format(temp_params), "DEBUG") + self.log("Formatted template params details: {0}".format(temp_params), "DEBUG") return temp_params def get_template(self, config): @@ -2069,7 +2069,7 @@ def get_want(self, config): want = {} configuration_templates = config.get("configuration_templates") - self.log("Playbook Details: {0}".format(config), "INFO") + self.log("Playbook details: {0}".format(config), "INFO") if configuration_templates: template_params = self.get_template_params(configuration_templates) project_params = self.get_project_params(configuration_templates) @@ -2107,7 +2107,6 @@ def create_project_or_template(self, is_create_project=False): project_params = self.want.get("project_params") if is_create_project: - self.log("Project Created.", "DEBUG") params_key = project_params name = "project: {0}".format(project_params.get('name')) validation_string = "Successfully created project" @@ -2125,28 +2124,31 @@ def create_project_or_template(self, is_create_project=False): params=params_key, ) if not isinstance(response, dict): - self.log("Response not in dictionary format.", "CRITICAL") + self.log("Response of '{0}' is not in dictionary format." + .format(creation_value), "CRITICAL") return creation_id, created task_id = response.get("response").get("taskId") if not task_id: - self.log("Task id {0} not found".format(task_id), "CRITICAL") + self.log("Task id {0} not found for '{1}'.".format(task_id, creation_value), "CRITICAL") return creation_id, created while not created: task_details = self.get_task_details(task_id) if not task_details: - self.log("Failed to get task details for taskid: {0}".format(task_id), "CRITICAL") + self.log("Failed to get task details of '{0}' for taskid: {1}" + .format(creation_value, task_id), "CRITICAL") return creation_id, created - self.log("task_details: {0}".format(task_details), "DEBUG") + self.log("Task details for {0}: {1}".format(creation_value, task_details), "DEBUG") if task_details.get("isError"): - self.log("isError set to true for taskid: {0}".format(task_id), "ERROR") + self.log("Error occurred for '{0}' with taskid: {1}" + .format(creation_value, task_id), "ERROR") return creation_id, created if validation_string not in task_details.get("progress"): - self.log("progress set to {0} for taskid: {1}" - .format(task_details.get('progress'), task_id), "DEBUG") + self.log("'{0}' progress set to {1} for taskid: {2}" + .format(creation_value, task_details.get('progress'), task_id), "DEBUG") continue task_details_data = task_details.get("data") @@ -2156,7 +2158,8 @@ def create_project_or_template(self, is_create_project=False): else: creation_id = value.get("templateId") if not creation_id: - self.log("Data is not found for taskid: {0}".format(task_id), "DEBUG") + self.log("Export data is not found for '{0}' with taskid : {1}" + .format(creation_value, task_id), "DEBUG") continue created = True @@ -2183,7 +2186,8 @@ def requires_update(self): """ if self.have_template.get("isCommitPending"): - self.log("Template is in saved state and needs to be updated and committed.", "DEBUG") + self.log("Template '{0}' is in saved state and needs to be updated and committed." + .format(self.have_template.get("template").get("name")), "DEBUG") return True current_obj = self.have_template.get("template") @@ -2304,22 +2308,22 @@ def get_export_template_values(self, export_values): ) for values in export_values: project_name = values.get("project_name") - self.log("Project Name for Export Template: {0}".format(project_name), "DEBUG") + self.log("Project name for export template: {0}".format(project_name), "DEBUG") template_details = template_details.get("response") - self.log("Template Details: {0}".format(template_details), "DEBUG") + self.log("Template details: {0}".format(template_details), "DEBUG") all_template_details = get_dict_result(template_details, "name", project_name) - self.log("Template Details under the Project Name {0}: {1}" + self.log("Template details under the project name {0}: {1}" .format(project_name, all_template_details), "DEBUG") all_template_details = all_template_details.get("templates") - self.log("Template Details under the Project Name {0}: {1}" + self.log("Template details under the project name {0}: {1}" .format(project_name, all_template_details), "DEBUG") template_name = values.get("template_name") template_detail = get_dict_result(all_template_details, "name", template_name) - self.log("Template Details with Template Name {0}: {1}" + self.log("Template details with template name {0}: {1}" .format(template_name, template_detail), "DEBUG") if template_detail is None: self.msg = "Invalid project_name and template_name in export" @@ -2357,8 +2361,8 @@ def update_configuration_templates(self, config): is_template_found = self.have_template.get("template_found") template_params = self.want.get("template_params") - self.log("Template Details in Playbook: {0}".format(template_params), "DEBUG") - self.log("Template Details in DNAC: {0}".format(self.have_template), "DEBUG") + self.log("Desired template details: {0}".format(template_params), "DEBUG") + self.log("Current template details: {0}".format(self.have_template), "DEBUG") template_id = None template_updated = False self.validate_input_merge(is_template_found).check_return_status() @@ -2375,7 +2379,8 @@ def update_configuration_templates(self, config): op_modifies=True, ) template_updated = True - self.log("Updating Existing Template.", "INFO") + self.log("Updating existing template '{0}'." + .format(self.have_template.get("template").get("name")), "INFO") else: # Template does not need update self.result.update({ @@ -2413,7 +2418,7 @@ def update_configuration_templates(self, config): self.result['changed'] = True self.result['msg'] = task_details.get('progress') self.result['diff'] = config.get("configuration_templates") - self.log("Task Details: {0}".format(task_details), "DEBUG") + self.log("Task details for 'version_template': {0}".format(task_details), "DEBUG") self.result['response'] = task_details if task_details else response if not self.result.get('msg'): @@ -2435,7 +2440,7 @@ def handle_export(self, config): export = config.get("export") if export: export_project = export.get("project") - self.log("Export Project Playbook Details: {0}" + self.log("Export project playbook details: {0}" .format(export_project), "DEBUG") if export_project: response = self.dnac._exec( @@ -2452,7 +2457,7 @@ def handle_export(self, config): export_values = export.get("template") if export_values: self.get_export_template_values(export_values).check_return_status() - self.log("Export Template Playbook Details: {0}" + self.log("Exporting template playbook details: {0}" .format(self.export_template), "DEBUG") response = self.dnac._exec( family="configuration_templates", @@ -2494,7 +2499,7 @@ def handle_import(self, config): # "payload": "{0}".format(payload) "payload": payload } - self.log("Import Project Details from the Playbook: {0}" + self.log("Importing project details from the playbook: {0}" .format(_import_project), "DEBUG") if _import_project: response = self.dnac._exec( @@ -2522,7 +2527,7 @@ def handle_import(self, config): "projectName": _import_template.get("project_name"), "payload": self.get_template_params(payload) } - self.log("Import Template Details from the Playbook: {0}" + self.log("Import template details from the playbook: {0}" .format(_import_template), "DEBUG") if _import_template: response = self.dnac._exec( @@ -2600,7 +2605,7 @@ def delete_project_or_template(self, config, is_delete_project=False): self.result['msg'] = task_details.get('progress') self.result['diff'] = config.get("configuration_templates") - self.log("Task Details: {0}".format(task_details), "DEBUG") + self.log("Task details for '{0}': {1}".format(deletion_value, task_details), "DEBUG") self.result['response'] = task_details if task_details else response if not self.result['msg']: self.result['msg'] = "Error while deleting {name} : " @@ -2643,8 +2648,9 @@ def get_diff_deleted(self, config): self.status = "failed" return self else: - self.log("Template Name is empty, deleting the project and " - "associated templates", "INFO") + self.log("Template name is empty, deleting the project '{0}' and " + "associated templates" + .format(config.get("configuration_templates").get("project_name")), "INFO") is_project_deletable = self.have_project.get("isDeletable") if is_project_deletable: self.delete_project_or_template(config, is_delete_project=True) @@ -2672,7 +2678,7 @@ def verify_diff_merged(self, config): if config.get("configuration_templates") is not None: is_template_available = self.get_have_project(config) - self.log("Template Availability: {0}".format(is_template_available), "INFO") + self.log("Template availability: {0}".format(is_template_available), "INFO") if not is_template_available: self.msg = "Configuration Template config is not applied to the DNAC." self.status = "failed" @@ -2688,7 +2694,7 @@ def verify_diff_merged(self, config): self.msg = " Configuration Template config is not applied to the DNAC." self.status = "failed" return self - self.log("Successfully validated the Template in the DNAC.", "INFO") + self.log("Successfully validated the Template in the Catalyst Center.", "INFO") self.result.get("response").update({"Validation": "Success"}) self.msg = "Successfully validated the Configuration Templates." @@ -2726,7 +2732,7 @@ def verify_diff_deleted(self, config): self.status = "failed" return self - self.log("Successfully validated absence of Template in the DNAC.", "INFO") + self.log("Successfully validated absence of template in the Catalyst Center.", "INFO") self.result.get("response").update({"Validation": "Success"}) self.msg = "Successfully validated the absence of Template in the DNAC." From 707b7bc9893c70b1da784b70ddfea70d9eede48b Mon Sep 17 00:00:00 2001 From: MUTHU-RAKESH-27 <19cs127@psgitech.ac.in> Date: Thu, 25 Jan 2024 17:19:36 +0530 Subject: [PATCH 16/16] Refactored the logs and addressed the review comments --- plugins/modules/device_credential_intent.py | 3 ++- plugins/modules/network_settings_intent.py | 8 ++++---- plugins/modules/template_intent.py | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/plugins/modules/device_credential_intent.py b/plugins/modules/device_credential_intent.py index 375a5d7972..d1f860ba7e 100644 --- a/plugins/modules/device_credential_intent.py +++ b/plugins/modules/device_credential_intent.py @@ -2251,7 +2251,8 @@ def update_device_credentials(self): values = ["cliCredential", "snmpV2cRead", "snmpV2cWrite", "httpsRead", "httpsWrite", "snmpV3"] final_response = [] - self.log("Desired State for updation: {0}".format(want_update), "DEBUG") + self.log("Desired State for global device credentials updation: {0}" + .format(want_update), "DEBUG") while flag: flag = False credential_params = {} diff --git a/plugins/modules/network_settings_intent.py b/plugins/modules/network_settings_intent.py index 384944e1f1..8f24cd5055 100644 --- a/plugins/modules/network_settings_intent.py +++ b/plugins/modules/network_settings_intent.py @@ -668,7 +668,7 @@ def get_site_id(self, site_name): return None _id = response.get("response")[0].get("id") - self.log("Site ID: {0}".format(_id), "DEBUG") + self.log("Site ID for site name '{0}': {1}".format(site_name, _id), "DEBUG") except Exception as msg: self.log("Exception occurred while retrieving site_id from the site_name: {0}" .format(msg), "CRITICAL") @@ -1768,7 +1768,7 @@ def update_reserve_pool(self, config): .format(self.want.get("wantReserve")), "DEBUG") # Check pool exist, if not create and return - self.log("Ipv4 global pool: {0}" + self.log("IPv4 global pool: {0}" .format(self.want.get("wantReserve").get("ipv4GlobalPool")), "DEBUG") site_name = config.get("reserve_pool_details").get("site_name") reserve_params = self.want.get("wantReserve") @@ -2037,7 +2037,7 @@ def verify_diff_merged(self, config): self.status = "failed" return self - self.log("Successfully validated the reserve pool '{0}'." + self.log("Successfully validated the reserved pool '{0}'." .format(self.want.get("wantReserve").get("name")), "INFO") self.result.get("response")[1].get("reservePool").update({"Validation": "Success"}) @@ -2088,7 +2088,7 @@ def verify_diff_deleted(self, config): if config.get("reserve_pool_details") is not None: reserve_pool_exists = self.have.get("reservePool").get("exists") if reserve_pool_exists: - self.msg = "Reserved Pool Config is not applied to the DNAC" + self.msg = "Reserved Pool Config is not applied to the Catalyst Center" self.status = "failed" return self diff --git a/plugins/modules/template_intent.py b/plugins/modules/template_intent.py index 368d4270d3..540eb6f058 100644 --- a/plugins/modules/template_intent.py +++ b/plugins/modules/template_intent.py @@ -1609,7 +1609,7 @@ def get_template_info(self, template_params): i = 0 self.log("Template params details: {0}".format(template_params), "DEBUG") for item in template_params: - self.log("Template Pprams items: {0}".format(item), "DEBUG") + self.log("Template params items: {0}".format(item), "DEBUG") templateParams.append({}) binding = item.get("binding") if binding is not None: