Skip to content

Commit

Permalink
Changes for getting auth user list (dell#113)
Browse files Browse the repository at this point in the history
* Changes for getting auth user list

* Updated unit test case

* Updated unit test case

* Updated file with filter option

---------

Co-authored-by: Sachin Apagundi <62133262+sachin-apa@users.noreply.github.com>
  • Loading branch information
meenakshidembi691 and sachin-apa authored Sep 20, 2024
1 parent 5a7f60d commit ed16092
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 80 deletions.
12 changes: 12 additions & 0 deletions playbooks/modules/info.yml
Original file line number Diff line number Diff line change
Expand Up @@ -442,3 +442,15 @@
writable_snapshots:
sort: src_snap
state: active

- name: To filter the users using username
dellemc.powerscale.info:
onefs_host: "{{ onefs_host }}"
verify_ssl: "{{ verify_ssl }}"
api_user: "{{ api_user }}"
api_password: "{{ api_password }}"
gather_subset:
- users
query_parameters:
users:
filter: sample
3 changes: 2 additions & 1 deletion playbooks/modules/nfs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@
client_state: 'absent-in-export'
state: 'present'

# This task will replace existing read only clients, client1 and client2 with client3 and client4
# This task will replace existing read only clients,
# client1 and client2 with client3 and client4
- name: Replace existing readonly clients
dellemc.powerscale.nfs:
onefs_host: "{{ onefs_host }}"
Expand Down
36 changes: 36 additions & 0 deletions plugins/module_utils/storage/dell/shared_library/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,39 @@ def get_auth_roles(self, zone):
f'due to error {error_msg}.'
LOG.error(error_message)
self.module.fail_json(msg=error_message)

def get_auth_users(self, zone):
"""
Get list of the auth user for a given access zone
"""
LOG.info("Getting list of auth users.")
try:
query_params = self.module.params.get('query_parameters')
auth_user_query_params = []
if query_params:
auth_user_query_params = query_params.get('users')
filter_params = {}
if auth_user_query_params:
for parm in auth_user_query_params:
for key, value in parm.items():
if key in ['filter']:
filter_params[key] = value
user_list = []
user_list_details = (self.auth_api.list_auth_users(**filter_params)).to_dict()
user_list.extend(user_list_details['users'])
resume = user_list_details.get('resume')
while resume:
user_list_details = (self.auth_api.list_auth_users(resume=resume, **filter_params)).to_dict()
user_list.extend(user_list_details['users'])
resume = user_list_details['resume']
msg = f"Got user list from PowerScale cluster {self.module.params['onefs_host']}"
LOG.info(msg)
return user_list
except Exception as e:
error_msg = (
'Get Users List for PowerScale cluster: {0} and access zone: {1} '
'failed with error: {2}' .format(
self.module.params['onefs_host'], zone,
utils.determine_error(e)))
LOG.error(error_msg)
self.module.fail_json(msg=error_msg)
109 changes: 47 additions & 62 deletions plugins/modules/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,28 +54,38 @@
- Kritika Bhateja(@Kritika-Bhateja-03) <ansible.team.dell.com>
options:
include_all_access_zones:
description:
- Specifies if requested component details need to be fetched from all
access zones.
- It is mutually exclusive with I(access_zone).
type: bool
access_zone:
description:
- The access zone. If no Access Zone is specified, the 'System' access
zone would be taken by default.
default: 'System'
type: str
scope:
filters:
description:
- The scope of ldap. If no scope is specified, the C(effective) scope
would be taken by default.
- If specified as C(effective) or not specified, all fields are returned.
- If specified as C(user), only fields with non-default values are shown.
- If specified as C(default), the original values are returned.
choices: ['effective', 'user', 'default']
default: 'effective'
type: str
- List of filters to support filtered output for storage entities.
- Each filter is a tuple of {filter_key, filter_operator, filter_value}.
- Supports passing of multiple filters.
required: False
type: list
elements: dict
suboptions:
filter_key:
description:
- Name identifier of the filter.
type: str
required: True
filter_operator:
description:
- Operation to be performed on filter key.
type: str
choices: [equal]
required: True
filter_value:
description:
- Value of the filter key.
type: raw
required: True
version_added: '3.2.0'
gather_subset:
description:
- List of string variables to specify the PowerScale Storage System
Expand Down Expand Up @@ -155,32 +165,22 @@
alert_rules, alert_channels, alert_categories, event_group, writable_snapshots]
type: list
elements: str
filters:
include_all_access_zones:
description:
- List of filters to support filtered output for storage entities.
- Each filter is a tuple of {filter_key, filter_operator, filter_value}.
- Supports passing of multiple filters.
required: False
type: list
elements: dict
suboptions:
filter_key:
description:
- Name identifier of the filter.
type: str
required: True
filter_operator:
description:
- Operation to be performed on filter key.
type: str
choices: [equal]
required: True
filter_value:
description:
- Value of the filter key.
type: raw
required: True
version_added: '3.2.0'
- Specifies if requested component details need to be fetched from all
access zones.
- It is mutually exclusive with I(access_zone).
type: bool
scope:
description:
- The scope of ldap. If no scope is specified, the C(effective) scope
would be taken by default.
- If specified as C(effective) or not specified, all fields are returned.
- If specified as C(user), only fields with non-default values are shown.
- If specified as C(default), the original values are returned.
choices: ['effective', 'user', 'default']
default: 'effective'
type: str
query_parameters:
description:
- Contains dictionary of query parameters for specific I(gather_subset).
Expand Down Expand Up @@ -252,6 +252,9 @@
access_zone: "{{access_zone}}"
gather_subset:
- users
query_parameters:
users:
- filter: 'sample_user'
- name: Get list of groups for an access zone of the PowerScale cluster
dellemc.powerscale.info:
Expand Down Expand Up @@ -3341,25 +3344,6 @@ def get_providers_list(self, access_zone):
LOG.error(error_msg)
self.module.fail_json(msg=error_msg)

