Skip to content

Commit edb0eee

Browse files
authored
Merge pull request #326 from cisco-en-programmability/develop
Develop
2 parents 0b27a0c + 2fcb20e commit edb0eee

13 files changed

Lines changed: 6356 additions & 1182 deletions

changelogs/changelog.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1971,3 +1971,17 @@ releases:
19711971
deprecated_features:
19721972
- The cisco.dnac collection is now deprecated. Please migrate to cisco.catalystcenter, which provides the same functionality under the updated Cisco Catalyst Center branding.
19731973
- All modules now emit a deprecation warning at runtime directing users to cisco.catalystcenter.
1974+
1975+
6.48.2:
1976+
release_date: "2026-03-18"
1977+
changes:
1978+
release_summary: Changes in workflow manager modules, Documentation enhancements and Ansible Galaxy build configuration updates for the cisco.dnac Ansible Collection
1979+
minor_changes:
1980+
- Changes in events_and_notifications_workflow_manager module
1981+
- Changes in lan_automation_workflow_manager module
1982+
- Changes in reports_workflow_manager module
1983+
- Changes in sda_extranet_policies_workflow_manager module
1984+
- Changes in site_workflow_manager module
1985+
- Changes in template_workflow_manager module
1986+
- Changes in wired_campus_automation_workflow_manager module
1987+
- Changes in wireless_design_workflow_manager module

galaxy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
namespace: cisco
33
name: dnac
4-
version: 6.48.1
4+
version: 6.48.2
55
readme: README.md
66
authors:
77
- Rafael Campos <rcampos@cloverhound.com>

plugins/module_utils/dnac.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1738,11 +1738,13 @@ def is_json(self, file_path):
17381738
self.log("The provided file '{0}' is not in JSON format".format(file_path), "CRITICAL")
17391739
return False
17401740

1741-
def check_task_tree_response(self, task_id):
1741+
def check_task_tree_response(self, task_id, all_failure_reason=None):
17421742
"""
17431743
Returns the task tree response of the task ID.
17441744
Args:
17451745
task_id (string) - The unique identifier of the task for which you want to retrieve details.
1746+
all_failure_reason (bool) - If True, retrieves all failure reasons for the task.
1747+
17461748
Returns:
17471749
error_msg (str) - Returns the task tree error message of the task ID.
17481750
"""
@@ -1752,15 +1754,24 @@ def check_task_tree_response(self, task_id):
17521754
function='get_task_tree',
17531755
params={"task_id": task_id}
17541756
)
1755-
self.log("Retrieving task tree details by the API 'get_task_tree' using task ID: {0}, Response: {1}"
1756-
.format(task_id, response), "DEBUG")
1757+
self.log(f"Retrieving task tree details by the API 'get_task_tree' using task ID: {task_id}, "
1758+
f"and failure reason set to '{all_failure_reason}', "
1759+
f"Response: {self.pprint(response)}", "DEBUG")
1760+
17571761
error_msg = ""
17581762
if response and isinstance(response, dict):
17591763
result = response.get('response')
17601764
error_messages = []
1761-
for item in result:
1762-
if item.get("isError") is True:
1763-
error_messages.append(item.get("progress"))
1765+
1766+
if all_failure_reason is True:
1767+
for item in result:
1768+
if item.get("isError") is True:
1769+
error_messages.append(item.get("failureReason"))
1770+
error_messages = error_messages[::-1]
1771+
else:
1772+
for item in result:
1773+
if item.get("isError") is True:
1774+
error_messages.append(item.get("progress"))
17641775

17651776
if error_messages:
17661777
error_msg = ". ".join(error_messages) + "."
@@ -2207,7 +2218,7 @@ def get_taskid_post_api_call(self, api_family, api_function, api_parameters):
22072218
)
22082219
self.fail_and_exit(self.msg)
22092220

2210-
def get_task_status_from_tasks_by_id(self, task_id, task_name, success_msg):
2221+
def get_task_status_from_tasks_by_id(self, task_id, task_name, success_msg, all_reasons=None):
22112222
"""
22122223
Retrieves and monitors the status of a task by its task ID.
22132224
This function continuously checks the status of a specified task using its task ID.
@@ -2217,6 +2228,7 @@ def get_task_status_from_tasks_by_id(self, task_id, task_name, success_msg):
22172228
task_id (str): The unique identifier of the task to monitor.
22182229
task_name (str): The name of the task being monitored.
22192230
success_msg (str): The success message to set if the task completes successfully.
2231+
all_reasons (bool, optional): If True, retrieves all failure reasons for the task. Defaults to None.
22202232
Returns:
22212233
self: The instance of the class with updated status and message.
22222234
"""
@@ -2253,15 +2265,18 @@ def get_task_status_from_tasks_by_id(self, task_id, task_name, success_msg):
22532265
if status == "FAILURE":
22542266
get_task_details_response = self.get_task_details_by_id(task_id)
22552267
failure_reason = get_task_details_response.get("failureReason")
2256-
if failure_reason:
2257-
self.msg = (
2258-
"Failed to execute the task {0} with Task ID: {1}."
2259-
"Failure reason: {2}".format(task_name, task_id, failure_reason)
2260-
)
2268+
if all_reasons is True:
2269+
self.msg = self.check_task_tree_response(task_id, True)
22612270
else:
2262-
self.msg = (
2263-
"Failed to execute the task {0} with Task ID: {1}.".format(task_name, task_id)
2264-
).format(task_name, task_id)
2271+
if failure_reason:
2272+
self.msg = (
2273+
"Failed to execute the task {0} with Task ID: {1}."
2274+
"Failure reason: {2}".format(task_name, task_id, failure_reason)
2275+
)
2276+
else:
2277+
self.msg = (
2278+
"Failed to execute the task {0} with Task ID: {1}.".format(task_name, task_id)
2279+
).format(task_name, task_id)
22652280
self.set_operation_result("failed", False, self.msg, "ERROR")
22662281
break
22672282
elif status == "SUCCESS":

plugins/modules/events_and_notifications_workflow_manager.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2352,11 +2352,32 @@ def collect_webhook_playbook_params(self, webhook_details):
23522352

23532353
if webhook_details.get("headers") == []:
23542354
playbook_params["headers"] = []
2355+
self.log(
2356+
"Webhook headers explicitly set to empty list in playbook - "
2357+
"existing headers will be removed during update.",
2358+
"DEBUG",
2359+
)
23552360
elif webhook_details.get("headers"):
23562361
custom_header = webhook_details["headers"]
23572362
playbook_params["headers"] = []
23582363
for header in custom_header:
23592364
playbook_params["headers"].append(header)
2365+
self.log(
2366+
"Webhook headers collected from playbook: {0}".format(
2367+
playbook_params["headers"]
2368+
),
2369+
"DEBUG",
2370+
)
2371+
else:
2372+
# Headers not specified in playbook — set to empty list so that
2373+
# any existing headers on the destination are detected as a change
2374+
# and removed during update.
2375+
playbook_params["headers"] = []
2376+
self.log(
2377+
"No webhook headers specified in playbook - defaulting to empty list. "
2378+
"Any existing headers on the destination will be removed during update.",
2379+
"DEBUG",
2380+
)
23602381

23612382
return playbook_params
23622383

plugins/modules/lan_automation_workflow_manager.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,12 @@
7272
type: dict
7373
suboptions:
7474
discovered_device_site_name_hierarchy:
75-
description: Site hierarchy where the discovered
76-
devices will be placed.
75+
description: |
76+
- Site hierarchy where the discovered
77+
devices will be placed.
78+
- Required only in merged state.
7779
type: str
78-
required: true
80+
required: false
7981
primary_device_management_ip_address:
8082
description: Management IP address of the
8183
primary or seed device in the LAN Automation
@@ -88,18 +90,22 @@
8890
type: str
8991
required: false
9092
primary_device_interface_names:
91-
description: A list of interface names on
92-
the primary device to be used for LAN
93-
automation.
93+
description: |
94+
- A list of interface names on
95+
the primary device to be used for LAN
96+
automation.
97+
- Required only in merged state.
9498
type: list
9599
elements: str
96-
required: true
100+
required: false
97101
ip_pools:
98-
description: A list of IP pools used during
99-
the LAN Automation session.
102+
description: |
103+
- A list of IP pools used during
104+
the LAN Automation session.
105+
- Required only in merged state.
100106
type: list
101107
elements: dict
102-
required: true
108+
required: false
103109
suboptions:
104110
ip_pool_name:
105111
description: Name of the IP pool.
@@ -1041,15 +1047,15 @@ def validate_input(self):
10411047
"elements": "dict",
10421048
"discovered_device_site_name_hierarchy": {
10431049
"type": "str",
1044-
"required": True,
1050+
"required": False,
10451051
},
10461052
"primary_device_management_ip_address": {
10471053
"type": "str",
10481054
"required": True,
10491055
},
10501056
"primary_device_interface_names": {
10511057
"type": "list",
1052-
"required": True,
1058+
"required": False,
10531059
"elements": "str",
10541060
},
10551061
"peer_device_management_ip_address": {
@@ -1058,7 +1064,7 @@ def validate_input(self):
10581064
},
10591065
"ip_pools": {
10601066
"type": "list",
1061-
"required": True,
1067+
"required": False,
10621068
"elements": "dict",
10631069
"ip_pool_name": {"type": "str", "required": True},
10641070
"ip_pool_role": {
@@ -5115,10 +5121,10 @@ def get_lan_auto_task_status(self, task_id):
51155121
pnp_authorization = lan_automation.get("pnpAuthorization", False)
51165122
device_serials = [
51175123
serial.upper()
5118-
for serial in lan_automation.get("deviceSerialNumberAuthorization", [])
5124+
for serial in (lan_automation.get("deviceSerialNumberAuthorization") or [])
51195125
] or [
51205126
device.get("deviceSerialNumber", "").upper()
5121-
for device in lan_automation.get("discoveryDevices", [])
5127+
for device in (lan_automation.get("discoveryDevices") or [])
51225128
]
51235129

51245130
self.log("LAN Automation Config: {}".format(lan_automation), "DEBUG")

0 commit comments

Comments
 (0)