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

Removing dnac_log_level from code along with fixing is… #127

Merged
merged 3 commits into from
Feb 1, 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
1 change: 1 addition & 0 deletions playbooks/PnP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
dnac_port: "{{ dnac_port }}"
dnac_version: "{{ dnac_version }}"
dnac_debug: "{{ dnac_debug }}"
dnac_log_level: DEBUG

tasks:

Expand Down
28 changes: 8 additions & 20 deletions playbooks/discovery_intent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
dnac_port: "{{ dnac_port }}"
dnac_version: "{{ dnac_version }}"
dnac_debug: "{{ dnac_debug }}"
dnac_log: True
dnac_log_level: DEBUG

tasks:
- name: Execute discovery devices using MULTI RANGE
Expand All @@ -24,21 +26,11 @@
state: merged
config_verify: True
config:
- devices_list:
- name: SJ-BN-9300
site: Global/USA/SAN JOSE/BLD23
role: MAPSERVER,BORDERNODE,INTERNAL,EXTERNAL,SDATRANSIT
l2interface: TenGigabitEthernet1/1/8
ip: 204.1.2.1
- name: NY-BN-9300
site: Global/USA/New York/BLDNYC
role: MAPSERVER,BORDERNODE,INTERNAL,EXTERNAL,SDATRANSIT,NOIPTRANSIT,ECA
managed_ap_site: Global/USA/New York/BLDNYC/FLOOR1
rolling_ap_count: 25
l2interface: TenGigabitEthernet1/1/6
ip: 204.1.2.3
- ip_address_list:
- 204.1.2.1 #It will be taken as 204.1.2.1 - 204.1.2.1
- 205.2.1.1-205.2.1.10
discovery_type: "MULTI RANGE"
discovery_name: Multi_Range_Discovery_Test
discovery_name: File_111
protocol_order: ssh
start_index: 1
records_to_return: 25
Expand All @@ -50,12 +42,8 @@
state: merged
config_verify: True
config:
- devices_list: #List length should be one
- name: SJ-BN-9300
site: Global/USA/SAN JOSE/BLD23
role: MAPSERVER,BORDERNODE,INTERNAL,EXTERNAL,SDATRANSIT
l2interface: TenGigabitEthernet1/1/8
ip: 204.1.2.1
- ip_address_list: #List length should be one
- 204.1.2.1
discovery_type: "CDP" #Can be LLDP and CIDR
cdp_level: 16 #Instead use lldp for LLDP and prefix length for CIDR
discovery_name: CDP_Test_1
Expand Down
141 changes: 76 additions & 65 deletions plugins/modules/discovery_intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@
description: Set to True to verify the Cisco DNA Center config after applying the playbook config.
type: bool
default: False
dnac_log_level:
description: Specifies the log level for Cisco Catalyst Center logging, categorizing logs by severity.
Options- [CRITICAL, ERROR, WARNING, INFO, DEBUG]
type: str
default: WARNING
state:
description: The state of DNAC after module completion.
type: str
Expand All @@ -43,19 +38,11 @@
elements: dict
required: true
suboptions:
devices_list:
description: List of devices with details necessary for discovering the devices.
ip_address_list:
description: List of IP addresses to be discoverred.
type: list
elements: dict
elements: str
required: true
suboptions:
name:
description: Hostname of the device
type: str
ip:
description: Management IP address of the device
type: str
required: true
discovery_type:
description: Type of discovery (SINGLE/RANGE/MULTI RANGE/CDP/LLDP)
type: str
Expand Down Expand Up @@ -147,10 +134,13 @@
snmp_version:
description: Version of SNMP (v2/v3)
type: str
required: true
timeout:
description: Time to wait for device response in seconds
type: int
cli_cred_len:
description: Specifies the total number of CLI credentials to be used, ranging from 1 to 5.
type: int
default: 1
requirements:
- dnacentersdk == 2.6.10
- python >= 3.5
Expand Down Expand Up @@ -186,10 +176,9 @@
dnac_log: True
dnac_log_level: "{{dnac_log_level}}"
state: merged
config_verify: True
config:
- devices_list:
- name: string
ip: string
- ip_address_list: list
discovery_type: string
cdp_level: string
lldp_level: string
Expand Down Expand Up @@ -217,6 +206,7 @@
snmp_version: string
timeout: integer
username_list: list
cli_cred_length: integer
- name: Delete disovery by name
cisco.dnac.discovery_intent:
dnac_host: "{{dnac_host}}"
Expand All @@ -227,11 +217,11 @@
dnac_version: "{{dnac_version}}"
dnac_debug: "{{dnac_debug}}"
dnac_log: True
dnac_log_level: "{{dnac_log_level}}"
state: deleted
config_verify: True
config:
- devices_list:
- name: string
ip: string
- ip_address_list: list
start_index: integer
records_to_return: integer
discovery_name: string
Expand Down Expand Up @@ -335,8 +325,8 @@ def validate_input(self):
'discovery_type': {'type': 'str', 'required': True},
'enable_password_list': {'type': 'list', 'required': False,
'elements': 'str'},
'devices_list': {'type': 'list', 'required': True,
'elements': 'dict'},
'ip_address_list': {'type': 'list', 'required': True,
'elements': 'str'},
'start_index': {'type': 'int', 'required': False,
'default': 25},
'records_to_return': {'type': 'int', 'required': False},
Expand Down Expand Up @@ -366,10 +356,12 @@ def validate_input(self):
'snmp_rw_community': {'type': 'str', 'required': False},
'snmp_rw_community_desc': {'type': 'str', 'required': False},
'snmp_username': {'type': 'str', 'required': False},
'snmp_version': {'type': 'str', 'required': True},
'snmp_version': {'type': 'str', 'required': False},
'timeout': {'type': 'str', 'required': False},
'username_list': {'type': 'list', 'required': False,
'elements': 'str'}
'elements': 'str'},
'cli_cred_len': {'type': 'int', 'required': False,
'default': 1}
}

