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 8__metaclass__ = type 9 10ANSIBLE_METADATA = {'metadata_version': '1.1', 11 'status': ['preview'], 12 'supported_by': 'certified'} 13 14DOCUMENTATION = ''' 15module: na_ontap_vscan 16short_description: NetApp ONTAP Vscan enable/disable. 17extends_documentation_fragment: 18 - netapp.na_ontap 19version_added: '2.9' 20author: NetApp Ansible Team (@carchi8py) <ng-ansibleteam@netapp.com> 21notes: 22- on demand task, on_access_policy and scanner_pools must be set up before running this module 23description: 24- Enable and Disable Vscan 25options: 26 enable: 27 description: 28 - Whether to enable to disable a Vscan 29 type: bool 30 default: True 31 32 vserver: 33 description: 34 - the name of the data vserver to use. 35 required: true 36 type: str 37''' 38 39EXAMPLES = """ 40 - name: Enable Vscan 41 na_ontap_vscan: 42 enable: True 43 username: '{{ netapp_username }}' 44 password: '{{ netapp_password }}' 45 hostname: '{{ netapp_hostname }}' 46 vserver: trident_svm 47 48 - name: Disable Vscan 49 na_ontap_vscan: 50 enable: False 51 username: '{{ netapp_username }}' 52 password: '{{ netapp_password }}' 53 hostname: '{{ netapp_hostname }}' 54 vserver: trident_svm 55""" 56 57RETURN = """ 58 59""" 60 61import traceback 62 63from ansible.module_utils.basic import AnsibleModule 64from ansible.module_utils._text import to_native 65import ansible.module_utils.netapp as netapp_utils 66from ansible.module_utils.netapp import OntapRestAPI 67from ansible.module_utils.netapp_module import NetAppModule 68 69HAS_NETAPP_LIB = netapp_utils.has_netapp_lib() 70 71 72class NetAppOntapVscan(object): 73 def __init__(self): 74 self.use_rest = False 75 self.argument_spec = netapp_utils.na_ontap_host_argument_spec() 76 self.argument_spec.update(dict( 77 enable=dict(type='bool', default=True), 78 vserver=dict(required=True, type='str'), 79 )) 80 self.module = AnsibleModule( 81 argument_spec=self.argument_spec, 82 supports_check_mode=True 83 ) 84 self.na_helper = NetAppModule() 85 self.parameters = self.na_helper.set_parameters(self.module.params) 86 87 # API should be used for ONTAP 9.6 or higher, Zapi for lower version 88 self.restApi = OntapRestAPI(self.module) 89 if self.restApi.is_rest(): 90 self.use_rest = True 91 else: 92 if HAS_NETAPP_LIB is False: 93 self.module.fail_json(msg="the python NetApp-Lib module is required") 94 else: 95 self.server = netapp_utils.setup_na_ontap_zapi(module=self.module, vserver=self.parameters['vserver']) 96 97 def get_vscan(self): 98 if self.use_rest: 99 params = {'fields': 'svm,enabled', 100 "svm.name": self.parameters['vserver']} 101 api = "protocols/vscan" 102 message, error = self.restApi.get(api, params) 103 if error: 104 self.module.fail_json(msg=error) 105 return message['records'][0] 106 else: 107 vscan_status_iter = netapp_utils.zapi.NaElement('vscan-status-get-iter') 108 vscan_status_info = netapp_utils.zapi.NaElement('vscan-status-info') 109 vscan_status_info.add_new_child('vserver', self.parameters['vserver']) 110 query = netapp_utils.zapi.NaElement('query') 111 query.add_child_elem(vscan_status_info) 112 vscan_status_iter.add_child_elem(query) 113 try: 114 result = self.server.invoke_successfully(vscan_status_iter, True) 115 except netapp_utils.zapi.NaApiError as error: 116 self.module.fail_json(msg='Error getting Vscan info for Vserver %s: %s' % 117 (self.parameters['vserver'], to_native(error)), 118 exception=traceback.format_exc()) 119 if result.get_child_by_name('num-records') and int(result.get_child_content('num-records')) >= 1: 120 return result.get_child_by_name('attributes-list').get_child_by_name('vscan-status-info') 121 122 def enable_vscan(self, uuid=None): 123 if self.use_rest: 124 params = {"svm.name": self.parameters['vserver']} 125 data = {"enabled": self.parameters['enable']} 126 api = "protocols/vscan/" + uuid 127 message, error = self.restApi.patch(api, data, params) 128 if error is not None: 129 self.module.fail_json(msg=error) 130 # self.module.fail_json(msg=repr(self.restApi.errors), log=repr(self.restApi.debug_logs)) 131 else: 132 vscan_status_obj = netapp_utils.zapi.NaElement("vscan-status-modify") 133 vscan_status_obj.add_new_child('is-vscan-enabled', str(self.parameters['enable'])) 134 try: 135 self.server.invoke_successfully(vscan_status_obj, True) 136 except netapp_utils.zapi.NaApiError as error: 137 self.module.fail_json(msg="Error Enable/Disabling Vscan: %s" % to_native(error), exception=traceback.format_exc()) 138 139 def asup_log(self): 140 if self.use_rest: 141 # TODO: logging for Rest 142 return 143 else: 144 # Either we are using ZAPI, or REST failed when it should not 145 try: 146 netapp_utils.ems_log_event("na_ontap_vscan", self.server) 147 except Exception: 148 # TODO: we may fail to connect to REST or ZAPI, the line below shows REST issues only 149 # self.module.fail_json(msg=repr(self.restApi.errors), log=repr(self.restApi.debug_logs)) 150 pass 151 152 def apply(self): 153 changed = False 154 self.asup_log() 155 current = self.get_vscan() 156 if self.use_rest: 157 if current['enabled'] != self.parameters['enable']: 158 if not self.module.check_mode: 159 self.enable_vscan(current['svm']['uuid']) 160 changed = True 161 else: 162 if current.get_child_content('is-vscan-enabled') != str(self.parameters['enable']).lower(): 163 if not self.module.check_mode: 164 self.enable_vscan() 165 changed = True 166 self.module.exit_json(changed=changed) 167 168 169def main(): 170 """ 171 Execute action from playbook 172 """ 173 command = NetAppOntapVscan() 174 command.apply() 175 176 177if __name__ == '__main__': 178 main() 179