Skip to content
Snippets Groups Projects
test_ipam.py 6.29 KiB
Newer Older
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')
    )