API+ADMIN_API: SSL and DB fixes
* Add SSL to Admin API * Improve debug flag on both APIs * Make Admin API use its own model * Improve DB session handling and rollbacks Change-Id: I9d268079effbaca70c8c69d591bf48d494c1293f
This commit is contained in:
parent
971f37d680
commit
df060ccd19
@ -76,6 +76,8 @@ poll_timeout_retry = 30
|
|||||||
db_user=root
|
db_user=root
|
||||||
db_pass=passwd
|
db_pass=passwd
|
||||||
db_schema=lbaas
|
db_schema=lbaas
|
||||||
|
ssl_certfile=certfile.crt
|
||||||
|
ssl_keyfile=keyfile.key
|
||||||
|
|
||||||
[api]
|
[api]
|
||||||
host=0.0.0.0
|
host=0.0.0.0
|
||||||
|
@ -46,6 +46,10 @@ def setup_app(pecan_config, args):
|
|||||||
'host': args.db_host,
|
'host': args.db_host,
|
||||||
'schema': args.db_schema
|
'schema': args.db_schema
|
||||||
}
|
}
|
||||||
|
if args.debug:
|
||||||
|
config['wsme'] = {'debug': True}
|
||||||
|
config['app']['debug'] = True
|
||||||
|
|
||||||
pecan.configuration.set_config(config, overwrite=True)
|
pecan.configuration.set_config(config, overwrite=True)
|
||||||
|
|
||||||
app = pecan.make_app(
|
app = pecan.make_app(
|
||||||
@ -93,11 +97,20 @@ def main():
|
|||||||
options.parser.add_argument(
|
options.parser.add_argument(
|
||||||
'--db_schema', help='MySQL schema for libra'
|
'--db_schema', help='MySQL schema for libra'
|
||||||
)
|
)
|
||||||
|
options.parser.add_argument(
|
||||||
|
'--ssl_cert',
|
||||||
|
help='Path to an SSL certificate file'
|
||||||
|
)
|
||||||
|
options.parser.add_argument(
|
||||||
|
'--ssl_keyfile',
|
||||||
|
help='Path to an SSL key file'
|
||||||
|
)
|
||||||
|
|
||||||
args = options.run()
|
args = options.run()
|
||||||
|
|
||||||
required_args = [
|
required_args = [
|
||||||
'db_user', 'db_pass', 'db_host', 'db_schema'
|
'db_user', 'db_pass', 'db_host', 'db_schema', 'ssl_certfile',
|
||||||
|
'ssl_keyfile'
|
||||||
]
|
]
|
||||||
|
|
||||||
missing_args = 0
|
missing_args = 0
|
||||||
@ -131,6 +144,15 @@ def main():
|
|||||||
logger.info('Starting on {0}:{1}'.format(args.host, args.port))
|
logger.info('Starting on {0}:{1}'.format(args.host, args.port))
|
||||||
api = setup_app(pc, args)
|
api = setup_app(pc, args)
|
||||||
sys.stderr = LogStdout(logger)
|
sys.stderr = LogStdout(logger)
|
||||||
wsgi.server(eventlet.listen((args.host, args.port)), api)
|
# TODO: set ca_certs and cert_reqs=CERT_REQUIRED
|
||||||
|
wsgi.server(
|
||||||
|
eventlet.wrap_ssl(
|
||||||
|
eventlet.listen((args.host, args.port)),
|
||||||
|
certfile=args.ssl_certfile,
|
||||||
|
keyfile=args.ssl_keyfile,
|
||||||
|
server_side=True
|
||||||
|
),
|
||||||
|
api
|
||||||
|
)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
@ -19,31 +19,8 @@ app = {
|
|||||||
'modules': ['libra.admin_api'],
|
'modules': ['libra.admin_api'],
|
||||||
'static_root': '%(confdir)s/public',
|
'static_root': '%(confdir)s/public',
|
||||||
'template_path': '%(confdir)s/admin_api/templates',
|
'template_path': '%(confdir)s/admin_api/templates',
|
||||||
'debug': True,
|
|
||||||
'errors': {
|
'errors': {
|
||||||
404: '/notfound',
|
404: '/notfound',
|
||||||
'__force_dict__': True
|
'__force_dict__': True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wsme = {
|
|
||||||
'debug': True
|
|
||||||
}
|
|
||||||
|
|
||||||
#database = {
|
|
||||||
# 'username': 'root',
|
|
||||||
# 'password': 'testaburger',
|
|
||||||
# 'host': 'localhost',
|
|
||||||
# 'schema': 'lbaas'
|
|
||||||
#}
|
|
||||||
|
|
||||||
#gearman = {
|
|
||||||
# 'server': ['localhost:4730'],
|
|
||||||
#}
|
|
||||||
|
|
||||||
# Custom Configurations must be in Python dictionary format::
|
|
||||||
#
|
|
||||||
# foo = {'bar':'baz'}
|
|
||||||
#
|
|
||||||
# All configurations are accessible at::
|
|
||||||
# pecan.conf
|
|
||||||
|
@ -21,8 +21,8 @@ import wsmeext.pecan as wsme_pecan
|
|||||||
from wsme.exc import ClientSideError
|
from wsme.exc import ClientSideError
|
||||||
from usage import UsageController
|
from usage import UsageController
|
||||||
from libra.admin_api.model.validators import DeviceResp, DevicePost, DevicePut
|
from libra.admin_api.model.validators import DeviceResp, DevicePost, DevicePut
|
||||||
from libra.api.model.lbaas import LoadBalancer, Device, session
|
from libra.admin_api.model.lbaas import LoadBalancer, Device, session
|
||||||
from libra.api.model.lbaas import loadbalancers_devices
|
from libra.admin_api.model.lbaas import loadbalancers_devices
|
||||||
|
|
||||||
|
|
||||||
class DevicesController(RestController):
|
class DevicesController(RestController):
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
from pecan import expose, response
|
from pecan import expose, response
|
||||||
from libra.api.model.lbaas import Device, session
|
from libra.admin_api.model.lbaas import Device, session
|
||||||
from libra.admin_api.model.responses import Responses
|
from libra.admin_api.model.responses import Responses
|
||||||
from pecan.rest import RestController
|
from pecan.rest import RestController
|
||||||
|
|
||||||
|
@ -59,6 +59,10 @@ def setup_app(pecan_config, args):
|
|||||||
config['gearman'] = {
|
config['gearman'] = {
|
||||||
'server': args.gearman
|
'server': args.gearman
|
||||||
}
|
}
|
||||||
|
if args.debug:
|
||||||
|
config['wsme'] = {'debug': True}
|
||||||
|
config['app']['debug'] = True
|
||||||
|
|
||||||
pecan.configuration.set_config(config, overwrite=True)
|
pecan.configuration.set_config(config, overwrite=True)
|
||||||
|
|
||||||
app = pecan.make_app(
|
app = pecan.make_app(
|
||||||
|
@ -19,31 +19,8 @@ app = {
|
|||||||
'modules': ['libra.api'],
|
'modules': ['libra.api'],
|
||||||
'static_root': '%(confdir)s/public',
|
'static_root': '%(confdir)s/public',
|
||||||
'template_path': '%(confdir)s/api/templates',
|
'template_path': '%(confdir)s/api/templates',
|
||||||
'debug': True,
|
|
||||||
'errors': {
|
'errors': {
|
||||||
404: '/notfound',
|
404: '/notfound',
|
||||||
'__force_dict__': True
|
'__force_dict__': True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#wsme = {
|
|
||||||
# 'debug': True
|
|
||||||
#}
|
|
||||||
|
|
||||||
#database = {
|
|
||||||
# 'username': 'root',
|
|
||||||
# 'password': 'testaburger',
|
|
||||||
# 'host': 'localhost',
|
|
||||||
# 'schema': 'lbaas'
|
|
||||||
#}
|
|
||||||
|
|
||||||
#gearman = {
|
|
||||||
# 'server': ['localhost:4730'],
|
|
||||||
#}
|
|
||||||
|
|
||||||
# Custom Configurations must be in Python dictionary format::
|
|
||||||
#
|
|
||||||
# foo = {'bar':'baz'}
|
|
||||||
#
|
|
||||||
# All configurations are accessible at::
|
|
||||||
# pecan.conf
|
|
||||||
|
@ -15,16 +15,18 @@
|
|||||||
|
|
||||||
from pecan import expose
|
from pecan import expose
|
||||||
from pecan.rest import RestController
|
from pecan.rest import RestController
|
||||||
from libra.api.model.lbaas import Limits, session
|
from libra.api.model.lbaas import Limits, get_session
|
||||||
|
|
||||||
|
|
||||||
class LimitsController(RestController):
|
class LimitsController(RestController):
|
||||||
@expose('json')
|
@expose('json')
|
||||||
def get(self):
|
def get(self):
|
||||||
resp = {}
|
resp = {}
|
||||||
|
session = get_session()
|
||||||
limits = session.query(Limits).all()
|
limits = session.query(Limits).all()
|
||||||
for limit in limits:
|
for limit in limits:
|
||||||
resp[limit.name] = limit.value
|
resp[limit.name] = limit.value
|
||||||
|
|
||||||
resp = {"limits": {"absolute": {"values": resp}}}
|
resp = {"limits": {"absolute": {"values": resp}}}
|
||||||
|
session.rollback()
|
||||||
return resp
|
return resp
|
||||||
|
@ -25,7 +25,7 @@ from nodes import NodesController
|
|||||||
from virtualips import VipsController
|
from virtualips import VipsController
|
||||||
from logs import LogsController
|
from logs import LogsController
|
||||||
# models
|
# models
|
||||||
from libra.api.model.lbaas import LoadBalancer, Device, Node, session
|
from libra.api.model.lbaas import LoadBalancer, Device, Node, get_session
|
||||||
from libra.api.model.lbaas import loadbalancers_devices, Limits
|
from libra.api.model.lbaas import loadbalancers_devices, Limits
|
||||||
from libra.api.model.validators import LBPut, LBPost, LBResp, LBVipResp
|
from libra.api.model.validators import LBPut, LBPost, LBResp, LBVipResp
|
||||||
from libra.api.model.validators import LBRespNode
|
from libra.api.model.validators import LBRespNode
|
||||||
@ -58,7 +58,7 @@ class LoadBalancersController(RestController):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
tenant_id = get_limited_to_project(request.headers)
|
tenant_id = get_limited_to_project(request.headers)
|
||||||
|
session = get_session()
|
||||||
# if we don't have an id then we want a list of them own by this tenent
|
# if we don't have an id then we want a list of them own by this tenent
|
||||||
if not load_balancer_id:
|
if not load_balancer_id:
|
||||||
lbs = session.query(
|
lbs = session.query(
|
||||||
@ -177,7 +177,7 @@ class LoadBalancersController(RestController):
|
|||||||
raise ClientSideError(
|
raise ClientSideError(
|
||||||
'IP Address {0} not valid'.format(node.address)
|
'IP Address {0} not valid'.format(node.address)
|
||||||
)
|
)
|
||||||
|
session = get_session()
|
||||||
lblimit = session.query(Limits.value).\
|
lblimit = session.query(Limits.value).\
|
||||||
filter(Limits.name == 'maxLoadBalancers').scalar()
|
filter(Limits.name == 'maxLoadBalancers').scalar()
|
||||||
nodelimit = session.query(Limits.value).\
|
nodelimit = session.query(Limits.value).\
|
||||||
@ -189,16 +189,19 @@ class LoadBalancersController(RestController):
|
|||||||
filter(LoadBalancer.status != 'DELETED').count()
|
filter(LoadBalancer.status != 'DELETED').count()
|
||||||
|
|
||||||
if len(body.name) > namelimit:
|
if len(body.name) > namelimit:
|
||||||
|
session.rollback()
|
||||||
raise ClientSideError(
|
raise ClientSideError(
|
||||||
'Length of Load Balancer name too long'
|
'Length of Load Balancer name too long'
|
||||||
)
|
)
|
||||||
# TODO: this should probably be a 413, not sure how to do that yet
|
# TODO: this should probably be a 413, not sure how to do that yet
|
||||||
if count >= lblimit:
|
if count >= lblimit:
|
||||||
|
session.rollback()
|
||||||
raise OverLimit(
|
raise OverLimit(
|
||||||
'Account has hit limit of {0} Load Balancers'.
|
'Account has hit limit of {0} Load Balancers'.
|
||||||
format(lblimit)
|
format(lblimit)
|
||||||
)
|
)
|
||||||
if len(body.nodes) > nodelimit:
|
if len(body.nodes) > nodelimit:
|
||||||
|
session.rollback()
|
||||||
raise OverLimit(
|
raise OverLimit(
|
||||||
'Too many backend nodes supplied (limit is {0}'.
|
'Too many backend nodes supplied (limit is {0}'.
|
||||||
format(nodelimit)
|
format(nodelimit)
|
||||||
@ -230,6 +233,7 @@ class LoadBalancersController(RestController):
|
|||||||
filter(Device.id == virtual_id).\
|
filter(Device.id == virtual_id).\
|
||||||
first()
|
first()
|
||||||
if old_lb is None:
|
if old_lb is None:
|
||||||
|
session.rollback()
|
||||||
raise InvalidInput(
|
raise InvalidInput(
|
||||||
'virtualIps', virtual_id, 'Invalid virtual IP provided'
|
'virtualIps', virtual_id, 'Invalid virtual IP provided'
|
||||||
)
|
)
|
||||||
@ -243,6 +247,7 @@ class LoadBalancersController(RestController):
|
|||||||
filter(LoadBalancer.protocol == 'HTTP').\
|
filter(LoadBalancer.protocol == 'HTTP').\
|
||||||
count()
|
count()
|
||||||
if old_count:
|
if old_count:
|
||||||
|
session.rollback()
|
||||||
# Error here, can have only one HTTP
|
# Error here, can have only one HTTP
|
||||||
raise ClientSideError(
|
raise ClientSideError(
|
||||||
'Only one HTTP load balancer allowed per device'
|
'Only one HTTP load balancer allowed per device'
|
||||||
@ -256,12 +261,14 @@ class LoadBalancersController(RestController):
|
|||||||
filter(LoadBalancer.protocol == 'TCP').\
|
filter(LoadBalancer.protocol == 'TCP').\
|
||||||
count()
|
count()
|
||||||
if old_count:
|
if old_count:
|
||||||
|
session.rollback()
|
||||||
# Error here, can have only one TCP
|
# Error here, can have only one TCP
|
||||||
raise ClientSideError(
|
raise ClientSideError(
|
||||||
'Only one TCP load balancer allowed per device'
|
'Only one TCP load balancer allowed per device'
|
||||||
)
|
)
|
||||||
|
|
||||||
if device is None:
|
if device is None:
|
||||||
|
session.rollback()
|
||||||
raise RuntimeError('No devices available')
|
raise RuntimeError('No devices available')
|
||||||
|
|
||||||
lb.tenantid = tenant_id
|
lb.tenantid = tenant_id
|
||||||
@ -354,7 +361,7 @@ class LoadBalancersController(RestController):
|
|||||||
raise ClientSideError('Load Balancer ID is required')
|
raise ClientSideError('Load Balancer ID is required')
|
||||||
|
|
||||||
tenant_id = get_limited_to_project(request.headers)
|
tenant_id = get_limited_to_project(request.headers)
|
||||||
|
session = get_session()
|
||||||
# grab the lb
|
# grab the lb
|
||||||
lb = session.query(LoadBalancer).\
|
lb = session.query(LoadBalancer).\
|
||||||
filter(LoadBalancer.id == self.lbid).\
|
filter(LoadBalancer.id == self.lbid).\
|
||||||
@ -362,12 +369,14 @@ class LoadBalancersController(RestController):
|
|||||||
filter(LoadBalancer.status != 'DELETED').first()
|
filter(LoadBalancer.status != 'DELETED').first()
|
||||||
|
|
||||||
if lb is None:
|
if lb is None:
|
||||||
|
session.rollback()
|
||||||
raise ClientSideError('Load Balancer ID is not valid')
|
raise ClientSideError('Load Balancer ID is not valid')
|
||||||
|
|
||||||
if body.name != Unset:
|
if body.name != Unset:
|
||||||
namelimit = session.query(Limits.value).\
|
namelimit = session.query(Limits.value).\
|
||||||
filter(Limits.name == 'maxLoadBalancerNameLength').scalar()
|
filter(Limits.name == 'maxLoadBalancerNameLength').scalar()
|
||||||
if len(body.name) > namelimit:
|
if len(body.name) > namelimit:
|
||||||
|
session.rollback()
|
||||||
raise ClientSideError(
|
raise ClientSideError(
|
||||||
'Length of Load Balancer name too long'
|
'Length of Load Balancer name too long'
|
||||||
)
|
)
|
||||||
@ -405,12 +414,14 @@ class LoadBalancersController(RestController):
|
|||||||
"""
|
"""
|
||||||
tenant_id = get_limited_to_project(request.headers)
|
tenant_id = get_limited_to_project(request.headers)
|
||||||
# grab the lb
|
# grab the lb
|
||||||
|
session = get_session()
|
||||||
lb = session.query(LoadBalancer).\
|
lb = session.query(LoadBalancer).\
|
||||||
filter(LoadBalancer.id == load_balancer_id).\
|
filter(LoadBalancer.id == load_balancer_id).\
|
||||||
filter(LoadBalancer.tenantid == tenant_id).\
|
filter(LoadBalancer.tenantid == tenant_id).\
|
||||||
filter(LoadBalancer.status != 'DELETED').first()
|
filter(LoadBalancer.status != 'DELETED').first()
|
||||||
|
|
||||||
if lb is None:
|
if lb is None:
|
||||||
|
session.rollback()
|
||||||
response.status = 400
|
response.status = 400
|
||||||
return dict(
|
return dict(
|
||||||
faultcode="Client",
|
faultcode="Client",
|
||||||
@ -435,6 +446,7 @@ class LoadBalancersController(RestController):
|
|||||||
response.status = 202
|
response.status = 202
|
||||||
return ''
|
return ''
|
||||||
except:
|
except:
|
||||||
|
session.rollback()
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
logger.exception('Error communicating with load balancer pool')
|
logger.exception('Error communicating with load balancer pool')
|
||||||
response.status = 500
|
response.status = 500
|
||||||
|
@ -19,7 +19,7 @@ from pecan import conf
|
|||||||
import wsmeext.pecan as wsme_pecan
|
import wsmeext.pecan as wsme_pecan
|
||||||
from wsme.exc import ClientSideError
|
from wsme.exc import ClientSideError
|
||||||
from wsme import Unset
|
from wsme import Unset
|
||||||
from libra.api.model.lbaas import LoadBalancer, Device, session
|
from libra.api.model.lbaas import LoadBalancer, Device, get_session
|
||||||
from libra.api.acl import get_limited_to_project
|
from libra.api.acl import get_limited_to_project
|
||||||
from libra.api.model.validators import LBLogsPost
|
from libra.api.model.validators import LBLogsPost
|
||||||
from libra.api.library.gearman_client import submit_job
|
from libra.api.library.gearman_client import submit_job
|
||||||
@ -35,13 +35,14 @@ class LogsController(RestController):
|
|||||||
raise ClientSideError('Load Balancer ID has not been supplied')
|
raise ClientSideError('Load Balancer ID has not been supplied')
|
||||||
|
|
||||||
tenant_id = get_limited_to_project(request.headers)
|
tenant_id = get_limited_to_project(request.headers)
|
||||||
|
session = get_session()
|
||||||
load_balancer = session.query(LoadBalancer).\
|
load_balancer = session.query(LoadBalancer).\
|
||||||
filter(LoadBalancer.tenantid == tenant_id).\
|
filter(LoadBalancer.tenantid == tenant_id).\
|
||||||
filter(LoadBalancer.id == self.lbid).\
|
filter(LoadBalancer.id == self.lbid).\
|
||||||
filter(LoadBalancer.status != 'DELETED').\
|
filter(LoadBalancer.status != 'DELETED').\
|
||||||
first()
|
first()
|
||||||
if load_balancer is None:
|
if load_balancer is None:
|
||||||
|
session.rollback()
|
||||||
raise ClientSideError('Load Balancer not found')
|
raise ClientSideError('Load Balancer not found')
|
||||||
|
|
||||||
load_balancer.status = 'PENDING_UPDATE'
|
load_balancer.status = 'PENDING_UPDATE'
|
||||||
|
@ -20,7 +20,8 @@ import wsmeext.pecan as wsme_pecan
|
|||||||
from wsme.exc import ClientSideError
|
from wsme.exc import ClientSideError
|
||||||
from wsme import Unset
|
from wsme import Unset
|
||||||
#default response objects
|
#default response objects
|
||||||
from libra.api.model.lbaas import LoadBalancer, Node, session, Limits, Device
|
from libra.api.model.lbaas import LoadBalancer, Node, get_session, Limits
|
||||||
|
from libra.api.model.lbaas import Device
|
||||||
from libra.api.acl import get_limited_to_project
|
from libra.api.acl import get_limited_to_project
|
||||||
from libra.api.model.validators import LBNodeResp, LBNodePost, NodeResp
|
from libra.api.model.validators import LBNodeResp, LBNodePost, NodeResp
|
||||||
from libra.api.model.validators import LBNodePut
|
from libra.api.model.validators import LBNodePut
|
||||||
@ -56,7 +57,7 @@ class NodesController(RestController):
|
|||||||
faultcode='Client',
|
faultcode='Client',
|
||||||
faultstring='Load Balancer ID not supplied'
|
faultstring='Load Balancer ID not supplied'
|
||||||
)
|
)
|
||||||
|
session = get_session()
|
||||||
if not node_id:
|
if not node_id:
|
||||||
nodes = session.query(
|
nodes = session.query(
|
||||||
Node.id, Node.address, Node.port, Node.status, Node.enabled
|
Node.id, Node.address, Node.port, Node.status, Node.enabled
|
||||||
@ -132,13 +133,14 @@ class NodesController(RestController):
|
|||||||
raise ClientSideError(
|
raise ClientSideError(
|
||||||
'IP Address {0} not valid'.format(node.address)
|
'IP Address {0} not valid'.format(node.address)
|
||||||
)
|
)
|
||||||
|
session = get_session()
|
||||||
load_balancer = session.query(LoadBalancer).\
|
load_balancer = session.query(LoadBalancer).\
|
||||||
filter(LoadBalancer.tenantid == tenant_id).\
|
filter(LoadBalancer.tenantid == tenant_id).\
|
||||||
filter(LoadBalancer.id == self.lbid).\
|
filter(LoadBalancer.id == self.lbid).\
|
||||||
filter(LoadBalancer.status != 'DELETED').\
|
filter(LoadBalancer.status != 'DELETED').\
|
||||||
first()
|
first()
|
||||||
if load_balancer is None:
|
if load_balancer is None:
|
||||||
|
session.rollback()
|
||||||
raise ClientSideError('Load Balancer not found')
|
raise ClientSideError('Load Balancer not found')
|
||||||
|
|
||||||
load_balancer.status = 'PENDING_UPDATE'
|
load_balancer.status = 'PENDING_UPDATE'
|
||||||
@ -149,6 +151,7 @@ class NodesController(RestController):
|
|||||||
filter(Node.lbid == self.lbid).count()
|
filter(Node.lbid == self.lbid).count()
|
||||||
|
|
||||||
if (nodecount + len(body.nodes)) > nodelimit:
|
if (nodecount + len(body.nodes)) > nodelimit:
|
||||||
|
session.rollback()
|
||||||
raise OverLimit(
|
raise OverLimit(
|
||||||
'Command would exceed Load Balancer node limit'
|
'Command would exceed Load Balancer node limit'
|
||||||
)
|
)
|
||||||
@ -195,6 +198,7 @@ class NodesController(RestController):
|
|||||||
raise ClientSideError('Node ID has not been supplied')
|
raise ClientSideError('Node ID has not been supplied')
|
||||||
|
|
||||||
tenant_id = get_limited_to_project(request.headers)
|
tenant_id = get_limited_to_project(request.headers)
|
||||||
|
session = get_session()
|
||||||
# grab the lb
|
# grab the lb
|
||||||
lb = session.query(LoadBalancer).\
|
lb = session.query(LoadBalancer).\
|
||||||
filter(LoadBalancer.id == self.lbid).\
|
filter(LoadBalancer.id == self.lbid).\
|
||||||
@ -202,6 +206,7 @@ class NodesController(RestController):
|
|||||||
filter(LoadBalancer.status != 'DELETED').first()
|
filter(LoadBalancer.status != 'DELETED').first()
|
||||||
|
|
||||||
if lb is None:
|
if lb is None:
|
||||||
|
session.rollback()
|
||||||
raise ClientSideError('Load Balancer ID is not valid')
|
raise ClientSideError('Load Balancer ID is not valid')
|
||||||
|
|
||||||
node = session.query(Node).\
|
node = session.query(Node).\
|
||||||
@ -209,6 +214,7 @@ class NodesController(RestController):
|
|||||||
filter(Node.id == self.nodeid).first()
|
filter(Node.id == self.nodeid).first()
|
||||||
|
|
||||||
if node is None:
|
if node is None:
|
||||||
|
session.rollback()
|
||||||
raise ClientSideError('Node ID is not valid')
|
raise ClientSideError('Node ID is not valid')
|
||||||
|
|
||||||
if body.condition != Unset:
|
if body.condition != Unset:
|
||||||
@ -250,12 +256,14 @@ class NodesController(RestController):
|
|||||||
)
|
)
|
||||||
|
|
||||||
tenant_id = get_limited_to_project(request.headers)
|
tenant_id = get_limited_to_project(request.headers)
|
||||||
|
session = get_session()
|
||||||
load_balancer = session.query(LoadBalancer).\
|
load_balancer = session.query(LoadBalancer).\
|
||||||
filter(LoadBalancer.tenantid == tenant_id).\
|
filter(LoadBalancer.tenantid == tenant_id).\
|
||||||
filter(LoadBalancer.id == self.lbid).\
|
filter(LoadBalancer.id == self.lbid).\
|
||||||
filter(LoadBalancer.device != 'DELETED').\
|
filter(LoadBalancer.device != 'DELETED').\
|
||||||
first()
|
first()
|
||||||
if load_balancer is None:
|
if load_balancer is None:
|
||||||
|
session.rollback()
|
||||||
response.status = 400
|
response.status = 400
|
||||||
return dict(
|
return dict(
|
||||||
faultcode="Client",
|
faultcode="Client",
|
||||||
@ -266,16 +274,18 @@ class NodesController(RestController):
|
|||||||
filter(Node.lbid == self.lbid).count()
|
filter(Node.lbid == self.lbid).count()
|
||||||
# Can't delete the last LB
|
# Can't delete the last LB
|
||||||
if nodecount <= 1:
|
if nodecount <= 1:
|
||||||
|
session.rollback()
|
||||||
response.status = 400
|
response.status = 400
|
||||||
return dict(
|
return dict(
|
||||||
faultcode="Client",
|
faultcode="Client",
|
||||||
faultstring="Load Balancer not found"
|
faultstring="Cannot delete the last node in a load balancer"
|
||||||
)
|
)
|
||||||
node = session.query(Node).\
|
node = session.query(Node).\
|
||||||
filter(Node.lbid == self.lbid).\
|
filter(Node.lbid == self.lbid).\
|
||||||
filter(Node.id == node_id).\
|
filter(Node.id == node_id).\
|
||||||
first()
|
first()
|
||||||
if not node:
|
if not node:
|
||||||
|
session.rollback()
|
||||||
response.status = 400
|
response.status = 400
|
||||||
return dict(
|
return dict(
|
||||||
faultcode="Client",
|
faultcode="Client",
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
from pecan import response, expose, request
|
from pecan import response, expose, request
|
||||||
from pecan.rest import RestController
|
from pecan.rest import RestController
|
||||||
from libra.api.model.lbaas import LoadBalancer, Device, session
|
from libra.api.model.lbaas import LoadBalancer, Device, get_session
|
||||||
from libra.api.acl import get_limited_to_project
|
from libra.api.acl import get_limited_to_project
|
||||||
|
|
||||||
|
|
||||||
@ -41,6 +41,7 @@ class VipsController(RestController):
|
|||||||
faultcode="Client",
|
faultcode="Client",
|
||||||
faultstring="Load Balancer ID not provided"
|
faultstring="Load Balancer ID not provided"
|
||||||
)
|
)
|
||||||
|
session = get_session()
|
||||||
device = session.query(
|
device = session.query(
|
||||||
Device.id, Device.floatingIpAddr
|
Device.id, Device.floatingIpAddr
|
||||||
).join(LoadBalancer.devices).\
|
).join(LoadBalancer.devices).\
|
||||||
@ -48,6 +49,7 @@ class VipsController(RestController):
|
|||||||
filter(LoadBalancer.tenantid == tenant_id).first()
|
filter(LoadBalancer.tenantid == tenant_id).first()
|
||||||
|
|
||||||
if not device:
|
if not device:
|
||||||
|
session.rollback()
|
||||||
response.status = 400
|
response.status = 400
|
||||||
return dict(
|
return dict(
|
||||||
faultcode="Client",
|
faultcode="Client",
|
||||||
@ -61,5 +63,5 @@ class VipsController(RestController):
|
|||||||
"ipVersion": "IPV4"
|
"ipVersion": "IPV4"
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
session.rollback()
|
||||||
return resp
|
return resp
|
||||||
|
@ -16,7 +16,7 @@ import eventlet
|
|||||||
eventlet.monkey_patch()
|
eventlet.monkey_patch()
|
||||||
import logging
|
import logging
|
||||||
from libra.common.json_gearman import JSONGearmanClient
|
from libra.common.json_gearman import JSONGearmanClient
|
||||||
from libra.api.model.lbaas import LoadBalancer, session, Device
|
from libra.api.model.lbaas import LoadBalancer, get_session, Device
|
||||||
from pecan import conf
|
from pecan import conf
|
||||||
|
|
||||||
|
|
||||||
@ -56,6 +56,7 @@ class GearmanClientThread(object):
|
|||||||
self.gearman_client = JSONGearmanClient(conf.gearman.server)
|
self.gearman_client = JSONGearmanClient(conf.gearman.server)
|
||||||
|
|
||||||
def send_delete(self, data):
|
def send_delete(self, data):
|
||||||
|
session = get_session()
|
||||||
count = session.query(
|
count = session.query(
|
||||||
LoadBalancer
|
LoadBalancer
|
||||||
).join(LoadBalancer.devices).\
|
).join(LoadBalancer.devices).\
|
||||||
@ -100,7 +101,7 @@ class GearmanClientThread(object):
|
|||||||
filter(LoadBalancer.id == self.lbid).\
|
filter(LoadBalancer.id == self.lbid).\
|
||||||
first()
|
first()
|
||||||
if not status:
|
if not status:
|
||||||
self._set_error(data, response)
|
self._set_error(data, response, session)
|
||||||
else:
|
else:
|
||||||
lb.status = 'DELETED'
|
lb.status = 'DELETED'
|
||||||
if count == 0:
|
if count == 0:
|
||||||
@ -111,7 +112,7 @@ class GearmanClientThread(object):
|
|||||||
device.status = 'OFFLINE'
|
device.status = 'OFFLINE'
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
def _set_error(self, device_id, errmsg):
|
def _set_error(self, device_id, errmsg, session):
|
||||||
lbs = session.query(
|
lbs = session.query(
|
||||||
LoadBalancer
|
LoadBalancer
|
||||||
).join(LoadBalancer.nodes).\
|
).join(LoadBalancer.nodes).\
|
||||||
@ -128,6 +129,7 @@ class GearmanClientThread(object):
|
|||||||
lb.errmsg = errmsg
|
lb.errmsg = errmsg
|
||||||
|
|
||||||
def send_archive(self, data):
|
def send_archive(self, data):
|
||||||
|
session = get_session()
|
||||||
lb = session.query(LoadBalancer).\
|
lb = session.query(LoadBalancer).\
|
||||||
filter(LoadBalancer.id == self.lbid).\
|
filter(LoadBalancer.id == self.lbid).\
|
||||||
first()
|
first()
|
||||||
@ -155,6 +157,7 @@ class GearmanClientThread(object):
|
|||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
def send_update(self, data):
|
def send_update(self, data):
|
||||||
|
session = get_session()
|
||||||
lbs = session.query(
|
lbs = session.query(
|
||||||
LoadBalancer
|
LoadBalancer
|
||||||
).join(LoadBalancer.nodes).\
|
).join(LoadBalancer.nodes).\
|
||||||
@ -190,7 +193,7 @@ class GearmanClientThread(object):
|
|||||||
filter(LoadBalancer.id == self.lbid).\
|
filter(LoadBalancer.id == self.lbid).\
|
||||||
first()
|
first()
|
||||||
if not status:
|
if not status:
|
||||||
self._set_error(data, response)
|
self._set_error(data, response, session)
|
||||||
else:
|
else:
|
||||||
lb.status = 'ACTIVE'
|
lb.status = 'ACTIVE'
|
||||||
session.commit()
|
session.commit()
|
||||||
|
@ -113,5 +113,6 @@ class Node(DeclarativeBase):
|
|||||||
weight = Column(u'weight', INTEGER(), nullable=False)
|
weight = Column(u'weight', INTEGER(), nullable=False)
|
||||||
|
|
||||||
|
|
||||||
"""session"""
|
def get_session():
|
||||||
session = sessionmaker(bind=engine)()
|
session = sessionmaker(bind=engine)()
|
||||||
|
return session
|
||||||
|
Loading…
x
Reference in New Issue
Block a user