From 46348c918f1fbbc773a05f8909f278a9785e90a7 Mon Sep 17 00:00:00 2001 From: Shane McGough Date: Thu, 26 Mar 2015 10:44:08 +0000 Subject: [PATCH] Implement KEMPtechnologies lbaas driver v2 shim Added the passthrough shim driver for KEMP appliances. Updated the config file with the KEMP path to the driver. Added unit tests to test the shim. Change-Id: Ib429c8ebde4d2cbb54ad37f4bfe6e4255706479b Closes-bug: 1436781 --- etc/neutron_lbaas.conf | 1 + .../drivers/kemptechnologies/__init__.py | 0 .../drivers/kemptechnologies/config.py | 32 ++++++ .../drivers/kemptechnologies/driver_v2.py | 101 ++++++++++++++++++ .../unit/drivers/kemptechnologies/__init__.py | 0 .../kemptechnologies/test_driver_v2.py | 98 +++++++++++++++++ 6 files changed, 232 insertions(+) create mode 100644 neutron_lbaas/drivers/kemptechnologies/__init__.py create mode 100644 neutron_lbaas/drivers/kemptechnologies/config.py create mode 100644 neutron_lbaas/drivers/kemptechnologies/driver_v2.py create mode 100644 neutron_lbaas/tests/unit/drivers/kemptechnologies/__init__.py create mode 100644 neutron_lbaas/tests/unit/drivers/kemptechnologies/test_driver_v2.py diff --git a/etc/neutron_lbaas.conf b/etc/neutron_lbaas.conf index f1a11640f..28413e1ff 100644 --- a/etc/neutron_lbaas.conf +++ b/etc/neutron_lbaas.conf @@ -62,6 +62,7 @@ service_provider=LOADBALANCER:Haproxy:neutron_lbaas.services.loadbalancer.driver # service_provider=LOADBALANCERV2:Haproxy:neutron_lbaas.drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver:default # service_provider = LOADBALANCERV2:A10Networks:neutron_lbaas.drivers.a10networks.driver_v2.ThunderDriver:default # service_provider = LOADBALANCERV2:brocade:neutron_lbaas.drivers.brocade.driver_v2.BrocadeLoadBalancerDriver:default +# service_provider = LOADBALANCERV2:kemptechnologies:neutron_lbaas.drivers.kemptechnologies.driver_v2.KempLoadMasterDriver:default [certificates] # cert_manager_class = neutron_lbaas.common.cert_manager.barbican_cert_manager diff --git a/neutron_lbaas/drivers/kemptechnologies/__init__.py b/neutron_lbaas/drivers/kemptechnologies/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/neutron_lbaas/drivers/kemptechnologies/config.py b/neutron_lbaas/drivers/kemptechnologies/config.py new file mode 100644 index 000000000..53ce575df --- /dev/null +++ b/neutron_lbaas/drivers/kemptechnologies/config.py @@ -0,0 +1,32 @@ +# Copyright 2015, Shane McGough, KEMPtechnologies +# 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 oslo_config import cfg + +KEMP_OPTS = [ + cfg.StrOpt('lm_address', default='192.168.0.1', + help=_('Management address of the LoadMaster appliance.')), + cfg.StrOpt('lm_username', default='bal', + help=_('The management user. Default is bal.')), + cfg.StrOpt('lm_password', default='1fourall', secret=True, + help=_('Password for management user. Default is 1fourall.')), + cfg.IntOpt('check_interval', default=9, + help=_('The interval between real server health checks.')), + cfg.IntOpt('connect_timeout', default=4, + help=_('The time to wait for a real server to respond to a ' + 'health check request.')), + cfg.IntOpt('retry_count', default=2, + help=_('If a real server fails to respond to a health check ' + 'request. The LoadMaster will retry the specified ' + 'number of times.')), +] diff --git a/neutron_lbaas/drivers/kemptechnologies/driver_v2.py b/neutron_lbaas/drivers/kemptechnologies/driver_v2.py new file mode 100644 index 000000000..284edc538 --- /dev/null +++ b/neutron_lbaas/drivers/kemptechnologies/driver_v2.py @@ -0,0 +1,101 @@ +# Copyright 2015, Shane McGough, KEMPtechnologies +# 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 kemptech_openstack_lbaas import driver as kemptech +from oslo_config import cfg + +from neutron_lbaas.drivers import driver_base +from neutron_lbaas.drivers.kemptechnologies import config + +cfg.CONF.register_opts(config.KEMP_OPTS, 'kemptechnologies') +CONF = cfg.CONF.kemptechnologies + + +class LoadBalancerManager(driver_base.BaseLoadBalancerManager): + + def create(self, context, lb): + self.driver.kemptech.load_balancer.create(context, lb) + + def update(self, context, old_lb, lb): + self.driver.kemptech.load_balancer.update(context, old_lb, lb) + + def delete(self, context, lb): + self.driver.kemptech.load_balancer.delete(context, lb) + + def refresh(self, context, lb): + self.driver.kemptech.load_balancer.refresh(context, lb) + + def stats(self, context, lb): + return self.driver.kemptech.load_balancer.stats(context, lb) + + +class ListenerManager(driver_base.BaseListenerManager): + + def create(self, context, listener): + self.driver.kemptech.listener.create(context, listener) + + def update(self, context, old_listener, listener): + self.driver.kemptech.listener.update(context, old_listener, listener) + + def delete(self, context, listener): + self.driver.kemptech.listener.delete(context, listener) + + +class PoolManager(driver_base.BasePoolManager): + + def create(self, context, pool): + self.driver.kemptech.pool.create(context, pool) + + def update(self, context, old_pool, pool): + self.driver.kemptech.pool.update(context, old_pool, pool) + + def delete(self, context, pool): + self.driver.kemptech.pool.delete(context, pool) + + +class MemberManager(driver_base.BaseMemberManager): + + def create(self, context, member): + self.driver.kemptech.member.create(context, member) + + def update(self, context, old_member, member): + self.driver.kemptech.member.update(context, old_member, member) + + def delete(self, context, member): + self.driver.kemptech.member.delete(context, member) + + +class HealthMonitorManager(driver_base.BaseHealthMonitorManager): + + def create(self, context, health_monitor): + self.driver.kemptech.health_monitor.create(context, health_monitor) + + def update(self, context, old_health_monitor, health_monitor): + self.driver.kemptech.health_monitor.update(context, + old_health_monitor, + health_monitor) + + def delete(self, context, health_monitor): + self.driver.kemptech.health_monitor.delete(context, health_monitor) + + +class KempLoadMasterDriver(driver_base.LoadBalancerBaseDriver): + + def __init__(self, plugin): + super(KempLoadMasterDriver, self).__init__(plugin) + self.load_balancer = LoadBalancerManager(self) + self.listener = ListenerManager(self) + self.pool = PoolManager(self) + self.member = MemberManager(self) + self.health_monitor = HealthMonitorManager(self) + self.kemptech = kemptech.KempLoadMasterDriver(self, CONF) diff --git a/neutron_lbaas/tests/unit/drivers/kemptechnologies/__init__.py b/neutron_lbaas/tests/unit/drivers/kemptechnologies/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/neutron_lbaas/tests/unit/drivers/kemptechnologies/test_driver_v2.py b/neutron_lbaas/tests/unit/drivers/kemptechnologies/test_driver_v2.py new file mode 100644 index 000000000..9f467b9e8 --- /dev/null +++ b/neutron_lbaas/tests/unit/drivers/kemptechnologies/test_driver_v2.py @@ -0,0 +1,98 @@ +# Copyright 2015, Shane McGough, KEMPtechnologies +# 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 sys + +import mock +from neutron import context + +from neutron_lbaas.tests.unit.db.loadbalancer import test_db_loadbalancerv2 + +with mock.patch.dict(sys.modules, {'kemptech_openstack_lbaas': mock.Mock()}): + from neutron_lbaas.drivers.kemptechnologies import driver_v2 + + +class FakeModel(object): + def __init__(self, id): + self.id = id + self.address = '1.1.1.1' + self.tenant_id = "copying-pre-existing-work-is-easy" + + +class ManagerTest(object): + def __init__(self, parent, manager, model, mocked_root): + self.parent = parent + self.context = parent.context + self.driver = parent.driver + self.manager = manager + self.model = model + self.mocked_root = mocked_root + + self.create(model) + self.update(model, model) + self.delete(model) + + def create(self, model): + self.manager.create(self.context, model) + self.mocked_root.create.assert_called_with(self.context, model) + + def update(self, old_model, model): + self.manager.update(self.context, old_model, model) + self.mocked_root.update.assert_called_with(self.context, + old_model, model) + + def delete(self, model): + self.manager.delete(self.context, model) + self.mocked_root.delete.assert_called_with(self.context, model) + + def refresh(self): + self.manager.refresh(self.context, self.model) + self.mocked_root.refresh.assert_called_with(self.context, self.model) + + def stats(self): + self.manager.stats(self.context, self.model) + self.mocked_root.stats.assert_called_with(self.context, self.model) + + +class TestKempLoadMasterDriver(test_db_loadbalancerv2.LbaasPluginDbTestCase): + + def setUp(self): + super(TestKempLoadMasterDriver, self).setUp() + self.context = context.get_admin_context() + self.plugin = mock.Mock() + self.driver = driver_v2.KempLoadMasterDriver(self.plugin) + self.driver.kemptech = mock.Mock() + + def test_load_balancer_ops(self): + m = ManagerTest(self, self.driver.load_balancer, + FakeModel("load_balancer-kemptech"), + self.driver.kemptech.load_balancer) + m.refresh() + m.stats() + + def test_listener_ops(self): + ManagerTest(self, self.driver.listener, FakeModel("listener-kemptech"), + self.driver.kemptech.listener) + + def test_pool_ops(self): + ManagerTest(self, self.driver.pool, FakeModel("pool-kemptech"), + self.driver.kemptech.pool) + + def test_member_ops(self): + ManagerTest(self, self.driver.member, FakeModel("member-kemptech"), + self.driver.kemptech.member) + + def test_health_monitor_ops(self): + ManagerTest(self, self.driver.health_monitor, + FakeModel("health_monitor-kemptech"), + self.driver.kemptech.health_monitor)