diff options
author | ZhiQiang Fan <aji.zqfan@gmail.com> | 2014-11-27 04:35:12 +0800 |
---|---|---|
committer | gordon chung <gord@live.ca> | 2015-04-16 12:56:31 +0000 |
commit | 40d7913cee4a3e6c133c51caec93c5820473cee3 (patch) | |
tree | c9b128b4e3896928bb71b7da0b0203dc863be7de | |
parent | 1b346fb64796cd9aba39ee1e9453223738bd1b30 (diff) | |
download | python-ceilometerclient-40d7913cee4a3e6c133c51caec93c5820473cee3.tar.gz |
Enable specified project_id in CLI commands
After we port to oslo-incubator.apiclient, the project_id can no
longer be specified for alarm-{,threhsold,combination}-{create,update}
and sample-create, this is because client.AuthPlugin registers a CLI
argument named --os-project-id which will shadow the project-id
argument.
Since os-project-id is used for Keystone V3 API, we should not
remove it from AuthPlugin, so this patch moves the dest of project_id
to {alarm,sample}_project_id, and adds a decorator to restore shadowed
project_id field when we call v2 client.
Change-Id: I0ce2416dccd61eb50584799e6df0b8c45d44cdda
Closes-Bug: #1393489
(cherry picked from commit 0c23c62cef6f1388d26c04d6cf0e74153db0a0b5)
-rw-r--r-- | ceilometerclient/tests/v2/test_shell.py | 54 | ||||
-rw-r--r-- | ceilometerclient/v2/shell.py | 38 |
2 files changed, 84 insertions, 8 deletions
diff --git a/ceilometerclient/tests/v2/test_shell.py b/ceilometerclient/tests/v2/test_shell.py index 4030439..921bded 100644 --- a/ceilometerclient/tests/v2/test_shell.py +++ b/ceilometerclient/tests/v2/test_shell.py @@ -24,6 +24,7 @@ from testtools import matchers from ceilometerclient import exc from ceilometerclient import shell as base_shell +from ceilometerclient.tests import test_shell from ceilometerclient.tests import utils from ceilometerclient.v2 import alarms from ceilometerclient.v2 import events @@ -1119,3 +1120,56 @@ class ShellEventListCommandTest(utils.BaseTestCase): +--------------------------------------+-------------------------------\ +----------------------------+ ''', sys.stdout.getvalue()) + + +class ShellShadowedArgsTest(test_shell.ShellTestBase): + + def _test_project_id_alarm(self, command, args, method): + self.make_env(test_shell.FAKE_V2_ENV) + cli_args = [ + '--os-project-id', '0ba30185ddf44834914a0b859d244c56', + '--debug', command, + '--project-id', 'the-project-id-i-want-to-set', + '--name', 'project-id-test'] + args + with mock.patch.object(alarms.AlarmManager, method) as mocked: + base_shell.main(cli_args) + args, kwargs = mocked.call_args + self.assertEqual('the-project-id-i-want-to-set', + kwargs.get('project_id')) + + def test_project_id_threshold_alarm(self): + cli_args = ['--meter-name', 'cpu', '--threshold', '90'] + self._test_project_id_alarm('alarm-create', cli_args, 'create') + self._test_project_id_alarm('alarm-threshold-create', + cli_args, 'create') + cli_args += ['--alarm_id', '437b7ed0-3733-4054-a877-e9a297b8be85'] + self._test_project_id_alarm('alarm-update', cli_args, 'update') + self._test_project_id_alarm('alarm-threshold-update', + cli_args, 'update') + + def test_project_id_combination_alarm(self): + cli_args = ['--alarm_ids', 'fb16a05a-669d-414e-8bbe-93aa381df6a8', + '--alarm_ids', 'b189bcca-0a7b-49a9-a244-a927ac291881'] + self._test_project_id_alarm('alarm-combination-create', + cli_args, 'create') + cli_args += ['--alarm_id', '437b7ed0-3733-4054-a877-e9a297b8be85'] + self._test_project_id_alarm('alarm-combination-update', + cli_args, 'update') + + @mock.patch.object(samples.OldSampleManager, 'create') + def test_project_id_sample_create(self, mocked): + self.make_env(test_shell.FAKE_V2_ENV) + cli_args = [ + '--os-project-id', '0ba30185ddf44834914a0b859d244c56', + '--debug', 'sample-create', + '--project-id', 'the-project-id-i-want-to-set', + '--resource-id', 'b666633d-9bb6-4e05-89c0-ee5a8752fb0b', + '--meter-name', 'cpu', + '--meter-type', 'cumulative', + '--meter-unit', 'ns', + '--sample-volume', '10086', + ] + base_shell.main(cli_args) + args, kwargs = mocked.call_args + self.assertEqual('the-project-id-i-want-to-set', + kwargs.get('project_id')) diff --git a/ceilometerclient/v2/shell.py b/ceilometerclient/v2/shell.py index f1ecf02..c537e7d 100644 --- a/ceilometerclient/v2/shell.py +++ b/ceilometerclient/v2/shell.py @@ -181,10 +181,22 @@ def do_sample_show(cc, args): utils.print_dict(data, wrap=72) -@utils.arg('--project-id', metavar='<PROJECT_ID>', +def _restore_shadowed_arg(shadowed, observed): + def wrapper(func): + @functools.wraps(func) + def wrapped(cc, args): + v = getattr(args, observed, None) + setattr(args, shadowed, v) + return func(cc, args) + return wrapped + return wrapper + + +@utils.arg('--project-id', metavar='<SAMPLE_PROJECT_ID>', + dest='sample_project_id', help='Tenant to associate with sample ' '(only settable by admin users).') -@utils.arg('--user-id', metavar='<USER_ID>', +@utils.arg('--user-id', metavar='<SAMPLE_USER_ID>', help='User to associate with sample ' '(only settable by admin users).') @utils.arg('-r', '--resource-id', metavar='<RESOURCE_ID>', required=True, @@ -202,12 +214,15 @@ def do_sample_show(cc, args): 'key-value pairs e.g. {"key":"value"}.') @utils.arg('--timestamp', metavar='<TIMESTAMP>', help='The sample timestamp.') +@_restore_shadowed_arg('project_id', 'sample_project_id') def do_sample_create(cc, args={}): """Create a sample.""" - arg_to_field_mapping = {'meter_name': 'counter_name', - 'meter_unit': 'counter_unit', - 'meter_type': 'counter_type', - 'sample_volume': 'counter_volume'} + arg_to_field_mapping = { + 'meter_name': 'counter_name', + 'meter_unit': 'counter_unit', + 'meter_type': 'counter_type', + 'sample_volume': 'counter_volume', + } fields = {} for var in vars(args).items(): k, v = var[0], var[1] @@ -397,10 +412,11 @@ def common_alarm_arguments(create=False): def _wrapper(func): @utils.arg('--name', metavar='<NAME>', required=create, help='Name of the alarm (must be unique per tenant).') - @utils.arg('--project-id', metavar='<PROJECT_ID>', + @utils.arg('--project-id', metavar='<ALARM_PROJECT_ID>', + dest='alarm_project_id', help='Tenant to associate with alarm ' '(only settable by admin users).') - @utils.arg('--user-id', metavar='<USER_ID>', + @utils.arg('--user-id', metavar='<ALARM_USER_ID>', help='User to associate with alarm ' '(only settable by admin users).') @utils.arg('--description', metavar='<DESCRIPTION>', @@ -559,6 +575,7 @@ def common_alarm_gnocchi_resources_arguments(create=False): default=False, help=('True if actions should be repeatedly notified ' 'while alarm remains in target state.')) +@_restore_shadowed_arg('project_id', 'alarm_project_id') def do_alarm_create(cc, args={}): """Create a new alarm (Deprecated). Use alarm-threshold-create instead.""" fields = dict(filter(lambda x: not (x[1] is None), vars(args).items())) @@ -639,6 +656,7 @@ def do_alarm_gnocchi_aggregation_by_resources_threshold_create(cc, args={}): default=False, help=('True if actions should be repeatedly notified ' 'while alarm remains in target state.')) +@_restore_shadowed_arg('project_id', 'alarm_project_id') def do_alarm_threshold_create(cc, args={}): """Create a new alarm based on computed statistics.""" fields = dict(filter(lambda x: not (x[1] is None), vars(args).items())) @@ -665,6 +683,7 @@ def do_alarm_threshold_create(cc, args={}): default=False, help=('True if actions should be repeatedly notified ' 'while alarm remains in target state.')) +@_restore_shadowed_arg('project_id', 'alarm_project_id') def do_alarm_combination_create(cc, args={}): """Create a new alarm based on state of other alarms.""" fields = dict(filter(lambda x: not (x[1] is None), vars(args).items())) @@ -706,6 +725,7 @@ def do_alarm_combination_create(cc, args={}): metavar='{True|False}', type=strutils.bool_from_string, help=('True if actions should be repeatedly notified ' 'while alarm remains in target state.')) +@_restore_shadowed_arg('project_id', 'alarm_project_id') def do_alarm_update(cc, args={}): """Update an existing alarm (Deprecated).""" fields = dict(filter(lambda x: not (x[1] is None), vars(args).items())) @@ -757,6 +777,7 @@ def do_alarm_update(cc, args={}): metavar='{True|False}', type=strutils.bool_from_string, help=('True if actions should be repeatedly notified ' 'while alarm remains in target state.')) +@_restore_shadowed_arg('project_id', 'alarm_project_id') def do_alarm_threshold_update(cc, args={}): """Update an existing alarm based on computed statistics.""" fields = dict(filter(lambda x: not (x[1] is None), vars(args).items())) @@ -875,6 +896,7 @@ def do_alarm_gnocchi_aggregation_by_resources_threshold_update(cc, args={}): metavar='{True|False}', type=strutils.bool_from_string, help=('True if actions should be repeatedly notified ' 'while alarm remains in target state.')) +@_restore_shadowed_arg('project_id', 'alarm_project_id') def do_alarm_combination_update(cc, args={}): """Update an existing alarm based on state of other alarms.""" fields = dict(filter(lambda x: not (x[1] is None), vars(args).items())) |