[API] Completed TCP Timeout work
Change-Id: Ie512dc5758609d0d0601f448984846b124647e24
This commit is contained in:
parent
6aabea4b51
commit
f50921e25e
|
@ -32,7 +32,7 @@ from libra.common.api.lbaas import loadbalancers_devices, Limits, Vip, Ports
|
|||
from libra.common.api.lbaas import HealthMonitor
|
||||
from libra.common.exc import ExhaustedError
|
||||
from libra.api.model.validators import LBPut, LBPost, LBResp, LBVipResp
|
||||
from libra.api.model.validators import LBRespNode
|
||||
from libra.api.model.validators import LBRespNode, LBOptions
|
||||
from libra.common.api.gearman_client import submit_job
|
||||
from libra.api.acl import get_limited_to_project
|
||||
from libra.api.library.exp import OverLimit, IPOutOfRange, NotFound
|
||||
|
@ -44,6 +44,12 @@ from wsme import types as wtypes
|
|||
|
||||
|
||||
class LoadBalancersController(RestController):
|
||||
|
||||
LB_TIMEOUT_MS = 30000
|
||||
LB_TIMEOUT_MAX = 1000000
|
||||
LB_RETRIES = 3
|
||||
LB_RETRIES_MAX = 256
|
||||
|
||||
def __init__(self, lbid=None):
|
||||
self.lbid = lbid
|
||||
|
||||
|
@ -77,7 +83,8 @@ class LoadBalancersController(RestController):
|
|||
LoadBalancer.protocol,
|
||||
LoadBalancer.port, LoadBalancer.algorithm,
|
||||
LoadBalancer.status, LoadBalancer.created,
|
||||
LoadBalancer.updated
|
||||
LoadBalancer.updated, LoadBalancer.timeout,
|
||||
LoadBalancer.retries
|
||||
).filter(LoadBalancer.tenantid == tenant_id).\
|
||||
filter(LoadBalancer.status == 'DELETED').all()
|
||||
else:
|
||||
|
@ -86,7 +93,8 @@ class LoadBalancersController(RestController):
|
|||
LoadBalancer.protocol,
|
||||
LoadBalancer.port, LoadBalancer.algorithm,
|
||||
LoadBalancer.status, LoadBalancer.created,
|
||||
LoadBalancer.updated
|
||||
LoadBalancer.updated, LoadBalancer.timeout,
|
||||
LoadBalancer.retries
|
||||
).filter(LoadBalancer.tenantid == tenant_id).\
|
||||
filter(LoadBalancer.status != 'DELETED').all()
|
||||
load_balancers = {'loadBalancers': []}
|
||||
|
@ -96,6 +104,20 @@ class LoadBalancersController(RestController):
|
|||
lb['nodeCount'] = session.query(Node).\
|
||||
filter(Node.lbid == lb['id']).count()
|
||||
lb['id'] = str(lb['id'])
|
||||
|
||||
# Unset options get set to default values
|
||||
lb['options'] = {}
|
||||
if lb['timeout']:
|
||||
lb['options']['timeout'] = lb['timeout']
|
||||
else:
|
||||
lb['options']['timeout'] = self.LB_TIMEOUT_MS
|
||||
if lb['retries']:
|
||||
lb['options']['retries'] = lb['retries']
|
||||
else:
|
||||
lb['options']['retries'] = self.LB_RETRIES
|
||||
del(lb['timeout'])
|
||||
del(lb['retries'])
|
||||
|
||||
load_balancers['loadBalancers'].append(lb)
|
||||
else:
|
||||
load_balancers = session.query(
|
||||
|
@ -103,6 +125,7 @@ class LoadBalancersController(RestController):
|
|||
LoadBalancer.port, LoadBalancer.algorithm,
|
||||
LoadBalancer.status, LoadBalancer.created,
|
||||
LoadBalancer.updated, LoadBalancer.errmsg,
|
||||
LoadBalancer.timeout, LoadBalancer.retries,
|
||||
Vip.id.label('vipid'), Vip.ip
|
||||
).join(LoadBalancer.devices).\
|
||||
outerjoin(Device.vip).\
|
||||
|
@ -168,6 +191,21 @@ class LoadBalancersController(RestController):
|
|||
del node['weight']
|
||||
load_balancers['nodes'].append(node)
|
||||
|
||||
# Unset options get set to default values
|
||||
load_balancers['options'] = {}
|
||||
if load_balancers['timeout']:
|
||||
load_balancers['options']['timeout'] =\
|
||||
load_balancers['timeout']
|
||||
else:
|
||||
load_balancers['options']['timeout'] = self.LB_TIMEOUT_MS
|
||||
if load_balancers['retries']:
|
||||
load_balancers['options']['retries'] =\
|
||||
load_balancers['retries']
|
||||
else:
|
||||
load_balancers['options']['retries'] = self.LB_RETRIES
|
||||
del(load_balancers['timeout'])
|
||||
del(load_balancers['retries'])
|
||||
|
||||
session.rollback()
|
||||
response.status = 200
|
||||
return load_balancers
|
||||
|
@ -252,19 +290,33 @@ class LoadBalancersController(RestController):
|
|||
num_galera_primary_nodes += 1
|
||||
|
||||
# Options defaults
|
||||
client_timeout_ms = 30000
|
||||
server_timeout_ms = 30000
|
||||
connect_timeout_ms = 30000
|
||||
connect_retries = 3
|
||||
timeout_ms = self.LB_TIMEOUT_MS
|
||||
retries = self.LB_RETRIES
|
||||
if body.options:
|
||||
if body.options.client_timeout != Unset:
|
||||
client_timeout_ms = body.options.client_timeout
|
||||
if body.options.server_timeout != Unset:
|
||||
server_timeout_ms = body.options.server_timeout
|
||||
if body.options.connect_timeout != Unset:
|
||||
connect_timeout_ms = body.options.connect_timeout
|
||||
if body.options.connect_retries != Unset:
|
||||
connect_retries = body.options.connect_retries
|
||||
if body.options.timeout != Unset:
|
||||
try:
|
||||
timeout_ms = int(body.options.timeout)
|
||||
if timeout_ms < 0 or timeout_ms > self.LB_TIMEOUT_MAX:
|
||||
raise ClientSideError(
|
||||
'timeout must be between 0 and {0} ms'
|
||||
.format(self.LB_TIMEOUT_MAX)
|
||||
)
|
||||
except ValueError:
|
||||
raise ClientSideError(
|
||||
'timeout must be an integer'
|
||||
)
|
||||
if body.options.retries != Unset:
|
||||
try:
|
||||
retries = int(body.options.retries)
|
||||
if retries < 0 or retries > self.LB_RETRIES_MAX:
|
||||
raise ClientSideError(
|
||||
'retries must be between 0 and {0}'
|
||||
.format(self.LB_RETRIES_MAX)
|
||||
)
|
||||
except ValueError:
|
||||
raise ClientSideError(
|
||||
'retries must be an integer'
|
||||
)
|
||||
|
||||
# Galera sanity checks
|
||||
if is_galera and num_galera_primary_nodes != 1:
|
||||
|
@ -431,10 +483,8 @@ class LoadBalancersController(RestController):
|
|||
else:
|
||||
lb.algorithm = 'ROUND_ROBIN'
|
||||
|
||||
lb.client_timeout = client_timeout_ms
|
||||
lb.server_timeout = server_timeout_ms
|
||||
lb.connect_timeout = connect_timeout_ms
|
||||
lb.connect_retries = connect_retries
|
||||
lb.timeout = timeout_ms
|
||||
lb.retries = retries
|
||||
|
||||
lb.devices = [device]
|
||||
# write to database
|
||||
|
@ -491,20 +541,42 @@ class LoadBalancersController(RestController):
|
|||
address=None, id=None, type='ASSIGNING', ipVersion='IPV4'
|
||||
)
|
||||
return_data.virtualIps = [vip_resp]
|
||||
|
||||
nodes = session.query(
|
||||
Node.id, Node.address, Node.port, Node.status,
|
||||
Node.enabled, Node.weight
|
||||
).join(LoadBalancer.nodes).\
|
||||
filter(LoadBalancer.tenantid == tenant_id).\
|
||||
filter(LoadBalancer.id == lb.id).\
|
||||
all()
|
||||
|
||||
return_data.nodes = []
|
||||
for node in body.nodes:
|
||||
if node.weight != Unset and node.weight != 1:
|
||||
out_node = LBRespNode(
|
||||
port=str(node.port), address=node.address,
|
||||
condition=node.condition, weight=weight
|
||||
for node in nodes:
|
||||
if node.enabled == 1:
|
||||
condition = 'ENABLED'
|
||||
else:
|
||||
condition = 'DISABLED'
|
||||
|
||||
if node.weight == 1:
|
||||
return_data.nodes.append(
|
||||
LBRespNode(
|
||||
id=str(node.id), port=str(node.port),
|
||||
address=node.address, condition=condition,
|
||||
status=node.status
|
||||
)
|
||||
)
|
||||
else:
|
||||
out_node = LBRespNode(
|
||||
port=str(node.port), address=node.address,
|
||||
condition=node.condition
|
||||
return_data.nodes.append(
|
||||
LBRespNode(
|
||||
id=str(node.id), port=str(node.port),
|
||||
address=node.address, condition=condition,
|
||||
status=node.status, weight=str(node.weight)
|
||||
)
|
||||
)
|
||||
|
||||
return_data.nodes.append(out_node)
|
||||
return_data.options = LBOptions(timeout=timeout_ms,
|
||||
retries=retries)
|
||||
|
||||
session.commit()
|
||||
# trigger gearman client to create new lb
|
||||
submit_job(
|
||||
|
@ -551,6 +623,34 @@ class LoadBalancersController(RestController):
|
|||
if body.algorithm != Unset:
|
||||
lb.algorithm = body.algorithm
|
||||
|
||||
if body.options:
|
||||
if body.options.timeout != Unset:
|
||||
try:
|
||||
timeout_ms = int(body.options.timeout)
|
||||
if timeout_ms < 0 or timeout_ms > self.LB_TIMEOUT_MAX:
|
||||
raise ClientSideError(
|
||||
'timeout must be between 0 and {0} ms'
|
||||
.format(self.LB_TIMEOUT_MAX)
|
||||
)
|
||||
lb.timeout = timeout_ms
|
||||
except ValueError:
|
||||
raise ClientSideError(
|
||||
'timeout must be an integer'
|
||||
)
|
||||
if body.options.retries != Unset:
|
||||
try:
|
||||
retries = int(body.options.retries)
|
||||
if retries < 0 or retries > self.LB_RETRIES_MAX:
|
||||
raise ClientSideError(
|
||||
'retries must be between 0 and {0}'
|
||||
.format(self.LB_RETRIES_MAX)
|
||||
)
|
||||
lb.retries = retries
|
||||
except ValueError:
|
||||
raise ClientSideError(
|
||||
'retries must be an integer'
|
||||
)
|
||||
|
||||
lb.status = 'PENDING_UPDATE'
|
||||
device = session.query(
|
||||
Device.id, Device.name, Device.status
|
||||
|
|
|
@ -27,10 +27,12 @@ class LBNode(Base):
|
|||
|
||||
|
||||
class LBRespNode(Base):
|
||||
id = wtypes.text
|
||||
port = wtypes.text
|
||||
address = wtypes.text
|
||||
condition = wtypes.text
|
||||
weight = int
|
||||
status = wtypes.text
|
||||
weight = wtypes.text
|
||||
|
||||
|
||||
class LBNodePut(Base):
|
||||
|
@ -60,10 +62,8 @@ class LBVip(Base):
|
|||
|
||||
|
||||
class LBOptions(Base):
|
||||
client_timeout = int
|
||||
server_timeout = int
|
||||
connect_timeout = int
|
||||
connect_retries = int
|
||||
timeout = int
|
||||
retries = int
|
||||
|
||||
|
||||
class LBPost(Base):
|
||||
|
@ -79,6 +79,7 @@ class LBPost(Base):
|
|||
class LBPut(Base):
|
||||
name = wtypes.text
|
||||
algorithm = Enum(wtypes.text, 'ROUND_ROBIN', 'LEAST_CONNECTIONS')
|
||||
options = wsattr('LBOptions')
|
||||
|
||||
|
||||
class LBVipResp(Base):
|
||||
|
@ -106,6 +107,7 @@ class LBResp(Base):
|
|||
updated = wtypes.text
|
||||
virtualIps = wsattr(['LBVipResp'])
|
||||
nodes = wsattr(['LBRespNode'])
|
||||
options = wsattr('LBOptions')
|
||||
|
||||
|
||||
class LBMonitorPut(Base):
|
||||
|
|
|
@ -443,13 +443,12 @@ class GearmanClientThread(object):
|
|||
# All new LBs created since these options were supported
|
||||
# will have default values in the DB. Pre-existing LBs will
|
||||
# not have any values, so we need to check for that.
|
||||
if any([lb.client_timeout, lb.server_timeout,
|
||||
lb.connect_timeout, lb.connect_retries]):
|
||||
if any([lb.timeout, lb.retries]):
|
||||
lb_data['options'] = {
|
||||
'client_timeout': lb.client_timeout,
|
||||
'server_timeout': lb.server_timeout,
|
||||
'connect_timeout': lb.connect_timeout,
|
||||
'connect_retries': lb.connect_retries
|
||||
'client_timeout': lb.timeout,
|
||||
'server_timeout': lb.timeout,
|
||||
'connect_timeout': lb.timeout,
|
||||
'connect_retries': lb.retries
|
||||
}
|
||||
|
||||
lb_data['monitor'] = monitor_data
|
||||
|
|
|
@ -111,10 +111,8 @@ class LoadBalancer(DeclarativeBase):
|
|||
tenantid = Column(u'tenantid', VARCHAR(length=128), nullable=False)
|
||||
updated = Column(u'updated', FormatedDateTime(), nullable=False)
|
||||
created = Column(u'created', FormatedDateTime(), nullable=False)
|
||||
client_timeout = Column(u'client_timeout', INTEGER(), nullable=True)
|
||||
server_timeout = Column(u'server_timeout', INTEGER(), nullable=True)
|
||||
connect_timeout = Column(u'connect_timeout', INTEGER(), nullable=True)
|
||||
connect_retries = Column(u'connect_retries', INTEGER(), nullable=True)
|
||||
timeout = Column(u'timeout', INTEGER(), nullable=True)
|
||||
retries = Column(u'retries', INTEGER(), nullable=True)
|
||||
nodes = relationship(
|
||||
'Node', backref=backref('loadbalancers', order_by='Node.id')
|
||||
)
|
||||
|
|
|
@ -26,10 +26,8 @@ CREATE TABLE loadbalancers (
|
|||
created TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00', # timestamp of when LB was created
|
||||
updated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, # timestamp of when LB was last updated
|
||||
errmsg VARCHAR(128) DEFAULT NULL, # optional error message which can describe details regarding LBs state, can be blank if no error state exists
|
||||
client_timeout INT,
|
||||
server_timeout INT,
|
||||
connect_timeout INT,
|
||||
connect_retries INT,
|
||||
timeout INT,
|
||||
retries INT,
|
||||
PRIMARY KEY (id) # ids are unique accross all LBs
|
||||
) DEFAULT CHARSET utf8 DEFAULT COLLATE utf8_general_ci;
|
||||
|
||||
|
|
Loading…
Reference in New Issue