Services: Set missing SGs for haproxy provider
Since we started using Octavia we never got around to setting the
security groups for the legacy haproxy provider. This only affects when
using the native firewall as otherwise the haproxy internal ovs port
bypasses the SGs
Change-Id: Ie4a53dedf54472394f92fdfacddf0632e33f1f5b
Closes-Bug: 1749968
Co-Authored-By: Michał Dulko <mdulko@redhat.com>
Signed-off-by: Antoni Segura Puimedon <antonisp@celebdor.com>
(cherry picked from commit c9041d6979
)
This commit is contained in:
parent
b9be59ed0b
commit
b9006ce30f
|
@ -37,6 +37,7 @@ KURYR_PORT_NAME = 'kuryr-pool-port'
|
|||
|
||||
OCTAVIA_L2_MEMBER_MODE = "L2"
|
||||
OCTAVIA_L3_MEMBER_MODE = "L3"
|
||||
NEUTRON_LBAAS_HAPROXY_PROVIDER = 'haproxy'
|
||||
|
||||
VIF_POOL_POPULATE = '/populatePool'
|
||||
VIF_POOL_FREE = '/freePool'
|
||||
|
|
|
@ -22,6 +22,7 @@ from oslo_utils import excutils
|
|||
from oslo_utils import timeutils
|
||||
|
||||
from kuryr_kubernetes import clients
|
||||
from kuryr_kubernetes import constants as const
|
||||
from kuryr_kubernetes.controller.drivers import base
|
||||
from kuryr_kubernetes import exceptions as k_exc
|
||||
from kuryr_kubernetes.objects import lbaas as obj_lbaas
|
||||
|
@ -48,8 +49,22 @@ class LBaaSv2Driver(base.LBaaSDriver):
|
|||
# deleted externally between 'create' and 'find'
|
||||
raise k_exc.ResourceNotReady(request)
|
||||
|
||||
# TODO(ivc): handle security groups
|
||||
|
||||
# We only handle SGs for legacy LBaaSv2, Octavia handles it dynamically
|
||||
# according to listener ports.
|
||||
if response.provider == const.NEUTRON_LBAAS_HAPROXY_PROVIDER:
|
||||
vip_port_id = response.port_id
|
||||
neutron = clients.get_neutron_client()
|
||||
try:
|
||||
neutron.update_port(
|
||||
vip_port_id,
|
||||
{'port': {'security_groups': security_groups_ids}})
|
||||
except n_exc.NeutronClientException:
|
||||
LOG.exception('Failed to set SG for LBaaS v2 VIP port %s.',
|
||||
vip_port_id)
|
||||
# NOTE(dulek): `endpoints` arguments on release_loadbalancer()
|
||||
# is ignored for some reason, so just pass None.
|
||||
self.release_loadbalancer(None, response)
|
||||
raise
|
||||
return response
|
||||
|
||||
def release_loadbalancer(self, endpoints, loadbalancer):
|
||||
|
@ -136,6 +151,7 @@ class LBaaSv2Driver(base.LBaaSDriver):
|
|||
'vip_subnet_id': loadbalancer.subnet_id}})
|
||||
loadbalancer.id = response['loadbalancer']['id']
|
||||
loadbalancer.port_id = self._get_vip_port_id(loadbalancer)
|
||||
loadbalancer.provider = response['loadbalancer']['provider']
|
||||
return loadbalancer
|
||||
|
||||
def _find_loadbalancer(self, loadbalancer):
|
||||
|
@ -150,6 +166,7 @@ class LBaaSv2Driver(base.LBaaSDriver):
|
|||
try:
|
||||
loadbalancer.id = response['loadbalancers'][0]['id']
|
||||
loadbalancer.port_id = self._get_vip_port_id(loadbalancer)
|
||||
loadbalancer.provider = response['loadbalancers'][0]['provider']
|
||||
except (KeyError, IndexError):
|
||||
return None
|
||||
|
||||
|
|
|
@ -22,7 +22,9 @@ from kuryr_kubernetes.objects import fields as k_fields
|
|||
|
||||
@obj_base.VersionedObjectRegistry.register
|
||||
class LBaaSLoadBalancer(k_obj.KuryrK8sObjectBase):
|
||||
VERSION = '1.0'
|
||||
# Version 1.0: Initial version
|
||||
# Version 1.1: Added provider field
|
||||
VERSION = '1.1'
|
||||
|
||||
fields = {
|
||||
'id': obj_fields.UUIDField(),
|
||||
|
@ -31,6 +33,7 @@ class LBaaSLoadBalancer(k_obj.KuryrK8sObjectBase):
|
|||
'ip': obj_fields.IPAddressField(),
|
||||
'subnet_id': obj_fields.UUIDField(),
|
||||
'port_id': obj_fields.UUIDField(),
|
||||
'provider': obj_fields.StringField(),
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import mock
|
|||
|
||||
from neutronclient.common import exceptions as n_exc
|
||||
|
||||
from kuryr_kubernetes import constants as const
|
||||
from kuryr_kubernetes.controller.drivers import lbaasv2 as d_lbaasv2
|
||||
from kuryr_kubernetes import exceptions as k_exc
|
||||
from kuryr_kubernetes.objects import lbaas as obj_lbaas
|
||||
|
@ -26,19 +27,21 @@ from kuryr_kubernetes.tests.unit import kuryr_fixtures as k_fix
|
|||
|
||||
class TestLBaaSv2Driver(test_base.TestCase):
|
||||
def test_ensure_loadbalancer(self):
|
||||
neutron = self.useFixture(k_fix.MockNeutronClient()).client
|
||||
cls = d_lbaasv2.LBaaSv2Driver
|
||||
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
|
||||
expected_resp = mock.sentinel.expected_resp
|
||||
expected_resp = obj_lbaas.LBaaSLoadBalancer(
|
||||
provider='octavia', port_id='D3FA400A-F543-4B91-9CD3-047AF0CE42E2')
|
||||
namespace = 'TEST_NAMESPACE'
|
||||
name = 'TEST_NAME'
|
||||
project_id = 'TEST_PROJECT'
|
||||
subnet_id = 'D3FA400A-F543-4B91-9CD3-047AF0CE42D1'
|
||||
ip = '1.2.3.4'
|
||||
# TODO(ivc): handle security groups
|
||||
sg_ids = []
|
||||
sg_ids = ['foo', 'bar']
|
||||
endpoints = {'metadata': {'namespace': namespace, 'name': name}}
|
||||
|
||||
m_driver._ensure.return_value = expected_resp
|
||||
neutron.update_port = mock.Mock()
|
||||
resp = cls.ensure_loadbalancer(m_driver, endpoints, project_id,
|
||||
subnet_id, ip, sg_ids)
|
||||
m_driver._ensure.assert_called_once_with(mock.ANY,
|
||||
|
@ -50,6 +53,74 @@ class TestLBaaSv2Driver(test_base.TestCase):
|
|||
self.assertEqual(subnet_id, req.subnet_id)
|
||||
self.assertEqual(ip, str(req.ip))
|
||||
self.assertEqual(expected_resp, resp)
|
||||
neutron.update_port.assert_not_called()
|
||||
|
||||
def test_ensure_loadbalancer_sg_updated(self):
|
||||
neutron = self.useFixture(k_fix.MockNeutronClient()).client
|
||||
cls = d_lbaasv2.LBaaSv2Driver
|
||||
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
|
||||
expected_resp = obj_lbaas.LBaaSLoadBalancer(
|
||||
provider=const.NEUTRON_LBAAS_HAPROXY_PROVIDER,
|
||||
port_id='D3FA400A-F543-4B91-9CD3-047AF0CE42E2')
|
||||
namespace = 'TEST_NAMESPACE'
|
||||
name = 'TEST_NAME'
|
||||
project_id = 'TEST_PROJECT'
|
||||
subnet_id = 'D3FA400A-F543-4B91-9CD3-047AF0CE42D1'
|
||||
ip = '1.2.3.4'
|
||||
sg_ids = ['foo', 'bar']
|
||||
endpoints = {'metadata': {'namespace': namespace, 'name': name}}
|
||||
|
||||
m_driver._ensure.return_value = expected_resp
|
||||
neutron.update_port = mock.Mock()
|
||||
resp = cls.ensure_loadbalancer(m_driver, endpoints, project_id,
|
||||
subnet_id, ip, sg_ids)
|
||||
m_driver._ensure.assert_called_once_with(mock.ANY,
|
||||
m_driver._create_loadbalancer,
|
||||
m_driver._find_loadbalancer)
|
||||
req = m_driver._ensure.call_args[0][0]
|
||||
self.assertEqual("%s/%s" % (namespace, name), req.name)
|
||||
self.assertEqual(project_id, req.project_id)
|
||||
self.assertEqual(subnet_id, req.subnet_id)
|
||||
self.assertEqual(ip, str(req.ip))
|
||||
self.assertEqual(expected_resp, resp)
|
||||
neutron.update_port.assert_called_once_with(
|
||||
'D3FA400A-F543-4B91-9CD3-047AF0CE42E2',
|
||||
{'port': {'security_groups': ['foo', 'bar']}})
|
||||
|
||||
def test_ensure_loadbalancer_neutron_error(self):
|
||||
neutron = self.useFixture(k_fix.MockNeutronClient()).client
|
||||
cls = d_lbaasv2.LBaaSv2Driver
|
||||
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
|
||||
expected_resp = obj_lbaas.LBaaSLoadBalancer(
|
||||
provider=const.NEUTRON_LBAAS_HAPROXY_PROVIDER,
|
||||
port_id='D3FA400A-F543-4B91-9CD3-047AF0CE42E2')
|
||||
namespace = 'TEST_NAMESPACE'
|
||||
name = 'TEST_NAME'
|
||||
project_id = 'TEST_PROJECT'
|
||||
subnet_id = 'D3FA400A-F543-4B91-9CD3-047AF0CE42D1'
|
||||
ip = '1.2.3.4'
|
||||
sg_ids = ['foo', 'bar']
|
||||
endpoints = {'metadata': {'namespace': namespace, 'name': name}}
|
||||
|
||||
m_driver._ensure.return_value = expected_resp
|
||||
neutron.update_port = mock.Mock(
|
||||
side_effect=n_exc.NeutronClientException)
|
||||
self.assertRaises(n_exc.NeutronClientException,
|
||||
cls.ensure_loadbalancer, m_driver, endpoints,
|
||||
project_id, subnet_id, ip, sg_ids)
|
||||
m_driver._ensure.assert_called_once_with(mock.ANY,
|
||||
m_driver._create_loadbalancer,
|
||||
m_driver._find_loadbalancer)
|
||||
req = m_driver._ensure.call_args[0][0]
|
||||
self.assertEqual("%s/%s" % (namespace, name), req.name)
|
||||
self.assertEqual(project_id, req.project_id)
|
||||
self.assertEqual(subnet_id, req.subnet_id)
|
||||
self.assertEqual(ip, str(req.ip))
|
||||
neutron.update_port.assert_called_once_with(
|
||||
'D3FA400A-F543-4B91-9CD3-047AF0CE42E2',
|
||||
{'port': {'security_groups': ['foo', 'bar']}})
|
||||
m_driver.release_loadbalancer.assert_called_once_with(None,
|
||||
expected_resp)
|
||||
|
||||
def test_ensure_loadbalancer_not_ready(self):
|
||||
cls = d_lbaasv2.LBaaSv2Driver
|
||||
|
@ -227,8 +298,9 @@ class TestLBaaSv2Driver(test_base.TestCase):
|
|||
'project_id': loadbalancer.project_id,
|
||||
'tenant_id': loadbalancer.project_id,
|
||||
'vip_address': str(loadbalancer.ip),
|
||||
'vip_subnet_id': loadbalancer.subnet_id}}
|
||||
resp = {'loadbalancer': {'id': loadbalancer_id}}
|
||||
'vip_subnet_id': loadbalancer.subnet_id,
|
||||
}}
|
||||
resp = {'loadbalancer': {'id': loadbalancer_id, 'provider': 'haproxy'}}
|
||||
neutron.create_loadbalancer.return_value = resp
|
||||
|
||||
ret = cls._create_loadbalancer(m_driver, loadbalancer)
|
||||
|
@ -244,9 +316,11 @@ class TestLBaaSv2Driver(test_base.TestCase):
|
|||
m_driver = mock.Mock(spec=d_lbaasv2.LBaaSv2Driver)
|
||||
loadbalancer = obj_lbaas.LBaaSLoadBalancer(
|
||||
name='TEST_NAME', project_id='TEST_PROJECT', ip='1.2.3.4',
|
||||
subnet_id='D3FA400A-F543-4B91-9CD3-047AF0CE42D1')
|
||||
subnet_id='D3FA400A-F543-4B91-9CD3-047AF0CE42D1',
|
||||
provider='haproxy')
|
||||
loadbalancer_id = '00EE9E11-91C2-41CF-8FD4-7970579E5C4C'
|
||||
resp = {'loadbalancers': [{'id': loadbalancer_id}]}
|
||||
resp = {'loadbalancers': [{'id': loadbalancer_id,
|
||||
'provider': 'haproxy'}]}
|
||||
neutron.list_loadbalancers.return_value = resp
|
||||
|
||||
ret = cls._find_loadbalancer(m_driver, loadbalancer)
|
||||
|
|
Loading…
Reference in New Issue