Migrate loadbalancer to Octavia
Change-Id: I4c87e5ce2eb978c45d07c2207abdd8097deebb3a Implements: blueprint migrate-lbaas-to-octavia
This commit is contained in:
parent
d66803026a
commit
dbf0abacd8
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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)
|
|
@ -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))
|
||||
|
||||
|
|
Loading…
Reference in New Issue