diff --git a/lib/ansible/modules/storage/netapp/na_ontap_svm.py b/lib/ansible/modules/storage/netapp/na_ontap_svm.py index 497aef1b3a2..7d6a15f9e89 100644 --- a/lib/ansible/modules/storage/netapp/na_ontap_svm.py +++ b/lib/ansible/modules/storage/netapp/na_ontap_svm.py @@ -17,14 +17,14 @@ DOCUMENTATION = ''' module: na_ontap_svm -short_description: Manage NetApp Ontap svm +short_description: Manage NetApp ONTAP svm extends_documentation_fragment: - netapp.na_ontap version_added: '2.6' -author: Sumit Kumar (sumit4@netapp.com), Archana Ganesan (garchana@netapp.com) +author: NetApp Ansible Team (ng-ansibleteam@netapp.com) description: -- Create, modify or delete svm on NetApp Ontap +- Create, modify or delete svm on NetApp ONTAP options: @@ -39,18 +39,20 @@ options: - The name of the SVM to manage. required: true - new_name: + from_name: description: - - New name of the SVM to be renamed + - Name of the SVM to be renamed + version_added: '2.7' root_volume: description: - - Root volume of the SVM. Required when C(state=present). + - Root volume of the SVM. + - Cannot be modified after creation. root_volume_aggregate: description: - The aggregate on which the root volume will be created. - - Required when C(state=present). + - Cannot be modified after creation. root_volume_security_style: description: @@ -61,7 +63,7 @@ options: this will return the list of matching Vservers. - The 'unified' security style, which applies only to Infinite Volumes, cannot be applied to a Vserver's root volume. - - Required when C(state=present) + - Cannot be modified after creation. choices: ['unix', 'ntfs', 'mixed', 'unified'] allowed_protocols: @@ -96,6 +98,72 @@ options: this will return the list of Vservers which have any of the aggregates specified as part of the aggr-list. + ipspace: + description: + - IPSpace name + - Cannot be modified after creation. + version_added: '2.7' + + + snapshot_policy: + description: + - Default snapshot policy setting for all volumes of the Vserver. + This policy will be assigned to all volumes created in this + Vserver unless the volume create request explicitly provides a + snapshot policy or volume is modified later with a specific + snapshot policy. A volume-level snapshot policy always overrides + the default Vserver-wide snapshot policy. + version_added: '2.7' + + language: + description: + - Language to use for the SVM + - Default to C.UTF-8 + - Possible values Language + - c POSIX + - ar Arabic + - cs Czech + - da Danish + - de German + - en English + - en_us English (US) + - es Spanish + - fi Finnish + - fr French + - he Hebrew + - hr Croatian + - hu Hungarian + - it Italian + - ja Japanese euc-j + - ja_v1 Japanese euc-j + - ja_jp.pck Japanese PCK (sjis) + - ja_jp.932 Japanese cp932 + - ja_jp.pck_v2 Japanese PCK (sjis) + - ko Korean + - no Norwegian + - nl Dutch + - pl Polish + - pt Portuguese + - ro Romanian + - ru Russian + - sk Slovak + - sl Slovenian + - sv Swedish + - tr Turkish + - zh Simplified Chinese + - zh.gbk Simplified Chinese (GBK) + - zh_tw Traditional Chinese euc-tw + - zh_tw.big5 Traditional Chinese Big 5 + version_added: '2.7' + + subtype: + description: + - The subtype for vserver to be created. + - Cannot be modified after creation. + choices: ['default', 'dp_destination', 'sync_source', 'sync_destination'] + version_added: '2.7' + + ''' EXAMPLES = """ @@ -132,7 +200,7 @@ class NetAppOntapSVM(object): state=dict(required=False, choices=[ 'present', 'absent'], default='present'), name=dict(required=True, type='str'), - new_name=dict(required=False, type='str'), + from_name=dict(required=False, type='str'), root_volume=dict(type='str'), root_volume_aggregate=dict(type='str'), root_volume_security_style=dict(type='str', choices=['unix', @@ -141,7 +209,11 @@ class NetAppOntapSVM(object): 'unified' ]), allowed_protocols=dict(type='list'), - aggr_list=dict(type='list') + aggr_list=dict(type='list'), + ipspace=dict(type='str', required=False), + snapshot_policy=dict(type='str', required=False), + language=dict(type='str', required=False), + subtype=dict(choices=['default', 'dp_destination', 'sync_source', 'sync_destination']) )) self.module = AnsibleModule( @@ -154,12 +226,16 @@ class NetAppOntapSVM(object): # set up state variables self.state = p['state'] self.name = p['name'] - self.new_name = p['new_name'] + self.from_name = p['from_name'] self.root_volume = p['root_volume'] self.root_volume_aggregate = p['root_volume_aggregate'] self.root_volume_security_style = p['root_volume_security_style'] self.allowed_protocols = p['allowed_protocols'] self.aggr_list = p['aggr_list'] + self.language = p['language'] + self.ipspace = p['ipspace'] + self.snapshot_policy = p['snapshot_policy'] + self.subtype = p['subtype'] if HAS_NETAPP_LIB is False: self.module.fail_json( @@ -167,19 +243,21 @@ class NetAppOntapSVM(object): else: self.server = netapp_utils.setup_na_ontap_zapi(module=self.module) - def get_vserver(self): + def get_vserver(self, vserver_name=None): """ Checks if vserver exists. :return: - True if vserver found - False if vserver is not found - :rtype: bool + vserver object if vserver found + None if vserver is not found + :rtype: object/None """ + if vserver_name is None: + vserver_name = self.name vserver_info = netapp_utils.zapi.NaElement('vserver-get-iter') query_details = netapp_utils.zapi.NaElement.create_node_with_children( - 'vserver-info', **{'vserver-name': self.name}) + 'vserver-info', **{'vserver-name': vserver_name}) query = netapp_utils.zapi.NaElement('query') query.add_child_elem(query_details) @@ -206,9 +284,14 @@ class NetAppOntapSVM(object): 'allowed-protocols').get_children() for protocol in get_protocols: protocols.append(protocol.get_content()) - vserver_details = {'name': vserver_info.get_child_content( - 'vserver-name'), + vserver_details = {'name': vserver_info.get_child_content('vserver-name'), + 'root_volume': vserver_info.get_child_content('root-volume'), + 'root_volume_aggregate': vserver_info.get_child_content('root-volume-aggregate'), + 'root_volume_security_style': vserver_info.get_child_content('root-volume-security-style'), + 'subtype': vserver_info.get_child_content('vserver-subtype'), 'aggr_list': aggr_list, + 'language': vserver_info.get_child_content('language'), + 'snapshot_policy': vserver_info.get_child_content('snapshot-policy'), 'allowed_protocols': protocols} return vserver_details @@ -218,6 +301,14 @@ class NetAppOntapSVM(object): options['root-volume-aggregate'] = self.root_volume_aggregate if self.root_volume_security_style is not None: options['root-volume-security-style'] = self.root_volume_security_style + if self.language is not None: + options['language'] = self.language + if self.ipspace is not None: + options['ipspace'] = self.ipspace + if self.snapshot_policy is not None: + options['snapshot-policy'] = self.snapshot_policy + if self.subtype is not None: + options['vserver-subtype'] = self.subtype vserver_create = netapp_utils.zapi.NaElement.create_node_with_children( 'vserver-create', **options) @@ -247,8 +338,8 @@ class NetAppOntapSVM(object): def rename_vserver(self): vserver_rename = netapp_utils.zapi.NaElement.create_node_with_children( - 'vserver-rename', **{'vserver-name': self.name, - 'new-name': self.new_name}) + 'vserver-rename', **{'vserver-name': self.from_name, + 'new-name': self.name}) try: self.server.invoke_successfully(vserver_rename, @@ -258,9 +349,16 @@ class NetAppOntapSVM(object): % (self.name, to_native(e)), exception=traceback.format_exc()) - def modify_vserver(self, allowed_protocols, aggr_list): + def modify_vserver(self, allowed_protocols, aggr_list, language, snapshot_policy): + + options = {'vserver-name': self.name} + if language: + options['language'] = self.language + if snapshot_policy: + options['snapshot-policy'] = self.snapshot_policy + vserver_modify = netapp_utils.zapi.NaElement.create_node_with_children( - 'vserver-modify', **{'vserver-name': self.name}) + 'vserver-modify', **options) if allowed_protocols: allowed_protocols = netapp_utils.zapi.NaElement( @@ -286,23 +384,25 @@ class NetAppOntapSVM(object): def apply(self): changed = False vserver_details = self.get_vserver() - if vserver_details is not None: - results = netapp_utils.get_cserver(self.server) - cserver = netapp_utils.setup_ontap_zapi( - module=self.module, vserver=results) - netapp_utils.ems_log_event("na_ontap_svm", cserver) +# These are being commentted out as part of bugfix 595. + +# if vserver_details is not None: +# results = netapp_utils.get_cserver(self.server) +# cserver = netapp_utils.setup_ontap_zapi( +# module=self.module, vserver=results) +# netapp_utils.ems_log_event("na_ontap_svm", cserver) rename_vserver = False modify_protocols = False modify_aggr_list = False - obj = open('vserver-log', 'a') + modify_snapshot_policy = False + modify_language = False + if vserver_details is not None: if self.state == 'absent': changed = True elif self.state == 'present': - if self.new_name is not None and self.new_name != self.name: - rename_vserver = True - changed = True + # SVM is present, is it a modify? if self.allowed_protocols is not None: self.allowed_protocols.sort() vserver_details['allowed_protocols'].sort() @@ -315,6 +415,24 @@ class NetAppOntapSVM(object): if self.aggr_list != vserver_details['aggr_list']: modify_aggr_list = True changed = True + if self.snapshot_policy is not None: + if self.snapshot_policy != vserver_details['snapshot_policy']: + modify_snapshot_policy = True + changed = True + if self.language is not None: + if self.language != vserver_details['language']: + modify_language = True + changed = True + if self.root_volume is not None and self.root_volume != vserver_details['root_volume']: + self.module.fail_json(msg='Error modifying SVM %s: %s' % (self.name, 'cannot change root volume')) + if self.root_volume_aggregate is not None and self.root_volume_aggregate != vserver_details['root_volume_aggregate']: + self.module.fail_json(msg='Error modifying SVM %s: %s' % (self.name, 'cannot change root volume aggregate')) + if self.root_volume_security_style is not None and self.root_volume_security_style != vserver_details['root_volume_security_style']: + self.module.fail_json(msg='Error modifying SVM %s: %s' % (self.name, 'cannot change root volume security style')) + if self.subtype is not None and self.subtype != vserver_details['subtype']: + self.module.fail_json(msg='Error modifying SVM %s: %s' % (self.name, 'cannot change subtype')) + if self.ipspace is not None and self.ipspace != vserver_details['ipspace']: + self.module.fail_json(msg='Error modifying SVM %s: %s' % (self.name, 'cannot change ipspace')) else: if self.state == 'present': changed = True @@ -324,13 +442,15 @@ class NetAppOntapSVM(object): else: if self.state == 'present': if vserver_details is None: - self.create_vserver() - else: - if rename_vserver: + # create or rename + if self.from_name is not None and self.get_vserver(self.from_name): self.rename_vserver() + else: + self.create_vserver() + else: if modify_protocols or modify_aggr_list: self.modify_vserver( - modify_protocols, modify_aggr_list) + modify_protocols, modify_aggr_list, modify_language, modify_snapshot_policy) elif self.state == 'absent': self.delete_vserver()