Add healthmonitor support in openstack lbaas driver
This patch adds healthmonitor support in openstack lbaas driver. Change-Id: If619ea526bb3c3bbf57767d34656a976203c387e
This commit is contained in:
parent
5d32fc300a
commit
0f0ca57e22
|
@ -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):
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue