]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Add status description field for lbaas objects
authorOleg Bondarev <obondarev@mirantis.com>
Mon, 24 Jun 2013 12:50:19 +0000 (16:50 +0400)
committerOleg Bondarev <obondarev@mirantis.com>
Wed, 10 Jul 2013 14:04:46 +0000 (18:04 +0400)
Fixes bug 1166925

Change-Id: I44d936afd8cd531a786c09c38bbc4702737ce99c

neutron/db/loadbalancer/loadbalancer_db.py
neutron/db/migration/alembic_migrations/versions/2032abe8edac_lbaas_add_status_des.py [new file with mode: 0644]
neutron/db/models_v2.py
neutron/extensions/loadbalancer.py
neutron/tests/unit/db/loadbalancer/test_db_loadbalancer.py

index b207e3f8a1b79c4f57a92763bcadc45e88ebe7f8..12dee74d454182cb8f2c5246950bc4b088e3e515 100644 (file)
@@ -71,7 +71,8 @@ class PoolStatistics(model_base.BASEV2):
         return value
 
 
-class Vip(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
+class Vip(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant,
+          models_v2.HasStatusDescription):
     """Represents a v2 neutron loadbalancer vip."""
 
     name = sa.Column(sa.String(255))
@@ -85,13 +86,13 @@ class Vip(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
                                            uselist=False,
                                            backref="vips",
                                            cascade="all, delete-orphan")
-    status = sa.Column(sa.String(16), nullable=False)
     admin_state_up = sa.Column(sa.Boolean(), nullable=False)
     connection_limit = sa.Column(sa.Integer)
     port = orm.relationship(models_v2.Port)
 
 
-class Member(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
+class Member(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant,
+             models_v2.HasStatusDescription):
     """Represents a v2 neutron loadbalancer member."""
 
     pool_id = sa.Column(sa.String(36), sa.ForeignKey("pools.id"),
@@ -99,11 +100,11 @@ class Member(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
     address = sa.Column(sa.String(64), nullable=False)
     protocol_port = sa.Column(sa.Integer, nullable=False)
     weight = sa.Column(sa.Integer, nullable=False)
-    status = sa.Column(sa.String(16), nullable=False)
     admin_state_up = sa.Column(sa.Boolean(), nullable=False)
 
 
-class Pool(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
+class Pool(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant,
+           models_v2.HasStatusDescription):
     """Represents a v2 neutron loadbalancer pool."""
 
     vip_id = sa.Column(sa.String(36), sa.ForeignKey("vips.id"))
@@ -117,7 +118,6 @@ class Pool(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
                                   "SOURCE_IP",
                                   name="pools_lb_method"),
                           nullable=False)
-    status = sa.Column(sa.String(16), nullable=False)
     admin_state_up = sa.Column(sa.Boolean(), nullable=False)
     stats = orm.relationship(PoolStatistics,
                              uselist=False,
@@ -130,7 +130,8 @@ class Pool(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
     vip = orm.relationship(Vip, backref='pool')
 
 
-class HealthMonitor(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
+class HealthMonitor(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant,
+                    models_v2.HasStatusDescription):
     """Represents a v2 neutron loadbalancer healthmonitor."""
 
     type = sa.Column(sa.Enum("PING", "TCP", "HTTP", "HTTPS",
@@ -142,7 +143,6 @@ class HealthMonitor(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant):
     http_method = sa.Column(sa.String(16))
     url_path = sa.Column(sa.String(255))
     expected_codes = sa.Column(sa.String(64))
-    status = sa.Column(sa.String(16), nullable=False)
     admin_state_up = sa.Column(sa.Boolean(), nullable=False)
 
     pools = orm.relationship(
@@ -175,10 +175,16 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase,
     def _core_plugin(self):
         return manager.NeutronManager.get_plugin()
 
-    def update_status(self, context, model, id, status):
+    def update_status(self, context, model, id, status,
+                      status_description=None):
         with context.session.begin(subtransactions=True):
             v_db = self._get_resource(context, model, id)
-            v_db.update({'status': status})
+            v_db.status = status
+            # update status_description in two cases:
+            # - new value is passed
+            # - old value is not None (needs to be updated anyway)
+            if status_description or v_db['status_description']:
+                v_db.status_description = status_description
 
     def _get_resource(self, context, model, id):
         try:
@@ -219,7 +225,8 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase,
                'pool_id': vip['pool_id'],
                'connection_limit': vip['connection_limit'],
                'admin_state_up': vip['admin_state_up'],
-               'status': vip['status']}
+               'status': vip['status'],
+               'status_description': vip['status_description']}
 
         if vip['session_persistence']:
             s_p = {
@@ -448,7 +455,8 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase,
                'vip_id': pool['vip_id'],
                'lb_method': pool['lb_method'],
                'admin_state_up': pool['admin_state_up'],
-               'status': pool['status']}
+               'status': pool['status'],
+               'status_description': pool['status_description']}
 
         # Get the associated members
         res['members'] = [member['id'] for member in pool['members']]
@@ -593,7 +601,9 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase,
                'protocol_port': member['protocol_port'],
                'weight': member['weight'],
                'admin_state_up': member['admin_state_up'],
-               'status': member['status']}
+               'status': member['status'],
+               'status_description': member['status_description']}
+
         return self._fields(res, fields)
 
     def create_member(self, context, member):
@@ -650,7 +660,8 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase,
                'timeout': health_monitor['timeout'],
                'max_retries': health_monitor['max_retries'],
                'admin_state_up': health_monitor['admin_state_up'],
-               'status': health_monitor['status']}
+               'status': health_monitor['status'],
+               'status_description': health_monitor['status_description']}
         # no point to add the values below to
         # the result if the 'type' is not HTTP/S
         if res['type'] in ['HTTP', 'HTTPS']:
diff --git a/neutron/db/migration/alembic_migrations/versions/2032abe8edac_lbaas_add_status_des.py b/neutron/db/migration/alembic_migrations/versions/2032abe8edac_lbaas_add_status_des.py
new file mode 100644 (file)
index 0000000..05b30e3
--- /dev/null
@@ -0,0 +1,55 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# Copyright 2013 OpenStack Foundation
+#
+#    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.
+#
+
+"""LBaaS add status description
+
+Revision ID: 2032abe8edac
+Revises: b7a8863760e
+Create Date: 2013-06-24 06:51:47.308545
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '2032abe8edac'
+down_revision = 'b7a8863760e'
+
+# Change to ['*'] if this migration applies to all plugins
+
+migration_for_plugins = ['*']
+
+from alembic import op
+import sqlalchemy as sa
+
+from neutron.db import migration
+
+ENTITIES = ['vips', 'pools', 'members', 'healthmonitors']
+
+
+def upgrade(active_plugin=None, options=None):
+    if not migration.should_run(active_plugin, migration_for_plugins):
+        return
+
+    for entity in ENTITIES:
+        op.add_column(entity, sa.Column('status_description', sa.String(255)))
+
+
+def downgrade(active_plugin=None, options=None):
+    if not migration.should_run(active_plugin, migration_for_plugins):
+        return
+
+    for entity in ENTITIES:
+        op.drop_column(entity, 'status_description')
index 2db0e63986472ab540b0fc3f46158624f640306c..8c00ffce546d5acc35c71e70fdcaa631eaeb7216 100644 (file)
@@ -37,6 +37,13 @@ class HasId(object):
                    default=uuidutils.generate_uuid)
 
 
+class HasStatusDescription(object):
+    """Status with description mixin."""
+
+    status = sa.Column(sa.String(16), nullable=False)
+    status_description = sa.Column(sa.String(255))
+
+
 class IPAvailabilityRange(model_base.BASEV2):
     """Internal representation of available IPs for Neutron subnets.
 
index 7a6da2619dfccfe8c1708f139da2fc22a2925e28..d93360f037d28a2ed9f4090c6249dcb2bc5bb874 100644 (file)
@@ -124,7 +124,9 @@ RESOURCE_ATTRIBUTE_MAP = {
                            'convert_to': attr.convert_to_boolean,
                            'is_visible': True},
         'status': {'allow_post': False, 'allow_put': False,
-                   'is_visible': True}
+                   'is_visible': True},
+        'status_description': {'allow_post': False, 'allow_put': False,
+                               'is_visible': True}
     },
     'pools': {
         'id': {'allow_post': False, 'allow_put': False,
@@ -165,7 +167,9 @@ RESOURCE_ATTRIBUTE_MAP = {
                            'convert_to': attr.convert_to_boolean,
                            'is_visible': True},
         'status': {'allow_post': False, 'allow_put': False,
-                   'is_visible': True}
+                   'is_visible': True},
+        'status_description': {'allow_post': False, 'allow_put': False,
+                               'is_visible': True}
     },
     'members': {
         'id': {'allow_post': False, 'allow_put': False,
@@ -196,7 +200,9 @@ RESOURCE_ATTRIBUTE_MAP = {
                            'convert_to': attr.convert_to_boolean,
                            'is_visible': True},
         'status': {'allow_post': False, 'allow_put': False,
-                   'is_visible': True}
+                   'is_visible': True},
+        'status_description': {'allow_post': False, 'allow_put': False,
+                               'is_visible': True}
     },
     'health_monitors': {
         'id': {'allow_post': False, 'allow_put': False,
@@ -240,7 +246,9 @@ RESOURCE_ATTRIBUTE_MAP = {
                            'convert_to': attr.convert_to_boolean,
                            'is_visible': True},
         'status': {'allow_post': False, 'allow_put': False,
-                   'is_visible': True}
+                   'is_visible': True},
+        'status_description': {'allow_post': False, 'allow_put': False,
+                               'is_visible': True}
     }
 }
 
