From db0f1613fef9c870e515bdbbee087ea4825e32c2 Mon Sep 17 00:00:00 2001 From: Ubuntu <jorge.sasiain@ehu.eus> Date: Mon, 15 May 2023 11:59:56 +0000 Subject: [PATCH] NAT-186: implement cname record support --- gso/services/_ipam.py | 34 ++++++++++++++++++++++++++++++++-- gso/services/ipam.py | 26 ++++++++++++++++---------- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/gso/services/_ipam.py b/gso/services/_ipam.py index a13ccad8..efd1da45 100644 --- a/gso/services/_ipam.py +++ b/gso/services/_ipam.py @@ -224,6 +224,7 @@ def _find_next_available_ip(infoblox_params, network_ref): def _allocate_host(hostname=None, addrs=None, networks=None, + cname_aliases=None, extattrs={} ) -> HostAddresses: """ @@ -266,7 +267,7 @@ def _allocate_host(hostname=None, assert _ip_addr_version(ipv4_addr) == 4 assert _ip_addr_version(ipv6_addr) == 6 - ip_req_payload = { + req_payload = { "ipv4addrs": [ { "ipv4addr": ipv4_addr @@ -285,7 +286,7 @@ def _allocate_host(hostname=None, r = requests.post( f'{_wapi(infoblox_params)}/record:host', - json=ip_req_payload, + json=req_payload, auth=HTTPBasicAuth(infoblox_params.username, infoblox_params.password), verify=False @@ -295,6 +296,28 @@ def _allocate_host(hostname=None, assert isinstance(r.json(), str) assert r.json().startswith("record:host/") + if cname_aliases: + + cname_req_payload = { + "name": "", + "canonical": hostname, + "view": "default", + "extattrs": extattrs + } + + for alias in cname_aliases: + cname_req_payload["name"] = alias + r = requests.post( + f'{_wapi(infoblox_params)}/record:cname', + json=cname_req_payload, + auth=HTTPBasicAuth(infoblox_params.username, + infoblox_params.password), + verify=False + ) + assert r.status_code >= 200 and r.status_code < 300, \ + f"HTTP error {r.status_code}: {r.reason}\n\n{r.text}" + assert r.json().startswith("record:cname/") + return HostAddresses(v4=ipaddress.ip_address(ipv4_addr), v6=ipaddress.ip_address(ipv6_addr)) @@ -303,6 +326,7 @@ def allocate_service_host(hostname=None, service_type=None, service_networks: ServiceNetworks = None, host_addresses: HostAddresses = None, + cname_aliases=None, extattrs={} ) -> HostAddresses: """ @@ -327,6 +351,9 @@ def allocate_service_host(hostname=None, ipv6_containers = getattr(ipam_params, service_type).V6.containers domain_name = getattr(ipam_params, service_type).domain_name + if cname_aliases: + cname_aliases = [alias + domain_name for alias in cname_aliases] + if not service_networks and not host_addresses: # IPv4 ipv4_network = str(allocate_service_ipv4_network( @@ -343,6 +370,7 @@ def allocate_service_host(hostname=None, network_tuple = (ipv4_network, ipv6_network) host = _allocate_host(hostname=hostname+domain_name, networks=network_tuple, + cname_aliases=cname_aliases, extattrs=extattrs) elif service_networks: @@ -359,6 +387,7 @@ def allocate_service_host(hostname=None, host = _allocate_host( hostname=hostname+domain_name, networks=(str(ipv4_network), str(ipv6_network)), + cname_aliases=cname_aliases, extattrs=extattrs ) @@ -376,6 +405,7 @@ def allocate_service_host(hostname=None, host = _allocate_host( hostname=hostname+domain_name, addrs=(str(ipv4_addr), str(ipv6_addr)), + cname_aliases=cname_aliases, extattrs=extattrs ) diff --git a/gso/services/ipam.py b/gso/services/ipam.py index d794dd43..9957a442 100644 --- a/gso/services/ipam.py +++ b/gso/services/ipam.py @@ -46,31 +46,35 @@ def new_service_host(hostname, service_type, service_networks: ServiceNetworks = None, host_addresses: HostAddresses = None, + cname_aliases=None, extattrs={}) -> HostAddresses: return _ipam.allocate_service_host( hostname=hostname, service_type=service_type, service_networks=service_networks, host_addresses=host_addresses, + cname_aliases=cname_aliases, extattrs=extattrs) if __name__ == '__main__': # sample call flow to allocate two loopback interfaces and a trunk service # new_service_host can be called passing networks or addresses - # - host h1 for service LO uses a specific ipv4/ipv6 address pair + # - host h3 for service LO uses a specific ipv4/ipv6 address pair # - the rest use the ipv4/ipv6 network pair # networks and hosts can be allocated with extensible attributes - # - host h2 for service LO uses extattrs for both network and address/DNS + # - host h4 for service LO uses extattrs for both network and address/DNS # - the rest don't use extattrs + # CNAME records can be optionally created + # - hosts for service TRUNK use some alias names - hostname_A = 'h1' - hostname_B = 'h2' + hostname_A = 'h3' + hostname_B = 'h4' - # h1 LO (loopback) + # h3 LO (loopback) lo1_service_networks = new_service_networks( service_type='LO', - comment="Network for h1 LO" + comment="Network for h3 LO" ) lo1_v4_host_address = lo1_service_networks.v4.network_address lo1_v6_host_address = lo1_service_networks.v6.network_address @@ -80,7 +84,7 @@ if __name__ == '__main__': service_type='LO', host_addresses=lo1_host_addresses) - # h2 LO (loopback) + # h4 LO (loopback) lo2_network_extattrs = { "vrf_name": {"value": "dummy_vrf"}, } @@ -89,21 +93,23 @@ if __name__ == '__main__': } lo2_service_networks = \ new_service_networks(service_type='LO', - comment="Network for h2 LO", + comment="Network for h4 LO", extattrs=lo2_network_extattrs) new_service_host(hostname=hostname_B+"_LO", service_type='LO', service_networks=lo2_service_networks, extattrs=lo2_host_extattrs) - # h1-h2 TRUNK + # h3-h4 TRUNK trunk12_service_networks = new_service_networks( service_type='TRUNK', - comment="Network for h1-h2 TRUNK" + comment="Network for h3-h4 TRUNK" ) new_service_host(hostname=hostname_A+"_TRUNK", service_type='TRUNK', + cname_aliases=["alias1.h3", "alias2.h3"], service_networks=trunk12_service_networks) new_service_host(hostname=hostname_B+"_TRUNK", service_type='TRUNK', + cname_aliases=["alias1.h4"], service_networks=trunk12_service_networks) -- GitLab