]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
LBaaS: fix handling pending create/update members and health monitors
authorOleg Bondarev <obondarev@mirantis.com>
Thu, 12 Dec 2013 08:13:22 +0000 (12:13 +0400)
committerOleg Bondarev <obondarev@mirantis.com>
Thu, 12 Dec 2013 10:53:33 +0000 (14:53 +0400)
When agent requests loadbalancer logical config from server,
server returns only active pool members and health_monitors.
Need to make server return also members and monitors which are in pending states.

Also a small refactoring moving ACTIVE_PENDING set to common place

Change-Id: I8e10004f199f982b055da18ea7a0e5e4d11fa7fb
Closes-Bug: #1259965

neutron/plugins/common/constants.py
neutron/services/loadbalancer/drivers/haproxy/cfg.py
neutron/services/loadbalancer/drivers/haproxy/namespace_driver.py
neutron/services/loadbalancer/drivers/haproxy/plugin_driver.py
neutron/tests/unit/services/loadbalancer/drivers/haproxy/test_cfg.py
neutron/tests/unit/services/loadbalancer/drivers/haproxy/test_plugin_driver.py

index e3ed1ab70ecfd891d04c969e27bade8d0801a974..0bbddd0711f533100e1b181ff133432bd00a4e78 100644 (file)
@@ -58,6 +58,12 @@ PENDING_DELETE = "PENDING_DELETE"
 INACTIVE = "INACTIVE"
 ERROR = "ERROR"
 
+ACTIVE_PENDING = (
+    ACTIVE,
+    PENDING_CREATE,
+    PENDING_UPDATE
+)
+
 # FWaaS firewall rule action
 FWAAS_ALLOW = "allow"
 FWAAS_DENY = "deny"
index 776b4b1500a5f928beb13a96029c811bd9fa9073..74447c6b55704b929936901b50fe7596c52ba24c 100644 (file)
@@ -47,7 +47,7 @@ STATS_MAP = {
     constants.STATS_RESPONSE_ERRORS: 'eresp'
 }
 
-ACTIVE = qconstants.ACTIVE
+ACTIVE_PENDING = qconstants.ACTIVE_PENDING
 INACTIVE = qconstants.INACTIVE
 
 
@@ -138,7 +138,9 @@ def _build_backend(config):
 
     # add the members
     for member in config['members']:
-        if member['status'] in (ACTIVE, INACTIVE) and member['admin_state_up']:
+        if ((member['status'] in ACTIVE_PENDING or
+             member['status'] == INACTIVE)
+            and member['admin_state_up']):
             server = (('server %(id)s %(address)s:%(protocol_port)s '
                        'weight %(weight)s') % member) + server_addon
             if _has_http_cookie_persistence(config):
index 03ff795a78be8114a32eb45cc8d2117fb6efd18a..1e09eb1d42794d6e312e43784820c9eda0eeab64 100644 (file)
@@ -37,12 +37,6 @@ LOG = logging.getLogger(__name__)
 NS_PREFIX = 'qlbaas-'
 DRIVER_NAME = 'haproxy_ns'
 