# Validate discovery params
Expand Down Expand Up @@ -399,7 +391,7 @@ def get_creds_ids_list(self):
the class instance.
"""

self.log("Credential IDs list is {0}".format(str(self.creds_ids_list)), "INFO")
self.log("Credential Ids list passed is {0}".format(str(self.creds_ids_list)), "INFO")
return self.creds_ids_list

def get_dnac_global_credentials_v2_info(self):
Expand All @@ -422,11 +414,19 @@ def get_dnac_global_credentials_v2_info(self):
params=self.validated_config[0].get('headers'),
)
response = response.get('response')
cli_len_inp = self.validated_config[0].get("cli_cred_len")
if cli_len_inp > 5:
cli_len_inp = 5
self.log("The Global credentials response from 'get all global credentials v2' API is {0}".format(str(response)), "DEBUG")
for value in response.values():
if not value:
continue
self.creds_ids_list.extend(element.get('id') for element in value)
cli_len = 0
for key in response.keys():
if key == "cliCredential":
for element in response.get(key):
while cli_len < cli_len_inp:
self.creds_ids_list.append(element.get('id'))
cli_len += 1
else:
self.creds_ids_list.extend(element.get('id') for element in response.get(key))

if not self.creds_ids_list:
msg = 'Not found any credentials to perform discovery'
Expand All @@ -441,60 +441,71 @@ def get_devices_list_info(self):
It then updates the result attribute with this list.

Returns:
- devices_list: The list of devices extracted from the
- ip_address_list: The list of devices extracted from the
'validated_config' attribute.
"""
devices_list = self.validated_config[0].get('devices_list')
self.result.update(dict(devices_info=devices_list))
self.log("Devices list info passed is {0}".format(str(devices_list)), "INFO")
return devices_list
ip_address_list = self.validated_config[0].get('ip_address_list')
self.result.update(dict(devices_info=ip_address_list))
self.log("Details of the device list passed: {0}".format(str(ip_address_list)), "INFO")
return ip_address_list

def preprocessing_devices_info(self, devices_list=None):
def preprocess_device_discovery(self, ip_address_list=None):
"""
Preprocess the devices' information. Extract the IP addresses from
the list of devices and perform additional processing based on the
'discovery_type' in the validated configuration.

Parameters:
- devices_list: The list of devices to preprocess. If not
provided, an empty list is used.
- ip_address_list: The list of devices' IP addresses intended for preprocessing.
If not provided, an empty list will be used.

Returns:
- ip_address_list: If 'discovery_type' is "SINGLE", it returns the
first IP address. Otherwise, it returns a string
of IP ranges separated by commas.
- ip_address_list: It returns IP address list for the API to process. The value passed
for single, CDP, LLDP, CIDR, Range and Multi Range varies depending
on the need.
"""

if devices_list is None:
devices_list = []

ip_address_list = [device['ip'] for device in devices_list]

