Merge "Add healthmonitor support for lb_policy"

This commit is contained in:
Jenkins 2016-03-03 05:38:44 +00:00 committed by Gerrit Code Review
commit 3f7e156052
5 changed files with 131 additions and 4 deletions

View File

@ -39,3 +39,29 @@ properties:
# TCP port to listen on
protocol_port: 80
health_monitor:
# The type of probe sent by the load balancer to verify the member state,
# can be PING, TCP, HTTP, or HTTPS.
type: 'PING'
# The amount of time, in seconds, between sending probes to members.
delay: 10
# The maximum time in seconds that a monitor waits to connect before it
# times out. This value must be less than the delay value.
timeout: 5
# The number of allowed connection failures before changing the status
# of the member to INACTIVE. A valid value is from 1 to 10.
max_retries: 4
# The HTTP method that the monitor uses for requests.
http_method: 'GET'
# The HTTP path of the request sent by the monitor to test the health of
# a member. A string value that must begin with the forward slash '/'.
url_path: '/index.html'
# Expected HTTP codes for a passing HTTP(S) monitor.
expected_codes: '200, 202'

View File

@ -154,6 +154,9 @@ class LoadBalancerDriver(base.DriverBase):
if not hm:
return True, result
if not hm:
return True, result
# Create health monitor
try:
health_monitor = self.nc().healthmonitor_create(

View File

@ -53,9 +53,9 @@ class LoadBalancingPolicy(base.Policy):
]
KEYS = (
POOL, VIP,
POOL, VIP, HEALTH_MONITOR,
) = (
'pool', 'vip',
'pool', 'vip', 'health_monitor',
)
_POOL_KEYS = (
@ -78,6 +78,18 @@ class LoadBalancingPolicy(base.Policy):
'ROUND_ROBIN', 'LEAST_CONNECTIONS', 'SOURCE_IP',
)
HEALTH_MONITOR_TYPES = (
PING, TCP, HTTP, HTTPS,
) = (
'PING', 'TCP', 'HTTP', 'HTTPS',
)
HTTP_METHODS = (
GET, POST, PUT, DELETE,
) = (
'GET', 'POST', 'PUT', 'DELETE',
)
_VIP_KEYS = (
VIP_SUBNET, VIP_ADDRESS, VIP_CONNECTION_LIMIT, VIP_PROTOCOL,
VIP_PROTOCOL_PORT, VIP_ADMIN_STATE_UP,
@ -86,6 +98,14 @@ class LoadBalancingPolicy(base.Policy):
'protocol_port', 'admin_state_up',
)
HEALTH_MONITOR_KEYS = (
HM_TYPE, HM_DELAY, HM_TIMEOUT, HM_MAX_RETRIES, HM_ADMIN_STATE_UP,
HM_HTTP_METHOD, HM_URL_PATH, HM_EXPECTED_CODES,
) = (
'type', 'delay', 'timeout', 'max_retries', 'admin_state_up',
'http_method', 'url_path', 'expected_codes',
)
_SESSION_PERSISTENCE_KEYS = (
PERSISTENCE_TYPE, COOKIE_NAME,
) = (
@ -180,6 +200,51 @@ class LoadBalancingPolicy(base.Policy):
),
},
),
HEALTH_MONITOR: schema.Map(
_('Health monitor for loadbalancer.'),
schema={
HM_TYPE: schema.String(
_('The type of probe sent by the load balancer to verify '
'the member state.'),
constraints=[
constraints.AllowedValues(HEALTH_MONITOR_TYPES),
],
default=PING,
),
HM_DELAY: schema.Integer(
_('The amount of time in seconds between sending '
'probes to members.'),
default=10,
),
HM_TIMEOUT: schema.Integer(
_('The maximum time in seconds that a monitor waits to '
'connect before it times out.'),
default=5,
),
HM_MAX_RETRIES: schema.Integer(
_('The number of allowed connection failures before '
'changing the status of the member to INACTIVE.'),
default=3,
),
HM_ADMIN_STATE_UP: schema.Boolean(
_('Administrative state of the health monitor.'),
default=True,
),
HM_HTTP_METHOD: schema.String(
_('The HTTP method that the monitor uses for requests.'),
constraints=[
constraints.AllowedValues(HTTP_METHODS),
],
),
HM_URL_PATH: schema.String(
_('The HTTP path of the request sent by the monitor to '
'test the health of a member.'),
),
HM_EXPECTED_CODES: schema.String(
_('Expected HTTP codes for a passing HTTP(S) monitor.'),
),
},
),
}
def __init__(self, name, spec, **kwargs):
@ -187,6 +252,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.validate()
self.lb = None
@ -213,7 +279,8 @@ class LoadBalancingPolicy(base.Policy):
params = self._build_conn_params(cluster)
lb_driver = driver_base.SenlinDriver().loadbalancing(params)
res, data = lb_driver.lb_create(self.vip_spec, self.pool_spec)
res, data = lb_driver.lb_create(self.vip_spec, self.pool_spec,
self.hm_spec)
if res is False:
return False, data

View File

@ -63,6 +63,16 @@ spec_lb_policy = {
"connection_limit": 100,
"protocol": "HTTP",
"protocol_port": 80
},
"health_monitor": {
"type": "HTTP",
"delay": "1",
"timeout": 1,
"max_retries": 5,
"admin_state_up": True,
"http_method": "GET",
"url_path": "/index.html",
"expected_codes": "200,201,202"
}
}
}

View File

@ -52,6 +52,16 @@ class TestLoadBalancingPolicy(base.SenlinTestCase):
'protocol': 'HTTP',
'protocol_port': 80,
'admin_state_up': True,
},
'health_monitor': {
'type': 'HTTP',
'delay': 10,
'timeout': 5,
'max_retries': 3,
'admin_state_up': True,
'http_method': 'GET',
'url_path': '/index.html',
'expected_codes': '200,201,202'
}
}
}
@ -145,7 +155,8 @@ class TestLoadBalancingPolicy(base.SenlinTestCase):
self.assertTrue(res)
self.assertEqual('policy_data', data)
self.lb_driver.lb_create.assert_called_once_with(policy.vip_spec,
policy.pool_spec)
policy.pool_spec,
policy.hm_spec)
m_load.assert_called_once_with(mock.ANY, cluster_id=cluster.id)
member_add_calls = [
mock.call(node1, 'LB_ID', 'POOL_ID', 80, 'test-subnet'),
@ -343,6 +354,16 @@ class TestLoadBalancingPolicyOperations(base.SenlinTestCase):
'protocol': 'HTTP',
'protocol_port': 80,
'admin_state_up': True,
},
'health_monitor': {
'type': 'HTTP',
'delay': '1',
'timeout': 1,
'max_retries': 5,
'admin_state_up': True,
'http_method': 'GET',
'url_path': '/index.html',
'expected_codes': '200,201,202'
}
}
}