[API] Support per-tenant max loadbalancers

Note: Schema altering change

Adds a new table that allows maximum number of load balancers to
be set per tenant ID. If a value is not set, the global value is
used. The per-tenant value always overrides the global value.

Change-Id: Ib7911742510756e34a4ef0ecf9380abb2a759e8e
This commit is contained in:
David Shrewsbury
2014-02-09 14:01:07 -05:00
parent 42bcd83362
commit 2b829118b3
4 changed files with 39 additions and 5 deletions

View File

@@ -13,20 +13,32 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from pecan import expose from pecan import expose, request
from pecan.rest import RestController from pecan.rest import RestController
from libra.common.api.lbaas import Limits, db_session from libra.api.acl import get_limited_to_project
from libra.common.api.lbaas import Limits, TenantLimits, db_session
class LimitsController(RestController): class LimitsController(RestController):
@expose('json') @expose('json')
def get(self): def get(self):
resp = {} resp = {}
tenant_id = get_limited_to_project(request.headers)
with db_session() as session: with db_session() as session:
limits = session.query(Limits).all() limits = session.query(Limits).all()
# Get per-tenant values
tenant_lblimit = session.query(TenantLimits.loadbalancers).\
filter(TenantLimits.tenantid == tenant_id).scalar()
for limit in limits: for limit in limits:
resp[limit.name] = limit.value resp[limit.name] = limit.value
# Set per-tenant values
if tenant_lblimit:
resp['maxLoadBalancers'] = tenant_lblimit
resp = {"limits": {"absolute": {"values": resp}}} resp = {"limits": {"absolute": {"values": resp}}}
session.rollback() session.rollback()
return resp return resp

View File

@@ -28,6 +28,7 @@ from logs import LogsController
# models # models
from libra.common.api.lbaas import LoadBalancer, Device, Node, db_session 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 loadbalancers_devices, Limits, Vip
from libra.common.api.lbaas import TenantLimits
from libra.common.api.lbaas import HealthMonitor from libra.common.api.lbaas import HealthMonitor
from libra.common.exc import ExhaustedError from libra.common.exc import ExhaustedError
from libra.api.model.validators import LBPut, LBPost, LBResp, LBVipResp from libra.api.model.validators import LBPut, LBPost, LBResp, LBVipResp
@@ -267,6 +268,13 @@ class LoadBalancersController(RestController):
filter(LoadBalancer.tenantid == tenant_id).\ filter(LoadBalancer.tenantid == tenant_id).\
filter(LoadBalancer.status != 'DELETED').count() filter(LoadBalancer.status != 'DELETED').count()
# Allow per-tenant LB limit, defaulting to the global limit if
# the per-tenant value is not set.
tenant_lblimit = session.query(TenantLimits.loadbalancers).\
filter(TenantLimits.tenantid == tenant_id).scalar()
if tenant_lblimit:
lblimit = tenant_lblimit
if len(body.name) > namelimit: if len(body.name) > namelimit:
session.rollback() session.rollback()
raise ClientSideError( raise ClientSideError(

View File

@@ -50,6 +50,13 @@ class FormatedDateTime(types.TypeDecorator):
return value.strftime('%Y-%m-%dT%H:%M:%S') return value.strftime('%Y-%m-%dT%H:%M:%S')
class TenantLimits(DeclarativeBase):
__tablename__ = 'tenant_limits'
id = Column(u'id', Integer, primary_key=True, nullable=False)
tenantid = Column(u'tenantid', VARCHAR(length=128), nullable=False)
loadbalancers = Column(u'loadbalancers', INTEGER(), nullable=True)
class Limits(DeclarativeBase): class Limits(DeclarativeBase):
__tablename__ = 'global_limits' __tablename__ = 'global_limits'
id = Column(u'id', Integer, primary_key=True, nullable=False) id = Column(u'id', Integer, primary_key=True, nullable=False)

View File

@@ -100,6 +100,14 @@ CREATE TABLE `global_limits` (
INSERT INTO `global_limits` VALUES (1,'maxLoadBalancerNameLength',128),(2,'maxVIPsPerLoadBalancer',1),(3,'maxNodesPerLoadBalancer',50),(4,'maxLoadBalancers',20); INSERT INTO `global_limits` VALUES (1,'maxLoadBalancerNameLength',128),(2,'maxVIPsPerLoadBalancer',1),(3,'maxNodesPerLoadBalancer',50),(4,'maxLoadBalancers',20);
CREATE TABLE `tenant_limits` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tenantid` VARCHAR(128) NOT NULL,
`loadbalancers` INT, # Max number of load balancers
PRIMARY KEY(id),
UNIQUE KEY `tenantid` (`tenantid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
# Billing # Billing
CREATE TABLE billing ( CREATE TABLE billing (
id int(11) NOT NULL, id int(11) NOT NULL,
@@ -120,4 +128,3 @@ CREATE TABLE stats (
status VARCHAR(50) NOT NULL, # Current LB status status VARCHAR(50) NOT NULL, # Current LB status
PRIMARY KEY (id) # ids are unique across all LBs PRIMARY KEY (id) # ids are unique across all LBs
) ENGINE=InnoDB DEFAULT CHARSET latin1; ) ENGINE=InnoDB DEFAULT CHARSET latin1;