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
|
state: absent
|
||||||
user: admin
|
user: admin
|
||||||
|
|
||||||
- name: Delete project
|
|
||||||
openstack.cloud.project:
|
|
||||||
cloud: "{{ cloud }}"
|
|
||||||
state: absent
|
|
||||||
name: ansible_project
|
|
||||||
|
|
||||||
- name: Create domain
|
- name: Create domain
|
||||||
openstack.cloud.identity_domain:
|
openstack.cloud.identity_domain:
|
||||||
cloud: "{{ cloud }}"
|
cloud: "{{ cloud }}"
|
||||||
@@ -78,6 +72,7 @@
|
|||||||
state: present
|
state: present
|
||||||
name: ansible_user
|
name: ansible_user
|
||||||
domain: default
|
domain: default
|
||||||
|
register: specific_user
|
||||||
|
|
||||||
- name: Create user in specific domain
|
- name: Create user in specific domain
|
||||||
openstack.cloud.identity_user:
|
openstack.cloud.identity_user:
|
||||||
@@ -138,6 +133,45 @@
|
|||||||
that:
|
that:
|
||||||
- role_assignment is changed
|
- 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
|
- name: Delete group in default domain
|
||||||
openstack.cloud.identity_group:
|
openstack.cloud.identity_group:
|
||||||
cloud: "{{ cloud }}"
|
cloud: "{{ cloud }}"
|
||||||
@@ -171,3 +205,10 @@
|
|||||||
cloud: "{{ cloud }}"
|
cloud: "{{ cloud }}"
|
||||||
state: absent
|
state: absent
|
||||||
name: ansible_domain
|
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.
|
- Valid only with keystone version 3.
|
||||||
- Required if I(project) is not specified.
|
- Required if I(project) is not specified.
|
||||||
- When I(project) is specified, then I(domain) will not be used for
|
- 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
|
- "When scoping the role association, I(project) has precedence over
|
||||||
I(domain) and I(domain) has precedence over I(system): When I(project)
|
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
|
is specified, then I(domain) and I(system) are not used for role
|
||||||
@@ -32,24 +34,45 @@ options:
|
|||||||
- Valid only with keystone version 3.
|
- Valid only with keystone version 3.
|
||||||
- If I(group) is not specified, then I(user) is required. Both may not be
|
- If I(group) is not specified, then I(user) is required. Both may not be
|
||||||
specified at the same time.
|
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
|
type: str
|
||||||
project:
|
project:
|
||||||
description:
|
description:
|
||||||
- Name or ID of the project to scope the role association to.
|
- Name or ID of the project to scope the role association to.
|
||||||
- If you are using keystone version 2, then this value is required.
|
- 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
|
- 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
|
- "When scoping the role association, I(project) has precedence over
|
||||||
I(domain) and I(domain) has precedence over I(system): When I(project)
|
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
|
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
|
association. When I(domain) is specified, then I(system) will not be
|
||||||
used for role association."
|
used for role association."
|
||||||
type: str
|
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:
|
role:
|
||||||
description:
|
description:
|
||||||
- Name or ID for the role.
|
- Name or ID for the role.
|
||||||
required: true
|
required: true
|
||||||
type: str
|
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:
|
state:
|
||||||
description:
|
description:
|
||||||
- Should the roles be present or absent on the user.
|
- 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
|
- If I(user) is not specified, then I(group) is required. Both may not be
|
||||||
specified at the same time.
|
specified at the same time.
|
||||||
type: str
|
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:
|
extends_documentation_fragment:
|
||||||
- openstack.cloud.openstack
|
- openstack.cloud.openstack
|
||||||
'''
|
'''
|
||||||
@@ -101,11 +130,15 @@ class IdentityRoleAssignmentModule(OpenStackModule):
|
|||||||
argument_spec = dict(
|
argument_spec = dict(
|
||||||
domain=dict(),
|
domain=dict(),
|
||||||
group=dict(),
|
group=dict(),
|
||||||
|
group_domain=dict(type='str'),
|
||||||
project=dict(),
|
project=dict(),
|
||||||
|
project_domain=dict(type='str'),
|
||||||
role=dict(required=True),
|
role=dict(required=True),
|
||||||
|
role_domain=dict(type='str'),
|
||||||
state=dict(default='present', choices=['absent', 'present']),
|
state=dict(default='present', choices=['absent', 'present']),
|
||||||
system=dict(),
|
system=dict(),
|
||||||
user=dict(),
|
user=dict(),
|
||||||
|
user_domain=dict(type='str'),
|
||||||
)
|
)
|
||||||
|
|
||||||
module_kwargs = dict(
|
module_kwargs = dict(
|
||||||
@@ -113,17 +146,33 @@ class IdentityRoleAssignmentModule(OpenStackModule):
|
|||||||
('user', 'group'),
|
('user', 'group'),
|
||||||
('domain', 'project', 'system'),
|
('domain', 'project', 'system'),
|
||||||
],
|
],
|
||||||
|
mutually_exclusive=[
|
||||||
|
('user', 'group'),
|
||||||
|
('project', 'system'), # domain should be part of this
|
||||||
|
],
|
||||||
supports_check_mode=True
|
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):
|
def run(self):
|
||||||
filters = {}
|
filters = {}
|
||||||
find_filters = {}
|
group_find_filters = {}
|
||||||
kwargs = {}
|
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_name_or_id = self.params['role']
|
||||||
role = self.conn.identity.find_role(role_name_or_id,
|
role = self.conn.identity.find_role(role_name_or_id,
|
||||||
ignore_missing=False)
|
ignore_missing=False,
|
||||||
|
**role_find_filters)
|
||||||
filters['role_id'] = role['id']
|
filters['role_id'] = role['id']
|
||||||
|
|
||||||
domain_name_or_id = self.params['domain']
|
domain_name_or_id = self.params['domain']
|
||||||
@@ -131,22 +180,31 @@ class IdentityRoleAssignmentModule(OpenStackModule):
|
|||||||
domain = self.conn.identity.find_domain(
|
domain = self.conn.identity.find_domain(
|
||||||
domain_name_or_id, ignore_missing=False)
|
domain_name_or_id, ignore_missing=False)
|
||||||
filters['scope_domain_id'] = domain['id']
|
filters['scope_domain_id'] = domain['id']
|
||||||
find_filters['domain_id'] = domain['id']
|
group_find_filters['domain_id'] = domain['id']
|
||||||
kwargs['domain'] = domain['id']
|
project_find_filters['domain_id'] = domain['id']
|
||||||
|
user_find_filters['domain_id'] = domain['id']
|
||||||
|
|
||||||
user_name_or_id = self.params['user']
|
user_name_or_id = self.params['user']
|
||||||
if user_name_or_id is not None:
|
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 = 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']
|
filters['user_id'] = user['id']
|
||||||
kwargs['user'] = user['id']
|
else:
|
||||||
|
user = None
|
||||||
|
|
||||||
group_name_or_id = self.params['group']
|
group_name_or_id = self.params['group']
|
||||||
if group_name_or_id is not None:
|
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 = 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']
|
filters['group_id'] = group['id']
|
||||||
kwargs['group'] = group['id']
|
else:
|
||||||
|
group = None
|
||||||
|
|
||||||
system_name = self.params['system']
|
system_name = self.params['system']
|
||||||
if system_name is not None:
|
if system_name is not None:
|
||||||
@@ -154,14 +212,14 @@ class IdentityRoleAssignmentModule(OpenStackModule):
|
|||||||
if 'scope_domain_id' not in filters:
|
if 'scope_domain_id' not in filters:
|
||||||
filters['scope.system'] = system_name
|
filters['scope.system'] = system_name
|
||||||
|
|
||||||
kwargs['system'] = system_name
|
|
||||||
|
|
||||||
project_name_or_id = self.params['project']
|
project_name_or_id = self.params['project']
|
||||||
if project_name_or_id is not None:
|
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 = 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']
|
filters['scope_project_id'] = project['id']
|
||||||
kwargs['project'] = project['id']
|
|
||||||
|
|
||||||
# project has precedence over domain and system
|
# project has precedence over domain and system
|
||||||
filters.pop('scope_domain_id', None)
|
filters.pop('scope_domain_id', None)
|
||||||
@@ -176,10 +234,50 @@ class IdentityRoleAssignmentModule(OpenStackModule):
|
|||||||
or (state == 'absent' and role_assignments)))
|
or (state == 'absent' and role_assignments)))
|
||||||
|
|
||||||
if state == 'present' and not 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)
|
self.exit_json(changed=True)
|
||||||
elif state == 'absent' and role_assignments:
|
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)
|
self.exit_json(changed=True)
|
||||||
else:
|
else:
|
||||||
self.exit_json(changed=False)
|
self.exit_json(changed=False)
|
||||||
|
|||||||
Reference in New Issue
Block a user