-
Notifications
You must be signed in to change notification settings - Fork 9
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
Changes for typos, fixed CIDR issue and added delete all feature #132
Changes from 2 commits
d71b273
80ce79a
e015c82
c6a4737
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,13 +58,15 @@ | |
start_index: | ||
description: Start index for the header in fetching SNMP v2 credentials | ||
type: int | ||
default: 1 | ||
enable_password_list: | ||
description: List of enable passwords for the CLI crfedentials | ||
type: list | ||
elements: str | ||
records_to_return: | ||
description: Number of records to return for the header in fetching global v2 credentials | ||
type: int | ||
default: 100 | ||
http_read_credential: | ||
description: HTTP read credentials for hosting a device | ||
type: dict | ||
|
@@ -141,6 +143,10 @@ | |
description: Specifies the total number of CLI credentials to be used, ranging from 1 to 5. | ||
type: int | ||
default: 1 | ||
delete_all: | ||
description: Parameter to delete all the discoveries at one go | ||
type: bool | ||
default: False | ||
requirements: | ||
- dnacentersdk == 2.6.10 | ||
- python >= 3.5 | ||
|
@@ -152,6 +158,8 @@ | |
discovery.Discovery.get_discoveries_by_range, | ||
discovery.Discovery.get_discovered_network_devices_by_discovery_id', | ||
discovery.Discovery.delete_discovery_by_id | ||
discovery.Discovery.delete_all_discovery | ||
discovery.Discovery.get_count_of_all_discovery_jobs | ||
|
||
- Paths used are | ||
get /dna/intent/api/v2/global-credential | ||
|
@@ -160,6 +168,8 @@ | |
get /dna/intent/api/v1/discovery/{startIndex}/{recordsToReturn} | ||
get /dna/intent/api/v1/discovery/{id}/network-device | ||
delete /dna/intent/api/v1/discovery/{id} | ||
delete /dna/intent/api/v1/delete | ||
get /dna/intent/api/v1/discovery/count | ||
|
||
""" | ||
|
||
|
@@ -206,7 +216,7 @@ | |
snmp_version: string | ||
timeout: integer | ||
username_list: list | ||
cli_cred_length: integer | ||
cli_cred_len: integer | ||
- name: Delete disovery by name | ||
cisco.dnac.discovery_intent: | ||
dnac_host: "{{dnac_host}}" | ||
|
@@ -221,10 +231,7 @@ | |
state: deleted | ||
config_verify: True | ||
config: | ||
- ip_address_list: list | ||
start_index: integer | ||
records_to_return: integer | ||
discovery_name: string | ||
- discovery_name: string | ||
""" | ||
|
||
RETURN = r""" | ||
|
@@ -293,7 +300,7 @@ def __init__(self, module): | |
super().__init__(module) | ||
self.creds_ids_list = [] | ||
|
||
def validate_input(self): | ||
def validate_input(self, state=None): | ||
""" | ||
Validate the fields provided in the playbook. Checks the | ||
configuration provided in the playbook against a predefined | ||
|
@@ -322,22 +329,18 @@ def validate_input(self): | |
discovery_spec = { | ||
'cdp_level': {'type': 'int', 'required': False, | ||
'default': 16}, | ||
'discovery_type': {'type': 'str', 'required': True}, | ||
'enable_password_list': {'type': 'list', 'required': False, | ||
'elements': 'str'}, | ||
'ip_address_list': {'type': 'list', 'required': True, | ||
'elements': 'str'}, | ||
'start_index': {'type': 'int', 'required': False, | ||
'default': 25}, | ||
'records_to_return': {'type': 'int', 'required': False}, | ||
'default': 1}, | ||
'records_to_return': {'type': 'int', 'required': False, | ||
'default': 100}, | ||
'http_read_credential': {'type': 'dict', 'required': False}, | ||
'http_write_credential': {'type': 'dict', 'required': False}, | ||
'ip_filter_list': {'type': 'list', 'required': False, | ||
'elements': 'str'}, | ||
'lldp_level': {'type': 'int', 'required': False, | ||
'default': 16}, | ||
'prefix_length': {'type': 'int', 'required': False, | ||
'default': 30}, | ||
'discovery_name': {'type': 'str', 'required': True}, | ||
'netconf_port': {'type': 'str', 'required': False}, | ||
'password_list': {'type': 'list', 'required': False, | ||
|
@@ -364,6 +367,18 @@ def validate_input(self): | |
'default': 1} | ||
} | ||
|
||
if state == "merged": | ||
discovery_spec["ip_address_list"] = {'type': 'list', 'required': True, | ||
'elements': 'str'} | ||
discovery_spec["discovery_type"] = {'type': 'str', 'required': True} | ||
|
||
if state == "deleted": | ||
if self.config[0].get("delete_all") is True: | ||
self.validated_config = [{"delete_all": True}] | ||
self.msg = "Sucessfully collected input for deletion of all the discoveries" | ||
self.log(self.msg, "WARNING") | ||
return self | ||
|
||
# Validate discovery params | ||
valid_discovery, invalid_params = validate_list_of_dicts( | ||
self.config, discovery_spec | ||
|
@@ -475,9 +490,12 @@ def preprocess_device_discovery(self, ip_address_list=None): | |
else: | ||
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')) | ||
if len(ip_address_list) == 1: | ||
if len(ip_address_list[0].split("/")) == 2: | ||
ip_address_list = ip_address_list[0] | ||
else: | ||
ip_address_list = str(ip_address_list[0]) + "/" + str("30") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we give a warning message? Say that prefix length is not given, hence taking 30 as default.. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
self.log("Prefix length is not given, hence taking 30 as default", "WARNING") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we add bit more detail? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
else: | ||
self.preprocess_device_discovery_handle_error() | ||
elif discovery_type == "RANGE": | ||
|
@@ -493,7 +511,9 @@ def preprocess_device_discovery(self, ip_address_list=None): | |
for ip in ip_address_list: | ||
if len(str(ip).split("-")) != 2: | ||
ip_collected = "{0}-{0}".format(ip) | ||
new_ip_collected.append(ip_collected) | ||
new_ip_collected.append(ip_collected) | ||
else: | ||
new_ip_collected.append(ip) | ||
ip_address_list = ','.join(new_ip_collected) | ||
self.log("Collected IP address/addresses are {0}".format(str(ip_address_list)), "INFO") | ||
return str(ip_address_list) | ||
|
@@ -567,7 +587,7 @@ def create_params(self, credential_ids=None, ip_address_list=None): | |
'snmp_username') | ||
new_object_params['snmpVersion'] = self.validated_config[0].get('snmp_version') | ||
new_object_params['timeout'] = self.validated_config[0].get('timeout') | ||
new_object_params['userNameList'] = self.validated_config[0].get('user_name_list') | ||
new_object_params['userNameList'] = self.validated_config[0].get('username_list') | ||
self.log("The payload/object created for calling the start discovery API is {0}".format(str(new_object_params)), "INFO") | ||
|
||
return new_object_params | ||
|
@@ -855,20 +875,43 @@ def get_diff_deleted(self): | |
- self: The instance of the class with updated attributes. | ||
""" | ||
|
||
exist_discovery = self.get_exist_discovery() | ||
if not exist_discovery: | ||
self.result['msg'] = "Discovery {0} Not Found".format( | ||
self.validated_config[0].get("discovery_name")) | ||
self.log(self.result['msg'], "ERROR") | ||
return self | ||
if self.validated_config[0].get("delete_all"): | ||
count_discoveries = self.dnac_apply['exec']( | ||
family="discovery", | ||
function="get_count_of_all_discovery_jobs", | ||
) | ||
if count_discoveries.get("response") == 0: | ||
msg = "There are no discoveries present in the Discovery Dashboard for deletion" | ||
self.result['msg'] = msg | ||
self.log(msg, "WARNING") | ||
self.result['response'] = self.validated_config[0] | ||
return self | ||
|
||
delete_all_response = self.dnac_apply['exec']( | ||
family="discovery", | ||
function="delete_all_discovery", | ||
) | ||
discovery_task_id = delete_all_response.get('response').get('taskId') | ||
self.result["changed"] = True | ||
self.result['msg'] = "All of the Discoveries Deleted Successfully" | ||
self.result['diff'] = self.validated_config | ||
|
||
else: | ||
exist_discovery = self.get_exist_discovery() | ||
if not exist_discovery: | ||
self.result['msg'] = "Discovery {0} Not Found".format( | ||
self.validated_config[0].get("discovery_name")) | ||
self.log(self.result['msg'], "ERROR") | ||
return self | ||
|
||
params = dict(id=exist_discovery.get('id')) | ||
discovery_task_id = self.delete_exist_discovery(params=params) | ||
complete_discovery = self.get_task_status(task_id=discovery_task_id) | ||
self.result["changed"] = True | ||
self.result['msg'] = "Successfully deleted discovery" | ||
self.result['diff'] = self.validated_config | ||
self.result['response'] = discovery_task_id | ||
|
||
params = dict(id=exist_discovery.get('id')) | ||
discovery_task_id = self.delete_exist_discovery(params=params) | ||
complete_discovery = self.get_task_status(task_id=discovery_task_id) | ||
self.result["changed"] = True | ||
self.result['msg'] = "Discovery Deleted Successfully" | ||
self.result['diff'] = self.validated_config | ||
self.result['response'] = discovery_task_id | ||
self.log(self.result['msg'], "INFO") | ||
return self | ||
|
||
|
@@ -900,9 +943,8 @@ def verify_diff_merged(self, config): | |
function='get_discovery_by_id', | ||
params=params | ||
) | ||
|
||
discovery_name = config.get('discovery_name') | ||
if response: | ||
discovery_name = response.get('response').get('name') | ||
self.log("Requested Discovery with name {0} is completed".format(discovery_name), "INFO") | ||
|
||
else: | ||
|
@@ -928,19 +970,9 @@ def verify_diff_deleted(self, config): | |
self.log("Current State (have): {0}".format(str(self.have)), "INFO") | ||
self.log("Desired State (want): {0}".format(str(config)), "INFO") | ||
# Code to validate dnac config for deleted state | ||
discovery_task_info = self.get_discoveries_by_range_until_success() | ||
discovery_id = discovery_task_info.get('id') | ||
params = dict( | ||
id=discovery_id | ||
) | ||
response = self.dnac_apply['exec']( | ||
family="discovery", | ||
function='get_discovery_by_id', | ||
params=params | ||
) | ||
|
||
if response: | ||
discovery_name = response.get('response').get('name') | ||
discovery_task_info = self.lookup_discovery_by_range_via_name() | ||
discovery_name = config.get('discovery_name') | ||
if discovery_task_info: | ||
self.log("Requested Discovery with name {0} is present".format(discovery_name), "WARNING") | ||
|
||
else: | ||
|
@@ -981,7 +1013,7 @@ def main(): | |
dnac_discovery.msg = "State {0} is invalid".format(state) | ||
dnac_discovery.check_return_status() | ||
|
||
dnac_discovery.validate_input().check_return_status() | ||
dnac_discovery.validate_input(state=state).check_return_status() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reasons for this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are passing the state value here to use in the validation part There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. but why do we need to assign state = state when we call the function? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will it work if I don't pass the state? |
||
for config in dnac_discovery.validated_config: | ||
dnac_discovery.reset_values() | ||
dnac_discovery.get_diff_state_apply[state]().check_return_status() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the 'state' is merged, there is no possibility for the state to be "deleted". Therefore, it is more efficient to use "elif" instead. By using two "if" statements, we unnecessarily perform the state comparison twice…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done