def get_users_list(self, access_zone):
"""Get the list of users for an access zone of a given PowerScale
Storage"""
try:
users_list = (self.auth_api.list_auth_users(zone=access_zone))\
.to_dict()
LOG.info('Got Users from PowerScale cluster %s',
self.module.params['onefs_host'])
return users_list
except Exception as e:
error_msg = (
'Get Users List for PowerScale cluster: {0} and access zone: {1} '
'failed with error: {2}' .format(
self.module.params['onefs_host'],
access_zone,
utils.determine_error(e)))
LOG.error(error_msg)
self.module.fail_json(msg=error_msg)

def get_groups_list(self, access_zone):
"""Get the list of groups for an access zone of a given PowerScale
Storage"""
Expand Down Expand Up @@ -3995,7 +3979,7 @@ def perform_module_operation(self):
'access_zones': self.get_access_zones_list,
'nodes': self.get_nodes_list,
'providers': lambda: self.get_providers_list(access_zone),
'users': lambda: self.get_users_list(access_zone),
'users': lambda: Auth(self.auth_api, self.module).get_auth_users(access_zone),
'groups': lambda: self.get_groups_list(access_zone),
'smb_shares': lambda: self.get_smb_shares_list(access_zone),
'clients': self.get_clients_list,
Expand Down Expand Up @@ -4085,15 +4069,16 @@ def perform_module_operation(self):
}

# Map the subset to the appropriate Key
subset_list = ['attributes', 'access_zones', 'nodes', 'providers', 'users', 'groups', 'smb_shares', 'clients',
subset_list = ['attributes', 'access_zones', 'nodes', 'providers', 'groups', 'smb_shares', 'clients',
'nfs_exports', 'nfs_aliases', 'synciq_reports', 'synciq_target_reports', 'synciq_policies',
'synciq_target_cluster_certificates', 'synciq_performance_rules', 'network_groupnets',
'network_pools', 'network_rules', 'network_interfaces', 'network_subnets', 'node_pools',
'storagepool_tiers', 'smb_files', 'user_mapping_rules', 'ldap', 'nfs_zone_settings',
'nfs_default_settings', 'nfs_global_settings', 'synciq_global_settings', 's3_buckets',
'smb_global_settings', 'ntp_servers', 'email_settings', 'cluster_identity', 'cluster_owner',
'snmp_settings', 'server_certificate', 'event_group', 'smartquota', 'filesystem',
'writable_snapshots']
'writable_snapshots', 'users']

for key in subset:
if key not in subset_list:
result[key] = subset_mapping[key]()
Expand Down
33 changes: 18 additions & 15 deletions tests/unit/plugins/module_utils/mock_info_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -989,16 +989,19 @@ def get_providers_response(response_type):
return resp

@staticmethod
def get_users_response(response_type):
resp = [{
"name": "testuser",
}, {
"name": "testuser1",
}]
if response_type == "error":
return "Get Users List for PowerScale cluster: **.***.**.*** and access zone: System failed with error: SDK Error message"
def get_auth_users(response_type):
if response_type in ["api", "module"]:
return {
"users": [
{
"id": "id1",
"id_name": "id_name1",
"name": "name1"
}
]
}
else:
return resp
return "Get Users List for PowerScale cluster: **.***.**.*** and access zone: System failed with error: SDK Error message"

