diff --git a/src/config/api-server/vnc_cfg_api_server.py b/src/config/api-server/vnc_cfg_api_server.py index 9dc7df8885a..0ddc5fa15c8 100644 --- a/src/config/api-server/vnc_cfg_api_server.py +++ b/src/config/api-server/vnc_cfg_api_server.py @@ -267,6 +267,14 @@ def __init__(self, args_str=None): self._resource_classes['physical-interface'] = \ vnc_cfg_types.PhysicalInterfaceServer + self._resource_classes['virtual-ip'] = vnc_cfg_types.VirtualIpServer + self._resource_classes['loadbalancer-healthmonitor'] = ( + vnc_cfg_types.LoadbalancerHealthmonitorServer) + self._resource_classes['loadbalancer-member'] = ( + vnc_cfg_types.LoadbalancerMemberServer) + self._resource_classes['loadbalancer-pool'] = ( + vnc_cfg_types.LoadbalancerPoolServer) + # TODO default-generation-setting can be from ini file self._resource_classes['bgp-router'].generate_default_instance = False self._resource_classes[ diff --git a/src/config/api-server/vnc_cfg_types.py b/src/config/api-server/vnc_cfg_types.py index 660bdb3fd28..245d4022a5f 100644 --- a/src/config/api-server/vnc_cfg_types.py +++ b/src/config/api-server/vnc_cfg_types.py @@ -1147,3 +1147,91 @@ def _check_interface_name(cls, obj_dict, db_conn): # end _check_interface_name # end class PhysicalInterfaceServer + + +class LoadbalancerMemberServer(LoadbalancerMemberServerGen): + + @classmethod + def http_post_collection(cls, tenant_name, obj_dict, db_conn): + user_visibility = obj_dict['id_perms'].get('user_visible', True) + + try: + fq_name = obj_dict['fq_name'] + proj_uuid = db_conn.fq_name_to_uuid('project', fq_name[0:2]) + except cfgm_common.exceptions.NoIdError: + return (False, (500, 'No Project ID error : ' + proj_uuid)) + + ok, proj_dict = db_conn.dbe_read('project', {'uuid': proj_uuid}) + if not ok: + return (False, (500, 'Internal error : ' + pformat(proj_dict))) + + if not user_visibility: + return True, "" + + lb_pools = proj_dict.get('loadbalancer_pools', []) + quota_count = 0 + + for pool in lb_pools: + ok, lb_pool_dict = db_conn.dbe_read('loadbalancer-pool', + {'uuid': pool['uuid']}) + if not ok: + return (False, (500, 'Internal error : ' + + pformat(lb_pool_dict))) + + quota_count += len(lb_pool_dict.get('loadbalancer_members', [])) + + (ok, quota_limit) = QuotaHelper.check_quota_limit( + proj_dict, 'loadbalancer-member', quota_count) + if not ok: + return (False, (403, pformat(fq_name) + ' : ' + quota_limit)) + + return True, "" + +#end class LoadbalancerMemberServer + + +class LoadbalancerPoolServer(LoadbalancerPoolServerGen): + + @classmethod + def http_post_collection(cls, tenant_name, obj_dict, db_conn): + user_visibility = obj_dict['id_perms'].get('user_visible', True) + verify_quota_kwargs = {'db_conn': db_conn, + 'fq_name': obj_dict['fq_name'], + 'resource': 'loadbalancer_pools', + 'obj_type': 'loadbalancer-pool', + 'user_visibility': user_visibility} + return QuotaHelper.verify_quota_for_resource(**verify_quota_kwargs) + +# end class LoadbalancerPoolServer + + +class LoadbalancerHealthmonitorServer(LoadbalancerHealthmonitorServerGen): + + @classmethod + def http_post_collection(cls, tenant_name, obj_dict, db_conn): + user_visibility = obj_dict['id_perms'].get('user_visible', True) + verify_quota_kwargs = {'db_conn': db_conn, + 'fq_name': obj_dict['fq_name'], + 'resource': 'loadbalancer_healthmonitors', + 'obj_type': 'loadbalancer-healthmonitor', + 'user_visibility': user_visibility} + return QuotaHelper.verify_quota_for_resource(**verify_quota_kwargs) + +# end class LoadbalancerHealthmonitorServer + + +class VirtualIpServer(VirtualIpServerGen): + + @classmethod + def http_post_collection(cls, tenant_name, obj_dict, db_conn): + + user_visibility = obj_dict['id_perms'].get('user_visible', True) + verify_quota_kwargs = {'db_conn': db_conn, + 'fq_name': obj_dict['fq_name'], + 'resource': 'virtual_ips', + 'obj_type': 'virtual-ip', + 'user_visibility': user_visibility} + return QuotaHelper.verify_quota_for_resource(**verify_quota_kwargs) + +# end class VirtualIpServer + diff --git a/src/config/api-server/vnc_quota.py b/src/config/api-server/vnc_quota.py index 209cec238c2..884ab420c55 100644 --- a/src/config/api-server/vnc_quota.py +++ b/src/config/api-server/vnc_quota.py @@ -2,6 +2,7 @@ from gen.resource_xsd import * from gen.resource_common import * from gen.resource_server import * +from pprint import pformat class QuotaHelper(object): @@ -31,3 +32,27 @@ def check_quota_limit(cls, proj_dict, obj_type, quota_count): if quota_limit > 0 and quota_count >= quota_limit: return (False, 'quota limit (%d) exceeded for resource %s' % (quota_limit, obj_type)) return (True, quota_limit) + + @classmethod + def verify_quota_for_resource(cls, db_conn, resource, obj_type, + user_visibility, proj_uuid=None, fq_name=[]): + if not proj_uuid and fq_name: + try: + proj_uuid = db_conn.fq_name_to_uuid('project', fq_name[0:2]) + except cfgm_common.exceptions.NoIdError: + return (False, (500, 'No Project ID error : ' + proj_uuid)) + + (ok, proj_dict) = cls.get_project_dict(proj_uuid, db_conn) + if not ok: + return (False, (500, 'Internal error : ' + pformat(proj_dict))) + + if not user_visibility: + return True, "" + + quota_count = len(proj_dict.get(resource, [])) + (ok, quota_limit) = cls.check_quota_limit(proj_dict, obj_type, + quota_count) + if not ok: + return (False, (403, pformat(fq_name) + ' : ' + quota_limit)) + return True, "" + diff --git a/src/schema/vnc_cfg.xsd b/src/schema/vnc_cfg.xsd index 0b18d3f8882..08a9ae65256 100644 --- a/src/schema/vnc_cfg.xsd +++ b/src/schema/vnc_cfg.xsd @@ -531,6 +531,10 @@ targetNamespace="http://www.contrailsystems.com/2012/VNC-CONFIG/0"> + + + +