#!/usr/bin/python # Copyright (c) 2016 IBM # # This module is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This software is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this software. If not, see . try: import shade HAS_SHADE = True except ImportError: HAS_SHADE = False from distutils.version import StrictVersion DOCUMENTATION = ''' --- module: os_user_role short_description: Associate OpenStack Identity users and roles extends_documentation_fragment: openstack author: "Monty Taylor (@emonty), David Shrewsbury (@Shrews)" version_added: "2.1" description: - Grant and revoke roles in either project or domain context for OpenStack Identity Users. options: role: description: - Name or ID for the role. required: true user: description: - Name or ID for the user. If I(user) is not specified, then I(group) is required. Both may not be specified. required: false default: null 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. required: false default: null project: description: - Name or ID of the project to scope the role assocation to. If you are using keystone version 2, then this value is required. required: false default: null domain: description: - ID of the domain to scope the role association to. Valid only with keystone version 3, and required if I(project) is not specified. required: false default: null state: description: - Should the roles be present or absent on the user. choices: [present, absent] default: present requirements: - "python >= 2.6" - "shade" ''' EXAMPLES = ''' # Grant an admin role on the user admin in the project project1 - os_user_role: cloud: mycloud user: admin role: admin project: project1 # Revoke the admin role from the user barney in the newyork domain - os_user_role: cloud: mycloud state: absent user: barney role: admin domain: newyork ''' RETURN = ''' # ''' def _system_state_change(state, assignment): if state == 'present' and not assignment: return True elif state == 'absent' and assignment: return True return False def _build_kwargs(user, group, project, domain): kwargs = {} if user: kwargs['user'] = user if group: kwargs['group'] = group if project: kwargs['project'] = project if domain: kwargs['domain'] = domain return kwargs def main(): argument_spec = openstack_full_argument_spec( role=dict(required=True), user=dict(required=False), group=dict(required=False), project=dict(required=False), domain=dict(required=False), state=dict(default='present', choices=['absent', 'present']), ) module_kwargs = openstack_module_kwargs( required_one_of=[ ['user', 'group'] ]) module = AnsibleModule(argument_spec, supports_check_mode=True, **module_kwargs) # role grant/revoke API introduced in 1.5.0 if not HAS_SHADE or (StrictVersion(shade.__version__) < StrictVersion('1.5.0')): module.fail_json(msg='shade 1.5.0 or higher is required for this module') role = module.params.pop('role') user = module.params.pop('user') group = module.params.pop('group') project = module.params.pop('project') domain = module.params.pop('domain') state = module.params.pop('state') try: cloud = shade.operator_cloud(**module.params) filters = {} r = cloud.get_role(role) if r is None: module.fail_json(msg="Role %s is not valid" % role) filters['role'] = r['id'] if user: u = cloud.get_user(user) if u is None: module.fail_json(msg="User %s is not valid" % user) filters['user'] = u['id'] if group: g = cloud.get_group(group) if g is None: module.fail_json(msg="Group %s is not valid" % group) filters['group'] = g['id'] if domain: d = cloud.get_domain(domain) if d is None: module.fail_json(msg="Domain %s is not valid" % domain) filters['domain'] = d['id'] if project: if domain: p = cloud.get_project(project, domain_id=filters['domain']) else: p = cloud.get_project(project) if p is None: module.fail_json(msg="Project %s is not valid" % project) filters['project'] = p['id'] assignment = cloud.list_role_assignments(filters=filters) if module.check_mode: module.exit_json(changed=_system_state_change(state, assignment)) changed = False if state == 'present': if not assignment: kwargs = _build_kwargs(user, group, project, domain) cloud.grant_role(role, **kwargs) changed = True elif state == 'absent': if assignment: kwargs = _build_kwargs(user, group, project, domain) cloud.revoke_role(role, **kwargs) changed=True module.exit_json(changed=changed) except shade.OpenStackCloudException as e: module.fail_json(msg=str(e)) from ansible.module_utils.basic import * from ansible.module_utils.openstack import * if __name__ == '__main__': main()