Files
offline_kubespray/collection/infinidat/infinibox/plugins/modules/infini_user.py
ByeonJungHun 360c6eef4a offline 작업
2024-02-19 16:02:29 +09:00

333 lines
10 KiB
Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2020, Infinidat <info@infinidat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from infi.dtypes.iqn import make_iscsi_name
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = r'''
---
module: infini_user
version_added: '2.10'
short_description: Create, Delete and Modify a User on Infinibox
description:
- This module creates, deletes or modifies a user on Infinibox.
author: David Ohlemacher (@ohlemacher)
options:
user_name:
description:
- The new user's Name. Once a user is created, the user_name may not be
changed from this module. It may be changed from the UI or from
infinishell.
required: true
user_email:
description:
- The new user's Email address
required: true
user_password:
description:
- The new user's password
required: true
user_role:
description:
- The user's role
required: true
choices: [ "admin", "pool_admin", "read_only" ]
user_enabled:
description:
- Specify whether to enable the user
type: bool
required: false
default: true
user_pool:
description:
- Use with role==pool_admin. Specify the new user's pool.
required: False
state:
description:
- Creates/Modifies user when present or removes when absent
required: false
default: present
choices: [ "stat", "reset_password", "present", "absent" ]
extends_documentation_fragment:
- infinibox
'''
EXAMPLES = r'''
- name: Create new user
infini_user:
user_name: foo_user
user_email: foo@example.com
user_password: secret2
user_role: pool_admin
user_enabled: false
pool: foo_pool
state: present
password: secret1
system: ibox001
'''
# RETURN = r''' # '''
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible_collections.infinidat.infinibox.plugins.module_utils.infinibox import \
HAS_INFINISDK, api_wrapper, infinibox_argument_spec, \
get_system, get_user, get_pool, unixMillisecondsToDate, merge_two_dicts
@api_wrapper
def create_user(module, system):
if not module.check_mode:
user = system.users.create(name=module.params['user_name'],
password=module.params['user_password'],
email=module.params['user_email'],
enabled=module.params['user_enabled'],
)
# Set the user's role
user.update_role(module.params['user_role'])
if module.params['user_pool']:
assert module.params['user_role'] == 'pool_admin', \
'user_pool set, but role is not pool_admin'
# Add the user to the pool's owners
pool = system.pools.get(name=module.params['user_pool'])
add_user_to_pool_owners(user, pool)
changed = True
return changed
def add_user_to_pool_owners(user, pool):
"""
Find the current list of pool owners and add user using pool.set_owners().
set_owners() replaces the current owners with the list of new owners. So,
get owners, add user, then set owners. Further, we need to know if the
owners changed. Use sets of owners to compare.
"""
#print("add_user_to_pool_owners(): start")
changed = False
pool_fields = pool.get_fields(from_cache=True, raw_value=True)
pool_owners = pool_fields.get('owners', [])
#print('pool_owners:', pool_owners, 'pool_owners type:', type(pool_owners))
#print('user:', user)
#print('pool:', pool)
pool_owners_set = set(pool_owners)
#print('pool_owners_set:', pool_owners_set)
new_pool_owners_set = pool_owners_set.copy()
new_pool_owners_set.add(user.id)
#print('new_pool_owners_set:', new_pool_owners_set)
if pool_owners_set != new_pool_owners_set:
pool.set_owners([user]) #(pool_owners.append(user))
changed = True
#print("changed:", changed)
#print("add_user_to_pool_owners(): end")
return changed
def remove_user_from_pool_owners(user, pool):
changed = False
pool_fields = pool.get_fields(from_cache=True, raw_value=True)
pool_owners = pool_fields.get('owners', [])
try:
pool_owners.remove(user)
pool.set_owners(pool_owners)
changed = True
except ValueError:
pass # User is not a pool owner
return changed
@api_wrapper
def update_user(module, system, user):
#print("update_user()")
assert user is not None, "Cannot update user. User not found."
changed = False
fields = user.get_fields(from_cache=True, raw_value=True)
if fields.get('role') != module.params['user_role'].upper():
user.update_field('role', module.params['user_role'])
changed = True
if fields.get('enabled') != module.params['user_enabled']:
user.update_field('enabled', module.params['user_enabled'])
changed = True
if fields.get('email') != module.params['user_email']:
user.update_field('email', module.params['user_email'])
changed = True
if module.params['user_pool']:
try:
pool_name = module.params['user_pool']
pool = system.pools.get(name=pool_name)
except Exception as err:
module.fail_json(msg='Cannot find pool {0}: {1}'.format(pool_name, err))
if add_user_to_pool_owners(user, pool):
changed = True
return changed
@api_wrapper
def reset_user_password(module, system, user):
#print("update_user()")
assert user is not None, "Cannot change user password. User not found."
user.update_password(module.params['user_password'])
@api_wrapper
def delete_user(module, user):
if not user:
return False
changed = True
if not module.check_mode:
# May raise APICommandFailed if mapped, etc.
user.delete()
return changed
def get_sys_user(module):
system = get_system(module)
user = get_user(module, system)
#print("get_sys_user(): user:", user)
return (system, user)
def get_user_fields(user):
pools = user.get_owned_pools()
pool_names = [pool.get_field('name') for pool in pools]
fields = user.get_fields(from_cache=True, raw_value=True)
field_dict = dict(
id=user.id,
enabled=fields.get('enabled', None),
role=fields.get('role', None),
email=fields.get('email', None),
pools=pool_names,
)
return field_dict
def handle_stat(module):
system, user = get_sys_user(module)
user_name = module.params["user_name"]
if not user:
module.fail_json(msg='User {0} not found'.format(user_name))
field_dict = get_user_fields(user)
result = dict(
changed=False,
msg='User stat found'
)
result = merge_two_dicts(result, field_dict)
module.exit_json(**result)
def handle_present(module):
system, user = get_sys_user(module)
user_name = module.params["user_name"]
if not user:
changed = create_user(module, system)
msg='User {0} created'.format(user_name)
else:
changed = update_user(module, system, user)
if changed:
msg='User {0} updated'.format(user_name)
else:
msg='User {0} update required no changes'.format(user_name)
module.exit_json(changed=changed, msg=msg)
def handle_absent(module):
system, user = get_sys_user(module)
user_name = module.params["user_name"]
if not user:
changed = False
msg="User {0} already absent".format(user_name)
else:
changed = delete_user(module, user)
msg="User {0} removed".format(user_name)
module.exit_json(changed=changed, msg=msg)
def handle_reset_password(module):
system, user = get_sys_user(module)
user_name = module.params["user_name"]
if not user:
msg = 'Cannot change password. User {0} not found'.format(user_name)
module.fail_json(msg=msg)
else:
reset_user_password(module, system, user)
msg='User {0} password changed'.format(user_name)
module.exit_json(changed=True, msg=msg)
def execute_state(module):
state = module.params['state']
try:
if state == 'stat':
handle_stat(module)
elif state == 'present':
handle_present(module)
elif state == 'absent':
handle_absent(module)
elif state == 'reset_password':
handle_reset_password(module)
else:
module.fail_json(msg='Internal handler error. Invalid state: {0}'.format(state))
finally:
system = get_system(module)
system.logout()
def check_options(module):
state = module.params['state']
user_role = module.params['user_role']
user_pool = module.params['user_pool']
if state == 'present':
if user_role == 'pool_admin' and not user_pool:
module.fail_json(msg='user_role "pool_admin" requires a user_pool to be provided')
if user_role != 'pool_admin' and user_pool:
module.fail_json(msg='Only user_role "pool_admin" should have a user_pool provided')
valid_keys = ['user_email', 'user_password', 'user_role', 'user_enabled']
for valid_key in valid_keys:
try:
_ = module.params[valid_key]
except KeyError:
msg = 'For state "present", options {0} are required'.format(", ".join(valid_keys))
module.fail_json(msg=msg)
elif state == 'reset_password':
if not module.params['user_password']:
msg = 'For state "reset_password", user_password is required'
def main():
argument_spec = infinibox_argument_spec()
argument_spec.update(
dict(
user_name=dict(required=True),
user_email=dict(required=False),
user_password=dict(required=False, no_log=True),
user_role=dict(required=False, choices=['admin', 'pool_admin', 'read_only']),
user_enabled=dict(required=False, type='bool'),
user_pool=dict(required=False),
state=dict(default='present', choices=['stat', 'reset_password', 'present', 'absent']),
)
)
module = AnsibleModule(argument_spec, supports_check_mode=True)
if not HAS_INFINISDK:
module.fail_json(msg=missing_required_lib('infinisdk'))
check_options(module)
execute_state(module)
if __name__ == '__main__':
main()