@staticmethod
def get_groups_response(response_type):
Expand Down Expand Up @@ -1393,7 +1396,7 @@ def get_event_maintenance(response_type):
"start": 1719831994
}
],
"maintenance": "true"
"maintenance": "True"
}
else:
return "Fetching maintenance events failed with error: SDK Error message"
Expand Down Expand Up @@ -1422,7 +1425,7 @@ def get_event_channels(response_type):
"channels": [
{
"allowed_nodes": [],
"enabled": "true",
"enabled": "True",
"excluded_nodes": [],
"id": 2,
"name": MockGatherfactsApi.NAME,
Expand All @@ -1441,7 +1444,7 @@ def get_event_channels(response_type):
"subject": ""
},
"rules": ["Heatrbeat"],
"system": "true",
"system": "True",
"type": "heartbreak"
}
],
Expand Down Expand Up @@ -1691,7 +1694,7 @@ def get_gather_facts_module_response(gather_subset):
"network_pools": MockGatherfactsApi.get_network_pools_response(param),
"network_groupnets": MockGatherfactsApi.get_network_groupnets_response(param),
"providers": MockGatherfactsApi.get_providers_response(param),
"users": MockGatherfactsApi.get_users_response(param),
"users": MockGatherfactsApi.get_auth_users(param),
"groups": MockGatherfactsApi.get_groups_response(param),
"smb_shares": MockGatherfactsApi.get_smb_shares_response(param),
"nfs_exports": MockGatherfactsApi.get_nfs_exports_response(param),
Expand Down Expand Up @@ -1738,7 +1741,7 @@ def get_gather_facts_api_response(gather_subset):
"network_pools": MockGatherfactsApi.get_network_pools_response(param),
"network_groupnets": MockGatherfactsApi.get_network_groupnets_response(param),
"providers": MockGatherfactsApi.get_providers_response(param),
"users": MockGatherfactsApi.get_users_response(param),
"users": MockGatherfactsApi.get_auth_users(param),
"groups": MockGatherfactsApi.get_groups_response(param),
"smb_shares": MockGatherfactsApi.get_smb_shares_response(param),
"nfs_exports": MockGatherfactsApi.get_nfs_exports_response(param),
Expand Down Expand Up @@ -1786,7 +1789,7 @@ def get_gather_facts_error_response(gather_subset):
"network_pools": MockGatherfactsApi.get_network_pools_response(param),
"network_groupnets": MockGatherfactsApi.get_network_groupnets_response(param),
"providers": MockGatherfactsApi.get_providers_response(param),
"users": MockGatherfactsApi.get_users_response(param),
"users": MockGatherfactsApi.get_auth_users(param),
"groups": MockGatherfactsApi.get_groups_response(param),
"smb_shares": MockGatherfactsApi.get_smb_shares_response(param),
"nfs_exports": MockGatherfactsApi.get_nfs_exports_response(param),
Expand Down
23 changes: 21 additions & 2 deletions tests/unit/plugins/modules/test_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,6 @@ def test_get_facts_storagepool_api_exception(self, gatherfacts_module_mock, gath
{"gather_subset": "ldap", "return_key": "LdapProviders"},
{"gather_subset": "user_mapping_rules", "return_key": "UserMappingRules"},
{"gather_subset": "providers", "return_key": "Providers"},
{"gather_subset": "users", "return_key": "Users"},
{"gather_subset": "groups", "return_key": "Groups"},
{"gather_subset": "roles", "return_key": "roles"},
]
Expand Down Expand Up @@ -474,7 +473,6 @@ def test_get_facts_supportassist_exception(self, gatherfacts_module_mock, gather
gatherfacts_module_mock.major = 8
gatherfacts_module_mock.minor = 4
resp = gatherfacts_module_mock.get_support_assist_settings()
print(f"response is: {resp}")
assert "support_assist_settings is supported for One FS version 9.5.0 and above" in gatherfacts_module_mock.module.fail_json.call_args[1]['msg']

@pytest.mark.parametrize("input_params", [
Expand Down Expand Up @@ -780,3 +778,24 @@ def test_get_filters_failure_case2(self, gatherfacts_module_mock):
gatherfacts_module_mock.get_filters(filters=filter_dict)
assert gatherfacts_module_mock.module.fail_json.call_args[1]['msg'] \
== "The filter operator is not supported -- only 'equal' is supported."

@pytest.mark.parametrize("input_params", [
{"gather_subset": "users", "return_key": "Users"}
]
)
def test_get_facts_auth_user_module(self, gatherfacts_module_mock, input_params):
"""Test the get_facts that uses the auth api endpoint to get the module response"""

gather_subset = input_params.get('gather_subset')
return_key = input_params.get('return_key')
api_response = MockGatherfactsApi.get_gather_facts_api_response(
gather_subset)
self.get_module_args.update({
'gather_subset': [gather_subset]
})
gatherfacts_module_mock.module.params = self.get_module_args
with patch.object(gatherfacts_module_mock.auth_api, MockGatherfactsApi.get_gather_facts_error_method(gather_subset)) as mock_method:
mock_method.return_value = MockSDKResponse(api_response)
gatherfacts_module_mock.perform_module_operation()
assert MockGatherfactsApi.get_gather_facts_module_response(
gather_subset)['users'] == gatherfacts_module_mock.module.exit_json.call_args[1][return_key]

0 comments on commit ed16092

Please sign in to comment.