Merge "Radware: When a pip is needed, reuse the Port"

This commit is contained in:
Jenkins 2014-08-05 13:43:32 +00:00 committed by Gerrit Code Review
commit c417c63e1b
2 changed files with 62 additions and 18 deletions

View File

@ -196,11 +196,12 @@ class LoadBalancerDriver(abstract_driver.LoadBalancerAbstractDriver):
# if VIP and PIP are different, we need an IP address for the PIP
# so create port on PIP's network and use its IP address
if vip_network_id != pool_network_id:
pip_address = self._create_port_for_pip(
pip_address = self._get_pip(
context,
vip['tenant_id'],
_make_pip_name_from_vip(vip),
pool_network_id)
pool_network_id,
ext_vip['pool']['subnet_id'])
ext_vip['pip_address'] = pip_address
else:
ext_vip['pip_address'] = vip['address']
@ -613,24 +614,44 @@ class LoadBalancerDriver(abstract_driver.LoadBalancerAbstractDriver):
raise r_exc.WorkflowMissing(workflow=wf)
self.workflow_templates_exists = True
def _create_port_for_pip(self, context, tenant_id, port_name, subnet):
"""Creates port on subnet, returns that port's IP."""
def _get_pip(self, context, tenant_id, port_name,
network_id, subnet_id):
"""Get proxy IP
# create port, we just want any IP allocated to the port based on the
# network id, so setting 'fixed_ips' to ATTR_NOT_SPECIFIED
port_data = {
'tenant_id': tenant_id,
'name': port_name,
'network_id': subnet,
'mac_address': attributes.ATTR_NOT_SPECIFIED,
'admin_state_up': False,
'device_id': '',
'device_owner': 'neutron:' + constants.LOADBALANCER,
'fixed_ips': attributes.ATTR_NOT_SPECIFIED
Creates or get port on network_id, returns that port's IP
on the subnet_id.
"""
port_filter = {
'name': [port_name],
}
port = self.plugin._core_plugin.create_port(context,
{'port': port_data})
return port['fixed_ips'][0]['ip_address']
ports = self.plugin._core_plugin.get_ports(context,
filters=port_filter)
if not ports:
# create port, we just want any IP allocated to the port
# based on the network id and subnet_id
port_data = {
'tenant_id': tenant_id,
'name': port_name,
'network_id': network_id,
'mac_address': attributes.ATTR_NOT_SPECIFIED,
'admin_state_up': False,
'device_id': '',
'device_owner': 'neutron:' + constants.LOADBALANCER,
'fixed_ips': [{'subnet_id': subnet_id}]
}
port = self.plugin._core_plugin.create_port(context,
{'port': port_data})
else:
port = ports[0]
ips_on_subnet = [ip for ip in port['fixed_ips']
if ip['subnet_id'] == subnet_id]
if not ips_on_subnet:
raise Exception(_('Could not find or allocate '
'IP address for subnet id %s'),
subnet_id)
else:
return ips_on_subnet[0]['ip_address']
class vDirectRESTClient:

View File

@ -153,6 +153,29 @@ class TestLoadBalancerPlugin(TestLoadBalancerPluginBase):
self.addCleanup(radware_driver.completion_handler.join)
def test_get_pip(self):
"""Call _get_pip twice and verify that a Port is created once."""
port_dict = {'fixed_ips': [{'subnet_id': '10.10.10.10',
'ip_address': '11.11.11.11'}]}
self.plugin_instance._core_plugin.get_ports = mock.Mock(
return_value=[])
self.plugin_instance._core_plugin.create_port = mock.Mock(
return_value=port_dict)
radware_driver = self.plugin_instance.drivers['radware']
radware_driver._get_pip(context.get_admin_context(),
'tenant_id', 'port_name',
'network_id', '10.10.10.10')
self.plugin_instance._core_plugin.get_ports.assert_called_once()
self.plugin_instance._core_plugin.create_port.assert_called_once()
self.plugin_instance._core_plugin.create_port.reset_mock()
self.plugin_instance._core_plugin.get_ports.reset_mock()
self.plugin_instance._core_plugin.get_ports.return_value = [port_dict]
radware_driver._get_pip(context.get_admin_context(),
'tenant_id', 'port_name',
'network_id', '10.10.10.10')
self.plugin_instance._core_plugin.get_ports.assert_called_once()
self.plugin_instance._core_plugin.create_port.assert_has_calls([])
def test_rest_client_recover_was_called(self):
"""Call the real REST client and verify _recover is called."""
radware_driver = self.plugin_instance.drivers['radware']