From fb34fdbfc0efafc8388d2617177972b03377e521 Mon Sep 17 00:00:00 2001 From: Pattabi Ayyasami Date: Tue, 17 Mar 2015 21:53:00 -0400 Subject: [PATCH] Brocade Driver for lbaas v2 data model Change-Id: I38721a91d8c365dfadf09535c50463fa634ef7e4 --- etc/neutron_lbaas.conf | 1 + neutron_lbaas/drivers/brocade/README | 12 ++ neutron_lbaas/drivers/brocade/__init__.py | 0 neutron_lbaas/drivers/brocade/driver_v2.py | 167 ++++++++++++++++++ .../tests/unit/drivers/brocade/__init__.py | 0 .../unit/drivers/brocade/test_driver_v2.py | 145 +++++++++++++++ 6 files changed, 325 insertions(+) create mode 100644 neutron_lbaas/drivers/brocade/README create mode 100644 neutron_lbaas/drivers/brocade/__init__.py create mode 100644 neutron_lbaas/drivers/brocade/driver_v2.py create mode 100644 neutron_lbaas/tests/unit/drivers/brocade/__init__.py create mode 100644 neutron_lbaas/tests/unit/drivers/brocade/test_driver_v2.py diff --git a/etc/neutron_lbaas.conf b/etc/neutron_lbaas.conf index 6c04e8971..c0190d0ba 100644 --- a/etc/neutron_lbaas.conf +++ b/etc/neutron_lbaas.conf @@ -60,6 +60,7 @@ service_provider=LOADBALANCER:Haproxy:neutron_lbaas.services.loadbalancer.driver # service_provider = LOADBALANCERV2:LoggingNoop:neutron_lbaas.drivers.logging_noop.driver.LoggingNoopLoadBalancerDriver:default # 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 [certificates] # cert_manager_class = neutron_lbaas.common.cert_manager.local_cert_manager diff --git a/neutron_lbaas/drivers/brocade/README b/neutron_lbaas/drivers/brocade/README new file mode 100644 index 000000000..b7537f92b --- /dev/null +++ b/neutron_lbaas/drivers/brocade/README @@ -0,0 +1,12 @@ +Brocade LBaaS Driver + +Installation info: + +- Install Brocade LBaaS Device Driver +- Enable Brocade as default lbaas service provider in neutron_lbaas.conf file +- Restart Neutron Server + +Third-party CI info: + +Contact info for any problems is: DL-GRP-ENG-brocade-adx-openstack-ci at brocade dot com +Or contact Pattabi Ayyasami directly (IRC: pattabi) diff --git a/neutron_lbaas/drivers/brocade/__init__.py b/neutron_lbaas/drivers/brocade/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/neutron_lbaas/drivers/brocade/driver_v2.py b/neutron_lbaas/drivers/brocade/driver_v2.py new file mode 100644 index 000000000..30e7b2478 --- /dev/null +++ b/neutron_lbaas/drivers/brocade/driver_v2.py @@ -0,0 +1,167 @@ +# +# Copyright 2014 Brocade Communications Systems, Inc. All rights reserved. +# +# 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. +# +# Pattabi Ayyasami (pattabi), Brocade Communications Systems,Inc. +# + +from brocade_neutron_lbaas import adx_device_driver_v2 as device_driver + +from neutron_lbaas.drivers import driver_base + + +class BrocadeLoadBalancerDriver(driver_base.LoadBalancerBaseDriver): + + def __init__(self, plugin): + super(BrocadeLoadBalancerDriver, self).__init__(plugin) + + self.load_balancer = BrocadeLoadBalancerManager(self) + self.listener = BrocadeListenerManager(self) + self.pool = BrocadePoolManager(self) + self.member = BrocadeMemberManager(self) + self.health_monitor = BrocadeHealthMonitorManager(self) + self.device_driver = device_driver.BrocadeAdxDeviceDriverV2(plugin) + + +class BrocadeLoadBalancerManager(driver_base.BaseLoadBalancerManager): + def create(self, context, obj): + try: + self.driver.device_driver.create_loadbalancer(obj) + self.successful_completion(context, obj) + except Exception: + self.failed_completion(context, obj) + + def update(self, context, old_obj, obj): + try: + self.driver.device_driver.update_loadbalancer(obj, old_obj) + self.successful_completion(context, obj) + except Exception: + self.failed_completion(context, obj) + + def delete(self, context, obj): + try: + self.driver.device_driver.delete_loadbalancer(obj) + except Exception: + # Ignore the exception + pass + + self.successful_completion(context, obj, delete=True) + + def refresh(self, context, lb_obj): + # This is intended to trigger the backend to check and repair + # the state of this load balancer and all of its dependent objects + self.driver.device_driver.refresh(lb_obj) + + def stats(self, context, lb_obj): + return self.driver.device_driver.stats(lb_obj) + + +class BrocadeListenerManager(driver_base.BaseListenerManager): + def create(self, context, obj): + try: + self.driver.device_driver.create_listener(obj) + self.successful_completion(context, obj) + except Exception: + self.failed_completion(context, obj) + + def update(self, context, old_obj, obj): + try: + self.driver.device_driver.update_listener(obj, old_obj) + self.successful_completion(context, obj) + except Exception: + self.failed_completion(context, obj) + + def delete(self, context, obj): + try: + self.driver.device_driver.delete_listener(obj) + except Exception: + # Ignore the exception + pass + + self.successful_completion(context, obj, delete=True) + + +class BrocadePoolManager(driver_base.BasePoolManager): + def create(self, context, obj): + try: + self.driver.device_driver.create_pool(obj) + self.successful_completion(context, obj) + except Exception: + self.failed_completion(context, obj) + + def update(self, context, old_obj, obj): + try: + self.driver.device_driver.update_pool(obj, old_obj) + self.successful_completion(context, obj) + except Exception: + self.failed_completion(context, obj) + + def delete(self, context, obj): + try: + self.driver.device_driver.delete_pool(obj) + except Exception: + # Ignore the exception + pass + + self.successful_completion(context, obj, delete=True) + + +class BrocadeMemberManager(driver_base.BaseMemberManager): + def create(self, context, obj): + try: + self.driver.device_driver.create_member(obj) + self.successful_completion(context, obj) + except Exception: + self.failed_completion(context, obj) + + def update(self, context, old_obj, obj): + try: + self.driver.device_driver.update_member(obj, old_obj) + self.successful_completion(context, obj) + except Exception: + self.failed_completion(context, obj) + + def delete(self, context, obj): + try: + self.driver.device_driver.delete_member(obj) + except Exception: + # Ignore the exception + pass + + self.successful_completion(context, obj, delete=True) + + +class BrocadeHealthMonitorManager(driver_base.BaseHealthMonitorManager): + def create(self, context, obj): + try: + self.driver.device_driver.create_healthmonitor(obj) + self.successful_completion(context, obj) + except Exception: + self.failed_completion(context, obj) + + def update(self, context, old_obj, obj): + try: + self.driver.device_driver.update_healthmonitor(obj, old_obj) + self.successful_completion(context, obj) + except Exception: + self.failed_completion(context, obj) + + def delete(self, context, obj): + try: + self.driver.device_driver.delete_healthmonitor(obj) + except Exception: + # Ignore the exception + pass + + self.successful_completion(context, obj, delete=True) diff --git a/neutron_lbaas/tests/unit/drivers/brocade/__init__.py b/neutron_lbaas/tests/unit/drivers/brocade/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/neutron_lbaas/tests/unit/drivers/brocade/test_driver_v2.py b/neutron_lbaas/tests/unit/drivers/brocade/test_driver_v2.py new file mode 100644 index 000000000..597870791 --- /dev/null +++ b/neutron_lbaas/tests/unit/drivers/brocade/test_driver_v2.py @@ -0,0 +1,145 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# +# Copyright 2014 Brocade Communications Systems, Inc. +# All Rights Reserved. +# +# 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. +# +# Pattabi Ayyasami (pattabi), Brocade Communication Systems, Inc. +# +import sys + +import mock +from neutron import context + +with mock.patch.dict(sys.modules, {'brocade_neutron_lbaas': mock.Mock()}): + from neutron_lbaas.drivers.brocade import driver_v2 as driver +from neutron_lbaas.services.loadbalancer import data_models +from neutron_lbaas.tests.unit.db.loadbalancer import test_db_loadbalancer + + +class FakeModel(object): + def __init__(self, id): + self.id = id + + def attached_to_loadbalancer(self): + return True + + +class ManagerTest(object): + def __init__(self, parent, manager, model): + self.parent = parent + self.manager = manager + self.model = model + + self.create(model) + self.update(model, model) + self.delete(model) + + def create(self, model): + self.manager.create(self.parent.context, model) + + def update(self, old_model, model): + self.manager.update(self.parent.context, old_model, model) + + def delete(self, model): + self.manager.delete(self.parent.context, model) + + +class LoadBalancerManagerTest(ManagerTest): + def __init__(self, parent, manager, model): + super(LoadBalancerManagerTest, self).__init__(parent, manager, model) + + self.refresh(model) + self.stats(model) + + def refresh(self, model): + self.manager.refresh(self.parent.context, model) + self.parent.driver.device_driver.refresh \ + .assert_called_once_with(model) + + def stats(self, model): + self.manager.stats(self.parent.context, model) + self.parent.driver.device_driver.stats.assert_called_once_with(model) + + +class TestBrocadeLoadBalancerDriver( + test_db_loadbalancer.LoadBalancerPluginDbTestCase): + + def _create_fake_models(self): + id = 'name-001' + lb = data_models.LoadBalancer(id=id) + listener = data_models.Listener(id=id, loadbalancer=lb) + pool = data_models.Pool(id=id, listener=listener) + member = data_models.Member(id=id, pool=pool) + hm = data_models.HealthMonitor(id=id, pool=pool) + lb.listeners = [listener] + listener.default_pool = pool + pool.members = [member] + pool.healthmonitor = hm + return lb + + def setUp(self): + super(TestBrocadeLoadBalancerDriver, self).setUp() + self.context = context.get_admin_context() + self.plugin = mock.Mock() + self.driver = driver.BrocadeLoadBalancerDriver(self.plugin) + self.lb = self._create_fake_models() + + def test_load_balancer_ops(self): + LoadBalancerManagerTest(self, self.driver.load_balancer, + self.lb) + self.driver.device_driver.create_loadbalancer \ + .assert_called_once_with(self.lb) + self.driver.device_driver.update_loadbalancer \ + .assert_called_once_with(self.lb, self.lb) + self.driver.device_driver.delete_loadbalancer \ + .assert_called_once_with(self.lb) + + def test_listener_ops(self): + ManagerTest(self, self.driver.listener, self.lb.listeners[0]) + self.driver.device_driver.create_listener \ + .assert_called_once_with(self.lb.listeners[0]) + self.driver.device_driver.update_listener \ + .assert_called_once_with(self.lb.listeners[0], + self.lb.listeners[0]) + self.driver.device_driver.delete_listener \ + .assert_called_once_with(self.lb.listeners[0]) + + def test_pool_ops(self): + pool_fake_model = self.lb.listeners[0].default_pool + ManagerTest(self, self.driver.pool, + pool_fake_model) + self.driver.device_driver.update_pool \ + .assert_called_once_with(pool_fake_model, pool_fake_model) + self.driver.device_driver.delete_pool \ + .assert_called_once_with(pool_fake_model) + + def test_member_ops(self): + member_fake_model = self.lb.listeners[0].default_pool.members[0] + ManagerTest(self, self.driver.member, + member_fake_model) + self.driver.device_driver.create_member \ + .assert_called_once_with(member_fake_model) + self.driver.device_driver.update_member \ + .assert_called_once_with(member_fake_model, member_fake_model) + self.driver.device_driver.delete_member \ + .assert_called_once_with(member_fake_model) + + def test_health_monitor_ops(self): + hm_fake_model = self.lb.listeners[0].default_pool.healthmonitor + ManagerTest(self, self.driver.health_monitor, hm_fake_model) + self.driver.device_driver.update_healthmonitor \ + .assert_called_once_with(hm_fake_model, hm_fake_model) + self.driver.device_driver.delete_healthmonitor \ + .assert_called_once_with(hm_fake_model)