1#!/usr/bin/python 2# -*- coding: utf-8 -*- 3 4# (c) 2018, Simon Dodsley (simon@purestorage.com) 5# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6 7from __future__ import absolute_import, division, print_function 8__metaclass__ = type 9 10ANSIBLE_METADATA = {'metadata_version': '1.1', 11 'status': ['preview'], 12 'supported_by': 'community'} 13 14DOCUMENTATION = r''' 15--- 16module: purefa_user 17version_added: '2.8' 18short_description: Create, modify or delete FlashArray local user account 19description: 20- Create, modify or delete local users on a Pure Storage FlashArray. 21author: 22- Pure Storage Ansible Team (@sdodsley) <pure-ansible-team@purestorage.com> 23options: 24 state: 25 description: 26 - Create, delete or update local user account 27 default: present 28 type: str 29 choices: [ absent, present ] 30 name: 31 description: 32 - The name of the local user account 33 type: str 34 role: 35 description: 36 - Sets the local user's access level to the array 37 type: str 38 choices: [ readonly, storage_admin, array_admin ] 39 password: 40 description: 41 - Password for the local user. 42 type: str 43 old_password: 44 description: 45 - If changing an existing password, you must provide the old password for security 46 type: str 47 api: 48 description: 49 - Define whether to create an API token for this user 50 - Token can be exposed using the I(debug) module 51 type: bool 52 default: false 53extends_documentation_fragment: 54- purestorage.fa 55''' 56 57EXAMPLES = r''' 58- name: Create new user ansible with API token 59 purefa_user: 60 name: ansible 61 password: apassword 62 role: storage_admin 63 api: true 64 fa_url: 10.10.10.2 65 api_token: e31060a7-21fc-e277-6240-25983c6c4592 66 register: result 67 68 debug: 69 msg: "API Token: {{ result['user_info']['user_api'] }}" 70 71- name: Change role type for existing user 72 purefa_user: 73 name: ansible 74 role: array_admin 75 state: update 76 fa_url: 10.10.10.2 77 api_token: e31060a7-21fc-e277-6240-25983c6c4592 78 79- name: Change password type for existing user (NOT IDEMPOTENT) 80 purefa_user: 81 name: ansible 82 password: anewpassword 83 old_password: apassword 84 fa_url: 10.10.10.2 85 api_token: e31060a7-21fc-e277-6240-25983c6c4592 86 87- name: Change API token for existing user 88 purefa_user: 89 name: ansible 90 api: true 91 state: update 92 fa_url: 10.10.10.2 93 api_token: e31060a7-21fc-e277-6240-25983c6c4592 94 register: result 95 96 debug: 97 msg: "API Token: {{ result['user_info']['user_api'] }}" 98''' 99 100RETURN = r''' 101''' 102 103 104from ansible.module_utils.basic import AnsibleModule 105from ansible.module_utils.pure import get_system, purefa_argument_spec 106 107MIN_REQUIRED_API_VERSION = '1.14' 108 109 110def get_user(module, array): 111 """Return Local User Account or None""" 112 user = None 113 users = array.list_admins() 114 for acct in range(0, len(users)): 115 if users[acct]['name'] == module.params['name']: 116 user = users[acct] 117 return user 118 119 120def create_user(module, array): 121 """Create or Update Local User Account""" 122 changed = False 123 user = get_user(module, array) 124 role = module.params['role'] 125 api_changed = False 126 role_changed = False 127 passwd_changed = False 128 user_token = {} 129 if not user: 130 try: 131 if not role: 132 role = 'readonly' 133 array.create_admin(module.params['name'], role=role, 134 password=module.params['password']) 135 if module.params['api']: 136 try: 137 user_token['user_api'] = array.create_api_token(module.params['name'])['api_token'] 138 except Exception: 139 array.delete_user(module.params['name']) 140 module.fail_json(msg='Local User {0}: Creation failed'.format(module.params['name'])) 141 changed = True 142 except Exception: 143 module.fail_json(msg='Local User {0}: Creation failed'.format(module.params['name'])) 144 else: 145 if module.params['password'] and not module.params['old_password']: 146 changed = False 147 module.exit_json(changed=changed) 148 if module.params['password'] and module.params['old_password']: 149 if module.params['old_password'] and (module.params['password'] != module.params['old_password']): 150 try: 151 array.set_admin(module.params['name'], password=module.params['password'], 152 old_password=module.params['old_password']) 153 passwd_changed = True 154 except Exception: 155 module.fail_json(msg='Local User {0}: Password reset failed. ' 156 'Check old password.'.format(module.params['name'])) 157 else: 158 module.fail_json(msg='Local User Account {0}: Password change failed - ' 159 'Check both old and new passwords'.format(module.params['name'])) 160 if module.params['api']: 161 try: 162 if not array.get_api_token(module.params['name'])['api_token'] is None: 163 array.delete_api_token(module.params['name']) 164 user_token['user_api'] = array.create_api_token(module.params['name'])['api_token'] 165 api_changed = True 166 except Exception: 167 module.fail_json(msg='Local User {0}: API token change failed'.format(module.params['name'])) 168 if module.params['role'] != user['role']: 169 try: 170 array.set_admin(module.params['name'], role=module.params['role']) 171 role_changed = True 172 except Exception: 173 module.fail_json(msg='Local User {0}: Role changed failed'.format(module.params['name'])) 174 if passwd_changed or role_changed or api_changed: 175 changed = True 176 module.exit_json(changed=changed, user_info=user_token) 177 178 179def delete_user(module, array): 180 """Delete Local User Account""" 181 changed = False 182 if get_user(module, array): 183 try: 184 array.delete_admin(module.params['name']) 185 changed = True 186 except Exception: 187 module.fail_json(msg='Object Store Account {0}: Deletion failed'.format(module.params['name'])) 188 module.exit_json(changed=changed) 189 190 191def main(): 192 argument_spec = purefa_argument_spec() 193 argument_spec.update(dict( 194 name=dict(required=True, type='str'), 195 role=dict(type='str', choices=['readonly', 'storage_admin', 'array_admin']), 196 state=dict(type='str', default='present', choices=['absent', 'present']), 197 password=dict(type='str', no_log=True), 198 old_password=dict(type='str', no_log=True), 199 api=dict(type='bool', default=False), 200 )) 201 202 module = AnsibleModule(argument_spec, 203 supports_check_mode=False) 204 205 state = module.params['state'] 206 array = get_system(module) 207 api_version = array._list_available_rest_versions() 208 209 if MIN_REQUIRED_API_VERSION not in api_version: 210 module.fail_json(msg='FlashArray REST version not supported. ' 211 'Minimum version required: {0}'.format(MIN_REQUIRED_API_VERSION)) 212 213 if state == 'absent': 214 delete_user(module, array) 215 elif state == 'present': 216 create_user(module, array) 217 else: 218 module.exit_json(changed=False) 219 220 221if __name__ == '__main__': 222 main() 223