Merge "LBaaS: add status field to PoolMonitorAssociation table"

This commit is contained in:
Jenkins 2013-08-01 21:50:25 +00:00 committed by Gerrit Code Review
commit 0a21ea951b
7 changed files with 132 additions and 21 deletions

View File

@ -152,7 +152,8 @@ class HealthMonitor(model_base.BASEV2, models_v2.HasId, models_v2.HasTenant,
) )
class PoolMonitorAssociation(model_base.BASEV2): class PoolMonitorAssociation(model_base.BASEV2,
models_v2.HasStatusDescription):
"""Many-to-many association between pool and healthMonitor classes.""" """Many-to-many association between pool and healthMonitor classes."""
pool_id = sa.Column(sa.String(36), pool_id = sa.Column(sa.String(36),
@ -568,7 +569,8 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase,
pool = self._get_resource(context, Pool, pool_id) pool = self._get_resource(context, Pool, pool_id)
assoc = PoolMonitorAssociation(pool_id=pool_id, assoc = PoolMonitorAssociation(pool_id=pool_id,
monitor_id=monitor_id) monitor_id=monitor_id,
status=constants.PENDING_CREATE)
pool.monitors.append(assoc) pool.monitors.append(assoc)
monitors = [monitor['monitor_id'] for monitor in pool['monitors']] monitors = [monitor['monitor_id'] for monitor in pool['monitors']]
@ -577,19 +579,25 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase,
def delete_pool_health_monitor(self, context, id, pool_id): def delete_pool_health_monitor(self, context, id, pool_id):
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
assoc = self.get_pool_health_monitor(context, id, pool_id)
pool = self._get_resource(context, Pool, pool_id) pool = self._get_resource(context, Pool, pool_id)
try: pool.monitors.remove(assoc)
monitor_qry = context.session.query(PoolMonitorAssociation)
monitor = monitor_qry.filter_by(monitor_id=id,
pool_id=pool_id).one()
pool.monitors.remove(monitor)
except exc.NoResultFound:
raise loadbalancer.HealthMonitorNotFound(monitor_id=id)
def get_pool_health_monitor(self, context, id, pool_id, fields=None): def get_pool_health_monitor(self, context, id, pool_id, fields=None):
# TODO(markmcclain) look into why pool_id is ignored try:
healthmonitor = self._get_resource(context, HealthMonitor, id) assoc_qry = context.session.query(PoolMonitorAssociation)
return self._make_health_monitor_dict(healthmonitor, fields) return assoc_qry.filter_by(monitor_id=id, pool_id=pool_id).one()
except exc.NoResultFound:
raise loadbalancer.PoolMonitorAssociationNotFound(
monitor_id=id, pool_id=pool_id)
def update_pool_health_monitor(self, context, id, pool_id,
status, status_description=None):
with context.session.begin(subtransactions=True):
assoc = self.get_pool_health_monitor(context, id, pool_id)
self.assert_modification_allowed(assoc)
assoc.status = status
assoc.status_description = status_description
######################################################## ########################################################
# Member DB access # Member DB access
@ -674,6 +682,7 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase,
v = health_monitor['health_monitor'] v = health_monitor['health_monitor']
tenant_id = self._get_tenant_id_for_create(context, v) tenant_id = self._get_tenant_id_for_create(context, v)
with context.session.begin(subtransactions=True): with context.session.begin(subtransactions=True):
# setting ACTIVE status sinse healthmon is shared DB object
monitor_db = HealthMonitor(id=uuidutils.generate_uuid(), monitor_db = HealthMonitor(id=uuidutils.generate_uuid(),
tenant_id=tenant_id, tenant_id=tenant_id,
type=v['type'], type=v['type'],
@ -684,7 +693,7 @@ class LoadBalancerPluginDb(LoadBalancerPluginBase,
url_path=v['url_path'], url_path=v['url_path'],
expected_codes=v['expected_codes'], expected_codes=v['expected_codes'],
admin_state_up=v['admin_state_up'], admin_state_up=v['admin_state_up'],
status=constants.PENDING_CREATE) status=constants.ACTIVE)
context.session.add(monitor_db) context.session.add(monitor_db)
return self._make_health_monitor_dict(monitor_db) return self._make_health_monitor_dict(monitor_db)

View File

@ -0,0 +1,63 @@
# 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.
#
"""Pool Monitor status field
Revision ID: 11c6e18605c8
Revises: 39cf3f799352
Create Date: 2013-07-10 06:07:20.878520
"""
# revision identifiers, used by Alembic.
revision = '11c6e18605c8'
down_revision = '39cf3f799352'
# 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
# Change to ['*'] if this migration applies to all plugins
migration_for_plugins = ['*']
def upgrade(active_plugin=None, options=None):
if not migration.should_run(active_plugin, migration_for_plugins):
return
op.add_column('poolmonitorassociations', sa.Column('status',
sa.String(16),
nullable=False))
op.add_column('poolmonitorassociations', sa.Column('status_description',
sa.String(255)))
# Set status to ACTIVE for existing associations
op.execute("UPDATE poolmonitorassociations SET status='ACTIVE'")
def downgrade(active_plugin=None, options=None):
if not migration.should_run(active_plugin, migration_for_plugins):
return
op.drop_column('poolmonitorassociations', 'status')
op.drop_column('poolmonitorassociations', 'status_description')

View File

@ -49,6 +49,11 @@ class HealthMonitorNotFound(qexception.NotFound):
message = _("Health_monitor %(monitor_id)s could not be found") message = _("Health_monitor %(monitor_id)s could not be found")
class PoolMonitorAssociationNotFound(qexception.NotFound):
message = _("Monitor %(monitor_id)s is not associated "
"with Pool %(pool_id)s")
class StateInvalid(qexception.NeutronException): class StateInvalid(qexception.NeutronException):
message = _("Invalid state %(state)s of Loadbalancer resource %(id)s") message = _("Invalid state %(state)s of Loadbalancer resource %(id)s")

View File

@ -131,6 +131,12 @@ class LoadBalancerAbstractDriver(object):
def create_pool_health_monitor(self, context, def create_pool_health_monitor(self, context,
health_monitor, health_monitor,
pool_id): pool_id):
"""Driver may call the code below in order to update the status.
self.plugin.update_pool_health_monitor(context,
health_monitor["id"],
pool_id,
constants.ACTIVE)
"""
pass pass
@abc.abstractmethod @abc.abstractmethod

View File

@ -110,8 +110,8 @@ class LoadBalancerCallbacks(object):
m.status = constants.ACTIVE m.status = constants.ACTIVE
for hm in pool.monitors: for hm in pool.monitors:
if hm.healthmonitor.status in ACTIVE_PENDING: if hm.status in ACTIVE_PENDING:
hm.healthmonitor.status = constants.ACTIVE hm.status = constants.ACTIVE
if (pool.status != constants.ACTIVE if (pool.status != constants.ACTIVE
or pool.vip.status != constants.ACTIVE): or pool.vip.status != constants.ACTIVE):
@ -137,7 +137,7 @@ class LoadBalancerCallbacks(object):
retval['healthmonitors'] = [ retval['healthmonitors'] = [
self.plugin._make_health_monitor_dict(hm.healthmonitor) self.plugin._make_health_monitor_dict(hm.healthmonitor)
for hm in pool.monitors for hm in pool.monitors
if hm.healthmonitor.status == constants.ACTIVE if hm.status == constants.ACTIVE
] ]
return retval return retval

View File

@ -206,14 +206,13 @@ class LoadBalancerPlugin(loadbalancer_db.LoadBalancerPluginDb,
health_monitor, health_monitor,
pool_id pool_id
) )
# open issue: PoolMonitorAssociation has no status field
# so we cant set the status to pending and let the driver
# set the real status of the association
self.driver.create_pool_health_monitor( self.driver.create_pool_health_monitor(
context, health_monitor, pool_id) context, health_monitor, pool_id)
return retval return retval
def delete_pool_health_monitor(self, context, id, pool_id): def delete_pool_health_monitor(self, context, id, pool_id):
self.update_pool_health_monitor(context, id, pool_id,
constants.PENDING_DELETE)
hm = self.get_health_monitor(context, id) hm = self.get_health_monitor(context, id)
self.driver.delete_pool_health_monitor( self.driver.delete_pool_health_monitor(
context, hm, pool_id) context, hm, pool_id)

View File

@ -832,7 +832,7 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
('timeout', 10), ('timeout', 10),
('max_retries', 3), ('max_retries', 3),
('admin_state_up', True), ('admin_state_up', True),
('status', 'PENDING_CREATE')] ('status', 'ACTIVE')]
with self.health_monitor() as monitor: with self.health_monitor() as monitor:
for k, v in keys: for k, v in keys:
self.assertEqual(monitor['health_monitor'][k], v) self.assertEqual(monitor['health_monitor'][k], v)
@ -916,7 +916,7 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
('timeout', 10), ('timeout', 10),
('max_retries', 3), ('max_retries', 3),
('admin_state_up', True), ('admin_state_up', True),
('status', 'PENDING_CREATE')] ('status', 'ACTIVE')]
req = self.new_show_request('health_monitors', req = self.new_show_request('health_monitors',
monitor['health_monitor']['id'], monitor['health_monitor']['id'],
fmt=self.fmt) fmt=self.fmt)
@ -1225,6 +1225,35 @@ class TestLoadBalancer(LoadBalancerPluginDbTestCase):
self.assertEqual(updated_pool['status'], 'ACTIVE') self.assertEqual(updated_pool['status'], 'ACTIVE')
self.assertFalse(pool['pool']['status_description']) self.assertFalse(pool['pool']['status_description'])
def test_update_pool_health_monitor(self):
with self.pool() as pool:
with self.health_monitor() as hm:
res = self.plugin.create_pool_health_monitor(
context.get_admin_context(),
hm, pool['pool']['id'])
self.assertEqual({'health_monitor':
[hm['health_monitor']['id']]},
res)
assoc = self.plugin.get_pool_health_monitor(
context.get_admin_context(),
hm['health_monitor']['id'],
pool['pool']['id'])
self.assertEqual(assoc['status'], 'PENDING_CREATE')
self.assertIsNone(assoc['status_description'])
self.plugin.update_pool_health_monitor(
context.get_admin_context(),
hm['health_monitor']['id'],
pool['pool']['id'],
'ACTIVE', 'ok')
assoc = self.plugin.get_pool_health_monitor(
context.get_admin_context(),
hm['health_monitor']['id'],
pool['pool']['id'])
self.assertEqual(assoc['status'], 'ACTIVE')
self.assertEqual(assoc['status_description'], 'ok')
class TestLoadBalancerXML(TestLoadBalancer): class TestLoadBalancerXML(TestLoadBalancer):
fmt = 'xml' fmt = 'xml'