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': 'certified'}
13
14
15DOCUMENTATION = """
16module: na_ontap_nfs
17short_description: NetApp ONTAP NFS status
18extends_documentation_fragment:
19    - netapp.na_ontap
20version_added: '2.6'
21author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com>
22description:
23- Enable or disable NFS on ONTAP
24options:
25  state:
26    description:
27    - Whether NFS should exist or not.
28    choices: ['present', 'absent']
29    default: present
30  service_state:
31    description:
32    - Whether the specified NFS should be enabled or disabled. Creates NFS service if does not exist.
33    choices: ['started', 'stopped']
34  vserver:
35    description:
36    - Name of the vserver to use.
37    required: true
38  nfsv3:
39    description:
40    - status of NFSv3.
41    choices: ['enabled', 'disabled']
42  nfsv3_fsid_change:
43    description:
44    - status of if NFSv3 clients see change in FSID as they traverse filesystems.
45    choices: ['enabled', 'disabled']
46    version_added: '2.7'
47  nfsv4_fsid_change:
48    description:
49    - status of if NFSv4 clients see change in FSID as they traverse filesystems.
50    choices: ['enabled', 'disabled']
51    version_added: '2.9'
52  nfsv4:
53    description:
54    - status of NFSv4.
55    choices: ['enabled', 'disabled']
56  nfsv41:
57    description:
58    - status of NFSv41.
59    aliases: ['nfsv4.1']
60    choices: ['enabled', 'disabled']
61  nfsv41_pnfs:
62    description:
63    - status of NFSv41 pNFS.
64    choices: ['enabled', 'disabled']
65    version_added: '2.9'
66  nfsv4_numeric_ids:
67    description:
68    - status of NFSv4 numeric ID's.
69    choices: ['enabled', 'disabled']
70    version_added: '2.9'
71  vstorage_state:
72    description:
73    - status of vstorage_state.
74    choices: ['enabled', 'disabled']
75  nfsv4_id_domain:
76    description:
77    - Name of the nfsv4_id_domain to use.
78  nfsv40_acl:
79    description:
80    - status of NFS v4.0 ACL feature
81    choices: ['enabled', 'disabled']
82    version_added: '2.7'
83  nfsv40_read_delegation:
84    description:
85    - status for NFS v4.0 read delegation feature.
86    choices: ['enabled', 'disabled']
87    version_added: '2.7'
88  nfsv40_write_delegation:
89    description:
90    - status for NFS v4.0 write delegation feature.
91    choices: ['enabled', 'disabled']
92    version_added: '2.7'
93  nfsv41_acl:
94    description:
95    - status of NFS v4.1 ACL feature
96    choices: ['enabled', 'disabled']
97    version_added: '2.7'
98  nfsv41_read_delegation:
99    description:
100    - status for NFS v4.1 read delegation feature.
101    choices: ['enabled', 'disabled']
102    version_added: '2.7'
103  nfsv41_write_delegation:
104    description:
105    - status for NFS v4.1 write delegation feature.
106    choices: ['enabled', 'disabled']
107    version_added: '2.7'
108  nfsv40_referrals:
109    description:
110    - status for NFS v4.0 referrals.
111    choices: ['enabled', 'disabled']
112    version_added: '2.9'
113  nfsv41_referrals:
114    description:
115    - status for NFS v4.1 referrals.
116    choices: ['enabled', 'disabled']
117    version_added: '2.9'
118  tcp:
119    description:
120    - Enable TCP (support from ONTAP 9.3 onward).
121    choices: ['enabled', 'disabled']
122  udp:
123    description:
124    - Enable UDP (support from ONTAP 9.3 onward).
125    choices: ['enabled', 'disabled']
126  showmount:
127    description:
128    - Whether SVM allows showmount
129    choices: ['enabled', 'disabled']
130    version_added: '2.7'
131  tcp_max_xfer_size:
132    description:
133    - TCP Maximum Transfer Size (bytes). The default value is 65536.
134    version_added: '2.8'
135    type: int
136
137"""
138
139EXAMPLES = """
140    - name: change nfs status
141      na_ontap_nfs:
142        state: present
143        service_state: stopped
144        vserver: vs_hack
145        nfsv3: disabled
146        nfsv4: disabled
147        nfsv41: enabled
148        tcp: disabled
149        udp: disabled
150        vstorage_state: disabled
151        nfsv4_id_domain: example.com
152        hostname: "{{ netapp_hostname }}"
153        username: "{{ netapp_username }}"
154        password: "{{ netapp_password }}"
155"""
156
157RETURN = """
158"""
159import traceback
160
161from ansible.module_utils.basic import AnsibleModule
162from ansible.module_utils._text import to_native
163import ansible.module_utils.netapp as netapp_utils
164
165
166HAS_NETAPP_LIB = netapp_utils.has_netapp_lib()
167
168
169class NetAppONTAPNFS(object):
170    """ object initialize and class methods """
171
172    def __init__(self):
173
174        self.argument_spec = netapp_utils.na_ontap_host_argument_spec()
175        self.argument_spec.update(dict(
176            state=dict(required=False, type='str', choices=['present', 'absent'], default='present'),
177            service_state=dict(required=False, choices=['started', 'stopped']),
178            vserver=dict(required=True, type='str'),
179            nfsv3=dict(required=False, default=None, choices=['enabled', 'disabled']),
180            nfsv3_fsid_change=dict(required=False, default=None, choices=['enabled', 'disabled']),
181            nfsv4_fsid_change=dict(required=False, default=None, choices=['enabled', 'disabled']),
182            nfsv4=dict(required=False, default=None, choices=['enabled', 'disabled']),
183            nfsv41=dict(required=False, default=None, choices=['enabled', 'disabled'], aliases=['nfsv4.1']),
184            nfsv41_pnfs=dict(required=False, default=None, choices=['enabled', 'disabled']),
185            nfsv4_numeric_ids=dict(required=False, default=None, choices=['enabled', 'disabled']),
186            vstorage_state=dict(required=False, default=None, choices=['enabled', 'disabled']),
187            tcp=dict(required=False, default=None, choices=['enabled', 'disabled']),
188            udp=dict(required=False, default=None, choices=['enabled', 'disabled']),
189            nfsv4_id_domain=dict(required=False, type='str', default=None),
190            nfsv40_acl=dict(required=False, default=None, choices=['enabled', 'disabled']),
191            nfsv40_read_delegation=dict(required=False, default=None, choices=['enabled', 'disabled']),
192            nfsv40_referrals=dict(required=False, default=None, choices=['enabled', 'disabled']),
193            nfsv40_write_delegation=dict(required=False, default=None, choices=['enabled', 'disabled']),
194            nfsv41_acl=dict(required=False, default=None, choices=['enabled', 'disabled']),
195            nfsv41_read_delegation=dict(required=False, default=None, choices=['enabled', 'disabled']),
196            nfsv41_referrals=dict(required=False, default=None, choices=['enabled', 'disabled']),
197            nfsv41_write_delegation=dict(required=False, default=None, choices=['enabled', 'disabled']),
198            showmount=dict(required=False, default=None, choices=['enabled', 'disabled']),
199            tcp_max_xfer_size=dict(required=False, default=None, type='int')
200        ))
201
202        self.module = AnsibleModule(
203            argument_spec=self.argument_spec,
204            supports_check_mode=True
205        )
206
207        parameters = self.module.params
208
209        # set up service_state variables
210        self.state = parameters['state']
211        self.service_state = parameters['service_state']
212        self.vserver = parameters['vserver']
213        self.nfsv3 = parameters['nfsv3']
214        self.nfsv3_fsid_change = parameters['nfsv3_fsid_change']
215        self.nfsv4_fsid_change = parameters['nfsv4_fsid_change']
216        self.nfsv4 = parameters['nfsv4']
217        self.nfsv41 = parameters['nfsv41']
218        self.vstorage_state = parameters['vstorage_state']
219        self.nfsv4_id_domain = parameters['nfsv4_id_domain']
220        self.udp = parameters['udp']
221        self.tcp = parameters['tcp']
222        self.nfsv40_acl = parameters['nfsv40_acl']
223        self.nfsv40_read_delegation = parameters['nfsv40_read_delegation']
224        self.nfsv40_referrals = parameters['nfsv40_referrals']
225        self.nfsv40_write_delegation = parameters['nfsv40_write_delegation']
226        self.nfsv41_acl = parameters['nfsv41_acl']
227        self.nfsv41_read_delegation = parameters['nfsv41_read_delegation']
228        self.nfsv41_referrals = parameters['nfsv41_referrals']
229        self.nfsv41_write_delegation = parameters['nfsv41_write_delegation']
230        self.nfsv41_pnfs = parameters['nfsv41_pnfs']
231        self.nfsv4_numeric_ids = parameters['nfsv4_numeric_ids']
232        self.showmount = parameters['showmount']
233        self.tcp_max_xfer_size = parameters['tcp_max_xfer_size']
234
235        if HAS_NETAPP_LIB is False:
236            self.module.fail_json(msg="the python NetApp-Lib module is required")
237        else:
238            self.server = netapp_utils.setup_na_ontap_zapi(module=self.module, vserver=self.vserver)
239
240    def get_nfs_service(self):
241        """
242        Return details about nfs
243        :param:
244            name : name of the vserver
245        :return: Details about nfs. None if not found.
246        :rtype: dict
247        """
248        nfs_get_iter = netapp_utils.zapi.NaElement('nfs-service-get-iter')
249        nfs_info = netapp_utils.zapi.NaElement('nfs-info')
250        nfs_info.add_new_child('vserver', self.vserver)
251        query = netapp_utils.zapi.NaElement('query')
252        query.add_child_elem(nfs_info)
253        nfs_get_iter.add_child_elem(query)
254        result = self.server.invoke_successfully(nfs_get_iter, True)
255        nfs_details = None
256        # check if job exists
257        if result.get_child_by_name('num-records') and \
258                int(result.get_child_content('num-records')) >= 1:
259            attributes_list = result.get_child_by_name('attributes-list').get_child_by_name('nfs-info')
260            is_nfsv3_enabled = attributes_list.get_child_content('is-nfsv3-enabled')
261            is_nfsv3_fsid_change_enabled = attributes_list.get_child_content('is-nfsv3-fsid-change-enabled')
262            is_nfsv4_fsid_change_enabled = attributes_list.get_child_content('is-nfsv4-fsid-change-enabled')
263            is_nfsv40_enabled = attributes_list.get_child_content('is-nfsv40-enabled')
264            is_nfsv41_enabled = attributes_list.get_child_content('is-nfsv41-enabled')
265            is_vstorage_enabled = attributes_list.get_child_content('is-vstorage-enabled')
266            nfsv4_id_domain_value = attributes_list.get_child_content('nfsv4-id-domain')
267            is_tcp_enabled = attributes_list.get_child_content('is-tcp-enabled')
268            is_udp_enabled = attributes_list.get_child_content('is-udp-enabled')
269            is_nfsv40_acl_enabled = attributes_list.get_child_content('is-nfsv40-acl-enabled')
270            is_nfsv40_write_delegation_enabled = attributes_list.get_child_content('is-nfsv40-write-delegation-enabled')
271            is_nfsv40_read_delegation_enabled = attributes_list.get_child_content('is-nfsv40-read-delegation-enabled')
272            is_nfsv40_referrals_enabled = attributes_list.get_child_content('is-nfsv40-referrals-enabled')
273            is_nfsv41_acl_enabled = attributes_list.get_child_content('is-nfsv41-acl-enabled')
274            is_nfsv41_write_delegation_enabled = attributes_list.get_child_content('is-nfsv41-write-delegation-enabled')
275            is_nfsv41_read_delegation_enabled = attributes_list.get_child_content('is-nfsv41-read-delegation-enabled')
276            is_nfsv41_referrals_enabled = attributes_list.get_child_content('is-nfsv41-referrals-enabled')
277            is_nfsv41_pnfs_enabled = attributes_list.get_child_content('is-nfsv41-pnfs-enabled')
278            is_nfsv4_numeric_ids_enabled = attributes_list.get_child_content('is-nfsv4-numeric-ids-enabled')
279            is_showmount_enabled = attributes_list.get_child_content('showmount')
280            tcp_max_xfer_size = attributes_list.get_child_content('tcp-max-xfer-size')
281            nfs_details = {
282                'is_nfsv3_enabled': is_nfsv3_enabled,
283                'is_nfsv3_fsid_change_enabled': is_nfsv3_fsid_change_enabled,
284                'is_nfsv4_fsid_change_enabled': is_nfsv4_fsid_change_enabled,
285                'is_nfsv40_enabled': is_nfsv40_enabled,
286                'is_nfsv41_enabled': is_nfsv41_enabled,
287                'is_nfsv41_pnfs_enabled': is_nfsv41_pnfs_enabled,
288                'is_nfsv4_numeric_ids_enabled': is_nfsv4_numeric_ids_enabled,
289                'is_vstorage_enabled': is_vstorage_enabled,
290                'nfsv4_id_domain': nfsv4_id_domain_value,
291                'is_tcp_enabled': is_tcp_enabled,
292                'is_udp_enabled': is_udp_enabled,
293                'is_nfsv40_acl_enabled': is_nfsv40_acl_enabled,
294                'is_nfsv40_read_delegation_enabled': is_nfsv40_read_delegation_enabled,
295                'is_nfsv40_referrals_enabled': is_nfsv40_referrals_enabled,
296                'is_nfsv40_write_delegation_enabled': is_nfsv40_write_delegation_enabled,
297                'is_nfsv41_acl_enabled': is_nfsv41_acl_enabled,
298                'is_nfsv41_read_delegation_enabled': is_nfsv41_read_delegation_enabled,
299                'is_nfsv41_referrals_enabled': is_nfsv41_referrals_enabled,
300                'is_nfsv41_write_delegation_enabled': is_nfsv41_write_delegation_enabled,
301                'is_showmount_enabled': is_showmount_enabled,
302                'tcp_max_xfer_size': tcp_max_xfer_size
303            }
304        return nfs_details
305
306    def get_nfs_status(self):
307        """
308        Return status of nfs
309        :param:
310            name : Name of the vserver
311        :return: status of nfs. None if not found.
312        :rtype: bool
313        """
314        nfs_status = netapp_utils.zapi.NaElement('nfs-status')
315        result = self.server.invoke_successfully(nfs_status, True)
316        return_value = result.get_child_content('is-enabled')
317
318        return return_value
319
320    def enable_nfs(self):
321        """
322        enable nfs (online). If the NFS service was not explicitly created,
323        this API will create one with default options.
324        """
325        nfs_enable = netapp_utils.zapi.NaElement.create_node_with_children('nfs-enable')
326        try:
327            self.server.invoke_successfully(nfs_enable,
328                                            enable_tunneling=True)
329        except netapp_utils.zapi.NaApiError as error:
330            self.module.fail_json(msg='Error changing the service_state of nfs %s to %s: %s' %
331                                  (self.vserver, self.service_state, to_native(error)),
332                                  exception=traceback.format_exc())
333
334    def disable_nfs(self):
335        """
336        disable nfs (offline).
337        """
338        nfs_disable = netapp_utils.zapi.NaElement.create_node_with_children('nfs-disable')
339        try:
340            self.server.invoke_successfully(nfs_disable,
341                                            enable_tunneling=True)
342        except netapp_utils.zapi.NaApiError as error:
343            self.module.fail_json(msg='Error changing the service_state of nfs %s to %s: %s' %
344                                  (self.vserver, self.service_state, to_native(error)),
345                                  exception=traceback.format_exc())
346
347    def modify_nfs(self):
348        """
349        modify nfs service
350        """
351        nfs_modify = netapp_utils.zapi.NaElement('nfs-service-modify')
352        if self.nfsv3 == 'enabled':
353            nfs_modify.add_new_child('is-nfsv3-enabled', 'true')
354        elif self.nfsv3 == 'disabled':
355            nfs_modify.add_new_child('is-nfsv3-enabled', 'false')
356        if self.nfsv3_fsid_change == 'enabled':
357            nfs_modify.add_new_child('is-nfsv3-fsid-change-enabled', 'true')
358        elif self.nfsv3_fsid_change == 'disabled':
359            nfs_modify.add_new_child('is-nfsv3-fsid-change-enabled', 'false')
360        if self.nfsv4_fsid_change == 'enabled':
361            nfs_modify.add_new_child('is-nfsv4-fsid-change-enabled', 'true')
362        elif self.nfsv4_fsid_change == 'disabled':
363            nfs_modify.add_new_child('is-nfsv4-fsid-change-enabled', 'false')
364        if self.nfsv4 == 'enabled':
365            nfs_modify.add_new_child('is-nfsv40-enabled', 'true')
366        elif self.nfsv4 == 'disabled':
367            nfs_modify.add_new_child('is-nfsv40-enabled', 'false')
368        if self.nfsv41 == 'enabled':
369            nfs_modify.add_new_child('is-nfsv41-enabled', 'true')
370        elif self.nfsv41 == 'disabled':
371            nfs_modify.add_new_child('is-nfsv41-enabled', 'false')
372        if self.vstorage_state == 'enabled':
373            nfs_modify.add_new_child('is-vstorage-enabled', 'true')
374        elif self.vstorage_state == 'disabled':
375            nfs_modify.add_new_child('is-vstorage-enabled', 'false')
376        if self.tcp == 'enabled':
377            nfs_modify.add_new_child('is-tcp-enabled', 'true')
378        elif self.tcp == 'disabled':
379            nfs_modify.add_new_child('is-tcp-enabled', 'false')
380        if self.udp == 'enabled':
381            nfs_modify.add_new_child('is-udp-enabled', 'true')
382        elif self.udp == 'disabled':
383            nfs_modify.add_new_child('is-udp-enabled', 'false')
384        if self.nfsv40_acl == 'enabled':
385            nfs_modify.add_new_child('is-nfsv40-acl-enabled', 'true')
386        elif self.nfsv40_acl == 'disabled':
387            nfs_modify.add_new_child('is-nfsv40-acl-enabled', 'false')
388        if self.nfsv40_read_delegation == 'enabled':
389            nfs_modify.add_new_child('is-nfsv40-read-delegation-enabled', 'true')
390        elif self.nfsv40_read_delegation == 'disabled':
391            nfs_modify.add_new_child('is-nfsv40-read-delegation-enabled', 'false')
392        if self.nfsv40_referrals == 'enabled':
393            nfs_modify.add_new_child('is-nfsv40-referrals-enabled', 'true')
394        elif self.nfsv40_referrals == 'disabled':
395            nfs_modify.add_new_child('is-nfsv40-referrals-enabled', 'false')
396        if self.nfsv40_write_delegation == 'enabled':
397            nfs_modify.add_new_child('is-nfsv40-write-delegation-enabled', 'true')
398        elif self.nfsv40_write_delegation == 'disabled':
399            nfs_modify.add_new_child('is-nfsv40-write-delegation-enabled', 'false')
400        if self.nfsv41_acl == 'enabled':
401            nfs_modify.add_new_child('is-nfsv41-acl-enabled', 'true')
402        elif self.nfsv41_acl == 'disabled':
403            nfs_modify.add_new_child('is-nfsv41-acl-enabled', 'false')
404        if self.nfsv41_read_delegation == 'enabled':
405            nfs_modify.add_new_child('is-nfsv41-read-delegation-enabled', 'true')
406        elif self.nfsv41_read_delegation == 'disabled':
407            nfs_modify.add_new_child('is-nfsv41-read-delegation-enabled', 'false')
408        if self.nfsv41_referrals == 'enabled':
409            nfs_modify.add_new_child('is-nfsv41-referrals-enabled', 'true')
410        elif self.nfsv41_referrals == 'disabled':
411            nfs_modify.add_new_child('is-nfsv41-referrals-enabled', 'false')
412        if self.nfsv41_write_delegation == 'enabled':
413            nfs_modify.add_new_child('is-nfsv41-write-delegation-enabled', 'true')
414        elif self.nfsv41_write_delegation == 'disabled':
415            nfs_modify.add_new_child('is-nfsv41-write-delegation-enabled', 'false')
416        if self.nfsv41_pnfs == 'enabled':
417            nfs_modify.add_new_child('is-nfsv41-pnfs-enabled', 'true')
418        elif self.nfsv41_pnfs == 'disabled':
419            nfs_modify.add_new_child('is-nfsv41-pnfs-enabled', 'false')
420        if self.nfsv4_numeric_ids == 'enabled':
421            nfs_modify.add_new_child('is-nfsv4-numeric-ids-enabled', 'true')
422        elif self.nfsv4_numeric_ids == 'disabled':
423            nfs_modify.add_new_child('is-nfsv4-numeric-ids-enabled', 'false')
424        if self.showmount == 'enabled':
425            nfs_modify.add_new_child('showmount', 'true')
426        elif self.showmount == 'disabled':
427            nfs_modify.add_new_child('showmount', 'false')
428        if self.tcp_max_xfer_size is not None:
429            nfs_modify.add_new_child('tcp-max-xfer-size', str(self.tcp_max_xfer_size))
430        try:
431            self.server.invoke_successfully(nfs_modify,
432                                            enable_tunneling=True)
433        except netapp_utils.zapi.NaApiError as error:
434            self.module.fail_json(msg='Error modifying nfs: %s'
435                                  % (to_native(error)),
436                                  exception=traceback.format_exc())
437
438    def modify_nfsv4_id_domain(self):
439        """
440        modify nfs service
441        """
442        nfsv4_id_domain_modify = netapp_utils.zapi.NaElement.create_node_with_children(
443            'nfs-service-modify', **{'nfsv4-id-domain': self.nfsv4_id_domain})
444        if nfsv4_id_domain_modify is not None:
445            try:
446                self.server.invoke_successfully(nfsv4_id_domain_modify,
447                                                enable_tunneling=True)
448            except netapp_utils.zapi.NaApiError as error:
449                self.module.fail_json(msg='Error modifying nfs: %s'
450                                      % (to_native(error)),
451                                      exception=traceback.format_exc())
452
453    def delete_nfs(self):
454        """
455        delete nfs service.
456        """
457        nfs_delete = netapp_utils.zapi.NaElement.create_node_with_children('nfs-service-destroy')
458        try:
459            self.server.invoke_successfully(nfs_delete,
460                                            enable_tunneling=True)
461        except netapp_utils.zapi.NaApiError as error:
462            self.module.fail_json(msg='Error deleting nfs: %s' %
463                                  (to_native(error)),
464                                  exception=traceback.format_exc())
465
466    def apply(self):
467        """Apply action to nfs"""
468        changed = False
469        nfs_exists = False
470        modify_nfs = False
471        enable_nfs = False
472        disable_nfs = False
473        netapp_utils.ems_log_event("na_ontap_nfs", self.server)
474        nfs_enabled = self.get_nfs_status()
475        nfs_service_details = self.get_nfs_service()
476        is_nfsv4_id_domain_changed = False
477
478        def state_changed(expected, current):
479            if expected == "enabled" and current == "true":
480                return False
481            if expected == "disabled" and current == "false":
482                return False
483            return True
484
485        def is_modify_needed():
486            if (((self.nfsv3 is not None) and state_changed(self.nfsv3, nfs_service_details['is_nfsv3_enabled'])) or
487                ((self.nfsv3_fsid_change is not None) and state_changed(self.nfsv3_fsid_change, nfs_service_details['is_nfsv3_fsid_change_enabled'])) or
488                ((self.nfsv4_fsid_change is not None) and state_changed(self.nfsv4_fsid_change, nfs_service_details['is_nfsv4_fsid_change_enabled'])) or
489                ((self.nfsv4 is not None) and state_changed(self.nfsv4, nfs_service_details['is_nfsv40_enabled'])) or
490                ((self.nfsv41 is not None) and state_changed(self.nfsv41, nfs_service_details['is_nfsv41_enabled'])) or
491                ((self.nfsv41_pnfs is not None) and state_changed(self.nfsv41_pnfs, nfs_service_details['is_nfsv41_pnfs_enabled'])) or
492                ((self.nfsv4_numeric_ids is not None) and state_changed(self.nfsv4_numeric_ids, nfs_service_details['is_nfsv4_numeric_ids_enabled'])) or
493                ((self.tcp is not None) and state_changed(self.tcp, nfs_service_details['is_tcp_enabled'])) or
494                ((self.udp is not None) and state_changed(self.udp, nfs_service_details['is_udp_enabled'])) or
495                ((self.nfsv40_acl is not None) and state_changed(self.nfsv40_acl, nfs_service_details['is_nfsv40_acl_enabled'])) or
496                ((self.nfsv40_read_delegation is not None) and state_changed(self.nfsv40_read_delegation,
497                                                                             nfs_service_details['is_nfsv40_read_delegation_enabled'])) or
498                ((self.nfsv40_write_delegation is not None) and state_changed(self.nfsv40_write_delegation,
499                                                                              nfs_service_details['is_nfsv40_write_delegation_enabled'])) or
500                ((self.nfsv41_acl is not None) and state_changed(self.nfsv41_acl, nfs_service_details['is_nfsv41_acl_enabled'])) or
501                ((self.nfsv41_read_delegation is not None) and state_changed(self.nfsv41_read_delegation,
502                                                                             nfs_service_details['is_nfsv41_read_delegation_enabled'])) or
503                ((self.nfsv41_write_delegation is not None) and state_changed(self.nfsv41_write_delegation,
504                                                                              nfs_service_details['is_nfsv41_write_delegation_enabled'])) or
505                ((self.nfsv40_referrals is not None) and state_changed(self.nfsv40_referrals,
506                                                                       nfs_service_details['is_nfsv40_referrals_enabled'])) or
507                ((self.nfsv41_referrals is not None) and state_changed(self.nfsv41_referrals,
508                                                                       nfs_service_details['is_nfsv41_referrals_enabled'])) or
509                ((self.showmount is not None) and state_changed(self.showmount, nfs_service_details['is_showmount_enabled'])) or
510                    ((self.vstorage_state is not None) and state_changed(self.vstorage_state, nfs_service_details['is_vstorage_enabled'])) or
511                    ((self.tcp_max_xfer_size is not None) and int(self.tcp_max_xfer_size) != int(nfs_service_details['tcp_max_xfer_size']))):
512                return True
513            return False
514
515        def is_domain_changed():
516            if (self.nfsv4_id_domain is not None) and (self.nfsv4_id_domain != nfs_service_details['nfsv4_id_domain']):
517                return True
518            return False
519
520        if nfs_service_details:
521            nfs_exists = True
522            if self.state == 'absent':  # delete
523                changed = True
524            elif self.state == 'present':  # modify
525                if self.service_state == 'started' and nfs_enabled == 'false':
526                    enable_nfs = True
527                    changed = True
528                elif self.service_state == 'stopped' and nfs_enabled == 'true':
529                    disable_nfs = True
530                    changed = True
531                if is_modify_needed():
532                    modify_nfs = True
533                    changed = True
534                if is_domain_changed():
535                    is_nfsv4_id_domain_changed = True
536                    changed = True
537        else:
538            if self.state == 'present':  # create
539                changed = True
540        if changed:
541            if self.module.check_mode:
542                pass
543            else:
544                if self.state == 'present':  # execute create
545                    if not nfs_exists:
546                        self.enable_nfs()
547                        nfs_service_details = self.get_nfs_service()
548                        if self.service_state == 'stopped':
549                            self.disable_nfs()
550                        if is_modify_needed():
551                            self.modify_nfs()
552                        if is_domain_changed():
553                            self.modify_nfsv4_id_domain()
554                    else:
555                        if enable_nfs:
556                            self.enable_nfs()
557                        elif disable_nfs:
558                            self.disable_nfs()
559                        if modify_nfs:
560                            self.modify_nfs()
561                        if is_nfsv4_id_domain_changed:
562                            self.modify_nfsv4_id_domain()
563                elif self.state == 'absent':  # execute delete
564                    self.delete_nfs()
565
566        self.module.exit_json(changed=changed)
567
568
569def main():
570    """ Create object and call apply """
571    obj = NetAppONTAPNFS()
572    obj.apply()
573
574
575if __name__ == '__main__':
576    main()
577