LBaaS driver: Add provider support

The  OVN provider was added lately to Octavia [1] in addition
to the 'amphora' provider.
In order to create a LB with a specific provider the provider
name should be posted in load balancer creation request,
in case the provider name is not specified, Octavia default
provider will be used.

This patch enhances LBaaS driver to support LB provider functionality.
The functionality of translating K8S-services into Octavia-OVN
load balancers will be based on this change.

[1] 66502f19f2

Partially Implements: blueprint octavia-ovn-provider

Change-Id: I07532c0fd93d9269f317eace53b4baaa70df9201
This commit is contained in:
Yossi Boaron 2018-09-16 14:57:28 +03:00
parent fa927d4890
commit ed218a4a63
5 changed files with 77 additions and 8 deletions

View File

@ -423,7 +423,7 @@ class LBaaSDriver(DriverBase):
@abc.abstractmethod
def ensure_loadbalancer(self, name, project_id, subnet_id, ip,
security_groups_ids, service_type):
security_groups_ids, service_type, provider):
"""Get or create load balancer.
:param name: LoadBlancer name
@ -433,6 +433,7 @@ class LBaaSDriver(DriverBase):
:param security_groups_ids: security groups that should be allowed
access to the load balancer
:param service_type: K8s service type (ClusterIP or LoadBalancer)
:param provider: load balancer backend service
"""
raise NotImplementedError()

View File

@ -53,10 +53,11 @@ class LBaaSv2Driver(base.LBaaSDriver):
return "%s/%s/%s" % (loadbalancer.name, namespace, svc_name)
def ensure_loadbalancer(self, name, project_id, subnet_id, ip,
security_groups_ids=None, service_type=None):
security_groups_ids=None, service_type=None,
provider=None):
request = obj_lbaas.LBaaSLoadBalancer(
name=name, project_id=project_id, subnet_id=subnet_id, ip=ip,
security_groups=security_groups_ids)
security_groups=security_groups_ids, provider=provider)
response = self._ensure(request, self._create_loadbalancer,
self._find_loadbalancer)
if not response:
@ -329,13 +330,25 @@ class LBaaSv2Driver(base.LBaaSDriver):
def _create_loadbalancer(self, loadbalancer):
lbaas = clients.get_loadbalancer_client()
response = lbaas.create_loadbalancer({'loadbalancer': {
request = {'loadbalancer': {
'name': loadbalancer.name,
'project_id': loadbalancer.project_id,
'vip_address': str(loadbalancer.ip),
'vip_subnet_id': loadbalancer.subnet_id}})
'vip_subnet_id': loadbalancer.subnet_id}}
if loadbalancer.provider is not None:
request['loadbalancer']['provider'] = loadbalancer.provider
response = lbaas.create_loadbalancer(request)
loadbalancer.id = response['loadbalancer']['id']
loadbalancer.port_id = self._get_vip_port(loadbalancer).get("id")
if (loadbalancer.provider is not None and
loadbalancer.provider != response['loadbalancer']['provider']):
LOG.error("Request provider(%s) != Response provider(%s)",
loadbalancer.provider,
response['loadbalancer']['provider'])
return None
loadbalancer.provider = response['loadbalancer']['provider']
return loadbalancer

View File

@ -25,7 +25,8 @@ class LBaaSLoadBalancer(k_obj.KuryrK8sObjectBase):
# Version 1.0: Initial version
# Version 1.1: Added provider field and security_groups field.
# Version 1.2: Added support for security_groups=None
VERSION = '1.2'
# Version 1.3: Added support for provider=None
VERSION = '1.3'
fields = {
'id': obj_fields.UUIDField(),
@ -34,7 +35,8 @@ class LBaaSLoadBalancer(k_obj.KuryrK8sObjectBase):
'ip': obj_fields.IPAddressField(),
'subnet_id': obj_fields.UUIDField(),
'port_id': obj_fields.UUIDField(),
'provider': obj_fields.StringField(),
'provider': obj_fields.StringField(nullable=True,
default=None),
'security_groups': k_fields.ListOfUUIDField(nullable=True,
default=None),
}

View File

@ -256,6 +256,59 @@ class TestLBaaSv2Driver(test_base.TestCase):
getattr(ret, attr))
self.assertEqual(loadbalancer_id, ret.id)
def test_create_loadbalancer_provider_defined(self):
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
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',
security_groups=[],
provider='amphora')
loadbalancer_id = '00EE9E11-91C2-41CF-8FD4-7970579E5C4C'
req = {'loadbalancer': {
'name': loadbalancer.name,
'project_id': loadbalancer.project_id,
'vip_address': str(loadbalancer.ip),
'vip_subnet_id': loadbalancer.subnet_id,
'provider': loadbalancer.provider,
}}
resp = {'loadbalancer': {'id': loadbalancer_id, 'provider': 'amphora'}}
lbaas.create_loadbalancer.return_value = resp
m_driver._get_vip_port.return_value = {'id': mock.sentinel.port_id}
ret = cls._create_loadbalancer(m_driver, loadbalancer)
lbaas.create_loadbalancer.assert_called_once_with(req)
for attr in loadbalancer.obj_fields:
self.assertEqual(getattr(loadbalancer, attr),
getattr(ret, attr))
self.assertEqual(loadbalancer_id, ret.id)
def test_create_loadbalancer_provider_mismatch(self):
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver
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',
security_groups=[],
provider='amphora')
loadbalancer_id = '00EE9E11-91C2-41CF-8FD4-7970579E5C4C'
req = {'loadbalancer': {
'name': loadbalancer.name,
'project_id': loadbalancer.project_id,
'vip_address': str(loadbalancer.ip),
'vip_subnet_id': loadbalancer.subnet_id,
'provider': loadbalancer.provider,
}}
resp = {'loadbalancer': {'id': loadbalancer_id, 'provider': 'haproxy'}}
lbaas.create_loadbalancer.return_value = resp
m_driver._get_vip_port.return_value = {'id': mock.sentinel.port_id}
ret = cls._create_loadbalancer(m_driver, loadbalancer)
lbaas.create_loadbalancer.assert_called_once_with(req)
self.assertIsNone(ret)
def test_find_loadbalancer(self):
lbaas = self.useFixture(k_fix.MockLBaaSClient()).client
cls = d_lbaasv2.LBaaSv2Driver

View File

@ -25,7 +25,7 @@ object_data = {
'1.0-3ac4fcd50a555f433a78c67cb6a4cd52',
'LBaaSL7Rule': '1.0-276d9d678e1a8fc4b53fdbf3b2ac39ec',
'LBaaSListener': '1.0-a9e2d5c73687f5edc66fdb2f48650e15',
'LBaaSLoadBalancer': '1.2-d498ade2e705c3977eb66ff46133ed2b',
'LBaaSLoadBalancer': '1.3-8bc0a9bdbd160da67572aa38784378d1',
'LBaaSMember': '1.0-a770c6884c27d6d8c21186b27d0e2ccb',
'LBaaSPool': '1.1-6e77370d7632a902445444249eb77b01',
'LBaaSPortSpec': '1.0-51dfa3436bec32db3614720056fcc83f',