summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorM V P Nitesh <m.nitesh@nectechnologies.in>2017-09-21 15:38:55 +0530
committerDaniel Abad <d.abad@cern.ch>2018-02-28 12:14:54 +0000
commite6856282a30d3fff678d8e2592c825ad33314730 (patch)
tree3d5fb33f832669746b65ce4d1ee3bd0534f3b9f0
parent05ccd7f5fc20adae89330971c7c0cca2a1e354bb (diff)
OSC command for magnum quota's
Implemented Openstack command for quotas-create, quotas-update, quotas-delete, quotas-show and quotas-list. Change-Id: I889c2384afdf4cf113345af646b865271784c40c Partially-Implements: blueprint deprecate-magnum-client
Notes
Notes (review): Code-Review+2: Spyros Trigazis <strigazi@gmail.com> Workflow+1: Spyros Trigazis <strigazi@gmail.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Fri, 02 Mar 2018 12:24:38 +0000 Reviewed-on: https://review.openstack.org/506100 Project: openstack/python-magnumclient Branch: refs/heads/master
-rw-r--r--magnumclient/exceptions.py1
-rw-r--r--magnumclient/osc/v1/quotas.py215
-rw-r--r--magnumclient/tests/osc/unit/v1/fakes.py43
-rw-r--r--magnumclient/tests/osc/unit/v1/test_clusters.py146
-rw-r--r--magnumclient/tests/osc/unit/v1/test_quotas.py315
-rw-r--r--magnumclient/v1/quotas_shell.py5
-rw-r--r--releasenotes/notes/partial_osc_implementation_for_quotas-33f44c0496d721f8.yaml6
-rw-r--r--setup.cfg5
8 files changed, 736 insertions, 0 deletions
diff --git a/magnumclient/exceptions.py b/magnumclient/exceptions.py
index e78c336..d069f85 100644
--- a/magnumclient/exceptions.py
+++ b/magnumclient/exceptions.py
@@ -30,6 +30,7 @@ class AmbiguousAuthSystem(ClientException):
30 """Could not obtain token and endpoint using provided credentials.""" 30 """Could not obtain token and endpoint using provided credentials."""
31 pass 31 pass
32 32
33
33# Alias for backwards compatibility 34# Alias for backwards compatibility
34AmbigiousAuthSystem = AmbiguousAuthSystem 35AmbigiousAuthSystem = AmbiguousAuthSystem
35 36
diff --git a/magnumclient/osc/v1/quotas.py b/magnumclient/osc/v1/quotas.py
new file mode 100644
index 0000000..602294c
--- /dev/null
+++ b/magnumclient/osc/v1/quotas.py
@@ -0,0 +1,215 @@
1# Copyright 2015 NEC Corporation. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
15from magnumclient.common import cliutils as utils
16from magnumclient.common import utils as magnum_utils
17from magnumclient.i18n import _
18from osc_lib.command import command
19
20QUOTA_ATTRIBUTES = [
21 'resource',
22 'created_at',
23 'updated_at',
24 'hard_limit',
25 'project_id',
26 'id'
27]
28
29
30def _show_quota(quota):
31 utils.print_dict(quota._info)
32
33
34class CreateQuotas(command.Command):
35 _description = _("Create a quota.")
36
37 def get_parser(self, prog_name):
38 parser = super(CreateQuotas, self).get_parser(prog_name)
39 parser.add_argument('--project-id',
40 required=True,
41 metavar='<project-id>',
42 help='Project ID')
43 parser.add_argument('--resource',
44 required=True,
45 metavar='<resource>',
46 help='Resource name.')
47 parser.add_argument('--hard-limit',
48 metavar='<hard-limit>',
49 type=int,
50 default=1,
51 help='Max resource limit (default: hard-limit=1)')
52 return parser
53
54 def take_action(self, parsed_args):
55 self.log.debug("take_action(%s)", parsed_args)
56
57 mag_client = self.app.client_manager.container_infra
58
59 opts = {
60 'project_id': parsed_args.project_id,
61 'resource': parsed_args.resource,
62 'hard_limit': parsed_args.hard_limit
63 }
64 try:
65 quota = mag_client.quotas.create(**opts)
66 _show_quota(quota)
67 except Exception as e:
68 print("Create quota for project_id %(id)s resource %(res)s failed:"
69 " %(e)s" % {'id': parsed_args.project_id,
70 'res': parsed_args.resource,
71 'e': e})
72
73
74class DeleteQuotas(command.Command):
75 _description = _("Delete specified resource quota.")
76
77 def get_parser(self, prog_name):
78 parser = super(DeleteQuotas, self).get_parser(prog_name)
79 parser.add_argument('--project-id',
80 required=True,
81 metavar='<project-id>',
82 help='Project ID')
83 parser.add_argument('--resource',
84 required=True,
85 metavar='<resource>',
86 help='Resource name.')
87 return parser
88
89 def take_action(self, parsed_args):
90 self.log.debug("take_action(%s)", parsed_args)
91
92 mag_client = self.app.client_manager.container_infra
93
94 try:
95 mag_client.quotas.delete(parsed_args.project_id,
96 parsed_args.resource)
97 print("Request to delete quota for project id %(id)s and resource "
98 "%(res)s has been accepted." % {'id': parsed_args.project_id,
99 'res': parsed_args.resource})
100 except Exception as e:
101 print("Quota delete failed for project id %(id)s and resource "
102 "%(res)s :%(e)s" % {'id': parsed_args.project_id,
103 'res': parsed_args.resource,
104 'e': e})
105
106
107class ShowQuotas(command.Command):
108 _description = _("Show details about the given project resource quota.")
109
110 def get_parser(self, prog_name):
111 parser = super(ShowQuotas, self).get_parser(prog_name)
112 parser.add_argument('--project-id',
113 required=True,
114 metavar='<project-id>',
115 help='Project ID')
116 parser.add_argument('--resource',
117 required=True,
118 metavar='<resource>',
119 help='Resource name.')
120 return parser
121
122 def take_action(self, parsed_args):
123 self.log.debug("take_action(%s)", parsed_args)
124
125 mag_client = self.app.client_manager.container_infra
126 project_id = parsed_args.project_id
127 resource = parsed_args.resource
128 quota = mag_client.quotas.get(project_id, resource)
129 _show_quota(quota)
130
131
132class UpdateQuotas(command.Command):
133 _description = _("Update information about the given "
134 "project resource quota.")
135
136 def get_parser(self, prog_name):
137 parser = super(UpdateQuotas, self).get_parser(prog_name)
138 parser.add_argument('--project-id',
139 required=True,
140 metavar='<project-id>',
141 help='Project ID')
142 parser.add_argument('--resource',
143 required=True,
144 metavar='<resource>',
145 help='Resource name.')
146 parser.add_argument('--hard-limit',
147 metavar='<hard-limit>',
148 type=int,
149 default=1,
150 help='Max resource limit (default: hard-limit=1)')
151 return parser
152
153 def take_action(self, parsed_args):
154 self.log.debug("take_action(%s)", parsed_args)
155
156 mag_client = self.app.client_manager.container_infra
157
158 opts = {
159 'project_id': parsed_args.project_id,
160 'resource': parsed_args.resource,
161 'hard_limit': parsed_args.hard_limit
162 }
163 try:
164 quota = mag_client.quotas.update(parsed_args.project_id,
165 parsed_args.resource, opts)
166 _show_quota(quota)
167 except Exception as e:
168 print("Update quota for project_id %(id)s resource %(res)s failed:"
169 " %(e)s" % {'id': parsed_args.project_id,
170 'res': parsed_args.resource,
171 'e': e})
172
173
174class ListQuotas(command.Command):
175 _description = _("Print a list of available quotas.")
176
177 def get_parser(self, prog_name):
178 parser = super(ListQuotas, self).get_parser(prog_name)
179 parser.add_argument('--marker',
180 metavar='<marker>',
181 default=None,
182 help=_('The last quota UUID of the previous page; '
183 'displays list of quotas after "marker".'))
184 parser.add_argument('--limit',
185 metavar='<limit>',
186 type=int,
187 help='Maximum number of quotas to return.')
188 parser.add_argument('--sort-key',
189 metavar='<sort-key>',
190 help='Column to sort results by.')
191 parser.add_argument('--sort-dir',
192 metavar='<sort-dir>',
193 choices=['desc', 'asc'],
194 help='Direction to sort. "asc" or "desc".')
195 parser.add_argument('--all-tenants',
196 action='store_true',
197 default=False,
198 help='Flag to indicate list all tenant quotas.')
199 return parser
200
201 def take_action(self, parsed_args):
202 self.log.debug("take_action(%s)", parsed_args)
203
204 mag_client = self.app.client_manager.container_infra
205
206 quotas = mag_client.quotas.list(marker=parsed_args.marker,
207 limit=parsed_args.limit,
208 sort_key=parsed_args.sort_key,
209 sort_dir=parsed_args.sort_dir,
210 all_tenants=parsed_args.all_tenants)
211 columns = ['project_id', 'resource', 'hard_limit']
212 utils.print_list(quotas, columns,
213 {'versions':
214 magnum_utils.print_list_field('versions')},
215 sortby_index=None)
diff --git a/magnumclient/tests/osc/unit/v1/fakes.py b/magnumclient/tests/osc/unit/v1/fakes.py
index 3f60bb6..df11d41 100644
--- a/magnumclient/tests/osc/unit/v1/fakes.py
+++ b/magnumclient/tests/osc/unit/v1/fakes.py
@@ -51,6 +51,17 @@ class FakeStatsModelManager(object):
51 pass 51 pass
52 52
53 53
54class FakeQuotasModelManager(object):
55 def get(self, id, resource):
56 pass
57
58 def create(self, **kwargs):
59 pass
60
61 def delete(self, id):
62 pass
63
64
54class MagnumFakeContainerInfra(object): 65class MagnumFakeContainerInfra(object):
55 def __init__(self): 66 def __init__(self):
56 self.cluster_templates = FakeBaseModelManager() 67 self.cluster_templates = FakeBaseModelManager()
@@ -58,6 +69,7 @@ class MagnumFakeContainerInfra(object):
58 self.mservices = FakeBaseModelManager() 69 self.mservices = FakeBaseModelManager()
59 self.certificates = FakeBaseModelManager() 70 self.certificates = FakeBaseModelManager()
60 self.stats = FakeStatsModelManager() 71 self.stats = FakeStatsModelManager()
72 self.quotas = FakeQuotasModelManager()
61 73
62 74
63class MagnumFakeClientManager(osc_fakes.FakeClientManager): 75class MagnumFakeClientManager(osc_fakes.FakeClientManager):
@@ -223,3 +235,34 @@ class FakeCluster(object):
223 cluster = osc_fakes.FakeResource(info=copy.deepcopy(cluster_info), 235 cluster = osc_fakes.FakeResource(info=copy.deepcopy(cluster_info),
224 loaded=True) 236 loaded=True)
225 return cluster 237 return cluster
238
239
240class FakeQuota(object):
241 """Fake one or more Quota"""
242
243 @staticmethod
244 def create_one_quota(attrs=None):
245 """Create a fake quota
246
247 :param Dictionary attrs:
248 A dictionary with all attributes
249 :return:
250 A FakeResource object, with project_id, resource and so on
251 """
252
253 attrs = attrs or {}
254
255 quota_info = {
256 'resource': 'Cluster',
257 'created_at': '2017-09-15T05:40:34+00:00',
258 'updated_at': '2017-09-15T05:40:34+00:00',
259 'hard_limit': 1,
260 'project_id': 'be24b6fba2ed4476b2bd01fa8f0ba74e',
261 'id': 10,
262 'name': 'fake-quota',
263 }
264
265 quota_info.update(attrs)
266 quota = osc_fakes.FakeResource(info=copy.deepcopy(quota_info),
267 loaded=True)
268 return quota
diff --git a/magnumclient/tests/osc/unit/v1/test_clusters.py b/magnumclient/tests/osc/unit/v1/test_clusters.py
index a0bbe62..67375ba 100644
--- a/magnumclient/tests/osc/unit/v1/test_clusters.py
+++ b/magnumclient/tests/osc/unit/v1/test_clusters.py
@@ -15,8 +15,18 @@
15 15
16import copy 16import copy
17import mock 17import mock
18import os
19import sys
20import tempfile
21
22from contextlib import contextmanager
23try:
24 from StringIO import StringIO
25except ImportError:
26 from io import StringIO
18from mock import call 27from mock import call
19 28
29from magnumclient import exceptions
20from magnumclient.osc.v1 import clusters as osc_clusters 30from magnumclient.osc.v1 import clusters as osc_clusters
21from magnumclient.tests.osc.unit.v1 import fakes as magnum_fakes 31from magnumclient.tests.osc.unit.v1 import fakes as magnum_fakes
22 32
@@ -327,3 +337,139 @@ class TestClusterShow(TestCluster):
327 337
328 self.assertRaises(magnum_fakes.MagnumParseException, 338 self.assertRaises(magnum_fakes.MagnumParseException,
329 self.check_parser, self.cmd, arglist, verifylist) 339 self.check_parser, self.cmd, arglist, verifylist)
340
341
342@contextmanager
343def capture(command, *args, **kwargs):
344 out, sys.stdout = sys.stdout, StringIO()
345 try:
346 command(*args, **kwargs)
347 sys.stdout.seek(0)
348 yield sys.stdout.read()
349 finally:
350 sys.stdout = out
351
352
353class TestClusterConfig(TestCluster):
354
355 def setUp(self):
356 super(TestClusterConfig, self).setUp()
357
358 attr = dict()
359 attr['name'] = 'fake-cluster-1'
360 attr['status'] = 'CREATE_COMPLETE'
361 self._cluster = magnum_fakes.FakeCluster.create_one_cluster(attr)
362
363 self.clusters_mock.get = mock.Mock()
364 self.clusters_mock.get.return_value = self._cluster
365
366 # Fake the cluster_template
367 attr = dict()
368 attr['name'] = 'fake-ct'
369 attr['tls_disabled'] = True
370 self._cluster_template = \
371 magnum_fakes.FakeClusterTemplate.create_one_cluster_template(attr)
372
373 self.cluster_templates_mock = \
374 self.app.client_manager.container_infra.cluster_templates
375 self.cluster_templates_mock.get = mock.Mock()
376 self.cluster_templates_mock.get.return_value = self._cluster_template
377
378 # Get the command object to test
379 self.cmd = osc_clusters.ConfigCluster(self.app, None)
380
381 def test_cluster_config_no_cluster_fail(self):
382 arglist = []
383 verifylist = []
384
385 self.assertRaises(magnum_fakes.MagnumParseException,
386 self.check_parser, self.cmd, arglist, verifylist)
387
388 @mock.patch.dict(os.environ, {'SHELL': '/bin/bash'})
389 def test_cluster_config_custom_dir_with_config_only_works_if_force(self):
390 tmp_dir = tempfile.mkdtemp()
391 open(os.path.join(tmp_dir, 'config'), 'a').close() # touch config
392
393 arglist = ['fake-cluster', '--dir', tmp_dir]
394 verifylist = [
395 ('cluster', 'fake-cluster'),
396 ('force', False),
397 ('dir', tmp_dir),
398 ]
399 parsed_args = self.check_parser(self.cmd, arglist, verifylist)
400 self.assertRaises(exceptions.CommandError,
401 self.cmd.take_action, parsed_args)
402
403 self.clusters_mock.get.assert_called_with('fake-cluster')
404
405 arglist = ['fake-cluster', '--force', '--dir', tmp_dir]
406 verifylist = [
407 ('cluster', 'fake-cluster'),
408 ('force', True),
409 ('dir', tmp_dir),
410 ]
411
412 parsed_args = self.check_parser(self.cmd, arglist, verifylist)
413 expected_value = '''\
414export KUBECONFIG={}/config
415
416'''.format(tmp_dir)
417
418 with capture(self.cmd.take_action, parsed_args) as output:
419 self.assertEqual(expected_value, output)
420
421 self.clusters_mock.get.assert_called_with('fake-cluster')
422
423 @mock.patch.dict(os.environ, {'SHELL': '/bin/bash'})
424 def test_cluster_config_with_custom_dir(self):
425 tmp_dir = tempfile.mkdtemp()
426
427 arglist = ['fake-cluster', '--dir', tmp_dir]
428 verifylist = [
429 ('cluster', 'fake-cluster'),
430 ('dir', tmp_dir),
431 ]
432 parsed_args = self.check_parser(self.cmd, arglist, verifylist)
433
434 expected_value = '''\
435export KUBECONFIG={}/config
436
437'''.format(tmp_dir)
438
439 with capture(self.cmd.take_action, parsed_args) as output:
440 self.assertEqual(expected_value, output)
441
442 self.clusters_mock.get.assert_called_with('fake-cluster')
443
444 @mock.patch.dict(os.environ, {'SHELL': '/bin/bash'})
445 def test_cluster_config_creates_config_in_cwd_if_not_dir_specified(self):
446 tmp_dir = tempfile.mkdtemp()
447 os.chdir(tmp_dir)
448
449 arglist = ['fake-cluster']
450 verifylist = [
451 ('cluster', 'fake-cluster'),
452 ]
453
454 parsed_args = self.check_parser(self.cmd, arglist, verifylist)
455 expected_value = '''\
456export KUBECONFIG={}/config
457
458'''.format(os.getcwd())
459
460 with capture(self.cmd.take_action, parsed_args) as output:
461 self.assertEqual(expected_value, output)
462
463 self.clusters_mock.get.assert_called_with('fake-cluster')
464
465 def test_cluster_config_with_in_progress_status(self):
466 self._cluster.status = 'CREATE_IN_PROGRESS'
467
468 arglist = ['fake-cluster-1']
469 verifylist = [
470 ('cluster', 'fake-cluster-1')
471 ]
472
473 parsed_args = self.check_parser(self.cmd, arglist, verifylist)
474 self.assertRaises(exceptions.CommandError,
475 self.cmd.take_action, parsed_args)
diff --git a/magnumclient/tests/osc/unit/v1/test_quotas.py b/magnumclient/tests/osc/unit/v1/test_quotas.py
new file mode 100644
index 0000000..d4b4abc
--- /dev/null
+++ b/magnumclient/tests/osc/unit/v1/test_quotas.py
@@ -0,0 +1,315 @@
1# Copyright 2015 NEC Corporation. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14import mock
15
16from magnumclient.osc.v1 import quotas as osc_quotas
17from magnumclient.tests.osc.unit.v1 import fakes as magnum_fakes
18
19
20class TestQuotas(magnum_fakes.TestMagnumClientOSCV1):
21
22 def setUp(self):
23 super(TestQuotas, self).setUp()
24
25 self.quotas_mock = self.app.client_manager.container_infra.quotas
26
27
28class TestQuotasCreate(TestQuotas):
29
30 def setUp(self):
31 super(TestQuotasCreate, self).setUp()
32 attr = dict()
33 attr['name'] = 'fake-quota'
34 attr['project_id'] = 'abc'
35 attr['resource'] = 'Cluster'
36 self._quota = magnum_fakes.FakeQuota.create_one_quota(attr)
37
38 self._default_args = {
39 'project_id': 'abc',
40 'resource': 'Cluster',
41 'hard_limit': 1
42 }
43
44 self.quotas_mock.create = mock.Mock()
45 self.quotas_mock.create.return_value = self._quota
46
47 self.cmd = osc_quotas.CreateQuotas(self.app, None)
48
49 self.data = tuple(map(lambda x: getattr(self._quota, x),
50 osc_quotas.QUOTA_ATTRIBUTES))
51
52 def test_quotas_create(self):
53 arglist = [
54 '--project-id', 'abc',
55 '--resource', 'Cluster'
56 ]
57 verifylist = [
58 ('project_id', 'abc'),
59 ('resource', 'Cluster')
60 ]
61 parsed_args = self.check_parser(self.cmd, arglist, verifylist)
62 self.cmd.take_action(parsed_args)
63 self.quotas_mock.create.assert_called_with(**self._default_args)
64
65 def test_quotas_create_with_hardlimit(self):
66 arglist = [
67 '--project-id', 'abc',
68 '--resource', 'Cluster',
69 '--hard-limit', '10'
70 ]
71 verifylist = [
72 ('project_id', 'abc'),
73 ('resource', 'Cluster'),
74 ('hard_limit', 10)
75 ]
76 self._default_args['hard_limit'] = 10
77 parsed_args = self.check_parser(self.cmd, arglist, verifylist)
78
79 self.cmd.take_action(parsed_args)
80 self.quotas_mock.create.assert_called_with(**self._default_args)
81
82 def test_quotas_create_wrong_projectid(self):
83 arglist = ['abcd']
84 verifylist = [
85 ('project_id', 'abcd')
86 ]
87
88 self.assertRaises(magnum_fakes.MagnumParseException,
89 self.check_parser, self.cmd, arglist, verifylist)
90
91 def test_quotas_create_missing_args(self):
92 arglist = []
93 verifylist = []
94 self.assertRaises(magnum_fakes.MagnumParseException,
95 self.check_parser, self.cmd, arglist, verifylist)
96
97 def test_quotas_create_with_wrong_args(self):
98 arglist = [
99 '--project-id', 'abc',
100 '--resources', 'Cluster', # Misspelling 'resources'
101 '--hard-limit', '10'
102 ]
103 verifylist = []
104 self.assertRaises(magnum_fakes.MagnumParseException,
105 self.check_parser, self.cmd, arglist, verifylist)
106
107
108class TestQuotasDelete(TestQuotas):
109
110 def setUp(self):
111 super(TestQuotasDelete, self).setUp()
112
113 self.quotas_mock.delete = mock.Mock()
114 self.quotas_mock.delete.return_value = None
115
116 self.cmd = osc_quotas.DeleteQuotas(self.app, None)
117
118 def test_quotas_delete(self):
119 arglist = [
120 '--project-id', 'abc',
121 '--resource', 'Cluster'
122 ]
123 verifylist = [
124 ('project_id', 'abc'),
125 ('resource', 'Cluster')
126 ]
127
128 parsed_args = self.check_parser(self.cmd, arglist, verifylist)
129 self.cmd.take_action(parsed_args)
130 self.quotas_mock.delete.assert_called_with('abc', 'Cluster')
131
132 def test_quotas_delete_no_project_id(self):
133 arglist = [
134 '--resource', 'Cluster'
135 ]
136 verifylist = [
137 ('resource', 'Cluster')
138 ]
139 self.assertRaises(magnum_fakes.MagnumParseException,
140 self.check_parser, self.cmd, arglist, verifylist)
141
142 def test_quotas_delete_no_resource(self):
143 arglist = [
144 '--project-id', 'abc',
145 ]
146 verifylist = [
147 ('project_id', 'abc')
148 ]
149 self.assertRaises(magnum_fakes.MagnumParseException,
150 self.check_parser, self.cmd, arglist, verifylist)
151
152 def test_quotas_delete_missing_args(self):
153 arglist = []
154 verifylist = []
155 self.assertRaises(magnum_fakes.MagnumParseException,
156 self.check_parser, self.cmd, arglist, verifylist)
157
158 def test_quotas_delete_wrong_args(self):
159 arglist = [
160 '--project-ids', 'abc', # Misspelling 'ids' instead of 'id'
161 '--resource', 'Cluster'
162 ]
163 verifylist = []
164 self.assertRaises(magnum_fakes.MagnumParseException,
165 self.check_parser, self.cmd, arglist, verifylist)
166
167
168class TestQuotasShow(TestQuotas):
169
170 def setUp(self):
171 super(TestQuotasShow, self).setUp()
172
173 attr = dict()
174 attr['name'] = 'fake-quota'
175 attr['project_id'] = 'abc'
176 attr['resource'] = 'Cluster'
177 self._quota = magnum_fakes.FakeQuota.create_one_quota(attr)
178
179 self._default_args = {
180 'project_id': 'abc',
181 'resource': 'Cluster',
182 }
183
184 self.quotas_mock.get = mock.Mock()
185 self.quotas_mock.get.return_value = self._quota
186
187 self.cmd = osc_quotas.ShowQuotas(self.app, None)
188
189 self.data = tuple(map(lambda x: getattr(self._quota, x),
190 osc_quotas.QUOTA_ATTRIBUTES))
191
192 def test_quotas_show(self):
193 arglist = [
194 '--project-id', 'abc',
195 '--resource', 'Cluster'
196 ]
197 verifylist = [
198 ('project_id', 'abc'),
199 ('resource', 'Cluster')
200 ]
201 parsed_args = self.check_parser(self.cmd, arglist, verifylist)
202 self.cmd.take_action(parsed_args)
203 self.quotas_mock.get.assert_called_with('abc', 'Cluster')
204
205 def test_quotas_show_missing_args(self):
206 arglist = []
207 verifylist = []
208 self.assertRaises(magnum_fakes.MagnumParseException,
209 self.check_parser, self.cmd, arglist, verifylist)
210
211
212class TestQuotasUpdate(TestQuotas):
213
214 def setUp(self):
215 super(TestQuotasUpdate, self).setUp()
216 attr = dict()
217 attr['name'] = 'fake-quota'
218 attr['project_id'] = 'abc'
219 attr['resource'] = 'Cluster'
220 self._quota = magnum_fakes.FakeQuota.create_one_quota(attr)
221
222 self._default_args = {
223 'project_id': 'abc',
224 'resource': 'Cluster',
225 'hard_limit': 10
226 }
227
228 self.quotas_mock.update = mock.Mock()
229 self.quotas_mock.update.return_value = self._quota
230
231 self.cmd = osc_quotas.UpdateQuotas(self.app, None)
232
233 def test_quotas_update(self):
234 arglist = [
235 '--project-id', 'abc',
236 '--resource', 'Cluster',
237 '--hard-limit', '10'
238 ]
239 verifylist = [
240 ('project_id', 'abc'),
241 ('resource', 'Cluster'),
242 ('hard_limit', 10)
243 ]
244 parsed_args = self.check_parser(self.cmd, arglist, verifylist)
245 self.cmd.take_action(parsed_args)
246 self.quotas_mock.update.assert_called_with('abc', 'Cluster',
247 self._default_args)
248
249 def test_quotas_update_missing_args(self):
250 arglist = ['abcd']
251 verifylist = [
252 ('project_id', 'abcd')
253 ]
254
255 self.assertRaises(magnum_fakes.MagnumParseException,
256 self.check_parser, self.cmd, arglist, verifylist)
257
258 def test_quotas_update_wrong_args(self):
259 arglist = [
260 '--project-id', 'abc',
261 '--resource', 'Cluster',
262 '--hard-limits', '10' # Misspelling 'hard-limits'
263 ]
264 verifylist = [
265 ('project_id', 'abc'),
266 ('resource', 'Cluster'),
267 ('hard_limit', 10)
268 ]
269
270 self.assertRaises(magnum_fakes.MagnumParseException,
271 self.check_parser, self.cmd, arglist, verifylist)
272
273
274class TestQuotasList(TestQuotas):
275
276 def setUp(self):
277 super(TestQuotasList, self).setUp()
278 attr = dict()
279 attr['name'] = 'fake-quota'
280 attr['project_id'] = 'abc'
281 attr['resource'] = 'Cluster'
282 self._quota = magnum_fakes.FakeQuota.create_one_quota(attr)
283
284 self.quotas_mock.list = mock.Mock()
285 self.quotas_mock.list.return_value = [self._quota]
286
287 self.cmd = osc_quotas.ListQuotas(self.app, None)
288
289 def test_quotas_list_with_no_options(self):
290 arglist = [
291 ]
292 verifylist = [
293 ('limit', None),
294 ('sort_key', None),
295 ('sort_dir', None),
296 ('marker', None),
297 ('all_tenants', False)
298 ]
299 parsed_args = self.check_parser(self.cmd, arglist, verifylist)
300 self.cmd.take_action(parsed_args)
301 self.quotas_mock.list.assert_called_with(
302 limit=None,
303 sort_dir=None,
304 sort_key=None,
305 marker=None,
306 all_tenants=False
307 )
308
309 def test_quotas_list_wrong_args(self):
310 arglist = ['--wrong']
311 verifylist = [
312 ('wrong')
313 ]
314 self.assertRaises(magnum_fakes.MagnumParseException,
315 self.check_parser, self.cmd, arglist, verifylist)
diff --git a/magnumclient/v1/quotas_shell.py b/magnumclient/v1/quotas_shell.py
index ff98c00..3df0918 100644
--- a/magnumclient/v1/quotas_shell.py
+++ b/magnumclient/v1/quotas_shell.py
@@ -39,6 +39,7 @@ def _show_quota(quota):
39 action='store_true', 39 action='store_true',
40 default=False, 40 default=False,
41 help=_('Flag to indicate list all tenant quotas.')) 41 help=_('Flag to indicate list all tenant quotas.'))
42@utils.deprecated(utils.MAGNUM_CLIENT_DEPRECATION_WARNING)
42def do_quotas_list(cs, args): 43def do_quotas_list(cs, args):
43 """Print a list of available quotas.""" 44 """Print a list of available quotas."""
44 quotas = cs.quotas.list(marker=args.marker, 45 quotas = cs.quotas.list(marker=args.marker,
@@ -65,6 +66,7 @@ def do_quotas_list(cs, args):
65 type=int, 66 type=int,
66 default=1, 67 default=1,
67 help=_('Max resource limit.')) 68 help=_('Max resource limit.'))
69@utils.deprecated(utils.MAGNUM_CLIENT_DEPRECATION_WARNING)
68def do_quotas_create(cs, args): 70def do_quotas_create(cs, args):
69 """Create a quota.""" 71 """Create a quota."""
70 72
@@ -91,6 +93,7 @@ def do_quotas_create(cs, args):
91 required=True, 93 required=True,
92 metavar='<resource>', 94 metavar='<resource>',
93 help=_('Resource name')) 95 help=_('Resource name'))
96@utils.deprecated(utils.MAGNUM_CLIENT_DEPRECATION_WARNING)
94def do_quotas_delete(cs, args): 97def do_quotas_delete(cs, args):
95 """Delete specified resource quota.""" 98 """Delete specified resource quota."""
96 try: 99 try:
@@ -113,6 +116,7 @@ def do_quotas_delete(cs, args):
113 required=True, 116 required=True,
114 metavar='<resource>', 117 metavar='<resource>',
115 help=_('Resource name')) 118 help=_('Resource name'))
119@utils.deprecated(utils.MAGNUM_CLIENT_DEPRECATION_WARNING)
116def do_quotas_show(cs, args): 120def do_quotas_show(cs, args):
117 """Show details about the given project resource quota.""" 121 """Show details about the given project resource quota."""
118 quota = cs.quotas.get(args.project_id, args.resource) 122 quota = cs.quotas.get(args.project_id, args.resource)
@@ -132,6 +136,7 @@ def do_quotas_show(cs, args):
132 type=int, 136 type=int,
133 default=1, 137 default=1,
134 help=_('Max resource limit.')) 138 help=_('Max resource limit.'))
139@utils.deprecated(utils.MAGNUM_CLIENT_DEPRECATION_WARNING)
135def do_quotas_update(cs, args): 140def do_quotas_update(cs, args):
136 """Update information about the given project resource quota.""" 141 """Update information about the given project resource quota."""
137 patch = dict() 142 patch = dict()
diff --git a/releasenotes/notes/partial_osc_implementation_for_quotas-33f44c0496d721f8.yaml b/releasenotes/notes/partial_osc_implementation_for_quotas-33f44c0496d721f8.yaml
new file mode 100644
index 0000000..be3507c
--- /dev/null
+++ b/releasenotes/notes/partial_osc_implementation_for_quotas-33f44c0496d721f8.yaml
@@ -0,0 +1,6 @@
1---
2features:
3 - |
4 Implemented Openstack command for quotas-create,
5 quotas-update, quotas-delete, quotas-show and
6 quotas-list
diff --git a/setup.cfg b/setup.cfg
index 36ffd53..6a464b1 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -46,6 +46,11 @@ openstack.container_infra.v1 =
46 coe_ca_show = magnumclient.osc.v1.certificates:ShowCa 46 coe_ca_show = magnumclient.osc.v1.certificates:ShowCa
47 coe_ca_sign = magnumclient.osc.v1.certificates:SignCa 47 coe_ca_sign = magnumclient.osc.v1.certificates:SignCa
48 coe_stats_list = magnumclient.osc.v1.stats:ListStats 48 coe_stats_list = magnumclient.osc.v1.stats:ListStats
49 coe_quotas_create = magclient.osc.v1.quotas:CreateQuotas
50 coe_quotas_delete = magclient.osc.v1.quotas:DeleteQuotas
51 coe_quotas_update = magclient.osc.v1.quotas:UpdateQuotas
52 coe_quotas_show = magclient.osc.v1.quotas:ShowQuotas
53 coe_quotas_list = magclient.osc.v1.quotas:ListQuotas
49 54
50 coe_service_list = magnumclient.osc.v1.mservices:ListService 55 coe_service_list = magnumclient.osc.v1.mservices:ListService
51 56