1#!/usr/bin/python
2
3# (c) 2018-2019, NetApp, Inc
4# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
5
6from __future__ import absolute_import, division, print_function
7__metaclass__ = type
8
9
10ANSIBLE_METADATA = {'metadata_version': '1.1',
11                    'status': ['preview'],
12                    'supported_by': 'community'}
13
14
15DOCUMENTATION = '''
16
17module: na_ontap_unix_user
18
19short_description: NetApp ONTAP UNIX users
20extends_documentation_fragment:
21    - netapp.na_ontap
22version_added: '2.8'
23author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com>
24
25description:
26- Create, delete or modify UNIX users local to ONTAP.
27
28options:
29
30  state:
31    description:
32    - Whether the specified user should exist or not.
33    choices: ['present', 'absent']
34    default: 'present'
35
36  name:
37    description:
38    - Specifies user's UNIX account name.
39    - Non-modifiable.
40    required: true
41
42  group_id:
43    description:
44    - Specifies the primary group identification number for the UNIX user
45    - Required for create, modifiable.
46
47  vserver:
48    description:
49    - Specifies the Vserver for the UNIX user.
50    - Non-modifiable.
51    required: true
52
53  id:
54    description:
55    - Specifies an identification number for the UNIX user.
56    - Required for create, modifiable.
57
58  full_name:
59    description:
60    - Specifies the full name of the UNIX user
61    - Optional for create, modifiable.
62'''
63
64EXAMPLES = """
65
66    - name: Create UNIX User
67      na_ontap_unix_user:
68        state: present
69        name: SampleUser
70        vserver: ansibleVServer
71        group_id: 1
72        id: 2
73        full_name: Test User
74        hostname: "{{ netapp_hostname }}"
75        username: "{{ netapp_username }}"
76        password: "{{ netapp_password }}"
77
78    - name: Delete UNIX User
79      na_ontap_unix_user:
80        state: absent
81        name: SampleUser
82        vserver: ansibleVServer
83        hostname: "{{ netapp_hostname }}"
84        username: "{{ netapp_username }}"
85        password: "{{ netapp_password }}"
86
87"""
88
89RETURN = """
90
91"""
92import traceback
93
94from ansible.module_utils.basic import AnsibleModule
95from ansible.module_utils._text import to_native
96import ansible.module_utils.netapp as netapp_utils
97from ansible.module_utils.netapp_module import NetAppModule
98
99HAS_NETAPP_LIB = netapp_utils.has_netapp_lib()
100
101
102class NetAppOntapUnixUser(object):
103    """
104    Common operations to manage users and roles.
105    """
106
107    def __init__(self):
108        self.argument_spec = netapp_utils.na_ontap_host_argument_spec()
109        self.argument_spec.update(dict(
110            state=dict(required=False, choices=['present', 'absent'], default='present'),
111            name=dict(required=True, type='str'),
112            group_id=dict(required=False, type='int'),
113            id=dict(required=False, type='int'),
114            full_name=dict(required=False, type='str'),
115            vserver=dict(required=True, type='str'),
116        ))
117
118        self.module = AnsibleModule(
119            argument_spec=self.argument_spec,
120            supports_check_mode=True
121        )
122
123        self.na_helper = NetAppModule()
124        self.parameters = self.na_helper.set_parameters(self.module.params)
125
126        if HAS_NETAPP_LIB is False:
127            self.module.fail_json(msg="the python NetApp-Lib module is required")
128        else:
129            self.server = netapp_utils.setup_na_ontap_zapi(module=self.module, vserver=self.parameters['vserver'])
130
131    def get_unix_user(self):
132        """
133        Checks if the UNIX user exists.
134
135        :return:
136            dict() if user found
137            None if user is not found
138        """
139
140        get_unix_user = netapp_utils.zapi.NaElement('name-mapping-unix-user-get-iter')
141        attributes = {
142            'query': {
143                'unix-user-info': {
144                    'user-name': self.parameters['name'],
145                    'vserver': self.parameters['vserver'],
146                }
147            }
148        }
149        get_unix_user.translate_struct(attributes)
150        try:
151            result = self.server.invoke_successfully(get_unix_user, enable_tunneling=True)
152            if result.get_child_by_name('num-records') and int(result.get_child_content('num-records')) >= 1:
153                user_info = result['attributes-list']['unix-user-info']
154                return {'group_id': int(user_info['group-id']),
155                        'id': int(user_info['user-id']),
156                        'full_name': user_info['full-name']}
157            return None
158        except netapp_utils.zapi.NaApiError as error:
159            self.module.fail_json(msg='Error getting UNIX user %s: %s' % (self.parameters['name'], to_native(error)),
160                                  exception=traceback.format_exc())
161
162    def create_unix_user(self):
163        """
164        Creates an UNIX user in the specified Vserver
165
166        :return: None
167        """
168        if self.parameters.get('group_id') is None or self.parameters.get('id') is None:
169            self.module.fail_json(msg='Error: Missing one or more required parameters for create: (group_id, id)')
170
171        user_create = netapp_utils.zapi.NaElement.create_node_with_children(
172            'name-mapping-unix-user-create', **{'user-name': self.parameters['name'],
173                                                'group-id': str(self.parameters['group_id']),
174                                                'user-id': str(self.parameters['id'])})
175        if self.parameters.get('full_name') is not None:
176            user_create.add_new_child('full-name', self.parameters['full_name'])
177
178        try:
179            self.server.invoke_successfully(user_create, enable_tunneling=True)
180        except netapp_utils.zapi.NaApiError as error:
181            self.module.fail_json(msg='Error creating UNIX user %s: %s' % (self.parameters['name'], to_native(error)),
182                                  exception=traceback.format_exc())
183
184    def delete_unix_user(self):
185        """
186        Deletes an UNIX user from a vserver
187
188        :return: None
189        """
190        user_delete = netapp_utils.zapi.NaElement.create_node_with_children(
191            'name-mapping-unix-user-destroy', **{'user-name': self.parameters['name']})
192
193        try:
194            self.server.invoke_successfully(user_delete, enable_tunneling=True)
195        except netapp_utils.zapi.NaApiError as error:
196            self.module.fail_json(msg='Error removing UNIX user %s: %s' % (self.parameters['name'], to_native(error)),
197                                  exception=traceback.format_exc())
198
199    def modify_unix_user(self, params):
200        user_modify = netapp_utils.zapi.NaElement.create_node_with_children(
201            'name-mapping-unix-user-modify', **{'user-name': self.parameters['name']})
202        for key in params:
203            if key == 'group_id':
204                user_modify.add_new_child('group-id', str(params['group_id']))
205            if key == 'id':
206                user_modify.add_new_child('user-id', str(params['id']))
207            if key == 'full_name':
208                user_modify.add_new_child('full-name', params['full_name'])
209
210        try:
211            self.server.invoke_successfully(user_modify, enable_tunneling=True)
212        except netapp_utils.zapi.NaApiError as error:
213            self.module.fail_json(msg='Error modifying UNIX user %s: %s' % (self.parameters['name'], to_native(error)),
214                                  exception=traceback.format_exc())
215
216    def autosupport_log(self):
217        """
218          Autosupport log for unix_user
219          :return: None
220          """
221        netapp_utils.ems_log_event("na_ontap_unix_user", self.server)
222
223    def apply(self):
224        """
225        Invoke appropriate action based on playbook parameters
226
227        :return: None
228        """
229        self.autosupport_log()
230        current = self.get_unix_user()
231        cd_action = self.na_helper.get_cd_action(current, self.parameters)
232        if self.parameters['state'] == 'present' and cd_action is None:
233            modify = self.na_helper.get_modified_attributes(current, self.parameters)
234        if self.na_helper.changed:
235            if self.module.check_mode:
236                pass
237            else:
238                if cd_action == 'create':
239                    self.create_unix_user()
240                elif cd_action == 'delete':
241                    self.delete_unix_user()
242                else:
243                    self.modify_unix_user(modify)
244        self.module.exit_json(changed=self.na_helper.changed)
245
246
247def main():
248    obj = NetAppOntapUnixUser()
249    obj.apply()
250
251
252if __name__ == '__main__':
253    main()
254