index 750441f2cba38bed97b8a7dbe19daeada642bd93..e28d227261caadc80eddd5edd76c5afb90663f84 100644 (file)
@@ -1179,6 +1179,26 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
                               "123-456-789"
                               )
 
+    def test_update_status(self):
+        with self.pool() as pool:
+            self.assertEqual(pool['pool']['status'], 'PENDING_CREATE')
+            self.assertFalse(pool['pool']['status_description'])
+
+            self.plugin.update_status(context.get_admin_context(), ldb.Pool,
+                                      pool['pool']['id'], 'ERROR', 'unknown')
+            updated_pool = self.plugin.get_pool(context.get_admin_context(),
+                                                pool['pool']['id'])
+            self.assertEqual(updated_pool['status'], 'ERROR')
+            self.assertEqual(updated_pool['status_description'], 'unknown')
+
+            # update status to ACTIVE, status_description should be cleared
+            self.plugin.update_status(context.get_admin_context(), ldb.Pool,
+                                      pool['pool']['id'], 'ACTIVE')
+            updated_pool = self.plugin.get_pool(context.get_admin_context(),
+                                                pool['pool']['id'])
+            self.assertEqual(updated_pool['status'], 'ACTIVE')
+            self.assertFalse(pool['pool']['status_description'])
+
 
 class TestLoadBalancerXML(TestLoadBalancer):
     fmt = 'xml'