diff --git a/libra/api/controllers/load_balancers.py b/libra/api/controllers/load_balancers.py index c91a5ea3..9c44fc9a 100644 --- a/libra/api/controllers/load_balancers.py +++ b/libra/api/controllers/load_balancers.py @@ -27,8 +27,8 @@ from logs import LogsController # models from libra.common.api.lbaas import LoadBalancer, Device, Node, db_session -from libra.common.api.lbaas import loadbalancers_devices, Limits, Vip from libra.common.api.lbaas import TenantLimits +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 @@ -282,6 +282,8 @@ class LoadBalancersController(RestController): count = session.query(LoadBalancer).\ filter(LoadBalancer.tenantid == tenant_id).\ filter(LoadBalancer.status != 'DELETED').count() + ports = session.query(Ports.protocol, Ports.portnum).\ + filter(Ports.enabled == 1).all() # Allow per-tenant LB limit, defaulting to the global limit if # the per-tenant value is not set. @@ -330,7 +332,19 @@ class LoadBalancersController(RestController): raise ClientSideError( 'Port number {0} is invalid'.format(body.port) ) - lb.port = body.port + # Make sure the port is valid and enabled + valid = False + for item in ports: + item = item._asdict() + if(lb.protocol == item["protocol"].upper() and + body.port == item["portnum"]): + valid = True + if valid: + lb.port = body.port + else: + raise ClientSideError( + 'Port number {0} is invalid'.format(body.port) + ) else: if lb.protocol == 'HTTP': lb.port = 80 diff --git a/libra/api/controllers/protocols.py b/libra/api/controllers/protocols.py new file mode 100644 index 00000000..34e01e82 --- /dev/null +++ b/libra/api/controllers/protocols.py @@ -0,0 +1,37 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# Copyright 2013 Hewlett-Packard Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from pecan import expose +from pecan.rest import RestController +from libra.common.api.lbaas import Ports, db_session + + +class ProtocolsController(RestController): + @expose('json') + def get(self): + protocols = [] + with db_session() as session: + ports = session.query(Ports.protocol, Ports.portnum).\ + filter(Ports.enabled == 1).all() + for item in ports: + data = {} + item = item._asdict() + data["name"] = item["protocol"] + data["port"] = item["portnum"] + protocols.append(data) + + resp = {"protocols": protocols} + session.rollback() + return resp diff --git a/libra/api/controllers/v1.py b/libra/api/controllers/v1.py index d94b237c..80ba5122 100644 --- a/libra/api/controllers/v1.py +++ b/libra/api/controllers/v1.py @@ -16,6 +16,7 @@ from pecan import expose, response from load_balancers import LoadBalancersController from limits import LimitsController +from protocols import ProtocolsController from libra.api.model.responses import Responses @@ -27,18 +28,6 @@ class V1Controller(object): response.status = 200 return Responses.versions - @expose('json') - def protocols(self): - """Lists all supported load balancing protocols. - - Url: - GET /protocols - - Returns: dict - """ - response.status = 200 - return Responses.protocols - @expose('json') def algorithms(self): """List all supported load balancing algorithms. @@ -54,3 +43,4 @@ class V1Controller(object): #pecan uses this controller class for urls that start with /loadbalancers loadbalancers = LoadBalancersController() limits = LimitsController() + protocols = ProtocolsController() diff --git a/libra/api/model/responses.py b/libra/api/model/responses.py index a77fbaeb..48c5b19e 100644 --- a/libra/api/model/responses.py +++ b/libra/api/model/responses.py @@ -36,24 +36,6 @@ class Responses(object): ] } - """protocols response""" - protocols = { - 'protocols': [ - { - 'name': 'HTTP', - 'port': '80' - }, - { - 'name': 'TCP', - 'port': '443' - }, - { - 'name': 'GALERA', - 'port': '3306' - } - ] - } - versions = { "versions": [ { diff --git a/libra/common/api/lbaas.py b/libra/common/api/lbaas.py index 6c8306a9..b603e875 100644 --- a/libra/common/api/lbaas.py +++ b/libra/common/api/lbaas.py @@ -184,6 +184,16 @@ class Stats(DeclarativeBase): status = Column(u'status', VARCHAR(length=50), nullable=False) +class Ports(DeclarativeBase): + """ports model""" + __tablename__ = 'ports' + #column definitions + id = Column(u'id', BIGINT(), primary_key=True, nullable=False) + protocol = Column(u'protocol', VARCHAR(length=50), nullable=False) + portnum = Column(u'portnum', BIGINT(), nullable=False) + enabled = Column(u'enabled', INTEGER(), nullable=False, default=0) + + class RoutingSession(Session): """ Try to use the first engine provided. If this fails use the next in sequence and so on. Reset to the first after 60 seconds diff --git a/libra/common/api/lbaas.sql b/libra/common/api/lbaas.sql index 9bf3bf3b..23c3803f 100644 --- a/libra/common/api/lbaas.sql +++ b/libra/common/api/lbaas.sql @@ -132,3 +132,15 @@ CREATE TABLE stats ( status VARCHAR(50) NOT NULL, # Current LB status PRIMARY KEY (id) # ids are unique across all LBs ) ENGINE=InnoDB DEFAULT CHARSET latin1; + +# Ports +CREATE TABLE ports ( + id BIGINT NOT NULL AUTO_INCREMENT, # unique id + protocol VARCHAR(50) NOT NULL, # Ptotocol type (HTTP, TCP, etc) + portnum INT NOT NULL, # port number + enabled BOOLEAN NOT NULL DEFAULT FALSE, # enabled/disabled + PRIMARY KEY (id) # ids are unique across all LBs + ) ENGINE=InnoDB DEFAULT CHARSET latin1; + +INSERT INTO ports VALUES (1, 'HTTP', 80, true),(2, 'HTTP', 8080, false),(3, 'HTTP', 8088, false),(4,'TCP', 443, true),(5, 'TCP', 8443, false),(6, 'TCP', 3306, true),(7, 'GALERA', 3306, true); +