Add healthmonitor support in openstack lbaas driver

This patch adds healthmonitor support in openstack lbaas driver.

Change-Id: If619ea526bb3c3bbf57767d34656a976203c387e
This commit is contained in:
yanyanhu 2016-02-25 21:26:49 -05:00
parent 5d32fc300a
commit 0f0ca57e22
2 changed files with 98 additions and 12 deletions

View File

@ -27,7 +27,7 @@ LOG = logging.getLogger(__name__)
class LoadBalancerDriver(base.DriverBase):
"""Load-balancing driver based on Neutron LBaaS service."""
"""Load-balancing driver based on Neutron LBaaS V2 service."""
def __init__(self, params):
super(LoadBalancerDriver, self).__init__(params)
@ -80,11 +80,12 @@ class LoadBalancerDriver(base.DriverBase):
return False
def lb_create(self, vip, pool):
def lb_create(self, vip, pool, hm):
"""Create a LBaaS instance
:param vip: A dict containing the properties for the VIP;
:param pool: A dict describing the pool of load-balancer members.
:param pool: A dict describing the health monitor.
"""
def _cleanup(msg, **kwargs):
LOG.error(msg)
@ -161,6 +162,28 @@ class LoadBalancerDriver(base.DriverBase):
_cleanup(msg, **result)
return res, msg
# Create health monitor
try:
health_monitor = self.nc().healthmonitor_create(
hm['type'], hm['delay'], hm['timeout'], hm['max_retries'],
pool.id, hm['admin_state_up'], hm['http_method'],
hm['url_path'], hm['expected_codes'])
except exception.InternalError as ex:
msg = _LE('Failed in creating lb health monitor: %s.'
) % six.text_type(ex)
LOG.exception(msg)
EVENT.warning(oslo_context.get_current(), self,
'HEALTH_MONITOR_CREATE',
'ERROR', msg)
return False, msg
result['healthmonitor'] = health_monitor.id
res = self._wait_for_lb_ready(lb.id)
if res is False:
msg = _LE('Failed in creating health monitor (%s).'
) % health_monitor.id
_cleanup(msg, **result)
return res, msg
return True, result
def lb_delete(self, **kwargs):

View File

