Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the new feature of deploying the template to the devices using de… #443

Merged
merged 4 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 29 additions & 4 deletions playbooks/template_workflow_manager.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@
dnac_username: "{{ dnac_username }}"
dnac_password: "{{ dnac_password }}"
dnac_verify: "{{ dnac_verify }}"
dnac_version: "{{dnac_version}}"
dnac_debug: "{{ dnac_debug }}"
dnac_log: True
dnac_log: true
dnac_log_level: DEBUG
dnac_log_append: True
dnac_log_file_path: "{{ dnac_log_file_path }}"
validate_response_schema: False
dnac_log_append: true
# dnac_log_file_path: "{{ dnac_log_file_path }}"
validate_response_schema: false
state: "merged"
config_verify: true
#ignore_errors: true #Enable this to continue execution even the task fails
Expand All @@ -41,6 +42,30 @@
import:
project: "{{ item.import_project }}"
template: "{{ item.import_template }}"

deploy_template:
project_name: "{{ item.proj_name }}"
template_name: "{{ item.temp_name }}"
force_push: "{{ item.force_push }}"
template_parameters:
- param_name: "{{ item.template_parameters.param_name }}"
param_value: "{{ item.template_parameters.param_value }}"
- param_name: "{{ item.template_parameters.param_name }}"
param_value: "{{ item.template_parameters.param_value }}"
device_details:
# Provide any of the one device_specific details either device_ips, device_hostnames
# serial_numbers, mac_addresses to deploy template to the devices
# device_ips: "{{ item.device_details.device_ips }}"
device_hostnames: "{{ item.device_details.device_hostnames }}"
# serial_numbers: "{{ item.device_details.serial_numbers }}"
# mac_addresses: "{{ item.device_details.mac_addresses }}"
site_provisioning_details:
# Provide the site name and other parameters are optional to narrow down the results
- site_name: "{{ item.site_provisioning_details.site_name }}"
device_family: "{{ item.site_provisioning_details.device_family }}"
device_role: "{{ item.site_provisioning_details.device_role }}"
device_tag: "{{ item.site_provisioning_details.device_tag }}"

register: template_result
with_items: '{{ template_details }}'
tags:
Expand Down
351 changes: 346 additions & 5 deletions plugins/module_utils/dnac.py

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions plugins/modules/accesspoint_workflow_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2291,7 +2291,8 @@ def get_site_device(self, site_id, ap_mac_address, site_exist=None, current_site
not found or if an error occurs during the API call, it returns False.
"""
try:
device_list = self.get_device_ids_from_site(site_id)
site_name = self.have.get("site_name_hierarchy", self.want.get("site_name"))
device_list = self.get_device_ids_from_site(site_name, site_id)
if current_config.get("id") is not None and current_config.get("id") in device_list:
self.log("Device with MAC address: {0} found in site: {1} Proceeding with ap_site updation."
.format(ap_mac_address, site_id), "INFO")
Expand All @@ -2301,8 +2302,8 @@ def get_site_device(self, site_id, ap_mac_address, site_exist=None, current_site
return False

except Exception as e:
self.log("Failed to execute the get_device_ids_from_site function '{}'\
Error: {}".format(site_id, str(e)), "ERROR")
self.log("Failed to execute the get_device_ids_from_site function '{0}'\
Error: {1}".format(site_id, str(e)), "ERROR")
return False

def verify_ap_provision(self, wlc_ip_address):
Expand Down
2 changes: 1 addition & 1 deletion plugins/modules/device_credential_workflow_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -2782,7 +2782,7 @@ def apply_credentials_to_site(self):
self.status = "success"
return self

site_response = self.get_device_ids_from_site(site_id)
site_response = self.get_device_ids_from_site(site_name, site_id)
if not site_response:
result_apply_credential.update({
"No Apply Credentials": {
Expand Down
55 changes: 29 additions & 26 deletions plugins/modules/inventory_intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,17 @@
or resyncing devices, with Meraki devices being the exception.
elements: str
type: list
hostname_list:
hostnames:
description: "A list of hostnames representing devices. Operations such as updating, deleting, resyncing, or rebooting
can be performed as alternatives to using IP addresses."
type: list
elements: str
serial_number_list:
serial_numbers:
description: A list of serial numbers representing devices. Operations such as updating, deleting, resyncing, or rebooting
can be performed as alternatives to using IP addresses.
type: list
elements: str
mac_address_list:
mac_addresses:
description: "A list of MAC addresses representing devices. Operations such as updating, deleting, resyncing, or rebooting
can be performed as alternatives to using IP addresses."
type: list
Expand Down Expand Up @@ -771,9 +771,9 @@ def validate_input(self):
'http_secure': {'type': 'bool'},
'http_username': {'type': 'str'},
'ip_address_list': {'type': 'list', 'elements': 'str'},
'hostname_list': {'type': 'list', 'elements': 'str'},
'serial_number_list': {'type': 'list', 'elements': 'str'},
'mac_address_list': {'type': 'list', 'elements': 'str'},
'hostnames': {'type': 'list', 'elements': 'str'},
'serial_numbers': {'type': 'list', 'elements': 'str'},
'mac_addresses': {'type': 'list', 'elements': 'str'},
'netconf_port': {'type': 'str'},
'password': {'type': 'str'},
'snmp_auth_passphrase': {'type': 'str'},
Expand Down Expand Up @@ -864,25 +864,28 @@ def get_device_ips_from_config_priority(self):
If none of the information is available, an empty list is returned.
"""
# Retrieve device IPs from the configuration
device_ips = self.config[0].get("ip_address_list")
device_ips = self.want.get("device_params").get("ipAddress")

if device_ips:
return device_ips

# If device IPs are not available, check hostnames
device_hostnames = self.config[0].get("hostname_list")
device_hostnames = self.config[0].get("hostnames")
if device_hostnames:
return self.get_device_ips_from_hostname(device_hostnames)
device_ip_dict = self.get_device_ips_from_hostnames(device_hostnames)
return self.get_list_from_dict_values(device_ip_dict)

# If hostnames are not available, check serial numbers
device_serial_numbers = self.config[0].get("serial_number_list")
device_serial_numbers = self.config[0].get("serial_numbers")
if device_serial_numbers:
return self.get_device_ips_from_serial_number(device_serial_numbers)
device_ip_dict = self.get_device_ips_from_serial_numbers(device_serial_numbers)
return self.get_list_from_dict_values(device_ip_dict)

# If serial numbers are not available, check MAC addresses
device_mac_addresses = self.config[0].get("mac_address_list")
device_mac_addresses = self.config[0].get("mac_addresses")
if device_mac_addresses:
return self.get_device_ips_from_mac_address(device_mac_addresses)
device_ip_dict = self.get_device_ips_from_mac_addresses(device_mac_addresses)
return self.get_list_from_dict_values(device_ip_dict)

# If no information is available, return an empty list
return []
Expand Down Expand Up @@ -1465,7 +1468,7 @@ def reboot_access_points(self):
return self

# Get and store the apEthernetMacAddress of given devices
ap_mac_address_list = []
ap_mac_addresses = []
for device_ip in input_device_ips:
response = self.dnac._exec(
family="devices",
Expand All @@ -1481,9 +1484,9 @@ def reboot_access_points(self):
ap_mac_address = response.get('apEthernetMacAddress')

if ap_mac_address is not None:
ap_mac_address_list.append(ap_mac_address)
ap_mac_addresses.append(ap_mac_address)

if not ap_mac_address_list:
if not ap_mac_addresses:
self.status = "success"
self.result['changed'] = False
self.msg = "Cannot find the AP devices for rebooting"
Expand All @@ -1493,7 +1496,7 @@ def reboot_access_points(self):

# Now call the Reboot Access Point API
reboot_params = {
"apMacAddresses": ap_mac_address_list
"apMacAddresses": ap_mac_addresses
}
response = self.dnac._exec(
family="wireless",
Expand Down Expand Up @@ -2239,12 +2242,12 @@ def get_device_ids(self, device_ips):

return device_ids

def get_device_ips_from_hostname(self, hostname_list):
def get_device_ips_from_hostnames(self, hostnames):
"""
Get the list of unique device IPs for list of specified hostnames of devices in Cisco Catalyst Center.
Parameters:
self (object): An instance of a class used for interacting with Cisco Catalyst Center.
hostname_list (list): The hostnames of devices for which you want to retrieve the device IPs.
hostnames (list): The hostnames of devices for which you want to retrieve the device IPs.
Returns:
list: The list of unique device IPs for the specified devices hostname list.
Description:
Expand All @@ -2253,7 +2256,7 @@ def get_device_ips_from_hostname(self, hostname_list):
"""

device_ips = []
for hostname in hostname_list:
for hostname in hostnames:
try:
response = self.dnac._exec(
family="devices",
Expand All @@ -2274,12 +2277,12 @@ def get_device_ips_from_hostname(self, hostname_list):

return device_ips

def get_device_ips_from_serial_number(self, serial_number_list):
def get_device_ips_from_serial_numbers(self, serial_numbers):
"""
Get the list of unique device IPs for a specified list of serial numbers in Cisco Catalyst Center.
Parameters:
self (object): An instance of a class used for interacting with Cisco Catalyst Center.
serial_number_list (list): The list of serial number of devices for which you want to retrieve the device IPs.
serial_numbers (list): The list of serial number of devices for which you want to retrieve the device IPs.
Returns:
list: The list of unique device IPs for the specified devices with serial numbers.
Description:
Expand All @@ -2288,7 +2291,7 @@ def get_device_ips_from_serial_number(self, serial_number_list):
"""

device_ips = []
for serial_number in serial_number_list:
for serial_number in serial_numbers:
try:
response = self.dnac._exec(
family="devices",
Expand All @@ -2309,12 +2312,12 @@ def get_device_ips_from_serial_number(self, serial_number_list):

return device_ips

def get_device_ips_from_mac_address(self, mac_address_list):
def get_device_ips_from_mac_addresses(self, mac_addresses):
"""
Get the list of unique device IPs for list of specified mac address of devices in Cisco Catalyst Center.
Parameters:
self (object): An instance of a class used for interacting with Cisco Catalyst Center.
mac_address_list (list): The list of mac address of devices for which you want to retrieve the device IPs.
mac_addresses (list): The list of mac address of devices for which you want to retrieve the device IPs.
Returns:
list: The list of unique device IPs for the specified devices.
Description:
Expand All @@ -2323,7 +2326,7 @@ def get_device_ips_from_mac_address(self, mac_address_list):
"""

device_ips = []
for mac_address in mac_address_list:
for mac_address in mac_addresses:
try:
response = self.dnac._exec(
family="devices",
Expand Down
117 changes: 6 additions & 111 deletions plugins/modules/inventory_workflow_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -878,17 +878,20 @@ def get_device_ips_from_config_priority(self):
# If device IPs are not available, check hostnames
device_hostnames = self.config[0].get("hostname_list")
if device_hostnames:
return self.get_device_ips_from_hostname(device_hostnames)
device_ip_dict = self.get_device_ips_from_hostnames(device_hostnames)
return self.get_list_from_dict_values(device_ip_dict)

# If hostnames are not available, check serial numbers
device_serial_numbers = self.config[0].get("serial_number_list")
if device_serial_numbers:
return self.get_device_ips_from_serial_number(device_serial_numbers)
device_ip_dict = self.get_device_ips_from_serial_numbers(device_serial_numbers)
return self.get_list_from_dict_values(device_ip_dict)

# If serial numbers are not available, check MAC addresses
device_mac_addresses = self.config[0].get("mac_address_list")
if device_mac_addresses:
return self.get_device_ips_from_mac_address(device_mac_addresses)
device_ip_dict = self.get_device_ips_from_mac_addresses(device_mac_addresses)
return self.get_list_from_dict_values(device_ip_dict)

# If no information is available, return an empty list
return []
Expand Down Expand Up @@ -2398,114 +2401,6 @@ def get_device_ids(self, device_ips):

return device_ids

def get_device_ips_from_hostname(self, hostname_list):
"""
Get the list of unique device IPs for list of specified hostnames of devices in Cisco Catalyst Center.
Parameters:
self (object): An instance of a class used for interacting with Cisco Catalyst Center.
hostname_list (list): The hostnames of devices for which you want to retrieve the device IPs.
Returns:
list: The list of unique device IPs for the specified devices hostname list.
Description:
Queries Cisco Catalyst Center to retrieve the unique device IP's associated with a device having the specified
list of hostnames. If a device is not found in Cisco Catalyst Center, an error log message is printed.
"""

device_ips = []
for hostname in hostname_list:
try:
response = self.dnac._exec(
family="devices",
function='get_device_list',
op_modifies=True,
params={"hostname": hostname}
)
if response:
self.log("Received API response from 'get_device_list': {0}".format(str(response)), "DEBUG")
response = response.get("response")
if response:
device_ip = response[0]["managementIpAddress"]
if device_ip:
device_ips.append(device_ip)
except Exception as e:
error_message = "Exception occurred while fetching device from Cisco Catalyst Center: {0}".format(str(e))
self.log(error_message, "ERROR")

return device_ips

def get_device_ips_from_serial_number(self, serial_number_list):
"""
Get the list of unique device IPs for a specified list of serial numbers in Cisco Catalyst Center.
Parameters:
self (object): An instance of a class used for interacting with Cisco Catalyst Center.
serial_number_list (list): The list of serial number of devices for which you want to retrieve the device IPs.
Returns:
list: The list of unique device IPs for the specified devices with serial numbers.
Description:
Queries Cisco Catalyst Center to retrieve the unique device IPs associated with a device having the specified
serial numbers.If a device is not found in Cisco Catalyst Center, an error log message is printed.
"""

device_ips = []
for serial_number in serial_number_list:
try:
response = self.dnac._exec(
family="devices",
function='get_device_list',
op_modifies=True,
params={"serialNumber": serial_number}
)
if response:
self.log("Received API response from 'get_device_list': {0}".format(str(response)), "DEBUG")
response = response.get("response")
if response:
device_ip = response[0]["managementIpAddress"]
if device_ip:
device_ips.append(device_ip)
except Exception as e:
error_message = "Exception occurred while fetching device from Cisco Catalyst Center - {0}".format(str(e))
self.log(error_message, "ERROR")

return device_ips

def get_device_ips_from_mac_address(self, mac_address_list):
"""
Get the list of unique device IPs for list of specified mac address of devices in Cisco Catalyst Center.
Parameters:
self (object): An instance of a class used for interacting with Cisco Catalyst Center.
mac_address_list (list): The list of mac address of devices for which you want to retrieve the device IPs.
Returns:
list: The list of unique device IPs for the specified devices.
Description:
Queries Cisco Catalyst Center to retrieve the unique device IPs associated with a device having the specified
mac addresses. If a device is not found in Cisco Catalyst Center, an error log message is printed.
"""

device_ips = []
for mac_address in mac_address_list:
try:
response = self.dnac._exec(
family="devices",
function='get_device_list',
op_modifies=True,
params={"macAddress": mac_address}
)
if response:
self.log("Received API response from 'get_device_list': {0}".format(str(response)), "DEBUG")
response = response.get("response")
if response:
device_ip = response[0]["managementIpAddress"]
if device_ip:
device_ips.append(device_ip)
except Exception as e:
self.status = "failed"
self.msg = "Exception occurred while fetching device from Cisco Catalyst Center - {0}".format(str(e))
self.result['response'] = self.msg
self.log(self.msg, "ERROR")
self.check_return_status()

return device_ips

def get_interface_from_id_and_name(self, device_id, interface_name):
"""
Retrieve the interface ID for a device in Cisco Catalyst Center based on device id and interface name.
Expand Down
2 changes: 1 addition & 1 deletion plugins/modules/site_workflow_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -1598,7 +1598,7 @@ def get_diff_deleted(self, config):

if self.compare_dnac_versions(self.get_ccc_version(), "2.3.5.3") <= 0:
site_id = self.have.get("site_id")
api_response, response = self.get_device_ids_from_site(site_id)
api_response, response = self.get_device_ids_from_site(site_name, site_id)

self.log(
"Received API response from 'get_membership': {0}".format(str(api_response)), "DEBUG")
Expand Down
Loading
Loading