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

New provision workflow feature #62

Conversation

syed-khadeerahmed
Copy link
Collaborator

@syed-khadeerahmed syed-khadeerahmed commented Dec 12, 2024

Description

Please include a summary of the changes and the related issue. Also, include relevant motivation and context.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules
  • All the sanity checks have been completed and the sanity test cases have been executed

Ansible Best Practices

  • Tasks are idempotent (can be run multiple times without changing state)
  • Variables and secrets are handled securely (e.g., using ansible-vault or environment variables)
  • Playbooks are modular and reusable
  • Handlers are used for actions that need to run on change

Documentation

  • All options and parameters are documented clearly.
  • Examples are provided and tested.
  • Notes and limitations are clearly stated.

Screenshots (if applicable)

Notes to Reviewers

to be validated.
- uuid (str): The UUID of the device to check for site assignment.
Returns:
- boolean: True if the device is assigned to a site, False otherwise.
Copy link
Collaborator

Choose a reason for hiding this comment

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

You are returning tuple..

      - tuple: (bool, Optional[str]) 
        - True and the site name if the device is assigned to a site.
        - False and None if not assigned or in case of an error.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed the code


self.log("Response collected from the API 'get_site_assigned_network_device' {0}".format(site_response))
site_name = None
if site_response.get("response").get("siteNameHierarchy"):
Copy link
Collaborator

Choose a reason for hiding this comment

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

            site_api_response = self.dnac_apply['exec'](
                family="site_design",
                function='get_site_assigned_network_device',
                params={"id": uuid}
            )


Getting site_response in two places.. Also else is not required as we return from if statement.. We can log a message before returning..

        site_response = site_api_response.get("response")
        if site_response:
            site_name = site_response.get("siteNameHierarchy")
            if site_name:
                self.log("Device with UUID {0} is assigned to site: {1}".format(uuid, site_name), "INFO")
                return True, site_name

        self.log("Device with UUID {0} is not assigned to any site.".format(uuid), "INFO")
        return False, None

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed the code

self.log("Managed AP Location must be a floor", "CRITICAL")
self.module.fail_json(msg="Managed AP Location must be a floor", response=[])
ap_locations = wireless_params[0].get("managedAPLocations")
if not (ap_locations and isinstance(ap_locations, list)):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Make it more readable..

if not ap_locations or not isinstance(ap_locations, list):

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed the code

self.floor_names.append(ap_loc)

if site_type == "building":
Bulding_name = ap_loc + ".*"
Copy link
Collaborator

Choose a reason for hiding this comment

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

"building_name" Not "Building_name"

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed the code

floors = self.get_site(Bulding_name)

for item in floors['response']:

Copy link
Collaborator

Choose a reason for hiding this comment

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

no need of new line

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed the code

site_type = self.get_site_type(site_name_hierarchy=ap_loc)
self.log("Checking site type for AP location '{0}', resolved type: '{1}'".format(ap_loc, site_type), "DEBUG")

if site_type not in ["floor", "building"]:
Copy link
Collaborator

Choose a reason for hiding this comment

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

The site_type could be either floor or building or otherwise.. Can we simplify it?

    if site_type == "floor":
        self.log("Adding '{0}' to floor names list".format(ap_loc), "DEBUG")
        self.floor_names.append(ap_loc)
    elif site_type == "building":
        self.log("Building site type detected for '{0}'. Retrieving floor details.".format(ap_loc), "DEBUG")
        building_name = ap_loc + ".*"
        floors = self.get_site(building_name)

        for item in floors['response']:
            if item.get('type') == 'floor':
                self.log("Floor found: '{0}' for building '{1}'".format(item['nameHierarchy'], ap_loc), "DEBUG")
                self.floor_names.append(item['nameHierarchy'])
            elif 'additionalInfo' in item:
                for additional_info in item['additionalInfo']:
                    if 'attributes' in additional_info and additional_info['attributes'].get('type') == 'floor':
                        self.log("Floor found in additionalInfo: '{0}' for building '{1}'".format(item['siteNameHierarchy'], ap_loc), "DEBUG")
                        self.floor_names.append(item['siteNameHierarchy'])
    else:
        self.log("Invalid site type detected for '{0}'. Managed AP Location must be building or floor.".format(ap_loc), "CRITICAL")
        self.module.fail_json(msg="Managed AP Location must be building or floor", response=[])

self.log("Final list of floor names: {0}".format(self.floor_names), "DEBUG")

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed the code

self.module.fail_json(msg=msg, response=[])

self.floor_names = []
for ap_loc in self.validated_config.get("managed_ap_locations"):
Copy link
Collaborator

Choose a reason for hiding this comment

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

self.log("Processing AP location: {0}".format(ap_loc), "DEBUG")

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed the code

self.floor_names = []
for ap_loc in self.validated_config.get("managed_ap_locations"):
site_type = self.get_site_type(site_name_hierarchy=ap_loc)
self.log("Checking site type for AP location '{0}', resolved type: '{1}'".format(ap_loc, site_type), "DEBUG")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Instead
self.log("Resolved site type for AP location '{0}': '{1}'".format(ap_loc, site_type), "DEBUG")

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed the code

self.log(self.result['msg'], "INFO")
return self

if self.status == 'failed':
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we check only for failed? What happens if status is exited? Do we print any message?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed the code

self.log("Exception occurred during 'delete_provisioned_devices': {0}".format(str(fail_reason)), "ERROR")
self.msg = "Error in delete provisioned device '{0}' due to {1}".format(self.device_ip, str(fail_reason))
self.log(self.msg, "ERROR")
self.status = "failed"
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is the use of setting again to failed.. you compared it in line 1644..

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

the above self.status comes from the function - check_tasks_response_status but the below self.status is used to end the code as failed

@madhansansel madhansansel merged commit 88b09a4 into cisco-en-programmability:main Dec 17, 2024
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants