Migrate loadbalancer to Octavia

Change-Id: I4c87e5ce2eb978c45d07c2207abdd8097deebb3a
Implements: blueprint migrate-lbaas-to-octavia
This commit is contained in:
liyi 2017-11-27 14:07:07 +08:00
parent d66803026a
commit dbf0abacd8
11 changed files with 555 additions and 436 deletions

View File

@ -39,6 +39,7 @@ class SenlinDriver(object):
self.compute = backend.compute
self.loadbalancing = backend.loadbalancing
self.network = backend.network
self.octavia = backend.octavia
self.orchestration = backend.orchestration
self.telemetry = backend.telemetry
self.identity = backend.identity

View File

@ -18,6 +18,7 @@ from senlin.drivers.openstack import lbaas
from senlin.drivers.openstack import mistral_v2
from senlin.drivers.openstack import neutron_v2
from senlin.drivers.openstack import nova_v2
from senlin.drivers.openstack import octavia_v2
from senlin.drivers.openstack import zaqar_v2
@ -26,6 +27,7 @@ identity = keystone_v3.KeystoneClient
loadbalancing = lbaas.LoadBalancerDriver
message = zaqar_v2.ZaqarClient
network = neutron_v2.NeutronClient
octavia = octavia_v2.OctaviaClient
orchestration = heat_v1.HeatClient
telemetry = ceilometer_v2.CeilometerClient
workflow = mistral_v2.MistralClient

View File

