Jakob Meng d5ab2bf33f Refactored {group,role}_assignment modules
Change-Id: I6ec79eb203d0f68661b54bc89a194c366b3574c6
2023-01-26 13:36:30 +01:00

195 lines
6.7 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2016 IBM
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
DOCUMENTATION = r'''
---
module: role_assignment
short_description: Assign OpenStack identity groups and users to roles
author: OpenStack Ansible SIG
description:
- Grant and revoke roles in either project or domain context for
OpenStack identity (Keystone) users and groups.
options:
domain:
description:
- Name or ID of the domain to scope the role association to.
- Valid only with keystone version 3.
- Required if I(project) is not specified.
- When I(project) is specified, then I(domain) will not be used for
scoping the role association, only for finding resources.
- "When scoping the role association, I(project) has precedence over
I(domain) and I(domain) has precedence over I(system): When I(project)
is specified, then I(domain) and I(system) are not used for role
association. When I(domain) is specified, then I(system) will not be
used for role association."
type: str
group:
description:
- Name or ID for the group.
- Valid only with keystone version 3.
- If I(group) is not specified, then I(user) is required. Both may not be
specified at the same time.
type: str
project:
description:
- Name or ID of the project to scope the role association to.
- If you are using keystone version 2, then this value is required.
- When I(project) is specified, then I(domain) will not be used for
scoping the role association, only for finding resources.
- "When scoping the role association, I(project) has precedence over
I(domain) and I(domain) has precedence over I(system): When I(project)
is specified, then I(domain) and I(system) are not used for role
association. When I(domain) is specified, then I(system) will not be
used for role association."
type: str
role:
description:
- Name or ID for the role.
required: true
type: str
state:
description:
- Should the roles be present or absent on the user.
choices: [present, absent]
default: present
type: str
system:
description:
- Name of system to scope the role association to.
- Valid only with keystone version 3.
- Required if I(project) and I(domain) are not specified.
- "When scoping the role association, I(project) has precedence over
I(domain) and I(domain) has precedence over I(system): When I(project)
is specified, then I(domain) and I(system) are not used for role
association. When I(domain) is specified, then I(system) will not be
used for role association."
type: str
user:
description:
- Name or ID for the user.
- If I(user) is not specified, then I(group) is required. Both may not be
specified at the same time.
type: str
extends_documentation_fragment:
- openstack.cloud.openstack
'''
EXAMPLES = r'''
- name: Grant an admin role on the user admin in the project project1
openstack.cloud.role_assignment:
cloud: mycloud
user: admin
role: admin
project: project1
- name: Revoke the admin role from the user barney in the newyork domain
openstack.cloud.role_assignment:
cloud: mycloud
state: absent
user: barney
role: admin
domain: newyork
'''
from ansible_collections.openstack.cloud.plugins.module_utils.openstack import OpenStackModule
class IdentityRoleAssignmentModule(OpenStackModule):
argument_spec = dict(
domain=dict(),
group=dict(),
project=dict(),
role=dict(required=True),
state=dict(default='present', choices=['absent', 'present']),
system=dict(),
user=dict(),
)
module_kwargs = dict(
required_one_of=[
('user', 'group'),
('domain', 'project', 'system'),
],
supports_check_mode=True
)
def run(self):
filters = {}
find_filters = {}
kwargs = {}
role_name_or_id = self.params['role']
role = self.conn.identity.find_role(role_name_or_id,
ignore_missing=False)
filters['role_id'] = role['id']
domain_name_or_id = self.params['domain']
if domain_name_or_id is not None:
domain = self.conn.identity.find_domain(
domain_name_or_id, ignore_missing=False)
filters['scope_domain_id'] = domain['id']
find_filters['domain_id'] = domain['id']
kwargs['domain'] = domain['id']
user_name_or_id = self.params['user']
if user_name_or_id is not None:
user = self.conn.identity.find_user(
user_name_or_id, ignore_missing=False, **find_filters)
filters['user_id'] = user['id']
kwargs['user'] = user['id']
group_name_or_id = self.params['group']
if group_name_or_id is not None:
group = self.conn.identity.find_group(
group_name_or_id, ignore_missing=False, **find_filters)
filters['group_id'] = group['id']
kwargs['group'] = group['id']
system_name = self.params['system']
if system_name is not None:
# domain has precedence over system
if 'scope_domain_id' not in filters:
filters['scope.system'] = system_name
kwargs['system'] = system_name
project_name_or_id = self.params['project']
if project_name_or_id is not None:
project = self.conn.identity.find_project(
project_name_or_id, ignore_missing=False, **find_filters)
filters['scope_project_id'] = project['id']
kwargs['project'] = project['id']
# project has precedence over domain and system
filters.pop('scope_domain_id', None)
filters.pop('scope.system', None)
role_assignments = list(self.conn.identity.role_assignments(**filters))
state = self.params['state']
if self.ansible.check_mode:
self.exit_json(
changed=((state == 'present' and not role_assignments)
or (state == 'absent' and role_assignments)))
if state == 'present' and not role_assignments:
self.conn.grant_role(role['id'], **kwargs)
self.exit_json(changed=True)
elif state == 'absent' and role_assignments:
self.conn.revoke_role(role['id'], **kwargs)
self.exit_json(changed=True)
else:
self.exit_json(changed=False)
def main():
module = IdentityRoleAssignmentModule()
module()
if __name__ == '__main__':
main()