Network driver should generate network configs

Currently the network task configures the network
configs, this means other driver cannot use the data
they need to.

Change-Id: I3b6e25f3c7f7343d89b9e6844382e7696ea5d4be
Closes-Bug: #1581303
This commit is contained in:
ptoohill1 2016-05-16 15:12:05 -05:00
parent 2f33429db9
commit 65cc70ec26
7 changed files with 109 additions and 55 deletions

View File

@ -363,28 +363,7 @@ class GetAmphoraeNetworkConfigs(BaseNetworkTask):
def execute(self, loadbalancer):
LOG.debug("Retrieving vip network details.")
vip_subnet = self.network_driver.get_subnet(loadbalancer.vip.subnet_id)
vip_port = self.network_driver.get_port(loadbalancer.vip.port_id)
amp_net_configs = {}
for amp in loadbalancer.amphorae:
if amp.status != constants.DELETED:
LOG.debug("Retrieving network details for amphora %s", amp.id)
vrrp_port = self.network_driver.get_port(amp.vrrp_port_id)
vrrp_subnet = self.network_driver.get_subnet(
vrrp_port.get_subnet_id(amp.vrrp_ip))
ha_port = self.network_driver.get_port(amp.ha_port_id)
ha_subnet = self.network_driver.get_subnet(
ha_port.get_subnet_id(amp.ha_ip))
amp_net_configs[amp.id] = n_data_models.AmphoraNetworkConfig(
amphora=amp,
vip_subnet=vip_subnet,
vip_port=vip_port,
vrrp_subnet=vrrp_subnet,
vrrp_port=vrrp_port,
ha_subnet=ha_subnet,
ha_port=ha_port
)
return amp_net_configs
return self.network_driver.get_network_configs(loadbalancer)
class FailoverPreparationForAmphora(BaseNetworkTask):

View File

