-
Karel van Klink authoredKarel van Klink authored
test_infoblox.py 10.26 KiB
import ipaddress
import re
from os import PathLike
import pytest
import responses
from requests import codes
from gso.services import infoblox
from gso.services.infoblox import AllocationError, DeletionError
def _set_up_network_responses():
responses.add(
method=responses.GET,
url=re.compile(r".+/wapi/v2\.12/network\?network=10\.255\.255\.0.+"),
json=[],
)
responses.add(
method=responses.GET,
url=re.compile(r".+/wapi/v2\.12/ipv6network\?network=dead%3Abeef.+"),
json=[],
)
responses.add(
method=responses.POST,
url=re.compile(r".+/wapi/v2\.12/network.+"),
json={
"_ref": "network/ZG5zLm5ldHdvcmskMTAuMjU1LjI1NS4yMC8zMi8w:10.255.255.20/32/default",
"network": "10.255.255.20/32",
},
status=codes.CREATED,
)
responses.add(
method=responses.POST,
url=re.compile(r".+/wapi/v2\.12/ipv6network.+"),
json={
"_ref": "ipv6network/ZG5zLm5ldHdvcmskZGVhZDpiZWVmOjoxOC8xMjgvMA:dead%3Abeef%3A%3A18/128/default",
"network": "dead:beef::18/128",
},
status=codes.CREATED,
)
def _set_up_host_responses():
responses.add(
method=responses.GET,
url="https://10.0.0.1/wapi/v2.12/record%3Ahost?_return_fields=extattrs%2Cipv6addrs%2Cname%2Cview%2Caliases",
json=[],
)
responses.add(
method=responses.GET,
url="https://10.0.0.1/wapi/v2.12/record%3Ahost?name=test.lo.geant.net&ipv6addr=func%3Anextavailableip%3Adead%3A"
"beef%3A%3A%2F80%2Cdefault",
json=[],
)
responses.add(
method=responses.GET,
url="https://10.0.0.1/wapi/v2.12/record%3Ahost?name=test.lo.geant.net&_return_fields=extattrs%2Cipv4addrs%2Cnam"
"e%2Cview%2Caliases",
json=[],
)
responses.add(
method=responses.GET,
url="https://10.0.0.1/wapi/v2.12/record%3Ahost?name=broken&_return_fields=extattrs%2Cipv4addrs%2Cname%2Cview%2C"
"aliases",
json=[],
)
responses.add(
method=responses.GET,
url=re.compile(
r"https://10.0.0.1/wapi/v2.12/record%3Ahost\?name=broken&ipv6addr=func%3Anextavailableip%3Adead%3Abeef%3A%3"
r"A%2F80%2Cdefault.*",
),
json=[],
status=codes.BAD,
)
responses.add(
method=responses.POST,
url=re.compile(r".+/wapi/v2\.12/record%3Ahost\?_return_fields=extattrs%2Cipv6addrs.+"),
json={
"_ref": "record:host/ZG5zLmhvc3QkLl9kZWZhdWx0Lm5ldC5nZWFudC5sby50ZXN0:test.lo.geant.net/default",
"ipv6addrs": [
{
"_ref": "record:host_ipv6addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQubmV0LmdlYW50LmxvLnRlc3QuZGVhZDpiZ"
"WVmOjoxLg:dead%3Abeef%3A%3A1/test.lo.geant.net/default",
"configure_for_dhcp": False,
"duid": "00:00:00:00:00:00:00:00:00:00",
"host": "test.lo.geant.net",
"ipv6addr": "dead:beef::1",
},
],
"ip": "dead:beef::1",
"name": "test.lo.geant.net",
"view": "default",
},
status=codes.CREATED,
)
responses.add(
method=responses.PUT,
url="https://10.0.0.1/wapi/v2.12/record%3Ahost/ZG5zLmhvc3QkLl9kZWZhdWx0Lm5ldC5nZWFudC5sd28udGVzdA%3Atest.lo.gea"
"nt.net/default?_return_fields=extattrs%2Cipv4addrs%2Cname%2Cview%2Caliases",
json={
"ipv4addrs": [
{
"_ref": "record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQubmV0LmdlYW50Lmx3by50ZXN0LjEwLjI1N"
"S4yNTUuMTI5Lg:10.255.255.129/test.lo.geant.net/default",
"configure_for_dhcp": False,
"host": "test.lo.geant.net",
"ipv4addr": "10.255.255.129",
"mac": "00:00:00:00:00:00",
},
],
"name": "test.lo.geant.net",
"view": "default",
},
)
responses.add(
method=responses.GET,
url="https://10.0.0.1/wapi/v2.12/record%3Ahost?name=test.lo.geant.net&_return_fields=extattrs%2Cipv4addrs%2Cnam"
"e%2Cview%2Caliases",
json=[
{
"_ref": "record:host/ZG5zLmhvc3QkLl9kZWZhdWx0Lm5ldC5nZWFudC5sd28udGVzdA:test.lo.geant.net/default",
"ipv4addrs": [
{
"_ref": "record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQubmV0LmdlYW50Lmx3by50ZXN0LjEwL"
"jI1N"
"S4yNTUuMTI5Lg:10.255.255.129/test.lo.geant.net/default",
"configure_for_dhcp": False,
"host": "test.lo.geant.net",
"ipv4addr": "10.255.255.129",
"mac": "00:00:00:00:00:00",
},
],
"name": "test.lo.geant.net",
"view": "default",
},
],
)
@responses.activate
def test_allocate_networks(data_config_filename: PathLike):
_set_up_network_responses()
new_v4_network = infoblox.allocate_v4_network("TRUNK")
new_v6_network = infoblox.allocate_v6_network("TRUNK")
assert new_v4_network == ipaddress.IPv4Network("10.255.255.20/32")
assert new_v6_network == ipaddress.IPv6Network("dead:beef::18/128")
@responses.activate
def test_allocate_bad_network(data_config_filename: PathLike):
_set_up_network_responses()
with pytest.raises(AllocationError) as e:
infoblox.allocate_v4_network("LO")
assert e.value.args[0] == "Cannot allocate anything in [], check whether any IP space is available."
with pytest.raises(AllocationError) as e:
infoblox.allocate_v6_network("LO")
assert e.value.args[0] == "Cannot allocate anything in [], check whether any IP space is available."
@responses.activate
def test_allocate_good_host(data_config_filename: PathLike):
_set_up_host_responses()
new_host = infoblox.allocate_host("test.lo.geant.net", "LO", [], "test host")
assert new_host == (
ipaddress.ip_address("10.255.255.129"),
ipaddress.ip_address("dead:beef::1"),
)
@responses.activate
def test_allocate_bad_host(data_config_filename: PathLike):
_set_up_host_responses()
with pytest.raises(AllocationError) as e:
infoblox.allocate_host("broken", "TRUNK", [], "Unavailable host")
assert e.value.args[0] == "Cannot find 1 available IP address in networks []."
@responses.activate
def test_delete_good_network(data_config_filename: PathLike):
responses.add(
method=responses.GET,
url="https://10.0.0.1/wapi/v2.12/network?network=10.255.255.0%2F26&_return_fields=comment%2Cextattrs%2Cnetwork%"
"2Cnetwork_view",
json=[
{
"_ref": "network/ZG5zLm5ldHdvcmskNjIuNDAuOTYuMC8yNC8w:10.255.255.0/26/default",
"network": "10.255.255.0/26",
"network_view": "default",
},
],
)
responses.add(
method=responses.DELETE,
url="https://10.0.0.1/wapi/v2.12/network/ZG5zLm5ldHdvcmskNjIuNDAuOTYuMC8yNC8w%3A10.255.255.0/26/default",
json=[],
)
infoblox.delete_network(ipaddress.IPv4Network("10.255.255.0/26"))
@responses.activate
def test_delete_non_existent_network(data_config_filename: PathLike):
responses.add(
method=responses.GET,
url="https://10.0.0.1/wapi/v2.12/network?network=10.255.255.0%2F26&_return_fields=comment%2Cextattrs%2Cnetwork%"
"2Cnetwork_view",
json=[],
)
with pytest.raises(DeletionError) as e:
infoblox.delete_network(ipaddress.IPv4Network("10.255.255.0/26"))
assert e.value.args[0] == "Could not find network 10.255.255.0/26, nothing has been deleted."
@responses.activate
def test_delete_good_host(data_config_filename: PathLike):
responses.add(
method=responses.GET,
url=re.compile(
r"https://10\.0\.0\.1/wapi/v2\.12/record%3Ahost\?(?:name=ha_lo\.gso|ipv4addr=10\.255\.255\.1)?.+",
),
json=[
{
"_ref": "record:host/ZG5zLmhvc3QkLl9kZWZhdWx0Lmdzby5oYV9sbw:ha_lo.gso/default",
"ipv4addrs": [
{
"_ref": "record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQuZ3NvLmhhX2xvLjEwLjI1NS4yNTUuM"
"S40.255.255.1/ha_lo.gso/default",
"configure_for_dhcp": False,
"host": "ha_lo.gso",
"ipv4addr": "10.255.255.1",
},
],
"ipv6addrs": [
{
"_ref": "record:host_ipv6addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQuZvLmhhX2xvLmRlYWQ6YmVlZjo6MS4"
":dead%3Abeef%3A%3A1/ha_lo.gso/default",
"configure_for_dhcp": False,
"host": "ha_lo.gso",
"ipv6addr": "dead:beef::1",
},
],
"name": "ha_lo.gso",
"view": "default",
},
],
)
responses.add(
method=responses.DELETE,
url=re.compile(
r"https://10\.0\.0\.1/wapi/v2\.12/record%3Ahost/.+(ha_lo\.gso|dead:beef::1|10\.255\.255\.1)/default",
),
json=[],
)
infoblox.delete_host_by_fqdn("ha_lo.gso")
infoblox.delete_host_by_ip(ipaddress.IPv4Address("10.255.255.1"))
infoblox.delete_host_by_ip(ipaddress.IPv6Address("dead:beef::1"))
@responses.activate
def test_delete_bad_host(data_config_filename: PathLike):
responses.add(
method=responses.GET,
url=re.compile(r".+"),
json=[],
)
with pytest.raises(DeletionError) as e:
infoblox.delete_host_by_ip(ipaddress.IPv4Address("10.255.255.1"))
assert e.value.args[0] == "Could not find host at 10.255.255.1, nothing has been deleted."
with pytest.raises(DeletionError) as e:
infoblox.delete_host_by_ip(ipaddress.IPv6Address("dead:beef::1"))
assert e.value.args[0] == "Could not find host at dead:beef::1, nothing has been deleted."
with pytest.raises(DeletionError) as e:
infoblox.delete_host_by_fqdn("fake.host.net")
assert e.value.args[0] == "Could not find host at fake.host.net, nothing has been deleted."