Add get_network_details_v2 in BaseOpenStackService
Partially-Implements: blueprint json-network-config Change-Id: Ia2a31518f87f34c234988fc512f1698617efdb10 Co-Authored-By: Adrian Vladu <avladu@cloudbasesolutions.com>
This commit is contained in:
parent
6782252536
commit
1cdf43ce23
@ -16,14 +16,28 @@
|
|||||||
import json
|
import json
|
||||||
import posixpath
|
import posixpath
|
||||||
|
|
||||||
|
import netaddr
|
||||||
from oslo_log import log as oslo_logging
|
from oslo_log import log as oslo_logging
|
||||||
|
|
||||||
from cloudbaseinit import conf as cloudbaseinit_conf
|
from cloudbaseinit import conf as cloudbaseinit_conf
|
||||||
|
from cloudbaseinit import exception
|
||||||
from cloudbaseinit.metadata.services import base
|
from cloudbaseinit.metadata.services import base
|
||||||
|
from cloudbaseinit.models import network as network_model
|
||||||
from cloudbaseinit.utils import debiface
|
from cloudbaseinit.utils import debiface
|
||||||
from cloudbaseinit.utils import encoding
|
from cloudbaseinit.utils import encoding
|
||||||
from cloudbaseinit.utils import x509constants
|
from cloudbaseinit.utils import x509constants
|
||||||
|
|
||||||
|
NETWORK_LINK_TYPE_PHYSICAL = "phy"
|
||||||
|
NETWORK_LINK_TYPE_BOND = "bond"
|
||||||
|
NETWORK_LINK_TYPE_VLAN = "vlan"
|
||||||
|
|
||||||
|
NETWORK_TYPE_IPV4 = "ipv4"
|
||||||
|
NETWORK_TYPE_IPV4_DHCP = "ipv4_dhcp"
|
||||||
|
NETWORK_TYPE_IPV6 = "ipv6"
|
||||||
|
NETWORK_TYPE_IPV6_DHCP = "ipv6_dhcp"
|
||||||
|
|
||||||
|
NETWORK_SERVICE_TYPE_DNS = "dns"
|
||||||
|
|
||||||
CONF = cloudbaseinit_conf.CONF
|
CONF = cloudbaseinit_conf.CONF
|
||||||
LOG = oslo_logging.getLogger(__name__)
|
LOG = oslo_logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -40,13 +54,19 @@ class BaseOpenStackService(base.BaseMetadataService):
|
|||||||
posixpath.join('openstack', 'latest', 'user_data'))
|
posixpath.join('openstack', 'latest', 'user_data'))
|
||||||
return self._get_cache_data(path)
|
return self._get_cache_data(path)
|
||||||
|
|
||||||
def _get_meta_data(self, version='latest'):
|
def _get_openstack_json_data(self, version, file_name):
|
||||||
path = posixpath.normpath(
|
path = posixpath.normpath(
|
||||||
posixpath.join('openstack', version, 'meta_data.json'))
|
posixpath.join('openstack', version, file_name))
|
||||||
data = self._get_cache_data(path, decode=True)
|
data = self._get_cache_data(path, decode=True)
|
||||||
if data:
|
if data:
|
||||||
return json.loads(data)
|
return json.loads(data)
|
||||||
|
|
||||||
|
def _get_meta_data(self, version='latest'):
|
||||||
|
return self._get_openstack_json_data(version, 'meta_data.json')
|
||||||
|
|
||||||
|
def _get_network_data(self, version='latest'):
|
||||||
|
return self._get_openstack_json_data(version, 'network_data.json')
|
||||||
|
|
||||||
def get_instance_id(self):
|
def get_instance_id(self):
|
||||||
return self._get_meta_data().get('uuid')
|
return self._get_meta_data().get('uuid')
|
||||||
|
|
||||||
@ -81,6 +101,158 @@ class BaseOpenStackService(base.BaseMetadataService):
|
|||||||
|
|
||||||
return debiface.parse(content)
|
return debiface.parse(content)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _ip_netmask_to_cidr(ip_address, netmask):
|
||||||
|
if netmask is None:
|
||||||
|
return ip_address
|
||||||
|
prefix_len = netaddr.IPNetwork(
|
||||||
|
u"%s/%s" % (ip_address, netmask)).prefixlen
|
||||||
|
return u"%s/%s" % (ip_address, prefix_len)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_network_data_links(links_data):
|
||||||
|
links = []
|
||||||
|
for link_data in links_data:
|
||||||
|
link_id = link_data.get("id")
|
||||||
|
mac = link_data.get("ethernet_mac_address")
|
||||||
|
mtu = link_data.get("mtu")
|
||||||
|
openstack_link_type = link_data.get("type")
|
||||||
|
|
||||||
|
bond = None
|
||||||
|
vlan_id = None
|
||||||
|
vlan_link = None
|
||||||
|
if openstack_link_type == NETWORK_LINK_TYPE_BOND:
|
||||||
|
link_type = network_model.LINK_TYPE_BOND
|
||||||
|
bond_links = link_data.get("bond_links")
|
||||||
|
bond_mode = link_data.get("bond_mode")
|
||||||
|
bond_xmit_hash_policy = link_data.get("bond_xmit_hash_policy")
|
||||||
|
|
||||||
|
if bond_mode not in network_model.AVAILABLE_BOND_TYPES:
|
||||||
|
raise exception.CloudbaseInitException(
|
||||||
|
"Unsupported bond mode: %s" % bond_mode)
|
||||||
|
|
||||||
|
if (bond_xmit_hash_policy is not None and
|
||||||
|
bond_xmit_hash_policy not in
|
||||||
|
network_model.AVAILABLE_BOND_LB_ALGORITHMS):
|
||||||
|
raise exception.CloudbaseInitException(
|
||||||
|
"Unsupported bond hash policy: %s" %
|
||||||
|
bond_xmit_hash_policy)
|
||||||
|
|
||||||
|
bond = network_model.Bond(
|
||||||
|
members=bond_links,
|
||||||
|
type=bond_mode,
|
||||||
|
lb_algorithm=bond_xmit_hash_policy,
|
||||||
|
lacp_rate=None,
|
||||||
|
)
|
||||||
|
elif openstack_link_type == NETWORK_LINK_TYPE_VLAN:
|
||||||
|
link_type = network_model.LINK_TYPE_VLAN
|
||||||
|
vlan_id = link_data.get("vlan_id")
|
||||||
|
vlan_link = link_data.get("vlan_link")
|
||||||
|
vlan_mac_address = link_data.get("vlan_mac_address")
|
||||||
|
if vlan_mac_address is not None:
|
||||||
|
mac = vlan_mac_address
|
||||||
|
else:
|
||||||
|
# Any other link type is considered physical
|
||||||
|
link_type = network_model.LINK_TYPE_PHYSICAL
|
||||||
|
|
||||||
|
link = network_model.Link(
|
||||||
|
id=link_id,
|
||||||
|
name=link_id,
|
||||||
|
type=link_type,
|
||||||
|
enabled=True,
|
||||||
|
mac_address=mac,
|
||||||
|
mtu=mtu,
|
||||||
|
bond=bond,
|
||||||
|
vlan_id=vlan_id,
|
||||||
|
vlan_link=vlan_link)
|
||||||
|
links.append(link)
|
||||||
|
|
||||||
|
return links
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_dns_data(services_data):
|
||||||
|
dns_nameservers = []
|
||||||
|
for service_data in services_data:
|
||||||
|
service_type = service_data.get("type")
|
||||||
|
if service_type != NETWORK_SERVICE_TYPE_DNS:
|
||||||
|
LOG.warn("Skipping unsupported service type: %s", service_type)
|
||||||
|
continue
|
||||||
|
|
||||||
|
address = service_data.get("address")
|
||||||
|
if address is not None:
|
||||||
|
dns_nameservers.append(address)
|
||||||
|
|
||||||
|
return dns_nameservers
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_network_data_networks(networks_data):
|
||||||
|
networks = []
|
||||||
|
for network_data in networks_data:
|
||||||
|
network_type = network_data.get("type")
|
||||||
|
if network_type not in [NETWORK_TYPE_IPV4, NETWORK_TYPE_IPV6]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
link_id = network_data.get("link")
|
||||||
|
ip_address = network_data.get("ip_address")
|
||||||
|
netmask = network_data.get("netmask")
|
||||||
|
address_cidr = BaseOpenStackService._ip_netmask_to_cidr(
|
||||||
|
ip_address, netmask)
|
||||||
|
|
||||||
|
routes = []
|
||||||
|
for route_data in network_data.get("routes", []):
|
||||||
|
gateway = route_data.get("gateway")
|
||||||
|
network = route_data.get("network")
|
||||||
|
netmask = route_data.get("netmask")
|
||||||
|
network_cidr = BaseOpenStackService._ip_netmask_to_cidr(
|
||||||
|
network, netmask)
|
||||||
|
|
||||||
|
route = network_model.Route(
|
||||||
|
network_cidr=network_cidr,
|
||||||
|
gateway=gateway
|
||||||
|
)
|
||||||
|
routes.append(route)
|
||||||
|
|
||||||
|
dns_nameservers = BaseOpenStackService._parse_dns_data(
|
||||||
|
network_data.get("services", []))
|
||||||
|
|
||||||
|
network = network_model.Network(
|
||||||
|
link=link_id,
|
||||||
|
address_cidr=address_cidr,
|
||||||
|
dns_nameservers=dns_nameservers,
|
||||||
|
routes=routes
|
||||||
|
)
|
||||||
|
networks.append(network)
|
||||||
|
|
||||||
|
return networks
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_network_data_services(services_data):
|
||||||
|
services = []
|
||||||
|
dns_nameservers = BaseOpenStackService._parse_dns_data(services_data)
|
||||||
|
if len(dns_nameservers):
|
||||||
|
service = network_model.NameServerService(
|
||||||
|
addresses=dns_nameservers,
|
||||||
|
search=None
|
||||||
|
)
|
||||||
|
services.append(service)
|
||||||
|
return services
|
||||||
|
|
||||||
|
def get_network_details_v2(self):
|
||||||
|
network_data = self._get_network_data()
|
||||||
|
|
||||||
|
links = self._parse_network_data_links(
|
||||||
|
network_data.get("links", []))
|
||||||
|
networks = self._parse_network_data_networks(
|
||||||
|
network_data.get("networks", []))
|
||||||
|
services = self._parse_network_data_services(
|
||||||
|
network_data.get("services", []))
|
||||||
|
|
||||||
|
return network_model.NetworkDetailsV2(
|
||||||
|
links=links,
|
||||||
|
networks=networks,
|
||||||
|
services=services
|
||||||
|
)
|
||||||
|
|
||||||
def get_admin_password(self):
|
def get_admin_password(self):
|
||||||
meta_data = self._get_meta_data()
|
meta_data = self._get_meta_data()
|
||||||
meta = meta_data.get('meta')
|
meta = meta_data.get('meta')
|
||||||
|
@ -17,12 +17,15 @@ import functools
|
|||||||
import posixpath
|
import posixpath
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
import netaddr
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import unittest.mock as mock
|
import unittest.mock as mock
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
from cloudbaseinit import conf as cloudbaseinit_conf
|
from cloudbaseinit import conf as cloudbaseinit_conf
|
||||||
|
from cloudbaseinit import exception
|
||||||
from cloudbaseinit.metadata.services import base
|
from cloudbaseinit.metadata.services import base
|
||||||
from cloudbaseinit.metadata.services import baseopenstackservice
|
from cloudbaseinit.metadata.services import baseopenstackservice
|
||||||
from cloudbaseinit.models import network as network_model
|
from cloudbaseinit.models import network as network_model
|
||||||
@ -265,3 +268,223 @@ class TestBaseOpenStackService(unittest.TestCase):
|
|||||||
|
|
||||||
def test_get_network_details(self):
|
def test_get_network_details(self):
|
||||||
self._partial_test_get_network_details()
|
self._partial_test_get_network_details()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _get_network_data():
|
||||||
|
return {
|
||||||
|
"links": [{
|
||||||
|
"ethernet_mac_address": mock.sentinel.link_mac1,
|
||||||
|
"type": baseopenstackservice.NETWORK_LINK_TYPE_PHYSICAL,
|
||||||
|
"id": mock.sentinel.link_id1,
|
||||||
|
"mtu": mock.sentinel.link_mtu1,
|
||||||
|
}, {
|
||||||
|
"ethernet_mac_address": mock.sentinel.link_mac2,
|
||||||
|
"type": mock.sentinel.another_link_type,
|
||||||
|
"id": mock.sentinel.link_id2,
|
||||||
|
"mtu": mock.sentinel.link_mtu2,
|
||||||
|
}, {
|
||||||
|
"bond_miimon": mock.sentinel.bond_miimon1,
|
||||||
|
"bond_xmit_hash_policy": mock.sentinel.bond_lb_algo1,
|
||||||
|
"ethernet_mac_address": mock.sentinel.bond_mac1,
|
||||||
|
"mtu": mock.sentinel.bond_mtu1,
|
||||||
|
"bond_mode": mock.sentinel.bond_type1,
|
||||||
|
"bond_links": [
|
||||||
|
mock.sentinel.link_id1,
|
||||||
|
mock.sentinel.link_id2,
|
||||||
|
],
|
||||||
|
"type": baseopenstackservice.NETWORK_LINK_TYPE_BOND,
|
||||||
|
"id": mock.sentinel.bond_id1,
|
||||||
|
}, {
|
||||||
|
"id": mock.sentinel.vlan_link_id1,
|
||||||
|
"type": baseopenstackservice.NETWORK_LINK_TYPE_VLAN,
|
||||||
|
"vlan_link": mock.sentinel.bond_id1,
|
||||||
|
"vlan_id": mock.sentinel.vlan_id1,
|
||||||
|
"mtu": mock.sentinel.vlan_mtu1,
|
||||||
|
"ethernet_mac_address": mock.sentinel.vlan_mac1,
|
||||||
|
}],
|
||||||
|
"networks": [{
|
||||||
|
"id": mock.sentinel.network_id1,
|
||||||
|
"network_id": mock.sentinel.network_openstack_id1,
|
||||||
|
"link": mock.sentinel.bond_id1,
|
||||||
|
"type": baseopenstackservice.NETWORK_TYPE_IPV4_DHCP,
|
||||||
|
}, {
|
||||||
|
"id": mock.sentinel.network_id2,
|
||||||
|
"type": baseopenstackservice.NETWORK_TYPE_IPV4,
|
||||||
|
"link": mock.sentinel.bond_id1,
|
||||||
|
"ip_address": mock.sentinel.ip_address1,
|
||||||
|
"netmask": mock.sentinel.netmask1,
|
||||||
|
"services": [{
|
||||||
|
"type": baseopenstackservice.NETWORK_SERVICE_TYPE_DNS,
|
||||||
|
"address": mock.sentinel.dns1,
|
||||||
|
}, {
|
||||||
|
"type": baseopenstackservice.NETWORK_SERVICE_TYPE_DNS,
|
||||||
|
"address": mock.sentinel.dns2
|
||||||
|
}],
|
||||||
|
"routes": [{
|
||||||
|
"network": mock.sentinel.route_network1,
|
||||||
|
"netmask": mock.sentinel.route_netmask1,
|
||||||
|
"gateway": mock.sentinel.route_gateway1,
|
||||||
|
}, {
|
||||||
|
"network": mock.sentinel.route_network2,
|
||||||
|
"netmask": mock.sentinel.route_netmask2,
|
||||||
|
"gateway": mock.sentinel.route_gateway2,
|
||||||
|
}],
|
||||||
|
"network_id": mock.sentinel.network_openstack_id2
|
||||||
|
}, {
|
||||||
|
"id": mock.sentinel.network_id3,
|
||||||
|
"type": baseopenstackservice.NETWORK_TYPE_IPV6,
|
||||||
|
"link": mock.sentinel.bond_id1,
|
||||||
|
"ip_address": mock.sentinel.ip_address_ipv61,
|
||||||
|
"routes": [{
|
||||||
|
"network": mock.sentinel.route_network_ipv61,
|
||||||
|
"gateway": mock.sentinel.route_gateway_ipv61,
|
||||||
|
}],
|
||||||
|
"network_id": mock.sentinel.network_openstack_id3
|
||||||
|
}],
|
||||||
|
"services": [{
|
||||||
|
"type": baseopenstackservice.NETWORK_SERVICE_TYPE_DNS,
|
||||||
|
"address": mock.sentinel.dns3,
|
||||||
|
}, {
|
||||||
|
"type": baseopenstackservice.NETWORK_SERVICE_TYPE_DNS,
|
||||||
|
"address": mock.sentinel.dns4
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
|
||||||
|
@mock.patch(MODPATH + ".BaseOpenStackService._get_network_data")
|
||||||
|
def _test_get_network_details_v2(self, mock_get_network_data,
|
||||||
|
invalid_bond_type=False,
|
||||||
|
invalid_bond_lb_algo=False):
|
||||||
|
mock.sentinel.ip_address1 = "10.0.0.1"
|
||||||
|
mock.sentinel.netmask1 = "255.255.255.0"
|
||||||
|
mock.sentinel.route_network1 = "172.16.0.0"
|
||||||
|
mock.sentinel.route_netmask1 = "255.255.0.0"
|
||||||
|
mock.sentinel.route_gateway1 = "172.16.1.1"
|
||||||
|
mock.sentinel.route_network2 = "0.0.0.0"
|
||||||
|
mock.sentinel.route_netmask2 = "0.0.0.0"
|
||||||
|
mock.sentinel.route_gateway2 = "10.0.0.254"
|
||||||
|
mock.sentinel.ip_address_ipv61 = "2001:cdba::3257:9652/24"
|
||||||
|
mock.sentinel.route_network_ipv61 = "::/0"
|
||||||
|
mock.sentinel.route_gateway_ipv61 = "fd00::1"
|
||||||
|
|
||||||
|
if invalid_bond_type:
|
||||||
|
mock.sentinel.bond_type1 = "invalid bond type"
|
||||||
|
else:
|
||||||
|
mock.sentinel.bond_type1 = network_model.BOND_TYPE_ACTIVE_BACKUP
|
||||||
|
|
||||||
|
if invalid_bond_lb_algo:
|
||||||
|
mock.sentinel.bond_lb_algo1 = "invalid lb algorithm"
|
||||||
|
else:
|
||||||
|
mock.sentinel.bond_lb_algo1 = network_model.BOND_LB_ALGO_L2
|
||||||
|
|
||||||
|
network_data = self._get_network_data()
|
||||||
|
|
||||||
|
mock_get_network_data.return_value = network_data
|
||||||
|
|
||||||
|
if invalid_bond_type or invalid_bond_lb_algo:
|
||||||
|
with self.assertRaises(exception.CloudbaseInitException):
|
||||||
|
self._service.get_network_details_v2()
|
||||||
|
return
|
||||||
|
|
||||||
|
network_details = self._service.get_network_details_v2()
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
len(network_data["links"]), len(network_details.links))
|
||||||
|
|
||||||
|
self.assertEqual(1, len([
|
||||||
|
l for l in network_details.links if
|
||||||
|
l.type == network_model.LINK_TYPE_PHYSICAL and
|
||||||
|
l.id == mock.sentinel.link_id1 and
|
||||||
|
l.name == mock.sentinel.link_id1 and
|
||||||
|
l.mac_address == mock.sentinel.link_mac1 and
|
||||||
|
l.mtu == mock.sentinel.link_mtu1]))
|
||||||
|
|
||||||
|
self.assertEqual(1, len([
|
||||||
|
l for l in network_details.links if
|
||||||
|
l.type == network_model.LINK_TYPE_PHYSICAL and
|
||||||
|
l.id == mock.sentinel.link_id2 and
|
||||||
|
l.name == mock.sentinel.link_id2 and
|
||||||
|
l.mac_address == mock.sentinel.link_mac2 and
|
||||||
|
l.mtu == mock.sentinel.link_mtu2]))
|
||||||
|
|
||||||
|
self.assertEqual(1, len([
|
||||||
|
l for l in network_details.links if
|
||||||
|
l.type == network_model.LINK_TYPE_BOND and
|
||||||
|
l.id == mock.sentinel.bond_id1 and
|
||||||
|
l.name == mock.sentinel.bond_id1 and
|
||||||
|
l.mtu == mock.sentinel.bond_mtu1 and
|
||||||
|
l.mac_address == mock.sentinel.bond_mac1 and
|
||||||
|
l.vlan_link is None and
|
||||||
|
l.vlan_id is None and
|
||||||
|
l.bond.type == network_model.BOND_TYPE_ACTIVE_BACKUP and
|
||||||
|
l.bond.members == [
|
||||||
|
mock.sentinel.link_id1, mock.sentinel.link_id2] and
|
||||||
|
l.bond.lb_algorithm == network_model.BOND_LB_ALGO_L2 and
|
||||||
|
l.bond.lacp_rate is None]))
|
||||||
|
|
||||||
|
self.assertEqual(1, len([
|
||||||
|
l for l in network_details.links if
|
||||||
|
l.type == network_model.LINK_TYPE_VLAN and
|
||||||
|
l.id == mock.sentinel.vlan_link_id1 and
|
||||||
|
l.name == mock.sentinel.vlan_link_id1 and
|
||||||
|
l.mac_address == mock.sentinel.vlan_mac1 and
|
||||||
|
l.mtu == mock.sentinel.vlan_mtu1 and
|
||||||
|
l.vlan_link == mock.sentinel.bond_id1 and
|
||||||
|
l.vlan_id == mock.sentinel.vlan_id1]))
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
len([n for n in network_data["networks"]
|
||||||
|
if n["type"] in [
|
||||||
|
baseopenstackservice.NETWORK_TYPE_IPV4,
|
||||||
|
baseopenstackservice.NETWORK_TYPE_IPV6]]),
|
||||||
|
len(network_details.networks))
|
||||||
|
|
||||||
|
def _get_cidr_address(ip_address, netmask):
|
||||||
|
prefix_len = netaddr.IPNetwork(
|
||||||
|
u"%s/%s" % (ip_address, netmask)).prefixlen
|
||||||
|
return u"%s/%s" % (ip_address, prefix_len)
|
||||||
|
|
||||||
|
address_cidr = _get_cidr_address(
|
||||||
|
mock.sentinel.ip_address1, mock.sentinel.netmask1)
|
||||||
|
|
||||||
|
network = [
|
||||||
|
n for n in network_details.networks
|
||||||
|
if n.address_cidr == address_cidr and
|
||||||
|
n.dns_nameservers == [mock.sentinel.dns1, mock.sentinel.dns2] and
|
||||||
|
n.link == mock.sentinel.bond_id1]
|
||||||
|
self.assertEqual(1, len(network))
|
||||||
|
|
||||||
|
network_cidr1 = _get_cidr_address(
|
||||||
|
mock.sentinel.route_network1, mock.sentinel.route_netmask1)
|
||||||
|
|
||||||
|
network_cidr2 = _get_cidr_address(
|
||||||
|
mock.sentinel.route_network2, mock.sentinel.route_netmask2)
|
||||||
|
|
||||||
|
self.assertEqual([
|
||||||
|
network_model.Route(
|
||||||
|
network_cidr=network_cidr1,
|
||||||
|
gateway=mock.sentinel.route_gateway1),
|
||||||
|
network_model.Route(
|
||||||
|
network_cidr=network_cidr2,
|
||||||
|
gateway=mock.sentinel.route_gateway2)],
|
||||||
|
network[0].routes)
|
||||||
|
|
||||||
|
network_ipv6 = [
|
||||||
|
n for n in network_details.networks
|
||||||
|
if n.address_cidr == mock.sentinel.ip_address_ipv61 and
|
||||||
|
n.link == mock.sentinel.bond_id1]
|
||||||
|
self.assertEqual(1, len(network_ipv6))
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
[network_model.NameServerService(
|
||||||
|
addresses=[mock.sentinel.dns3, mock.sentinel.dns4],
|
||||||
|
search=None)],
|
||||||
|
network_details.services)
|
||||||
|
|
||||||
|
def test_get_network_details_v2(self):
|
||||||
|
self._test_get_network_details_v2()
|
||||||
|
|
||||||
|
def test_get_network_details_v2_invalid_bond_type(self):
|
||||||
|
self._test_get_network_details_v2(invalid_bond_type=True)
|
||||||
|
|
||||||
|
def test_get_network_details_v2_invalid_bond_lb_algo(self):
|
||||||
|
self._test_get_network_details_v2(invalid_bond_lb_algo=True)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user