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 swim workflow feature #57

55 changes: 53 additions & 2 deletions plugins/modules/swim_workflow_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ class Swim(DnacBase):
def __init__(self, module):
super().__init__(module)
self.supported_states = ["merged"]
self.images_to_import, self.existing_images = [], []

def validate_input(self):
"""
Expand Down Expand Up @@ -1373,6 +1374,7 @@ def get_diff_import(self):
self.log(name)
if self.is_image_exist(name):
existing_images.append(name)
self.existing_images.append(name)
self.log("Image '{0}' already exists in Cisco Catalyst Center, skipping import.".format(name), "INFO")
else:
images_to_import.append(name)
Expand Down Expand Up @@ -1457,7 +1459,7 @@ def get_diff_import(self):
if "completed successfully" in task_details.get("progress", "").lower():
if images_to_import:
images_to_import_str = ", ".join(images_to_import)

self.images_to_import.append(images_to_import_str)
self.result['changed'] = True
self.status = "success"
self.msg = "Swim Image(s) {0} imported successfully".format(images_to_import_str)
Expand Down Expand Up @@ -1679,6 +1681,15 @@ def get_diff_tagging(self):
self.result['response'] = self.msg
self.log(self.msg, "INFO")
break
elif task_details.get("isError"):
Copy link
Collaborator

Choose a reason for hiding this comment

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

getting isError, progress, failure_reason from task_details used in multiple places.
Can't we get the vaules, store and use it?

<<< Sample Code, modify the code based on your logic.... >>>>>>>>>>

device_family = tagging_details.get("device_image_family_name")
device_role = tagging_details.get("device_role", "ALL")
site_name = tagging_details.get("site_name", "Global")

while True:
    task_details = self.get_task_details(task_id)
    is_error = task_details.get("isError")
    progress = task_details.get("progress", "")
    failure_reason = task_details.get("failureReason", "")

    if is_error:
        if not tag_image_golden and "An inheritted tag cannot be un-tagged" in failure_reason:
            self.msg = failure_reason
        else:
            action = "Tagging" if tag_image_golden else "Un-Tagging"
            self.msg = (
                "{0} image {1} golden for site {2} for family {3} for device role {4} failed."
                .format(action, image_name, site_name, device_family, device_role)
            )
        self.status = "failed"
        self.result['changed'] = False
        self.result['msg'] = self.msg
        self.log(self.msg, "ERROR")
        break

    if "successful" in progress:
        action = "Tagging" if tag_image_golden else "Un-Tagging"
        self.msg = (
            "{0} image {1} golden for site {2} for family {3} for device role {4} successful."
            .format(action, image_name, site_name, device_family, device_role)
        )
        self.status = "success"
        self.result['changed'] = True
        self.result['msg'] = self.msg
        self.log(self.msg, "INFO")
        break

return self

What happens if not is_error, and not successful in progress? Do we sleep for some time? Is it needed to be in while loop to do tag and untag an image? If we still need to check "while" loop, then add sleep and do checks for default times and break from the loop..

self.status = "failed"
self.result['changed'] = False
self.msg = ("Tagging image {0} golden for site {1} for family {2} for device deviceTag"
" - {3} Failed".format(image_name, site_name, device_family, device_role))
self.result['msg'] = self.msg
self.result['response'] = self.msg
self.log(self.msg, "ERROR")
break
else:
if not task_details.get("isError") and 'successful' in task_details.get("progress"):
self.status = "success"
Expand All @@ -1689,6 +1700,7 @@ def get_diff_tagging(self):
self.result['response'] = self.msg
self.log(self.msg, "INFO")
break

elif task_details.get("isError"):
failure_reason = task_details.get("failureReason", "")
if failure_reason and "An inheritted tag cannot be un-tagged" in failure_reason:
Expand Down Expand Up @@ -2315,6 +2327,45 @@ def verify_diff_merged(self, config):

return self

def update_swim_profile_messages(self):
"""
Verify the merged status (Importing/Tagging/Distributing/Activating) of the SWIM Image in devices in Cisco Catalyst Center.
Args:
- self (object): An instance of a class used for interacting with Cisco Catalyst Center.
Return:
- self (object): An instance of a class used for interacting with Cisco Catalyst Center.
Description:
This method checks the merged status of a configuration in Cisco Catalyst Center by retrieving the current state
(have) and desired state (want) of the configuration. It logs the current and desired states, and validates whether
the specified SWIM operation (Importing, Tagging, Distributing, or Activating) has been successfully performed or not.
"""

if self.images_to_import or self.existing_images:
imported_images_str = ", ".join(self.images_to_import)
skipped_images_str = ", ".join(self.existing_images)

messages = []

if skipped_images_str:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we opimize the logic?

        messages = []

        if skipped_images_str:
            messages.append("Image(s) {0} were skipped as they already exist in Cisco Catalyst Center.".format(skipped_images_str))

        if imported_images_str:
            messages.append("Image(s) {0} have been imported successfully into Cisco Catalyst Center.".format(imported_images_str))
        elif not skipped_images_str:
            messages.append("No images were imported.")

if imported_images_str:
messages.append("Image(s) {0} were skipped as they already exist in Cisco Catalyst Center.".format(skipped_images_str))
messages.append("Images {0} have been imported successfully.".format(imported_images_str))
else:
messages.append("Image(s) {0} were skipped as they already exist in Cisco Catalyst Center."
"No new images were imported.".format(skipped_images_str))
elif imported_images_str:
messages.append("Image(s) {0} have been imported successfully into Cisco Catalyst Center.".format(imported_images_str))
else:
messages.append("No images were imported.")

self.msg = " ".join(messages)

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

return self


def main():
""" main entry point for module execution
Expand Down Expand Up @@ -2361,7 +2412,7 @@ def main():
ccc_swims.get_diff_state_apply[state](config).check_return_status()
if config_verify:
ccc_swims.verify_diff_state_apply[state](config).check_return_status()

ccc_swims.update_swim_profile_messages()
module.exit_json(**ccc_swims.result)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,26 +256,26 @@
# Delete Device #
#############################################

- name: Delete device
cisco.dnac.inventory_workflow_manager:
<<: *dnac_login
state: deleted
config:
- "{{ item }}"
loop: "{{ vars_map.delete_devices }}"
register: result_device_deleted
# - name: Delete device
Copy link
Collaborator

Choose a reason for hiding this comment

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

Remove commented lines...

# cisco.dnac.inventory_workflow_manager:
# <<: *dnac_login
# state: deleted
# config:
# - "{{ item }}"
# loop: "{{ vars_map.delete_devices }}"
# register: result_device_deleted

# - name: Debug item
# debug:
# var: item
# loop: "{{ result_device_deleted.results }}"
# when: result_device_deleted is defined
# # - name: Debug item
# # debug:
# # var: item
# # loop: "{{ result_device_deleted.results }}"
# # when: result_device_deleted is defined

- name: Assert device deletion success
assert:
that:
- result_device_deleted.changed == true
when: result_device_deleted is defined
# - name: Assert device deletion success
# assert:
# that:
# - result_device_deleted.changed == true
# when: result_device_deleted is defined

#############################################
# PAUSE #
Expand Down
Loading