1#!/usr/bin/python 2''' 3(c) 2018-2019, NetApp, Inc 4GNU General Public License v3.0+ 5(see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6''' 7 8from __future__ import absolute_import, division, print_function 9__metaclass__ = type 10 11ANSIBLE_METADATA = {'metadata_version': '1.1', 12 'status': ['preview'], 13 'supported_by': 'certified'} 14 15DOCUMENTATION = ''' 16 17module: na_ontap_ldap 18 19short_description: NetApp ONTAP LDAP 20extends_documentation_fragment: 21 - netapp.na_ontap 22version_added: '2.9' 23author: Milan Zink (@zeten30) <zeten30@gmail.com>/<mzink@redhat.com> 24 25description: 26- Create, modify or delete LDAP on NetApp ONTAP SVM/vserver 27 28options: 29 30 state: 31 description: 32 - Whether the LDAP is present or not. 33 choices: ['present', 'absent'] 34 default: 'present' 35 type: str 36 37 vserver: 38 description: 39 - vserver/svm configured to use LDAP 40 required: true 41 type: str 42 43 name: 44 description: 45 - The name of LDAP client configuration 46 required: true 47 type: str 48 49 skip_config_validation: 50 description: 51 - Skip LDAP validation 52 choices: ['true', 'false'] 53 type: str 54''' 55 56EXAMPLES = ''' 57 58 - name: Enable LDAP on SVM 59 na_ontap_ldap: 60 state: present 61 name: 'example_ldap' 62 vserver: 'vserver1' 63 hostname: "{{ netapp_hostname }}" 64 username: "{{ netapp_username }}" 65 password: "{{ netapp_password }}" 66 67''' 68 69RETURN = ''' 70''' 71 72import traceback 73import ansible.module_utils.netapp as netapp_utils 74from ansible.module_utils.basic import AnsibleModule 75from ansible.module_utils._text import to_native 76from ansible.module_utils.netapp_module import NetAppModule 77 78HAS_NETAPP_LIB = netapp_utils.has_netapp_lib() 79 80 81class NetAppOntapLDAP(object): 82 ''' 83 LDAP Client definition class 84 ''' 85 86 def __init__(self): 87 self.argument_spec = netapp_utils.na_ontap_host_argument_spec() 88 self.argument_spec.update(dict( 89 name=dict(required=True, type='str'), 90 skip_config_validation=dict(required=False, default=None, choices=['true', 'false']), 91 state=dict(required=False, choices=['present', 'absent'], default='present'), 92 vserver=dict(required=True, type='str') 93 )) 94 95 self.module = AnsibleModule( 96 argument_spec=self.argument_spec, 97 supports_check_mode=True 98 ) 99 self.na_helper = NetAppModule() 100 self.parameters = self.na_helper.set_parameters(self.module.params) 101 102 if HAS_NETAPP_LIB is False: 103 self.module.fail_json( 104 msg="the python NetApp-Lib module is required") 105 else: 106 self.server = netapp_utils.setup_na_ontap_zapi(module=self.module, vserver=self.parameters['vserver']) 107 108 def get_ldap(self, client_config_name=None): 109 ''' 110 Checks if LDAP config exists. 111 112 :return: 113 ldap config object if found 114 None if not found 115 :rtype: object/None 116 ''' 117 # Make query 118 config_info = netapp_utils.zapi.NaElement('ldap-config-get-iter') 119 120 if client_config_name is None: 121 client_config_name = self.parameters['name'] 122 123 query_details = netapp_utils.zapi.NaElement.create_node_with_children('ldap-config', **{'client-config': client_config_name}) 124 125 query = netapp_utils.zapi.NaElement('query') 126 query.add_child_elem(query_details) 127 config_info.add_child_elem(query) 128 129 result = self.server.invoke_successfully(config_info, enable_tunneling=True) 130 131 # Get LDAP configuration details 132 config_details = None 133 if (result.get_child_by_name('num-records') and int(result.get_child_content('num-records')) >= 1): 134 attributes_list = result.get_child_by_name('attributes-list') 135 config_info = attributes_list.get_child_by_name('ldap-config') 136 137 # Define config details structure 138 config_details = {'client_config': config_info.get_child_content('client-config'), 139 'skip_config_validation': config_info.get_child_content('skip-config-validation'), 140 'vserver': config_info.get_child_content('vserver')} 141 142 return config_details 143 144 def create_ldap(self): 145 ''' 146 Create LDAP configuration 147 ''' 148 options = { 149 'client-config': self.parameters['name'], 150 'client-enabled': 'true' 151 } 152 153 if self.parameters.get('skip_config_validation') is not None: 154 options['skip-config-validation'] = self.parameters['skip_config_validation'] 155 156 # Initialize NaElement 157 ldap_create = netapp_utils.zapi.NaElement.create_node_with_children('ldap-config-create', **options) 158 159 # Try to create LDAP configuration 160 try: 161 self.server.invoke_successfully(ldap_create, enable_tunneling=True) 162 except netapp_utils.zapi.NaApiError as errcatch: 163 self.module.fail_json(msg='Error creating LDAP configuration %s: %s' % (self.parameters['name'], to_native(errcatch)), 164 exception=traceback.format_exc()) 165 166 def delete_ldap(self): 167 ''' 168 Delete LDAP configuration 169 ''' 170 ldap_client_delete = netapp_utils.zapi.NaElement.create_node_with_children('ldap-config-delete', **{}) 171 172 try: 173 self.server.invoke_successfully(ldap_client_delete, enable_tunneling=True) 174 except netapp_utils.zapi.NaApiError as errcatch: 175 self.module.fail_json(msg='Error deleting LDAP configuration %s: %s' % ( 176 self.parameters['name'], to_native(errcatch)), exception=traceback.format_exc()) 177 178 def modify_ldap(self, modify): 179 ''' 180 Modify LDAP 181 :param modify: list of modify attributes 182 ''' 183 ldap_modify = netapp_utils.zapi.NaElement('ldap-config-modify') 184 ldap_modify.add_new_child('client-config', self.parameters['name']) 185 186 for attribute in modify: 187 if attribute == 'skip_config_validation': 188 ldap_modify.add_new_child('skip-config-validation', self.parameters[attribute]) 189 190 # Try to modify LDAP 191 try: 192 self.server.invoke_successfully(ldap_modify, enable_tunneling=True) 193 except netapp_utils.zapi.NaApiError as errcatch: 194 self.module.fail_json(msg='Error modifying LDAP %s: %s' % (self.parameters['name'], to_native(errcatch)), 195 exception=traceback.format_exc()) 196 197 def apply(self): 198 '''Call create/modify/delete operations.''' 199 current = self.get_ldap() 200 cd_action = self.na_helper.get_cd_action(current, self.parameters) 201 modify = self.na_helper.get_modified_attributes(current, self.parameters) 202 # create an ems log event for users with auto support turned on 203 netapp_utils.ems_log_event("na_ontap_ldap", self.server) 204 205 if self.na_helper.changed: 206 if self.module.check_mode: 207 pass 208 else: 209 if cd_action == 'create': 210 self.create_ldap() 211 elif cd_action == 'delete': 212 self.delete_ldap() 213 elif modify: 214 self.modify_ldap(modify) 215 self.module.exit_json(changed=self.na_helper.changed) 216 217 218# 219# MAIN 220# 221def main(): 222 '''ONTAP LDAP client configuration''' 223 ldapclient = NetAppOntapLDAP() 224 ldapclient.apply() 225 226 227if __name__ == '__main__': 228 main() 229