Make lb timeout configurable

This patch adds a new property 'lb_status_timeout' for lb policy.
User can use this property to configure the timeout value that
senlin waits for loadbalancer to be ready before or after requests
to lbaas V2 service for lb operations.

Change-Id: If1a46748ee8ccd0159e0c517e9d4eb5d2d17349d
This commit is contained in:
yanyanhu 2016-07-27 01:40:21 -04:00
parent e5a9c8065d
commit de233ffdb8
7 changed files with 48 additions and 20 deletions

View File

@ -1,6 +1,6 @@
# Load-balancing policy spec using Neutron LBaaS service
type: senlin.policy.loadbalance
version: 1.0
version: 1.1
description: A policy for load-balancing the nodes in a cluster.
properties:
pool:
@ -65,3 +65,7 @@ properties:
# Expected HTTP codes for a passing HTTP(S) monitor.
expected_codes: '200, 202'
# Time in second to wait for loadbalancer to become ready before and after
# senlin requests lbaas V2 service for lb operations.
lb_status_timeout: 300

View File

@ -29,6 +29,7 @@ class LoadBalancerDriver(base.DriverBase):
"""Load-balancing driver based on Neutron LBaaS V2 service."""
def __init__(self, params):
self.lb_status_timeout = params.pop('lb_status_timeout')
super(LoadBalancerDriver, self).__init__(params)
self._nc = None
@ -39,7 +40,7 @@ class LoadBalancerDriver(base.DriverBase):
self._nc = neutronclient.NeutronClient(self.conn_params)
return self._nc
def _wait_for_lb_ready(self, lb_id, timeout=600, ignore_not_found=False):
def _wait_for_lb_ready(self, lb_id, ignore_not_found=False):
"""Keep waiting until loadbalancer is ready
This method will keep waiting until loadbalancer resource specified
@ -47,12 +48,11 @@ class LoadBalancerDriver(base.DriverBase):
its operating_status is ONLINE.
:param lb_id: ID of the load-balancer to check.
:param timeout: timeout in seconds.
:param ignore_not_found: if set to True, nonexistent loadbalancer
resource is also an acceptable result.
"""
waited = 0
while waited < timeout:
while waited < self.lb_status_timeout:
try:
lb = self.nc().loadbalancer_get(lb_id)
except exception.InternalError as ex:
@ -82,7 +82,7 @@ class LoadBalancerDriver(base.DriverBase):
: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.
:param hm: A dict describing the health monitor.
"""
def _cleanup(msg, **kwargs):
LOG.error(msg)

View File

@ -45,7 +45,7 @@ class LoadBalancingPolicy(base.Policy):
the cluster (which could be created by the policy) when these actions are
performed.
"""
VERSION = '1.0'
VERSION = '1.1'
PRIORITY = 500
@ -65,9 +65,9 @@ class LoadBalancingPolicy(base.Policy):
]
KEYS = (
POOL, VIP, HEALTH_MONITOR,
POOL, VIP, HEALTH_MONITOR, LB_STATUS_TIMEOUT
) = (
'pool', 'vip', 'health_monitor',
'pool', 'vip', 'health_monitor', 'lb_status_timeout'
)
_POOL_KEYS = (
@ -257,6 +257,13 @@ class LoadBalancingPolicy(base.Policy):
),
},
),
LB_STATUS_TIMEOUT: schema.Integer(
_('Time in second to wait for loadbalancer to be ready'
'(provisioning_status is ACTIVE and operating_status is '
'ONLINE) before and after senlin requests lbaas V2 service '
'for lb operations. '),
default=600,
)
}
def __init__(self, name, spec, **kwargs):
@ -265,6 +272,7 @@ class LoadBalancingPolicy(base.Policy):
self.pool_spec = self.properties.get(self.POOL, {})
self.vip_spec = self.properties.get(self.VIP, {})
self.hm_spec = self.properties.get(self.HEALTH_MONITOR, None)
self.lb_status_timeout = self.properties.get(self.LB_STATUS_TIMEOUT)
self.validate()
self.lb = None
@ -289,6 +297,7 @@ class LoadBalancingPolicy(base.Policy):
cluster_id=cluster.id)
params = self._build_conn_params(cluster)
params['lb_status_timeout'] = self.lb_status_timeout
lb_driver = driver_base.SenlinDriver().loadbalancing(params)
res, data = lb_driver.lb_create(self.vip_spec, self.pool_spec,
@ -332,6 +341,7 @@ class LoadBalancingPolicy(base.Policy):
"""
reason = _('LB resources deletion succeeded.')
params = self._build_conn_params(cluster)
params['lb_status_timeout'] = self.lb_status_timeout
lb_driver = driver_base.SenlinDriver().loadbalancing(params)
cp = cluster_policy.ClusterPolicy.load(oslo_context.get_current(),
@ -424,6 +434,7 @@ class LoadBalancingPolicy(base.Policy):
db_cluster = co.Cluster.get(action.context, cluster_id)
params = self._build_conn_params(db_cluster)
params['lb_status_timeout'] = self.lb_status_timeout
lb_driver = driver_base.SenlinDriver().loadbalancing(params)
cp = cluster_policy.ClusterPolicy.load(action.context, cluster_id,
self.id)
@ -473,6 +484,7 @@ class LoadBalancingPolicy(base.Policy):
db_cluster = co.Cluster.get(action.context, cluster_id)
params = self._build_conn_params(db_cluster)
params['lb_status_timeout'] = self.lb_status_timeout
lb_driver = driver_base.SenlinDriver().loadbalancing(params)
cp = cluster_policy.ClusterPolicy.load(action.context, cluster_id,
self.id)

View File

@ -31,7 +31,7 @@ class LoadBalancerDriver(base.DriverBase):
def lb_delete(self, **kwargs):
return True, 'LB deletion succeeded'
def member_add(self, node, lb_id, pool_id, port, subnet):
def member_add(self, node, lb_id, pool_id, port, subneat):
return self.member_id
def member_remove(self, lb_id, pool_id, member_id):

View File

@ -99,6 +99,7 @@ spec_lb_policy = {
"http_method": "GET",
"url_path": "/index.html",
"expected_codes": "200,201,202"
}
},
"lb_status_timeout": 300
}
}

View File

@ -29,6 +29,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
super(TestNeutronLBaaSDriver, self).setUp()
self.context = utils.dummy_context()
self.conn_params = self.context.to_dict()
self.conn_params['lb_status_timeout'] = 10
self.lb_driver = lbaas.LoadBalancerDriver(self.conn_params)
self.patchobject(neutron_v2, 'NeutronClient')
self.nc = self.lb_driver.nc()
@ -59,27 +60,33 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
}
def test_init(self):
res = lbaas.LoadBalancerDriver(self.conn_params)
self.assertEqual(self.conn_params, res.conn_params)
conn_params = self.context.to_dict()
conn_params['lb_status_timeout'] = 10
res = lbaas.LoadBalancerDriver(conn_params)
self.assertEqual(conn_params, res.conn_params)
self.assertIsNone(res._nc)
@mock.patch.object(neutron_v2, 'NeutronClient')
def test_nc_initialize(self, mock_neutron_client):
conn_params = self.context.to_dict()
conn_params['lb_status_timeout'] = 10
fake_nc = mock.Mock()
mock_neutron_client.return_value = fake_nc
lb_driver = lbaas.LoadBalancerDriver(self.conn_params)
lb_driver = lbaas.LoadBalancerDriver(conn_params)
self.assertIsNone(lb_driver._nc)
# Create a new NeutronClient
res = lb_driver.nc()
mock_neutron_client.assert_called_once_with(self.conn_params)
mock_neutron_client.assert_called_once_with(conn_params)
self.assertEqual(fake_nc, res)
# Use the existing NeutronClient stored in self._nc
fake_nc_new = mock.Mock()
mock_neutron_client.return_value = fake_nc_new
res1 = lb_driver.nc()
mock_neutron_client.assert_called_once_with(self.conn_params)
mock_neutron_client.assert_called_once_with(conn_params)
self.assertNotEqual(fake_nc_new, res1)
self.assertEqual(res, res1)
@ -91,14 +98,14 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
lb_obj.operating_status = 'ONLINE'
self.nc.loadbalancer_get.return_value = lb_obj
res = self.lb_driver._wait_for_lb_ready(lb_id, timeout=4)
res = self.lb_driver._wait_for_lb_ready(lb_id)
self.assertTrue(res)
def test_wait_for_lb_ready_ignore_not_found(self):
lb_id = 'LB_ID'
self.nc.loadbalancer_get.return_value = None
res = self.lb_driver._wait_for_lb_ready(lb_id, timeout=4,
res = self.lb_driver._wait_for_lb_ready(lb_id,
ignore_not_found=True)
self.assertTrue(res)
@ -111,7 +118,7 @@ class TestNeutronLBaaSDriver(base.SenlinTestCase):
lb_obj.provisioning_status = 'PENDING_UPDATE'
lb_obj.operating_status = 'OFFLINE'
res = self.lb_driver._wait_for_lb_ready(lb_id, timeout=2)
res = self.lb_driver._wait_for_lb_ready(lb_id)
self.assertFalse(res)
mock_sleep.assert_called_once_with(10)

View File

@ -63,7 +63,8 @@ class TestLoadBalancingPolicy(base.SenlinTestCase):
'http_method': 'GET',
'url_path': '/index.html',
'expected_codes': '200,201,202'
}
},
'lb_status_timeout': 600
}
}
sd = mock.Mock()
@ -111,7 +112,8 @@ class TestLoadBalancingPolicy(base.SenlinTestCase):
'protocol': 'HTTP',
'protocol_port': 80,
'admin_state_up': True,
}
},
'lb_status_timeout': 600
}
}
@ -122,6 +124,8 @@ class TestLoadBalancingPolicy(base.SenlinTestCase):
self.assertEqual('senlin.policy.loadbalance-1.0', policy.type)
self.assertEqual(default_spec['properties']['pool'], policy.pool_spec)
self.assertEqual(default_spec['properties']['vip'], policy.vip_spec)
self.assertEqual(default_spec['properties']['lb_status_timeout'],
policy.lb_status_timeout)
self.assertIsNone(policy.lb)
@mock.patch.object(policy_base.Policy, 'validate')