self.log("Discovery type passed for the discovery is {0}".format(self.validated_config[0].get('discovery_type')), "INFO")
if self.validated_config[0].get('discovery_type') in ["SINGLE", "CDP", "LLDP"]:
if ip_address_list is None:
ip_address_list = []
discovery_type = self.validated_config[0].get('discovery_type')
self.log("Discovery type passed for the discovery is {0}".format(discovery_type), "INFO")
if discovery_type in ["SINGLE", "CDP", "LLDP"]:
if len(ip_address_list) == 1:
ip_address_list = ip_address_list[0]
else:
self.log("Device list's length is longer than 1", "ERROR")
self.module.fail_json(msg="Device list's length is longer than 1", response=[])
elif self.validated_config[0].get('discovery_type') == "CIDR":
self.preprocess_device_discovery_handle_error()
elif discovery_type == "CIDR":
if len(ip_address_list) == 1 and self.validated_config[0].get('prefix_length'):
ip_address_list = ip_address_list[0]
ip_address_list = str(ip_address_list) + "/" + str(self.validated_config[0].get('prefix_length'))
else:
self.log("Device list's length is longer than 1", "ERROR")
self.module.fail_json(msg="Device list's length is longer than 1", response=[])
self.preprocess_device_discovery_handle_error()
elif discovery_type == "RANGE":
if len(ip_address_list) == 1:
if len(str(ip_address_list[0]).split("-")) == 2:
ip_address_list = ip_address_list[0]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we getting a list from a list?
or
ip_address = ip_address_list[0]

We can also simply write like:
ip = ip_list[0]

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are actually fetching the data for performing the API call

else:
ip_address_list = "{0}-{1}".format(ip_address_list[0], ip_address_list[0])
else:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these error messages are repeated for more than 3 times. Can we write an API and simplify it?
def preprocess_device_discovery_handle_error(self):
self.log("IP Address list's length is longer than 1", "ERROR")
self.module.fail_json(msg="IP Address list's length is longer than 1", response=[])

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

self.preprocess_device_discovery_handle_error()
else:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As many lines are repeated in this API:

if discovery_type in ["SINGLE", "CDP", "LLDP"]:
    if len(ip_address_list) == 1: 
        processed_ip_addresses = ip_address_list[0] 
    else:
        self.handle_discovery_error()
elif discovery_type == "CIDR":
    processed_ip_addresses = self.process_discovery_cidr(ip_address_list)
elif discovery_type == "RANGE":
    processed_ip_addresses = self.process_discovery_range(ip_address_list)
else:
    processed_ip_addresses = self.process_discovery_other(ip_address_list)

self.log("Collected IP address/addresses are {0}".format(str(processed_ip_addresses)), "INFO")

And followed by the functions?

def handle_discovery_error(self):
    self.log("The length of the IP address list is longer than 1", "ERROR")
    self.module.fail_json(msg="he length of the IP address list is longer than 1", response=[])

def process_cidr(self, ip_address_list):
    if  len(ip_address_list) != 1:
                self.handle_discovery_error()
                return

    prefix_length = self.validated_config[0].get('prefix_length')
#check prefix length if required...
    return "{0}/{1}".format(ip_address_list[0], prefix_length))

Likewise you can write other APIs...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved

ip_address_list = list(
map(
lambda x: '{0}-{value}'.format(x, value=x),
ip_address_list
)
)
ip_address_list = ','.join(ip_address_list)

new_ip_collected = []
for ip in ip_address_list:
if len(str(ip).split("-")) != 2:
ip_collected = "{0}-{0}".format(ip)
new_ip_collected.append(ip_collected)
ip_address_list = ','.join(new_ip_collected)
self.log("Collected IP address/addresses are {0}".format(str(ip_address_list)), "INFO")
return ip_address_list
return str(ip_address_list)

def preprocess_device_discovery_handle_error(self):
"""
Method for failing discovery based on the length of list of IP Addresses passed
for performing discovery.
"""

self.log("IP Address list's length is longer than 1", "ERROR")
self.module.fail_json(msg="IP Address list's length is longer than 1", response=[])

def create_params(self, credential_ids=None, ip_address_list=None):
"""
Expand Down Expand Up @@ -812,7 +823,7 @@ def get_diff_merged(self):

self.get_dnac_global_credentials_v2_info()
devices_list_info = self.get_devices_list_info()
ip_address_list = self.preprocessing_devices_info(devices_list_info)
ip_address_list = self.preprocess_device_discovery(devices_list_info)
exist_discovery = self.get_exist_discovery()
if exist_discovery:
params = dict(id=exist_discovery.get('id'))
Expand Down
5 changes: 0 additions & 5 deletions plugins/modules/pnp_intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@
description: Set to True to verify the Cisco DNA Center config after applying the playbook config.
type: bool
default: False
dnac_log_level:
description: Specifies the log level for Cisco Catalyst Center logging, categorizing logs by severity.
Options- [CRITICAL, ERROR, WARNING, INFO, DEBUG]
type: str
default: WARNING
state:
description: The state of DNAC after module completion.
type: str
Expand Down
Loading