diff --git a/doc/source/contributor/internals/quota.rst b/doc/source/contributor/internals/quota.rst index 2d94942940b..c964a004b37 100644 --- a/doc/source/contributor/internals/quota.rst +++ b/doc/source/contributor/internals/quota.rst @@ -245,7 +245,7 @@ The process of making a reservation is fairly straightforward: on every requested resource, and then retrieving the amount of reserved resources. * Fetch current quota limits for requested resources, by invoking the - _get_tenant_quotas method. + _get_project_quotas method. * Fetch expired reservations for selected resources. This amount will be subtracted from resource usage. As in most cases there won't be any expired reservation, this approach actually requires less DB operations than diff --git a/neutron/db/db_base_plugin_v2.py b/neutron/db/db_base_plugin_v2.py index b197e8b11af..6ff09b670bb 100644 --- a/neutron/db/db_base_plugin_v2.py +++ b/neutron/db/db_base_plugin_v2.py @@ -401,8 +401,10 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon, def create_network_db(self, context, network): # single request processing n = network['network'] + # TODO(ralonsoh): "tenant_id" reference should be removed. + project_id = n.get('project_id') or n['tenant_id'] with db_api.CONTEXT_WRITER.using(context): - args = {'tenant_id': n['tenant_id'], + args = {'tenant_id': project_id, 'id': n.get('id') or uuidutils.generate_uuid(), 'name': n['name'], 'mtu': n.get('mtu', constants.DEFAULT_NETWORK_MTU), @@ -1426,12 +1428,14 @@ class NeutronDbPluginV2(db_base_plugin_common.DbBasePluginCommon, p = port['port'] port_id = p.get('id') or uuidutils.generate_uuid() network_id = p['network_id'] + # TODO(ralonsoh): "tenant_id" reference should be removed. + project_id = p.get('project_id') or p['tenant_id'] if p.get('device_owner'): self._enforce_device_owner_not_router_intf_or_device_id( context, p.get('device_owner'), p.get('device_id'), - p['tenant_id']) + project_id) - port_data = dict(tenant_id=p['tenant_id'], + port_data = dict(tenant_id=project_id, name=p['name'], id=port_id, network_id=network_id, diff --git a/neutron/db/quota/api.py b/neutron/db/quota/api.py index 121e19a1ca2..8f5b0ffa380 100644 --- a/neutron/db/quota/api.py +++ b/neutron/db/quota/api.py @@ -31,28 +31,28 @@ def utcnow(): class QuotaUsageInfo(collections.namedtuple( - 'QuotaUsageInfo', ['resource', 'tenant_id', 'used', 'dirty'])): + 'QuotaUsageInfo', ['resource', 'project_id', 'used', 'dirty'])): """Information about resource quota usage.""" class ReservationInfo(collections.namedtuple( - 'ReservationInfo', ['reservation_id', 'tenant_id', + 'ReservationInfo', ['reservation_id', 'project_id', 'expiration', 'deltas'])): """Information about a resource reservation.""" @db_api.retry_if_session_inactive() -def get_quota_usage_by_resource_and_tenant(context, resource, tenant_id): - """Return usage info for a given resource and tenant. +def get_quota_usage_by_resource_and_project(context, resource, project_id): + """Return usage info for a given resource and project. :param context: Request context :param resource: Name of the resource - :param tenant_id: Tenant identifier + :param project_id: Project identifier :returns: a QuotaUsageInfo instance """ result = quota_obj.QuotaUsage.get_object_dirty_protected( - context, resource=resource, project_id=tenant_id) + context, resource=resource, project_id=project_id) if not result: return return QuotaUsageInfo(result.resource, result.project_id, result.in_use, @@ -69,23 +69,22 @@ def get_quota_usage_by_resource(context, resource): @db_api.retry_if_session_inactive() -def get_quota_usage_by_tenant_id(context, tenant_id): - objs = quota_obj.QuotaUsage.get_objects(context, project_id=tenant_id) +def get_quota_usage_by_project_id(context, project_id): + objs = quota_obj.QuotaUsage.get_objects(context, project_id=project_id) return [QuotaUsageInfo(item.resource, - tenant_id, + project_id, item.in_use, item.dirty) for item in objs] @db_api.retry_if_session_inactive() -def set_quota_usage(context, resource, tenant_id, - in_use=None, delta=False): +def set_quota_usage(context, resource, project_id, in_use=None, delta=False): """Set resource quota usage. :param context: instance of neutron context with db session :param resource: name of the resource for which usage is being set - :param tenant_id: identifier of the tenant for which quota usage is - being set + :param project_id: identifier of the project for which quota usage is + being set :param in_use: integer specifying the new quantity of used resources, or a delta to apply to current used resource :param delta: Specifies whether in_use is an absolute number @@ -93,11 +92,11 @@ def set_quota_usage(context, resource, tenant_id, """ with db_api.CONTEXT_WRITER.using(context): usage_data = quota_obj.QuotaUsage.get_object( - context, resource=resource, project_id=tenant_id) + context, resource=resource, project_id=project_id) if not usage_data: # Must create entry usage_data = quota_obj.QuotaUsage( - context, resource=resource, project_id=tenant_id) + context, resource=resource, project_id=project_id) usage_data.create() # Perform explicit comparison with None as 0 is a valid value if in_use is not None: @@ -113,16 +112,16 @@ def set_quota_usage(context, resource, tenant_id, @db_api.retry_if_session_inactive() @db_api.CONTEXT_WRITER -def set_quota_usage_dirty(context, resource, tenant_id, dirty=True): - """Set quota usage dirty bit for a given resource and tenant. +def set_quota_usage_dirty(context, resource, project_id, dirty=True): + """Set quota usage dirty bit for a given resource and project. :param resource: a resource for which quota usage if tracked - :param tenant_id: tenant identifier + :param project_id: project identifier :param dirty: the desired value for the dirty bit (defaults to True) :returns: 1 if the quota usage data were updated, 0 otherwise. """ obj = quota_obj.QuotaUsage.get_object( - context, resource=resource, project_id=tenant_id) + context, resource=resource, project_id=project_id) if obj: obj.dirty = dirty obj.update() @@ -132,16 +131,17 @@ def set_quota_usage_dirty(context, resource, tenant_id, dirty=True): @db_api.retry_if_session_inactive() @db_api.CONTEXT_WRITER -def set_resources_quota_usage_dirty(context, resources, tenant_id, dirty=True): - """Set quota usage dirty bit for a given tenant and multiple resources. +def set_resources_quota_usage_dirty(context, resources, project_id, + dirty=True): + """Set quota usage dirty bit for a given project and multiple resources. :param resources: list of resource for which the dirty bit is going to be set - :param tenant_id: tenant identifier + :param project_id: project identifier :param dirty: the desired value for the dirty bit (defaults to True) :returns: the number of records for which the bit was actually set. """ - filters = {'project_id': tenant_id} + filters = {'project_id': project_id} if resources: filters['resource'] = resources objs = quota_obj.QuotaUsage.get_objects(context, **filters) @@ -154,10 +154,10 @@ def set_resources_quota_usage_dirty(context, resources, tenant_id, dirty=True): @db_api.retry_if_session_inactive() @db_api.CONTEXT_WRITER def set_all_quota_usage_dirty(context, resource, dirty=True): - """Set the dirty bit on quota usage for all tenants. + """Set the dirty bit on quota usage for all projects. :param resource: the resource for which the dirty bit should be set - :returns: the number of tenants for which the dirty bit was + :returns: the number of projects for which the dirty bit was actually updated """ # TODO(manjeets) consider squashing this method with @@ -170,7 +170,7 @@ def set_all_quota_usage_dirty(context, resource, dirty=True): @db_api.retry_if_session_inactive() -def create_reservation(context, tenant_id, deltas, expiration=None): +def create_reservation(context, project_id, deltas, expiration=None): # This method is usually called from within another transaction. # Consider using begin_nested expiration = expiration or (utcnow() + datetime.timedelta(0, 120)) @@ -179,7 +179,7 @@ def create_reservation(context, tenant_id, deltas, expiration=None): delta_objs.append(quota_obj.ResourceDelta( context, resource=resource, amount=delta)) reserv_obj = quota_obj.Reservation( - context, project_id=tenant_id, expiration=expiration, + context, project_id=project_id, expiration=expiration, resource_deltas=delta_objs) reserv_obj.create() return ReservationInfo(reserv_obj['id'], @@ -223,12 +223,12 @@ def remove_reservation(context, reservation_id, set_dirty=False): @db_api.retry_if_session_inactive() @db_api.CONTEXT_READER -def get_reservations_for_resources(context, tenant_id, resources, +def get_reservations_for_resources(context, project_id, resources, expired=False): """Retrieve total amount of reservations for specified resources. :param context: Neutron context with db session - :param tenant_id: Tenant identifier + :param project_id: Project identifier :param resources: Resources for which reserved amounts should be fetched :param expired: False to fetch active reservations, True to fetch expired reservations (defaults to False) @@ -238,17 +238,17 @@ def get_reservations_for_resources(context, tenant_id, resources, # can be mocked easily where as datetime is built in type # mock.path does not allow mocking built in types. return quota_obj.Reservation.get_total_reservations_map( - context, utcnow(), tenant_id, resources, expired) + context, utcnow(), project_id, resources, expired) @db_api.retry_if_session_inactive() @db_api.CONTEXT_WRITER -def remove_expired_reservations(context, tenant_id=None, timeout=None): +def remove_expired_reservations(context, project_id=None, timeout=None): expiring_time = utcnow() if timeout: expiring_time -= datetime.timedelta(seconds=timeout) return quota_obj.Reservation.delete_expired(context, expiring_time, - tenant_id) + project_id) class QuotaDriverAPI(object, metaclass=abc.ABCMeta): @@ -257,7 +257,7 @@ class QuotaDriverAPI(object, metaclass=abc.ABCMeta): @abc.abstractmethod def get_default_quotas(context, resources, project_id): """Given a list of resources, retrieve the default quotas set for - a tenant. + a project. :param context: The request context, for access checks. :param resources: A dictionary of the registered resource keys. @@ -267,7 +267,7 @@ class QuotaDriverAPI(object, metaclass=abc.ABCMeta): @staticmethod @abc.abstractmethod - def get_tenant_quotas(context, resources, project_id): + def get_project_quotas(context, resources, project_id): """Retrieve the quotas for the given list of resources and project :param context: The request context, for access checks. @@ -278,7 +278,7 @@ class QuotaDriverAPI(object, metaclass=abc.ABCMeta): @staticmethod @abc.abstractmethod - def get_detailed_tenant_quotas(context, resources, project_id): + def get_detailed_project_quotas(context, resources, project_id): """Retrieve detailed quotas for the given list of resources and project :param context: The request context, for access checks. @@ -291,11 +291,11 @@ class QuotaDriverAPI(object, metaclass=abc.ABCMeta): @staticmethod @abc.abstractmethod - def delete_tenant_quota(context, project_id): + def delete_project_quota(context, project_id): """Delete the quota entries for a given project_id. - After deletion, this tenant will use default quota values in conf. - Raise a "not found" error if the quota for the given tenant was + After deletion, this project will use default quota values in conf. + Raise a "not found" error if the quota for the given project was never defined. :param context: The request context, for access checks. @@ -382,15 +382,15 @@ class NullQuotaDriver(QuotaDriverAPI): pass @staticmethod - def get_tenant_quotas(context, resources, project_id): + def get_project_quotas(context, resources, project_id): pass @staticmethod - def get_detailed_tenant_quotas(context, resources, project_id): + def get_detailed_project_quotas(context, resources, project_id): pass @staticmethod - def delete_tenant_quota(context, project_id): + def delete_project_quota(context, project_id): pass @staticmethod diff --git a/neutron/db/quota/driver.py b/neutron/db/quota/driver.py index 6ace65ce4a3..b033b2ca210 100644 --- a/neutron/db/quota/driver.py +++ b/neutron/db/quota/driver.py @@ -35,139 +35,142 @@ class DbQuotaDriver(quota_api.QuotaDriverAPI): """ @staticmethod - def get_default_quotas(context, resources, tenant_id): + def get_default_quotas(context, resources, project_id): """Given a list of resources, retrieve the default quotas set for - a tenant. + a project. :param context: The request context, for access checks. :param resources: A dictionary of the registered resource keys. - :param tenant_id: The ID of the tenant to return default quotas for. + :param project_id: The ID of the project to return default quotas for. :return: dict from resource name to dict of name and limit """ - # Currently the tenant_id parameter is unused, since all tenants + # Currently the project_id parameter is unused, since all projects # share the same default values. This may change in the future so - # we include tenant-id to remain backwards compatible. + # we include project ID to remain backwards compatible. return dict((key, resource.default) for key, resource in resources.items()) @staticmethod @db_api.retry_if_session_inactive() - def get_tenant_quotas(context, resources, tenant_id): + def get_project_quotas(context, resources, project_id): """Given a list of resources, retrieve the quotas for the given - tenant. If no limits are found for the specified tenant, the operation - returns the default limits. + project. If no limits are found for the specified project, the + operation returns the default limits. :param context: The request context, for access checks. :param resources: A dictionary of the registered resource keys. - :param tenant_id: The ID of the tenant to return quotas for. + :param project_id: The ID of the project to return quotas for. :return: dict from resource name to dict of name and limit """ # init with defaults - tenant_quota = dict((key, resource.default) + project_quota = dict((key, resource.default) for key, resource in resources.items()) - # update with tenant specific limits - quota_objs = quota_obj.Quota.get_objects(context, project_id=tenant_id) + # update with project specific limits + quota_objs = quota_obj.Quota.get_objects(context, + project_id=project_id) for item in quota_objs: - tenant_quota[item['resource']] = item['limit'] + project_quota[item['resource']] = item['limit'] - return tenant_quota + return project_quota @staticmethod @db_api.retry_if_session_inactive() - def get_detailed_tenant_quotas(context, resources, tenant_id): - """Given a list of resources and a sepecific tenant, retrieve + def get_detailed_project_quotas(context, resources, project_id): + """Given a list of resources and a specific project, retrieve the detailed quotas (limit, used, reserved). :param context: The request context, for access checks. :param resources: A dictionary of the registered resource keys. + :param project_id: The ID of the project to return quotas for. :return dict: mapping resource name in dict to its corresponding limit used and reserved. Reserved currently returns default value of 0 """ res_reserve_info = quota_api.get_reservations_for_resources( - context, tenant_id, resources.keys()) - tenant_quota_ext = {} + context, project_id, resources.keys()) + project_quota_ext = {} for key, resource in resources.items(): if isinstance(resource, res.TrackedResource): - used = resource.count_used(context, tenant_id, + used = resource.count_used(context, project_id, resync_usage=False) else: # NOTE(ihrachys) .count won't use the plugin we pass, but we # pass it regardless to keep the quota driver API intact plugins = directory.get_plugins() plugin = plugins.get(key, plugins[constants.CORE]) - used = resource.count(context, plugin, tenant_id) + used = resource.count(context, plugin, project_id) - tenant_quota_ext[key] = { + project_quota_ext[key] = { 'limit': resource.default, 'used': used, 'reserved': res_reserve_info.get(key, 0), } - # update with specific tenant limits - quota_objs = quota_obj.Quota.get_objects(context, project_id=tenant_id) + # update with specific project limits + quota_objs = quota_obj.Quota.get_objects(context, + project_id=project_id) for item in quota_objs: - tenant_quota_ext[item['resource']]['limit'] = item['limit'] - return tenant_quota_ext + project_quota_ext[item['resource']]['limit'] = item['limit'] + return project_quota_ext @staticmethod @db_api.retry_if_session_inactive() - def delete_tenant_quota(context, tenant_id): - """Delete the quota entries for a given tenant_id. + def delete_project_quota(context, project_id): + """Delete the quota entries for a given project_id. - After deletion, this tenant will use default quota values in conf. - Raise a "not found" error if the quota for the given tenant was + After deletion, this project will use default quota values in conf. + Raise a "not found" error if the quota for the given project was never defined. """ - if quota_obj.Quota.delete_objects(context, project_id=tenant_id) < 1: + if quota_obj.Quota.delete_objects(context, project_id=project_id) < 1: # No record deleted means the quota was not found - raise exceptions.TenantQuotaNotFound(tenant_id=tenant_id) + raise exceptions.TenantQuotaNotFound(tenant_id=project_id) @staticmethod @db_api.retry_if_session_inactive() def get_all_quotas(context, resources): - """Given a list of resources, retrieve the quotas for the all tenants. + """Given a list of resources, retrieve the quotas for the all projects. :param context: The request context, for access checks. :param resources: A dictionary of the registered resource keys. - :return: quotas list of dict of tenant_id:, resourcekey1: + :return: quotas list of dict of project_id:, resourcekey1: resourcekey2: ... """ - tenant_default = dict((key, resource.default) + project_default = dict((key, resource.default) for key, resource in resources.items()) - all_tenant_quotas = {} + all_project_quotas = {} for quota in quota_obj.Quota.get_objects(context): - tenant_id = quota['project_id'] + project_id = quota['project_id'] # avoid setdefault() because only want to copy when actually # required - tenant_quota = all_tenant_quotas.get(tenant_id) - if tenant_quota is None: - tenant_quota = tenant_default.copy() - tenant_quota['tenant_id'] = tenant_id - attributes.populate_project_info(tenant_quota) - all_tenant_quotas[tenant_id] = tenant_quota + project_quota = all_project_quotas.get(project_id) + if project_quota is None: + project_quota = project_default.copy() + project_quota['project_id'] = project_id + attributes.populate_project_info(project_quota) + all_project_quotas[project_id] = project_quota - tenant_quota[quota['resource']] = quota['limit'] + project_quota[quota['resource']] = quota['limit'] # Convert values to a list to as caller expect an indexable iterable, # where python3's dict_values does not support indexing - return list(all_tenant_quotas.values()) + return list(all_project_quotas.values()) @staticmethod @db_api.retry_if_session_inactive() - def update_quota_limit(context, tenant_id, resource, limit): - tenant_quotas = quota_obj.Quota.get_objects( - context, project_id=tenant_id, resource=resource) - if tenant_quotas: - tenant_quotas[0].limit = limit - tenant_quotas[0].update() + def update_quota_limit(context, project_id, resource, limit): + project_quotas = quota_obj.Quota.get_objects( + context, project_id=project_id, resource=resource) + if project_quotas: + project_quotas[0].limit = limit + project_quotas[0].update() else: - quota_obj.Quota(context, project_id=tenant_id, resource=resource, + quota_obj.Quota(context, project_id=project_id, resource=resource, limit=limit).create() - def _get_quotas(self, context, tenant_id, resources): + def _get_quotas(self, context, project_id, resources): """Retrieves the quotas for specific resources. A helper method which retrieves the quotas for the specific @@ -175,24 +178,23 @@ class DbQuotaDriver(quota_api.QuotaDriverAPI): context. :param context: The request context, for access checks. - :param tenant_id: the tenant_id to check quota. + :param project_id: the project ID to check quota. :param resources: A dictionary of the registered resources. """ # Grab and return the quotas (without usages) - quotas = DbQuotaDriver.get_tenant_quotas( - context, resources, tenant_id) + quotas = DbQuotaDriver.get_project_quotas( + context, resources, project_id) return dict((k, v) for k, v in quotas.items()) - def _handle_expired_reservations(self, context, tenant_id): - LOG.debug("Deleting expired reservations for tenant:%s", tenant_id) + def _handle_expired_reservations(self, context, project_id): + LOG.debug("Deleting expired reservations for project: %s", project_id) # Delete expired reservations (we don't want them to accrue # in the database) - quota_api.remove_expired_reservations( - context, tenant_id=tenant_id) + quota_api.remove_expired_reservations(context, project_id=project_id) @db_api.retry_if_session_inactive() - def make_reservation(self, context, tenant_id, resources, deltas, plugin): + def make_reservation(self, context, project_id, resources, deltas, plugin): # Lock current reservation table # NOTE(salv-orlando): This routine uses DB write locks. # These locks are acquired by the count() method invoked on resources. @@ -207,11 +209,11 @@ class DbQuotaDriver(quota_api.QuotaDriverAPI): # to a single node will be available. requested_resources = deltas.keys() with db_api.CONTEXT_WRITER.using(context): - # get_tenant_quotes needs in input a dictionary mapping resource + # "get_project_quotas" needs in input a dictionary mapping resource # name to BaseResosurce instances so that the default quota can be # retrieved - current_limits = self.get_tenant_quotas( - context, resources, tenant_id) + current_limits = self.get_project_quotas( + context, resources, project_id) unlimited_resources = set([resource for (resource, limit) in current_limits.items() if limit < 0]) # Do not even bother counting resources and calculating headroom @@ -230,13 +232,13 @@ class DbQuotaDriver(quota_api.QuotaDriverAPI): # instances current_usages = dict( (resource, resources[resource].count( - context, plugin, tenant_id, resync_usage=False)) for + context, plugin, project_id, resync_usage=False)) for resource in requested_resources) # Adjust for expired reservations. Apparently it is cheaper than # querying every time for active reservations and counting overall # quantity of resources reserved expired_deltas = quota_api.get_reservations_for_resources( - context, tenant_id, requested_resources, expired=True) + context, project_id, requested_resources, expired=True) # Verify that the request can be accepted with current limits resources_over_limit = [] for resource in requested_resources: @@ -254,14 +256,14 @@ class DbQuotaDriver(quota_api.QuotaDriverAPI): if res_headroom < deltas[resource]: resources_over_limit.append(resource) if expired_reservations: - self._handle_expired_reservations(context, tenant_id) + self._handle_expired_reservations(context, project_id) if resources_over_limit: raise exceptions.OverQuota(overs=sorted(resources_over_limit)) # Success, store the reservation # TODO(salv-orlando): Make expiration time configurable return quota_api.create_reservation( - context, tenant_id, deltas) + context, project_id, deltas) def commit_reservation(self, context, reservation_id): # Do not mark resource usage as dirty. If a reservation is committed, @@ -276,7 +278,7 @@ class DbQuotaDriver(quota_api.QuotaDriverAPI): quota_api.remove_reservation(context, reservation_id, set_dirty=True) - def limit_check(self, context, tenant_id, resources, values): + def limit_check(self, context, project_id, resources, values): """Check simple quota limits. For limits--those quotas for which there is no usage @@ -289,7 +291,7 @@ class DbQuotaDriver(quota_api.QuotaDriverAPI): nothing. :param context: The request context, for access checks. - :param tenant_id: The tenant_id to check the quota. + :param project_id: The project ID to check the quota. :param resources: A dictionary of the registered resources. :param values: A dictionary of the values to check against the quota. @@ -301,7 +303,7 @@ class DbQuotaDriver(quota_api.QuotaDriverAPI): raise exceptions.InvalidQuotaValue(unders=sorted(unders)) # Get the applicable quotas - quotas = self._get_quotas(context, tenant_id, resources) + quotas = self._get_quotas(context, project_id, resources) # Check the quotas and construct a list of the resources that # would be put over limit by the desired values diff --git a/neutron/db/quota/driver_nolock.py b/neutron/db/quota/driver_nolock.py index a9745729ffe..5190d71e990 100644 --- a/neutron/db/quota/driver_nolock.py +++ b/neutron/db/quota/driver_nolock.py @@ -45,7 +45,7 @@ class DbQuotaNoLockDriver(quota_driver.DbQuotaDriver): resources_over_limit = [] with db_api.CONTEXT_WRITER.using(context): # Filter out unlimited resources. - limits = self.get_tenant_quotas(context, resources, project_id) + limits = self.get_project_quotas(context, resources, project_id) unlimited_resources = set([resource for (resource, limit) in limits.items() if limit < 0]) requested_resources = (set(deltas.keys()) - unlimited_resources) @@ -54,7 +54,7 @@ class DbQuotaNoLockDriver(quota_driver.DbQuotaDriver): # operation is fast and by calling it before making any # reservation, we ensure the freshness of the reservations. quota_api.remove_expired_reservations( - context, tenant_id=project_id, + context, project_id=project_id, timeout=quota_api.RESERVATION_EXPIRATION_TIMEOUT) # Count the number of (1) used and (2) reserved resources for this diff --git a/neutron/db/securitygroups_db.py b/neutron/db/securitygroups_db.py index cbb0c8c0193..42c18e01d23 100644 --- a/neutron/db/securitygroups_db.py +++ b/neutron/db/securitygroups_db.py @@ -924,10 +924,10 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase, @registry.receives(resources.NETWORK, [events.BEFORE_CREATE]) def _ensure_default_security_group_handler(self, resource, event, trigger, payload): - if event == events.BEFORE_UPDATE: - project_id = payload.states[0]['tenant_id'] - else: - project_id = payload.latest_state['tenant_id'] + _state = (payload.states[0] if event == events.BEFORE_UPDATE else + payload.latest_state) + # TODO(ralonsoh): "tenant_id" reference should be removed. + project_id = _state.get('project_id') or _state['tenant_id'] if project_id: self._ensure_default_security_group(payload.context, project_id) @@ -993,7 +993,8 @@ class SecurityGroupDbMixin(ext_sg.SecurityGroupPluginBase, return port_sg = port.get(ext_sg.SECURITYGROUPS) if port_sg is None or not validators.is_attr_set(port_sg): - port_project = port.get('tenant_id') + # TODO(ralonsoh): "tenant_id" reference should be removed. + port_project = port.get('project_id') or port.get('tenant_id') default_sg = self._ensure_default_security_group(context, port_project) if default_sg: diff --git a/neutron/extensions/quotasv2.py b/neutron/extensions/quotasv2.py index ef283866b0b..e0b9b11949e 100644 --- a/neutron/extensions/quotasv2.py +++ b/neutron/extensions/quotasv2.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. +import warnings + from neutron_lib.api import converters from neutron_lib.api import extensions as api_extensions from neutron_lib.api import faults @@ -74,20 +76,20 @@ class QuotaSetsController(wsgi.Controller): 'is_visible': True} self._update_extended_attributes = False - def _get_quotas(self, request, tenant_id): - return self._driver.get_tenant_quotas( + def _get_quotas(self, request, project_id): + return self._driver.get_project_quotas( request.context, resource_registry.get_all_resources(), - tenant_id) + project_id) def default(self, request, id): context = request.context - if id != context.tenant_id: + if id != context.project_id: validate_policy(context, "get_quota") return {self._resource_name: self._driver.get_default_quotas( context=context, resources=resource_registry.get_all_resources(), - tenant_id=id)} + project_id=id)} def create(self, request, body=None): msg = _('POST requests are not supported on this resource.') @@ -101,20 +103,31 @@ class QuotaSetsController(wsgi.Controller): context, resource_registry.get_all_resources())} def tenant(self, request): - """Retrieve the tenant info in context.""" + """Retrieve the project info in context.""" + warnings.warn( + '"tenant" Quota API method is deprecated, use "project" instead') + return self._project(request, 'tenant') + + def project(self, request): + """Retrieve the project info in context.""" + return self._project(request, 'project') + + @staticmethod + def _project(request, key): + """Retrieve the project info in context.""" context = request.context - if not context.tenant_id: + if not context.project_id: raise exceptions.QuotaMissingTenant() - return {'tenant': {'tenant_id': context.tenant_id}} + return {key: {key + '_id': context.project_id}} def show(self, request, id): - if id != request.context.tenant_id: + if id != request.context.project_id: validate_policy(request.context, "get_quota") return {self._resource_name: self._get_quotas(request, id)} def delete(self, request, id): validate_policy(request.context, "delete_quota") - self._driver.delete_tenant_quota(request.context, id) + self._driver.delete_project_quota(request.context, id) def update(self, request, id, body=None): validate_policy(request.context, "update_quota") @@ -152,7 +165,7 @@ class Quotasv2(api_extensions.ExtensionDescriptor): def get_description(cls): description = 'Expose functions for quotas management' if cfg.CONF.QUOTAS.quota_driver == DB_QUOTA_DRIVER: - description += ' per tenant' + description += ' per project' return description @classmethod @@ -169,7 +182,8 @@ class Quotasv2(api_extensions.ExtensionDescriptor): Quotasv2.get_alias(), controller, member_actions={DEFAULT_QUOTAS_ACTION: 'GET'}, - collection_actions={'tenant': 'GET'})] + collection_actions={'tenant': 'GET', + 'project': 'GET'})] def get_extended_resources(self, version): if version == "2.0": diff --git a/neutron/extensions/quotasv2_detail.py b/neutron/extensions/quotasv2_detail.py index 26a8d36884c..5087022a525 100644 --- a/neutron/extensions/quotasv2_detail.py +++ b/neutron/extensions/quotasv2_detail.py @@ -46,17 +46,17 @@ EXTENDED_ATTRIBUTES_2_0 = { class DetailQuotaSetsController(quotasv2.QuotaSetsController): - def _get_detailed_quotas(self, request, tenant_id): - return self._driver.get_detailed_tenant_quotas( + def _get_detailed_quotas(self, request, project_id): + return self._driver.get_detailed_project_quotas( request.context, - resource_registry.get_all_resources(), tenant_id) + resource_registry.get_all_resources(), project_id) def details(self, request, id): if id != request.context.project_id: # Check if admin if not request.context.is_admin: - reason = _("Only admin is authorized to access quotas for" - " another tenant") + reason = _("Only admin is authorized to access quotas for " + "another project") raise n_exc.AdminRequired(reason=reason) return {self._resource_name: self._get_detailed_quotas(request, id)} @@ -95,7 +95,8 @@ class Quotasv2_detail(api_extensions.ExtensionDescriptor): RESOURCE_COLLECTION, controller, member_actions={'details': 'GET'}, - collection_actions={'tenant': 'GET'})] + collection_actions={'tenant': 'GET', + 'project': 'GET'})] def get_extended_resources(self, version): return EXTENDED_ATTRIBUTES_2_0 if version == "2.0" else {} diff --git a/neutron/plugins/ml2/plugin.py b/neutron/plugins/ml2/plugin.py index ab7d56c7cae..5d82b36fc47 100644 --- a/neutron/plugins/ml2/plugin.py +++ b/neutron/plugins/ml2/plugin.py @@ -1051,7 +1051,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2, def _create_network_db(self, context, network): net_data = network[net_def.RESOURCE_NAME] - tenant_id = net_data['tenant_id'] + # TODO(ralonsoh): "tenant_id" reference should be removed. + tenant_id = net_data.get('project_id') or net_data['tenant_id'] with db_api.CONTEXT_WRITER.using(context): net_db = self.create_network_db(context, network) net_data['id'] = net_db.id diff --git a/neutron/quota/resource.py b/neutron/quota/resource.py index 79c1ca21f46..ca45dabe6dd 100644 --- a/neutron/quota/resource.py +++ b/neutron/quota/resource.py @@ -30,7 +30,7 @@ from neutron.db.quota import api as quota_api LOG = log.getLogger(__name__) -def _count_resource(context, collection_name, tenant_id): +def _count_resource(context, collection_name, project_id): count_getter_name = "get_%s_count" % collection_name getter_name = "get_%s" % collection_name @@ -45,12 +45,12 @@ def _count_resource(context, collection_name, tenant_id): try: obj_count_getter = getattr(plugins[pname], count_getter_name) return obj_count_getter( - context, filters={'tenant_id': [tenant_id]}) + context, filters={'project_id': [project_id]}) except (NotImplementedError, AttributeError): try: obj_getter = getattr(plugins[pname], getter_name) obj_list = obj_getter( - context, filters={'tenant_id': [tenant_id]}) + context, filters={'project_id': [project_id]}) return len(obj_list) if obj_list else 0 except (NotImplementedError, AttributeError): pass @@ -172,7 +172,7 @@ class TrackedResource(BaseResource): usage data are employed when performing quota checks. This class operates under the assumption that the model class - describing the resource has a tenant identifier attribute. + describing the resource has a project identifier attribute. :param name: The name of the resource, i.e., "networks". :param model_class: The sqlalchemy model class of the resource for @@ -191,11 +191,11 @@ class TrackedResource(BaseResource): super(TrackedResource, self).__init__( name, flag=flag, plural_name=plural_name) # Register events for addition/removal of records in the model class - # As tenant_id is immutable for all Neutron objects there is no need + # As project_id is immutable for all Neutron objects there is no need # to register a listener for update events self._model_class = model_class - self._dirty_tenants = set() - self._out_of_sync_tenants = set() + self._dirty_projects = set() + self._out_of_sync_projects = set() # NOTE(ralonsoh): "DbQuotaNoLockDriver" driver does not need to track # the DB events or resync the resource quota usage. if cfg.CONF.QUOTAS.quota_driver == quota_conf.QUOTA_DB_DRIVER: @@ -207,78 +207,78 @@ class TrackedResource(BaseResource): def dirty(self): if not self._track_resource_events: return - return self._dirty_tenants + return self._dirty_projects def mark_dirty(self, context): - if not self._dirty_tenants or not self._track_resource_events: + if not self._dirty_projects or not self._track_resource_events: return with db_api.CONTEXT_WRITER.using(context): # It is not necessary to protect this operation with a lock. # Indeed when this method is called the request has been processed # and therefore all resources created or deleted. - # dirty_tenants will contain all the tenants for which the - # resource count is changed. The list might contain also tenants + # dirty_projects will contain all the projects for which the + # resource count is changed. The list might contain also projects # for which resource count was altered in other requests, but this # won't be harmful. - dirty_tenants_snap = self._dirty_tenants.copy() - for tenant_id in dirty_tenants_snap: - quota_api.set_quota_usage_dirty(context, self.name, tenant_id) - self._out_of_sync_tenants |= dirty_tenants_snap - self._dirty_tenants -= dirty_tenants_snap + dirty_projects_snap = self._dirty_projects.copy() + for project_id in dirty_projects_snap: + quota_api.set_quota_usage_dirty(context, self.name, project_id) + self._out_of_sync_projects |= dirty_projects_snap + self._dirty_projects -= dirty_projects_snap def _db_event_handler(self, mapper, _conn, target): try: - tenant_id = target['tenant_id'] + project_id = target['project_id'] except AttributeError: with excutils.save_and_reraise_exception(): - LOG.error("Model class %s does not have a tenant_id " + LOG.error("Model class %s does not have a project_id " "attribute", target) - self._dirty_tenants.add(tenant_id) + self._dirty_projects.add(project_id) # Retry the operation if a duplicate entry exception is raised. This # can happen is two or more workers are trying to create a resource of a - # give kind for the same tenant concurrently. Retrying the operation will + # give kind for the same project concurrently. Retrying the operation will # ensure that an UPDATE statement is emitted rather than an INSERT one @db_api.retry_if_session_inactive() - def _set_quota_usage(self, context, tenant_id, in_use): + def _set_quota_usage(self, context, project_id, in_use): return quota_api.set_quota_usage( - context, self.name, tenant_id, in_use=in_use) + context, self.name, project_id, in_use=in_use) - def _resync(self, context, tenant_id, in_use): + def _resync(self, context, project_id, in_use): # Update quota usage - usage_info = self._set_quota_usage(context, tenant_id, in_use) + usage_info = self._set_quota_usage(context, project_id, in_use) - self._dirty_tenants.discard(tenant_id) - self._out_of_sync_tenants.discard(tenant_id) - LOG.debug(("Unset dirty status for tenant:%(tenant_id)s on " + self._dirty_projects.discard(project_id) + self._out_of_sync_projects.discard(project_id) + LOG.debug(("Unset dirty status for project:%(project_id)s on " "resource:%(resource)s"), - {'tenant_id': tenant_id, 'resource': self.name}) + {'project_id': project_id, 'resource': self.name}) return usage_info - def resync(self, context, tenant_id): - if (tenant_id not in self._out_of_sync_tenants or + def resync(self, context, project_id): + if (project_id not in self._out_of_sync_projects or not self._track_resource_events): return - LOG.debug(("Synchronizing usage tracker for tenant:%(tenant_id)s on " + LOG.debug(("Synchronizing usage tracker for project:%(project_id)s on " "resource:%(resource)s"), - {'tenant_id': tenant_id, 'resource': self.name}) + {'project_id': project_id, 'resource': self.name}) in_use = context.session.query( - self._model_class.tenant_id).filter_by( - tenant_id=tenant_id).count() + self._model_class.project_id).filter_by( + project_id=project_id).count() # Update quota usage - return self._resync(context, tenant_id, in_use) + return self._resync(context, project_id, in_use) - def count_used(self, context, tenant_id, resync_usage=True): + def count_used(self, context, project_id, resync_usage=True): """Returns the current usage count for the resource. :param context: The request context. - :param tenant_id: The ID of the tenant + :param project_id: The ID of the project :param resync_usage: Default value is set to True. Syncs with in_use usage. """ # Load current usage data, setting a row-level lock on the DB - usage_info = quota_api.get_quota_usage_by_resource_and_tenant( - context, self.name, tenant_id) + usage_info = quota_api.get_quota_usage_by_resource_and_project( + context, self.name, project_id) # If dirty or missing, calculate actual resource usage querying # the database and set/create usage info data @@ -286,27 +286,28 @@ class TrackedResource(BaseResource): # assumption is generally valid, but if the database is tampered with, # or if data migrations do not take care of usage counters, the # assumption will not hold anymore - if (tenant_id in self._dirty_tenants or + if (project_id in self._dirty_projects or not usage_info or usage_info.dirty): - LOG.debug(("Usage tracker for resource:%(resource)s and tenant:" - "%(tenant_id)s is out of sync, need to count used " + LOG.debug(("Usage tracker for resource:%(resource)s and project:" + "%(project_id)s is out of sync, need to count used " "quota"), {'resource': self.name, - 'tenant_id': tenant_id}) + 'project_id': project_id}) in_use = context.session.query( - self._model_class.tenant_id).filter_by( - tenant_id=tenant_id).count() + self._model_class.project_id).filter_by( + project_id=project_id).count() # Update quota usage, if requested (by default do not do that, as # typically one counts before adding a record, and that would mark # the usage counter as dirty again) if resync_usage: - usage_info = self._resync(context, tenant_id, in_use) + usage_info = self._resync(context, project_id, in_use) else: resource = usage_info.resource if usage_info else self.name - tenant_id = usage_info.tenant_id if usage_info else tenant_id + project_id = (usage_info.project_id if usage_info else + project_id) dirty = usage_info.dirty if usage_info else True usage_info = quota_api.QuotaUsageInfo( - resource, tenant_id, in_use, dirty) + resource, project_id, in_use, dirty) LOG.debug(("Quota usage for %(resource)s was recalculated. " "Used quota:%(used)d."), @@ -314,16 +315,16 @@ class TrackedResource(BaseResource): 'used': usage_info.used}) return usage_info.used - def count_reserved(self, context, tenant_id): + def count_reserved(self, context, project_id): """Return the current reservation count for the resource.""" # NOTE(princenana) Current implementation of reservations # is ephemeral and returns the default value reservations = quota_api.get_reservations_for_resources( - context, tenant_id, [self.name]) + context, project_id, [self.name]) reserved = reservations.get(self.name, 0) return reserved - def count(self, context, _plugin, tenant_id, resync_usage=True, + def count(self, context, _plugin, project_id, resync_usage=True, count_db_registers=False): """Return the count of the resource. @@ -332,11 +333,11 @@ class TrackedResource(BaseResource): CountableResource instances. """ if count_db_registers: - count = self._count_db_registers(context, tenant_id) + count = self._count_db_registers(context, project_id) else: - count = self.count_used(context, tenant_id, resync_usage) + count = self.count_used(context, project_id, resync_usage) - return count + self.count_reserved(context, tenant_id) + return count + self.count_reserved(context, project_id) def _count_db_registers(self, context, project_id): """Return the existing resources (self._model_class) in a project. diff --git a/neutron/tests/functional/pecan_wsgi/test_controllers.py b/neutron/tests/functional/pecan_wsgi/test_controllers.py index c77e6c870d8..8d8ad1657ce 100644 --- a/neutron/tests/functional/pecan_wsgi/test_controllers.py +++ b/neutron/tests/functional/pecan_wsgi/test_controllers.py @@ -192,7 +192,7 @@ class TestQuotasController(test_functional.PecanFunctionalTest): def test_index_admin(self): # NOTE(salv-orlando): The quota controller has an hardcoded check for # admin-ness for this operation, which is supposed to return quotas for - # all tenants. Such check is "vestigial" from the home-grown WSGI and + # all projects. Such check is "vestigial" from the home-grown WSGI and # shall be removed response = self.app.get('%s.json' % self.base_url, headers={'X-Project-Id': 'admin', @@ -213,7 +213,7 @@ class TestQuotasController(test_functional.PecanFunctionalTest): self._verify_default_limits(json_body) def test_get(self): - # It is not ok to access another tenant's limits + # It is not ok to access another project's limits url = '%s/foo.json' % self.base_url response = self.app.get(url, expect_errors=True) self.assertEqual(403, response.status_int) @@ -269,7 +269,7 @@ class TestQuotasController(test_functional.PecanFunctionalTest): json_body = jsonutils.loads(response.body) found = False for qs in json_body['quotas']: - if qs['tenant_id'] == 'foo': + if qs['project_id'] == 'foo': found = True self.assertTrue(found) @@ -283,7 +283,7 @@ class TestQuotasController(test_functional.PecanFunctionalTest): self.assertEqual(200, response.status_int) json_body = jsonutils.loads(response.body) for qs in json_body['quotas']: - self.assertNotEqual('foo', qs['tenant_id']) + self.assertNotEqual('foo', qs['project_id']) def test_quotas_get_defaults(self): response = self.app.get('%s/foo/default.json' % self.base_url, @@ -294,13 +294,14 @@ class TestQuotasController(test_functional.PecanFunctionalTest): json_body = jsonutils.loads(response.body) self._verify_default_limits(json_body) - def test_get_tenant_info(self): - response = self.app.get('%s/tenant.json' % self.base_url, - headers={'X-Project-Id': 'admin', - 'X-Roles': 'admin'}) - self.assertEqual(200, response.status_int) - json_body = jsonutils.loads(response.body) - self.assertEqual('admin', json_body['tenant']['tenant_id']) + def test_get_project_info(self): + for key in ('project', 'tenant'): + response = self.app.get('%s/%s.json' % (self.base_url, key), + headers={'X-Project-Id': 'admin', + 'X-Roles': 'admin'}) + self.assertEqual(200, response.status_int) + json_body = jsonutils.loads(response.body) + self.assertEqual('admin', json_body[key][key + '_id']) class TestResourceController(TestRootController): @@ -318,11 +319,11 @@ class TestResourceController(TestRootController): def _gen_port(self): network_id = self.plugin.create_network(context.get_admin_context(), { 'network': - {'name': 'pecannet', 'tenant_id': 'tenid', 'shared': False, + {'name': 'pecannet', 'project_id': 'tenid', 'shared': False, 'admin_state_up': True, 'status': 'ACTIVE'}})['id'] self.port = self.plugin.create_port(context.get_admin_context(), { 'port': - {'tenant_id': 'tenid', 'network_id': network_id, + {'project_id': 'tenid', 'network_id': network_id, 'fixed_ips': n_const.ATTR_NOT_SPECIFIED, 'mac_address': '00:11:22:33:44:55', 'admin_state_up': True, 'device_id': 'FF', @@ -364,7 +365,7 @@ class TestResourceController(TestRootController): self._test_get_collection_with_fields_selector(fields=[]) def test_project_id_in_mandatory_fields(self): - # ports only specifies that tenant_id is mandatory, but project_id + # ports only specifies that project_id is mandatory, but project_id # should still be passed to the plugin. mock_get = mock.patch.object(self.plugin, 'get_ports', return_value=[]).start() @@ -384,10 +385,10 @@ class TestResourceController(TestRootController): # Explicitly require an attribute which is also 'required_by_policy'. # The attribute should not be stripped while generating the response item_resp = self.app.get( - '/v2.0/ports/%s.json?fields=id&fields=tenant_id' % self.port['id'], - headers={'X-Project-Id': 'tenid'}) + '/v2.0/ports/%s.json?fields=id&fields=project_id' % + self.port['id'], headers={'X-Project-Id': 'tenid'}) self.assertEqual(200, item_resp.status_int) - self._check_item(['id', 'tenant_id'], + self._check_item(['id', 'project_id'], jsonutils.loads(item_resp.body)['port']) def test_duped_and_empty_fields_stripped(self): @@ -406,7 +407,7 @@ class TestResourceController(TestRootController): '/v2.0/ports.json', params={'port': {'network_id': self.port['network_id'], 'admin_state_up': True, - 'tenant_id': 'tenid'}}, + 'project_id': 'tenid'}}, headers={'X-Project-Id': 'tenid'}) self.assertEqual(response.status_int, 201) @@ -426,7 +427,7 @@ class TestResourceController(TestRootController): '/v2.0/ports.json', params={'port': {'network_id': self.port['network_id'], 'admin_state_up': True, - 'tenant_id': 'tenid'}}, + 'project_id': 'tenid'}}, headers={'X-Project-Id': 'tenid'}) self.assertEqual(201, response.status_int) @@ -439,7 +440,7 @@ class TestResourceController(TestRootController): self.assertEqual(1, len(json_body)) self.assertIn('port', json_body) self.assertEqual('test', json_body['port']['name']) - self.assertEqual('tenid', json_body['port']['tenant_id']) + self.assertEqual('tenid', json_body['port']['project_id']) def test_delete(self): response = self.app.delete('/v2.0/ports/%s.json' % self.port['id'], @@ -487,10 +488,10 @@ class TestResourceController(TestRootController): '/v2.0/ports.json', params={'ports': [{'network_id': self.port['network_id'], 'admin_state_up': True, - 'tenant_id': 'tenid'}, + 'project_id': 'tenid'}, {'network_id': self.port['network_id'], 'admin_state_up': True, - 'tenant_id': 'tenid'}] + 'project_id': 'tenid'}] }, headers={'X-Project-Id': 'tenid'}) self.assertEqual(201, response.status_int) @@ -518,11 +519,11 @@ class TestResourceController(TestRootController): params={'ports': [{'network_id': self.port['network_id'], 'admin_state_up': True, 'security_groups': [sg_id], - 'tenant_id': 'tenid'}, + 'project_id': 'tenid'}, {'network_id': self.port['network_id'], 'admin_state_up': True, 'security_groups': [sg_id], - 'tenant_id': 'tenid'}] + 'project_id': 'tenid'}] }, headers={'X-Project-Id': 'tenid'}) self.assertEqual(201, port_response.status_int) @@ -539,10 +540,10 @@ class TestResourceController(TestRootController): '/v2.0/ports.json', params={'ports': [{'network_id': self.port['network_id'], 'admin_state_up': True, - 'tenant_id': 'tenid'}, + 'project_id': 'tenid'}, {'network_id': self.port['network_id'], 'admin_state_up': True, - 'tenant_id': 'tenid'}] + 'project_id': 'tenid'}] }, headers={'X-Project-Id': 'tenid'}) self.assertEqual(response.status_int, 201) @@ -556,13 +557,13 @@ class TestResourceController(TestRootController): '/v2.0/ports.json', params={'ports': [{'network_id': self.port['network_id'], 'admin_state_up': True, - 'tenant_id': 'tenid'}, + 'project_id': 'tenid'}, {'network_id': self.port['network_id'], 'admin_state_up': True, - 'tenant_id': 'tenid'}, + 'project_id': 'tenid'}, {'network_id': 'bad_net_id', 'admin_state_up': True, - 'tenant_id': 'tenid'}] + 'project_id': 'tenid'}] }, headers={'X-Project-Id': 'tenid'}, expect_errors=True) @@ -579,7 +580,7 @@ class TestResourceController(TestRootController): '/v2.0/ports.json', params={'ports': [{'network_id': self.port['network_id'], 'admin_state_up': True, - 'tenant_id': 'tenid'}] + 'project_id': 'tenid'}] }, headers={'X-Project-Id': 'tenid'}) self.assertEqual(response.status_int, 201) @@ -598,13 +599,15 @@ class TestPaginationAndSorting(test_functional.PecanFunctionalTest): self.addCleanup(policy.reset) self.plugin = directory.get_plugin() self.ctx = context.get_admin_context() + self._project_id = 'project_id1' self._create_networks(self.RESOURCE_COUNT) self.networks = self._get_collection()['networks'] def _create_networks(self, count=1): network_ids = [] for index in range(count): - network = {'name': 'pecannet-%d' % index, 'tenant_id': 'tenid', + network = {'name': 'pecannet-%d' % index, + 'project_id': self._project_id, 'shared': False, 'admin_state_up': True, 'status': 'ACTIVE'} network_id = self.plugin.create_network( @@ -632,7 +635,8 @@ class TestPaginationAndSorting(test_functional.PecanFunctionalTest): url = '/v2.0/%s.json' % collection if query_params: url = '%s?%s' % (url, '&'.join(query_params)) - list_resp = self.app.get(url, headers={'X-Project-Id': 'tenid'}) + list_resp = self.app.get(url, + headers={'X-Project-Id': self._project_id}) self.assertEqual(200, list_resp.status_int) return list_resp.json @@ -735,9 +739,9 @@ class TestRequestProcessing(TestRootController): def test_context_set_in_request(self): self.app.get('/v2.0/ports.json', - headers={'X-Project-Id': 'tenant_id'}) - self.assertEqual('tenant_id', - self.captured_context['neutron_context'].tenant_id) + headers={'X-Project-Id': 'project_id'}) + self.assertEqual('project_id', + self.captured_context['neutron_context'].project_id) def test_core_resource_identified(self): self.app.get('/v2.0/ports.json') @@ -1169,4 +1173,3 @@ class TestExcludeAttributePolicy(test_functional.PecanFunctionalTest): json_body = jsonutils.loads(response.body) self.assertEqual(response.status_int, 200) self.assertEqual('tenid', json_body['network']['project_id']) - self.assertEqual('tenid', json_body['network']['tenant_id']) diff --git a/neutron/tests/unit/db/quota/test_api.py b/neutron/tests/unit/db/quota/test_api.py index eb4550490f1..6ffbf1c57d5 100644 --- a/neutron/tests/unit/db/quota/test_api.py +++ b/neutron/tests/unit/db/quota/test_api.py @@ -31,26 +31,26 @@ DB_PLUGIN_KLASS = 'neutron.db.db_base_plugin_v2.NeutronDbPluginV2' class TestQuotaDbApi(testlib_api.SqlTestCaseLight): def _set_context(self): - self.tenant_id = 'Higuain' - self.context = context.Context('Gonzalo', self.tenant_id, + self.project_id = 'Higuain' + self.context = context.Context('Gonzalo', self.project_id, is_admin=False, is_advsvc=False) def _create_reservation(self, resource_deltas, - tenant_id=None, expiration=None): - tenant_id = tenant_id or self.tenant_id + project_id=None, expiration=None): + project_id = project_id or self.project_id return quota_api.create_reservation( - self.context, tenant_id, resource_deltas, expiration) + self.context, project_id, resource_deltas, expiration) - def _create_quota_usage(self, resource, used, tenant_id=None): - tenant_id = tenant_id or self.tenant_id + def _create_quota_usage(self, resource, used, project_id=None): + project_id = project_id or self.project_id return quota_api.set_quota_usage(context.get_admin_context(), - resource, tenant_id, in_use=used) + resource, project_id, in_use=used) def _verify_quota_usage(self, usage_info, expected_resource=None, expected_used=None, expected_dirty=None): - self.assertEqual(self.tenant_id, usage_info.tenant_id) + self.assertEqual(self.project_id, usage_info.project_id) if expected_resource: self.assertEqual(expected_resource, usage_info.resource) if expected_dirty is not None: @@ -75,12 +75,12 @@ class TestQuotaDbApi(testlib_api.SqlTestCaseLight): self._create_quota_usage('goals', 26) # Higuain scores a double usage_info_1 = quota_api.set_quota_usage( - self.context, 'goals', self.tenant_id, + self.context, 'goals', self.project_id, in_use=28) self._verify_quota_usage(usage_info_1, expected_used=28) usage_info_2 = quota_api.set_quota_usage( - self.context, 'goals', self.tenant_id, + self.context, 'goals', self.project_id, in_use=24) self._verify_quota_usage(usage_info_2, expected_used=24) @@ -89,7 +89,7 @@ class TestQuotaDbApi(testlib_api.SqlTestCaseLight): self._create_quota_usage('goals', 26) # Higuain scores a double usage_info_1 = quota_api.set_quota_usage( - self.context, 'goals', self.tenant_id, + self.context, 'goals', self.project_id, in_use=2, delta=True) self._verify_quota_usage(usage_info_1, expected_used=28) @@ -98,35 +98,36 @@ class TestQuotaDbApi(testlib_api.SqlTestCaseLight): self._create_quota_usage('goals', 26) # Higuain needs a shower after the match self.assertEqual(1, quota_api.set_quota_usage_dirty( - self.context, 'goals', self.tenant_id)) - usage_info = quota_api.get_quota_usage_by_resource_and_tenant( - self.context, 'goals', self.tenant_id) + self.context, 'goals', self.project_id)) + usage_info = quota_api.get_quota_usage_by_resource_and_project( + self.context, 'goals', self.project_id) self._verify_quota_usage(usage_info, expected_dirty=True) # Higuain is clean now self.assertEqual(1, quota_api.set_quota_usage_dirty( - self.context, 'goals', self.tenant_id, dirty=False)) - usage_info = quota_api.get_quota_usage_by_resource_and_tenant( - self.context, 'goals', self.tenant_id) + self.context, 'goals', self.project_id, dirty=False)) + usage_info = quota_api.get_quota_usage_by_resource_and_project( + self.context, 'goals', self.project_id) self._verify_quota_usage(usage_info, expected_dirty=False) def test_set_dirty_non_existing_quota_usage(self): self.assertEqual(0, quota_api.set_quota_usage_dirty( - self.context, 'meh', self.tenant_id)) + self.context, 'meh', self.project_id)) def test_set_resources_quota_usage_dirty(self): self._create_quota_usage('goals', 26) self._create_quota_usage('assists', 11) self._create_quota_usage('bookings', 3) self.assertEqual(2, quota_api.set_resources_quota_usage_dirty( - self.context, ['goals', 'bookings'], self.tenant_id)) - usage_info_goals = quota_api.get_quota_usage_by_resource_and_tenant( - self.context, 'goals', self.tenant_id) - usage_info_assists = quota_api.get_quota_usage_by_resource_and_tenant( - self.context, 'assists', self.tenant_id) - usage_info_bookings = quota_api.get_quota_usage_by_resource_and_tenant( - self.context, 'bookings', self.tenant_id) + self.context, ['goals', 'bookings'], self.project_id)) + usage_info_goals = quota_api.get_quota_usage_by_resource_and_project( + self.context, 'goals', self.project_id) + usage_info_assists = quota_api.get_quota_usage_by_resource_and_project( + self.context, 'assists', self.project_id) + usage_info_bookings = ( + quota_api.get_quota_usage_by_resource_and_project( + self.context, 'bookings', self.project_id)) self._verify_quota_usage(usage_info_goals, expected_dirty=True) self._verify_quota_usage(usage_info_assists, expected_dirty=False) self._verify_quota_usage(usage_info_bookings, expected_dirty=True) @@ -135,30 +136,31 @@ class TestQuotaDbApi(testlib_api.SqlTestCaseLight): self._create_quota_usage('goals', 26) self._create_quota_usage('assists', 11) self._create_quota_usage('bookings', 3) - # Expect all the resources for the tenant to be set dirty + # Expect all the resources for the project to be set dirty self.assertEqual(3, quota_api.set_resources_quota_usage_dirty( - self.context, [], self.tenant_id)) - usage_info_goals = quota_api.get_quota_usage_by_resource_and_tenant( - self.context, 'goals', self.tenant_id) - usage_info_assists = quota_api.get_quota_usage_by_resource_and_tenant( - self.context, 'assists', self.tenant_id) - usage_info_bookings = quota_api.get_quota_usage_by_resource_and_tenant( - self.context, 'bookings', self.tenant_id) + self.context, [], self.project_id)) + usage_info_goals = quota_api.get_quota_usage_by_resource_and_project( + self.context, 'goals', self.project_id) + usage_info_assists = quota_api.get_quota_usage_by_resource_and_project( + self.context, 'assists', self.project_id) + usage_info_bookings = ( + quota_api.get_quota_usage_by_resource_and_project( + self.context, 'bookings', self.project_id)) self._verify_quota_usage(usage_info_goals, expected_dirty=True) self._verify_quota_usage(usage_info_assists, expected_dirty=True) self._verify_quota_usage(usage_info_bookings, expected_dirty=True) # Higuain is clean now self.assertEqual(1, quota_api.set_quota_usage_dirty( - self.context, 'goals', self.tenant_id, dirty=False)) - usage_info = quota_api.get_quota_usage_by_resource_and_tenant( - self.context, 'goals', self.tenant_id) + self.context, 'goals', self.project_id, dirty=False)) + usage_info = quota_api.get_quota_usage_by_resource_and_project( + self.context, 'goals', self.project_id) self._verify_quota_usage(usage_info, expected_dirty=False) def _test_set_all_quota_usage_dirty(self, expected): self._create_quota_usage('goals', 26) - self._create_quota_usage('goals', 12, tenant_id='Callejon') + self._create_quota_usage('goals', 12, project_id='Callejon') self.assertEqual(expected, quota_api.set_all_quota_usage_dirty( self.context, 'goals')) @@ -167,13 +169,13 @@ class TestQuotaDbApi(testlib_api.SqlTestCaseLight): # admin context we can clean only one self._test_set_all_quota_usage_dirty(expected=1) - def test_get_quota_usage_by_tenant(self): + def test_get_quota_usage_by_project(self): self._create_quota_usage('goals', 26) self._create_quota_usage('assists', 11) - # Create a resource for a different tenant - self._create_quota_usage('mehs', 99, tenant_id='buffon') - usage_infos = quota_api.get_quota_usage_by_tenant_id( - self.context, self.tenant_id) + # Create a resource for a different project + self._create_quota_usage('mehs', 99, project_id='buffon') + usage_infos = quota_api.get_quota_usage_by_project_id( + self.context, self.project_id) self.assertEqual(2, len(usage_infos)) resources = [info.resource for info in usage_infos] @@ -183,26 +185,26 @@ class TestQuotaDbApi(testlib_api.SqlTestCaseLight): def test_get_quota_usage_by_resource(self): self._create_quota_usage('goals', 26) self._create_quota_usage('assists', 11) - self._create_quota_usage('goals', 12, tenant_id='Callejon') + self._create_quota_usage('goals', 12, project_id='Callejon') usage_infos = quota_api.get_quota_usage_by_resource( self.context, 'goals') - # Only 1 result expected in tenant context + # Only 1 result expected in project context self.assertEqual(1, len(usage_infos)) self._verify_quota_usage(usage_infos[0], expected_resource='goals', expected_used=26) - def test_get_quota_usage_by_tenant_and_resource(self): + def test_get_quota_usage_by_project_and_resource(self): self._create_quota_usage('goals', 26) - usage_info = quota_api.get_quota_usage_by_resource_and_tenant( - self.context, 'goals', self.tenant_id) + usage_info = quota_api.get_quota_usage_by_resource_and_project( + self.context, 'goals', self.project_id) self._verify_quota_usage(usage_info, expected_resource='goals', expected_used=26) def test_get_non_existing_quota_usage_returns_none(self): - self.assertIsNone(quota_api.get_quota_usage_by_resource_and_tenant( - self.context, 'goals', self.tenant_id)) + self.assertIsNone(quota_api.get_quota_usage_by_resource_and_project( + self.context, 'goals', self.project_id)) def _verify_reserved_resources(self, expected, actual): for (resource, delta) in actual.items(): @@ -214,14 +216,14 @@ class TestQuotaDbApi(testlib_api.SqlTestCaseLight): def test_create_reservation(self): resources = {'goals': 2, 'assists': 1} resv = self._create_reservation(resources) - self.assertEqual(self.tenant_id, resv.tenant_id) + self.assertEqual(self.project_id, resv.project_id) self._verify_reserved_resources(resources, resv.deltas) def test_create_reservation_with_expiration(self): resources = {'goals': 2, 'assists': 1} exp_date = datetime.datetime(2016, 3, 31, 14, 30) resv = self._create_reservation(resources, expiration=exp_date) - self.assertEqual(self.tenant_id, resv.tenant_id) + self.assertEqual(self.project_id, resv.project_id) self.assertEqual(exp_date, resv.expiration) self._verify_reserved_resources(resources, resv.deltas) @@ -245,7 +247,8 @@ class TestQuotaDbApi(testlib_api.SqlTestCaseLight): mock_utcnow.return_value = datetime.datetime( 2015, 5, 20, 0, 0) deltas = quota_api.get_reservations_for_resources( - self.context, self.tenant_id, ['goals', 'assists', 'bookings']) + self.context, self.project_id, + ['goals', 'assists', 'bookings']) self.assertIn('goals', deltas) self.assertEqual(5, deltas['goals']) self.assertIn('assists', deltas) @@ -260,7 +263,7 @@ class TestQuotaDbApi(testlib_api.SqlTestCaseLight): 2015, 5, 20, 0, 0) self._get_reservations_for_resource_helper() deltas = quota_api.get_reservations_for_resources( - self.context, self.tenant_id, + self.context, self.project_id, ['goals', 'assists', 'bookings'], expired=True) self.assertIn('assists', deltas) @@ -271,7 +274,7 @@ class TestQuotaDbApi(testlib_api.SqlTestCaseLight): def test_get_reservation_for_resources_with_empty_list(self): self.assertIsNone(quota_api.get_reservations_for_resources( - self.context, self.tenant_id, [])) + self.context, self.project_id, [])) def test_remove_expired_reservations(self): with mock.patch('neutron.db.quota.api.utcnow') as mock_utcnow: @@ -283,13 +286,13 @@ class TestQuotaDbApi(testlib_api.SqlTestCaseLight): exp_date_2 = datetime.datetime(2015, 3, 31, 14, 30) resv_2 = self._create_reservation(resources, expiration=exp_date_2) self.assertEqual(1, quota_api.remove_expired_reservations( - self.context, self.tenant_id)) + self.context, self.project_id)) self.assertIsNone(quota_api.get_reservation( self.context, resv_2.reservation_id)) self.assertIsNotNone(quota_api.get_reservation( self.context, resv_1.reservation_id)) - def test_remove_expired_reservations_no_tenant(self): + def test_remove_expired_reservations_no_project(self): with mock.patch('neutron.db.quota.api.utcnow') as mock_utcnow: mock_utcnow.return_value = datetime.datetime( 2015, 5, 20, 0, 0) @@ -299,7 +302,7 @@ class TestQuotaDbApi(testlib_api.SqlTestCaseLight): exp_date_2 = datetime.datetime(2015, 3, 31, 14, 30) resv_2 = self._create_reservation(resources, expiration=exp_date_2, - tenant_id='Callejon') + project_id='Callejon') self.assertEqual(2, quota_api.remove_expired_reservations( context.get_admin_context())) self.assertIsNone(quota_api.get_reservation( @@ -311,14 +314,14 @@ class TestQuotaDbApi(testlib_api.SqlTestCaseLight): class TestQuotaDbApiAdminContext(TestQuotaDbApi): def _set_context(self): - self.tenant_id = 'Higuain' - self.context = context.Context('Gonzalo', self.tenant_id, + self.project_id = 'Higuain' + self.context = context.Context('Gonzalo', self.project_id, is_admin=True, is_advsvc=True) def test_get_quota_usage_by_resource(self): self._create_quota_usage('goals', 26) self._create_quota_usage('assists', 11) - self._create_quota_usage('goals', 12, tenant_id='Callejon') + self._create_quota_usage('goals', 12, project_id='Callejon') usage_infos = quota_api.get_quota_usage_by_resource( self.context, 'goals') # 2 results expected in admin context diff --git a/neutron/tests/unit/db/quota/test_driver.py b/neutron/tests/unit/db/quota/test_driver.py index 50126eaef5c..c2e5ea0b7a0 100644 --- a/neutron/tests/unit/db/quota/test_driver.py +++ b/neutron/tests/unit/db/quota/test_driver.py @@ -28,7 +28,7 @@ from neutron.tests.unit import testlib_api DB_PLUGIN_KLASS = 'neutron.db.db_base_plugin_v2.NeutronDbPluginV2' -def _count_resource(context, resource, tenant_id): +def _count_resource(context, resource, project_id): """A fake counting function to determine current used counts""" if resource[-1] == 's': resource = resource[:-1] @@ -97,7 +97,8 @@ class TestDbQuotaDriver(testlib_api.SqlTestCase, defaults = {RESOURCE: TestResource(RESOURCE, 4)} self.plugin.update_quota_limit(self.context, PROJECT, RESOURCE, 2) - quotas = self.plugin.get_tenant_quotas(self.context, defaults, PROJECT) + quotas = self.plugin.get_project_quotas(self.context, defaults, + PROJECT) self.assertEqual(2, quotas[RESOURCE]) def test_update_quota_limit(self): @@ -105,15 +106,17 @@ class TestDbQuotaDriver(testlib_api.SqlTestCase, self.plugin.update_quota_limit(self.context, PROJECT, RESOURCE, 2) self.plugin.update_quota_limit(self.context, PROJECT, RESOURCE, 3) - quotas = self.plugin.get_tenant_quotas(self.context, defaults, PROJECT) + quotas = self.plugin.get_project_quotas(self.context, defaults, + PROJECT) self.assertEqual(3, quotas[RESOURCE]) - def test_delete_tenant_quota_restores_default_limit(self): + def test_delete_project_quota_restores_default_limit(self): defaults = {RESOURCE: TestResource(RESOURCE, 4)} self.plugin.update_quota_limit(self.context, PROJECT, RESOURCE, 2) - self.plugin.delete_tenant_quota(self.context, PROJECT) - quotas = self.plugin.get_tenant_quotas(self.context, defaults, PROJECT) + self.plugin.delete_project_quota(self.context, PROJECT) + quotas = self.plugin.get_project_quotas(self.context, defaults, + PROJECT) self.assertEqual(4, quotas[RESOURCE]) def test_get_default_quotas(self): @@ -123,20 +126,20 @@ class TestDbQuotaDriver(testlib_api.SqlTestCase, quotas = self.plugin.get_default_quotas(user_ctx, defaults, PROJECT) self.assertEqual(4, quotas[RESOURCE]) - def test_get_tenant_quotas(self): + def test_get_project_quotas(self): user_ctx = context.Context(user_id=PROJECT, tenant_id=PROJECT) self.plugin.update_quota_limit(self.context, PROJECT, RESOURCE, 2) - quotas = self.plugin.get_tenant_quotas(user_ctx, {}, PROJECT) + quotas = self.plugin.get_project_quotas(user_ctx, {}, PROJECT) self.assertEqual(2, quotas[RESOURCE]) - def test_get_tenant_quotas_different_tenant(self): + def test_get_project_quotas_different_project(self): user_ctx = context.Context(user_id=PROJECT, tenant_id='another_project') self.plugin.update_quota_limit(self.context, PROJECT, RESOURCE, 2) # It is appropriate to use assertFalse here as the expected return # value is an empty dict (the defaults passed in the statement below # after the request context) - self.assertFalse(self.plugin.get_tenant_quotas(user_ctx, {}, PROJECT)) + self.assertFalse(self.plugin.get_project_quotas(user_ctx, {}, PROJECT)) def test_get_all_quotas(self): project_1 = 'prj_test_1' @@ -151,14 +154,14 @@ class TestDbQuotaDriver(testlib_api.SqlTestCase, self.plugin.update_quota_limit(self.context, project_2, resource_2, 9) quotas = self.plugin.get_all_quotas(self.context, resources) - # Expect two tenants' quotas + # Expect two projects' quotas self.assertEqual(2, len(quotas)) - # But not quotas for the same tenant twice - self.assertNotEqual(quotas[0]['tenant_id'], quotas[1]['tenant_id']) + # But not quotas for the same project twice + self.assertNotEqual(quotas[0]['project_id'], quotas[1]['project_id']) # Check the expected limits. The quotas can be in any order. for quota in quotas: - project = quota['tenant_id'] + project = quota['project_id'] self.assertIn(project, (project_1, project_2)) if project == project_1: expected_limit_r1 = 7 @@ -208,15 +211,15 @@ class TestDbQuotaDriver(testlib_api.SqlTestCase, self.plugin.update_quota_limit(self.context, PROJECT, resource_name, 2) reservation = quota_driver.make_reservation( self.context, - self.context.tenant_id, + self.context.project_id, resources, deltas, self.plugin) self.assertIn(resource_name, reservation.deltas) self.assertEqual(deltas[resource_name], reservation.deltas[resource_name]) - self.assertEqual(self.context.tenant_id, - reservation.tenant_id) + self.assertEqual(self.context.project_id, + reservation.project_id) def test_make_reservation_single_resource(self): quota_driver = driver.DbQuotaDriver() @@ -237,7 +240,7 @@ class TestDbQuotaDriver(testlib_api.SqlTestCase, self.plugin.update_quota_limit(self.context, PROJECT, ALT_RESOURCE, 2) reservation = quota_driver.make_reservation( self.context, - self.context.tenant_id, + self.context.project_id, resources, deltas, self.plugin) @@ -245,8 +248,8 @@ class TestDbQuotaDriver(testlib_api.SqlTestCase, self.assertIn(ALT_RESOURCE, reservation.deltas) self.assertEqual(1, reservation.deltas[RESOURCE]) self.assertEqual(2, reservation.deltas[ALT_RESOURCE]) - self.assertEqual(self.context.tenant_id, - reservation.tenant_id) + self.assertEqual(self.context.project_id, + reservation.project_id) def test_make_reservation_over_quota_fails(self): quota_driver = driver.DbQuotaDriver() @@ -257,12 +260,12 @@ class TestDbQuotaDriver(testlib_api.SqlTestCase, self.assertRaises(exceptions.OverQuota, quota_driver.make_reservation, self.context, - self.context.tenant_id, + self.context.project_id, resources, deltas, self.plugin) - def test_get_detailed_tenant_quotas_resource(self): + def test_get_detailed_project_quotas_resource(self): res = {RESOURCE: TestTrackedResource(RESOURCE, test_quota.MehModel)} self.plugin.update_quota_limit(self.context, PROJECT, RESOURCE, 6) @@ -270,13 +273,13 @@ class TestDbQuotaDriver(testlib_api.SqlTestCase, quota_driver.make_reservation(self.context, PROJECT, res, {RESOURCE: 1}, self.plugin) quota_api.set_quota_usage(self.context, RESOURCE, PROJECT, 2) - detailed_quota = self.plugin.get_detailed_tenant_quotas(self.context, - res, PROJECT) + detailed_quota = self.plugin.get_detailed_project_quotas( + self.context, res, PROJECT) self.assertEqual(6, detailed_quota[RESOURCE]['limit']) self.assertEqual(2, detailed_quota[RESOURCE]['used']) self.assertEqual(1, detailed_quota[RESOURCE]['reserved']) - def test_get_detailed_tenant_quotas_multiple_resource(self): + def test_get_detailed_project_quotas_multiple_resource(self): project_1 = 'prj_test_1' resource_1 = 'res_test_1' resource_2 = 'res_test_2' @@ -295,9 +298,8 @@ class TestDbQuotaDriver(testlib_api.SqlTestCase, quota_api.set_quota_usage(self.context, resource_1, project_1, 2) quota_api.set_quota_usage(self.context, resource_2, project_1, 3) - detailed_quota = self.plugin.get_detailed_tenant_quotas(self.context, - resources, - project_1) + detailed_quota = self.plugin.get_detailed_project_quotas( + self.context, resources, project_1) self.assertEqual(6, detailed_quota[resource_1]['limit']) self.assertEqual(1, detailed_quota[resource_1]['reserved']) diff --git a/neutron/tests/unit/extensions/test_quotasv2.py b/neutron/tests/unit/extensions/test_quotasv2.py index 881d0cd2115..6ad124a0f6e 100644 --- a/neutron/tests/unit/extensions/test_quotasv2.py +++ b/neutron/tests/unit/extensions/test_quotasv2.py @@ -73,9 +73,9 @@ class QuotaExtensionTestCase(testlib_api.WebTestCase): router.APIRouter() def _test_quota_default_values(self, expected_values): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id)} + res = self.api.get(_get_path('quotas', id=project_id, fmt=self.fmt), extra_environ=env) quota = self.deserialize(res) for resource, expected_value in expected_values.items(): @@ -118,10 +118,10 @@ class QuotaExtensionDbTestCase(QuotaExtensionTestCase): 'extra1': qconf.DEFAULT_QUOTA}) def test_show_default_quotas_with_admin(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id + '2', is_admin=True)} - res = self.api.get(_get_path('quotas', id=tenant_id, + res = self.api.get(_get_path('quotas', id=project_id, action=DEFAULT_QUOTAS_ACTION, fmt=self.fmt), extra_environ=env) @@ -134,11 +134,11 @@ class QuotaExtensionDbTestCase(QuotaExtensionTestCase): self.assertEqual( qconf.DEFAULT_QUOTA_PORT, quota['quota']['port']) - def test_show_default_quotas_with_owner_tenant(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + def test_show_default_quotas_with_owner_project(self): + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=False)} - res = self.api.get(_get_path('quotas', id=tenant_id, + res = self.api.get(_get_path('quotas', id=project_id, action=DEFAULT_QUOTAS_ACTION, fmt=self.fmt), extra_environ=env) @@ -152,20 +152,20 @@ class QuotaExtensionDbTestCase(QuotaExtensionTestCase): qconf.DEFAULT_QUOTA_PORT, quota['quota']['port']) def test_show_default_quotas_without_admin_forbidden_returns_403(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id + '2', is_admin=False)} - res = self.api.get(_get_path('quotas', id=tenant_id, + res = self.api.get(_get_path('quotas', id=project_id, action=DEFAULT_QUOTAS_ACTION, fmt=self.fmt), extra_environ=env, expect_errors=True) self.assertEqual(403, res.status_int) def test_show_quotas_with_admin(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id + '2', is_admin=True)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.get(_get_path('quotas', id=project_id, fmt=self.fmt), extra_environ=env) self.assertEqual(200, res.status_int) quota = self.deserialize(res) @@ -177,18 +177,18 @@ class QuotaExtensionDbTestCase(QuotaExtensionTestCase): qconf.DEFAULT_QUOTA_PORT, quota['quota']['port']) def test_show_quotas_without_admin_forbidden_returns_403(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id + '2', is_admin=False)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.get(_get_path('quotas', id=project_id, fmt=self.fmt), extra_environ=env, expect_errors=True) self.assertEqual(403, res.status_int) - def test_show_quotas_with_owner_tenant(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + def test_show_quotas_with_owner_project(self): + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=False)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.get(_get_path('quotas', id=project_id, fmt=self.fmt), extra_environ=env) self.assertEqual(200, res.status_int) quota = self.deserialize(res) @@ -200,8 +200,8 @@ class QuotaExtensionDbTestCase(QuotaExtensionTestCase): qconf.DEFAULT_QUOTA_PORT, quota['quota']['port']) def test_list_quotas_with_admin(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=True)} res = self.api.get(_get_path('quotas', fmt=self.fmt), extra_environ=env) @@ -210,93 +210,93 @@ class QuotaExtensionDbTestCase(QuotaExtensionTestCase): self.assertEqual([], quota['quotas']) def test_list_quotas_without_admin_forbidden_returns_403(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=False)} res = self.api.get(_get_path('quotas', fmt=self.fmt), extra_environ=env, expect_errors=True) self.assertEqual(403, res.status_int) def test_update_quotas_without_admin_forbidden_returns_403(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=False)} quotas = {'quota': {'network': 100}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.put(_get_path('quotas', id=project_id, fmt=self.fmt), self.serialize(quotas), extra_environ=env, expect_errors=True) self.assertEqual(403, res.status_int) def test_update_quotas_with_non_integer_returns_400(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=True)} quotas = {'quota': {'network': 'abc'}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.put(_get_path('quotas', id=project_id, fmt=self.fmt), self.serialize(quotas), extra_environ=env, expect_errors=True) self.assertEqual(400, res.status_int) def test_update_quotas_with_negative_integer_returns_400(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=True)} quotas = {'quota': {'network': -2}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.put(_get_path('quotas', id=project_id, fmt=self.fmt), self.serialize(quotas), extra_environ=env, expect_errors=True) self.assertEqual(400, res.status_int) def test_update_quotas_with_out_of_range_integer_returns_400(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=True)} quotas = {'quota': {'network': constants.DB_INTEGER_MAX_VALUE + 1}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.put(_get_path('quotas', id=project_id, fmt=self.fmt), self.serialize(quotas), extra_environ=env, expect_errors=True) self.assertEqual(exc.HTTPBadRequest.code, res.status_int) def test_update_quotas_to_unlimited(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=True)} quotas = {'quota': {'network': -1}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.put(_get_path('quotas', id=project_id, fmt=self.fmt), self.serialize(quotas), extra_environ=env, expect_errors=False) self.assertEqual(200, res.status_int) def test_update_quotas_exceeding_current_limit(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=True)} quotas = {'quota': {'network': 120}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.put(_get_path('quotas', id=project_id, fmt=self.fmt), self.serialize(quotas), extra_environ=env, expect_errors=False) self.assertEqual(200, res.status_int) def test_update_quotas_with_non_support_resource_returns_400(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=True)} quotas = {'quota': {'abc': 100}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.put(_get_path('quotas', id=project_id, fmt=self.fmt), self.serialize(quotas), extra_environ=env, expect_errors=True) self.assertEqual(400, res.status_int) def test_update_quotas_with_admin(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id + '2', is_admin=True)} quotas = {'quota': {'network': 100}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.put(_get_path('quotas', id=project_id, fmt=self.fmt), self.serialize(quotas), extra_environ=env) self.assertEqual(200, res.status_int) - env2 = {'neutron.context': context.Context('', tenant_id)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), + env2 = {'neutron.context': context.Context('', project_id)} + res = self.api.get(_get_path('quotas', id=project_id, fmt=self.fmt), extra_environ=env2) quota = self.deserialize(res) self.assertEqual(100, quota['quota']['network']) @@ -304,44 +304,44 @@ class QuotaExtensionDbTestCase(QuotaExtensionTestCase): self.assertEqual(qconf.DEFAULT_QUOTA_PORT, quota['quota']['port']) def test_update_attributes(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id + '2', is_admin=True)} quotas = {'quota': {'extra1': 100}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.put(_get_path('quotas', id=project_id, fmt=self.fmt), self.serialize(quotas), extra_environ=env) self.assertEqual(200, res.status_int) - env2 = {'neutron.context': context.Context('', tenant_id)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), + env2 = {'neutron.context': context.Context('', project_id)} + res = self.api.get(_get_path('quotas', id=project_id, fmt=self.fmt), extra_environ=env2) quota = self.deserialize(res) self.assertEqual(100, quota['quota']['extra1']) def test_delete_quotas_with_admin(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id + '2', is_admin=True)} # Create a quota to ensure we have something to delete quotas = {'quota': {'network': 100}} - self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), + self.api.put(_get_path('quotas', id=project_id, fmt=self.fmt), self.serialize(quotas), extra_environ=env) - res = self.api.delete(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.delete(_get_path('quotas', id=project_id, fmt=self.fmt), extra_environ=env) self.assertEqual(204, res.status_int) def test_delete_quotas_without_admin_forbidden_returns_403(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=False)} - res = self.api.delete(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.delete(_get_path('quotas', id=project_id, fmt=self.fmt), extra_environ=env, expect_errors=True) self.assertEqual(403, res.status_int) - def test_delete_quota_with_unknown_tenant_returns_404(self): - tenant_id = 'idnotexist' - env = {'neutron.context': context.Context('', tenant_id + '2', + def test_delete_quota_with_unknown_project_returns_404(self): + project_id = 'idnotexist' + env = {'neutron.context': context.Context('', project_id + '2', is_admin=True)} - res = self.api.delete(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.delete(_get_path('quotas', id=project_id, fmt=self.fmt), extra_environ=env, expect_errors=True) self.assertEqual(exc.HTTPNotFound.code, res.status_int) @@ -353,44 +353,48 @@ class QuotaExtensionDbTestCase(QuotaExtensionTestCase): pass def test_quotas_limit_check(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=True)} quotas = {'quota': {'network': 5}} - res = self.api.put(_get_path('quotas', id=tenant_id, + res = self.api.put(_get_path('quotas', id=project_id, fmt=self.fmt), self.serialize(quotas), extra_environ=env) self.assertEqual(200, res.status_int) - quota.QUOTAS.limit_check(context.Context('', tenant_id), - tenant_id, + quota.QUOTAS.limit_check(context.Context('', project_id), + project_id, network=4) def test_quotas_limit_check_with_invalid_quota_value(self): - tenant_id = 'tenant_id1' + project_id = 'project_id1' with testtools.ExpectedException(exceptions.InvalidQuotaValue): - quota.QUOTAS.limit_check(context.Context('', tenant_id), - tenant_id, + quota.QUOTAS.limit_check(context.Context('', project_id), + project_id, network=-2) def test_quotas_limit_check_with_not_registered_resource_fails(self): - tenant_id = 'tenant_id1' + project_id = 'project_id1' self.assertRaises(exceptions.QuotaResourceUnknown, quota.QUOTAS.limit_check, context.get_admin_context(), - tenant_id, + project_id, foobar=1) - def test_quotas_get_tenant_from_request_context(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + def test_quotas_get_project_from_request_context(self): + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=True)} - res = self.api.get(_get_path('quotas/tenant', fmt=self.fmt), - extra_environ=env) - self.assertEqual(200, res.status_int) - quota = self.deserialize(res) - self.assertEqual(quota['tenant']['tenant_id'], tenant_id) + # NOTE(ralonsoh): the Quota API keeps "tenant" and "project" methods + # for compatibility. "tenant" is already deprecated and will be + # removed. + for key in ('project', 'tenant'): + res = self.api.get(_get_path('quotas/' + key, fmt=self.fmt), + extra_environ=env) + self.assertEqual(200, res.status_int) + quota = self.deserialize(res) + self.assertEqual(quota[key][key + '_id'], project_id) - def test_quotas_get_tenant_from_empty_request_context_returns_400(self): + def test_quotas_get_project_from_empty_request_context_returns_400(self): env = {'neutron.context': context.Context('', '', is_admin=True)} res = self.api.get(_get_path('quotas/tenant', fmt=self.fmt), @@ -398,20 +402,20 @@ class QuotaExtensionDbTestCase(QuotaExtensionTestCase): self.assertEqual(400, res.status_int) def test_make_reservation_resource_unknown_raises(self): - tenant_id = 'tenant_id1' + project_id = 'project_id1' self.assertRaises(exceptions.QuotaResourceUnknown, quota.QUOTAS.make_reservation, context.get_admin_context(), - tenant_id, + project_id, {'foobar': 1}, plugin=None) def test_make_reservation_negative_delta_raises(self): - tenant_id = 'tenant_id1' + project_id = 'project_id1' self.assertRaises(exceptions.InvalidQuotaValue, quota.QUOTAS.make_reservation, context.get_admin_context(), - tenant_id, + project_id, {'network': -1}, plugin=None) @@ -441,34 +445,34 @@ class QuotaExtensionCfgTestCase(QuotaExtensionTestCase): 'extra1': qconf.DEFAULT_QUOTA}) def test_show_quotas_with_admin(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id + '2', is_admin=True)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.get(_get_path('quotas', id=project_id, fmt=self.fmt), extra_environ=env) self.assertEqual(200, res.status_int) def test_show_quotas_without_admin_forbidden(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id + '2', is_admin=False)} - res = self.api.get(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.get(_get_path('quotas', id=project_id, fmt=self.fmt), extra_environ=env, expect_errors=True) self.assertEqual(403, res.status_int) def test_update_quotas_forbidden(self): - tenant_id = 'tenant_id1' + project_id = 'project_id1' quotas = {'quota': {'network': 100}} - res = self.api.put(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.put(_get_path('quotas', id=project_id, fmt=self.fmt), self.serialize(quotas), expect_errors=True) self.assertEqual(200, res.status_int) def test_delete_quotas_forbidden(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=False)} - res = self.api.delete(_get_path('quotas', id=tenant_id, fmt=self.fmt), + res = self.api.delete(_get_path('quotas', id=project_id, fmt=self.fmt), extra_environ=env, expect_errors=True) self.assertEqual(403, res.status_int) @@ -476,7 +480,7 @@ class QuotaExtensionCfgTestCase(QuotaExtensionTestCase): class TestDbQuotaDriver(base.BaseTestCase): """Test for neutron.db.quota.driver.DbQuotaDriver.""" - def test_get_tenant_quotas_arg(self): + def test_get_project_quotas_arg(self): """Call neutron.db.quota.driver.DbQuotaDriver._get_quotas.""" quota_driver = driver.DbQuotaDriver() @@ -484,20 +488,20 @@ class TestDbQuotaDriver(base.BaseTestCase): foo_quotas = {'network': 5} default_quotas = {'network': 10} - target_tenant = 'foo' + target_project = 'foo' with mock.patch.object(driver.DbQuotaDriver, - 'get_tenant_quotas', - return_value=foo_quotas) as get_tenant_quotas: + 'get_project_quotas', + return_value=foo_quotas) as get_project_quotas: quotas = quota_driver._get_quotas(ctx, - target_tenant, + target_project, default_quotas) self.assertEqual(quotas, foo_quotas) - get_tenant_quotas.assert_called_once_with(ctx, + get_project_quotas.assert_called_once_with(ctx, default_quotas, - target_tenant) + target_project) class TestQuotaDriverLoad(base.BaseTestCase): diff --git a/neutron/tests/unit/extensions/test_quotasv2_detail.py b/neutron/tests/unit/extensions/test_quotasv2_detail.py index 88403327b88..21254f198c6 100644 --- a/neutron/tests/unit/extensions/test_quotasv2_detail.py +++ b/neutron/tests/unit/extensions/test_quotasv2_detail.py @@ -67,9 +67,9 @@ class DetailQuotaExtensionDbTestCase(DetailQuotaExtensionTestCase): fmt = 'json' def test_show_detail_quotas(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id)} - res = self.api.get(_get_path('quotas', id=tenant_id, + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id)} + res = self.api.get(_get_path('quotas', id=project_id, fmt=self.fmt, endpoint=DEFAULT_QUOTAS_ACTION), extra_environ=env) @@ -95,10 +95,10 @@ class DetailQuotaExtensionDbTestCase(DetailQuotaExtensionTestCase): 'quota_network', -10, group='QUOTAS') cfg.CONF.set_override( 'quota_subnet', -50, group='QUOTAS') - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id, + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id, is_admin=True)} - res = self.api.get(_get_path('quotas', id=tenant_id, + res = self.api.get(_get_path('quotas', id=project_id, fmt=self.fmt, endpoint=DEFAULT_QUOTAS_ACTION), extra_environ=env) @@ -118,10 +118,10 @@ class DetailQuotaExtensionDbTestCase(DetailQuotaExtensionTestCase): quota['quota']['port']['limit']) def test_show_detail_quotas_with_admin(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id + '2', is_admin=True)} - res = self.api.get(_get_path('quotas', id=tenant_id, + res = self.api.get(_get_path('quotas', id=project_id, fmt=self.fmt, endpoint=DEFAULT_QUOTAS_ACTION), extra_environ=env) @@ -141,10 +141,10 @@ class DetailQuotaExtensionDbTestCase(DetailQuotaExtensionTestCase): quota['quota']['port']['limit']) def test_detail_quotas_without_admin_forbidden_returns_403(self): - tenant_id = 'tenant_id1' - env = {'neutron.context': context.Context('', tenant_id + '2', + project_id = 'project_id1' + env = {'neutron.context': context.Context('', project_id + '2', is_admin=False)} - res = self.api.get(_get_path('quotas', id=tenant_id, + res = self.api.get(_get_path('quotas', id=project_id, fmt=self.fmt, endpoint=DEFAULT_QUOTAS_ACTION), extra_environ=env, expect_errors=True) diff --git a/neutron/tests/unit/plugins/ml2/test_tracked_resources.py b/neutron/tests/unit/plugins/ml2/test_tracked_resources.py index 912b0dc143c..264dd8e9087 100644 --- a/neutron/tests/unit/plugins/ml2/test_tracked_resources.py +++ b/neutron/tests/unit/plugins/ml2/test_tracked_resources.py @@ -45,7 +45,9 @@ class BaseTestTrackedResources(test_plugin.Ml2PluginV2TestCase, test_db_base_plugin_v2.NeutronDbPluginV2TestCase.quota_db_driver = ( 'neutron.db.quota.driver.DbQuotaDriver') super(BaseTestTrackedResources, self).setUp() - self._tenant_id = uuidutils.generate_uuid() + self._project_id = uuidutils.generate_uuid() + # TODO(ralonsoh): "tenant_id" reference should be removed. + self._tenant_id = self._project_id @staticmethod def _cleanup(): @@ -54,7 +56,7 @@ class BaseTestTrackedResources(test_plugin.Ml2PluginV2TestCase, def _test_init(self, resource_name): quota_db_api.set_quota_usage( - self.ctx, resource_name, self._tenant_id) + self.ctx, resource_name, self._project_id) class BaseTestEventHandler(object): @@ -88,7 +90,7 @@ class BaseTestEventHandler(object): if item: model = self.handler_mock.call_args_list[call_idx][0][-1] self.assertEqual(model['id'], item['id']) - self.assertEqual(model['tenant_id'], item['tenant_id']) + self.assertEqual(model['project_id'], item['project_id']) call_idx = call_idx - 1 @@ -140,7 +142,7 @@ class TestTrackedResourcesEventHandler(BaseTestEventHandler, self._test_init('subnetpool') pool = self._make_subnetpool('json', ['10.0.0.0/8'], name='meh', - tenant_id=self._tenant_id)['subnetpool'] + tenant_id=self._project_id)['subnetpool'] self._verify_event_handler_calls(pool) self._delete('subnetpools', pool['id']) self._verify_event_handler_calls(pool, expected_call_count=2) @@ -148,7 +150,8 @@ class TestTrackedResourcesEventHandler(BaseTestEventHandler, def test_create_delete_securitygroup_triggers_event(self): self._test_init('security_group') sec_group = self._make_security_group( - 'json', 'meh', 'meh', tenant_id=self._tenant_id)['security_group'] + 'json', 'meh', 'meh', + project_id=self._project_id)['security_group'] # When a security group is created it also creates 2 rules, therefore # there will be three calls and we need to verify the first self._verify_event_handler_calls([None, None, sec_group], @@ -161,9 +164,10 @@ class TestTrackedResourcesEventHandler(BaseTestEventHandler, def test_create_delete_securitygrouprule_triggers_event(self): self._test_init('security_group_rule') sec_group = self._make_security_group( - 'json', 'meh', 'meh', tenant_id=self._tenant_id)['security_group'] + 'json', 'meh', 'meh', + project_id=self._project_id)['security_group'] rule_req = self._build_security_group_rule( - sec_group['id'], 'ingress', 'TCP', tenant_id=self._tenant_id) + sec_group['id'], 'ingress', 'TCP', tenant_id=self._project_id) sec_group_rule = self._make_security_group_rule( 'json', rule_req)['security_group_rule'] # When a security group is created it also creates 2 rules, therefore @@ -213,8 +217,8 @@ class TestL3ResourcesEventHandler(BaseTestEventHandler, class TestTrackedResources(BaseTestTrackedResources): def _verify_dirty_bit(self, resource_name, expected_value=True): - usage = quota_db_api.get_quota_usage_by_resource_and_tenant( - self.ctx, resource_name, self._tenant_id) + usage = quota_db_api.get_quota_usage_by_resource_and_project( + self.ctx, resource_name, self._project_id) self.assertEqual(expected_value, usage.dirty) def test_create_delete_network_marks_dirty(self): @@ -223,14 +227,14 @@ class TestTrackedResources(BaseTestTrackedResources): self._verify_dirty_bit('network') # Clear the dirty bit quota_db_api.set_quota_usage_dirty( - self.ctx, 'network', self._tenant_id, dirty=False) + self.ctx, 'network', self._project_id, dirty=False) self._delete('networks', net['id']) self._verify_dirty_bit('network') def test_list_networks_clears_dirty(self): self._test_init('network') net = self._make_network('json', 'meh', True)['network'] - self.ctx.tenant_id = net['tenant_id'] + self.ctx.project_id = net['project_id'] self._list('networks', neutron_context=self.ctx) self._verify_dirty_bit('network', expected_value=False) @@ -241,7 +245,7 @@ class TestTrackedResources(BaseTestTrackedResources): self._verify_dirty_bit('port') # Clear the dirty bit quota_db_api.set_quota_usage_dirty( - self.ctx, 'port', self._tenant_id, dirty=False) + self.ctx, 'port', self._project_id, dirty=False) self._delete('ports', port['id']) self._verify_dirty_bit('port') @@ -249,7 +253,7 @@ class TestTrackedResources(BaseTestTrackedResources): self._test_init('port') net = self._make_network('json', 'meh', True)['network'] port = self._make_port('json', net['id'])['port'] - self.ctx.tenant_id = port['tenant_id'] + self.ctx.project_id = port['project_id'] self._list('ports', neutron_context=self.ctx) self._verify_dirty_bit('port', expected_value=False) @@ -261,7 +265,7 @@ class TestTrackedResources(BaseTestTrackedResources): self._verify_dirty_bit('subnet') # Clear the dirty bit quota_db_api.set_quota_usage_dirty( - self.ctx, 'subnet', self._tenant_id, dirty=False) + self.ctx, 'subnet', self._project_id, dirty=False) self._delete('subnets', subnet['id']) self._verify_dirty_bit('subnet') @@ -274,7 +278,7 @@ class TestTrackedResources(BaseTestTrackedResources): self._verify_dirty_bit('subnet') # Clear the dirty bit quota_db_api.set_quota_usage_dirty( - self.ctx, 'subnet', self._tenant_id, dirty=False) + self.ctx, 'subnet', self._project_id, dirty=False) self._delete('networks', net['network']['id']) self._verify_dirty_bit('network') self._verify_dirty_bit('subnet') @@ -284,7 +288,7 @@ class TestTrackedResources(BaseTestTrackedResources): net = self._make_network('json', 'meh', True) subnet = self._make_subnet('json', net, '10.0.0.1', '10.0.0.0/24')['subnet'] - self.ctx.tenant_id = subnet['tenant_id'] + self.ctx.project_id = subnet['project_id'] self._list('subnets', neutron_context=self.ctx) self._verify_dirty_bit('subnet', expected_value=False) @@ -292,11 +296,11 @@ class TestTrackedResources(BaseTestTrackedResources): self._test_init('subnetpool') pool = self._make_subnetpool('json', ['10.0.0.0/8'], name='meh', - tenant_id=self._tenant_id)['subnetpool'] + tenant_id=self._project_id)['subnetpool'] self._verify_dirty_bit('subnetpool') # Clear the dirty bit quota_db_api.set_quota_usage_dirty( - self.ctx, 'subnetpool', self._tenant_id, dirty=False) + self.ctx, 'subnetpool', self._project_id, dirty=False) self._delete('subnetpools', pool['id']) self._verify_dirty_bit('subnetpool') @@ -304,51 +308,51 @@ class TestTrackedResources(BaseTestTrackedResources): self._test_init('subnetpool') pool = self._make_subnetpool('json', ['10.0.0.0/8'], name='meh', - tenant_id=self._tenant_id)['subnetpool'] - self.ctx.tenant_id = pool['tenant_id'] + tenant_id=self._project_id)['subnetpool'] + self.ctx.project_id = pool['project_id'] self._list('subnetpools', neutron_context=self.ctx) self._verify_dirty_bit('subnetpool', expected_value=False) def test_create_delete_securitygroup_marks_dirty(self): self._test_init('security_group') sec_group = self._make_security_group( - 'json', 'meh', 'meh', tenant_id=self._tenant_id)['security_group'] + 'json', 'meh', 'meh', tenant_id=self._project_id)['security_group'] self._verify_dirty_bit('security_group') # Clear the dirty bit quota_db_api.set_quota_usage_dirty( - self.ctx, 'security_group', self._tenant_id, dirty=False) + self.ctx, 'security_group', self._project_id, dirty=False) self._delete('security-groups', sec_group['id']) self._verify_dirty_bit('security_group') def test_list_securitygroups_clears_dirty(self): self._test_init('security_group') self._make_security_group( - 'json', 'meh', 'meh', tenant_id=self._tenant_id)['security_group'] - self.ctx.tenant_id = self._tenant_id + 'json', 'meh', 'meh', tenant_id=self._project_id)['security_group'] + self.ctx.project_id = self._project_id self._list('security-groups', neutron_context=self.ctx) self._verify_dirty_bit('security_group', expected_value=False) def test_create_delete_securitygrouprule_marks_dirty(self): self._test_init('security_group_rule') sec_group = self._make_security_group( - 'json', 'meh', 'meh', tenant_id=self._tenant_id)['security_group'] + 'json', 'meh', 'meh', tenant_id=self._project_id)['security_group'] rule_req = self._build_security_group_rule( - sec_group['id'], 'ingress', 'TCP', tenant_id=self._tenant_id) + sec_group['id'], 'ingress', 'TCP', tenant_id=self._project_id) sec_group_rule = self._make_security_group_rule( 'json', rule_req)['security_group_rule'] self._verify_dirty_bit('security_group_rule') # Clear the dirty bit quota_db_api.set_quota_usage_dirty( - self.ctx, 'security_group_rule', self._tenant_id, dirty=False) + self.ctx, 'security_group_rule', self._project_id, dirty=False) self._delete('security-group-rules', sec_group_rule['id']) self._verify_dirty_bit('security_group_rule') def test_list_securitygrouprules_clears_dirty(self): self._test_init('security_group_rule') self._make_security_group( - 'json', 'meh', 'meh', tenant_id=self._tenant_id)['security_group'] + 'json', 'meh', 'meh', tenant_id=self._project_id)['security_group'] # As the security group create operation also creates 2 security group # rules there is no need to explicitly create any rule - self.ctx.tenant_id = self._tenant_id + self.ctx.project_id = self._project_id self._list('security-group-rules', neutron_context=self.ctx) self._verify_dirty_bit('security_group_rule', expected_value=False) diff --git a/neutron/tests/unit/quota/test_resource.py b/neutron/tests/unit/quota/test_resource.py index 39918f9ebd1..38a9871f1b4 100644 --- a/neutron/tests/unit/quota/test_resource.py +++ b/neutron/tests/unit/quota/test_resource.py @@ -75,22 +75,22 @@ class TestResource(base.DietTestCase): class TestTrackedResource(testlib_api.SqlTestCase): - def _add_data(self, tenant_id=None): + def _add_data(self, project_id=None): session = db_api.get_writer_session() with session.begin(): - tenant_id = tenant_id or self.tenant_id + project_id = project_id or self.project_id session.add(test_quota.MehModel( meh='meh_%s' % uuidutils.generate_uuid(), - tenant_id=tenant_id)) + project_id=project_id)) session.add(test_quota.MehModel( meh='meh_%s' % uuidutils.generate_uuid(), - tenant_id=tenant_id)) + project_id=project_id)) def _delete_data(self): session = db_api.get_writer_session() with session.begin(): query = session.query(test_quota.MehModel).filter_by( - tenant_id=self.tenant_id) + project_id=self.project_id) for item in query: session.delete(item) @@ -98,7 +98,7 @@ class TestTrackedResource(testlib_api.SqlTestCase): session = db_api.get_writer_session() with session.begin(): query = session.query(test_quota.MehModel).filter_by( - tenant_id=self.tenant_id) + project_id=self.project_id) for item in query: item['meh'] = 'meh-%s' % item['meh'] session.add(item) @@ -109,9 +109,9 @@ class TestTrackedResource(testlib_api.SqlTestCase): self.setup_coreplugin(DB_PLUGIN_KLASS) self.resource = 'meh' self.other_resource = 'othermeh' - self.tenant_id = 'meh' + self.project_id = 'meh' self.context = context.Context( - user_id='', tenant_id=self.tenant_id, is_admin=False) + user_id='', project_id=self.project_id, is_admin=False) def _create_resource(self): res = resource.TrackedResource( @@ -133,7 +133,7 @@ class TestTrackedResource(testlib_api.SqlTestCase): def test_count_first_call_with_dirty_false(self): quota_api.set_quota_usage( - self.context, self.resource, self.tenant_id, in_use=1) + self.context, self.resource, self.project_id, in_use=1) res = self._create_resource() self._add_data() # explicitly set dirty flag to False @@ -141,17 +141,17 @@ class TestTrackedResource(testlib_api.SqlTestCase): self.context, self.resource, dirty=False) # Expect correct count to be returned anyway since the first call to # count() always resyncs with the db - self.assertEqual(2, res.count(self.context, None, self.tenant_id)) + self.assertEqual(2, res.count(self.context, None, self.project_id)) def test_count_reserved(self): res = self._create_resource() - quota_api.create_reservation(self.context, self.tenant_id, + quota_api.create_reservation(self.context, self.project_id, {res.name: 1}) - self.assertEqual(1, res.count_reserved(self.context, self.tenant_id)) + self.assertEqual(1, res.count_reserved(self.context, self.project_id)) def test_count_used_first_call_with_dirty_false(self): quota_api.set_quota_usage( - self.context, self.resource, self.tenant_id, in_use=1) + self.context, self.resource, self.project_id, in_use=1) res = self._create_resource() self._add_data() # explicitly set dirty flag to False @@ -160,18 +160,18 @@ class TestTrackedResource(testlib_api.SqlTestCase): # Expect correct count_used to be returned # anyway since the first call to # count_used() always resyncs with the db - self.assertEqual(2, res.count_used(self.context, self.tenant_id)) + self.assertEqual(2, res.count_used(self.context, self.project_id)) def _test_count(self): res = self._create_resource() quota_api.set_quota_usage( - self.context, res.name, self.tenant_id, in_use=0) + self.context, res.name, self.project_id, in_use=0) self._add_data() return res def test_count_with_dirty_false(self): res = self._test_count() - res.count(self.context, None, self.tenant_id) + res.count(self.context, None, self.project_id) # At this stage count has been invoked, and the dirty flag should be # false. Another invocation of count should not query the model class set_quota = 'neutron.db.quota.api.set_quota_usage' @@ -179,11 +179,11 @@ class TestTrackedResource(testlib_api.SqlTestCase): self.assertEqual(0, mock_set_quota.call_count) self.assertEqual(2, res.count(self.context, None, - self.tenant_id)) + self.project_id)) def test_count_used_with_dirty_false(self): res = self._test_count() - res.count_used(self.context, self.tenant_id) + res.count_used(self.context, self.project_id) # At this stage count_used has been invoked, # and the dirty flag should be false. Another invocation # of count_used should not query the model class @@ -191,7 +191,7 @@ class TestTrackedResource(testlib_api.SqlTestCase): with mock.patch(set_quota) as mock_set_quota: self.assertEqual(0, mock_set_quota.call_count) self.assertEqual(2, res.count_used(self.context, - self.tenant_id)) + self.project_id)) def test_count_with_dirty_true_resync(self): res = self._test_count() @@ -199,7 +199,7 @@ class TestTrackedResource(testlib_api.SqlTestCase): # set_quota_usage has been invoked with the correct parameters self.assertEqual(2, res.count(self.context, None, - self.tenant_id, + self.project_id, resync_usage=True)) def test_count_used_with_dirty_true_resync(self): @@ -207,7 +207,7 @@ class TestTrackedResource(testlib_api.SqlTestCase): # Expect correct count_used to be returned, which also implies # set_quota_usage has been invoked with the correct parameters self.assertEqual(2, res.count_used(self.context, - self.tenant_id, + self.project_id, resync_usage=True)) def test_count_with_dirty_true_resync_calls_set_quota_usage(self): @@ -216,11 +216,11 @@ class TestTrackedResource(testlib_api.SqlTestCase): with mock.patch(set_quota_usage) as mock_set_quota_usage: quota_api.set_quota_usage_dirty(self.context, self.resource, - self.tenant_id) - res.count(self.context, None, self.tenant_id, + self.project_id) + res.count(self.context, None, self.project_id, resync_usage=True) mock_set_quota_usage.assert_called_once_with( - self.context, self.resource, self.tenant_id, in_use=2) + self.context, self.resource, self.project_id, in_use=2) def test_count_used_with_dirty_true_resync_calls_set_quota_usage(self): res = self._test_count() @@ -228,25 +228,25 @@ class TestTrackedResource(testlib_api.SqlTestCase): with mock.patch(set_quota_usage) as mock_set_quota_usage: quota_api.set_quota_usage_dirty(self.context, self.resource, - self.tenant_id) - res.count_used(self.context, self.tenant_id, + self.project_id) + res.count_used(self.context, self.project_id, resync_usage=True) mock_set_quota_usage.assert_called_once_with( - self.context, self.resource, self.tenant_id, in_use=2) + self.context, self.resource, self.project_id, in_use=2) def test_count_with_dirty_true_no_usage_info(self): res = self._create_resource() self._add_data() # Invoke count without having usage info in DB - Expect correct # count to be returned - self.assertEqual(2, res.count(self.context, None, self.tenant_id)) + self.assertEqual(2, res.count(self.context, None, self.project_id)) def test_count_used_with_dirty_true_no_usage_info(self): res = self._create_resource() self._add_data() # Invoke count_used without having usage info in DB - Expect correct # count_used to be returned - self.assertEqual(2, res.count_used(self.context, self.tenant_id)) + self.assertEqual(2, res.count_used(self.context, self.project_id)) def test_count_with_dirty_true_no_usage_info_calls_set_quota_usage(self): res = self._create_resource() @@ -255,10 +255,10 @@ class TestTrackedResource(testlib_api.SqlTestCase): with mock.patch(set_quota_usage) as mock_set_quota_usage: quota_api.set_quota_usage_dirty(self.context, self.resource, - self.tenant_id) - res.count(self.context, None, self.tenant_id, resync_usage=True) + self.project_id) + res.count(self.context, None, self.project_id, resync_usage=True) mock_set_quota_usage.assert_called_once_with( - self.context, self.resource, self.tenant_id, in_use=2) + self.context, self.resource, self.project_id, in_use=2) def test_count_used_with_dirty_true_no_usage_info_calls_set_quota_usage( self): @@ -268,44 +268,44 @@ class TestTrackedResource(testlib_api.SqlTestCase): with mock.patch(set_quota_usage) as mock_set_quota_usage: quota_api.set_quota_usage_dirty(self.context, self.resource, - self.tenant_id) - res.count_used(self.context, self.tenant_id, resync_usage=True) + self.project_id) + res.count_used(self.context, self.project_id, resync_usage=True) mock_set_quota_usage.assert_called_once_with( - self.context, self.resource, self.tenant_id, in_use=2) + self.context, self.resource, self.project_id, in_use=2) def test_add_delete_data_triggers_event(self): res = self._create_resource() other_res = self._create_other_resource() - # Validate dirty tenants since mock does not work well with SQLAlchemy + # Validate dirty projects since mock does not work well with SQLAlchemy # event handlers. self._add_data() self._add_data('someone_else') - self.assertEqual(2, len(res._dirty_tenants)) + self.assertEqual(2, len(res._dirty_projects)) # Also, the dirty flag should not be set for other resources - self.assertEqual(0, len(other_res._dirty_tenants)) - self.assertIn(self.tenant_id, res._dirty_tenants) - self.assertIn('someone_else', res._dirty_tenants) + self.assertEqual(0, len(other_res._dirty_projects)) + self.assertIn(self.project_id, res._dirty_projects) + self.assertIn('someone_else', res._dirty_projects) def test_delete_data_triggers_event(self): res = self._create_resource() self._add_data() self._add_data('someone_else') - # Artificially clear _dirty_tenants - res._dirty_tenants.clear() + # Artificially clear _dirty_projects + res._dirty_projects.clear() self._delete_data() # We did not delete "someone_else", so expect only a single dirty - # tenant - self.assertEqual(1, len(res._dirty_tenants)) - self.assertIn(self.tenant_id, res._dirty_tenants) + # project + self.assertEqual(1, len(res._dirty_projects)) + self.assertIn(self.project_id, res._dirty_projects) def test_update_does_not_trigger_event(self): res = self._create_resource() self._add_data() self._add_data('someone_else') - # Artificially clear _dirty_tenants - res._dirty_tenants.clear() + # Artificially clear _dirty_projects + res._dirty_projects.clear() self._update_data() - self.assertEqual(0, len(res._dirty_tenants)) + self.assertEqual(0, len(res._dirty_projects)) def test_mark_dirty(self): res = self._create_resource() @@ -316,11 +316,11 @@ class TestTrackedResource(testlib_api.SqlTestCase): res.mark_dirty(self.context) self.assertEqual(2, mock_set_quota_usage.call_count) mock_set_quota_usage.assert_any_call( - self.context, self.resource, self.tenant_id) + self.context, self.resource, self.project_id) mock_set_quota_usage.assert_any_call( self.context, self.resource, 'someone_else') - def test_mark_dirty_no_dirty_tenant(self): + def test_mark_dirty_no_dirty_project(self): res = self._create_resource() set_quota_usage = 'neutron.db.quota.api.set_quota_usage_dirty' with mock.patch(set_quota_usage) as mock_set_quota_usage: @@ -331,14 +331,14 @@ class TestTrackedResource(testlib_api.SqlTestCase): res = self._create_resource() self._add_data() res.mark_dirty(self.context) - # self.tenant_id now is out of sync + # self.project_id now is out of sync set_quota_usage = 'neutron.db.quota.api.set_quota_usage' with mock.patch(set_quota_usage) as mock_set_quota_usage: - res.resync(self.context, self.tenant_id) + res.resync(self.context, self.project_id) # and now it should be in sync - self.assertNotIn(self.tenant_id, res._out_of_sync_tenants) + self.assertNotIn(self.project_id, res._out_of_sync_projects) mock_set_quota_usage.assert_called_once_with( - self.context, self.resource, self.tenant_id, in_use=2) + self.context, self.resource, self.project_id, in_use=2) class Test_CountResource(base.BaseTestCase): @@ -355,15 +355,15 @@ class Test_CountResource(base.BaseTestCase): context = mock.Mock() collection_name = 'floatingips' - tenant_id = 'fakeid' + project_id = 'fakeid' self.assertRaises( NotImplementedError, - resource._count_resource, context, collection_name, tenant_id) + resource._count_resource, context, collection_name, project_id) for plugin in plugins.values(): for func in (plugin.get_floatingips_count, plugin.get_floatingips): func.assert_called_with( - context, filters={'tenant_id': [tenant_id]}) + context, filters={'project_id': [project_id]}) def test_core_plugin_checked_first(self): plugin1 = mock.Mock() @@ -378,6 +378,6 @@ class Test_CountResource(base.BaseTestCase): context = mock.Mock() collection_name = 'floatingips' - tenant_id = 'fakeid' + project_id = 'fakeid' self.assertEqual( - 10, resource._count_resource(context, collection_name, tenant_id)) + 10, resource._count_resource(context, collection_name, project_id)) diff --git a/neutron/tests/unit/quota/test_resource_registry.py b/neutron/tests/unit/quota/test_resource_registry.py index 2df4c6dd401..2371ad9ba31 100644 --- a/neutron/tests/unit/quota/test_resource_registry.py +++ b/neutron/tests/unit/quota/test_resource_registry.py @@ -101,7 +101,7 @@ class TestAuxiliaryFunctions(base.DietTestCase): 'TrackedResource.resync') as mock_resync: self.registry.set_tracked_resource('meh', test_quota.MehModel) self.registry.register_resource_by_name('meh') - resource_registry.resync_resource(mock.ANY, 'meh', 'tenant_id') + resource_registry.resync_resource(mock.ANY, 'meh', 'project_id') self.assertEqual(0, mock_resync.call_count) def test_resync_tracked_resource(self): @@ -109,14 +109,14 @@ class TestAuxiliaryFunctions(base.DietTestCase): 'TrackedResource.resync') as mock_resync: self.registry.set_tracked_resource('meh', test_quota.MehModel) self.registry.register_resource_by_name('meh') - resource_registry.resync_resource(mock.ANY, 'meh', 'tenant_id') - mock_resync.assert_called_once_with(mock.ANY, 'tenant_id') + resource_registry.resync_resource(mock.ANY, 'meh', 'project_id') + mock_resync.assert_called_once_with(mock.ANY, 'project_id') def test_resync_non_tracked_resource(self): with mock.patch('neutron.quota.resource.' 'TrackedResource.resync') as mock_resync: self.registry.register_resource_by_name('meh') - resource_registry.resync_resource(mock.ANY, 'meh', 'tenant_id') + resource_registry.resync_resource(mock.ANY, 'meh', 'project_id') self.assertEqual(0, mock_resync.call_count) def test_set_resources_dirty_invoked_with_tracking_disabled(self): @@ -132,7 +132,7 @@ class TestAuxiliaryFunctions(base.DietTestCase): self.assertEqual(0, mock_mark_dirty.call_count) def test_set_resources_dirty_no_dirty_resource(self): - ctx = context.Context('user_id', 'tenant_id', + ctx = context.Context('user_id', 'project_id', is_admin=False, is_advsvc=False) with mock.patch('neutron.quota.resource.' 'TrackedResource.mark_dirty') as mock_mark_dirty: @@ -140,12 +140,12 @@ class TestAuxiliaryFunctions(base.DietTestCase): self.registry.register_resource_by_name('meh') res = self.registry.get_resource('meh') # This ensures dirty is false - res._dirty_tenants.clear() + res._dirty_projects.clear() resource_registry.set_resources_dirty(ctx) self.assertEqual(0, mock_mark_dirty.call_count) def test_set_resources_dirty_no_tracked_resource(self): - ctx = context.Context('user_id', 'tenant_id', + ctx = context.Context('user_id', 'project_id', is_admin=False, is_advsvc=False) with mock.patch('neutron.quota.resource.' 'TrackedResource.mark_dirty') as mock_mark_dirty: @@ -154,7 +154,7 @@ class TestAuxiliaryFunctions(base.DietTestCase): self.assertEqual(0, mock_mark_dirty.call_count) def test_set_resources_dirty(self): - ctx = context.Context('user_id', 'tenant_id', + ctx = context.Context('user_id', 'project_id', is_admin=False, is_advsvc=False) with mock.patch('neutron.quota.resource.' 'TrackedResource.mark_dirty') as mock_mark_dirty: @@ -163,6 +163,6 @@ class TestAuxiliaryFunctions(base.DietTestCase): self.registry.resources['meh']._track_resource_events = True res = self.registry.get_resource('meh') # This ensures dirty is true - res._dirty_tenants.add('tenant_id') + res._dirty_projects.add('project_id') resource_registry.set_resources_dirty(ctx) mock_mark_dirty.assert_called_once_with(ctx)