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

Delete entire site in one shot #64

Merged
merged 3 commits into from
Dec 8, 2023
Merged
Changes from 2 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
170 changes: 109 additions & 61 deletions plugins/modules/site_intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,11 +307,11 @@
)

floor_plan = {
'57057': 'CUBES AND WALLED OFFICES',
'57058': 'DRYWELL OFFICE ONLY',
'41541500': 'FREE SPACE',
'57060': 'INDOOR HIGH CEILING',
'57059': 'OUTDOOR OPEN SPACE'
'101101': 'Cubes And Walled Offices',
'101102': 'Drywall Office Only',
'101105': 'Free Space',
'101104': 'Indoor High Ceiling',
'101103': 'Outdoor Open Space'
}


Expand Down Expand Up @@ -373,7 +373,7 @@ def get_current_site(self, site):
"""
Get the current site information.
Parameters:
- self (object): An instance of the class containing the method.
self (object): An instance of a class used for interacting with Cisco DNA Center.
- site (list): A list containing information about the site.
Returns:
- dict: A dictionary containing the extracted site information.
Expand Down Expand Up @@ -403,7 +403,7 @@ def get_current_site(self, site):
building=dict(
name=site[0].get("name"),
parentName=site[0].get("siteNameHierarchy").split("/" + site[0].get("name"))[0],
address=location.get("attributes").get("address", ""),
address=location.get("attributes").get("address"),
latitude=location.get("attributes").get("latitude"),
longitude=location.get("attributes").get("longitude"),
)
Expand Down Expand Up @@ -484,6 +484,7 @@ def get_site_params(self, params):
Store the site-related parameters.

Parameters:
self (object): An instance of a class used for interacting with Cisco DNA Center.
- params (dict): Dictionary containing site-related parameters.
Returns:
- dict: Dictionary containing the stored site-related parameters.
Expand All @@ -509,7 +510,7 @@ def get_site_params(self, params):
building_details = params.get('site').get('building')
site_info['building'] = {
'name': building_details.get('name'),
'address': building_details.get('address', ""),
'address': building_details.get('address'),
'parentName': building_details.get('parent_name'),
'latitude': building_details.get('latitude'),
'longitude': building_details.get('longitude'),
Expand Down Expand Up @@ -542,6 +543,7 @@ def get_site_name(self, site):
Get and Return the site name.

Parameters:
self (object): An instance of a class used for interacting with Cisco DNA Center.
- site (dict): A dictionary containing information about the site.
Returns:
- str: The constructed site name.
Expand All @@ -564,14 +566,14 @@ def site_requires_update(self):
Check if the site requires updates.

Parameters:
- site (dict): A dictionary containing information about the site.
self (object): An instance of a class used for interacting with Cisco DNA Center.
Returns:
- bool: True if the site requires updates, False otherwise.
bool: True if the site requires updates, False otherwise.
Description:
This method compares the site parameters of the current site
('current_site') and the requested site parameters ('requested_site')
stored in the 'want' attribute. It checks for differences in
specified parameters, such as the site type and site details.
('current_site') and the requested site parameters ('requested_site')
stored in the 'want' attribute. It checks for differences in
specified parameters, such as the site type and site details.
"""

requested_site = self.want.get("site_params")
Expand All @@ -580,6 +582,15 @@ def site_requires_update(self):
self.log("Current Site: " + str(current_site))
self.log("Requested Site: " + str(requested_site))

if requested_site.get('type') == "building":
requested_address = requested_site['site']['building']['address']
current_address = current_site['site']['building']['address']

if requested_address is None or requested_address == current_address:
return False

return True

