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
This commit is contained in:
parent
f8765ce532
commit
0c23c62cef
@ -24,6 +24,7 @@ from testtools import matchers
|
|||||||
|
|
||||||
from ceilometerclient import exc
|
from ceilometerclient import exc
|
||||||
from ceilometerclient import shell as base_shell
|
from ceilometerclient import shell as base_shell
|
||||||
|
from ceilometerclient.tests import test_shell
|
||||||
from ceilometerclient.tests import utils
|
from ceilometerclient.tests import utils
|
||||||
from ceilometerclient.v2 import alarms
|
from ceilometerclient.v2 import alarms
|
||||||
from ceilometerclient.v2 import events
|
from ceilometerclient.v2 import events
|
||||||
@ -1119,3 +1120,56 @@ class ShellEventListCommandTest(utils.BaseTestCase):
|
|||||||
+--------------------------------------+-------------------------------\
|
+--------------------------------------+-------------------------------\
|
||||||
+----------------------------+
|
+----------------------------+
|
||||||
''', sys.stdout.getvalue())
|
''', 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'))
|
||||||
|
@ -181,10 +181,22 @@ def do_sample_show(cc, args):
|
|||||||
utils.print_dict(data, wrap=72)
|
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 '
|
help='Tenant to associate with sample '
|
||||||
'(only settable by admin users).')
|
'(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 '
|
help='User to associate with sample '
|
||||||
'(only settable by admin users).')
|
'(only settable by admin users).')
|
||||||
@utils.arg('-r', '--resource-id', metavar='<RESOURCE_ID>', required=True,
|
@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"}.')
|
'key-value pairs e.g. {"key":"value"}.')
|
||||||
@utils.arg('--timestamp', metavar='<TIMESTAMP>',
|
@utils.arg('--timestamp', metavar='<TIMESTAMP>',
|
||||||
help='The sample timestamp.')
|
help='The sample timestamp.')
|
||||||
|
@_restore_shadowed_arg('project_id', 'sample_project_id')
|
||||||
def do_sample_create(cc, args={}):
|
def do_sample_create(cc, args={}):
|
||||||
"""Create a sample."""
|
"""Create a sample."""
|
||||||
arg_to_field_mapping = {'meter_name': 'counter_name',
|
arg_to_field_mapping = {
|
||||||
'meter_unit': 'counter_unit',
|
'meter_name': 'counter_name',
|
||||||
'meter_type': 'counter_type',
|
'meter_unit': 'counter_unit',
|
||||||
'sample_volume': 'counter_volume'}
|
'meter_type': 'counter_type',
|
||||||
|
'sample_volume': 'counter_volume',
|
||||||
|
}
|
||||||
fields = {}
|
fields = {}
|
||||||
for var in vars(args).items():
|
for var in vars(args).items():
|
||||||
k, v = var[0], var[1]
|
k, v = var[0], var[1]
|
||||||
@ -397,10 +412,11 @@ def common_alarm_arguments(create=False):
|
|||||||
def _wrapper(func):
|
def _wrapper(func):
|
||||||
@utils.arg('--name', metavar='<NAME>', required=create,
|
@utils.arg('--name', metavar='<NAME>', required=create,
|
||||||
help='Name of the alarm (must be unique per tenant).')
|
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 '
|
help='Tenant to associate with alarm '
|
||||||
'(only settable by admin users).')
|
'(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 '
|
help='User to associate with alarm '
|
||||||
'(only settable by admin users).')
|
'(only settable by admin users).')
|
||||||
@utils.arg('--description', metavar='<DESCRIPTION>',
|
@utils.arg('--description', metavar='<DESCRIPTION>',
|
||||||
@ -535,6 +551,7 @@ def common_alarm_gnocchi_resources_arguments(create=False):
|
|||||||
default=False,
|
default=False,
|
||||||
help=('True if actions should be repeatedly notified '
|
help=('True if actions should be repeatedly notified '
|
||||||
'while alarm remains in target state.'))
|
'while alarm remains in target state.'))
|
||||||
|
@_restore_shadowed_arg('project_id', 'alarm_project_id')
|
||||||
def do_alarm_create(cc, args={}):
|
def do_alarm_create(cc, args={}):
|
||||||
"""Create a new alarm (Deprecated). Use alarm-threshold-create instead."""
|
"""Create a new alarm (Deprecated). Use alarm-threshold-create instead."""
|
||||||
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
|
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
|
||||||
@ -600,6 +617,7 @@ def do_alarm_gnocchi_metrics_threshold_create(cc, args={}):
|
|||||||
default=False,
|
default=False,
|
||||||
help=('True if actions should be repeatedly notified '
|
help=('True if actions should be repeatedly notified '
|
||||||
'while alarm remains in target state.'))
|
'while alarm remains in target state.'))
|
||||||
|
@_restore_shadowed_arg('project_id', 'alarm_project_id')
|
||||||
def do_alarm_threshold_create(cc, args={}):
|
def do_alarm_threshold_create(cc, args={}):
|
||||||
"""Create a new alarm based on computed statistics."""
|
"""Create a new alarm based on computed statistics."""
|
||||||
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
|
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
|
||||||
@ -626,6 +644,7 @@ def do_alarm_threshold_create(cc, args={}):
|
|||||||
default=False,
|
default=False,
|
||||||
help=('True if actions should be repeatedly notified '
|
help=('True if actions should be repeatedly notified '
|
||||||
'while alarm remains in target state.'))
|
'while alarm remains in target state.'))
|
||||||
|
@_restore_shadowed_arg('project_id', 'alarm_project_id')
|
||||||
def do_alarm_combination_create(cc, args={}):
|
def do_alarm_combination_create(cc, args={}):
|
||||||
"""Create a new alarm based on state of other alarms."""
|
"""Create a new alarm based on state of other alarms."""
|
||||||
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
|
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
|
||||||
@ -667,6 +686,7 @@ def do_alarm_combination_create(cc, args={}):
|
|||||||
metavar='{True|False}', type=strutils.bool_from_string,
|
metavar='{True|False}', type=strutils.bool_from_string,
|
||||||
help=('True if actions should be repeatedly notified '
|
help=('True if actions should be repeatedly notified '
|
||||||
'while alarm remains in target state.'))
|
'while alarm remains in target state.'))
|
||||||
|
@_restore_shadowed_arg('project_id', 'alarm_project_id')
|
||||||
def do_alarm_update(cc, args={}):
|
def do_alarm_update(cc, args={}):
|
||||||
"""Update an existing alarm (Deprecated)."""
|
"""Update an existing alarm (Deprecated)."""
|
||||||
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
|
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
|
||||||
@ -718,6 +738,7 @@ def do_alarm_update(cc, args={}):
|
|||||||
metavar='{True|False}', type=strutils.bool_from_string,
|
metavar='{True|False}', type=strutils.bool_from_string,
|
||||||
help=('True if actions should be repeatedly notified '
|
help=('True if actions should be repeatedly notified '
|
||||||
'while alarm remains in target state.'))
|
'while alarm remains in target state.'))
|
||||||
|
@_restore_shadowed_arg('project_id', 'alarm_project_id')
|
||||||
def do_alarm_threshold_update(cc, args={}):
|
def do_alarm_threshold_update(cc, args={}):
|
||||||
"""Update an existing alarm based on computed statistics."""
|
"""Update an existing alarm based on computed statistics."""
|
||||||
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
|
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
|
||||||
@ -808,6 +829,7 @@ def do_alarm_gnocchi_metrics_threshold_update(cc, args={}):
|
|||||||
metavar='{True|False}', type=strutils.bool_from_string,
|
metavar='{True|False}', type=strutils.bool_from_string,
|
||||||
help=('True if actions should be repeatedly notified '
|
help=('True if actions should be repeatedly notified '
|
||||||
'while alarm remains in target state.'))
|
'while alarm remains in target state.'))
|
||||||
|
@_restore_shadowed_arg('project_id', 'alarm_project_id')
|
||||||
def do_alarm_combination_update(cc, args={}):
|
def do_alarm_combination_update(cc, args={}):
|
||||||
"""Update an existing alarm based on state of other alarms."""
|
"""Update an existing alarm based on state of other alarms."""
|
||||||
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
|
fields = dict(filter(lambda x: not (x[1] is None), vars(args).items()))
|
||||||
|
Loading…
Reference in New Issue
Block a user