-
Notifications
You must be signed in to change notification settings - Fork 23.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add doc_fragment and module util for ManageIQ platform
This change also adds the manageiq_user module, responsible for user management in ManageIQ.
- Loading branch information
Showing
4 changed files
with
362 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
#!/usr/bin/python | ||
# | ||
# (c) 2017, Daniel Korn <korndaniel1@gmail.com> | ||
# | ||
# This file is part of Ansible | ||
# | ||
# Ansible 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. | ||
# | ||
# Ansible 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 Ansible. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
|
||
import os | ||
from manageiq_client.api import ManageIQClient | ||
|
||
|
||
def manageiq_argument_spec(): | ||
return dict( | ||
miq_url=dict(default=os.environ.get('MIQ_URL', None)), | ||
miq_username=dict(default=os.environ.get('MIQ_USERNAME', None)), | ||
miq_password=dict(default=os.environ.get('MIQ_PASSWORD', None), no_log=True), | ||
miq_verify_ssl=dict(require=False, type='bool', default=True), | ||
ca_bundle_path=dict(required=False, type='str', defualt=None) | ||
) | ||
|
||
|
||
class ManageIQ(object): | ||
""" | ||
class encapsulating ManageIQ API client | ||
""" | ||
|
||
def __init__(self, module): | ||
""" | ||
module - an AnsibleModule instance | ||
url - manageiq environment url | ||
user - the username in manageiq | ||
password - the user password in manageiq | ||
miq_verify_ssl - whether SSL certificates should be verified for HTTPS requests | ||
ca_bundle_path - the path to a CA_BUNDLE file or directory with certificates | ||
""" | ||
|
||
for arg in ['miq_url', 'miq_username', 'miq_password']: | ||
if module.params[arg] in (None, ''): | ||
module.fail_json(msg="missing required argument: {}".format(arg)) | ||
|
||
url = module.params['miq_url'] | ||
username = module.params['miq_username'] | ||
password = module.params['miq_password'] | ||
verify_ssl = module.params['miq_verify_ssl'] | ||
ca_bundle_path = module.params['ca_bundle_path'] | ||
|
||
self.module = module | ||
self.api_url = url + '/api' | ||
self.client = ManageIQClient(self.api_url, (username, password), verify_ssl=verify_ssl, ca_bundle_path=ca_bundle_path) | ||
|
||
def find_collection_resource_by(self, collection_name, **params): | ||
""" Searches the collection resource by the collection name and the param passed | ||
Returns: | ||
the resource as an object if it exists in manageiq, None otherwise. | ||
""" | ||
try: | ||
entity = self.client.collections.__getattribute__(collection_name).get(**params) | ||
except ValueError: | ||
return None | ||
except Exception as e: | ||
self.module.fail_json(msg="Failed to find resource {error}".format(error=e)) | ||
return vars(entity) | ||
|
||
|
||
|
229 changes: 229 additions & 0 deletions
229
lib/ansible/modules/monitoring/manageiq/manageiq_user.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
#!/usr/bin/python | ||
# | ||
# (c) 2017, Daniel Korn <korndaniel1@gmail.com> | ||
# | ||
# This file is part of Ansible | ||
# | ||
# Ansible 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. | ||
# | ||
# Ansible 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 Ansible. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
ANSIBLE_METADATA = {'metadata_version': '1.0', | ||
'status': ['preview'], | ||
'supported_by': 'community'} | ||
|
||
|
||
DOCUMENTATION = ''' | ||
module: manageiq_user | ||
short_description: management of users in ManageIQ | ||
extends_documentation_fragment: manageiq | ||
version_added: '2.3' | ||
author: Daniel Korn (@dkorn) | ||
description: | ||
- The manageiq_user module supports adding, updating and deleting users in ManageIQ. | ||
options: | ||
name: | ||
description: | ||
- the unique userid in manageiq, often mentioned as username | ||
required: true | ||
default: null | ||
fullname: | ||
description: | ||
- the users' full name | ||
required: false | ||
default: null | ||
password: | ||
description: | ||
- the users' password | ||
required: false | ||
default: null | ||
group: | ||
description: | ||
- the name of the group to which the user belongs | ||
required: false | ||
default: null | ||
email: | ||
description: | ||
- the users' E-mail address | ||
required: false | ||
default: null | ||
state: | ||
description: | ||
- the state of the user | ||
- On present, it will create the user if it does not exist or update the | ||
user if the associated data is different | ||
- On absent, it will delete the user if it exists | ||
required: False | ||
choices: ['present', 'absent'] | ||
default: 'present' | ||
''' | ||
|
||
EXAMPLES = ''' | ||
- name: Create a new user in ManageIQ | ||
manageiq_user: | ||
name: 'dkorn' | ||
fullname: 'Daniel Korn' | ||
password: '******' | ||
group: 'EvmGroup-user' | ||
email: 'dkorn@redhat.com' | ||
state: 'present' | ||
miq_url: 'http://localhost:3000' | ||
miq_username: 'admin' | ||
miq_password: '******' | ||
miq_verify_ssl: False | ||
''' | ||
|
||
import ansible.module_utils.manageiq_utils as manageiq_utils | ||
|
||
|
||
class ManageIQUser(object): | ||
""" | ||
object to execute user management operations in manageiq | ||
""" | ||
|
||
def __init__(self): | ||
self.changed = False | ||
|
||
def delete_user(self, manageiq, userid): | ||
"""Deletes the user from manageiq. | ||
Returns: | ||
a short message describing the operation executed. | ||
""" | ||
user = manageiq.find_collection_resource_by('users', userid=userid) | ||
if not user: # user doesn't exist | ||
return dict( | ||
changed=self.changed, | ||
msg="User {userid} does not exist in manageiq".format(userid=userid)) | ||
try: | ||
url = '{api_url}/users/{user_id}'.format(api_url=manageiq.api_url, user_id=user['id']) | ||
result = manageiq.client.post(url, action='delete') | ||
self.changed = True | ||
return dict(changed=self.changed, msg=result['message']) | ||
except Exception as e: | ||
manageiq.module.fail_json(msg="Failed to delete user {userid}: {error}".format(userid=userid, error=e)) | ||
|
||
def user_update_required(self, user, username, group_id, email): | ||
""" Returns True if the username, group id or email passed for the user | ||
differ from the user's existing ones, False otherwise. | ||
""" | ||
if username is not None and user['name'] != username: | ||
return True | ||
if group_id is not None and user['current_group_id'] != group_id: | ||
return True | ||
if email is not None and user.get('email') != email: | ||
return True | ||
return False | ||
|
||
def update_user_if_required(self, manageiq, user, userid, username, group_id, password, email): | ||
"""Updates the user in manageiq. | ||
Returns: | ||
the created user id, name, created_on timestamp, | ||
updated_on timestamp, userid and current_group_id | ||
""" | ||
if not self.user_update_required(user, username, group_id, email): | ||
return dict( | ||
changed=self.changed, | ||
msg="User {userid} already exist, no need for updates".format(userid=userid)) | ||
url = '{api_url}/users/{user_id}'.format(api_url=self.api_url, user_id=user.id) | ||
resource = {'userid': userid, 'name': username, 'password': password, | ||
'group': {'id': group_id}, 'email': email} | ||
try: | ||
result = manageiq.client.post(url, action='edit', resource=resource) | ||
except Exception as e: | ||
manageiq.module.fail_json(msg="Failed to update user {userid}: {error}".format(userid=userid, error=e)) | ||
self.changed = True | ||
return dict( | ||
changed=self.changed, | ||
msg="Successfully updated the user {userid}: {user_details}".format(userid=userid, user_details=result)) | ||
|
||
def create_user(self, manageiq, userid, username, group_id, password, email): | ||
"""Creates the user in manageiq. | ||
Returns: | ||
the created user id, name, created_on timestamp, | ||
updated_on timestamp, userid and current_group_id | ||
""" | ||
url = '{api_url}/users'.format(api_url=manageiq.api_url) | ||
resource = {'userid': userid, 'name': username, 'password': password, | ||
'group': {'id': group_id}, 'email': email} | ||
try: | ||
result = manageiq.client.post(url, action='create', resource=resource) | ||
except Exception as e: | ||
manageiq.module.fail_json(msg="Failed to create user {userid}: {error}".format(userid=userid, error=e)) | ||
self.changed = True | ||
return dict( | ||
changed=self.changed, | ||
msg="Successfully created the user {userid}: {user_details}".format(userid=userid, user_details=result['results'])) | ||
|
||
def create_or_update_user(self, manageiq, userid, username, password, group, email): | ||
""" Create or update a user in manageiq. | ||
Returns: | ||
Whether or not a change took place and a message describing the | ||
operation executed. | ||
""" | ||
group = manageiq.find_collection_resource_by('groups', description=group) | ||
if not group: # group doesn't exist | ||
manageiq.module.fail_json( | ||
msg="Failed to create user {userid}: group {group_name} does not exist in manageiq".format(userid=userid, group_name=group)) | ||
|
||
user = manageiq.find_collection_resource_by('users', userid=userid) | ||
if user: # user already exist | ||
return self.update_user_if_required(manageiq, user, userid, username, group['id'], password, email) | ||
else: | ||
return self.create_user(manageiq, userid, username, group['id'], password, email) | ||
|
||
|
||
def main(): | ||
module = AnsibleModule( | ||
argument_spec=dict( | ||
manageiq_utils.manageiq_argument_spec(), | ||
name=dict(required=True, type='str'), | ||
fullname=dict(required=False, type='str'), | ||
password=dict(required=False, type='str', no_log=True), | ||
group=dict(required=False, type='str'), | ||
email=dict(required=False, type='str'), | ||
state=dict(required=False, type='str', | ||
choices=['present', 'absent'], defualt='present'), | ||
), | ||
required_if=[ | ||
('state', 'present', ['fullname', 'group', 'password']) | ||
], | ||
) | ||
|
||
name = module.params['name'] | ||
fullname = module.params['fullname'] | ||
password = module.params['password'] | ||
group = module.params['group'] | ||
email = module.params['email'] | ||
state = module.params['state'] | ||
|
||
manageiq = manageiq_utils.ManageIQ(module) | ||
manageiq_user = ManageIQUser() | ||
if state == "present": | ||
res_args = manageiq_user.create_or_update_user(manageiq, name, fullname, | ||
password, group, email) | ||
if state == "absent": | ||
res_args = manageiq_user.delete_user(manageiq, name) | ||
|
||
module.exit_json(**res_args) | ||
|
||
|
||
# Import module bits | ||
from ansible.module_utils.basic import * | ||
if __name__ == "__main__": | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# | ||
# (c) 2017, Daniel Korn <korndaniel1@gmail.com> | ||
# | ||
# This file is part of Ansible | ||
# | ||
# Ansible 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. | ||
# | ||
# Ansible 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 Ansible. If not, see <http://www.gnu.org/licenses/>. | ||
|
||
|
||
class ModuleDocFragment(object): | ||
|
||
# Standard ManageIQ documentation fragment | ||
DOCUMENTATION = """ | ||
options: | ||
miq_url: | ||
description: | ||
- the manageiq environment url | ||
default: MIQ_URL env var if set. otherwise, it is required to pass it | ||
miq_username: | ||
description: | ||
- manageiq username | ||
default: MIQ_USERNAME env var if set. otherwise, it is required to pass it | ||
miq_password: | ||
description: | ||
- manageiq password | ||
default: MIQ_PASSWORD env var if set. otherwise, it is required to pass it | ||
miq_verify_ssl: | ||
required: False | ||
description: | ||
- whether SSL certificates should be verified for HTTPS requests | ||
default: True | ||
choices: ['True', 'False'] | ||
ca_bundle_path: | ||
required: False | ||
description: | ||
- the path to a CA_BUNDLE file or directory with certificates | ||
default: null | ||
requirements: | ||
- manageiq-api-client-python: | ||
- Install from source: https://github.com/ManageIQ/manageiq-api-client-python/ | ||
- Install using 'pip install manageiq-client' | ||
""" |