import contextlib import ipaddress import json import os import socket import pytest import re import responses import tempfile from gso.services import ipam @pytest.fixture(scope='session') def configuration_data(): with contextlib.closing( socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as s: s.bind(('', 0)) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) yield { "GENERAL": { "public_hostname": "https://gap.geant.org" }, "RESOURCE_MANAGER_API_PREFIX": "http://localhost:44444", "IPAM": { "INFOBLOX": { "scheme": "https", "wapi_version": "v2.12", "host": "10.0.0.1", "username": "robot-user", "password": "robot-user-password" }, "LO": { "V4": {"containers": ["10.255.255.0/24"], "mask": 32}, "V6": {"containers": ["dead:beef::/64"], "mask": 128}, "domain_name": ".lo" }, "TRUNK": { "V4": { "containers": ["10.255.255.0/24", "10.255.254.0/24"], "mask": 31 }, "V6": { "containers": ["dead:beef::/64", "dead:beee::/64"], "mask": 126 }, "domain_name": ".trunk" }, "GEANT_IP": { "V4": { "containers": ["10.255.255.0/24", "10.255.254.0/24"], "mask": 31 }, "V6": { "containers": ["dead:beef::/64", "dead:beee::/64"], "mask": 126 }, "domain_name": ".geantip" } }, "PROVISIONING_PROXY": { "scheme": "https", "api_base": "localhost:44444", "auth": "Bearer <token>", "api_version": 1123 } } @pytest.fixture(scope='session') def data_config_filename(configuration_data): file_name = os.path.join( tempfile.gettempdir(), os.urandom(24).hex()) open(file_name, 'x').close() with open(file_name, 'wb') as f: f.write(json.dumps(configuration_data).encode('utf-8')) f.flush() os.environ['OSS_PARAMS_FILENAME'] = f.name yield f.name @responses.activate def test_new_service_networks(data_config_filename, service_type='LO'): responses.add( method=responses.POST, url=re.compile(r'.*/wapi.*/network.*'), json={ '_ref': 'network/ZG5zLm5ldHdvcmskMTAuMjU1LjI1NS4yMC8zMi8w:10.255.255.20/32/default', # noqa: E501 'network': '10.255.255.20/32' } ) responses.add( method=responses.POST, url=re.compile(r'.*/wapi.*/ipv6network.*'), json={ '_ref': 'ipv6network/ZG5zLm5ldHdvcmskZGVhZDpiZWVmOjoxOC8xMjgvMA:dead%3Abeef%3A%3A18/128/default', # noqa: E501 'network': 'dead:beef::18/128' } ) service_networks = ipam.new_service_networks(service_type='LO') assert service_networks == ipam.ServiceNetworks( v4=ipaddress.ip_network('10.255.255.20/32'), v6=ipaddress.ip_network('dead:beef::18/128') ) @responses.activate def test_new_service_host(data_config_filename, service_type='LO'): responses.add( method=responses.POST, url=re.compile(r'.*/wapi.*/record:host$'), json='record:host/ZG5zLmhvc3QkLm5vbl9ETlNfaG9zdF9yb290LjAuMTY4MzcwNTU4MzY3MC5nc28udGVzdA:test.lo/%20' # noqa: E501 ) responses.add( method=responses.POST, url=re.compile(r'.*/wapi.*/record:a$'), json='record:a/ZG5zLmJpbmRfYSQuX2RlZmF1bHQuZ3NvLHRlc3QsMTAuMjU1LjI1NS44:test.lo/default' # noqa: E501 ) responses.add( method=responses.POST, url=re.compile(r'.*/wapi.*/record:aaaa$'), json='record:aaaa/ZG5zLmJpbmRfYSQuX2RlZmF1bHQuZ3NvLHRlc3QsMTAuMjU1LjI1NS44:test.lo/default' # noqa: E501 ) responses.add( method=responses.GET, url=re.compile(r'.*/wapi.*/network.*'), json=[ { "_ref": "network/ZG5zLm5ldHdvcmskMTAuMjU1LjI1NS4yMC8zMi8w:10.255.255.20/32/default", # noqa: E501 "network": "10.255.255.20/32", "network_view": "default" } ] ) responses.add( method=responses.GET, url=re.compile(r'.*/wapi.*/ipv6network.*'), json=[ { "_ref": "ipv6network/ZG5zLm5ldHdvcmskZGVhZDpiZWVmOjoxOC8xMjgvMA:dead%3Abeef%3A%3A18/128/default", # noqa: E501 "network": "dead:beef::18/128", "network_view": "default" } ] ) responses.add( method=responses.POST, url=re.compile(r'.*/wapi.*/network.*/.*?_function=next_available_ip&num=1.*'), # noqa: E501 json={'ips': ['10.255.255.20']} ) responses.add( method=responses.POST, url=re.compile(r'.*/wapi.*/ipv6network.*/.*?_function=next_available_ip&num=1.*'), # noqa: E501 json={'ips': ['dead:beef::18']} ) service_hosts = ipam.new_service_host( hostname='test', service_type='LO', host_addresses=ipam.HostAddresses( v4=ipaddress.ip_address('10.255.255.20'), v6=ipaddress.ip_address('dead:beef::18') ) ) assert service_hosts == ipam.HostAddresses( v4=ipaddress.ip_address('10.255.255.20'), v6=ipaddress.ip_address('dead:beef::18') ) service_hosts = ipam.new_service_host( hostname='test', service_type='LO', service_networks=ipam.ServiceNetworks( v4=ipaddress.ip_network('10.255.255.20/32'), v6=ipaddress.ip_network('dead:beef::18/128') ) ) assert service_hosts == ipam.HostAddresses( v4=ipaddress.ip_address('10.255.255.20'), v6=ipaddress.ip_address('dead:beef::18') )