@ -235,3 +235,25 @@ class AbstractNetworkDriver(object):
:raises: PlugNetworkException, AmphoraNotFound, NetworkNotFound
"""
pass
@abc.abstractmethod
def get_network_configs(self, load_balancer):
"""Retrieve network configurations
This method assumes that a dictionary of AmphoraNetworkConfigs keyed
off of the related amphora id are returned.
The configs contain data pertaining to each amphora that is later
used for finalization of the entire load balancer configuration.
The data provided to these configs is left up to the driver, this
means the driver is responsible for providing data that is appropriate
for the amphora network configurations.
Example return:
{<amphora.id>: <AmphoraNetworkConfig>}
:param load_balancer: The load_balancer configuration
:return: dict of octavia.network.data_models.AmphoraNetworkConfig
keyed off of the amphora id the config is associated with.
:raises: NotFound, NetworkNotFound, SubnetNotFound, PortNotFound
"""
pass

View File

@ -25,6 +25,7 @@ from octavia.common import constants
from octavia.common import data_models
from octavia.i18n import _LE, _LI, _LW
from octavia.network import base
from octavia.network import data_models as n_data_models
from octavia.network.drivers.neutron import base as neutron_base
from octavia.network.drivers.neutron import utils
@ -462,3 +463,28 @@ class AllowedAddressPairsDriver(neutron_base.BaseNeutronDriver):
port_id=port.id)
LOG.exception(message)
raise base.PlugNetworkException(message)
def get_network_configs(self, loadbalancer):
vip_subnet = self.get_subnet(loadbalancer.vip.subnet_id)
vip_port = self.get_port(loadbalancer.vip.port_id)
amp_configs = {}
for amp in loadbalancer.amphorae:
if amp.status != constants.DELETED:
LOG.debug("Retrieving network details for amphora %s", amp.id)
vrrp_port = self.get_port(amp.vrrp_port_id)
vrrp_subnet = self.get_subnet(
vrrp_port.get_subnet_id(amp.vrrp_ip))
ha_port = self.get_port(amp.ha_port_id)
ha_subnet = self.get_subnet(
ha_port.get_subnet_id(amp.ha_ip))
amp_configs[amp.id] = n_data_models.AmphoraNetworkConfig(
amphora=amp,
vip_subnet=vip_subnet,
vip_port=vip_port,
vrrp_subnet=vrrp_subnet,
vrrp_port=vrrp_port,
ha_subnet=ha_subnet,
ha_port=ha_port
)
return amp_configs

View File

@ -131,6 +131,12 @@ class NoopManager(object):
self.networkconfigconfig[(compute_id, port)] = (
compute_id, port, 'plug_port')
def get_network_configs(self, loadbalancer):
LOG.debug("Network %s no-op, get_network_configs loadbalancer id %s ",
self.__class__.__name__, loadbalancer.id)
self.networkconfigconfig[(loadbalancer)] = (
loadbalancer, 'get_network_configs')
class NoopNetworkDriver(driver_base.AbstractNetworkDriver):
def __init__(self):
@ -176,3 +182,6 @@ class NoopNetworkDriver(driver_base.AbstractNetworkDriver):
def plug_port(self, compute_id, port):
return self.driver.plug_port(compute_id, port)
def get_network_configs(self, loadbalancer):
return self.driver.get_network_configs(loadbalancer)

View File

@ -399,40 +399,10 @@ class TestNetworkTasks(base.TestCase):
mock_driver.update_vip.assert_called_once_with(lb)
def test_get_amphorae_network_configs(self, mock_driver):
lb = o_data_models.LoadBalancer()
net_task = network_tasks.GetAmphoraeNetworkConfigs()
net_task.execute(LB)
mock_driver.get_subnet.assert_called_once_with(SUBNET_ID)
mock_driver.get_port.assert_called_once_with(PORT_ID)
mock_driver.reset_mock()
self.amphora_mock.status = constants.DELETED
self.load_balancer_mock.amphorae = [self.amphora_mock]
net_task = network_tasks.GetAmphoraeNetworkConfigs()
configs = net_task.execute(self.load_balancer_mock)
self.assertEqual({}, configs)
mock_driver.reset_mock()
self.vip_mock.port_id = 1
self.amphora_mock.status = constants.ACTIVE
self.amphora_mock.vrrp_port_id = 2
self.amphora_mock.vrrp_ip = "10.0.0.1"
self.amphora_mock.ha_port_id = 3
self.amphora_mock.ha_ip = "10.0.0.2"
self.load_balancer_mock.amphorae = [self.amphora_mock]
net_task = network_tasks.GetAmphoraeNetworkConfigs()
configs = net_task.execute(self.load_balancer_mock)
vip_port_id = mock.call(1)
vrrp_port_id_call = mock.call(2)
ha_port_id_call = mock.call(3)
vrrp_port_subnet_call = mock.call().get_subnet_id('10.0.0.1')
ha_port_subnet_call = mock.call().get_subnet_id('10.0.0.2')
mock_driver.get_port.assert_has_calls([vip_port_id,
vrrp_port_id_call,
vrrp_port_subnet_call,
ha_port_id_call,
ha_port_subnet_call])
self.assertEqual(1, len(configs))
net_task.execute(lb)
mock_driver.get_network_configs.assert_called_once_with(lb)
def test_failover_preparation_for_amphora(self, mock_driver):
failover = network_tasks.FailoverPreparationForAmphora()

View File

@ -619,3 +619,44 @@ class TestAllowedAddressPairsDriver(base.TestCase):
self.driver.plug_port,
amphora,
port)
def test_get_network_configs(self):
amphora_mock = mock.MagicMock()
load_balancer_mock = mock.MagicMock()
vip_mock = mock.MagicMock()
amphora_mock.status = constants.DELETED
load_balancer_mock.amphorae = [amphora_mock]
show_port = self.driver.neutron_client.show_port
show_port.return_value = n_constants.MOCK_NEUTRON_PORT
fake_subnet = {'subnet': {
'id': n_constants.MOCK_SUBNET_ID,
'gateway_ip': n_constants.MOCK_IP_ADDRESS,
'cidr': n_constants.MOCK_CIDR}}
show_subnet = self.driver.neutron_client.show_subnet
show_subnet.return_value = fake_subnet
configs = self.driver.get_network_configs(load_balancer_mock)
self.assertEqual({}, configs)
vip_mock.port_id = 1
amphora_mock.id = 222
amphora_mock.status = constants.ACTIVE
amphora_mock.vrrp_port_id = 2
amphora_mock.vrrp_ip = "10.0.0.1"
amphora_mock.ha_port_id = 3
amphora_mock.ha_ip = "10.0.0.2"
load_balancer_mock.amphorae = [amphora_mock]
configs = self.driver.get_network_configs(load_balancer_mock)
self.assertEqual(1, len(configs))
config = configs[222]
# TODO(ptoohill): find a way to return different items for multiple
# calls to the same method, right now each call to show subnet
# will return the same values if a method happens to call it
# multiple times for different subnets. We should be able to verify
# different requests get different expected data.
expected_port_id = n_constants.MOCK_NEUTRON_PORT['port']['id']
self.assertEqual(expected_port_id, config.ha_port.id)
self.assertEqual(expected_port_id, config.vrrp_port.id)
expected_subnet_id = fake_subnet['subnet']['id']
self.assertEqual(expected_subnet_id, config.ha_subnet.id)
self.assertEqual(expected_subnet_id, config.vrrp_subnet.id)

View File

@ -127,3 +127,10 @@ class TestNoopNetworkDriver(base.TestCase):
(self.compute_id, self.port, 'plug_port'),
self.driver.driver.networkconfigconfig[self.compute_id, self.port]
)
def test_get_network_configs(self):
self.driver.get_network_configs(self.load_balancer)
self.assertEqual(
(self.load_balancer, 'get_network_configs'),
self.driver.driver.networkconfigconfig[self.load_balancer]
)