Skip to content

Access group feature added - user_role_workflow_manager#446

Merged
madhansansel merged 5 commits intocisco-en-programmability:mainfrom
Priyadharshini16092002:user_role_feature
Apr 29, 2026
Merged

Access group feature added - user_role_workflow_manager#446
madhansansel merged 5 commits intocisco-en-programmability:mainfrom
Priyadharshini16092002:user_role_feature

Conversation

@Priyadharshini16092002
Copy link
Copy Markdown

@Priyadharshini16092002 Priyadharshini16092002 commented Apr 27, 2026

Type of Change

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

Description

Summary:
Added enhancement for user_role_workflow_manager - creation, update and deletion of access group support is added from v3.1.6.0

Sample playbook:
config:
access_group_details:
- name: "Test_access_group"
description: "Updated description"
site_hierarchy: "Global/Australia"
role_name: "role_2"

Testing Done:

  • Manual testing
  • Unit tests
  • Integration tests

Test cases covered: [Mention test case IDs or brief points]

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

"ERROR",
)
self.set_operation_result("failed", False, self.msg, "ERROR")
return self
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Callers (get_diff_merged line 2358, access_group_requires_update line 5610) check if not role_id: — returning self is truthy, so the error is silently ignored and self is used as a role ID string in the API payload, causing a downstream API failure.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

        return None ??

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

updated the code

return self

self.log(
"xAccess group "
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Typo "xAccess group"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

        self.log(
            "Access group "

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated the code

"spaces.".format(name)
)

new_name = ag_config.get("new_name")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

the update comparison and payload construction are not using the new_name.. can you check and update?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Removed new_name parameter from the code as we will not be able to update access group name. Checked in both UI and API

"Description update required.",
"DEBUG",
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do we need to add check for new_name here?

        # Check name change (rename)
        desired_new_name = desired_config.get("new_name")
        if desired_new_name:
            current_name = current_config.get("name", "")
            self.log(
                "Comparing name - current: '{0}', "
                "desired new_name: '{1}'".format(
                    current_name, desired_new_name
                ),
                "DEBUG",
            )
            if desired_new_name != current_name:
                update_payload["name"] = desired_new_name
                update_required = True
                self.log(
                    "access_group_requires_update: "
                    "Name update (rename) required.",
                    "DEBUG",
                )

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Removed new_name parameter from the code as we will not be able to update access group name. Checked in both UI and API

"response": {
"msg": "Role not found."
}
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

# Case 12: Successful creation of access group
response_12:
  description: A message confirming access group creation.
  returned: always
  type: dict
  sample:
    {
        "response": "Access group(s) 'Test_access_group' created successfully in Cisco Catalyst Center."
    }

# Case 13: Access group already exists, no update needed
response_13:
  description: A message indicating the access group needs no update.
  returned: always
  type: dict
  sample:
    {
        "response": "Access group(s) 'Test_access_group' need no update in Cisco Catalyst Center."
    }

Also can you please add a new line for every case?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated the code

result_msg_list.append(delete_ag_msg)

if self.no_deleted_access_group:
no_delete_ag_msg = (
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

            no_delete_ag_msg = (
                "Access group(s) '{0}' is already absent in "
                "Cisco Catalyst Center. Nothing to "
                "delete.".format(
                    "', '".join(
                        self.no_deleted_access_group
                    )
                )
            )

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated the code

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

short_description: Resource module for managing users,
  roles, and access groups in Cisco Catalyst Center.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated the code

self.assertEqual(
result.get("response"),
"Invalid parameters in playbook config: role_name: Required when creating a new access group."
)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

def test_user_role_workflow_manager_resolve_role_api_failure(self):
    """
    Verify that when get_roles raises an exception during
    access group creation, the module fails gracefully with
    a clear error instead of passing 'self' as a role ID.
    """
    set_module_args(
        dict(
            dnac_host="1.1.1.1",
            dnac_username="dummy",
            dnac_password="dummy",
            dnac_log=True,
            state="merged",
            config_verify=False,
            dnac_version="3.1.6.0",
            config=self.playbook_create_access_group,
        )
    )
    # Mock get_access_groups to return no match,
    # get_sites to succeed, get_roles to raise
    self.run_dnac_exec.side_effect = [
        self.test_data.get("get_access_groups"),
        self.test_data.get("get_sites"),
        Exception("Connection timeout"),
    ]
    result = self.execute_module(changed=False, failed=True)
    self.assertIn("role", result.get("msg", "").lower())

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Updated the code

@madhansansel madhansansel merged commit 76cce65 into cisco-en-programmability:main Apr 29, 2026
12 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