mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-05-25 10:29:09 -07:00
The password param conflicts with os-client-config's password grabbing. The rest of the params really probably should also be popped - but keeping this just to password for now. Will follow up with a change that does an audit of all the os_ modules This patch was previously contributed by @emonty to the former ansible-modules-core repo however since the merge, it was closed and not completed. This patch includes the necessary changes cleaned up to work with the latest release of Ansible. This has been tested to work internally
278 lines
8.7 KiB
Python
278 lines
8.7 KiB
Python
#!/usr/bin/python
|
|
# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
|
|
#
|
|
# 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
try:
|
|
import shade
|
|
HAS_SHADE = True
|
|
except ImportError:
|
|
HAS_SHADE = False
|
|
|
|
ANSIBLE_METADATA = {'status': ['preview'],
|
|
'supported_by': 'community',
|
|
'version': '1.0'}
|
|
|
|
DOCUMENTATION = '''
|
|
---
|
|
module: os_user
|
|
short_description: Manage OpenStack Identity Users
|
|
extends_documentation_fragment: openstack
|
|
version_added: "2.0"
|
|
description:
|
|
- Manage OpenStack Identity users. Users can be created,
|
|
updated or deleted using this module. A user will be updated
|
|
if I(name) matches an existing user and I(state) is present.
|
|
The value for I(name) cannot be updated without deleting and
|
|
re-creating the user.
|
|
options:
|
|
name:
|
|
description:
|
|
- Username for the user
|
|
required: true
|
|
password:
|
|
description:
|
|
- Password for the user
|
|
required: false
|
|
default: None
|
|
update_password:
|
|
required: false
|
|
default: always
|
|
choices: ['always', 'on_create']
|
|
version_added: "2.3"
|
|
description:
|
|
- C(always) will attempt to update password. C(on_create) will only
|
|
set the password for newly created users.
|
|
email:
|
|
description:
|
|
- Email address for the user
|
|
required: false
|
|
default: None
|
|
default_project:
|
|
description:
|
|
- Project name or ID that the user should be associated with by default
|
|
required: false
|
|
default: None
|
|
domain:
|
|
description:
|
|
- Domain to create the user in if the cloud supports domains
|
|
required: false
|
|
default: None
|
|
enabled:
|
|
description:
|
|
- Is the user enabled
|
|
required: false
|
|
default: True
|
|
state:
|
|
description:
|
|
- Should the resource be present or absent.
|
|
choices: [present, absent]
|
|
default: present
|
|
requirements:
|
|
- "python >= 2.6"
|
|
- "shade"
|
|
'''
|
|
|
|
EXAMPLES = '''
|
|
# Create a user
|
|
- os_user:
|
|
cloud: mycloud
|
|
state: present
|
|
name: demouser
|
|
password: secret
|
|
email: demo@example.com
|
|
domain: default
|
|
default_project: demo
|
|
|
|
# Delete a user
|
|
- os_user:
|
|
cloud: mycloud
|
|
state: absent
|
|
name: demouser
|
|
|
|
# Create a user but don't update password if user exists
|
|
- os_user:
|
|
cloud: mycloud
|
|
state: present
|
|
name: demouser
|
|
password: secret
|
|
update_password: on_create
|
|
email: demo@example.com
|
|
domain: default
|
|
default_project: demo
|
|
'''
|
|
|
|
|
|
RETURN = '''
|
|
user:
|
|
description: Dictionary describing the user.
|
|
returned: On success when I(state) is 'present'
|
|
type: dictionary
|
|
contains:
|
|
default_project_id:
|
|
description: User default project ID. Only present with Keystone >= v3.
|
|
type: string
|
|
sample: "4427115787be45f08f0ec22a03bfc735"
|
|
domain_id:
|
|
description: User domain ID. Only present with Keystone >= v3.
|
|
type: string
|
|
sample: "default"
|
|
email:
|
|
description: User email address
|
|
type: string
|
|
sample: "demo@example.com"
|
|
id:
|
|
description: User ID
|
|
type: string
|
|
sample: "f59382db809c43139982ca4189404650"
|
|
name:
|
|
description: User name
|
|
type: string
|
|
sample: "demouser"
|
|
'''
|
|
|
|
def _needs_update(params_dict, user):
|
|
for k, v in params_dict.items():
|
|
if k not in ('password', 'update_password') and user[k] != v:
|
|
return True
|
|
|
|
# We don't get password back in the user object, so assume any supplied
|
|
# password is a change.
|
|
if (params_dict['password'] is not None and
|
|
params_dict['update_password'] == 'always'):
|
|
return True
|
|
|
|
return False
|
|
|
|
def _get_domain_id(cloud, domain):
|
|
try:
|
|
# We assume admin is passing domain id
|
|
domain_id = cloud.get_domain(domain)['id']
|
|
except:
|
|
# If we fail, maybe admin is passing a domain name.
|
|
# Note that domains have unique names, just like id.
|
|
try:
|
|
domain_id = cloud.search_domains(filters={'name': domain})[0]['id']
|
|
except:
|
|
# Ok, let's hope the user is non-admin and passing a sane id
|
|
domain_id = domain
|
|
|
|
return domain_id
|
|
|
|
def _get_default_project_id(cloud, default_project):
|
|
project = cloud.get_project(default_project)
|
|
if not project:
|
|
module.fail_json(msg='Default project %s is not valid' % default_project)
|
|
|
|
return project['id']
|
|
|
|
def main():
|
|
|
|
argument_spec = openstack_full_argument_spec(
|
|
name=dict(required=True),
|
|
password=dict(required=False, default=None),
|
|
email=dict(required=False, default=None),
|
|
default_project=dict(required=False, default=None),
|
|
domain=dict(required=False, default=None),
|
|
enabled=dict(default=True, type='bool'),
|
|
state=dict(default='present', choices=['absent', 'present']),
|
|
update_password=dict(default='always', choices=['always',
|
|
'on_create']),
|
|
)
|
|
|
|
module_kwargs = openstack_module_kwargs()
|
|
module = AnsibleModule(
|
|
argument_spec,
|
|
**module_kwargs)
|
|
|
|
if not HAS_SHADE:
|
|
module.fail_json(msg='shade is required for this module')
|
|
|
|
name = module.params['name']
|
|
password = module.params.pop('password')
|
|
email = module.params['email']
|
|
default_project = module.params['default_project']
|
|
domain = module.params['domain']
|
|
enabled = module.params['enabled']
|
|
state = module.params['state']
|
|
update_password = module.params['update_password']
|
|
|
|
try:
|
|
cloud = shade.openstack_cloud(**module.params)
|
|
user = cloud.get_user(name)
|
|
|
|
domain_id = None
|
|
if domain:
|
|
opcloud = shade.operator_cloud(**module.params)
|
|
domain_id = _get_domain_id(opcloud, domain)
|
|
|
|
if state == 'present':
|
|
if update_password in ('always', 'on_create'):
|
|
if not password:
|
|
msg = ("update_password is %s but a password value is "
|
|
"missing") % update_password
|
|
module.fail_json(msg=msg)
|
|
default_project_id = None
|
|
if default_project:
|
|
default_project_id = _get_default_project_id(cloud, default_project)
|
|
|
|
if user is None:
|
|
user = cloud.create_user(
|
|
name=name, password=password, email=email,
|
|
default_project=default_project_id, domain_id=domain_id,
|
|
enabled=enabled)
|
|
changed = True
|
|
else:
|
|
params_dict = {'email': email, 'enabled': enabled,
|
|
'password': password,
|
|
'update_password': update_password}
|
|
if domain_id is not None:
|
|
params_dict['domain_id'] = domain_id
|
|
if default_project_id is not None:
|
|
params_dict['default_project_id'] = default_project_id
|
|
|
|
if _needs_update(params_dict, user):
|
|
if update_password == 'always':
|
|
user = cloud.update_user(
|
|
user['id'], password=password, email=email,
|
|
default_project=default_project_id,
|
|
domain_id=domain_id, enabled=enabled)
|
|
else:
|
|
user = cloud.update_user(
|
|
user['id'], email=email,
|
|
default_project=default_project_id,
|
|
domain_id=domain_id, enabled=enabled)
|
|
changed = True
|
|
else:
|
|
changed = False
|
|
module.exit_json(changed=changed, user=user)
|
|
|
|
elif state == 'absent':
|
|
if user is None:
|
|
changed=False
|
|
else:
|
|
cloud.delete_user(user['id'])
|
|
changed=True
|
|
module.exit_json(changed=changed)
|
|
|
|
except shade.OpenStackCloudException as e:
|
|
module.fail_json(msg=str(e), extra_data=e.extra_data)
|
|
|
|
from ansible.module_utils.basic import *
|
|
from ansible.module_utils.openstack import *
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|