@ -47,6 +47,17 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
'protocol': 'HTTP',
'admin_state_up': True
}
self.hm = {
"type": "HTTP",
"delay": "1",
"timeout": 1,
"max_retries": 5,
"pool_id": "POOL_ID",
"admin_state_up": True,
"http_method": "GET",
"url_path": "/index.html",
"expected_codes": "200,201,202"
}
def test_init(self):
res = lbaas.LoadBalancerDriver(self.conn_params)
@ -109,6 +120,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
lb_obj = mock.Mock()
listener_obj = mock.Mock()
pool_obj = mock.Mock()
hm_obj = mock.Mock()
lb_obj.id = 'LB_ID'
listener_obj.id = 'LISTENER_ID'
pool_obj.id = 'POOL_ID'
@ -116,15 +128,17 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
subnet_obj.name = 'subnet1'
subnet_obj.id = 'SUBNET_ID'
subnet_obj.network_id = 'NETWORK_ID'
hm_obj.id = 'HEALTHMONITOR_ID'
self.nc.loadbalancer_create.return_value = lb_obj
self.nc.listener_create.return_value = listener_obj
self.nc.pool_create.return_value = pool_obj
self.nc.healthmonitor_create.return_value = hm_obj
self.nc.subnet_get.return_value = subnet_obj
self.lb_driver._wait_for_lb_ready = mock.Mock()
self.lb_driver._wait_for_lb_ready.return_value = True
status, res = self.lb_driver.lb_create(self.vip, self.pool)
status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm)
self.assertTrue(status)
self.nc.loadbalancer_create.assert_called_once_with(
@ -138,9 +152,14 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.pool['lb_method'], 'LISTENER_ID', self.pool['protocol'],
self.pool['admin_state_up'])
self.assertEqual('POOL_ID', res['pool'])
self.nc.healthmonitor_create.assert_called_once_with(
self.hm['type'], self.hm['delay'], self.hm['timeout'],
self.hm['max_retries'], 'POOL_ID', self.hm['admin_state_up'],
self.hm['http_method'], self.hm['url_path'],
self.hm['expected_codes'])
self.assertEqual('HEALTHMONITOR_ID', res['healthmonitor'])
self.lb_driver._wait_for_lb_ready.assert_called_with('LB_ID')
calls = [mock.call('LB_ID'), mock.call('LB_ID'),
mock.call('LB_ID')]
calls = [mock.call('LB_ID') for i in range(1, 5)]
self.lb_driver._wait_for_lb_ready.assert_has_calls(
calls, any_order=False)
@ -159,7 +178,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.lb_driver._wait_for_lb_ready.side_effect = [False]
self.lb_driver.lb_delete = mock.Mock()
status, res = self.lb_driver.lb_create(self.vip, self.pool)
status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm)
self.assertFalse(status)
msg = _('Failed in creating load balancer (%s).') % 'LB_ID'
self.assertEqual(msg, res)
@ -172,7 +191,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
# Exception happens in subnet_get.
self.nc.subnet_get.side_effect = exception.InternalError(
code=500, message='GET FAILED')
status, res = self.lb_driver.lb_create(self.vip, self.pool)
status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm)
self.assertFalse(status)
msg = _('Failed in getting subnet: GET FAILED.')
self.assertEqual(msg, res)
@ -181,7 +200,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.nc.subnet_get.side_effect = None
self.nc.loadbalancer_create.side_effect = exception.InternalError(
code=500, message='CREATE FAILED')
status, res = self.lb_driver.lb_create(self.vip, self.pool)
status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm)
self.assertFalse(status)
msg = _('Failed in creating loadbalancer: CREATE FAILED.')
self.assertEqual(msg, res)
@ -206,7 +225,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.nc.subnet_get.return_value = subnet_obj
self.lb_driver.lb_delete = mock.Mock()
status, res = self.lb_driver.lb_create(self.vip, self.pool)
status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm)
self.assertFalse(status)
msg = _('Failed in creating listener (%s).') % 'LISTENER_ID'
self.assertEqual(msg, res)
@ -224,7 +243,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.lb_driver._wait_for_lb_ready.side_effect = [True, False]
self.nc.listener_create.side_effect = exception.InternalError(
code=500, message='CREATE FAILED')
status, res = self.lb_driver.lb_create(self.vip, self.pool)
status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm)
self.assertFalse(status)
msg = _('Failed in creating lb listener: CREATE FAILED.')
self.assertEqual(msg, res)
@ -251,7 +270,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.nc.subnet_get.return_value = subnet_obj
self.lb_driver.lb_delete = mock.Mock()
status, res = self.lb_driver.lb_create(self.vip, self.pool)
status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm)
self.assertFalse(status)
msg = _('Failed in creating pool (%s).') % 'POOL_ID'
self.assertEqual(msg, res)
@ -272,12 +291,56 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
self.lb_driver._wait_for_lb_ready.side_effect = [True, True, False]
self.nc.pool_create.side_effect = exception.InternalError(
code=500, message='CREATE FAILED')
status, res = self.lb_driver.lb_create(self.vip, self.pool)
status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm)
self.assertFalse(status)
msg = _('Failed in creating lb pool: CREATE FAILED.')
self.assertEqual(msg, res)
self.assertTrue(mock_event.called)
@mock.patch.object(EVENT, 'warning')
def test_lb_create_healthmonitor_creation_failed(self, mock_event):
lb_obj = mock.Mock()
listener_obj = mock.Mock()
pool_obj = mock.Mock()
hm_obj = mock.Mock()
lb_obj.id = 'LB_ID'
listener_obj.id = 'LISTENER_ID'
pool_obj.id = 'POOL_ID'
subnet_obj = mock.Mock()
subnet_obj.name = 'subnet1'
subnet_obj.id = 'SUBNET_ID'
subnet_obj.network_id = 'NETWORK_ID'
hm_obj.id = 'HEALTHMONITOR_ID'
self.lb_driver._wait_for_lb_ready = mock.Mock()
self.lb_driver._wait_for_lb_ready.side_effect = [True, True,
True, False]
self.nc.loadbalancer_create.return_value = lb_obj
self.nc.listener_create.return_value = listener_obj
self.nc.pool_create.return_value = pool_obj
self.nc.healthmonitor_create.return_value = hm_obj
self.nc.subnet_get.return_value = subnet_obj
self.lb_driver.lb_delete = mock.Mock()
status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm)
self.assertFalse(status)
msg = _('Failed in creating health monitor (%s).') % 'HEALTHMONITOR_ID'
self.assertEqual(msg, res)
self.lb_driver.lb_delete.assert_called_once_with(
loadbalancer='LB_ID', listener='LISTENER_ID', pool='POOL_ID',
healthmonitor='HEALTHMONITOR_ID')
# Exception happens in healthmonitor_create
self.lb_driver._wait_for_lb_ready = mock.Mock()
self.lb_driver._wait_for_lb_ready.side_effect = [True, True, True]
self.nc.healthmonitor_create.side_effect = exception.InternalError(
code=500, message='CREATE FAILED')
status, res = self.lb_driver.lb_create(self.vip, self.pool, self.hm)
self.assertFalse(status)
msg = _('Failed in creating lb health monitor: CREATE FAILED.')
self.assertEqual(msg, res)
self.assertTrue(mock_event.called)
def test_lb_delete(self):
kwargs = {
'loadbalancer': 'LB_ID',