mirror of
https://opendev.org/openstack/ansible-collections-openstack.git
synced 2026-03-26 21:43:02 +00:00
Merge "Allow role_assignment module to work cross domain"
This commit is contained in:
@@ -45,12 +45,6 @@
|
||||
state: absent
|
||||
user: admin
|
||||
|
||||
- name: Delete project
|
||||
openstack.cloud.project:
|
||||
cloud: "{{ cloud }}"
|
||||
state: absent
|
||||
name: ansible_project
|
||||
|
||||
- name: Create domain
|
||||
openstack.cloud.identity_domain:
|
||||
cloud: "{{ cloud }}"
|
||||
@@ -78,6 +72,7 @@
|
||||
state: present
|
||||
name: ansible_user
|
||||
domain: default
|
||||
register: specific_user
|
||||
|
||||
- name: Create user in specific domain
|
||||
openstack.cloud.identity_user:
|
||||
@@ -138,6 +133,45 @@
|
||||
that:
|
||||
- role_assignment is changed
|
||||
|
||||
- name: Assign role to user in specific domain on default domain project
|
||||
openstack.cloud.role_assignment:
|
||||
cloud: "{{ cloud }}"
|
||||
role: anotherrole
|
||||
user: "{{ specific_user.user.id }}"
|
||||
domain: default
|
||||
project: ansible_project
|
||||
register: role_assignment
|
||||
|
||||
- name: Assert role assignment
|
||||
assert:
|
||||
that:
|
||||
- role_assignment is changed
|
||||
|
||||
- name: Revoke role to user in specific domain
|
||||
openstack.cloud.role_assignment:
|
||||
cloud: "{{ cloud }}"
|
||||
role: anotherrole
|
||||
user: "{{ specific_user.user.id }}"
|
||||
domain: default
|
||||
project: ansible_project
|
||||
state: absent
|
||||
register: role_assignment
|
||||
|
||||
- name: Assert role assignment revoked
|
||||
assert:
|
||||
that:
|
||||
- role_assignment is changed
|
||||
|
||||
- name: Assign role to user in specific domain on default domain project
|
||||
openstack.cloud.role_assignment:
|
||||
cloud: "{{ cloud }}"
|
||||
role: anotherrole
|
||||
user: ansible_user
|
||||
user_domain: "{{ specific_user.user.domain_id }}"
|
||||
project: ansible_project
|
||||
project_domain: default
|
||||
register: role_assignment
|
||||
|
||||
- name: Delete group in default domain
|
||||
openstack.cloud.identity_group:
|
||||
cloud: "{{ cloud }}"
|
||||
@@ -171,3 +205,10 @@
|
||||
cloud: "{{ cloud }}"
|
||||
state: absent
|
||||
name: ansible_domain
|
||||
|
||||
- name: Delete project
|
||||
openstack.cloud.project:
|
||||
cloud: "{{ cloud }}"
|
||||
state: absent
|
||||
name: ansible_project
|
||||
|
||||
|
||||
@@ -19,7 +19,9 @@ options:
|
||||
- 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.
|
||||
scoping the role association, only for finding resources. Deprecated
|
||||
for finding resources, please use I(group_domain), I(project_domain),
|
||||
I(role_domain), or I(user_domain).
|
||||
- "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
|
||||
@@ -32,24 +34,45 @@ options:
|
||||
- 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.
|
||||
- You can supply I(group_domain) or the deprecated usage of I(domain) to
|
||||
find group resources.
|
||||
type: str
|
||||
group_domain:
|
||||
description:
|
||||
- Name or ID for the domain.
|
||||
- Valid only with keystone version 3.
|
||||
- Only valid for finding group resources.
|
||||
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.
|
||||
scoping the role association, only for finding resources. Prefer
|
||||
I(group_domain) over I(domain).
|
||||
- "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
|
||||
project_domain:
|
||||
description:
|
||||
- Name or ID for the domain.
|
||||
- Valid only with keystone version 3.
|
||||
- Only valid for finding project resources.
|
||||
type: str
|
||||
role:
|
||||
description:
|
||||
- Name or ID for the role.
|
||||
required: true
|
||||
type: str
|
||||
role_domain:
|
||||
description:
|
||||
- Name or ID for the domain.
|
||||
- Valid only with keystone version 3.
|
||||
- Only valid for finding role resources.
|
||||
type: str
|
||||
state:
|
||||
description:
|
||||
- Should the roles be present or absent on the user.
|
||||
@@ -73,6 +96,12 @@ options:
|
||||
- If I(user) is not specified, then I(group) is required. Both may not be
|
||||
specified at the same time.
|
||||
type: str
|
||||
user_domain:
|
||||
description:
|
||||
- Name or ID for the domain.
|
||||
- Valid only with keystone version 3.
|
||||
- Only valid for finding user resources.
|
||||
type: str
|
||||
extends_documentation_fragment:
|
||||
- openstack.cloud.openstack
|
||||
'''
|
||||
@@ -101,11 +130,15 @@ class IdentityRoleAssignmentModule(OpenStackModule):
|
||||
argument_spec = dict(
|
||||
domain=dict(),
|
||||
group=dict(),
|
||||
group_domain=dict(type='str'),
|
||||
project=dict(),
|
||||
project_domain=dict(type='str'),
|
||||
role=dict(required=True),
|
||||
role_domain=dict(type='str'),
|
||||
state=dict(default='present', choices=['absent', 'present']),
|
||||
system=dict(),
|
||||
user=dict(),
|
||||
user_domain=dict(type='str'),
|
||||
)
|
||||
|
||||
module_kwargs = dict(
|
||||
@@ -113,17 +146,33 @@ class IdentityRoleAssignmentModule(OpenStackModule):
|
||||
('user', 'group'),
|
||||
('domain', 'project', 'system'),
|
||||
],
|
||||
mutually_exclusive=[
|
||||
('user', 'group'),
|
||||
('project', 'system'), # domain should be part of this
|
||||
],
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
def _find_domain_id(self, domain):
|
||||
if domain is not None:
|
||||
domain = self.conn.identity.find_domain(domain,
|
||||
ignore_missing=False)
|
||||
return dict(domain_id=domain['id'])
|
||||
return dict()
|
||||
|
||||
def run(self):
|
||||
filters = {}
|
||||
find_filters = {}
|
||||
kwargs = {}
|
||||
group_find_filters = {}
|
||||
project_find_filters = {}
|
||||
role_find_filters = {}
|
||||
user_find_filters = {}
|
||||
|
||||
role_find_filters.update(self._find_domain_id(
|
||||
self.params['role_domain']))
|
||||
role_name_or_id = self.params['role']
|
||||
role = self.conn.identity.find_role(role_name_or_id,
|
||||
ignore_missing=False)
|
||||
ignore_missing=False,
|
||||
**role_find_filters)
|
||||
filters['role_id'] = role['id']
|
||||
|
||||
domain_name_or_id = self.params['domain']
|
||||
@@ -131,22 +180,31 @@ class IdentityRoleAssignmentModule(OpenStackModule):
|
||||
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']
|
||||
group_find_filters['domain_id'] = domain['id']
|
||||
project_find_filters['domain_id'] = domain['id']
|
||||
user_find_filters['domain_id'] = domain['id']
|
||||
|
||||
user_name_or_id = self.params['user']
|
||||
if user_name_or_id is not None:
|
||||
user_find_filters.update(self._find_domain_id(
|
||||
self.params['user_domain']))
|
||||
user = self.conn.identity.find_user(
|
||||
user_name_or_id, ignore_missing=False, **find_filters)
|
||||
user_name_or_id, ignore_missing=False,
|
||||
**user_find_filters)
|
||||
filters['user_id'] = user['id']
|
||||
kwargs['user'] = user['id']
|
||||
else:
|
||||
user = None
|
||||
|
||||
group_name_or_id = self.params['group']
|
||||
if group_name_or_id is not None:
|
||||
group_find_filters.update(self._find_domain_id(
|
||||
self.params['group_domain']))
|
||||
group = self.conn.identity.find_group(
|
||||
group_name_or_id, ignore_missing=False, **find_filters)
|
||||
group_name_or_id, ignore_missing=False,
|
||||
**group_find_filters)
|
||||
filters['group_id'] = group['id']
|
||||
kwargs['group'] = group['id']
|
||||
else:
|
||||
group = None
|
||||
|
||||
system_name = self.params['system']
|
||||
if system_name is not None:
|
||||
@@ -154,14 +212,14 @@ class IdentityRoleAssignmentModule(OpenStackModule):
|
||||
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_find_filters.update(self._find_domain_id(
|
||||
self.params['project_domain']))
|
||||
project = self.conn.identity.find_project(
|
||||
project_name_or_id, ignore_missing=False, **find_filters)
|
||||
project_name_or_id, ignore_missing=False,
|
||||
**project_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)
|
||||
@@ -176,10 +234,50 @@ class IdentityRoleAssignmentModule(OpenStackModule):
|
||||
or (state == 'absent' and role_assignments)))
|
||||
|
||||
if state == 'present' and not role_assignments:
|
||||
self.conn.grant_role(role['id'], **kwargs)
|
||||
if 'scope_domain_id' in filters:
|
||||
if user is not None:
|
||||
self.conn.identity.assign_domain_role_to_user(
|
||||
filters['scope_domain_id'], user, role)
|
||||
else:
|
||||
self.conn.identity.assign_domain_role_to_group(
|
||||
filters['scope_domain_id'], group, role)
|
||||
elif 'scope_project_id' in filters:
|
||||
if user is not None:
|
||||
self.conn.identity.assign_project_role_to_user(
|
||||
filters['scope_project_id'], user, role)
|
||||
else:
|
||||
self.conn.identity.assign_project_role_to_group(
|
||||
filters['scope_project_id'], group, role)
|
||||
elif 'scope.system' in filters:
|
||||
if user is not None:
|
||||
self.conn.identity.assign_system_role_to_user(
|
||||
user, role, filters['scope.system'])
|
||||
else:
|
||||
self.conn.identity.assign_system_role_to_group(
|
||||
group, role, filters['scope.system'])
|
||||
self.exit_json(changed=True)
|
||||
elif state == 'absent' and role_assignments:
|
||||
self.conn.revoke_role(role['id'], **kwargs)
|
||||
if 'scope_domain_id' in filters:
|
||||
if user is not None:
|
||||
self.conn.identity.unassign_domain_role_from_user(
|
||||
filters['scope_domain_id'], user, role)
|
||||
else:
|
||||
self.conn.identity.unassign_domain_role_from_group(
|
||||
filters['scope_domain_id'], group, role)
|
||||
elif 'scope_project_id' in filters:
|
||||
if user is not None:
|
||||
self.conn.identity.unassign_project_role_from_user(
|
||||
filters['scope_project_id'], user, role)
|
||||
else:
|
||||
self.conn.identity.unassign_project_role_from_group(
|
||||
filters['scope_project_id'], group, role)
|
||||
elif 'scope.system' in filters:
|
||||
if user is not None:
|
||||
self.conn.identity.unassign_system_role_from_user(
|
||||
user, role, filters['scope.system'])
|
||||
else:
|
||||
self.conn.identity.unassign_system_role_from_group(
|
||||
group, role, filters['scope.system'])
|
||||
self.exit_json(changed=True)
|
||||
else:
|
||||
self.exit_json(changed=False)
|
||||
|
||||
Reference in New Issue
Block a user