obj_params = [
("type", "type"),
("site", "site")
Expand Down Expand Up @@ -628,14 +639,15 @@ def get_want(self, config):
creation in Cisco DNA Center.

Parameters:
- config (dict): A dictionary containing configuration information.
self (object): An instance of a class used for interacting with Cisco DNA Center.
config (dict): A dictionary containing configuration information.
Returns:
- object: The instance of the class.
self (object): An instance of a class used for interacting with Cisco DNA Center.
Description:
Retrieves all site-related information from playbook that is
required for creating a site in Cisco DNA Center. It includes
parameters such as 'site_params' and 'site_name.' The gathered
information is stored in the 'want' attribute for later reference.
required for creating a site in Cisco DNA Center. It includes
parameters such as 'site_params' and 'site_name.' The gathered
information is stored in the 'want' attribute for later reference.
"""

want = {}
Expand All @@ -654,25 +666,17 @@ def get_diff_merged(self, config):
provided in the playbook.

Parameters:
- config (dict): A dictionary containing configuration information.
self (object): An instance of a class used for interacting with Cisco DNA Center.
config (dict): A dictionary containing configuration information.

Returns:
- object: The instance of the class. The result dictionary includes
the following keys:
- 'changed' (bool): Indicates whether changes were made
during the update or creation process.
- 'response' (dict): Contains details about the execution
and the updated or created site ID.
- 'msg' (str): A message indicating the status of the
update or creation operation.
self (object): An instance of a class used for interacting with Cisco DNA Center.
Description:
This method determines whether to update or create a site in
Cisco DNA Center based on the provided configuration information. If
the specified site exists, the method checks if it requires an update
by calling the 'site_requires_update' method. If an update is
required, it calls the 'update_site' function from the 'sites' family
of the Cisco DNA Center API. If the site does not require an update,
the method exits, indicating that the site is up to date.
This method determines whether to update or create a site in Cisco DNA Center based on the provided
configuration information. If the specified site exists, the method checks if it requires an update
by calling the 'site_requires_update' method. If an update is required, it calls the 'update_site'
function from the 'sites' family of the Cisco DNA Center API. If the site does not require an update,
the method exits, indicating that the site is up to date.
"""

site_updated = False
Expand Down Expand Up @@ -746,6 +750,52 @@ def get_diff_merged(self, config):

return self

def delete_single_site(self, site_id, site_name):
""""
Delete a single site in the Cisco DNA Center.
Parameters:
self (object): An instance of a class used for interacting with Cisco DNA Center.
site_id (str): The ID of the site to be deleted.
site_name (str): The name of the site to be deleted.
Returns:
self (object): An instance of a class used for interacting with Cisco DNA Center.
Description:
This function initiates the deletion of a site in the Cisco DNA Center by calling the delete API.
If the deletion is successful, the result is marked as changed, and the status is set to "success."
If an error occurs during the deletion process, the status is set to "failed," and the log contains
details about the error.
"""

try:
response = self.dnac._exec(
family="sites",
function="delete_site",
params={"site_id": site_id},
)

if response and isinstance(response, dict):
executionid = response.get("executionId")
while True:
execution_details = self.get_execution_details(executionid)
if execution_details.get("status") == "SUCCESS":
msg = "Site - {0} deleted successfully".format(site_name)
self.result['changed'] = True
self.result['response'] = msg
self.status = "success"
self.log(msg)
break
elif execution_details.get("bapiError"):
self.module.fail_json(msg=execution_details.get("bapiError"), response=execution_details)
break

except Exception as e:
msg = "Cannot Delete device from Inventory because of {0}".format(str(e))
self.log(msg)
self.status = "failed"
self.msg = msg

return self

def get_diff_deleted(self, config):
"""
Call Cisco DNA Center API to delete sites with provided inputs.
Expand All @@ -772,37 +822,35 @@ def get_diff_deleted(self, config):
"""

site_exists = self.have.get("site_exists")
if not site_exists:
msg = msg = "Cannot delete Site - {0} as it's not found in Cisco DNA Center".format(self.want.get("site_name"))
self.result.update({'changed': False,
'response': msg,
'msg': msg})
self.log(msg)
self.status = "success"
return self

if site_exists:
response = self.dnac._exec(
family="sites",
function="delete_site",
params={"site_id": self.have.get("site_id")},
)
# Check here if the site have the childs then fetch it using get membership API and then sort it
# in reverse order and start deleting from bottom to top
site_id = self.have.get("site_id")
mem_response = self.dnac._exec(
family="sites",
function="get_membership",
params={"site_id": site_id},
)
site_response = mem_response.get("site").get("response")

if response and isinstance(response, dict):
executionid = response.get("executionId")
while True:
execution_details = self.get_execution_details(executionid)
if execution_details.get("status") == "SUCCESS":
self.result['changed'] = True
self.result['response'] = execution_details
self.result['response'].update({"siteId": self.have.get("site_id")})
self.result['msg'] = "Site - {0} deleted successfully".format(self.want.get("site_name"))
break
if len(site_response) == 0:
self.delete_single_site(site_id, self.want.get("site_name"))
return self

elif execution_details.get("bapiError"):
self.module.fail_json(msg=execution_details.get("bapiError"),
response=execution_details)
break
# Sorting the response in reverse order based on hierarchy levels
sorted_site_resp = sorted(site_response, key=lambda x: x.get("groupHierarchy"), reverse=True)

else:
msg = "Cannot delete Site - {0} as it's not found in Cisco DNA Center".format(self.want.get("site_name"))
self.status = "success"
self.result['changed'] = False
self.result['response'] = msg
self.log(msg)
self.result['msg'] = msg
# Deleting each level in reverse order till topmost parent site
for item in sorted_site_resp:
self.delete_single_site(item['id'], item['name'])

Abhishek-121 marked this conversation as resolved.
Show resolved Hide resolved
return self

Expand Down