diff --git a/python/avi/sdk/samples/custom_dns_script_infoblox.py b/python/avi/sdk/samples/custom_dns_script_infoblox.py index 736993dbe9..86536a8243 100644 --- a/python/avi/sdk/samples/custom_dns_script_infoblox.py +++ b/python/avi/sdk/samples/custom_dns_script_infoblox.py @@ -87,8 +87,8 @@ def _verify_required_fields_in_auth_params(auth_params): """ logger = logging.getLogger(auth_params.get('logger_name', '')) missing_req_params = [] - if 'server' not in auth_params: - missing_req_params.append('server') + if 'server' not in auth_params and 'server6' not in auth_params: + missing_req_params.append('server and server6') if 'username' not in auth_params: missing_req_params.append('username') if 'password' not in auth_params: @@ -120,38 +120,79 @@ def _get_ips_by_host(auth_params, record_name, ip_type='V4_V6'): """ Function to return ips for a given record name. """ - username = auth_params.get('username') - password = auth_params.get('password') - server = auth_params.get('server') - wapi_version = auth_params.get('wapi_version') + username = auth_params.get('username',None) + password = auth_params.get('password',None) + server = auth_params.get('server',None) + server6 = auth_params.get('server6',None) + wapi_version = auth_params.get('wapi_version',None) dns_view = auth_params.get('dns_view', 'default') logger = logging.getLogger(auth_params.get('logger_name', '')) - rest_url = 'https://' + server + '/wapi/' + wapi_version + \ - '/record:host?name=' + record_name + '&view=' + dns_view + rest_url = 'https://' + server + '/wapi/' + wapi_version + '/record:host?name=' + record_name + '&view=' + dns_view if server else None + rest_url6 = 'https://[' + server6 + ']/wapi/' + wapi_version + '/record:host?name=' + record_name + '&view=' + dns_view if server6 else None ipaddrs = [] try: - r = requests.get(url=rest_url, auth=(username, password), verify=False) - _check_and_raise_auth_error(r) - logger.info("record_name[%s], GET req[%s] status_code[%s]" % (record_name, rest_url, r.status_code)) - r_json = r.json() - err_msg = str(r.status_code) - if r.status_code == 200: - if len(r_json) > 0: - if ip_type == 'V4_ONLY' or ip_type == 'V4_V6': - if 'ipv4addrs' in r_json[0] and len(r_json[0]['ipv4addrs']) > 0: - for ipv4addr in r_json[0]['ipv4addrs']: - ipaddrs.append(ipv4addr['ipv4addr']) - if ip_type == 'V6_ONLY' or ip_type == 'V4_V6': - if 'ipv6addrs' in r_json[0] and len(r_json[0]['ipv6addrs']) > 0: - for ipv6addr in r_json[0]['ipv6addrs']: - ipaddrs.append(ipv6addr['ipv6addr']) - return ipaddrs + if server6: + r6 = requests.get(url=rest_url6, auth=(username, password), verify=False) + logger.info("record_name[%s], GET req[%s] status_code[%s]" % (record_name, rest_url6, r6.status_code)) + r6_json = r6.json() + err_msg = str(r6.status_code) + if r6.status_code == 200: + if len(r6_json) > 0: + if ip_type == 'V4_ONLY' or ip_type == 'V4_V6': + if 'ipv4addrs' in r6_json[0] and len(r6_json[0]['ipv4addrs']) > 0: + for ipv4addr in r6_json[0]['ipv4addrs']: + ipaddrs.append(ipv4addr['ipv4addr']) + if ip_type == 'V6_ONLY' or ip_type == 'V4_V6': + if 'ipv6addrs' in r6_json[0] and len(r6_json[0]['ipv6addrs']) > 0: + for ipv6addr in r6_json[0]['ipv6addrs']: + ipaddrs.append(ipv6addr['ipv6addr']) + return ipaddrs + else: + err_msg += ": No host records found!" + elif server: + r = requests.get(url=rest_url, auth=(username, password), verify=False) + logger.info("record_name[%s], GET req[%s] status_code[%s]" % (record_name, rest_url, r.status_code)) + r_json = r.json() + err_msg = str(r.status_code) + if r.status_code == 200: + if len(r_json) > 0: + if ip_type == 'V4_ONLY' or ip_type == 'V4_V6': + if 'ipv4addrs' in r_json[0] and len(r_json[0]['ipv4addrs']) > 0: + for ipv4addr in r_json[0]['ipv4addrs']: + ipaddrs.append(ipv4addr['ipv4addr']) + if ip_type == 'V6_ONLY' or ip_type == 'V4_V6': + if 'ipv6addrs' in r_json[0] and len(r_json[0]['ipv6addrs']) > 0: + for ipv6addr in r_json[0]['ipv6addrs']: + ipaddrs.append(ipv6addr['ipv6addr']) + return ipaddrs + else: + err_msg += ": No host records found!" else: - err_msg += ": No host records found!" - else: - err_msg += ' : ' + r_json['text'] if 'text' in r_json else '' - raise CustomDnsGeneralException(err_msg) + err_msg += ' : ' + r6_json['text'] if 'text' in r6_json else '' + raise CustomDnsGeneralException(err_msg) + elif server: + r = requests.get(url=rest_url, auth=(username, password), verify=False) + _check_and_raise_auth_error(r) + logger.info("record_name[%s], GET req[%s] status_code[%s]" % (record_name, rest_url, r.status_code)) + r_json = r.json() + err_msg = str(r.status_code) + if r.status_code == 200: + if len(r_json) > 0: + if ip_type == 'V4_ONLY' or ip_type == 'V4_V6': + if 'ipv4addrs' in r_json[0] and len(r_json[0]['ipv4addrs']) > 0: + for ipv4addr in r_json[0]['ipv4addrs']: + ipaddrs.append(ipv4addr['ipv4addr']) + if ip_type == 'V6_ONLY' or ip_type == 'V4_V6': + if 'ipv6addrs' in r_json[0] and len(r_json[0]['ipv6addrs']) > 0: + for ipv6addr in r_json[0]['ipv6addrs']: + ipaddrs.append(ipv6addr['ipv6addr']) + return ipaddrs + else: + err_msg += ": No host records found!" + else: + err_msg += ' : ' + r_json['text'] if 'text' in r_json else '' + raise CustomDnsGeneralException(err_msg) except CustomDnsAuthenticationErrorException as e: raise except Exception as e: @@ -163,40 +204,79 @@ def _create_dns_record(auth_params, record_name, ips): """ Function to create a DNS record. """ - username = auth_params.get('username') - password = auth_params.get('password') - server = auth_params.get('server') - wapi_version = auth_params.get('wapi_version') + username = auth_params.get('username',None) + password = auth_params.get('password',None) + server = auth_params.get('server',None) + server6 = auth_params.get('server6',None) + wapi_version = auth_params.get('wapi_version',None) dns_view = auth_params.get('dns_view', 'default') logger = logging.getLogger(auth_params.get('logger_name', '')) ipv4addrs, ipv6addrs = _build_ipvxaddrs_objects(ips) - rest_url = 'https://' + server + '/wapi/' + wapi_version + '/record:host?_return_fields=ipv4addrs,ipv6addrs' + rest_url = 'https://' + server + '/wapi/' + wapi_version + '/record:host?_return_fields=ipv4addrs,ipv6addrs' if server else None + rest_url6 = 'https://[' + server6 + ']/wapi/' + wapi_version + '/record:host?_return_fields=ipv4addrs,ipv6addrs' if server6 else None payload = json.dumps({'name': record_name,'view': dns_view, 'ipv4addrs': ipv4addrs, 'ipv6addrs': ipv6addrs }) try: - r = requests.post(url=rest_url, auth=(username, password), + if server6: + r6 = requests.post(url=rest_url6, auth=(username, password), verify=False, data=payload) - _check_and_raise_auth_error(r) - logger.info("record_name[%s], POST req[%s %s] status_code[%s]" % (record_name, rest_url, payload, r.status_code)) - r_json = r.json() - if r.status_code == 200 or r.status_code == 201: - return - elif r.text and 'already exists' in r_json['text']: - host_ips = _get_ips_by_host(auth_params, record_name) - logger.info("record_name[%s], record ips on infoblox[%s]" %(record_name, host_ips)) - if set(ips['v4_ips']).issubset(set(host_ips)) and set(ips['v6_ips']).issubset(set(host_ips)): - logger.info("record name[%s] for ipv4addrs %s and ipv6addrs %s already exists."% - (record_name, ips['v4_ips'], ips['v6_ips'])) - else: - raise CustomDnsRecordAlreadyExistsException(r_json['text']) + _check_and_raise_auth_error(r6) + logger.info("record_name[%s], POST req[%s %s] status_code[%s]" % (record_name, rest_url6, payload, r6.status_code)) + r6_json = r6.json() + if r6.status_code == 200 or r6.status_code == 201: + return + elif r6.text and 'already exists' in r6_json['text']: + host_ips = _get_ips_by_host(auth_params, record_name) + logger.info("record_name[%s], record ips on infoblox[%s]" %(record_name, host_ips)) + if set(ips['v4_ips']).issubset(set(host_ips)) and set(ips['v6_ips']).issubset(set(host_ips)): + logger.info("record name[%s] for ipv4addrs %s and ipv6addrs %s already exists."% + (record_name, ips['v4_ips'], ips['v6_ips'])) + else: + raise CustomDnsRecordAlreadyExistsException(r6_json['text']) + elif server: + r = requests.post(url=rest_url, auth=(username, password), + verify=False, data=payload) + _check_and_raise_auth_error(r) + logger.info("record_name[%s], POST req[%s %s] status_code[%s]" % (record_name, rest_url, payload, r.status_code)) + r_json = r.json() + if r.status_code == 200 or r.status_code == 201: + return + elif r.text and 'already exists' in r_json['text']: + host_ips = _get_ips_by_host(auth_params, record_name) + logger.info("record_name[%s], record ips on infoblox[%s]" %(record_name, host_ips)) + if set(ips['v4_ips']).issubset(set(host_ips)) and set(ips['v6_ips']).issubset(set(host_ips)): + logger.info("record name[%s] for ipv4addrs %s and ipv6addrs %s already exists."% + (record_name, ips['v4_ips'], ips['v6_ips'])) + else: + raise CustomDnsRecordAlreadyExistsException(r_json['text']) + elif server: + r = requests.post(url=rest_url, auth=(username, password), + verify=False, data=payload) + _check_and_raise_auth_error(r) + logger.info("record_name[%s], POST req[%s %s] status_code[%s]" % (record_name, rest_url, payload, r.status_code)) + r_json = r.json() + if r.status_code == 200 or r.status_code == 201: + return + elif r.text and 'already exists' in r_json['text']: + host_ips = _get_ips_by_host(auth_params, record_name) + logger.info("record_name[%s], record ips on infoblox[%s]" %(record_name, host_ips)) + if set(ips['v4_ips']).issubset(set(host_ips)) and set(ips['v6_ips']).issubset(set(host_ips)): + logger.info("record name[%s] for ipv4addrs %s and ipv6addrs %s already exists."% + (record_name, ips['v4_ips'], ips['v6_ips'])) + else: + raise CustomDnsRecordAlreadyExistsException(r_json['text']) except CustomDnsAuthenticationErrorException as e: raise except CustomDnsRecordAlreadyExistsException as e: raise CustomDnsRecordAlreadyExistsException("record[%s] reason[%s]" %(record_name, str(e))) except Exception as e: - logger.error("Error creating dns record %s on Infoblox, req[%s %s] rsp[%s]" % - (record_name, rest_url, payload, str(e))) + if server6: + logger.error("Error creating dns record %s on Infoblox, req[%s %s] rsp[%s]" % + (record_name, rest_url6, payload, str(e))) + elif server: + logger.error("Error creating dns record %s on Infoblox, req[%s %s] rsp[%s]" % + (record_name, rest_url, payload, str(e))) raise CustomDnsGeneralException("Error creating dns record %s on Infoblox, reason[%s]" %(record_name, str(e))) @@ -204,10 +284,11 @@ def _update_dns_record(auth_params, record_name, ips): """ Function to update a given DNS record. """ - username = auth_params.get('username') - password = auth_params.get('password') - server = auth_params.get('server') - wapi_version = auth_params.get('wapi_version') + username = auth_params.get('username',None) + password = auth_params.get('password',None) + server = auth_params.get('server',None) + server6 = auth_params.get('server6',None) + wapi_version = auth_params.get('wapi_version',None) dns_view = auth_params.get('dns_view', 'default') logger = logging.getLogger(auth_params.get('logger_name', '')) @@ -216,88 +297,217 @@ def _update_dns_record(auth_params, record_name, ips): # Get the reference of the dns record host_ref = None - rest_url = 'https://' + server + '/wapi/' + wapi_version + '/record:host?name=' + record_name + rest_url = 'https://' + server + '/wapi/' + wapi_version + '/record:host?name=' + record_name if server else None + rest_url6 = 'https://[' + server6 + ']/wapi/' + wapi_version + '/record:host?name=' + record_name if server6 else None try: - r = requests.get(url=rest_url, auth=(username, password), verify=False) - _check_and_raise_auth_error(r) - logger.info("record_name[%s], GET req[%s] status_code[%s]" % (record_name, rest_url, r.status_code)) - r_json = r.json() - if r.status_code == 200: - host_ref = r_json[0]['_ref'] if len(r_json) > 0 and r_json[0]['_ref'] else None - else: - err_msg = str(r.status_code) + (' : ' + r_json['text'] if 'text' in r_json else '') - raise CustomDnsGeneralException(err_msg) + if server6: + r6 = requests.get(url=rest_url6, auth=(username, password), verify=False) + _check_and_raise_auth_error(r6) + logger.info("record_name[%s], GET req[%s] status_code[%s]" % (record_name, rest_url6, r6.status_code)) + r6_json = r6.json() + if r6.status_code == 200: + host_ref = r6_json[0]['_ref'] if len(r6_json) > 0 and r6_json[0]['_ref'] else None + # Raise an error message if the record not found + if not host_ref: + err_msg = "record[%s] not found!" % record_name + logger.error(err_msg) + raise CustomDnsRecordNotFoundException(err_msg) + + rest_url6 = 'https://[' + server6 + ']/wapi/' + wapi_version + '/' + host_ref + '?_return_fields=ipv4addrs,ipv6addrs' + try: + r6 = requests.put(url=rest_url6, auth=(username, password), + verify=False, data=payload) + _check_and_raise_auth_error(r6) + logger.info("record_name[%s], PUT req[%s %s] status_code[%s]" % (record_name, rest_url6, payload, r6.status_code)) + r6_json = r6.json() + if r6.status_code == 200 or r6.status_code == 201: + return + elif 'text' in r6_json: + raise CustomDnsGeneralException(r6_json['text']) + except CustomDnsAuthenticationErrorException as e: + raise + except Exception as e: + logger.error("Error updating dns record %s on Infoblox, req[%s %s] rsp[%s]" % + (record_name, rest_url6, payload, str(e))) + raise CustomDnsGeneralException("Error updating dns record %s on Infoblox, reason[%s]" %(record_name, str(e))) + elif server: + r = requests.get(url=rest_url, auth=(username, password), verify=False) + _check_and_raise_auth_error(r) + logger.info("record_name[%s], GET req[%s] status_code[%s]" % (record_name, rest_url, r.status_code)) + r_json = r.json() + if r.status_code == 200: + host_ref = r_json[0]['_ref'] if len(r_json) > 0 and r_json[0]['_ref'] else None + # Raise an error message if the record not found + if not host_ref: + err_msg = "record[%s] not found!" % record_name + logger.error(err_msg) + raise CustomDnsRecordNotFoundException(err_msg) + + rest_url = 'https://' + server + '/wapi/' + wapi_version + '/' + host_ref + '?_return_fields=ipv4addrs,ipv6addrs' + try: + r = requests.put(url=rest_url, auth=(username, password), + verify=False, data=payload) + _check_and_raise_auth_error(r) + logger.info("record_name[%s], PUT req[%s %s] status_code[%s]" % (record_name, rest_url, payload, r.status_code)) + r_json = r.json() + if r.status_code == 200 or r.status_code == 201: + return + elif 'text' in r_json: + raise CustomDnsGeneralException(r_json['text']) + except CustomDnsAuthenticationErrorException as e: + raise + except Exception as e: + logger.error("Error updating dns record %s on Infoblox, req[%s %s] rsp[%s]" % + (record_name, rest_url, payload, str(e))) + raise CustomDnsGeneralException("Error updating dns record %s on Infoblox, reason[%s]" %(record_name, str(e))) + else: + err_msg = str(r.status_code) + (' : ' + r_json['text'] if 'text' in r_json else '') + raise CustomDnsGeneralException(err_msg) + else: + err_msg = str(r6.status_code) + (' : ' + r6_json['text'] if 'text' in r6_json else '') + raise CustomDnsGeneralException(err_msg) + elif server: + r = requests.get(url=rest_url, auth=(username, password), verify=False) + _check_and_raise_auth_error(r) + logger.info("record_name[%s], GET req[%s] status_code[%s]" % (record_name, rest_url, r.status_code)) + r_json = r.json() + if r.status_code == 200: + host_ref = r_json[0]['_ref'] if len(r_json) > 0 and r_json[0]['_ref'] else None + # Raise an error message if the record not found + if not host_ref: + err_msg = "record[%s] not found!" % record_name + logger.error(err_msg) + raise CustomDnsRecordNotFoundException(err_msg) + + rest_url = 'https://' + server + '/wapi/' + wapi_version + '/' + host_ref + '?_return_fields=ipv4addrs,ipv6addrs' + try: + r = requests.put(url=rest_url, auth=(username, password), + verify=False, data=payload) + _check_and_raise_auth_error(r) + logger.info("record_name[%s], PUT req[%s %s] status_code[%s]" % (record_name, rest_url, payload, r.status_code)) + r_json = r.json() + if r.status_code == 200 or r.status_code == 201: + return + elif 'text' in r_json: + raise CustomDnsGeneralException(r_json['text']) + except CustomDnsAuthenticationErrorException as e: + raise + except Exception as e: + logger.error("Error updating dns record %s on Infoblox, req[%s %s] rsp[%s]" % + (record_name, rest_url, payload, str(e))) + raise CustomDnsGeneralException("Error updating dns record %s on Infoblox, reason[%s]" %(record_name, str(e))) + else: + err_msg = str(r.status_code) + (' : ' + r_json['text'] if 'text' in r_json else '') + raise CustomDnsGeneralException(err_msg) except CustomDnsAuthenticationErrorException as e: raise except Exception as e: logger.error("Error retrieving the record[%s] reason[%s]" % (record_name, str(e))) raise CustomDnsGeneralException("Error retrieving the record[%s] reason[%s]" % (record_name, str(e))) - - # Raise an error message if the record not found - if not host_ref: - err_msg = "record[%s] not found!" % record_name - logger.error(err_msg) - raise CustomDnsRecordNotFoundException(err_msg) - - rest_url = 'https://' + server + '/wapi/' + wapi_version + '/' + host_ref + '?_return_fields=ipv4addrs,ipv6addrs' - try: - r = requests.put(url=rest_url, auth=(username, password), - verify=False, data=payload) - _check_and_raise_auth_error(r) - logger.info("record_name[%s], PUT req[%s %s] status_code[%s]" % (record_name, rest_url, payload, r.status_code)) - r_json = r.json() - if r.status_code == 200 or r.status_code == 201: - return - elif 'text' in r_json: - raise CustomDnsGeneralException(r_json['text']) - except CustomDnsAuthenticationErrorException as e: - raise - except Exception as e: - logger.error("Error updating dns record %s on Infoblox, req[%s %s] rsp[%s]" % - (record_name, rest_url, payload, str(e))) - raise CustomDnsGeneralException("Error updating dns record %s on Infoblox, reason[%s]" %(record_name, str(e))) def _delete_dns_record(auth_params, record_name): """ Function to delete a given DNS record. """ - username = auth_params.get('username') - password = auth_params.get('password') - server = auth_params.get('server') - wapi_version = auth_params.get('wapi_version') + username = auth_params.get('username',None) + password = auth_params.get('password',None) + server = auth_params.get('server',None) + server6 = auth_params.get('server6',None) + wapi_version = auth_params.get('wapi_version',None) dns_view = auth_params.get('dns_view', 'default') logger = logging.getLogger(auth_params.get('logger_name', '')) - rest_url = 'https://' + server + '/wapi/' + wapi_version +'/record:host?name=' + record_name + rest_url = 'https://' + server + '/wapi/' + wapi_version +'/record:host?name=' + record_name + '&view=' + dns_view if server else None + rest_url6 = 'https://[' + server6 + ']/wapi/' + wapi_version +'/record:host?name=' + record_name + '&view=' + dns_view if server6 else None try: - # Get the reference of the dns record - r = requests.get(url=rest_url, auth=(username, password), verify=False) - _check_and_raise_auth_error(r) - logger.info("record_name[%s], GET req[%s] status_code[%s]" % (record_name, rest_url, r.status_code)) - r_json = r.json() - host_ref = None - err_msg = "record[%s] not found!" % record_name - if r.status_code == 200: - host_ref = r_json[0]['_ref'] if len(r_json) > 0 and r_json[0]['_ref'] else None - if not host_ref: - logger.info(err_msg) - return - - # Delete the record - rest_url = 'https://' + server + '/wapi/' + \ - wapi_version + '/' + host_ref - r = requests.delete(url=rest_url, auth=(username, password), verify=False) + if server6: + # Get the reference of the dns record + r6 = requests.get(url=rest_url6, auth=(username, password), verify=False) + _check_and_raise_auth_error(r6) + logger.info("record_name[%s], GET req[%s] status_code[%s]" % (record_name, rest_url6, r6.status_code)) + r6_json = r6.json() + host_ref = None + err_msg = "record[%s] not found!" % record_name + if r6.status_code == 200: + host_ref = r6_json[0]['_ref'] if len(r6_json) > 0 and r6_json[0]['_ref'] else None + if not host_ref: + logger.info(err_msg) + return + + # Delete the record + rest_url6 = 'https://[' + server6 + ']/wapi/' + \ + wapi_version + '/' + host_ref + r6 = requests.delete(url=rest_url6, auth=(username, password), verify=False) + _check_and_raise_auth_error(r6) + logger.info("record_name[%s], DELETE req[%s] status_code[%s]" % (record_name, rest_url6, r6.status_code)) + r6_json = r6.json() + if r6.status_code == 200: + return + else: + if 'text' in r6_json: + err_msg = str(r6.status_code) + BeautifulSoup(r6.text, 'html.parser').text + logger.error(err_msg) + raise CustomDnsGeneralException(err_msg) + elif server: + r = requests.get(url=rest_url, auth=(username, password), verify=False) + _check_and_raise_auth_error(r) + logger.info("record_name[%s], GET req[%s] status_code[%s]" % (record_name, rest_url, r.status_code)) + r_json = r.json() + host_ref = None + err_msg = "record[%s] not found!" % record_name + if r.status_code == 200: + host_ref = r_json[0]['_ref'] if len(r_json) > 0 and r_json[0]['_ref'] else None + if not host_ref: + logger.info(err_msg) + return + + # Delete the record + rest_url = 'https://' + server + '/wapi/' + \ + wapi_version + '/' + host_ref + r = requests.delete(url=rest_url, auth=(username, password), verify=False) + _check_and_raise_auth_error(r) + logger.info("record_name[%s], DELETE req[%s] status_code[%s]" % (record_name, rest_url, r.status_code)) + r_json = r.json() + if r.status_code == 200: + return + if 'text' in r_json: + err_msg = str(r.status_code) + BeautifulSoup(r.text, 'html.parser').text + logger.error(err_msg) + raise CustomDnsGeneralException(err_msg) + else: + if 'text' in r6_json: + err_msg = str(r6.status_code) + BeautifulSoup(r6.text, 'html.parser').text + logger.error(err_msg) + raise CustomDnsGeneralException(err_msg) + elif server: + # Get the reference of the dns record + r = requests.get(url=rest_url, auth=(username, password), verify=False) _check_and_raise_auth_error(r) - logger.info("record_name[%s], DELETE req[%s] status_code[%s]" % (record_name, rest_url, r.status_code)) + logger.info("record_name[%s], GET req[%s] status_code[%s]" % (record_name, rest_url, r.status_code)) r_json = r.json() + host_ref = None + err_msg = "record[%s] not found!" % record_name if r.status_code == 200: - return - if 'text' in r_json: - err_msg = str(r.status_code) + BeautifulSoup(r.text, 'html.parser').text - logger.error(err_msg) - raise CustomDnsGeneralException(err_msg) + host_ref = r_json[0]['_ref'] if len(r_json) > 0 and r_json[0]['_ref'] else None + if not host_ref: + logger.info(err_msg) + return + + # Delete the record + rest_url = 'https://' + server + '/wapi/' + \ + wapi_version + '/' + host_ref + r = requests.delete(url=rest_url, auth=(username, password), verify=False) + _check_and_raise_auth_error(r) + logger.info("record_name[%s], DELETE req[%s] status_code[%s]" % (record_name, rest_url, r.status_code)) + r_json = r.json() + if r.status_code == 200: + return + if 'text' in r_json: + err_msg = str(r.status_code) + BeautifulSoup(r.text, 'html.parser').text + logger.error(err_msg) + raise CustomDnsGeneralException(err_msg) except CustomDnsAuthenticationErrorException as e: raise except Exception as e: @@ -315,7 +525,8 @@ def TestLogin(auth_params): Parameters required for authentication. These are script parameters provided while creating a Custom DNS profile. Eg: auth_params can have following keys - server: Server ip address of the custom DNS provider + server: Server IPv4 address of the custom DNS provider + server6: Server IPv6 address of the custom DNS provider username: self explanatory password: self explanatory logger_name: logger name @@ -334,22 +545,32 @@ def TestLogin(auth_params): tmp_auth_params['password'] = '' logger.info("Inside F[TestLogin] auth_params[%s]", tmp_auth_params) server = auth_params.get('server', None) + server6 = auth_params.get('server6', None) username = auth_params.get('username', None) password = auth_params.get('password', None) wapi_version = auth_params.get('wapi_version', None) - if not server or not username or not password or not wapi_version: + if not (server or server6) or not username or not password or not wapi_version: raise CustomDnsGeneralException("F[TestLogin] all credentials are not provided") + schema_url = 'https://' + server + '/wapi/' + wapi_version + '/?_schema' if server else None + schema_url6 = 'https://[' + server6 + ']/wapi/' + wapi_version + '/?_schema' if server6 else None + auth = (username, password) try: - schema_url = 'https://' + server + \ - '/wapi/' + wapi_version + '/?_schema' - auth = (username, password) - r = requests.get( - url=schema_url, auth=auth, verify=False, timeout=30) - logger.info("F[TestLogin] req[%s] status_code[%s]" % (schema_url, r.status_code)) - if r.status_code == 200: + r = None + r6 = None + if server: + r = requests.get(url=schema_url, auth=auth, verify=False, timeout=30) + logger.info("F[TestLogin] req[%s] status_code[%s]" % (schema_url, r.status_code)) + if server6: + r6 = requests.get(url=schema_url6, auth=auth, verify=False, timeout=30) + logger.info("F[TestLogin] req[%s] status_code[%s]" % (schema_url6, r6.status_code)) + if (not r or r.status_code == 200) and (not r6 or r6.status_code == 200): return True - _check_and_raise_auth_error(r) + else: + if server: + _check_and_raise_auth_error(r) + if server6: + _check_and_raise_auth_error(r6) except CustomDnsAuthenticationErrorException as e: raise except Exception as e: diff --git a/python/avi/sdk/samples/custom_ipam_script_infoblox.py b/python/avi/sdk/samples/custom_ipam_script_infoblox.py index a32a6cc7a6..6215265ee6 100644 --- a/python/avi/sdk/samples/custom_ipam_script_infoblox.py +++ b/python/avi/sdk/samples/custom_ipam_script_infoblox.py @@ -37,7 +37,7 @@ import time import logging import copy -from itertools import product +import json from bs4 import BeautifulSoup class CustomIpamAuthenticationErrorException(Exception): @@ -73,8 +73,8 @@ class CustomIpamGeneralException(Exception): def _verify_required_fields_in_auth_params(auth_params): missing_req_params = [] - if 'server' not in auth_params: - missing_req_params.append('server') + if 'server' not in auth_params and 'server6' not in auth_params: + missing_req_params.append('server and server6') if 'username' not in auth_params: missing_req_params.append('username') if 'password' not in auth_params: @@ -92,7 +92,7 @@ def _check_and_raise_auth_error(response): raise CustomIpamAuthenticationErrorException(response.reason, response.status_code, response.url, text) -def _get_api_paginated(auth_params, dest_url, data_key, results_per_page, api_timeout, ip_type): +def _get_api_paginated(auth_params, dest_url, dest_url6, data_key, results_per_page, api_timeout, ip_type): """ Function used to return paginated response for a given dest_url. @@ -102,7 +102,9 @@ def _get_api_paginated(auth_params, dest_url, data_key, results_per_page, api_ti auth_params: (dict of str: str) Parameters required for authentication. dest_url: (str) - URL for which pagination is desired. + IPv4 based URL for which pagination is desired. + dest_url6: (str) + IPv6 based URL for which pagination is desired. data_key: (str) Dictionary key to look for in the results. results_per_page: (str) @@ -124,45 +126,135 @@ def _get_api_paginated(auth_params, dest_url, data_key, results_per_page, api_ti logger = logging.getLogger(auth_params.get('logger_name', '')) data_vals = [] network_view = auth_params.get('network_view', 'default') - page_url = dest_url + '&_paging=1&_max_results=%d&_return_as_object=1' % results_per_page - r = requests.get( - url=page_url, auth=(auth_params['username'], auth_params['password']), verify=False, timeout=30) - logger.info("F[_get_api_paginated] req[%s] status_code[%s]" % (page_url, r.status_code)) - _check_and_raise_auth_error(r) - if r.status_code == 200: - resp = r.json() - for unit in resp['result']: - if data_key not in unit: - continue - sub_value = unit[data_key] - # Since infoblox doesn't return network values, dummy value can be given to nw_id - # from here or from UI during IPAM profile configuration. - nw_id = 'infoblox--' + network_view + '--' - v4_subnet = v6_subnet = None - if ip_type == 'V4_ONLY': - v4_subnet = sub_value - nw_id += v4_subnet.split('/')[0] + '-' + str(v4_subnet.split('/')[1]) - elif ip_type == 'V6_ONLY': - v6_subnet = sub_value - nw_id += v6_subnet.split('/')[0] + '-' + str(v6_subnet.split('/')[1]) - data_vals.append({'network': nw_id, 'v4_subnet': v4_subnet, 'v6_subnet': v6_subnet}) - - next_page_id = resp.get('next_page_id', '') - page_start_time = time.time() - elapsed_time = 0 - while next_page_id and elapsed_time < api_timeout: - page_url = dest_url + '&_page_id=%s' % next_page_id + if 'server' in auth_params: + page_url = dest_url + '&_paging=1&_max_results=%d&_return_as_object=1' % results_per_page + if 'server6' in auth_params: + page_url6 = dest_url6 + '&_paging=1&_max_results=%d&_return_as_object=1' % results_per_page + + if 'server6' in auth_params: + r6 = requests.get( + url=page_url6, auth=(auth_params['username'], auth_params['password']), verify=False, timeout=30) + logger.info("F[_get_api_paginated] req[%s] status_code[%s]" % (page_url6, r6.status_code)) + _check_and_raise_auth_error(r6) + if r6.status_code == 200: + resp = r6.json() + for unit in resp['result']: + if data_key not in unit: + continue + sub_value = unit[data_key] + # Since infoblox doesn't return network values, dummy value can be given to nw_id + # from here or from UI during IPAM profile configuration. + nw_id = 'infoblox--' + network_view + '--' + v4_subnet = v6_subnet = None + if ip_type == 'V4_ONLY': + v4_subnet = sub_value + nw_id += v4_subnet.split('/')[0] + '-' + str(v4_subnet.split('/')[1]) + elif ip_type == 'V6_ONLY': + v6_subnet = sub_value + nw_id += v6_subnet.split('/')[0] + '-' + str(v6_subnet.split('/')[1]) + data_vals.append({'network': nw_id, 'v4_subnet': v4_subnet, 'v6_subnet': v6_subnet}) + + next_page_id = resp.get('next_page_id', '') + page_start_time = time.time() + elapsed_time = 0 + while next_page_id and elapsed_time < api_timeout: + page_url6 = dest_url6 + '&_page_id=%s' % next_page_id + r6 = requests.get( + url=page_url6, auth=(auth_params['username'], auth_params['password']), verify=False, timeout=30) + logger.info("F[_get_api_paginated] req[%s] status_code[%s]" % (page_url6, r6.status_code)) + _check_and_raise_auth_error(r6) + if r6.status_code != 200: + break + resp = r6.json() + for unit in resp['result']: + if data_key not in unit: + continue + sub_value = unit[data_key] + nw_id = 'infoblox--' + network_view + '--' + v4_subnet = v6_subnet = None + if ip_type == 'V4_ONLY': + v4_subnet = sub_value + nw_id += v4_subnet.split('/')[0] + '-' + str(v4_subnet.split('/')[1]) + elif ip_type == 'V6_ONLY': + v6_subnet = sub_value + nw_id += v6_subnet.split('/')[0] + '-' + str(v6_subnet.split('/')[1]) + data_vals.append({'network': nw_id, 'v4_subnet': v4_subnet, 'v6_subnet': v6_subnet}) + + next_page_id = resp.get('next_page_id', '') + elapsed_time = int(time.time() - page_start_time) + return data_vals + elif 'server' in auth_params: r = requests.get( url=page_url, auth=(auth_params['username'], auth_params['password']), verify=False, timeout=30) logger.info("F[_get_api_paginated] req[%s] status_code[%s]" % (page_url, r.status_code)) _check_and_raise_auth_error(r) - if r.status_code != 200: - break + if r.status_code == 200: + resp = r.json() + for unit in resp['result']: + if data_key not in unit: + continue + sub_value = unit[data_key] + # Since infoblox doesn't return network values, dummy value can be given to nw_id + # from here or from UI during IPAM profile configuration. + nw_id = 'infoblox--' + network_view + '--' + v4_subnet = v6_subnet = None + if ip_type == 'V4_ONLY': + v4_subnet = sub_value + nw_id += v4_subnet.split('/')[0] + '-' + str(v4_subnet.split('/')[1]) + elif ip_type == 'V6_ONLY': + v6_subnet = sub_value + nw_id += v6_subnet.split('/')[0] + '-' + str(v6_subnet.split('/')[1]) + data_vals.append({'network': nw_id, 'v4_subnet': v4_subnet, 'v6_subnet': v6_subnet}) + + next_page_id = resp.get('next_page_id', '') + page_start_time = time.time() + elapsed_time = 0 + while next_page_id and elapsed_time < api_timeout: + page_url = dest_url + '&_page_id=%s' % next_page_id + r = requests.get( + url=page_url, auth=(auth_params['username'], auth_params['password']), verify=False, timeout=30) + logger.info("F[_get_api_paginated] req[%s] status_code[%s]" % (page_url, r.status_code)) + _check_and_raise_auth_error(r) + if r.status_code != 200: + break + resp = r.json() + for unit in resp['result']: + if data_key not in unit: + continue + sub_value = unit[data_key] + nw_id = 'infoblox--' + network_view + '--' + v4_subnet = v6_subnet = None + if ip_type == 'V4_ONLY': + v4_subnet = sub_value + nw_id += v4_subnet.split('/')[0] + '-' + str(v4_subnet.split('/')[1]) + elif ip_type == 'V6_ONLY': + v6_subnet = sub_value + nw_id += v6_subnet.split('/')[0] + '-' + str(v6_subnet.split('/')[1]) + data_vals.append({'network': nw_id, 'v4_subnet': v4_subnet, 'v6_subnet': v6_subnet}) + + next_page_id = resp.get('next_page_id', '') + elapsed_time = int(time.time() - page_start_time) + return data_vals + err_msg = r.status_code + ' : ' + r.text + logger.error("F[GetAvailableNetworksAndSubnets] req[%s] ip_type[%s] err[%s]" % (page_url, ip_type, err_msg)) + raise CustomIpamGeneralException("F[GetAvailableNetworksAndSubnets] req[%s] ip_type[%s] err[%s]" % (page_url, ip_type, err_msg)) + else: + err_msg = r6.status_code + ' : ' + r6.text + logger.error("F[GetAvailableNetworksAndSubnets] req[%s] ip_type[%s] err[%s]" % (page_url6, ip_type, err_msg)) + raise CustomIpamGeneralException("F[GetAvailableNetworksAndSubnets] req[%s] ip_type[%s] err[%s]" % (page_url6, ip_type, err_msg)) + elif 'server' in auth_params: + r = requests.get( + url=page_url, auth=(auth_params['username'], auth_params['password']), verify=False, timeout=30) + logger.info("F[_get_api_paginated] req[%s] status_code[%s]" % (page_url, r.status_code)) + _check_and_raise_auth_error(r) + if r.status_code == 200: resp = r.json() for unit in resp['result']: if data_key not in unit: continue sub_value = unit[data_key] + # Since infoblox doesn't return network values, dummy value can be given to nw_id + # from here or from UI during IPAM profile configuration. nw_id = 'infoblox--' + network_view + '--' v4_subnet = v6_subnet = None if ip_type == 'V4_ONLY': @@ -174,11 +266,37 @@ def _get_api_paginated(auth_params, dest_url, data_key, results_per_page, api_ti data_vals.append({'network': nw_id, 'v4_subnet': v4_subnet, 'v6_subnet': v6_subnet}) next_page_id = resp.get('next_page_id', '') - elapsed_time = int(time.time() - page_start_time) - return data_vals - err_msg = r.status_code + ' : ' + r.text - logger.error("F[GetAvailableNetworksAndSubnets] req[%s] ip_type[%s] err[%s]" % (page_url, ip_type, err_msg)) - raise CustomIpamGeneralException("F[GetAvailableNetworksAndSubnets] req[%s] ip_type[%s] err[%s]" % (page_url, ip_type, err_msg)) + page_start_time = time.time() + elapsed_time = 0 + while next_page_id and elapsed_time < api_timeout: + page_url = dest_url + '&_page_id=%s' % next_page_id + r = requests.get( + url=page_url, auth=(auth_params['username'], auth_params['password']), verify=False, timeout=30) + logger.info("F[_get_api_paginated] req[%s] status_code[%s]" % (page_url, r.status_code)) + _check_and_raise_auth_error(r) + if r.status_code != 200: + break + resp = r.json() + for unit in resp['result']: + if data_key not in unit: + continue + sub_value = unit[data_key] + nw_id = 'infoblox--' + network_view + '--' + v4_subnet = v6_subnet = None + if ip_type == 'V4_ONLY': + v4_subnet = sub_value + nw_id += v4_subnet.split('/')[0] + '-' + str(v4_subnet.split('/')[1]) + elif ip_type == 'V6_ONLY': + v6_subnet = sub_value + nw_id += v6_subnet.split('/')[0] + '-' + str(v6_subnet.split('/')[1]) + data_vals.append({'network': nw_id, 'v4_subnet': v4_subnet, 'v6_subnet': v6_subnet}) + + next_page_id = resp.get('next_page_id', '') + elapsed_time = int(time.time() - page_start_time) + return data_vals + err_msg = r.status_code + ' : ' + r.text + logger.error("F[GetAvailableNetworksAndSubnets] req[%s] ip_type[%s] err[%s]" % (page_url, ip_type, err_msg)) + raise CustomIpamGeneralException("F[GetAvailableNetworksAndSubnets] req[%s] ip_type[%s] err[%s]" % (page_url, ip_type, err_msg)) def GetIpamRecord(auth_params, record_info): @@ -219,7 +337,8 @@ def TestLogin(auth_params): Parameters required for authentication. These are script parameters provided while creating a Custom IPAM profile. Eg: auth_params can have following keys - server: Server ip address of the custom IPAM provider + server: Server IPv4 address of the custom IPAM provider + server6: Server IPv6 address of the custom IPAM provider username: self explanatory password: self explanatory logger_name: logger name @@ -238,22 +357,34 @@ def TestLogin(auth_params): tmp_auth_params['password'] = '' logger.info("Inside F[TestLogin] auth_params[%s]", tmp_auth_params) server = auth_params.get('server', None) + server6 = auth_params.get('server6', None) username = auth_params.get('username', None) password = auth_params.get('password', None) wapi_version = auth_params.get('wapi_version', None) - if not server or not username or not password or not wapi_version: + if not (server or server6) or not username or not password or not wapi_version: raise CustomIpamGeneralException("F[TestLogin] all credentials are not provided") + schema_url = 'https://' + server + '/wapi/' + wapi_version + '/?_schema' if server else None + schema_url6 = 'https://[' + server6 + ']/wapi/' + wapi_version + '/?_schema' if server6 else None + auth = (username, password) try: - schema_url = 'https://' + server + \ - '/wapi/' + wapi_version + '/?_schema' - auth = (username, password) - r = requests.get( - url=schema_url, auth=auth, verify=False, timeout=30) - logger.info("F[TestLogin] req[%s] status_code[%s]" % (schema_url, r.status_code)) - if r.status_code == 200: + r = None + r6 = None + if server: + r = requests.get(url=schema_url, auth=auth, verify=False, timeout=30) + logger.info("F[TestLogin] req[%s] status_code[%s]" % (schema_url, r.status_code)) + if server6: + r6 = requests.get(url=schema_url6, auth=auth, verify=False, timeout=30) + logger.info("F[TestLogin] req[%s] status_code[%s]" % (schema_url6, r6.status_code)) + if (not r or r.status_code == 200) and (not r6 or r6.status_code == 200): return True - _check_and_raise_auth_error(r) + else: + if server: + _check_and_raise_auth_error(r) + if server6: + _check_and_raise_auth_error(r6) + except CustomIpamAuthenticationErrorException as e: + raise except Exception as e: raise CustomIpamGeneralException("F[TestLogin] login failed reason[%s]" % str(e)) @@ -290,19 +421,24 @@ def GetAvailableNetworksAndSubnets(auth_params, ip_type): tmp_auth_params['password'] = '' logger.info("Inside F[GetAvailableNetworksAndSubnets] auth_params[%s] ip_type[%s]", tmp_auth_params, ip_type) network_view = auth_params.get('network_view', 'default') - base_url = 'https://' + auth_params['server'] + '/wapi/' + auth_params['wapi_version'] + if 'server' in auth_params: + base_url = 'https://' + auth_params['server'] + '/wapi/' + auth_params['wapi_version'] + if 'server6' in auth_params: + base_url6 = 'https://[' + auth_params['server6'] + ']/wapi/' + auth_params['wapi_version'] data_key = 'network' results_per_page = 1000 api_timeout = 600 subnet_list = [] if ip_type in ['V4_ONLY', 'V4_V6']: - rest_url = base_url + '/network?network_view=' + network_view - v4_subnets = _get_api_paginated(auth_params, rest_url, data_key, results_per_page, api_timeout, 'V4_ONLY') + rest_url = base_url + '/network?network_view=' + network_view if 'server' in auth_params else None + rest_url6 = base_url6 + '/network?network_view=' + network_view if 'server6' in auth_params else None + v4_subnets = _get_api_paginated(auth_params, rest_url, rest_url6, data_key, results_per_page, api_timeout, 'V4_ONLY') subnet_list.extend(v4_subnets) if ip_type in ['V6_ONLY', 'V4_V6']: - rest_url = base_url + '/ipv6network?network_view=' + network_view - v6_subnets = _get_api_paginated(auth_params, rest_url, data_key, results_per_page, api_timeout, 'V6_ONLY') + rest_url = base_url + '/ipv6network?network_view=' + network_view if 'server' in auth_params else None + rest_url6 = base_url6 + '/ipv6network?network_view=' + network_view if 'server6' in auth_params else None + v6_subnets = _get_api_paginated(auth_params, rest_url, rest_url6, data_key, results_per_page, api_timeout, 'V6_ONLY') subnet_list.extend(v6_subnets) return subnet_list @@ -344,7 +480,7 @@ def CreateIpamRecord(auth_params, record_info): tmp_auth_params['password'] = '' logger.info("Inside F[CreateIpamRecord] auth_params[%s] record_info[%s]", tmp_auth_params, record_info) network_view = auth_params.get('network_view', 'default') - dns_view = auth_params.get('dns_view', 'default') + dns_view = auth_params.get('dns_view', None) id = record_info.get('id', None) fqdns = record_info.get('fqdns', None) allocation_type = record_info.get('allocation_type', None) @@ -353,8 +489,12 @@ def CreateIpamRecord(auth_params, record_info): preferred_ip6 = record_info.get('preferred_ip6', None) name = id - base_uri = 'https://' + auth_params['server'] + '/wapi/' + auth_params['wapi_version'] - rest_url = base_uri + '/record:host?_return_fields=ipv4addrs,ipv6addrs' + if 'server' in auth_params: + base_uri = 'https://' + auth_params['server'] + '/wapi/' + auth_params['wapi_version'] + rest_url = base_uri + '/record:host?_return_fields=ipv4addrs,ipv6addrs' + if 'server6' in auth_params: + base_uri6 = 'https://[' + auth_params['server6'] + ']/wapi/' + auth_params['wapi_version'] + rest_url6 = base_uri6 + '/record:host?_return_fields=ipv4addrs,ipv6addrs' # Step 1: If the preferred_ip/preferred_ip6 is set, call specific rest URL according to the allocation_type. # @@ -380,29 +520,69 @@ def CreateIpamRecord(auth_params, record_info): v4_subnet = sub[1] v6_subnet = sub[2] if v4_subnet and v6_subnet: - nw_str_ip4 = 'func:nextavailableip:' + v4_subnet + ',' + network_view - nw_str_ip6 = 'func:nextavailableip:' + v6_subnet + ',' + network_view - payload = '{"ipv4addrs": [{"ipv4addr": "' + nw_str_ip4 + '"}], "ipv6addrs": [{"ipv6addr": "' + nw_str_ip6 + '"}], "name": "' + \ - name + '","configure_for_dns": false,"view": "' + dns_view + '"}' + ipv4addrs = [{"ipv4addr": 'func:nextavailableip:' + v4_subnet + ',' + network_view}] + ipv6addrs = [{"ipv6addr": 'func:nextavailableip:' + v6_subnet + ',' + network_view}] + payload = json.dumps({'name': name, 'view': dns_view, 'configure_for_dns':False, 'ipv4addrs': ipv4addrs, 'ipv6addrs': ipv6addrs}) else: continue - r = requests.post(url=rest_url, auth=(auth_params['username'], auth_params['password']), + #HA code for ipv6 and ipv4 addresses + if 'server6' in auth_params: + r6 = requests.post(url=rest_url6, auth=(auth_params['username'], auth_params['password']), verify=False, data=payload) - logger.info("F[CreateIpamRecord] req[%s %s] status_code[%s]" % (rest_url, payload, r.status_code)) - _check_and_raise_auth_error(r) - if r.status_code not in [200, 201]: - emsg = "req[%s %s], rsp[%s, %s]" % (rest_url, payload, r.status_code, r.text) - err_msgs.append(emsg) - continue - r_json = r.json() - alloc_info = {} - if 'ipv4addrs' in r_json and r_json['ipv4addrs'][0]['ipv4addr']: - alloc_info['v4_ip'] = r_json['ipv4addrs'][0]['ipv4addr'] - alloc_info['v4_subnet'] = v4_subnet - if 'ipv6addrs' in r_json and r_json['ipv6addrs'][0]['ipv6addr']: - alloc_info['v6_ip'] = r_json['ipv6addrs'][0]['ipv6addr'] - alloc_info['v6_subnet'] = v6_subnet - return alloc_info + logger.info("F[CreateIpamRecord] req[%s %s] status_code[%s]" % (rest_url6, payload, r6.status_code)) + _check_and_raise_auth_error(r6) + if r6.status_code in [200, 201]: + r6_json = r6.json() + alloc_info = {} + if 'ipv4addrs' in r6_json and r6_json['ipv4addrs'][0]['ipv4addr']: + alloc_info['v4_ip'] = r6_json['ipv4addrs'][0]['ipv4addr'] + alloc_info['v4_subnet'] = v4_subnet + if 'ipv6addrs' in r6_json and r6_json['ipv6addrs'][0]['ipv6addr']: + alloc_info['v6_ip'] = r6_json['ipv6addrs'][0]['ipv6addr'] + alloc_info['v6_subnet'] = v6_subnet + return alloc_info + elif 'server' in auth_params: + r = requests.post(url=rest_url, auth=(auth_params['username'], auth_params['password']), + verify=False, data=payload) + logger.info("F[CreateIpamRecord] req[%s %s] status_code[%s]" % (rest_url, payload, r.status_code)) + _check_and_raise_auth_error(r) + if r.status_code in [200,201]: + r_json = r.json() + alloc_info = {} + if 'ipv4addrs' in r_json and r_json['ipv4addrs'][0]['ipv4addr']: + alloc_info['v4_ip'] = r_json['ipv4addrs'][0]['ipv4addr'] + alloc_info['v4_subnet'] = v4_subnet + if 'ipv6addrs' in r_json and r_json['ipv6addrs'][0]['ipv6addr']: + alloc_info['v6_ip'] = r_json['ipv6addrs'][0]['ipv6addr'] + alloc_info['v6_subnet'] = v6_subnet + return alloc_info + else: + emsg = "req[%s %s], rsp[%s, %s]" % (rest_url, payload, r.status_code, r.text) + err_msgs.append(emsg) + continue + else: + emsg = "req[%s %s], rsp[%s, %s]" % (rest_url6, payload, r6.status_code, r6.text) + err_msgs.append(emsg) + continue + elif 'server' in auth_params: + r = requests.post(url=rest_url, auth=(auth_params['username'], auth_params['password']), + verify=False, data=payload) + logger.info("F[CreateIpamRecord] req[%s %s] status_code[%s]" % (rest_url, payload, r.status_code)) + _check_and_raise_auth_error(r) + if r.status_code in [200,201]: + r_json = r.json() + alloc_info = {} + if 'ipv4addrs' in r_json and r_json['ipv4addrs'][0]['ipv4addr']: + alloc_info['v4_ip'] = r_json['ipv4addrs'][0]['ipv4addr'] + alloc_info['v4_subnet'] = v4_subnet + if 'ipv6addrs' in r_json and r_json['ipv6addrs'][0]['ipv6addr']: + alloc_info['v6_ip'] = r_json['ipv6addrs'][0]['ipv6addr'] + alloc_info['v6_subnet'] = v6_subnet + return alloc_info + else: + emsg = "req[%s %s], rsp[%s, %s]" % (rest_url, payload, r.status_code, r.text) + err_msgs.append(emsg) + continue if len(err_msgs) == len(nw_and_subnet_list) and all('Cannot find 1 available IP address' in e for e in err_msgs): logger.error("F[CreateIpamRecord] No free available IP reason[%s]" % (err_msgs)) raise CustomIpamNoFreeIpException("F[CreateIpamRecord] No free available IP reason[%s]" % (err_msgs)) @@ -418,32 +598,71 @@ def CreateIpamRecord(auth_params, record_info): v4_subnet = sub[1] v6_subnet = sub[2] if allocation_type in 'V4_ONLY' and v4_subnet: - nw_str = 'func:nextavailableip:' + v4_subnet + ',' + network_view - payload = '{"ipv4addrs": [{"ipv4addr": "' + nw_str + '"}],"name": "' + name + \ - '","configure_for_dns": false,"view": "' + dns_view + '"}' + ipv4addrs = [{"ipv4addr": 'func:nextavailableip:' + v4_subnet + ',' + network_view}] + payload = json.dumps({'name': name, 'view': dns_view, 'configure_for_dns':False, 'ipv4addrs': ipv4addrs}) elif allocation_type in 'V6_ONLY' and v6_subnet: - nw_str = 'func:nextavailableip:' + v6_subnet + ',' + network_view - payload = '{"ipv6addrs": [{"ipv6addr": "' + nw_str + '"}],"name": "' + name + \ - '","configure_for_dns": false,"view": "' + dns_view + '"}' + ipv6addrs = [{"ipv6addr": 'func:nextavailableip:' + v6_subnet + ',' + network_view}] + payload = json.dumps({'name': name, 'view': dns_view, 'configure_for_dns':False, 'ipv6addrs': ipv6addrs}) else: continue - r = requests.post(url=rest_url, auth=(auth_params['username'], auth_params['password']), + #HA code for ipv6 and ipv4 addresses + if 'server6' in auth_params: + r6 = requests.post(url=rest_url6, auth=(auth_params['username'], auth_params['password']), verify=False, data=payload) - logger.info("F[CreateIpamRecord] req[%s %s] status_code[%s]" % (rest_url, payload, r.status_code)) - _check_and_raise_auth_error(r) - if r.status_code not in [200, 201]: - emsg = "req[%s %s], rsp[%s, %s]" % (rest_url, payload, r.status_code, r.text) - err_msgs.append(emsg) - continue - r_json = r.json() - alloc_info = {} - if 'ipv4addrs' in r_json and r_json['ipv4addrs'][0]['ipv4addr']: - alloc_info['v4_ip'] = r_json['ipv4addrs'][0]['ipv4addr'] - alloc_info['v4_subnet'] = v4_subnet - if 'ipv6addrs' in r_json and r_json['ipv6addrs'][0]['ipv6addr']: - alloc_info['v6_ip'] = r_json['ipv6addrs'][0]['ipv6addr'] - alloc_info['v6_subnet'] = v6_subnet - return alloc_info + logger.info("F[CreateIpamRecord] req[%s %s] status_code[%s]" % (rest_url6, payload, r6.status_code)) + _check_and_raise_auth_error(r6) + if r6.status_code in [200, 201]: + r6_json = r6.json() + alloc_info = {} + if 'ipv4addrs' in r6_json and r6_json['ipv4addrs'][0]['ipv4addr']: + alloc_info['v4_ip'] = r6_json['ipv4addrs'][0]['ipv4addr'] + alloc_info['v4_subnet'] = v4_subnet + if 'ipv6addrs' in r6_json and r6_json['ipv6addrs'][0]['ipv6addr']: + alloc_info['v6_ip'] = r6_json['ipv6addrs'][0]['ipv6addr'] + alloc_info['v6_subnet'] = v6_subnet + return alloc_info + elif 'server' in auth_params: + r = requests.post(url=rest_url, auth=(auth_params['username'], auth_params['password']), + verify=False, data=payload) + logger.info("F[CreateIpamRecord] req[%s %s] status_code[%s]" % (rest_url, payload, r.status_code)) + _check_and_raise_auth_error(r) + if r.status_code in [200,201]: + r_json = r.json() + alloc_info = {} + if 'ipv4addrs' in r_json and r_json['ipv4addrs'][0]['ipv4addr']: + alloc_info['v4_ip'] = r_json['ipv4addrs'][0]['ipv4addr'] + alloc_info['v4_subnet'] = v4_subnet + if 'ipv6addrs' in r_json and r_json['ipv6addrs'][0]['ipv6addr']: + alloc_info['v6_ip'] = r_json['ipv6addrs'][0]['ipv6addr'] + alloc_info['v6_subnet'] = v6_subnet + return alloc_info + else: + emsg = "req[%s %s], rsp[%s, %s]" % (rest_url, payload, r.status_code, r.text) + err_msgs.append(emsg) + continue + else: + emsg = "req[%s %s], rsp[%s, %s]" % (rest_url6, payload, r6.status_code, r6.text) + err_msgs.append(emsg) + continue + elif 'server' in auth_params: + r = requests.post(url=rest_url, auth=(auth_params['username'], auth_params['password']), + verify=False, data=payload) + logger.info("F[CreateIpamRecord] req[%s %s] status_code[%s]" % (rest_url, payload, r.status_code)) + _check_and_raise_auth_error(r) + if r.status_code in [200,201]: + r_json = r.json() + alloc_info = {} + if 'ipv4addrs' in r_json and r_json['ipv4addrs'][0]['ipv4addr']: + alloc_info['v4_ip'] = r_json['ipv4addrs'][0]['ipv4addr'] + alloc_info['v4_subnet'] = v4_subnet + if 'ipv6addrs' in r_json and r_json['ipv6addrs'][0]['ipv6addr']: + alloc_info['v6_ip'] = r_json['ipv6addrs'][0]['ipv6addr'] + alloc_info['v6_subnet'] = v6_subnet + return alloc_info + else: + emsg = "req[%s %s], rsp[%s, %s]" % (rest_url, payload, r.status_code, r.text) + err_msgs.append(emsg) + continue if len(err_msgs) == len(nw_and_subnet_list) and all('Cannot find 1 available IP address' in e for e in err_msgs): logger.error("F[CreateIpamRecord] No free available IP reason[%s]" % (err_msgs)) raise CustomIpamNoFreeIpException("F[CreateIpamRecord] No free available IP reason[%s]" % (err_msgs)) @@ -467,6 +686,7 @@ def DeleteIpamRecord(auth_params, record_info): True on successfully deleting the record. Raises ------ + CustomIpamAuthenticationErrorException: if authentication fails. CustomIpamRecordNotFoundException: if the given record not found CustomIpamGeneralException: if delete record request fails. """ @@ -481,35 +701,105 @@ def DeleteIpamRecord(auth_params, record_info): name = id # Step 1: Get the reference of the given IPAM record - rest_url = 'https://' + auth_params['server'] + '/wapi/' + auth_params['wapi_version'] + \ + if 'server' in auth_params: + rest_url = 'https://' + auth_params['server'] + '/wapi/' + auth_params['wapi_version'] + \ + '/record:host?name=' + name + if 'server6' in auth_params: + rest_url6 = 'https://[' + auth_params['server6'] + ']/wapi/' + auth_params['wapi_version'] + \ '/record:host?name=' + name try: - r = requests.get(url=rest_url, auth=(auth_params['username'], auth_params['password']), + #HA code for ipv6 and ipv4 addresses + if 'server6' in auth_params: + r6 = requests.get(url=rest_url6, auth=(auth_params['username'], auth_params['password']), verify=False, timeout=30) - logger.info("F[DeleteIpamRecord] req[%s] status_code[%s]" % (rest_url, r.status_code)) - _check_and_raise_auth_error(r) - r_json = r.json() - host_ref = None - err_msg = "F[DeleteIpamRecord] Record[%s] not found!" % name - if r.status_code == 200: - host_ref = r_json[0]['_ref'] if len(r_json) > 0 and r_json[0]['_ref'] else None - if not host_ref: + logger.info("F[DeleteIpamRecord] req[%s] status_code[%s]" % (rest_url6, r6.status_code)) + _check_and_raise_auth_error(r6) + r6_json = r6.json() + host_ref = None + err_msg = "F[DeleteIpamRecord] Record[%s] not found!" % name + if r6.status_code == 200: + host_ref = r6_json[0]['_ref'] if len(r6_json) > 0 and r6_json[0]['_ref'] else None + if not host_ref: + logger.error(err_msg) + raise CustomIpamRecordNotFoundException(err_msg) + # Step 2: Delete the record + url6 = 'https://[' + auth_params['server6'] + ']/wapi/' + \ + auth_params['wapi_version'] + '/' + host_ref + r6 = requests.delete(url=url6, auth=( + auth_params['username'], auth_params['password']), verify=False) + logger.info("F[DeleteIpamRecord] req[%s] status_code[%s]" % (url6, r6.status_code)) + _check_and_raise_auth_error(r6) + r6_json = r6.json() + if r6.status_code == 200: + return True + else: + if 'text' in r6_json: + err_msg += r6.status_code + " : " + BeautifulSoup(r6.text, 'html.parser').text + logger.error(err_msg) + raise CustomIpamRecordNotFoundException(err_msg) + elif 'server' in auth_params: + r = requests.get(url=rest_url, auth=(auth_params['username'], auth_params['password']), + verify=False, timeout=30) + logger.info("F[DeleteIpamRecord] req[%s] status_code[%s]" % (rest_url, r.status_code)) + _check_and_raise_auth_error(r) + r_json = r.json() + host_ref = None + err_msg = "F[DeleteIpamRecord] Record[%s] not found!" % name + if r.status_code == 200: + host_ref = r_json[0]['_ref'] if len(r_json) > 0 and r_json[0]['_ref'] else None + if not host_ref: + logger.error(err_msg) + raise CustomIpamRecordNotFoundException(err_msg) + # Step 2: Delete the record + url = 'https://' + auth_params['server'] + '/wapi/' + \ + auth_params['wapi_version'] + '/' + host_ref + r = requests.delete(url=url, auth=( + auth_params['username'], auth_params['password']), verify=False) + logger.info("F[DeleteIpamRecord] req[%s] status_code[%s]" % (url, r.status_code)) + _check_and_raise_auth_error(r) + r_json = r.json() + if r.status_code == 200: + return True + if 'text' in r_json: + err_msg += r.status_code + " : " + BeautifulSoup(r.text, 'html.parser').text logger.error(err_msg) raise CustomIpamRecordNotFoundException(err_msg) - # Step 2: Delete the record - rest_url = 'https://' + auth_params['server'] + '/wapi/' + \ - auth_params['wapi_version'] + '/' + host_ref - r = requests.delete(url=rest_url, auth=( - auth_params['username'], auth_params['password']), verify=False) + else: + if 'text' in r6_json: + err_msg += r6.status_code + " : " + BeautifulSoup(r6.text, 'html.parser').text + logger.error(err_msg) + raise CustomIpamRecordNotFoundException(err_msg) + elif 'server' in auth_params: + r = requests.get(url=rest_url, auth=(auth_params['username'], auth_params['password']), + verify=False, timeout=30) logger.info("F[DeleteIpamRecord] req[%s] status_code[%s]" % (rest_url, r.status_code)) _check_and_raise_auth_error(r) r_json = r.json() + host_ref = None + err_msg = "F[DeleteIpamRecord] Record[%s] not found!" % name if r.status_code == 200: - return True - if 'text' in r_json: - err_msg += r.status_code + " : " + BeautifulSoup(r.text, 'html.parser').text - logger.error(err_msg) - raise CustomIpamRecordNotFoundException(err_msg) + host_ref = r_json[0]['_ref'] if len(r_json) > 0 and r_json[0]['_ref'] else None + if not host_ref: + logger.error(err_msg) + raise CustomIpamRecordNotFoundException(err_msg) + # Step 2: Delete the record + url = 'https://' + auth_params['server'] + '/wapi/' + \ + auth_params['wapi_version'] + '/' + host_ref + r = requests.delete(url=url, auth=( + auth_params['username'], auth_params['password']), verify=False) + logger.info("F[DeleteIpamRecord] req[%s] status_code[%s]" % (url, r.status_code)) + _check_and_raise_auth_error(r) + r_json = r.json() + if r.status_code == 200: + return True + if 'text' in r_json: + err_msg += r.status_code + " : " + BeautifulSoup(r.text, 'html.parser').text + logger.error(err_msg) + raise CustomIpamRecordNotFoundException(err_msg) + except CustomIpamAuthenticationErrorException as e: + raise + except CustomIpamRecordNotFoundException as e: + raise except Exception as e: logger.error("F[DeleteIpamRecord] Error deleting the record[%s] reason[%s]" % (name, str(e))) raise CustomIpamGeneralException("F[DeleteIpamRecord] Error deleting the record[%s] reason[%s]" % (name, str(e))) @@ -553,6 +843,7 @@ def UpdateIpamRecord(auth_params, new_record_info, old_record_info): Raises ------ CustomIpamNotImplementedException: if this function or specific update requests not implemented. + CustomIpamAuthenticationErrorException: if authentication fails. CustomIpamRecordNotFoundException: if the given record not found CustomIpamGeneralException: if the api request fails for any other reason. """ @@ -572,6 +863,7 @@ def UpdateIpamRecord(auth_params, new_record_info, old_record_info): new_allocation_type = new_record_info.get('allocation_type', None) old_allocation_type = old_record_info.get('allocation_type', None) network_view = auth_params.get('network_view', 'default') + dns_view = auth_params.get('dns_view', None) # fqdn change: # record update with preferred ipv4/ipv6: @@ -595,21 +887,56 @@ def UpdateIpamRecord(auth_params, new_record_info, old_record_info): # Step 1: Get the reference of the given IPAM record name = id host_ref = None - rest_url = 'https://' + auth_params['server'] + '/wapi/' + auth_params['wapi_version'] + \ + if 'server' in auth_params: + rest_url = 'https://' + auth_params['server'] + '/wapi/' + auth_params['wapi_version'] + \ + '/record:host?name=' + name + if 'server6' in auth_params: + rest_url6 = 'https://[' + auth_params['server6'] + ']/wapi/' + auth_params['wapi_version'] + \ '/record:host?name=' + name try: - r = requests.get(url=rest_url, auth=(auth_params['username'], auth_params['password']), + if 'server6' in auth_params: + r6 = requests.get(url=rest_url6, auth=(auth_params['username'], auth_params['password']), verify=False, timeout=30) - logger.info("F[UpdateIpamRecord] req[%s] status_code[%s]" % (rest_url, r.status_code)) - _check_and_raise_auth_error(r) - r_json = r.json() - if r.status_code == 200: - host_ref = r_json[0]['_ref'] if len(r_json) > 0 and r_json[0]['_ref'] else None - else: - err_msg = r.status_code - err_msg += ' : ' + r_json['text'] if 'text' in r_json else None - logger.error("F[UpdateIpamRecord] Error retrieving the record[%s] reason[%s]" % (name, err_msg)) - raise CustomIpamRecordNotFoundException("F[UpdateIpamRecord] Error retrieving the record[%s] reason[%s]" % (name, err_msg)) + logger.info("F[UpdateIpamRecord] req[%s] status_code[%s]" % (rest_url6, r6.status_code)) + _check_and_raise_auth_error(r6) + r6_json = r6.json() + if r6.status_code == 200: + host_ref = r6_json[0]['_ref'] if len(r6_json) > 0 and r6_json[0]['_ref'] else None + elif 'server' in auth_params: + r = requests.get(url=rest_url, auth=(auth_params['username'], auth_params['password']), + verify=False, timeout=30) + logger.info("F[UpdateIpamRecord] req[%s] status_code[%s]" % (rest_url, r.status_code)) + _check_and_raise_auth_error(r) + r_json = r.json() + if r.status_code == 200: + host_ref = r_json[0]['_ref'] if len(r_json) > 0 and r_json[0]['_ref'] else None + else: + err_msg = r.status_code + err_msg += ' : ' + r_json['text'] if 'text' in r_json else None + logger.error("F[UpdateIpamRecord] Error retrieving the record[%s] reason[%s]" % (name, err_msg)) + raise CustomIpamRecordNotFoundException("F[UpdateIpamRecord] Error retrieving the record[%s] reason[%s]" % (name, err_msg)) + else: + err_msg = r6.status_code + err_msg += ' : ' + r6_json['text'] if 'text' in r6_json else None + logger.error("F[UpdateIpamRecord] Error retrieving the record[%s] reason[%s]" % (name, err_msg)) + raise CustomIpamRecordNotFoundException("F[UpdateIpamRecord] Error retrieving the record[%s] reason[%s]" % (name, err_msg)) + elif 'server' in auth_params: + r = requests.get(url=rest_url, auth=(auth_params['username'], auth_params['password']), + verify=False, timeout=30) + logger.info("F[UpdateIpamRecord] req[%s] status_code[%s]" % (rest_url, r.status_code)) + _check_and_raise_auth_error(r) + r_json = r.json() + if r.status_code == 200: + host_ref = r_json[0]['_ref'] if len(r_json) > 0 and r_json[0]['_ref'] else None + else: + err_msg = r.status_code + err_msg += ' : ' + r_json['text'] if 'text' in r_json else None + logger.error("F[UpdateIpamRecord] Error retrieving the record[%s] reason[%s]" % (name, err_msg)) + raise CustomIpamRecordNotFoundException("F[UpdateIpamRecord] Error retrieving the record[%s] reason[%s]" % (name, err_msg)) + except CustomIpamAuthenticationErrorException as e: + raise + except CustomIpamRecordNotFoundException as e: + raise except Exception as e: logger.error("F[UpdateIpamRecord] Error retrieving the record[%s] reason[%s]" % (name, str(e))) raise CustomIpamGeneralException("F[UpdateIpamRecord] Error retrieving the record[%s] reason[%s]" % (name, str(e))) @@ -622,52 +949,87 @@ def UpdateIpamRecord(auth_params, new_record_info, old_record_info): # Step 3: Build payload data according to the new allocation_type # and call specific rest API and return new allocated items(alloc_info). - rest_url = 'https://' + auth_params['server'] + '/wapi/' + \ - auth_params['wapi_version'] + '/' + host_ref + '?_return_fields=ipv4addrs,ipv6addrs' + if 'server' in auth_params: + rest_url = 'https://' + auth_params['server'] + '/wapi/' + \ + auth_params['wapi_version'] + '/' + host_ref + '?_return_fields=ipv4addrs,ipv6addrs' + if 'server6' in auth_params: + rest_url6 = 'https://[' + auth_params['server6'] + ']/wapi/' + \ + auth_params['wapi_version'] + '/' + host_ref + '?_return_fields=ipv4addrs,ipv6addrs' v4_subnet = new_nw_and_subnet_list[0][1] v6_subnet = new_nw_and_subnet_list[0][2] + payload_dict = {} if new_allocation_type == 'V4_ONLY' and old_allocation_type == 'V6_ONLY': - nw_str_ip4 = '"ipv4addrs": [{"ipv4addr": "func:nextavailableip:' + v4_subnet + ',' + network_view + '"}]' - nw_str_ip6 = '"ipv6addrs":[]' + payload_dict['ipv4addrs'] = [{"ipv4addr": 'func:nextavailableip:' + v4_subnet + ',' + network_view}] + payload_dict['ipv6addrs'] = [] elif new_allocation_type == 'V4_ONLY' and old_allocation_type == 'V4_V6': - nw_str_ip4 = None - nw_str_ip6 = '"ipv6addrs":[]' + payload_dict['ipv6addrs'] = [] elif new_allocation_type == 'V6_ONLY' and old_allocation_type == 'V4_ONLY': - nw_str_ip4 = '"ipv4addrs":[]' - nw_str_ip6 = '"ipv6addrs": [{"ipv6addr": "func:nextavailableip:' + v6_subnet + ',' + network_view + '"}]' + payload_dict['ipv4addrs'] = [] + payload_dict['ipv6addrs'] = [{"ipv6addr": 'func:nextavailableip:' + v6_subnet + ',' + network_view}] elif new_allocation_type == 'V6_ONLY' and old_allocation_type == 'V4_V6': - nw_str_ip4 = '"ipv4addrs":[]' - nw_str_ip6 = None + payload_dict['ipv4addrs'] = [] elif new_allocation_type == 'V4_V6' and old_allocation_type == 'V4_ONLY': - nw_str_ip4 = None - nw_str_ip6 = '"ipv6addrs": [{"ipv6addr": "func:nextavailableip:' + v6_subnet + ',' + network_view + '"}]' + payload_dict['ipv6addrs'] = [{"ipv6addr": 'func:nextavailableip:' + v6_subnet + ',' + network_view}] elif new_allocation_type == 'V4_V6' and old_allocation_type == 'V6_ONLY': - nw_str_ip4 = '"ipv4addrs": [{"ipv4addr": "func:nextavailableip:' + v4_subnet + ',' + network_view + '"}]' - nw_str_ip6 = None - - payload = '{' - if nw_str_ip4: - payload += nw_str_ip4 - if nw_str_ip4 and nw_str_ip6: - payload += ',' - if nw_str_ip6: - payload += nw_str_ip6 - payload += '}' - r = requests.put(url=rest_url, auth=(auth_params['username'], auth_params['password']), + payload_dict['ipv4addrs'] = [{"ipv4addr": 'func:nextavailableip:' + v4_subnet + ',' + network_view}] + + payload = json.dumps(payload_dict) + + if 'server6' in auth_params: + r6 = requests.put(url=rest_url6, auth=(auth_params['username'], auth_params['password']), verify=False, data=payload, timeout=30) - logger.info("F[UpdateIpamRecord] req[%s %s] status_code[%s]" % (rest_url, payload, r.status_code)) - _check_and_raise_auth_error(r) - if r.status_code not in [200, 201]: - err_msg = "%d %s" % (r.status_code, r.text) - logger.error("F[UpdateIpamRecord] Error updating the host record[%s] req[%s,%s] reason[%s]", name, rest_url, payload, err_msg) - raise CustomIpamGeneralException("F[UpdateIpamRecord] Error updating the host record[%s] req[%s,%s] reason[%s]", - name, rest_url, payload, err_msg) - r_json = r.json() - alloc_info = {} - if 'ipv4addrs' in r_json and r_json['ipv4addrs'][0]['ipv4addr']: - alloc_info['v4_ip'] = r_json['ipv4addrs'][0]['ipv4addr'] - alloc_info['v4_subnet'] = v4_subnet - if 'ipv6addrs' in r_json and r_json['ipv6addrs'][0]['ipv6addr']: - alloc_info['v6_ip'] = r_json['ipv6addrs'][0]['ipv6addr'] - alloc_info['v6_subnet'] = v6_subnet - return alloc_info + logger.info("F[UpdateIpamRecord] req[%s %s] status_code[%s]" % (rest_url6, payload, r6.status_code)) + _check_and_raise_auth_error(r6) + if r6.status_code in [200, 201]: + r6_json = r6.json() + alloc_info = {} + if 'ipv4addrs' in r6_json and r6_json['ipv4addrs'][0]['ipv4addr']: + alloc_info['v4_ip'] = r6_json['ipv4addrs'][0]['ipv4addr'] + alloc_info['v4_subnet'] = v4_subnet + if 'ipv6addrs' in r6_json and r6_json['ipv6addrs'][0]['ipv6addr']: + alloc_info['v6_ip'] = r6_json['ipv6addrs'][0]['ipv6addr'] + alloc_info['v6_subnet'] = v6_subnet + return alloc_info + elif 'server' in auth_params: + r = requests.put(url=rest_url, auth=(auth_params['username'], auth_params['password']), + verify=False, data=payload, timeout=30) + logger.info("F[UpdateIpamRecord] req[%s %s] status_code[%s]" % (rest_url, payload, r.status_code)) + _check_and_raise_auth_error(r) + if r.status_code not in [200, 201]: + err_msg = "%d %s" % (r.status_code, r.text) + logger.error("F[UpdateIpamRecord] Error updating the host record[%s] req[%s,%s] reason[%s]", name, rest_url, payload, err_msg) + raise CustomIpamGeneralException("F[UpdateIpamRecord] Error updating the host record[%s] req[%s,%s] reason[%s]", + name, rest_url, payload, err_msg) + r_json = r.json() + alloc_info = {} + if 'ipv4addrs' in r_json and r_json['ipv4addrs'][0]['ipv4addr']: + alloc_info['v4_ip'] = r_json['ipv4addrs'][0]['ipv4addr'] + alloc_info['v4_subnet'] = v4_subnet + if 'ipv6addrs' in r_json and r_json['ipv6addrs'][0]['ipv6addr']: + alloc_info['v6_ip'] = r_json['ipv6addrs'][0]['ipv6addr'] + alloc_info['v6_subnet'] = v6_subnet + return alloc_info + else: + err_msg = "%d %s" % (r6.status_code, r6.text) + logger.error("F[UpdateIpamRecord] Error updating the host record[%s] req[%s,%s] reason[%s]", name, rest_url6, payload, err_msg) + raise CustomIpamGeneralException("F[UpdateIpamRecord] Error updating the host record[%s] req[%s,%s] reason[%s]", + name, rest_url6, payload, err_msg) + elif 'server' in auth_params: + r = requests.put(url=rest_url, auth=(auth_params['username'], auth_params['password']), + verify=False, data=payload, timeout=30) + logger.info("F[UpdateIpamRecord] req[%s %s] status_code[%s]" % (rest_url, payload, r.status_code)) + _check_and_raise_auth_error(r) + if r.status_code not in [200, 201]: + err_msg = "%d %s" % (r.status_code, r.text) + logger.error("F[UpdateIpamRecord] Error updating the host record[%s] req[%s,%s] reason[%s]", name, rest_url, payload, err_msg) + raise CustomIpamGeneralException("F[UpdateIpamRecord] Error updating the host record[%s] req[%s,%s] reason[%s]", + name, rest_url, payload, err_msg) + r_json = r.json() + alloc_info = {} + if 'ipv4addrs' in r_json and r_json['ipv4addrs'][0]['ipv4addr']: + alloc_info['v4_ip'] = r_json['ipv4addrs'][0]['ipv4addr'] + alloc_info['v4_subnet'] = v4_subnet + if 'ipv6addrs' in r_json and r_json['ipv6addrs'][0]['ipv6addr']: + alloc_info['v6_ip'] = r_json['ipv6addrs'][0]['ipv6addr'] + alloc_info['v6_subnet'] = v6_subnet + return alloc_info