-ACTIVE_PENDING = (
-    constants.ACTIVE,
-    constants.PENDING_CREATE,
-    constants.PENDING_UPDATE
-)
-
 STATE_PATH_DEFAULT = '$state_path/lbaas'
 USER_GROUP_DEFAULT = 'nogroup'
 OPTS = [
@@ -269,7 +263,7 @@ class HaproxyNSDriver(agent_device_driver.AgentDeviceDriver):
     def deploy_instance(self, logical_config):
         # do actual deploy only if vip is configured and active
         if ('vip' not in logical_config or
-            logical_config['vip']['status'] not in ACTIVE_PENDING or
+            logical_config['vip']['status'] not in constants.ACTIVE_PENDING or
             not logical_config['vip']['admin_state_up']):
             return
 
index ad42b0c987a4b2ec0ad23263c8ee9c52723a34b5..a269af306ca54d1106cc808bbb35f072f2bd84c7 100644 (file)
@@ -36,12 +36,6 @@ from neutron.services.loadbalancer.drivers import abstract_driver
 
 LOG = logging.getLogger(__name__)
 
-ACTIVE_PENDING = (
-    constants.ACTIVE,
-    constants.PENDING_CREATE,
-    constants.PENDING_UPDATE
-)
-
 AGENT_SCHEDULER_OPTS = [
     cfg.StrOpt('loadbalancer_pool_scheduler_driver',
                default='neutron.services.loadbalancer.agent_scheduler'
@@ -92,7 +86,8 @@ class LoadBalancerCallbacks(object):
 
             qry = context.session.query(loadbalancer_db.Pool.id)
             qry = qry.filter(loadbalancer_db.Pool.id.in_(pool_ids))
-            qry = qry.filter(loadbalancer_db.Pool.status.in_(ACTIVE_PENDING))
+            qry = qry.filter(
+                loadbalancer_db.Pool.status.in_(constants.ACTIVE_PENDING))
             up = True  # makes pep8 and sqlalchemy happy
             qry = qry.filter(loadbalancer_db.Pool.admin_state_up == up)
             return [id for id, in qry]
@@ -123,13 +118,14 @@ class LoadBalancerCallbacks(object):
                     )
             retval['members'] = [
                 self.plugin._make_member_dict(m)
-                for m in pool.members if m.status in (constants.ACTIVE,
-                                                      constants.INACTIVE)
+                for m in pool.members if (
+                    m.status in constants.ACTIVE_PENDING or
+                    m.status == constants.INACTIVE)
             ]
             retval['healthmonitors'] = [
                 self.plugin._make_health_monitor_dict(hm.healthmonitor)
                 for hm in pool.monitors
-                if hm.status == constants.ACTIVE
+                if hm.status in constants.ACTIVE_PENDING
             ]
             retval['driver'] = (
                 self.plugin.drivers[pool.provider.provider_name].device_driver)
@@ -143,18 +139,18 @@ class LoadBalancerCallbacks(object):
             pool = qry.one()
 
             # set all resources to active
-            if pool.status in ACTIVE_PENDING:
+            if pool.status in constants.ACTIVE_PENDING:
                 pool.status = constants.ACTIVE
 
-            if pool.vip and pool.vip.status in ACTIVE_PENDING:
+            if pool.vip and pool.vip.status in constants.ACTIVE_PENDING:
                 pool.vip.status = constants.ACTIVE
 
             for m in pool.members:
-                if m.status in ACTIVE_PENDING:
+                if m.status in constants.ACTIVE_PENDING:
                     m.status = constants.ACTIVE
 
             for hm in pool.monitors:
-                if hm.status in ACTIVE_PENDING:
+                if hm.status in constants.ACTIVE_PENDING:
                     hm.status = constants.ACTIVE
 
     def update_status(self, context, obj_type, obj_id, status):
@@ -365,7 +361,7 @@ class AgentBasedPluginDriver(abstract_driver.LoadBalancerAbstractDriver):
 
     def update_vip(self, context, old_vip, vip):
         agent = self.get_pool_agent(context, vip['pool_id'])
-        if vip['status'] in ACTIVE_PENDING:
+        if vip['status'] in constants.ACTIVE_PENDING:
             self.agent_rpc.update_vip(context, old_vip, vip, agent['host'])
         else:
             self.agent_rpc.delete_vip(context, vip, agent['host'])
@@ -385,7 +381,7 @@ class AgentBasedPluginDriver(abstract_driver.LoadBalancerAbstractDriver):
 
     def update_pool(self, context, old_pool, pool):
         agent = self.get_pool_agent(context, pool['id'])
-        if pool['status'] in ACTIVE_PENDING:
+        if pool['status'] in constants.ACTIVE_PENDING:
             self.agent_rpc.update_pool(context, old_pool, pool,
                                        agent['host'])
         else:
index 6b40393fd4b9248491e380b3711740b16e0f6286..7c937c982e2565d8cf6798700a723ff4a6719a9d 100644 (file)
@@ -110,6 +110,12 @@ class TestHaproxyCfg(base.BaseTestCase):
                                     'id': 'member2_id',
                                     'address': '10.0.0.4',
                                     'protocol_port': 80,
+                                    'weight': 1},
+                                   {'status': 'PENDING_CREATE',
+                                    'admin_state_up': True,
+                                    'id': 'member3_id',
+                                    'address': '10.0.0.5',
+                                    'protocol_port': 80,
                                     'weight': 1}],
                        'healthmonitors': [{'admin_state_up': True,
                                            'delay': 3,
@@ -126,7 +132,9 @@ class TestHaproxyCfg(base.BaseTestCase):
                          '\tserver member1_id 10.0.0.3:80 weight 1 '
                          'check inter 3s fall 4 cookie 0',
                          '\tserver member2_id 10.0.0.4:80 weight 1 '
-                         'check inter 3s fall 4 cookie 1']
+                         'check inter 3s fall 4 cookie 1',
+                         '\tserver member3_id 10.0.0.5:80 weight 1 '
+                         'check inter 3s fall 4 cookie 2']
         opts = cfg._build_backend(test_config)
         self.assertEqual(expected_opts, list(opts))
 
