Merge "Implement support for project limits"
This commit is contained in:
		
							
								
								
									
										128
									
								
								doc/source/cli/command-objects/limit.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								doc/source/cli/command-objects/limit.rst
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,128 @@
 | 
				
			|||||||
 | 
					=====
 | 
				
			||||||
 | 
					limit
 | 
				
			||||||
 | 
					=====
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Identity v3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Limits are used to specify project-specific limits thresholds of resources.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					limit create
 | 
				
			||||||
 | 
					------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Create a new limit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. program:: limit create
 | 
				
			||||||
 | 
					.. code:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    openstack limit create
 | 
				
			||||||
 | 
					        [--description <description>]
 | 
				
			||||||
 | 
					        [--region <region>]
 | 
				
			||||||
 | 
					        --project <project>
 | 
				
			||||||
 | 
					        --service <service>
 | 
				
			||||||
 | 
					        --resource-limit <resource-limit>
 | 
				
			||||||
 | 
					        <resource-name>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. option:: --description <description>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Useful description of the limit or its purpose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. option:: --region <region>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Region that the limit should be applied to
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. describe:: --project <project>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   The project that the limit applies to (required)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. describe:: --service <service>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   The service that is responsible for the resource being limited (required)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. describe:: --resource-limit <resource-limit>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   The limit to apply to the project (required)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. describe:: <resource-name>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   The name of the resource to limit (e.g. cores or volumes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					limit delete
 | 
				
			||||||
 | 
					------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Delete project-specific limit(s)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. program:: limit delete
 | 
				
			||||||
 | 
					.. code:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    openstack limit delete
 | 
				
			||||||
 | 
					        <limit-id> [<limit-id> ...]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. describe:: <limit-id>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Limit(s) to delete (ID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					limit list
 | 
				
			||||||
 | 
					----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					List project-specific limits
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. program:: limit list
 | 
				
			||||||
 | 
					.. code:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    openstack limit list
 | 
				
			||||||
 | 
					        [--service <service>]
 | 
				
			||||||
 | 
					        [--resource-name <resource-name>]
 | 
				
			||||||
 | 
					        [--region <region>]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. option:: --service <service>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    The service to filter the response by (name or ID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. option:: --resource-name <resource-name>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    The name of the resource to filter the response by
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. option:: --region <region>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   The region name to filter the response by
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					limit show
 | 
				
			||||||
 | 
					----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Display details about a limit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. program:: limit show
 | 
				
			||||||
 | 
					.. code:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    openstack limit show
 | 
				
			||||||
 | 
					        <limit-id>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. describe:: <limit-id>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Limit to display (ID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					limit set
 | 
				
			||||||
 | 
					---------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Update a limit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. program:: limit show
 | 
				
			||||||
 | 
					.. code:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    openstack limit set
 | 
				
			||||||
 | 
					        [--description <description>]
 | 
				
			||||||
 | 
					        [--resource-limit <resource-limit>]
 | 
				
			||||||
 | 
					        <limit-id>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. option:: --description <description>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Useful description of the limit or its purpose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. option:: --resource-limit <resource-limit>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   The limit to apply to the project
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. describe:: <limit-id>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   Limit to update (ID)
 | 
				
			||||||
							
								
								
									
										238
									
								
								openstackclient/identity/v3/limit.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								openstackclient/identity/v3/limit.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,238 @@
 | 
				
			|||||||
 | 
					#   Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
				
			||||||
 | 
					#   not use this file except in compliance with the License. You may obtain
 | 
				
			||||||
 | 
					#   a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#        http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
				
			||||||
 | 
					#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
				
			||||||
 | 
					#   License for the specific language governing permissions and limitations
 | 
				
			||||||
 | 
					#   under the License.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""Limits action implementations."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from osc_lib.command import command
 | 
				
			||||||
 | 
					from osc_lib import exceptions
 | 
				
			||||||
 | 
					from osc_lib import utils
 | 
				
			||||||
 | 
					import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from openstackclient.i18n import _
 | 
				
			||||||
 | 
					from openstackclient.identity import common as common_utils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LOG = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CreateLimit(command.ShowOne):
 | 
				
			||||||
 | 
					    _description = _("Create a limit")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_parser(self, prog_name):
 | 
				
			||||||
 | 
					        parser = super(CreateLimit, self).get_parser(prog_name)
 | 
				
			||||||
 | 
					        parser.add_argument(
 | 
				
			||||||
 | 
					            '--description',
 | 
				
			||||||
 | 
					            metavar='<description>',
 | 
				
			||||||
 | 
					            help=_('Description of the limit'),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        parser.add_argument(
 | 
				
			||||||
 | 
					            '--region',
 | 
				
			||||||
 | 
					            metavar='<region>',
 | 
				
			||||||
 | 
					            help=_('Region for the limit to affect.'),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        parser.add_argument(
 | 
				
			||||||
 | 
					            '--project',
 | 
				
			||||||
 | 
					            metavar='<project>',
 | 
				
			||||||
 | 
					            required=True,
 | 
				
			||||||
 | 
					            help=_('Project to associate the resource limit to'),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        parser.add_argument(
 | 
				
			||||||
 | 
					            '--service',
 | 
				
			||||||
 | 
					            metavar='<service>',
 | 
				
			||||||
 | 
					            required=True,
 | 
				
			||||||
 | 
					            help=_('Service responsible for the resource to limit'),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        parser.add_argument(
 | 
				
			||||||
 | 
					            '--resource-limit',
 | 
				
			||||||
 | 
					            metavar='<resource-limit>',
 | 
				
			||||||
 | 
					            required=True,
 | 
				
			||||||
 | 
					            type=int,
 | 
				
			||||||
 | 
					            help=_('The resource limit for the project to assume'),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        parser.add_argument(
 | 
				
			||||||
 | 
					            'resource_name',
 | 
				
			||||||
 | 
					            metavar='<resource-name>',
 | 
				
			||||||
 | 
					            help=_('The name of the resource to limit'),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        return parser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def take_action(self, parsed_args):
 | 
				
			||||||
 | 
					        identity_client = self.app.client_manager.identity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        project = common_utils.find_project(
 | 
				
			||||||
 | 
					            identity_client, parsed_args.project
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        service = common_utils.find_service(
 | 
				
			||||||
 | 
					            identity_client, parsed_args.service
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        region = None
 | 
				
			||||||
 | 
					        if parsed_args.region:
 | 
				
			||||||
 | 
					            region = utils.find_resource(
 | 
				
			||||||
 | 
					                identity_client.regions, parsed_args.region
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        limit = identity_client.limits.create(
 | 
				
			||||||
 | 
					            project,
 | 
				
			||||||
 | 
					            service,
 | 
				
			||||||
 | 
					            parsed_args.resource_name,
 | 
				
			||||||
 | 
					            parsed_args.resource_limit,
 | 
				
			||||||
 | 
					            description=parsed_args.description,
 | 
				
			||||||
 | 
					            region=region
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        limit._info.pop('links', None)
 | 
				
			||||||
 | 
					        return zip(*sorted(six.iteritems(limit._info)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ListLimit(command.Lister):
 | 
				
			||||||
 | 
					    _description = _("List limits")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_parser(self, prog_name):
 | 
				
			||||||
 | 
					        parser = super(ListLimit, self).get_parser(prog_name)
 | 
				
			||||||
 | 
					        parser.add_argument(
 | 
				
			||||||
 | 
					            '--service',
 | 
				
			||||||
 | 
					            metavar='<service>',
 | 
				
			||||||
 | 
					            help=_('Service responsible for the resource to limit'),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        parser.add_argument(
 | 
				
			||||||
 | 
					            '--resource-name',
 | 
				
			||||||
 | 
					            metavar='<resource-name>',
 | 
				
			||||||
 | 
					            dest='resource_name',
 | 
				
			||||||
 | 
					            help=_('The name of the resource to limit'),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        parser.add_argument(
 | 
				
			||||||
 | 
					            '--region',
 | 
				
			||||||
 | 
					            metavar='<region>',
 | 
				
			||||||
 | 
					            help=_('Region for the registered limit to affect.'),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        return parser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def take_action(self, parsed_args):
 | 
				
			||||||
 | 
					        identity_client = self.app.client_manager.identity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        service = None
 | 
				
			||||||
 | 
					        if parsed_args.service:
 | 
				
			||||||
 | 
					            service = common_utils.find_service(
 | 
				
			||||||
 | 
					                identity_client, parsed_args.service
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        region = None
 | 
				
			||||||
 | 
					        if parsed_args.region:
 | 
				
			||||||
 | 
					            region = utils.find_resource(
 | 
				
			||||||
 | 
					                identity_client.regions, parsed_args.region
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        limits = identity_client.limits.list(
 | 
				
			||||||
 | 
					            service=service,
 | 
				
			||||||
 | 
					            resource_name=parsed_args.resource_name,
 | 
				
			||||||
 | 
					            region=region
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        columns = (
 | 
				
			||||||
 | 
					            'ID', 'Project ID', 'Service ID', 'Resource Name',
 | 
				
			||||||
 | 
					            'Resource Limit', 'Description', 'Region ID'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            columns,
 | 
				
			||||||
 | 
					            (utils.get_item_properties(s, columns) for s in limits),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ShowLimit(command.ShowOne):
 | 
				
			||||||
 | 
					    _description = _("Display limit details")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_parser(self, prog_name):
 | 
				
			||||||
 | 
					        parser = super(ShowLimit, self).get_parser(prog_name)
 | 
				
			||||||
 | 
					        parser.add_argument(
 | 
				
			||||||
 | 
					            'limit_id',
 | 
				
			||||||
 | 
					            metavar='<limit-id>',
 | 
				
			||||||
 | 
					            help=_('Limit to display (ID)'),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        return parser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def take_action(self, parsed_args):
 | 
				
			||||||
 | 
					        identity_client = self.app.client_manager.identity
 | 
				
			||||||
 | 
					        limit = identity_client.limits.get(parsed_args.limit_id)
 | 
				
			||||||
 | 
					        limit._info.pop('links', None)
 | 
				
			||||||
 | 
					        return zip(*sorted(six.iteritems(limit._info)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SetLimit(command.ShowOne):
 | 
				
			||||||
 | 
					    _description = _("Update information about a limit")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_parser(self, prog_name):
 | 
				
			||||||
 | 
					        parser = super(SetLimit, self).get_parser(prog_name)
 | 
				
			||||||
 | 
					        parser.add_argument(
 | 
				
			||||||
 | 
					            'limit_id',
 | 
				
			||||||
 | 
					            metavar='<limit-id>',
 | 
				
			||||||
 | 
					            help=_('Limit to update (ID)'),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        parser.add_argument(
 | 
				
			||||||
 | 
					            '--description',
 | 
				
			||||||
 | 
					            metavar='<description>',
 | 
				
			||||||
 | 
					            help=_('Description of the limit'),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        parser.add_argument(
 | 
				
			||||||
 | 
					            '--resource-limit',
 | 
				
			||||||
 | 
					            metavar='<resource-limit>',
 | 
				
			||||||
 | 
					            dest='resource_limit',
 | 
				
			||||||
 | 
					            type=int,
 | 
				
			||||||
 | 
					            help=_('The resource limit for the project to assume'),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        return parser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def take_action(self, parsed_args):
 | 
				
			||||||
 | 
					        identity_client = self.app.client_manager.identity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        limit = identity_client.limits.update(
 | 
				
			||||||
 | 
					            parsed_args.limit_id,
 | 
				
			||||||
 | 
					            description=parsed_args.description,
 | 
				
			||||||
 | 
					            resource_limit=parsed_args.resource_limit
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        limit._info.pop('links', None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return zip(*sorted(six.iteritems(limit._info)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DeleteLimit(command.Command):
 | 
				
			||||||
 | 
					    _description = _("Delete a limit")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_parser(self, prog_name):
 | 
				
			||||||
 | 
					        parser = super(DeleteLimit, self).get_parser(prog_name)
 | 
				
			||||||
 | 
					        parser.add_argument(
 | 
				
			||||||
 | 
					            'limit_id',
 | 
				
			||||||
 | 
					            metavar='<limit-id>',
 | 
				
			||||||
 | 
					            nargs="+",
 | 
				
			||||||
 | 
					            help=_('Limit to delete (ID)'),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        return parser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def take_action(self, parsed_args):
 | 
				
			||||||
 | 
					        identity_client = self.app.client_manager.identity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        errors = 0
 | 
				
			||||||
 | 
					        for limit_id in parsed_args.limit_id:
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                identity_client.limits.delete(limit_id)
 | 
				
			||||||
 | 
					            except Exception as e:
 | 
				
			||||||
 | 
					                errors += 1
 | 
				
			||||||
 | 
					                LOG.error(_("Failed to delete limit with ID "
 | 
				
			||||||
 | 
					                            "'%(id)s': %(e)s"),
 | 
				
			||||||
 | 
					                          {'id': limit_id, 'e': e})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if errors > 0:
 | 
				
			||||||
 | 
					            total = len(parsed_args.limit_id)
 | 
				
			||||||
 | 
					            msg = (_("%(errors)s of %(total)s limits failed to "
 | 
				
			||||||
 | 
					                   "delete.") % {'errors': errors, 'total': total})
 | 
				
			||||||
 | 
					            raise exceptions.CommandError(msg)
 | 
				
			||||||
@@ -59,6 +59,10 @@ class IdentityTests(base.TestCase):
 | 
				
			|||||||
    REGISTERED_LIMIT_LIST_HEADERS = ['ID', 'Service ID', 'Resource Name',
 | 
					    REGISTERED_LIMIT_LIST_HEADERS = ['ID', 'Service ID', 'Resource Name',
 | 
				
			||||||
                                     'Default Limit', 'Description',
 | 
					                                     'Default Limit', 'Description',
 | 
				
			||||||
                                     'Region ID']
 | 
					                                     'Region ID']
 | 
				
			||||||
 | 
					    LIMIT_FIELDS = ['id', 'project_id', 'service_id', 'resource_name',
 | 
				
			||||||
 | 
					                    'resource_limit', 'description', 'region_id']
 | 
				
			||||||
 | 
					    LIMIT_LIST_HEADERS = ['ID', 'Project ID', 'Service ID', 'Resource Name',
 | 
				
			||||||
 | 
					                          'Resource Limit', 'Description', 'Region ID']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def setUpClass(cls):
 | 
					    def setUpClass(cls):
 | 
				
			||||||
@@ -356,3 +360,42 @@ class IdentityTests(base.TestCase):
 | 
				
			|||||||
            for k, v in d.iteritems():
 | 
					            for k, v in d.iteritems():
 | 
				
			||||||
                if k == key:
 | 
					                if k == key:
 | 
				
			||||||
                    return v
 | 
					                    return v
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _create_dummy_limit(self, add_clean_up=True):
 | 
				
			||||||
 | 
					        registered_limit_id = self._create_dummy_registered_limit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        raw_output = self.openstack(
 | 
				
			||||||
 | 
					            'registered limit show %s' % registered_limit_id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        resource_name = self._extract_value_from_items('resource_name', items)
 | 
				
			||||||
 | 
					        service_id = self._extract_value_from_items('service_id', items)
 | 
				
			||||||
 | 
					        resource_limit = 15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        project_name = self._create_dummy_project()
 | 
				
			||||||
 | 
					        raw_output = self.openstack('project show %s' % project_name)
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        project_id = self._extract_value_from_items('id', items)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        params = {
 | 
				
			||||||
 | 
					            'project_id': project_id,
 | 
				
			||||||
 | 
					            'service_id': service_id,
 | 
				
			||||||
 | 
					            'resource_name': resource_name,
 | 
				
			||||||
 | 
					            'resource_limit': resource_limit
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        raw_output = self.openstack(
 | 
				
			||||||
 | 
					            'limit create'
 | 
				
			||||||
 | 
					            ' --project %(project_id)s'
 | 
				
			||||||
 | 
					            ' --service %(service_id)s'
 | 
				
			||||||
 | 
					            ' --resource-limit %(resource_limit)s'
 | 
				
			||||||
 | 
					            ' %(resource_name)s' % params
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        limit_id = self._extract_value_from_items('id', items)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if add_clean_up:
 | 
				
			||||||
 | 
					            self.addCleanup(self.openstack, 'limit delete %s' % limit_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_show_fields(items, self.LIMIT_FIELDS)
 | 
				
			||||||
 | 
					        return limit_id
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										192
									
								
								openstackclient/tests/functional/identity/v3/test_limit.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								openstackclient/tests/functional/identity/v3/test_limit.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,192 @@
 | 
				
			|||||||
 | 
					#    Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
				
			||||||
 | 
					#    not use this file except in compliance with the License. You may obtain
 | 
				
			||||||
 | 
					#    a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#         http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#    Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
				
			||||||
 | 
					#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
				
			||||||
 | 
					#    License for the specific language governing permissions and limitations
 | 
				
			||||||
 | 
					#    under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from tempest.lib.common.utils import data_utils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from openstackclient.tests.functional.identity.v3 import common
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class LimitTestCase(common.IdentityTests):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_create_with_service_name(self):
 | 
				
			||||||
 | 
					        registered_limit_id = self._create_dummy_registered_limit()
 | 
				
			||||||
 | 
					        raw_output = self.openstack(
 | 
				
			||||||
 | 
					            'registered limit show %s' % registered_limit_id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        service_id = self._extract_value_from_items('service_id', items)
 | 
				
			||||||
 | 
					        resource_name = self._extract_value_from_items('resource_name', items)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        raw_output = self.openstack('service show %s' % service_id)
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        service_name = self._extract_value_from_items('name', items)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        project_name = self._create_dummy_project()
 | 
				
			||||||
 | 
					        raw_output = self.openstack('project show %s' % project_name)
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        project_id = self._extract_value_from_items('id', items)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        params = {
 | 
				
			||||||
 | 
					            'project_id': project_id,
 | 
				
			||||||
 | 
					            'service_name': service_name,
 | 
				
			||||||
 | 
					            'resource_name': resource_name,
 | 
				
			||||||
 | 
					            'resource_limit': 15
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        raw_output = self.openstack(
 | 
				
			||||||
 | 
					            'limit create'
 | 
				
			||||||
 | 
					            ' --project %(project_id)s'
 | 
				
			||||||
 | 
					            ' --service %(service_name)s'
 | 
				
			||||||
 | 
					            ' --resource-limit %(resource_limit)s'
 | 
				
			||||||
 | 
					            ' %(resource_name)s' % params
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        limit_id = self._extract_value_from_items('id', items)
 | 
				
			||||||
 | 
					        self.addCleanup(self.openstack, 'limit delete %s' % limit_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_show_fields(items, self.LIMIT_FIELDS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_create_with_project_name(self):
 | 
				
			||||||
 | 
					        registered_limit_id = self._create_dummy_registered_limit()
 | 
				
			||||||
 | 
					        raw_output = self.openstack(
 | 
				
			||||||
 | 
					            'registered limit show %s' % registered_limit_id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        service_id = self._extract_value_from_items('service_id', items)
 | 
				
			||||||
 | 
					        resource_name = self._extract_value_from_items('resource_name', items)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        raw_output = self.openstack('service show %s' % service_id)
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        service_name = self._extract_value_from_items('name', items)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        project_name = self._create_dummy_project()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        params = {
 | 
				
			||||||
 | 
					            'project_name': project_name,
 | 
				
			||||||
 | 
					            'service_name': service_name,
 | 
				
			||||||
 | 
					            'resource_name': resource_name,
 | 
				
			||||||
 | 
					            'resource_limit': 15
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        raw_output = self.openstack(
 | 
				
			||||||
 | 
					            'limit create'
 | 
				
			||||||
 | 
					            ' --project %(project_name)s'
 | 
				
			||||||
 | 
					            ' --service %(service_name)s'
 | 
				
			||||||
 | 
					            ' --resource-limit %(resource_limit)s'
 | 
				
			||||||
 | 
					            ' %(resource_name)s' % params
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        limit_id = self._extract_value_from_items('id', items)
 | 
				
			||||||
 | 
					        self.addCleanup(self.openstack, 'limit delete %s' % limit_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_show_fields(items, self.LIMIT_FIELDS)
 | 
				
			||||||
 | 
					        registered_limit_id = self._create_dummy_registered_limit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_create_with_service_id(self):
 | 
				
			||||||
 | 
					        self._create_dummy_limit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_create_with_project_id(self):
 | 
				
			||||||
 | 
					        self._create_dummy_limit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_create_with_options(self):
 | 
				
			||||||
 | 
					        registered_limit_id = self._create_dummy_registered_limit()
 | 
				
			||||||
 | 
					        region_id = self._create_dummy_region()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        params = {
 | 
				
			||||||
 | 
					            'region_id': region_id,
 | 
				
			||||||
 | 
					            'registered_limit_id': registered_limit_id
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        raw_output = self.openstack(
 | 
				
			||||||
 | 
					            'registered limit set'
 | 
				
			||||||
 | 
					            ' %(registered_limit_id)s'
 | 
				
			||||||
 | 
					            ' --region %(region_id)s' % params
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        service_id = self._extract_value_from_items('service_id', items)
 | 
				
			||||||
 | 
					        resource_name = self._extract_value_from_items('resource_name', items)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        project_name = self._create_dummy_project()
 | 
				
			||||||
 | 
					        raw_output = self.openstack('project show %s' % project_name)
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        project_id = self._extract_value_from_items('id', items)
 | 
				
			||||||
 | 
					        description = data_utils.arbitrary_string()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        params = {
 | 
				
			||||||
 | 
					            'project_id': project_id,
 | 
				
			||||||
 | 
					            'service_id': service_id,
 | 
				
			||||||
 | 
					            'resource_name': resource_name,
 | 
				
			||||||
 | 
					            'resource_limit': 15,
 | 
				
			||||||
 | 
					            'region_id': region_id,
 | 
				
			||||||
 | 
					            'description': description
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        raw_output = self.openstack(
 | 
				
			||||||
 | 
					            'limit create'
 | 
				
			||||||
 | 
					            ' --project %(project_id)s'
 | 
				
			||||||
 | 
					            ' --service %(service_id)s'
 | 
				
			||||||
 | 
					            ' --resource-limit %(resource_limit)s'
 | 
				
			||||||
 | 
					            ' --region %(region_id)s'
 | 
				
			||||||
 | 
					            ' --description %(description)s'
 | 
				
			||||||
 | 
					            ' %(resource_name)s' % params
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        limit_id = self._extract_value_from_items('id', items)
 | 
				
			||||||
 | 
					        self.addCleanup(self.openstack, 'limit delete %s' % limit_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assert_show_fields(items, self.LIMIT_FIELDS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_show(self):
 | 
				
			||||||
 | 
					        limit_id = self._create_dummy_limit()
 | 
				
			||||||
 | 
					        raw_output = self.openstack('limit show %s' % limit_id)
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        self.assert_show_fields(items, self.LIMIT_FIELDS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_set_description(self):
 | 
				
			||||||
 | 
					        limit_id = self._create_dummy_limit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        params = {
 | 
				
			||||||
 | 
					            'description': data_utils.arbitrary_string(),
 | 
				
			||||||
 | 
					            'limit_id': limit_id
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        raw_output = self.openstack(
 | 
				
			||||||
 | 
					            'limit set'
 | 
				
			||||||
 | 
					            ' --description %(description)s'
 | 
				
			||||||
 | 
					            ' %(limit_id)s' % params
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        self.assert_show_fields(items, self.LIMIT_FIELDS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_set_resource_limit(self):
 | 
				
			||||||
 | 
					        limit_id = self._create_dummy_limit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        params = {
 | 
				
			||||||
 | 
					            'resource_limit': 5,
 | 
				
			||||||
 | 
					            'limit_id': limit_id
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        raw_output = self.openstack(
 | 
				
			||||||
 | 
					            'limit set'
 | 
				
			||||||
 | 
					            ' --resource-limit %(resource_limit)s'
 | 
				
			||||||
 | 
					            ' %(limit_id)s' % params
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        items = self.parse_show(raw_output)
 | 
				
			||||||
 | 
					        self.assert_show_fields(items, self.LIMIT_FIELDS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_list(self):
 | 
				
			||||||
 | 
					        self._create_dummy_limit()
 | 
				
			||||||
 | 
					        raw_output = self.openstack('limit list')
 | 
				
			||||||
 | 
					        items = self.parse_listing(raw_output)
 | 
				
			||||||
 | 
					        self.assert_table_structure(items, self.LIMIT_LIST_HEADERS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_delete(self):
 | 
				
			||||||
 | 
					        limit_id = self._create_dummy_limit(add_clean_up=False)
 | 
				
			||||||
 | 
					        raw_output = self.openstack('limit delete %s' % limit_id)
 | 
				
			||||||
 | 
					        self.assertEqual(0, len(raw_output))
 | 
				
			||||||
@@ -507,6 +507,29 @@ REGISTERED_LIMIT_OPTIONS = {
 | 
				
			|||||||
    'region_id': region_id
 | 
					    'region_id': region_id
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					limit_id = 'limit-id'
 | 
				
			||||||
 | 
					limit_resource_limit = 15
 | 
				
			||||||
 | 
					limit_description = 'limit of foobars'
 | 
				
			||||||
 | 
					limit_resource_name = 'foobars'
 | 
				
			||||||
 | 
					LIMIT = {
 | 
				
			||||||
 | 
					    'id': limit_id,
 | 
				
			||||||
 | 
					    'project_id': project_id,
 | 
				
			||||||
 | 
					    'resource_limit': limit_resource_limit,
 | 
				
			||||||
 | 
					    'resource_name': limit_resource_name,
 | 
				
			||||||
 | 
					    'service_id': service_id,
 | 
				
			||||||
 | 
					    'description': None,
 | 
				
			||||||
 | 
					    'region_id': None
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					LIMIT_OPTIONS = {
 | 
				
			||||||
 | 
					    'id': limit_id,
 | 
				
			||||||
 | 
					    'project_id': project_id,
 | 
				
			||||||
 | 
					    'resource_limit': limit_resource_limit,
 | 
				
			||||||
 | 
					    'resource_name': limit_resource_name,
 | 
				
			||||||
 | 
					    'service_id': service_id,
 | 
				
			||||||
 | 
					    'description': limit_description,
 | 
				
			||||||
 | 
					    'region_id': region_id
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def fake_auth_ref(fake_token, fake_service=None):
 | 
					def fake_auth_ref(fake_token, fake_service=None):
 | 
				
			||||||
    """Create an auth_ref using keystoneauth's fixtures"""
 | 
					    """Create an auth_ref using keystoneauth's fixtures"""
 | 
				
			||||||
@@ -601,6 +624,8 @@ class FakeIdentityv3Client(object):
 | 
				
			|||||||
        self.inference_rules.resource_class = fakes.FakeResource(None, {})
 | 
					        self.inference_rules.resource_class = fakes.FakeResource(None, {})
 | 
				
			||||||
        self.registered_limits = mock.Mock()
 | 
					        self.registered_limits = mock.Mock()
 | 
				
			||||||
        self.registered_limits.resource_class = fakes.FakeResource(None, {})
 | 
					        self.registered_limits.resource_class = fakes.FakeResource(None, {})
 | 
				
			||||||
 | 
					        self.limits = mock.Mock()
 | 
				
			||||||
 | 
					        self.limits.resource_class = fakes.FakeResource(None, {})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FakeFederationManager(object):
 | 
					class FakeFederationManager(object):
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										382
									
								
								openstackclient/tests/unit/identity/v3/test_limit.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										382
									
								
								openstackclient/tests/unit/identity/v3/test_limit.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,382 @@
 | 
				
			|||||||
 | 
					#   Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
				
			||||||
 | 
					#   not use this file except in compliance with the License. You may obtain
 | 
				
			||||||
 | 
					#   a copy of the License at
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#        http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#   Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					#   distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
				
			||||||
 | 
					#   WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
				
			||||||
 | 
					#   License for the specific language governing permissions and limitations
 | 
				
			||||||
 | 
					#   under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import copy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from keystoneauth1.exceptions import http as ksa_exceptions
 | 
				
			||||||
 | 
					from osc_lib import exceptions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from openstackclient.identity.v3 import limit
 | 
				
			||||||
 | 
					from openstackclient.tests.unit import fakes
 | 
				
			||||||
 | 
					from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestLimit(identity_fakes.TestIdentityv3):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        super(TestLimit, self).setUp()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        identity_manager = self.app.client_manager.identity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.limit_mock = identity_manager.limits
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.services_mock = identity_manager.services
 | 
				
			||||||
 | 
					        self.services_mock.reset_mock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.projects_mock = identity_manager.projects
 | 
				
			||||||
 | 
					        self.projects_mock.reset_mock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.regions_mock = identity_manager.regions
 | 
				
			||||||
 | 
					        self.regions_mock.reset_mock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestLimitCreate(TestLimit):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        super(TestLimitCreate, self).setUp()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.service = fakes.FakeResource(
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            copy.deepcopy(identity_fakes.SERVICE),
 | 
				
			||||||
 | 
					            loaded=True
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.services_mock.get.return_value = self.service
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.project = fakes.FakeResource(
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            copy.deepcopy(identity_fakes.PROJECT),
 | 
				
			||||||
 | 
					            loaded=True
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.projects_mock.get.return_value = self.project
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.region = fakes.FakeResource(
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            copy.deepcopy(identity_fakes.REGION),
 | 
				
			||||||
 | 
					            loaded=True
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.regions_mock.get.return_value = self.region
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.cmd = limit.CreateLimit(self.app, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_create_without_options(self):
 | 
				
			||||||
 | 
					        self.limit_mock.create.return_value = fakes.FakeResource(
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            copy.deepcopy(identity_fakes.LIMIT),
 | 
				
			||||||
 | 
					            loaded=True
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        resource_limit = 15
 | 
				
			||||||
 | 
					        arglist = [
 | 
				
			||||||
 | 
					            '--project', identity_fakes.project_id,
 | 
				
			||||||
 | 
					            '--service', identity_fakes.service_id,
 | 
				
			||||||
 | 
					            '--resource-limit', str(resource_limit),
 | 
				
			||||||
 | 
					            identity_fakes.limit_resource_name
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        verifylist = [
 | 
				
			||||||
 | 
					            ('project', identity_fakes.project_id),
 | 
				
			||||||
 | 
					            ('service', identity_fakes.service_id),
 | 
				
			||||||
 | 
					            ('resource_name', identity_fakes.limit_resource_name),
 | 
				
			||||||
 | 
					            ('resource_limit', resource_limit)
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        columns, data = self.cmd.take_action(parsed_args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        kwargs = {'description': None, 'region': None}
 | 
				
			||||||
 | 
					        self.limit_mock.create.assert_called_with(
 | 
				
			||||||
 | 
					            self.project,
 | 
				
			||||||
 | 
					            self.service,
 | 
				
			||||||
 | 
					            identity_fakes.limit_resource_name,
 | 
				
			||||||
 | 
					            resource_limit,
 | 
				
			||||||
 | 
					            **kwargs
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        collist = ('description', 'id', 'project_id', 'region_id',
 | 
				
			||||||
 | 
					                   'resource_limit', 'resource_name', 'service_id')
 | 
				
			||||||
 | 
					        self.assertEqual(collist, columns)
 | 
				
			||||||
 | 
					        datalist = (
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            identity_fakes.limit_id,
 | 
				
			||||||
 | 
					            identity_fakes.project_id,
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            resource_limit,
 | 
				
			||||||
 | 
					            identity_fakes.limit_resource_name,
 | 
				
			||||||
 | 
					            identity_fakes.service_id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertEqual(datalist, data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_create_with_options(self):
 | 
				
			||||||
 | 
					        self.limit_mock.create.return_value = fakes.FakeResource(
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            copy.deepcopy(identity_fakes.LIMIT_OPTIONS),
 | 
				
			||||||
 | 
					            loaded=True
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        resource_limit = 15
 | 
				
			||||||
 | 
					        arglist = [
 | 
				
			||||||
 | 
					            '--project', identity_fakes.project_id,
 | 
				
			||||||
 | 
					            '--service', identity_fakes.service_id,
 | 
				
			||||||
 | 
					            '--resource-limit', str(resource_limit),
 | 
				
			||||||
 | 
					            '--region', identity_fakes.region_id,
 | 
				
			||||||
 | 
					            '--description', identity_fakes.limit_description,
 | 
				
			||||||
 | 
					            identity_fakes.limit_resource_name
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        verifylist = [
 | 
				
			||||||
 | 
					            ('project', identity_fakes.project_id),
 | 
				
			||||||
 | 
					            ('service', identity_fakes.service_id),
 | 
				
			||||||
 | 
					            ('resource_name', identity_fakes.limit_resource_name),
 | 
				
			||||||
 | 
					            ('resource_limit', resource_limit),
 | 
				
			||||||
 | 
					            ('region', identity_fakes.region_id),
 | 
				
			||||||
 | 
					            ('description', identity_fakes.limit_description)
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        columns, data = self.cmd.take_action(parsed_args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        kwargs = {
 | 
				
			||||||
 | 
					            'description': identity_fakes.limit_description,
 | 
				
			||||||
 | 
					            'region': self.region
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        self.limit_mock.create.assert_called_with(
 | 
				
			||||||
 | 
					            self.project,
 | 
				
			||||||
 | 
					            self.service,
 | 
				
			||||||
 | 
					            identity_fakes.limit_resource_name,
 | 
				
			||||||
 | 
					            resource_limit,
 | 
				
			||||||
 | 
					            **kwargs
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        collist = ('description', 'id', 'project_id', 'region_id',
 | 
				
			||||||
 | 
					                   'resource_limit', 'resource_name', 'service_id')
 | 
				
			||||||
 | 
					        self.assertEqual(collist, columns)
 | 
				
			||||||
 | 
					        datalist = (
 | 
				
			||||||
 | 
					            identity_fakes.limit_description,
 | 
				
			||||||
 | 
					            identity_fakes.limit_id,
 | 
				
			||||||
 | 
					            identity_fakes.project_id,
 | 
				
			||||||
 | 
					            identity_fakes.region_id,
 | 
				
			||||||
 | 
					            resource_limit,
 | 
				
			||||||
 | 
					            identity_fakes.limit_resource_name,
 | 
				
			||||||
 | 
					            identity_fakes.service_id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertEqual(datalist, data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestLimitDelete(TestLimit):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        super(TestLimitDelete, self).setUp()
 | 
				
			||||||
 | 
					        self.cmd = limit.DeleteLimit(self.app, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_delete(self):
 | 
				
			||||||
 | 
					        self.limit_mock.delete.return_value = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        arglist = [identity_fakes.limit_id]
 | 
				
			||||||
 | 
					        verifylist = [
 | 
				
			||||||
 | 
					            ('limit_id', [identity_fakes.limit_id])
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        result = self.cmd.take_action(parsed_args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.limit_mock.delete.assert_called_with(
 | 
				
			||||||
 | 
					            identity_fakes.limit_id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertIsNone(result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_delete_with_exception(self):
 | 
				
			||||||
 | 
					        return_value = ksa_exceptions.NotFound()
 | 
				
			||||||
 | 
					        self.limit_mock.delete.side_effect = return_value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        arglist = ['fake-limit-id']
 | 
				
			||||||
 | 
					        verifylist = [
 | 
				
			||||||
 | 
					            ('limit_id', ['fake-limit-id'])
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            self.cmd.take_action(parsed_args)
 | 
				
			||||||
 | 
					            self.fail('CommandError should be raised.')
 | 
				
			||||||
 | 
					        except exceptions.CommandError as e:
 | 
				
			||||||
 | 
					            self.assertEqual(
 | 
				
			||||||
 | 
					                '1 of 1 limits failed to delete.', str(e)
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestLimitShow(TestLimit):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        super(TestLimitShow, self).setUp()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.limit_mock.get.return_value = fakes.FakeResource(
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            copy.deepcopy(identity_fakes.LIMIT),
 | 
				
			||||||
 | 
					            loaded=True
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.cmd = limit.ShowLimit(self.app, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_show(self):
 | 
				
			||||||
 | 
					        arglist = [identity_fakes.limit_id]
 | 
				
			||||||
 | 
					        verifylist = [('limit_id', identity_fakes.limit_id)]
 | 
				
			||||||
 | 
					        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        columns, data = self.cmd.take_action(parsed_args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.limit_mock.get.assert_called_with(identity_fakes.limit_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        collist = (
 | 
				
			||||||
 | 
					            'description', 'id', 'project_id', 'region_id', 'resource_limit',
 | 
				
			||||||
 | 
					            'resource_name', 'service_id'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertEqual(collist, columns)
 | 
				
			||||||
 | 
					        datalist = (
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            identity_fakes.limit_id,
 | 
				
			||||||
 | 
					            identity_fakes.project_id,
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            identity_fakes.limit_resource_limit,
 | 
				
			||||||
 | 
					            identity_fakes.limit_resource_name,
 | 
				
			||||||
 | 
					            identity_fakes.service_id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertEqual(datalist, data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestLimitSet(TestLimit):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        super(TestLimitSet, self).setUp()
 | 
				
			||||||
 | 
					        self.cmd = limit.SetLimit(self.app, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_set_description(self):
 | 
				
			||||||
 | 
					        limit = copy.deepcopy(identity_fakes.LIMIT)
 | 
				
			||||||
 | 
					        limit['description'] = identity_fakes.limit_description
 | 
				
			||||||
 | 
					        self.limit_mock.update.return_value = fakes.FakeResource(
 | 
				
			||||||
 | 
					            None, limit, loaded=True
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        arglist = [
 | 
				
			||||||
 | 
					            '--description', identity_fakes.limit_description,
 | 
				
			||||||
 | 
					            identity_fakes.limit_id
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        verifylist = [
 | 
				
			||||||
 | 
					            ('description', identity_fakes.limit_description),
 | 
				
			||||||
 | 
					            ('limit_id', identity_fakes.limit_id)
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        columns, data = self.cmd.take_action(parsed_args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.limit_mock.update.assert_called_with(
 | 
				
			||||||
 | 
					            identity_fakes.limit_id,
 | 
				
			||||||
 | 
					            description=identity_fakes.limit_description,
 | 
				
			||||||
 | 
					            resource_limit=None
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        collist = (
 | 
				
			||||||
 | 
					            'description', 'id', 'project_id', 'region_id', 'resource_limit',
 | 
				
			||||||
 | 
					            'resource_name', 'service_id'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertEqual(collist, columns)
 | 
				
			||||||
 | 
					        datalist = (
 | 
				
			||||||
 | 
					            identity_fakes.limit_description,
 | 
				
			||||||
 | 
					            identity_fakes.limit_id,
 | 
				
			||||||
 | 
					            identity_fakes.project_id,
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            identity_fakes.limit_resource_limit,
 | 
				
			||||||
 | 
					            identity_fakes.limit_resource_name,
 | 
				
			||||||
 | 
					            identity_fakes.service_id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertEqual(datalist, data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_set_resource_limit(self):
 | 
				
			||||||
 | 
					        resource_limit = 20
 | 
				
			||||||
 | 
					        limit = copy.deepcopy(identity_fakes.LIMIT)
 | 
				
			||||||
 | 
					        limit['resource_limit'] = resource_limit
 | 
				
			||||||
 | 
					        self.limit_mock.update.return_value = fakes.FakeResource(
 | 
				
			||||||
 | 
					            None, limit, loaded=True
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        arglist = [
 | 
				
			||||||
 | 
					            '--resource-limit', str(resource_limit),
 | 
				
			||||||
 | 
					            identity_fakes.limit_id
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        verifylist = [
 | 
				
			||||||
 | 
					            ('resource_limit', resource_limit),
 | 
				
			||||||
 | 
					            ('limit_id', identity_fakes.limit_id)
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        columns, data = self.cmd.take_action(parsed_args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.limit_mock.update.assert_called_with(
 | 
				
			||||||
 | 
					            identity_fakes.limit_id,
 | 
				
			||||||
 | 
					            description=None,
 | 
				
			||||||
 | 
					            resource_limit=resource_limit
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        collist = (
 | 
				
			||||||
 | 
					            'description', 'id', 'project_id', 'region_id', 'resource_limit',
 | 
				
			||||||
 | 
					            'resource_name', 'service_id'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertEqual(collist, columns)
 | 
				
			||||||
 | 
					        datalist = (
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            identity_fakes.limit_id,
 | 
				
			||||||
 | 
					            identity_fakes.project_id,
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            resource_limit,
 | 
				
			||||||
 | 
					            identity_fakes.limit_resource_name,
 | 
				
			||||||
 | 
					            identity_fakes.service_id
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertEqual(datalist, data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestLimitList(TestLimit):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        super(TestLimitList, self).setUp()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.limit_mock.list.return_value = [
 | 
				
			||||||
 | 
					            fakes.FakeResource(
 | 
				
			||||||
 | 
					                None,
 | 
				
			||||||
 | 
					                copy.deepcopy(identity_fakes.LIMIT),
 | 
				
			||||||
 | 
					                loaded=True
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.cmd = limit.ListLimit(self.app, None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_limit_list(self):
 | 
				
			||||||
 | 
					        arglist = []
 | 
				
			||||||
 | 
					        verifylist = []
 | 
				
			||||||
 | 
					        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        columns, data = self.cmd.take_action(parsed_args)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.limit_mock.list.assert_called_with(
 | 
				
			||||||
 | 
					            service=None, resource_name=None, region=None
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        collist = (
 | 
				
			||||||
 | 
					            'ID', 'Project ID', 'Service ID', 'Resource Name',
 | 
				
			||||||
 | 
					            'Resource Limit', 'Description', 'Region ID'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        self.assertEqual(collist, columns)
 | 
				
			||||||
 | 
					        datalist = ((
 | 
				
			||||||
 | 
					            identity_fakes.limit_id,
 | 
				
			||||||
 | 
					            identity_fakes.project_id,
 | 
				
			||||||
 | 
					            identity_fakes.service_id,
 | 
				
			||||||
 | 
					            identity_fakes.limit_resource_name,
 | 
				
			||||||
 | 
					            identity_fakes.limit_resource_limit,
 | 
				
			||||||
 | 
					            None,
 | 
				
			||||||
 | 
					            None
 | 
				
			||||||
 | 
					        ), )
 | 
				
			||||||
 | 
					        self.assertEqual(datalist, tuple(data))
 | 
				
			||||||
@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					features:
 | 
				
			||||||
 | 
					  - |
 | 
				
			||||||
 | 
					    [`bp unified-limits <https://blueprints.launchpad.net/keystone/+spec/unified-limit>`_]
 | 
				
			||||||
 | 
					    Support has been added for managing project-specific limits in keystone via
 | 
				
			||||||
 | 
					    the ``limit`` command. Limits define limits of resources for projects to
 | 
				
			||||||
 | 
					    consume once a limit has been registered.
 | 
				
			||||||
@@ -268,6 +268,12 @@ openstack.identity.v3 =
 | 
				
			|||||||
    implied_role_delete = openstackclient.identity.v3.implied_role:DeleteImpliedRole
 | 
					    implied_role_delete = openstackclient.identity.v3.implied_role:DeleteImpliedRole
 | 
				
			||||||
    implied_role_list = openstackclient.identity.v3.implied_role:ListImpliedRole
 | 
					    implied_role_list = openstackclient.identity.v3.implied_role:ListImpliedRole
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    limit_create = openstackclient.identity.v3.limit:CreateLimit
 | 
				
			||||||
 | 
					    limit_delete = openstackclient.identity.v3.limit:DeleteLimit
 | 
				
			||||||
 | 
					    limit_list = openstackclient.identity.v3.limit:ListLimit
 | 
				
			||||||
 | 
					    limit_set = openstackclient.identity.v3.limit:SetLimit
 | 
				
			||||||
 | 
					    limit_show = openstackclient.identity.v3.limit:ShowLimit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    mapping_create = openstackclient.identity.v3.mapping:CreateMapping
 | 
					    mapping_create = openstackclient.identity.v3.mapping:CreateMapping
 | 
				
			||||||
    mapping_delete = openstackclient.identity.v3.mapping:DeleteMapping
 | 
					    mapping_delete = openstackclient.identity.v3.mapping:DeleteMapping
 | 
				
			||||||
    mapping_list = openstackclient.identity.v3.mapping:ListMapping
 | 
					    mapping_list = openstackclient.identity.v3.mapping:ListMapping
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user