@ -20,6 +20,7 @@ from senlin.common import exception
from senlin.common.i18n import _
from senlin.drivers import base
from senlin.drivers.openstack import neutron_v2 as neutronclient
from senlin.drivers.openstack import octavia_v2 as octaviaclient
from senlin.engine import node as nodem
LOG = logging.getLogger(__name__)
@ -31,9 +32,26 @@ class LoadBalancerDriver(base.DriverBase):
def __init__(self, params):
super(LoadBalancerDriver, self).__init__(params)
self.lb_status_timeout = 600
self._oc = None
self._nc = None
def oc(self):
"""Octavia client
:return: octavia client
"""
if self._oc:
return self._oc
self._oc = octaviaclient.OctaviaClient(self.conn_params)
return self._oc
def nc(self):
"""Neutron client
:return: neutron client
"""
if self._nc:
return self._nc
@ -54,7 +72,7 @@ class LoadBalancerDriver(base.DriverBase):
waited = 0
while waited < self.lb_status_timeout:
try:
lb = self.nc().loadbalancer_get(lb_id, ignore_missing=True)
lb = self.oc().loadbalancer_get(lb_id, ignore_missing=True)
except exception.InternalError as ex:
msg = ('Failed in getting loadbalancer: %s.'
% six.text_type(ex))
@ -99,7 +117,7 @@ class LoadBalancerDriver(base.DriverBase):
return False, msg
subnet_id = subnet.id
try:
lb = self.nc().loadbalancer_create(subnet_id,
lb = self.oc().loadbalancer_create(subnet_id,
vip.get('address', None),
vip['admin_state_up'])
except exception.InternalError as ex:
@ -119,7 +137,7 @@ class LoadBalancerDriver(base.DriverBase):
# Create listener
try:
listener = self.nc().listener_create(lb.id, vip['protocol'],
listener = self.oc().listener_create(lb.id, vip['protocol'],
vip['protocol_port'],
vip.get('connection_limit',
None),
@ -138,7 +156,7 @@ class LoadBalancerDriver(base.DriverBase):
# Create pool
try:
pool = self.nc().pool_create(pool['lb_method'], listener.id,
pool = self.oc().pool_create(pool['lb_method'], listener.id,
pool['protocol'],
pool['admin_state_up'])
except exception.InternalError as ex:
@ -158,7 +176,7 @@ class LoadBalancerDriver(base.DriverBase):
# Create health monitor
try:
health_monitor = self.nc().healthmonitor_create(
health_monitor = self.oc().healthmonitor_create(
hm['type'], hm['delay'], hm['timeout'], hm['max_retries'],
pool.id, hm['admin_state_up'], hm['http_method'],
hm['url_path'], hm['expected_codes'])
@ -177,8 +195,10 @@ class LoadBalancerDriver(base.DriverBase):
return True, result
def lb_find(self, name_or_id, ignore_missing=False):
return self.nc().loadbalancer_get(name_or_id, ignore_missing)
def lb_find(self, name_or_id, ignore_missing=False,
show_deleted=False):
return self.oc().loadbalancer_get(name_or_id, ignore_missing,
show_deleted)
def lb_delete(self, **kwargs):
"""Delete a Neutron lbaas instance
@ -188,10 +208,15 @@ class LoadBalancerDriver(base.DriverBase):
"""
lb_id = kwargs.pop('loadbalancer')
lb = self.lb_find(lb_id, ignore_missing=True)
if lb is None:
LOG.debug('Loadbalancer (%s) is not existing.', lb_id)
return True, _('LB deletion succeeded')
healthmonitor_id = kwargs.pop('healthmonitor', None)
if healthmonitor_id:
try:
self.nc().healthmonitor_delete(healthmonitor_id)
self.oc().healthmonitor_delete(healthmonitor_id)
except exception.InternalError as ex:
msg = ('Failed in deleting healthmonitor: %s.'
% six.text_type(ex))
@ -206,7 +231,7 @@ class LoadBalancerDriver(base.DriverBase):
pool_id = kwargs.pop('pool', None)
if pool_id:
try:
self.nc().pool_delete(pool_id)
self.oc().pool_delete(pool_id)
except exception.InternalError as ex:
msg = ('Failed in deleting lb pool: %s.'
% six.text_type(ex))
@ -220,7 +245,7 @@ class LoadBalancerDriver(base.DriverBase):
listener_id = kwargs.pop('listener', None)
if listener_id:
try:
self.nc().listener_delete(listener_id)
self.oc().listener_delete(listener_id)
except exception.InternalError as ex:
msg = ('Failed in deleting listener: %s.'
% six.text_type(ex))
@ -231,7 +256,7 @@ class LoadBalancerDriver(base.DriverBase):
msg = 'Failed in deleting listener (%s).' % listener_id
return False, msg
self.nc().loadbalancer_delete(lb_id)
self.oc().loadbalancer_delete(lb_id)
res = self._wait_for_lb_ready(lb_id, ignore_not_found=True)
if res is False:
msg = 'Failed in deleting loadbalancer (%s).' % lb_id
@ -284,7 +309,7 @@ class LoadBalancerDriver(base.DriverBase):
if not res:
msg = 'Loadbalancer %s is not ready.' % lb_id
raise exception.Error(msg)
member = self.nc().pool_member_create(pool_id, address, port,
member = self.oc().pool_member_create(pool_id, address, port,
subnet_obj.id)
except (exception.InternalError, exception.Error) as ex:
msg = ('Failed in creating lb pool member: %s.'
@ -318,7 +343,7 @@ class LoadBalancerDriver(base.DriverBase):
if not res:
msg = 'Loadbalancer %s is not ready.' % lb_id
raise exception.Error(msg)
self.nc().pool_member_delete(pool_id, member_id)
self.oc().pool_member_delete(pool_id, member_id)
except (exception.InternalError, exception.Error) as ex:
msg = ('Failed in removing member %(m)s from pool %(p)s: '
'%(ex)s' % {'m': member_id, 'p': pool_id,

View File

@ -41,144 +41,6 @@ class NeutronClient(base.DriverBase):
subnet = self.conn.network.find_subnet(name_or_id, ignore_missing)
return subnet
@sdk.translate_exception
def loadbalancer_get(self, name_or_id, ignore_missing=False):
lb = self.conn.network.find_load_balancer(name_or_id, ignore_missing)
return lb
@sdk.translate_exception
def loadbalancer_create(self, vip_subnet_id, vip_address=None,
admin_state_up=True, name=None, description=None):
kwargs = {
'vip_subnet_id': vip_subnet_id,
'admin_state_up': admin_state_up,
}
if vip_address is not None:
kwargs['vip_address'] = vip_address
if name is not None:
kwargs['name'] = name
if description is not None:
kwargs['description'] = description
res = self.conn.network.create_load_balancer(**kwargs)
return res
@sdk.translate_exception
def loadbalancer_delete(self, lb_id, ignore_missing=True):
self.conn.network.delete_load_balancer(
lb_id, ignore_missing=ignore_missing)
return
@sdk.translate_exception
def listener_create(self, loadbalancer_id, protocol, protocol_port,
connection_limit=None,
admin_state_up=True, name=None, description=None):
kwargs = {
'loadbalancer_id': loadbalancer_id,
'protocol': protocol,
'protocol_port': protocol_port,
'admin_state_up': admin_state_up,
}
if connection_limit is not None:
kwargs['connection_limit'] = connection_limit
if name is not None:
kwargs['name'] = name
if description is not None:
kwargs['description'] = description
res = self.conn.network.create_listener(**kwargs)
return res
@sdk.translate_exception
def listener_delete(self, listener_id, ignore_missing=True):
self.conn.network.delete_listener(listener_id,
ignore_missing=ignore_missing)
return
@sdk.translate_exception
def pool_create(self, lb_algorithm, listener_id, protocol,
admin_state_up=True, name=None, description=None):
kwargs = {
'lb_algorithm': lb_algorithm,
'listener_id': listener_id,
'protocol': protocol,
'admin_state_up': admin_state_up,
}
if name is not None:
kwargs['name'] = name
if description is not None:
kwargs['description'] = description
res = self.conn.network.create_pool(**kwargs)
return res
@sdk.translate_exception
def pool_delete(self, pool_id, ignore_missing=True):
self.conn.network.delete_pool(pool_id,
ignore_missing=ignore_missing)
return
@sdk.translate_exception
def pool_member_create(self, pool_id, address, protocol_port, subnet_id,
weight=None, admin_state_up=True):
kwargs = {
'address': address,
'protocol_port': protocol_port,
'admin_state_up': admin_state_up,
'subnet_id': subnet_id,
}
if weight is not None:
kwargs['weight'] = weight
res = self.conn.network.create_pool_member(pool_id, **kwargs)
return res
@sdk.translate_exception
def pool_member_delete(self, pool_id, member_id, ignore_missing=True):
self.conn.network.delete_pool_member(
member_id, pool_id, ignore_missing=ignore_missing)
return
@sdk.translate_exception
def healthmonitor_create(self, hm_type, delay, timeout, max_retries,
pool_id, admin_state_up=True,
http_method=None, url_path=None,
expected_codes=None):
kwargs = {
'type': hm_type,
'delay': delay,
'timeout': timeout,
'max_retries': max_retries,
'pool_id': pool_id,
'admin_state_up': admin_state_up,
}
# TODO(anyone): verify if this is correct
if hm_type == 'HTTP':
if http_method is not None:
kwargs['http_method'] = http_method
if url_path is not None:
kwargs['url_path'] = url_path
if expected_codes is not None:
kwargs['expected_codes'] = expected_codes
res = self.conn.network.create_health_monitor(**kwargs)
return res
@sdk.translate_exception
def healthmonitor_delete(self, hm_id, ignore_missing=True):
self.conn.network.delete_health_monitor(
hm_id, ignore_missing=ignore_missing)
return
@sdk.translate_exception
def port_create(self, **attr):
res = self.conn.network.create_port(**attr)

View File

@ -0,0 +1,168 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from senlin.drivers import base
from senlin.drivers.openstack import sdk
class OctaviaClient(base.DriverBase):
"""Octavia v2 client"""
def __init__(self, params):
super(OctaviaClient, self).__init__(params)
self.conn = sdk.create_connection(params)
@sdk.translate_exception
def loadbalancer_get(self, name_or_id, ignore_missing=False,
show_deleted=False):
lb = self.conn.load_balancer.find_load_balancer(name_or_id,
ignore_missing)
# TODO(liyi)
# It's unreasonable for octavia don't support filter deleted
# loadbalancers. So if supported, we need to change the function.
if lb and not show_deleted and lb.provisioning_status == 'DELETED':
lb = None
return lb
@sdk.translate_exception
def loadbalancer_create(self, vip_subnet_id, vip_address=None,
admin_state_up=True, name=None, description=None):
kwargs = {
'vip_subnet_id': vip_subnet_id,
'admin_state_up': admin_state_up,
}
if vip_address is not None:
kwargs['vip_address'] = vip_address
if name is not None:
kwargs['name'] = name
if description is not None:
kwargs['description'] = description
res = self.conn.load_balancer.create_load_balancer(**kwargs)
return res
@sdk.translate_exception
def loadbalancer_delete(self, lb_id, ignore_missing=True):
self.conn.load_balancer.delete_load_balancer(
lb_id, ignore_missing=ignore_missing)
return
@sdk.translate_exception
def listener_create(self, loadbalancer_id, protocol, protocol_port,
connection_limit=None,
admin_state_up=True, name=None, description=None):
kwargs = {
'loadbalancer_id': loadbalancer_id,
'protocol': protocol,
'protocol_port': protocol_port,
'admin_state_up': admin_state_up,
}
if connection_limit is not None:
kwargs['connection_limit'] = connection_limit
if name is not None:
kwargs['name'] = name
if description is not None:
kwargs['description'] = description
res = self.conn.load_balancer.create_listener(**kwargs)
return res
@sdk.translate_exception
def listener_delete(self, listener_id, ignore_missing=True):
self.conn.load_balancer.delete_listener(
listener_id, ignore_missing=ignore_missing)
return
@sdk.translate_exception
def pool_create(self, lb_algorithm, listener_id, protocol,
admin_state_up=True, name=None, description=None):
kwargs = {
'lb_algorithm': lb_algorithm,
'listener_id': listener_id,
'protocol': protocol,
'admin_state_up': admin_state_up,
}
if name is not None:
kwargs['name'] = name
if description is not None:
kwargs['description'] = description
res = self.conn.load_balancer.create_pool(**kwargs)
return res
@sdk.translate_exception
def pool_delete(self, pool_id, ignore_missing=True):
self.conn.load_balancer.delete_pool(
pool_id, ignore_missing=ignore_missing)
return
@sdk.translate_exception
def pool_member_create(self, pool_id, address, protocol_port, subnet_id,
weight=None, admin_state_up=True):
kwargs = {
'address': address,
'protocol_port': protocol_port,
'admin_state_up': admin_state_up,
'subnet_id': subnet_id,
}
if weight is not None:
kwargs['weight'] = weight
res = self.conn.load_balancer.create_member(pool_id, **kwargs)
return res
@sdk.translate_exception
def pool_member_delete(self, pool_id, member_id, ignore_missing=True):
self.conn.load_balancer.delete_member(
member_id, pool_id, ignore_missing=ignore_missing)
return
@sdk.translate_exception
def healthmonitor_create(self, hm_type, delay, timeout, max_retries,
pool_id, admin_state_up=True,
http_method=None, url_path=None,
expected_codes=None):
kwargs = {
'type': hm_type,
'delay': delay,
'timeout': timeout,
'max_retries': max_retries,
'pool_id': pool_id,
'admin_state_up': admin_state_up,
}
# TODO(anyone): verify if this is correct
if hm_type == 'HTTP':
if http_method is not None:
kwargs['http_method'] = http_method
if url_path is not None:
kwargs['url_path'] = url_path
if expected_codes is not None:
kwargs['expected_codes'] = expected_codes
res = self.conn.load_balancer.create_health_monitor(**kwargs)
return res
@sdk.translate_exception
def healthmonitor_delete(self, hm_id, ignore_missing=True):
self.conn.load_balancer.delete_health_monitor(
hm_id, ignore_missing=ignore_missing)
return

View File

@ -117,6 +117,7 @@ class Policy(object):
self._novaclient = None
self._keystoneclient = None
self._networkclient = None
self._octaviaclient = None
self._lbaasclient = None
@classmethod
@ -283,6 +284,21 @@ class Policy(object):
self._networkclient = driver.SenlinDriver().network(params)
return self._networkclient
def octavia(self, user, project):
"""Construct octavia client based on user and project.
:param user: The ID of the requesting user.
:param project: The ID of the requesting project.
:returns: A reference to the octavia client.
"""
if self._octaviaclient is not None:
return self._octaviaclient
params = self._build_conn_params(user, project)
self._octaviaclient = driver.SenlinDriver().network(params)
return self._octaviaclient
def lbaas(self, user, project):
"""Construct LB service client based on user and project.

View File

@ -297,6 +297,7 @@ class LoadBalancingPolicy(base.Policy):
return True
nc = self.network(context.user, context.project)
oc = self.octavia(context.user, context.project)
# validate pool subnet
name_or_id = self.pool_spec.get(self.POOL_SUBNET)
@ -318,12 +319,11 @@ class LoadBalancingPolicy(base.Policy):
# validate loadbalancer
if self.lb:
name_or_id = self.lb
try:
nc.loadbalancer_get(name_or_id)
oc.loadbalancer_get(self.lb)
except exc.InternalError:
msg = _("The specified %(key)s '%(value)s' could not be found."
) % {'key': self.LOADBALANCER, 'value': name_or_id}
) % {'key': self.LOADBALANCER, 'value': self.lb}
raise exc.InvalidSpec(message=msg)
def attach(self, cluster, enabled=True):

View File

@ -19,21 +19,24 @@ from senlin.common import exception
from senlin.common.i18n import _
from senlin.drivers.openstack import lbaas
from senlin.drivers.openstack import neutron_v2
from senlin.drivers.openstack import octavia_v2
from senlin.engine import node as nodem
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils
class TestNeutronLBaaSDriver(base.SenlinTestCase):
class TestOctaviaLBaaSDriver(base.SenlinTestCase):
def setUp(self):
super(TestNeutronLBaaSDriver, self).setUp()
super(TestOctaviaLBaaSDriver, self).setUp()
self.context = utils.dummy_context()
self.conn_params = self.context.to_dict()
self.lb_driver = lbaas.LoadBalancerDriver(self.conn_params)
self.lb_driver.lb_status_timeout = 10
self.patchobject(neutron_v2, 'NeutronClient')
self.patchobject(octavia_v2, 'OctaviaClient')
self.nc = self.lb_driver.nc()
self.oc = self.lb_driver.oc()
self.vip = {
'subnet': 'subnet-01',
@ -97,14 +100,14 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
lb_obj.id = lb_id
lb_obj.provisioning_status = 'ACTIVE'
lb_obj.operating_status = 'ONLINE'
self.nc.loadbalancer_get.return_value = lb_obj
self.oc.loadbalancer_get.return_value = lb_obj
res = self.lb_driver._wait_for_lb_ready(lb_id)
self.assertTrue(res)
def test_wait_for_lb_ready_ignore_not_found(self):
lb_id = 'LB_ID'
self.nc.loadbalancer_get.return_value = None
self.oc.loadbalancer_get.return_value = None
res = self.lb_driver._wait_for_lb_ready(lb_id, ignore_not_found=True)
@ -114,7 +117,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
def test_wait_for_lb_ready_timeout(self, mock_sleep):
lb_id = 'LB_ID'
lb_obj = mock.Mock(id=lb_id)
self.nc.loadbalancer_get.return_value = lb_obj
self.oc.loadbalancer_get.return_value = lb_obj
lb_obj.provisioning_status = 'PENDING_UPDATE'
lb_obj.operating_status = 'OFFLINE'
@ -138,10 +141,10 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
subnet_obj.network_id = 'NETWORK_ID'
hm_obj.id = 'HEALTHMONITOR_ID'
self.nc.loadbalancer_create.return_value = lb_obj
self.nc.listener_create.return_value = listener_obj
self.nc.pool_create.return_value = pool_obj
self.nc.healthmonitor_create.return_value = hm_obj
self.oc.loadbalancer_create.return_value = lb_obj
self.oc.listener_create.return_value = listener_obj
self.oc.pool_create.return_value = pool_obj
self.oc.healthmonitor_create.return_value = hm_obj
self.nc.subnet_get.return_value = subnet_obj
self.lb_driver._wait_for_lb_ready = mock.Mock()
@ -149,19 +152,19 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm)
self.assertTrue(status)
self.nc.loadbalancer_create.assert_called_once_with(
self.oc.loadbalancer_create.assert_called_once_with(
'SUBNET_ID', self.vip['address'], self.vip['admin_state_up'])
self.assertEqual('LB_ID', res['loadbalancer'])
self.assertEqual('192.168.1.100', res['vip_address'])
self.nc.listener_create.assert_called_once_with(
self.oc.listener_create.assert_called_once_with(
'LB_ID', self.vip['protocol'], self.vip['protocol_port'],
self.vip['connection_limit'], self.vip['admin_state_up'])
self.assertEqual('LISTENER_ID', res['listener'])
self.nc.pool_create.assert_called_once_with(
self.oc.pool_create.assert_called_once_with(
self.pool['lb_method'], 'LISTENER_ID', self.pool['protocol'],
self.pool['admin_state_up'])
self.assertEqual('POOL_ID', res['pool'])
self.nc.healthmonitor_create.assert_called_once_with(
self.oc.healthmonitor_create.assert_called_once_with(
self.hm['type'], self.hm['delay'], self.hm['timeout'],
self.hm['max_retries'], 'POOL_ID', self.hm['admin_state_up'],
self.hm['http_method'], self.hm['url_path'],
@ -179,7 +182,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
subnet_obj.name = 'subnet'
subnet_obj.id = 'SUBNET_ID'
subnet_obj.network_id = 'NETWORK_ID'
self.nc.loadbalancer_create.return_value = lb_obj
self.oc.loadbalancer_create.return_value = lb_obj
self.nc.subnet_get.return_value = subnet_obj
self.lb_driver._wait_for_lb_ready = mock.Mock()
@ -190,7 +193,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.assertFalse(status)
msg = _('Failed in creating loadbalancer (%s).') % 'LB_ID'
self.assertEqual(msg, res)
self.nc.loadbalancer_create.assert_called_once_with(
self.oc.loadbalancer_create.assert_called_once_with(
'SUBNET_ID', self.vip['address'], self.vip['admin_state_up'])
self.lb_driver._wait_for_lb_ready.assert_called_once_with('LB_ID')
self.lb_driver.lb_delete.assert_called_once_with(
@ -206,7 +209,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
# Exception happens in loadbalancer_create.
self.nc.subnet_get.side_effect = None
self.nc.loadbalancer_create.side_effect = exception.InternalError(
self.oc.loadbalancer_create.side_effect = exception.InternalError(
code=500, message='CREATE FAILED')
status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm)
self.assertFalse(status)
@ -226,8 +229,8 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.lb_driver._wait_for_lb_ready = mock.Mock()
self.lb_driver._wait_for_lb_ready.side_effect = [True, False]
self.nc.loadbalancer_create.return_value = lb_obj
self.nc.listener_create.return_value = listener_obj
self.oc.loadbalancer_create.return_value = lb_obj
self.oc.listener_create.return_value = listener_obj
self.nc.subnet_get.return_value = subnet_obj
self.lb_driver.lb_delete = mock.Mock()
@ -235,9 +238,9 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.assertFalse(status)
msg = _('Failed in creating listener (%s).') % 'LISTENER_ID'
self.assertEqual(msg, res)
self.nc.loadbalancer_create.assert_called_once_with(
self.oc.loadbalancer_create.assert_called_once_with(
'SUBNET_ID', self.vip['address'], self.vip['admin_state_up'])
self.nc.listener_create.assert_called_once_with(
self.oc.listener_create.assert_called_once_with(
'LB_ID', self.vip['protocol'], self.vip['protocol_port'],
self.vip['connection_limit'], self.vip['admin_state_up'])
self.lb_driver._wait_for_lb_ready.assert_called_with('LB_ID')
@ -247,7 +250,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
# Exception happens in listen_create
self.lb_driver._wait_for_lb_ready = mock.Mock()
self.lb_driver._wait_for_lb_ready.side_effect = [True, False]
self.nc.listener_create.side_effect = exception.InternalError(
self.oc.listener_create.side_effect = exception.InternalError(
code=500, message='CREATE FAILED')
status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm)
self.assertFalse(status)
@ -269,9 +272,9 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.lb_driver._wait_for_lb_ready = mock.Mock()
self.lb_driver._wait_for_lb_ready.side_effect = [True, True, False]
self.nc.loadbalancer_create.return_value = lb_obj
self.nc.listener_create.return_value = listener_obj
self.nc.pool_create.return_value = pool_obj
self.oc.loadbalancer_create.return_value = lb_obj
self.oc.listener_create.return_value = listener_obj
self.oc.pool_create.return_value = pool_obj
self.nc.subnet_get.return_value = subnet_obj
self.lb_driver.lb_delete = mock.Mock()
@ -279,12 +282,12 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.assertFalse(status)
msg = _('Failed in creating pool (%s).') % 'POOL_ID'
self.assertEqual(msg, res)
self.nc.loadbalancer_create.assert_called_once_with(
self.oc.loadbalancer_create.assert_called_once_with(
'SUBNET_ID', self.vip['address'], self.vip['admin_state_up'])
self.nc.listener_create.assert_called_once_with(
self.oc.listener_create.assert_called_once_with(
'LB_ID', self.vip['protocol'], self.vip['protocol_port'],
self.vip['connection_limit'], self.vip['admin_state_up'])
self.nc.pool_create.assert_called_once_with(
self.oc.pool_create.assert_called_once_with(
self.pool['lb_method'], 'LISTENER_ID', self.pool['protocol'],
self.pool['admin_state_up'])
self.lb_driver._wait_for_lb_ready.assert_called_with('LB_ID')
@ -294,7 +297,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
# Exception happens in pool_create
self.lb_driver._wait_for_lb_ready = mock.Mock()
self.lb_driver._wait_for_lb_ready.side_effect = [True, True, False]
self.nc.pool_create.side_effect = exception.InternalError(
self.oc.pool_create.side_effect = exception.InternalError(
code=500, message='CREATE FAILED')
status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm)
self.assertFalse(status)
@ -318,10 +321,10 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.lb_driver._wait_for_lb_ready = mock.Mock()
self.lb_driver._wait_for_lb_ready.side_effect = [True, True,
True, False]
self.nc.loadbalancer_create.return_value = lb_obj
self.nc.listener_create.return_value = listener_obj
self.nc.pool_create.return_value = pool_obj
self.nc.healthmonitor_create.return_value = hm_obj
self.oc.loadbalancer_create.return_value = lb_obj
self.oc.listener_create.return_value = listener_obj
self.oc.pool_create.return_value = pool_obj
self.oc.healthmonitor_create.return_value = hm_obj
self.nc.subnet_get.return_value = subnet_obj
self.lb_driver.lb_delete = mock.Mock()
@ -336,7 +339,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
# Exception happens in healthmonitor_create
self.lb_driver._wait_for_lb_ready = mock.Mock()
self.lb_driver._wait_for_lb_ready.side_effect = [True, True, True]
self.nc.healthmonitor_create.side_effect = exception.InternalError(
self.oc.healthmonitor_create.side_effect = exception.InternalError(
code=500, message='CREATE FAILED')
status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm)
self.assertFalse(status)
@ -346,7 +349,8 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
@mock.patch.object(neutron_v2, 'NeutronClient')
def test_lb_find(self, mock_neutron):
self.lb_driver.lb_find("FAKELB")
self.nc.loadbalancer_get.assert_called_once_with("FAKELB", False)
self.oc.loadbalancer_get.assert_called_once_with(
"FAKELB", False, False)
def test_lb_delete(self):
kwargs = {
@ -361,10 +365,10 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
status, res = self.lb_driver.lb_delete(**kwargs)
self.assertTrue(status)
self.assertEqual('LB deletion succeeded', res)
self.nc.loadbalancer_delete.assert_called_once_with('LB_ID')
self.nc.listener_delete.assert_called_once_with('LISTENER_ID')
self.nc.pool_delete.assert_called_once_with('POOL_ID')
self.nc.healthmonitor_delete.assert_called_once_with('HM_ID')
self.oc.loadbalancer_delete.assert_called_once_with('LB_ID')
self.oc.listener_delete.assert_called_once_with('LISTENER_ID')
self.oc.pool_delete.assert_called_once_with('POOL_ID')
self.oc.healthmonitor_delete.assert_called_once_with('HM_ID')
calls = [mock.call('LB_ID') for i in range(1, 4)]
self.lb_driver._wait_for_lb_ready.assert_has_calls(
calls, any_order=False)
@ -376,7 +380,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
'pool': 'POOL_ID',
'healthmonitor': 'HM_ID'
}
self.nc.healthmonitor_delete.side_effect = exception.InternalError(
self.oc.healthmonitor_delete.side_effect = exception.InternalError(
code=500, message='DELETE FAILED')
status, res = self.lb_driver.lb_delete(**kwargs)
self.assertFalse(status)
@ -390,7 +394,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
'pool': 'POOL_ID',
'healthmonitor': 'HM_ID'
}
self.nc.pool_delete.side_effect = exception.InternalError(
self.oc.pool_delete.side_effect = exception.InternalError(
code=500, message='DELETE FAILED')
self.lb_driver._wait_for_lb_ready = mock.Mock()
self.lb_driver._wait_for_lb_ready.return_value = True
@ -406,7 +410,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
'pool': 'POOL_ID',
'healthmonitor': 'HM_ID'
}
self.nc.listener_delete.side_effect = exception.InternalError(
self.oc.listener_delete.side_effect = exception.InternalError(
code=500, message='DELETE FAILED')
self.lb_driver._wait_for_lb_ready = mock.Mock()
self.lb_driver._wait_for_lb_ready.return_value = True
@ -423,10 +427,10 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
status, res = self.lb_driver.lb_delete(**kwargs)
self.assertTrue(status)
self.assertEqual('LB deletion succeeded', res)
self.nc.loadbalancer_delete.assert_called_once_with('LB_ID')
self.assertEqual(0, self.nc.healthmonitor_delete.call_count)
self.assertEqual(0, self.nc.pool_delete.call_count)
self.assertEqual(0, self.nc.listener_delete.call_count)
self.oc.loadbalancer_delete.assert_called_once_with('LB_ID')
self.assertEqual(0, self.oc.healthmonitor_delete.call_count)
self.assertEqual(0, self.oc.pool_delete.call_count)
self.assertEqual(0, self.oc.listener_delete.call_count)
self.lb_driver._wait_for_lb_ready.assert_called_once_with(
'LB_ID', ignore_not_found=True)
@ -457,7 +461,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.nc.subnet_get.return_value = subnet_obj
self.nc.network_get.return_value = network_obj
self.nc.pool_member_create.return_value = member
self.oc.pool_member_create.return_value = member
self.lb_driver._wait_for_lb_ready = mock.Mock()
self.lb_driver._wait_for_lb_ready.return_value = True
@ -465,7 +469,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.assertEqual('MEMBER_ID', res)
self.nc.subnet_get.assert_called_once_with(subnet)
self.nc.network_get.assert_called_once_with('NETWORK_ID')
self.nc.pool_member_create.assert_called_once_with(
self.oc.pool_member_create.assert_called_once_with(
pool_id, 'ipaddr_net1', port, 'SUBNET_ID')
self.lb_driver._wait_for_lb_ready.assert_has_calls(
[mock.call('LB_ID'), mock.call('LB_ID')])
@ -518,7 +522,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.lb_driver._wait_for_lb_ready.return_value = False
self.nc.subnet_get.return_value = subnet_obj
self.nc.network_get.return_value = network_obj
self.nc.pool_member_create.side_effect = exception.InternalError(
self.oc.pool_member_create.side_effect = exception.InternalError(
code=500, message="CREATE FAILED")
res = self.lb_driver.member_add(node, 'LB_ID', 'POOL_ID', 80,
'subnet')
@ -549,7 +553,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.lb_driver._wait_for_lb_ready.return_value = True
self.nc.subnet_get.return_value = subnet_obj
self.nc.network_get.return_value = network_obj
self.nc.pool_member_create.side_effect = exception.InternalError(
self.oc.pool_member_create.side_effect = exception.InternalError(
code=500, message="CREATE FAILED")
res = self.lb_driver.member_add(node, 'LB_ID', 'POOL_ID', 80,
'subnet')
@ -619,7 +623,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
res = self.lb_driver.member_remove(lb_id, pool_id, member_id)
self.assertTrue(res)
self.nc.pool_member_delete.assert_called_once_with(pool_id, member_id)
self.oc.pool_member_delete.assert_called_once_with(pool_id, member_id)
self.lb_driver._wait_for_lb_ready.assert_has_calls(
[mock.call(lb_id), mock.call(lb_id)])
@ -634,18 +638,18 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
def test_member_remove_member_delete_failed(self):
self.lb_driver._wait_for_lb_ready = mock.Mock()
self.lb_driver._wait_for_lb_ready.return_value = True
self.nc.pool_member_delete.side_effect = exception.InternalError(
self.oc.pool_member_delete.side_effect = exception.InternalError(
code=500, message='')
res = self.lb_driver.member_remove('LB_ID', 'POOL_ID', 'MEMBER_ID')
self.assertFalse(res)
self.nc.pool_member_delete.assert_called_once_with('POOL_ID',
self.oc.pool_member_delete.assert_called_once_with('POOL_ID',
'MEMBER_ID')
def test_member_remove_wait_for_lb_timeout(self):
self.lb_driver._wait_for_lb_ready = mock.Mock()
self.lb_driver._wait_for_lb_ready.side_effect = [True, False]
self.nc.pool_member_delete.side_effect = None
self.oc.pool_member_delete.side_effect = None
res = self.lb_driver.member_remove('LB_ID', 'POOL_ID', 'MEMBER_ID')
self.assertIsNone(res)

View File

@ -72,233 +72,6 @@ class TestNeutronV2Driver(base.SenlinTestCase):
self.conn.network.find_subnet.assert_called_once_with(subnet_id, False)
self.assertEqual(subnet_obj, res)
def test_loadbalancer_get(self):
lb_id = 'loadbalancer_identifier'
loadbalancer_obj = mock.Mock()
self.conn.network.find_load_balancer.return_value = loadbalancer_obj
res = self.nc.loadbalancer_get(lb_id)
self.conn.network.find_load_balancer.assert_called_once_with(lb_id,
False)
self.assertEqual(loadbalancer_obj, res)
def test_loadbalancer_create(self):
vip_subnet_id = 'ID1'
lb_obj = mock.Mock()
# All input parameters are provided
kwargs = {
'vip_address': '192.168.0.100',
'name': 'test-loadbalancer',
'description': 'This is a loadbalancer',
'admin_state_up': True
}
self.conn.network.create_load_balancer.return_value = lb_obj
self.assertEqual(lb_obj, self.nc.loadbalancer_create(vip_subnet_id,
**kwargs))
self.conn.network.create_load_balancer.assert_called_once_with(
vip_subnet_id=vip_subnet_id, **kwargs)
# Use default input parameters
kwargs = {
'admin_state_up': True
}
self.assertEqual(lb_obj, self.nc.loadbalancer_create(vip_subnet_id))
self.conn.network.create_load_balancer.assert_called_with(
vip_subnet_id=vip_subnet_id, **kwargs)
def test_loadbalancer_delete(self):
lb_id = 'ID1'
self.nc.loadbalancer_delete(lb_id, ignore_missing=False)
self.conn.network.delete_load_balancer.assert_called_once_with(
lb_id, ignore_missing=False)
self.nc.loadbalancer_delete(lb_id)
self.conn.network.delete_load_balancer.assert_called_with(
lb_id, ignore_missing=True)
def test_listener_create(self):
loadbalancer_id = 'ID1'
protocol = 'HTTP'
protocol_port = 80
listener_obj = mock.Mock()
# All input parameters are provided
kwargs = {
'connection_limit': 100,
'admin_state_up': True,
'name': 'test-listener',
'description': 'This is a listener',
}
self.conn.network.create_listener.return_value = listener_obj
self.assertEqual(listener_obj, self.nc.listener_create(
loadbalancer_id, protocol, protocol_port, **kwargs))
self.conn.network.create_listener.assert_called_once_with(
loadbalancer_id=loadbalancer_id, protocol=protocol,
protocol_port=protocol_port, **kwargs)
# Use default input parameters
kwargs = {
'admin_state_up': True
}
self.assertEqual(listener_obj, self.nc.listener_create(
loadbalancer_id, protocol, protocol_port))
self.conn.network.create_listener.assert_called_with(
loadbalancer_id=loadbalancer_id, protocol=protocol,
protocol_port=protocol_port, **kwargs)
def test_listener_delete(self):
listener_id = 'ID1'
self.nc.listener_delete(listener_id, ignore_missing=False)
self.conn.network.delete_listener.assert_called_once_with(
listener_id, ignore_missing=False)
self.nc.listener_delete(listener_id)
self.conn.network.delete_listener.assert_called_with(
listener_id, ignore_missing=True)
def test_pool_create(self):
lb_algorithm = 'ROUND_ROBIN'
listener_id = 'ID1'
protocol = 'HTTP'
pool_obj = mock.Mock()
# All input parameters are provided
kwargs = {
'admin_state_up': True,
'name': 'test-pool',
'description': 'This is a pool',
}
self.conn.network.create_pool.return_value = pool_obj
self.assertEqual(pool_obj, self.nc.pool_create(
lb_algorithm, listener_id, protocol, **kwargs))
self.conn.network.create_pool.assert_called_once_with(
lb_algorithm=lb_algorithm, listener_id=listener_id,
protocol=protocol, **kwargs)
# Use default input parameters
kwargs = {
'admin_state_up': True
}
self.assertEqual(pool_obj, self.nc.pool_create(
lb_algorithm, listener_id, protocol))
self.conn.network.create_pool.assert_called_with(
lb_algorithm=lb_algorithm, listener_id=listener_id,
protocol=protocol, **kwargs)
def test_pool_delete(self):
pool_id = 'ID1'
self.nc.pool_delete(pool_id, ignore_missing=False)
self.conn.network.delete_pool.assert_called_once_with(
pool_id, ignore_missing=False)
self.nc.pool_delete(pool_id)
self.conn.network.delete_pool.assert_called_with(
pool_id, ignore_missing=True)
def test_pool_member_create(self):
pool_id = 'ID1'
address = '192.168.1.100'
protocol_port = 80
subnet_id = 'ID2'
weight = 50
member_obj = mock.Mock()
# All input parameters are provided
kwargs = {
'weight': weight,
'admin_state_up': True,
}
self.conn.network.create_pool_member.return_value = member_obj
self.assertEqual(member_obj, self.nc.pool_member_create(
pool_id, address, protocol_port, subnet_id, **kwargs))
self.conn.network.create_pool_member.assert_called_once_with(
pool_id, address=address, protocol_port=protocol_port,
subnet_id=subnet_id, **kwargs)
# Use default input parameters
kwargs = {
'admin_state_up': True
}
self.assertEqual(member_obj, self.nc.pool_member_create(
pool_id, address, protocol_port, subnet_id))
self.conn.network.create_pool_member.assert_called_with(
pool_id, address=address, protocol_port=protocol_port,
subnet_id=subnet_id, **kwargs)
def test_pool_member_delete(self):
pool_id = 'ID1'
member_id = 'ID2'
self.nc.pool_member_delete(pool_id, member_id, ignore_missing=False)
self.conn.network.delete_pool_member.assert_called_once_with(
member_id, pool_id, ignore_missing=False)
self.nc.pool_member_delete(pool_id, member_id)
self.conn.network.delete_pool_member.assert_called_with(
member_id, pool_id, ignore_missing=True)
def test_healthmonitor_create(self):
hm_type = 'HTTP'
delay = 30
timeout = 10
max_retries = 5
pool_id = 'ID1'
hm_obj = mock.Mock()
# All input parameters are provided
kwargs = {
'http_method': 'test-method',
'admin_state_up': True,
'url_path': '/test_page',
'expected_codes': [200, 201, 202],
}
self.conn.network.create_health_monitor.return_value = hm_obj
res = self.nc.healthmonitor_create(hm_type, delay, timeout,
max_retries, pool_id, **kwargs)
self.assertEqual(hm_obj, res)
self.conn.network.create_health_monitor.assert_called_once_with(
type=hm_type, delay=delay, timeout=timeout,
max_retries=max_retries, pool_id=pool_id, **kwargs)
# Use default input parameters
res = self.nc.healthmonitor_create(hm_type, delay, timeout,
max_retries, pool_id,
admin_state_up=True)
self.assertEqual(hm_obj, res)
self.conn.network.create_health_monitor.assert_called_with(
type=hm_type, delay=delay, timeout=timeout,
max_retries=max_retries, pool_id=pool_id,
admin_state_up=True)
# hm_type other than HTTP, then other params ignored
res = self.nc.healthmonitor_create('TCP', delay, timeout,
max_retries, pool_id, **kwargs)
self.assertEqual(hm_obj, res)
self.conn.network.create_health_monitor.assert_called_with(
type='TCP', delay=delay, timeout=timeout,
max_retries=max_retries, pool_id=pool_id,
admin_state_up=True)
def test_healthmonitor_delete(self):
healthmonitor_id = 'ID1'
self.nc.healthmonitor_delete(healthmonitor_id, ignore_missing=False)
self.conn.network.delete_health_monitor.assert_called_once_with(
healthmonitor_id, ignore_missing=False)
self.nc.healthmonitor_delete(healthmonitor_id)
self.conn.network.delete_health_monitor.assert_called_with(
healthmonitor_id, ignore_missing=True)
def test_port_create(self):
port_attr = {
'network_id': 'foo'

View File

@ -0,0 +1,264 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
from senlin.drivers.openstack import octavia_v2
from senlin.drivers.openstack import sdk
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils
class TestOctaviaV2Driver(base.SenlinTestCase):
def setUp(self):
super(TestOctaviaV2Driver, self).setUp()
self.context = utils.dummy_context()
self.conn_params = self.context.to_dict()
self.conn = mock.Mock()
with mock.patch.object(sdk, 'create_connection') as mock_creare_conn:
mock_creare_conn.return_value = self.conn
self.oc = octavia_v2.OctaviaClient(self.context)
@mock.patch.object(sdk, 'create_connection')
def test_init(self, mock_create_connection):
params = self.conn_params
octavia_v2.OctaviaClient(params)
mock_create_connection.assert_called_once_with(params)
def test_loadbalancer_get(self):
lb_id = 'loadbalancer_identifier'
loadbalancer_obj = mock.Mock()
self.conn.load_balancer.find_load_balancer.return_value =\
loadbalancer_obj
res = self.oc.loadbalancer_get(lb_id)
self.conn.load_balancer.find_load_balancer.assert_called_once_with(
lb_id, False)
self.assertEqual(loadbalancer_obj, res)
def test_loadbalancer_create(self):
vip_subnet_id = 'ID1'
lb_obj = mock.Mock()
# All input parameters are provided
kwargs = {
'vip_address': '192.168.0.100',
'name': 'test-loadbalancer',
'description': 'This is a loadbalancer',
'admin_state_up': True
}
self.conn.load_balancer.create_load_balancer.return_value = lb_obj
self.assertEqual(lb_obj, self.oc.loadbalancer_create(vip_subnet_id,
**kwargs))
self.conn.load_balancer.create_load_balancer.assert_called_once_with(
vip_subnet_id=vip_subnet_id, **kwargs)
# Use default input parameters
kwargs = {
'admin_state_up': True
}
self.assertEqual(lb_obj, self.oc.loadbalancer_create(vip_subnet_id))
self.conn.load_balancer.create_load_balancer.assert_called_with(
vip_subnet_id=vip_subnet_id, **kwargs)
def test_loadbalancer_delete(self):
lb_id = 'ID1'
self.oc.loadbalancer_delete(lb_id, ignore_missing=False)
self.conn.load_balancer.delete_load_balancer.assert_called_once_with(
lb_id, ignore_missing=False)
self.oc.loadbalancer_delete(lb_id)
self.conn.load_balancer.delete_load_balancer.assert_called_with(
lb_id, ignore_missing=True)
def test_listener_create(self):
loadbalancer_id = 'ID1'
protocol = 'HTTP'
protocol_port = 80
listener_obj = mock.Mock()
# All input parameters are provided
kwargs = {
'connection_limit': 100,
'admin_state_up': True,
'name': 'test-listener',
'description': 'This is a listener',
}
self.conn.load_balancer.create_listener.return_value = listener_obj
self.assertEqual(listener_obj, self.oc.listener_create(
loadbalancer_id, protocol, protocol_port, **kwargs))
self.conn.load_balancer.create_listener.assert_called_once_with(
loadbalancer_id=loadbalancer_id, protocol=protocol,
protocol_port=protocol_port, **kwargs)
# Use default input parameters
kwargs = {
'admin_state_up': True
}
self.assertEqual(listener_obj, self.oc.listener_create(
loadbalancer_id, protocol, protocol_port))
self.conn.load_balancer.create_listener.assert_called_with(
loadbalancer_id=loadbalancer_id, protocol=protocol,
protocol_port=protocol_port, **kwargs)
def test_listener_delete(self):
listener_id = 'ID1'
self.oc.listener_delete(listener_id, ignore_missing=False)
self.conn.load_balancer.delete_listener.assert_called_once_with(
listener_id, ignore_missing=False)
self.oc.listener_delete(listener_id)
self.conn.load_balancer.delete_listener.assert_called_with(
listener_id, ignore_missing=True)
def test_pool_create(self):
lb_algorithm = 'ROUND_ROBIN'
listener_id = 'ID1'
protocol = 'HTTP'
pool_obj = mock.Mock()
# All input parameters are provided
kwargs = {
'admin_state_up': True,
'name': 'test-pool',
'description': 'This is a pool',
}
self.conn.load_balancer.create_pool.return_value = pool_obj
self.assertEqual(pool_obj, self.oc.pool_create(
lb_algorithm, listener_id, protocol, **kwargs))
self.conn.load_balancer.create_pool.assert_called_once_with(
lb_algorithm=lb_algorithm, listener_id=listener_id,
protocol=protocol, **kwargs)
# Use default input parameters
kwargs = {
'admin_state_up': True
}
self.assertEqual(pool_obj, self.oc.pool_create(
lb_algorithm, listener_id, protocol))
self.conn.load_balancer.create_pool.assert_called_with(
lb_algorithm=lb_algorithm, listener_id=listener_id,
protocol=protocol, **kwargs)
def test_pool_delete(self):
pool_id = 'ID1'
self.oc.pool_delete(pool_id, ignore_missing=False)
self.conn.load_balancer.delete_pool.assert_called_once_with(
pool_id, ignore_missing=False)
self.oc.pool_delete(pool_id)
self.conn.load_balancer.delete_pool.assert_called_with(
pool_id, ignore_missing=True)
def test_pool_member_create(self):
pool_id = 'ID1'
address = '192.168.1.100'
protocol_port = 80
subnet_id = 'ID2'
weight = 50
member_obj = mock.Mock()
# All input parameters are provided
kwargs = {
'weight': weight,
'admin_state_up': True,
}
self.conn.load_balancer.create_member.return_value = member_obj
self.assertEqual(member_obj, self.oc.pool_member_create(
pool_id, address, protocol_port, subnet_id, **kwargs))
self.conn.load_balancer.create_member.assert_called_once_with(
pool_id, address=address, protocol_port=protocol_port,
subnet_id=subnet_id, **kwargs)
# Use default input parameters
kwargs = {
'admin_state_up': True
}
self.assertEqual(member_obj, self.oc.pool_member_create(
pool_id, address, protocol_port, subnet_id))
self.conn.load_balancer.create_member.assert_called_with(
pool_id, address=address, protocol_port=protocol_port,
subnet_id=subnet_id, **kwargs)
def test_pool_member_delete(self):
pool_id = 'ID1'
member_id = 'ID2'
self.oc.pool_member_delete(pool_id, member_id, ignore_missing=False)
self.conn.load_balancer.delete_member.assert_called_once_with(
member_id, pool_id, ignore_missing=False)
self.oc.pool_member_delete(pool_id, member_id)
self.conn.load_balancer.delete_member.assert_called_with(
member_id, pool_id, ignore_missing=True)
def test_healthmonitor_create(self):
hm_type = 'HTTP'
delay = 30
timeout = 10
max_retries = 5
pool_id = 'ID1'
hm_obj = mock.Mock()
# All input parameters are provided
kwargs = {
'http_method': 'test-method',
'admin_state_up': True,
'url_path': '/test_page',
'expected_codes': [200, 201, 202],
}
self.conn.load_balancer.create_health_monitor.return_value = hm_obj
res = self.oc.healthmonitor_create(hm_type, delay, timeout,
max_retries, pool_id, **kwargs)
self.assertEqual(hm_obj, res)
self.conn.load_balancer.create_health_monitor.assert_called_once_with(
type=hm_type, delay=delay, timeout=timeout,
max_retries=max_retries, pool_id=pool_id, **kwargs)
# Use default input parameters
res = self.oc.healthmonitor_create(hm_type, delay, timeout,
max_retries, pool_id,
admin_state_up=True)
self.assertEqual(hm_obj, res)
self.conn.load_balancer.create_health_monitor.assert_called_with(
type=hm_type, delay=delay, timeout=timeout,
max_retries=max_retries, pool_id=pool_id,
admin_state_up=True)
# hm_type other than HTTP, then other params ignored
res = self.oc.healthmonitor_create('TCP', delay, timeout,
max_retries, pool_id, **kwargs)
self.assertEqual(hm_obj, res)
self.conn.load_balancer.create_health_monitor.assert_called_with(
type='TCP', delay=delay, timeout=timeout,
max_retries=max_retries, pool_id=pool_id,
admin_state_up=True)
def test_healthmonitor_delete(self):
healthmonitor_id = 'ID1'
self.oc.healthmonitor_delete(healthmonitor_id, ignore_missing=False)
self.conn.load_balancer.delete_health_monitor.assert_called_once_with(
healthmonitor_id, ignore_missing=False)
self.oc.healthmonitor_delete(healthmonitor_id)
self.conn.load_balancer.delete_health_monitor.assert_called_with(
healthmonitor_id, ignore_missing=True)

View File

@ -72,6 +72,7 @@ class TestLoadBalancingPolicy(base.SenlinTestCase):
self.patchobject(driver_base, 'SenlinDriver', return_value=self.sd)
self.lb_driver = mock.Mock()
self.net_driver = mock.Mock()
self.octavia_driver = mock.Mock()
@mock.patch.object(lb_policy.LoadBalancingPolicy, 'validate')
def test_init(self, mock_validate):
@ -175,6 +176,7 @@ class TestLoadBalancingPolicy(base.SenlinTestCase):
def test_validate_pool_subnet_notfound(self, mock_validate):
policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec)
policy._networkclient = self.net_driver
policy._octaviaclient = self.octavia_driver
ctx = mock.Mock(user='user1', project='project1')
self.net_driver.subnet_get = mock.Mock(
side_effect=exc.InternalError(code='404', message='not found'))
@ -190,6 +192,7 @@ class TestLoadBalancingPolicy(base.SenlinTestCase):
def test_validate_vip_subnet_notfound(self, mock_validate):
policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec)
policy._networkclient = self.net_driver
policy._octaviaclient = self.octavia_driver
ctx = mock.Mock(user='user1', project='project1')
self.net_driver.subnet_get = mock.Mock(
side_effect=[
@ -212,14 +215,15 @@ class TestLoadBalancingPolicy(base.SenlinTestCase):
self.spec['properties']['loadbalancer'] = "LB_ID"
policy = lb_policy.LoadBalancingPolicy('test-policy', self.spec)
policy._networkclient = self.net_driver
policy._octaviaclient = self.octavia_driver
ctx = mock.Mock(user='user1', project='project1')
self.net_driver.loadbalancer_get = mock.Mock(
self.octavia_driver.loadbalancer_get = mock.Mock(
side_effect=exc.InternalError(code='404', message='not found'))
ex = self.assertRaises(exc.InvalidSpec, policy.validate, ctx, True)
mock_validate.assert_called_with(ctx, True)
self.net_driver.loadbalancer_get.assert_called_once_with('LB_ID')
self.octavia_driver.loadbalancer_get.assert_called_once_with('LB_ID')
self.assertEqual("The specified loadbalancer 'LB_ID' could not "
"be found.", six.text_type(ex))