Skip to content

Commit 6469d86

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Implement support for project limits"
2 parents d177727 + 735896e commit 6469d86

8 files changed

Lines changed: 1021 additions & 0 deletions

File tree

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
=====
2+
limit
3+
=====
4+
5+
Identity v3
6+
7+
Limits are used to specify project-specific limits thresholds of resources.
8+
9+
limit create
10+
------------
11+
12+
Create a new limit
13+
14+
.. program:: limit create
15+
.. code:: bash
16+
17+
openstack limit create
18+
[--description <description>]
19+
[--region <region>]
20+
--project <project>
21+
--service <service>
22+
--resource-limit <resource-limit>
23+
<resource-name>
24+
25+
.. option:: --description <description>
26+
27+
Useful description of the limit or its purpose
28+
29+
.. option:: --region <region>
30+
31+
Region that the limit should be applied to
32+
33+
.. describe:: --project <project>
34+
35+
The project that the limit applies to (required)
36+
37+
.. describe:: --service <service>
38+
39+
The service that is responsible for the resource being limited (required)
40+
41+
.. describe:: --resource-limit <resource-limit>
42+
43+
The limit to apply to the project (required)
44+
45+
.. describe:: <resource-name>
46+
47+
The name of the resource to limit (e.g. cores or volumes)
48+
49+
limit delete
50+
------------
51+
52+
Delete project-specific limit(s)
53+
54+
.. program:: limit delete
55+
.. code:: bash
56+
57+
openstack limit delete
58+
<limit-id> [<limit-id> ...]
59+
60+
.. describe:: <limit-id>
61+
62+
Limit(s) to delete (ID)
63+
64+
limit list
65+
----------
66+
67+
List project-specific limits
68+
69+
.. program:: limit list
70+
.. code:: bash
71+
72+
openstack limit list
73+
[--service <service>]
74+
[--resource-name <resource-name>]
75+
[--region <region>]
76+
77+
.. option:: --service <service>
78+
79+
The service to filter the response by (name or ID)
80+
81+
.. option:: --resource-name <resource-name>
82+
83+
The name of the resource to filter the response by
84+
85+
.. option:: --region <region>
86+
87+
The region name to filter the response by
88+
89+
limit show
90+
----------
91+
92+
Display details about a limit
93+
94+
.. program:: limit show
95+
.. code:: bash
96+
97+
openstack limit show
98+
<limit-id>
99+
100+
.. describe:: <limit-id>
101+
102+
Limit to display (ID)
103+
104+
limit set
105+
---------
106+
107+
Update a limit
108+
109+
.. program:: limit show
110+
.. code:: bash
111+
112+
openstack limit set
113+
[--description <description>]
114+
[--resource-limit <resource-limit>]
115+
<limit-id>
116+
117+
118+
.. option:: --description <description>
119+
120+
Useful description of the limit or its purpose
121+
122+
.. option:: --resource-limit <resource-limit>
123+
124+
The limit to apply to the project
125+
126+
.. describe:: <limit-id>
127+
128+
Limit to update (ID)
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
2+
# not use this file except in compliance with the License. You may obtain
3+
# a copy of the License at
4+
#
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
#
7+
# Unless required by applicable law or agreed to in writing, software
8+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10+
# License for the specific language governing permissions and limitations
11+
# under the License.
12+
#
13+
14+
"""Limits action implementations."""
15+
16+
import logging
17+
18+
from osc_lib.command import command
19+
from osc_lib import exceptions
20+
from osc_lib import utils
21+
import six
22+
23+
from openstackclient.i18n import _
24+
from openstackclient.identity import common as common_utils
25+
26+
LOG = logging.getLogger(__name__)
27+
28+
29+
class CreateLimit(command.ShowOne):
30+
_description = _("Create a limit")
31+
32+
def get_parser(self, prog_name):
33+
parser = super(CreateLimit, self).get_parser(prog_name)
34+
parser.add_argument(
35+
'--description',
36+
metavar='<description>',
37+
help=_('Description of the limit'),
38+
)
39+
parser.add_argument(
40+
'--region',
41+
metavar='<region>',
42+
help=_('Region for the limit to affect.'),
43+
)
44+
parser.add_argument(
45+
'--project',
46+
metavar='<project>',
47+
required=True,
48+
help=_('Project to associate the resource limit to'),
49+
)
50+
parser.add_argument(
51+
'--service',
52+
metavar='<service>',
53+
required=True,
54+
help=_('Service responsible for the resource to limit'),
55+
)
56+
parser.add_argument(
57+
'--resource-limit',
58+
metavar='<resource-limit>',
59+
required=True,
60+
type=int,
61+
help=_('The resource limit for the project to assume'),
62+
)
63+
parser.add_argument(
64+
'resource_name',
65+
metavar='<resource-name>',
66+
help=_('The name of the resource to limit'),
67+
)
68+
return parser
69+
70+
def take_action(self, parsed_args):
71+
identity_client = self.app.client_manager.identity
72+
73+
project = common_utils.find_project(
74+
identity_client, parsed_args.project
75+
)
76+
service = common_utils.find_service(
77+
identity_client, parsed_args.service
78+
)
79+
region = None
80+
if parsed_args.region:
81+
region = utils.find_resource(
82+
identity_client.regions, parsed_args.region
83+
)
84+
85+
limit = identity_client.limits.create(
86+
project,
87+
service,
88+
parsed_args.resource_name,
89+
parsed_args.resource_limit,
90+
description=parsed_args.description,
91+
region=region
92+
)
93+
94+
limit._info.pop('links', None)
95+
return zip(*sorted(six.iteritems(limit._info)))
96+
97+
98+
class ListLimit(command.Lister):
99+
_description = _("List limits")
100+
101+
def get_parser(self, prog_name):
102+
parser = super(ListLimit, self).get_parser(prog_name)
103+
parser.add_argument(
104+
'--service',
105+
metavar='<service>',
106+
help=_('Service responsible for the resource to limit'),
107+
)
108+
parser.add_argument(
109+
'--resource-name',
110+
metavar='<resource-name>',
111+
dest='resource_name',
112+
help=_('The name of the resource to limit'),
113+
)
114+
parser.add_argument(
115+
'--region',
116+
metavar='<region>',
117+
help=_('Region for the registered limit to affect.'),
118+
)
119+
return parser
120+
121+
def take_action(self, parsed_args):
122+
identity_client = self.app.client_manager.identity
123+
124+
service = None
125+
if parsed_args.service:
126+
service = common_utils.find_service(
127+
identity_client, parsed_args.service
128+
)
129+
region = None
130+
if parsed_args.region:
131+
region = utils.find_resource(
132+
identity_client.regions, parsed_args.region
133+
)
134+
135+
limits = identity_client.limits.list(
136+
service=service,
137+
resource_name=parsed_args.resource_name,
138+
region=region
139+
)
140+
141+
columns = (
142+
'ID', 'Project ID', 'Service ID', 'Resource Name',
143+
'Resource Limit', 'Description', 'Region ID'
144+
)
145+
return (
146+
columns,
147+
(utils.get_item_properties(s, columns) for s in limits),
148+
)
149+
150+
151+
class ShowLimit(command.ShowOne):
152+
_description = _("Display limit details")
153+
154+
def get_parser(self, prog_name):
155+
parser = super(ShowLimit, self).get_parser(prog_name)
156+
parser.add_argument(
157+
'limit_id',
158+
metavar='<limit-id>',
159+
help=_('Limit to display (ID)'),
160+
)
161+
return parser
162+
163+
def take_action(self, parsed_args):
164+
identity_client = self.app.client_manager.identity
165+
limit = identity_client.limits.get(parsed_args.limit_id)
166+
limit._info.pop('links', None)
167+
return zip(*sorted(six.iteritems(limit._info)))
168+
169+
170+
class SetLimit(command.ShowOne):
171+
_description = _("Update information about a limit")
172+
173+
def get_parser(self, prog_name):
174+
parser = super(SetLimit, self).get_parser(prog_name)
175+
parser.add_argument(
176+
'limit_id',
177+
metavar='<limit-id>',
178+
help=_('Limit to update (ID)'),
179+
)
180+
parser.add_argument(
181+
'--description',
182+
metavar='<description>',
183+
help=_('Description of the limit'),
184+
)
185+
parser.add_argument(
186+
'--resource-limit',
187+
metavar='<resource-limit>',
188+
dest='resource_limit',
189+
type=int,
190+
help=_('The resource limit for the project to assume'),
191+
)
192+
return parser
193+
194+
def take_action(self, parsed_args):
195+
identity_client = self.app.client_manager.identity
196+
197+
limit = identity_client.limits.update(
198+
parsed_args.limit_id,
199+
description=parsed_args.description,
200+
resource_limit=parsed_args.resource_limit
201+
)
202+
203+
limit._info.pop('links', None)
204+
205+
return zip(*sorted(six.iteritems(limit._info)))
206+
207+
208+
class DeleteLimit(command.Command):
209+
_description = _("Delete a limit")
210+
211+
def get_parser(self, prog_name):
212+
parser = super(DeleteLimit, self).get_parser(prog_name)
213+
parser.add_argument(
214+
'limit_id',
215+
metavar='<limit-id>',
216+
nargs="+",
217+
help=_('Limit to delete (ID)'),
218+
)
219+
return parser
220+
221+
def take_action(self, parsed_args):
222+
identity_client = self.app.client_manager.identity
223+
224+
errors = 0
225+
for limit_id in parsed_args.limit_id:
226+
try:
227+
identity_client.limits.delete(limit_id)
228+
except Exception as e:
229+
errors += 1
230+
LOG.error(_("Failed to delete limit with ID "
231+
"'%(id)s': %(e)s"),
232+
{'id': limit_id, 'e': e})
233+
234+
if errors > 0:
235+
total = len(parsed_args.limit_id)
236+
msg = (_("%(errors)s of %(total)s limits failed to "
237+
"delete.") % {'errors': errors, 'total': total})
238+
raise exceptions.CommandError(msg)

0 commit comments

Comments
 (0)