Support quota CLI

Change-Id: I6f3f5a8df8fcfac4e7b86f3030b86db1af9d3ae2
This commit is contained in:
Lingxian Kong
2020-02-04 10:42:15 +13:00
parent b5ca8f9013
commit 040498fdc4
6 changed files with 232 additions and 22 deletions

View File

@@ -147,7 +147,7 @@ class AodhClientTest(base.ClientTestBase):
ALARM_ID))
# LIST
result = self.aodh('alarm', params="list")
result = self.aodh('alarm', params="list --filter all_projects=true")
self.assertIn(ALARM_ID,
[r['alarm_id'] for r in self.parser.listing(result)])
output_colums = ['alarm_id', 'type', 'name', 'state', 'severity',
@@ -258,7 +258,7 @@ class AodhClientTest(base.ClientTestBase):
ALARM_ID))
# LIST
result = self.aodh('alarm', params="list")
result = self.aodh('alarm', params="list --filter all_projects=true")
self.assertIn(ALARM_ID,
[r['alarm_id'] for r in self.parser.listing(result)])
output_colums = ['alarm_id', 'type', 'name', 'state', 'severity',
@@ -271,12 +271,13 @@ class AodhClientTest(base.ClientTestBase):
# LIST WITH PAGINATION
# list with limit
result = self.aodh('alarm',
params="list --limit 1")
params="list --filter all_projects=true --limit 1 ")
alarm_list = self.parser.listing(result)
self.assertEqual(1, len(alarm_list))
# list with sort with key=name dir=asc
result = self.aodh('alarm',
params="list --sort name:asc")
result = self.aodh(
'alarm',
params="list --filter all_projects=true --sort name:asc")
names = [r['name'] for r in self.parser.listing(result)]
sorted_name = sorted(names)
self.assertEqual(sorted_name, names)
@@ -287,8 +288,10 @@ class AodhClientTest(base.ClientTestBase):
"-m meter_name --threshold 5 "
"--project-id %s" % PROJECT_ID))
created_alarm_id = self.details_multiple(result)[0]['alarm_id']
result = self.aodh('alarm',
params="list --sort name:asc --sort alarm_id:asc")
result = self.aodh(
'alarm',
params="list --filter all_projects=true --sort name:asc --sort "
"alarm_id:asc")
alarm_list = self.parser.listing(result)
ids_with_same_name = []
names = []
@@ -302,9 +305,10 @@ class AodhClientTest(base.ClientTestBase):
self.assertEqual(sorted_ids, ids_with_same_name)
# list with sort with key=name dir=desc and with the marker equal to
# the alarm_id of the test_threshold_scenario we created for this test.
result = self.aodh('alarm',
params="list --sort name:desc "
"--marker %s" % created_alarm_id)
result = self.aodh(
'alarm',
params="list --filter all_projects=true --sort name:desc "
"--marker %s" % created_alarm_id)
self.assertIn('alarm_tc',
[r['name'] for r in self.parser.listing(result)])
self.aodh('alarm', params="delete %s" % created_alarm_id)
@@ -399,7 +403,7 @@ class AodhClientTest(base.ClientTestBase):
alarm_id))
# LIST
result = self.aodh('alarm', params="list")
result = self.aodh('alarm', params="list --filter all_projects=true")
self.assertIn(alarm_id,
[r['alarm_id'] for r in self.parser.listing(result)])
output_colums = ['alarm_id', 'type', 'name', 'state', 'severity',
@@ -659,7 +663,7 @@ class AodhClientGnocchiRulesTest(base.ClientTestBase):
ALARM_ID))
# LIST
result = self.aodh('alarm', params="list")
result = self.aodh('alarm', params="list --filter all_projects=true")
self.assertIn(ALARM_ID,
[r['alarm_id'] for r in self.parser.listing(result)])
output_colums = ['alarm_id', 'type', 'name', 'state', 'severity',
@@ -672,12 +676,13 @@ class AodhClientGnocchiRulesTest(base.ClientTestBase):
# LIST WITH PAGINATION
# list with limit
result = self.aodh('alarm',
params="list --limit 1")
params="list --filter all_projects=true --limit 1")
alarm_list = self.parser.listing(result)
self.assertEqual(1, len(alarm_list))
# list with sort with key=name dir=asc
result = self.aodh('alarm',
params="list --sort name:asc")
result = self.aodh(
'alarm',
params="list --filter all_projects=true --sort name:asc")
names = [r['name'] for r in self.parser.listing(result)]
sorted_name = sorted(names)
self.assertEqual(sorted_name, names)
@@ -690,8 +695,10 @@ class AodhClientGnocchiRulesTest(base.ClientTestBase):
"--aggregation-method last --project-id %s "
% (RESOURCE_ID, PROJECT_ID)))
created_alarm_id = self.details_multiple(result)[0]['alarm_id']
result = self.aodh('alarm',
params="list --sort name:asc --sort alarm_id:asc")
result = self.aodh(
'alarm',
params="list --filter all_projects=true --sort name:asc "
"--sort alarm_id:asc")
alarm_list = self.parser.listing(result)
ids_with_same_name = []
names = []
@@ -705,9 +712,10 @@ class AodhClientGnocchiRulesTest(base.ClientTestBase):
self.assertEqual(sorted_ids, ids_with_same_name)
# list with sort with key=name dir=desc and with the marker equal to
# the alarm_id of the alarm_th we created for this test.
result = self.aodh('alarm',
params="list --sort name:desc "
"--marker %s" % created_alarm_id)
result = self.aodh(
'alarm',
params="list --filter all_projects=true --sort name:desc "
"--marker %s" % created_alarm_id)
self.assertIn('alarm_tc',
[r['name'] for r in self.parser.listing(result)])
self.aodh('alarm', params="delete %s" % created_alarm_id)
@@ -802,7 +810,7 @@ class AodhClientGnocchiRulesTest(base.ClientTestBase):
self.assertEqual('generic', alarm_show['resource_type'])
# LIST
result = self.aodh('alarm', params="list")
result = self.aodh('alarm', params="list --filter all_projects=true")
self.assertIn(ALARM_ID,
[r['alarm_id'] for r in self.parser.listing(result)])
output_colums = ['alarm_id', 'type', 'name', 'state', 'severity',
@@ -893,7 +901,7 @@ class AodhClientGnocchiRulesTest(base.ClientTestBase):
self.assertEqual('last', alarm_show['aggregation_method'])
# LIST
result = self.aodh('alarm', params="list")
result = self.aodh('alarm', params="list --filter all_projects=true")
self.assertIn(ALARM_ID,
[r['alarm_id'] for r in self.parser.listing(result)])
for alarm_list in self.parser.listing(result):

View File

@@ -0,0 +1,86 @@
#
# 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 mock
import testtools
from aodhclient import exceptions
from aodhclient.v2 import quota_cli
class QuotaShowTest(testtools.TestCase):
def setUp(self):
super(QuotaShowTest, self).setUp()
self.app = mock.Mock()
self.quota_mgr_mock = self.app.client_manager.alarming.quota
self.parser = mock.Mock()
self.quota_show = (
quota_cli.QuotaShow(self.app, self.parser))
def test_quota_show(self):
self.quota_mgr_mock.list.return_value = {
"project_id": "fake_project",
"quotas": [
{
"limit": 20,
"resource": "alarms"
}
]
}
parser = self.quota_show.get_parser('')
args = parser.parse_args(['--project', 'fake_project'])
# Something like [('alarms',), (20,)]
ret = list(self.quota_show.take_action(args))
self.quota_mgr_mock.list.assert_called_once_with(
project='fake_project')
self.assertIn('alarms', ret[0])
self.assertIn(20, ret[1])
class QuotaSetTest(testtools.TestCase):
def setUp(self):
super(QuotaSetTest, self).setUp()
self.app = mock.Mock()
self.quota_mgr_mock = self.app.client_manager.alarming.quota
self.parser = mock.Mock()
self.quota_set = (
quota_cli.QuotaSet(self.app, self.parser))
def test_quota_set(self):
self.quota_mgr_mock.create.return_value = {
"project_id": "fake_project",
"quotas": [
{
"limit": 20,
"resource": "alarms"
}
]
}
parser = self.quota_set.get_parser('')
args = parser.parse_args(['fake_project', '--alarm', '20'])
ret = list(self.quota_set.take_action(args))
self.quota_mgr_mock.create.assert_called_once_with(
'fake_project', [{'resource': 'alarms', 'limit': 20}])
self.assertIn('alarms', ret[0])
self.assertIn(20, ret[1])
def test_quota_set_invalid_quota(self):
parser = self.quota_set.get_parser('')
args = parser.parse_args(['fake_project', '--alarm', '-2'])
self.assertRaises(exceptions.CommandError,
self.quota_set.take_action,
args)

View File

@@ -17,6 +17,7 @@ from aodhclient import client
from aodhclient.v2 import alarm
from aodhclient.v2 import alarm_history
from aodhclient.v2 import capabilities
from aodhclient.v2 import quota
class Client(object):
@@ -33,3 +34,4 @@ class Client(object):
self.alarm = alarm.AlarmManager(self)
self.alarm_history = alarm_history.AlarmHistoryManager(self)
self.capabilities = capabilities.CapabilitiesManager(self)
self.quota = quota.QuotasManager(self)

41
aodhclient/v2/quota.py Normal file
View File

@@ -0,0 +1,41 @@
#
# 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 oslo_serialization import jsonutils
from aodhclient.v2 import base
class QuotasManager(base.Manager):
base_url = "v2/quotas"
def list(self, project=None):
url = self.base_url
if project:
url = "%s?project_id=%s" % (url, project)
return self._get(url).json()
def create(self, project, resource_quotas):
body = {
"project_id": project,
"quotas": []
}
for q in resource_quotas:
body['quotas'].append(
{"resource": q['resource'], 'limit': q['limit']}
)
return self._post(
self.base_url, headers={'Content-Type': "application/json"},
data=jsonutils.dumps(body)
).json()

View File

@@ -0,0 +1,71 @@
#
# 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 cliff import show
from aodhclient import exceptions
from aodhclient import utils
class QuotaShow(show.ShowOne):
"""Show quota for a project"""
def get_parser(self, prog_name):
parser = super(QuotaShow, self).get_parser(prog_name)
parser.add_argument(
"--project",
help="Project ID. If not specified, get quota for the current "
"project."
)
return parser
def take_action(self, parsed_args):
c = utils.get_client(self)
quota = c.quota.list(project=parsed_args.project)
ret = {}
for q in quota['quotas']:
ret[q['resource']] = q['limit']
return self.dict2columns(ret)
class QuotaSet(show.ShowOne):
def get_parser(self, prog_name):
parser = super(QuotaSet, self).get_parser(prog_name)
parser.add_argument(
"project",
help="Project ID."
)
parser.add_argument(
"--alarm", type=int,
help="New value for the alarm quota. Value -1 means unlimited."
)
return parser
def take_action(self, parsed_args):
resource_quotas = []
if parsed_args.alarm is not None:
if parsed_args.alarm < -1:
raise exceptions.CommandError(
'Quota limit cannot be less than -1.')
resource_quotas.append(
{'resource': 'alarms', 'limit': parsed_args.alarm})
c = utils.get_client(self)
quota = c.quota.create(parsed_args.project, resource_quotas)
ret = {}
for q in quota['quotas']:
ret[q['resource']] = q['limit']
return self.dict2columns(ret)

View File

@@ -54,6 +54,8 @@ openstack.alarming.v2 =
alarm-history search = aodhclient.v2.alarm_history_cli:CliAlarmHistorySearch
alarm-history show = aodhclient.v2.alarm_history_cli:CliAlarmHistoryShow
alarming capabilities list = aodhclient.v2.capabilities_cli:CliCapabilitiesList
alarm quota show = aodhclient.v2.quota_cli:QuotaShow
alarm quota set = aodhclient.v2.quota_cli:QuotaSet
[compile_catalog]
directory = aodhclient/locale