1#!/usr/bin/python
2"""
3this is ipspace module
4
5# (c) 2018, NTT Europe Ltd.
6# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
7"""
8
9from __future__ import absolute_import, division, print_function
10__metaclass__ = type
11
12ANSIBLE_METADATA = {
13    'metadata_version': '1.1',
14    'status': ['preview'],
15    'supported_by': 'community'
16}
17
18DOCUMENTATION = '''
19---
20module: na_ontap_ipspace
21
22short_description: NetApp ONTAP Manage an ipspace
23
24version_added: '2.9'
25
26author:
27      - NTTE Storage Engineering (@vicmunoz) <cl.eng.sto@ntt.eu>
28
29description:
30      - Manage an ipspace for an Ontap Cluster
31
32extends_documentation_fragment:
33      - netapp.na_ontap
34
35options:
36    state:
37        description:
38            - Whether the specified ipspace should exist or not
39        choices: ['present', 'absent']
40        default: present
41    name:
42        description:
43            - The name of the ipspace to manage
44        required: true
45    from_name:
46        description:
47            - Name of the existing ipspace to be renamed to name
48'''
49
50EXAMPLES = """
51    - name: Create ipspace
52      na_ontap_ipspace:
53        state: present
54        name: ansibleIpspace
55        hostname: "{{ netapp_hostname }}"
56        username: "{{ netapp_username }}"
57        password: "{{ netapp_password }}"
58
59    - name: Delete ipspace
60      na_ontap_ipspace:
61        state: absent
62        name: ansibleIpspace
63        hostname: "{{ netapp_hostname }}"
64        username: "{{ netapp_username }}"
65        password: "{{ netapp_password }}"
66
67    - name: Rename ipspace
68      na_ontap_ipspace:
69        state: present
70        name: ansibleIpspace_newname
71        from_name: ansibleIpspace
72        hostname: "{{ netapp_hostname }}"
73        username: "{{ netapp_username }}"
74        password: "{{ netapp_password }}"
75"""
76
77RETURN = """
78"""
79
80import traceback
81
82import ansible.module_utils.netapp as netapp_utils
83from ansible.module_utils.netapp_module import NetAppModule
84from ansible.module_utils.basic import AnsibleModule
85from ansible.module_utils._text import to_native
86
87HAS_NETAPP_LIB = netapp_utils.has_netapp_lib()
88
89
90class NetAppOntapIpspace(object):
91    '''Class with ipspace operations'''
92
93    def __init__(self):
94        self.argument_spec = netapp_utils.na_ontap_host_argument_spec()
95        self.argument_spec.update(dict(
96            state=dict(
97                required=False, choices=['present', 'absent'],
98                default='present'),
99            name=dict(required=True, type='str'),
100            from_name=dict(required=False, type='str'),
101        ))
102        self.module = AnsibleModule(
103            argument_spec=self.argument_spec,
104            supports_check_mode=True
105        )
106
107        self.na_helper = NetAppModule()
108        self.parameters = self.na_helper.set_parameters(self.module.params)
109
110        if HAS_NETAPP_LIB is False:
111            self.module.fail_json(
112                msg="the python NetApp-Lib module is required")
113        else:
114            self.server = netapp_utils.setup_na_ontap_zapi(module=self.module)
115        return
116
117    def ipspace_get_iter(self, name):
118        """
119        Return net-ipspaces-get-iter query results
120        :param name: Name of the ipspace
121        :return: NaElement if ipspace found, None otherwise
122        """
123        ipspace_get_iter = netapp_utils.zapi.NaElement('net-ipspaces-get-iter')
124        query_details = netapp_utils.zapi.NaElement.create_node_with_children(
125            'net-ipspaces-info', **{'ipspace': name})
126        query = netapp_utils.zapi.NaElement('query')
127        query.add_child_elem(query_details)
128        ipspace_get_iter.add_child_elem(query)
129        try:
130            result = self.server.invoke_successfully(
131                ipspace_get_iter, enable_tunneling=False)
132        except netapp_utils.zapi.NaApiError as error:
133            # Error 14636 denotes an ipspace does not exist
134            # Error 13073 denotes an ipspace not found
135            if to_native(error.code) == "14636" or to_native(error.code) == "13073":
136                return None
137            else:
138                self.module.self.fail_json(
139                    msg=to_native(error),
140                    exception=traceback.format_exc())
141        return result
142
143    def get_ipspace(self, name=None):
144        """
145        Fetch details if ipspace exists
146        :param name: Name of the ipspace to be fetched
147        :return:
148            Dictionary of current details if ipspace found
149            None if ipspace is not found
150        """
151        if name is None:
152            name = self.parameters['name']
153        ipspace_get = self.ipspace_get_iter(name)
154        if (ipspace_get and ipspace_get.get_child_by_name('num-records') and
155                int(ipspace_get.get_child_content('num-records')) >= 1):
156            current_ipspace = dict()
157            attr_list = ipspace_get.get_child_by_name('attributes-list')
158            attr = attr_list.get_child_by_name('net-ipspaces-info')
159            current_ipspace['name'] = attr.get_child_content('ipspace')
160            return current_ipspace
161        return None
162
163    def create_ipspace(self):
164        """
165        Create ipspace
166        :return: None
167        """
168        ipspace_create = netapp_utils.zapi.NaElement.create_node_with_children(
169            'net-ipspaces-create', **{'ipspace': self.parameters['name']})
170        try:
171            self.server.invoke_successfully(ipspace_create,
172                                            enable_tunneling=False)
173        except netapp_utils.zapi.NaApiError as error:
174            self.module.self.fail_json(
175                msg="Error provisioning ipspace %s: %s" % (
176                    self.parameters['name'],
177                    to_native(error)),
178                exception=traceback.format_exc())
179
180    def delete_ipspace(self):
181        """
182        Destroy ipspace
183        :return: None
184        """
185        ipspace_destroy = netapp_utils.zapi.NaElement.create_node_with_children(
186            'net-ipspaces-destroy',
187            **{'ipspace': self.parameters['name']})
188        try:
189            self.server.invoke_successfully(
190                ipspace_destroy, enable_tunneling=False)
191        except netapp_utils.zapi.NaApiError as error:
192            self.module.self.fail_json(
193                msg="Error removing ipspace %s: %s" % (
194                    self.parameters['name'],
195                    to_native(error)),
196                exception=traceback.format_exc())
197
198    def rename_ipspace(self):
199        """
200        Rename an ipspace
201        :return: Nothing
202        """
203        ipspace_rename = netapp_utils.zapi.NaElement.create_node_with_children(
204            'net-ipspaces-rename',
205            **{'ipspace': self.parameters['from_name'],
206               'new-name': self.parameters['name']})
207        try:
208            self.server.invoke_successfully(ipspace_rename,
209                                            enable_tunneling=False)
210        except netapp_utils.zapi.NaApiError as error:
211            self.module.fail_json(
212                msg="Error renaming ipspace %s: %s" % (
213                    self.parameters['from_name'],
214                    to_native(error)),
215                exception=traceback.format_exc())
216
217    def apply(self):
218        """
219        Apply action to the ipspace
220        :return: Nothing
221        """
222        current = self.get_ipspace()
223        # rename and create are mutually exclusive
224        rename, cd_action = None, None
225        if self.parameters.get('from_name'):
226            rename = self.na_helper.is_rename_action(
227                self.get_ipspace(self.parameters['from_name']),
228                current)
229            if rename is None:
230                self.module.fail_json(
231                    msg="Error renaming: ipspace %s does not exist" %
232                    self.parameters['from_name'])
233        else:
234            cd_action = self.na_helper.get_cd_action(current, self.parameters)
235        if self.na_helper.changed:
236            if self.module.check_mode:
237                pass
238            else:
239                if rename:
240                    self.rename_ipspace()
241                elif cd_action == 'create':
242                    self.create_ipspace()
243                elif cd_action == 'delete':
244                    self.delete_ipspace()
245        self.module.exit_json(changed=self.na_helper.changed)
246
247
248def main():
249    """
250    Execute action
251    :return: nothing
252    """
253    obj = NetAppOntapIpspace()
254    obj.apply()
255
256
257if __name__ == '__main__':
258    main()
259