index 5c521fdaea77eb71ff4a8df8ee22f0ac7e01511d..7e929a7791e8457aa3e3fed56247b6e64c0509f0 100644 (file)
@@ -261,6 +261,54 @@ class TestLoadBalancerCallbacks(TestLoadBalancerPluginBase):
                     self.assertEqual([member['member']],
                                      logical_config['members'])
 
+    def test_get_logical_device_pending_create_member(self):
+        with self.pool() as pool:
+            with self.vip(pool=pool) as vip:
+                with self.member(pool_id=vip['vip']['pool_id']) as member:
+                    ctx = context.get_admin_context()
+                    self.plugin_instance.update_status(ctx, ldb.Pool,
+                                                       pool['pool']['id'],
+                                                       'ACTIVE')
+                    self.plugin_instance.update_status(ctx, ldb.Vip,
+                                                       vip['vip']['id'],
+                                                       'ACTIVE')
+
+                    member = self.plugin_instance.get_member(
+                        ctx, member['member']['id'])
+                    self.assertEqual('PENDING_CREATE',
+                                     member['status'])
+                    logical_config = self.callbacks.get_logical_device(
+                        ctx, pool['pool']['id'])
+
+                    self.assertEqual([member], logical_config['members'])
+
+    def test_get_logical_device_pending_create_health_monitor(self):
+        with self.pool() as pool:
+            with self.vip(pool=pool) as vip:
+                with self.health_monitor() as monitor:
+                    ctx = context.get_admin_context()
+                    self.plugin_instance.update_status(ctx, ldb.Pool,
+                                                       pool['pool']['id'],
+                                                       'ACTIVE')
+                    self.plugin_instance.update_status(ctx, ldb.Vip,
+                                                       vip['vip']['id'],
+                                                       'ACTIVE')
+                    self.plugin_instance.create_pool_health_monitor(
+                        ctx, monitor, pool['pool']['id'])
+                    pool = self.plugin_instance.get_pool(
+                        ctx, pool['pool']['id'])
+                    monitor = self.plugin_instance.get_health_monitor(
+                        ctx, monitor['health_monitor']['id'])
+
+                    self.assertEqual(
+                        'PENDING_CREATE',
+                        pool['health_monitors_status'][0]['status'])
+                    logical_config = self.callbacks.get_logical_device(
+                        ctx, pool['id'])
+
+                    self.assertEqual([monitor],
+                                     logical_config['healthmonitors'])
+
     def _update_port_test_helper(self, expected, func, **kwargs):
         core = self.plugin_instance._core_plugin