diff --git a/senlin/drivers/base.py b/senlin/drivers/base.py index 71903a355..a8d968d82 100644 --- a/senlin/drivers/base.py +++ b/senlin/drivers/base.py @@ -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 diff --git a/senlin/drivers/openstack/__init__.py b/senlin/drivers/openstack/__init__.py index 4ec6604c7..09e644176 100644 --- a/senlin/drivers/openstack/__init__.py +++ b/senlin/drivers/openstack/__init__.py @@ -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 diff --git a/senlin/drivers/openstack/lbaas.py b/senlin/drivers/openstack/lbaas.py index f273f6a26..d2cbbcdb0 100644 --- a/senlin/drivers/openstack/lbaas.py +++ b/senlin/drivers/openstack/lbaas.py @@ -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, diff --git a/senlin/drivers/openstack/neutron_v2.py b/senlin/drivers/openstack/neutron_v2.py index 6b171c74f..b8a9ffade 100644 --- a/senlin/drivers/openstack/neutron_v2.py +++ b/senlin/drivers/openstack/neutron_v2.py @@ -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) diff --git a/senlin/drivers/openstack/octavia_v2.py b/senlin/drivers/openstack/octavia_v2.py new file mode 100644 index 000000000..fc211b1f5 --- /dev/null +++ b/senlin/drivers/openstack/octavia_v2.py @@ -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 diff --git a/senlin/policies/base.py b/senlin/policies/base.py index 6b7fea2a2..97126e6da 100644 --- a/senlin/policies/base.py +++ b/senlin/policies/base.py @@ -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. diff --git a/senlin/policies/lb_policy.py b/senlin/policies/lb_policy.py index 64a219dff..9dc324259 100644 --- a/senlin/policies/lb_policy.py +++ b/senlin/policies/lb_policy.py @@ -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): diff --git a/senlin/tests/unit/drivers/test_lbaas_driver.py b/senlin/tests/unit/drivers/test_lbaas_driver.py index 27f99afea..df275bcb2 100644 --- a/senlin/tests/unit/drivers/test_lbaas_driver.py +++ b/senlin/tests/unit/drivers/test_lbaas_driver.py @@ -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) diff --git a/senlin/tests/unit/drivers/test_neutron_v2_driver.py b/senlin/tests/unit/drivers/test_neutron_v2_driver.py index 64123bdd1..27ffd3812 100644 --- a/senlin/tests/unit/drivers/test_neutron_v2_driver.py +++ b/senlin/tests/unit/drivers/test_neutron_v2_driver.py @@ -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' diff --git a/senlin/tests/unit/drivers/test_octavia_v2.py b/senlin/tests/unit/drivers/test_octavia_v2.py new file mode 100644 index 000000000..182695643 --- /dev/null +++ b/senlin/tests/unit/drivers/test_octavia_v2.py @@ -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) diff --git a/senlin/tests/unit/policies/test_lb_policy.py b/senlin/tests/unit/policies/test_lb_policy.py index cc0dd1801..2fe88204b 100644 --- a/senlin/tests/unit/policies/test_lb_policy.py +++ b/senlin/tests/unit/policies/test_lb_policy.py @@ -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))