Merge "Add a mechanism to call out deprecated options"
This commit is contained in:
commit
c6c5a60a63
novaclient
@ -29,6 +29,7 @@ from keystoneauth1 import loading
|
||||
from oslo_utils import encodeutils
|
||||
from oslo_utils import importutils
|
||||
from oslo_utils import strutils
|
||||
import six
|
||||
|
||||
HAS_KEYRING = False
|
||||
all_errors = ValueError
|
||||
@ -63,6 +64,153 @@ HINT_HELP_MSG = (" [hint: use '--os-compute-api-version' flag to show help "
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DeprecatedAction(argparse.Action):
|
||||
"""An argparse action for deprecated options.
|
||||
|
||||
This class is an ``argparse.Action`` subclass that allows command
|
||||
line options to be explicitly deprecated. It modifies the help
|
||||
text for the option to indicate that it's deprecated (unless help
|
||||
has been suppressed using ``argparse.SUPPRESS``), and provides a
|
||||
means to specify an alternate option to use using the ``use``
|
||||
keyword argument to ``argparse.ArgumentParser.add_argument()``.
|
||||
The original action may be specified with the ``real_action``
|
||||
keyword argument, which has the same interpretation as the
|
||||
``action`` argument to ``argparse.ArgumentParser.add_argument()``,
|
||||
with the addition of the special "nothing" action which completely
|
||||
ignores the option (other than emitting the deprecation warning).
|
||||
Note that the deprecation warning is only emitted once per
|
||||
specific option string.
|
||||
|
||||
Note: If the ``real_action`` keyword argument specifies an unknown
|
||||
action, no warning will be emitted unless the action is used, due
|
||||
to limitations with the method used to resolve the action names.
|
||||
"""
|
||||
|
||||
def __init__(self, option_strings, dest, help=None,
|
||||
real_action=None, use=None, **kwargs):
|
||||
"""Initialize a ``DeprecatedAction`` instance.
|
||||
|
||||
:param option_strings: The recognized option strings.
|
||||
:param dest: The attribute that will be set.
|
||||
:param help: Help text. This will be updated to indicate the
|
||||
deprecation, and if ``use`` is provided, that
|
||||
text will be included as well.
|
||||
:param real_action: The actual action to invoke. This is
|
||||
interpreted the same way as the ``action``
|
||||
parameter.
|
||||
:param use: Text explaining which option to use instead.
|
||||
"""
|
||||
|
||||
# Update the help text
|
||||
if not help:
|
||||
if use:
|
||||
help = _('Deprecated; %(use)s') % {'use': use}
|
||||
else:
|
||||
help = _('Deprecated')
|
||||
elif help != argparse.SUPPRESS:
|
||||
if use:
|
||||
help = _('%(help)s (Deprecated; %(use)s)') % {
|
||||
'help': help,
|
||||
'use': use,
|
||||
}
|
||||
else:
|
||||
help = _('%(help)s (Deprecated)') % {'help': help}
|
||||
|
||||
# Initialize ourself appropriately
|
||||
super(DeprecatedAction, self).__init__(
|
||||
option_strings, dest, help=help, **kwargs)
|
||||
|
||||
# 'emitted' tracks which warnings we've emitted
|
||||
self.emitted = set()
|
||||
self.use = use
|
||||
|
||||
# Select the appropriate action
|
||||
if real_action == 'nothing':
|
||||
# NOTE(Vek): "nothing" is distinct from a real_action=None
|
||||
# argument. When real_action=None, the argparse default
|
||||
# action of "store" is used; when real_action='nothing',
|
||||
# however, we explicitly inhibit doing anything with the
|
||||
# option
|
||||
self.real_action_args = False
|
||||
self.real_action = None
|
||||
elif real_action is None or isinstance(real_action, six.string_types):
|
||||
# Specified by string (or None); we have to have a parser
|
||||
# to look up the actual action, so defer to later
|
||||
self.real_action_args = (option_strings, dest, help, kwargs)
|
||||
self.real_action = real_action
|
||||
else:
|
||||
self.real_action_args = False
|
||||
self.real_action = real_action(
|
||||
option_strings, dest, help=help, **kwargs)
|
||||
|
||||
def _get_action(self, parser):
|
||||
"""Retrieve the action callable.
|
||||
|
||||
This internal method is used to retrieve the callable
|
||||
implementing the action. If ``real_action`` was specified as
|
||||
``None`` or one of the standard string names, an internal
|
||||
method of the ``argparse.ArgumentParser`` instance is used to
|
||||
resolve it into an actual action class, which is then
|
||||
instantiated. This is cached, in case the action is called
|
||||
multiple times.
|
||||
|
||||
:param parser: The ``argparse.ArgumentParser`` instance.
|
||||
|
||||
:returns: The action callable.
|
||||
"""
|
||||
|
||||
# If a lookup is needed, look up the action in the parser
|
||||
if self.real_action_args is not False:
|
||||
option_strings, dest, help, kwargs = self.real_action_args
|
||||
action_class = parser._registry_get('action', self.real_action)
|
||||
|
||||
# Did we find the action class?
|
||||
if action_class is None:
|
||||
print(_('WARNING: Programming error: Unknown real action '
|
||||
'"%s"') % self.real_action, file=sys.stderr)
|
||||
self.real_action = None
|
||||
else:
|
||||
# OK, instantiate the action class
|
||||
self.real_action = action_class(
|
||||
option_strings, dest, help=help, **kwargs)
|
||||
|
||||
# It's been resolved, no further need to look it up
|
||||
self.real_action_args = False
|
||||
|
||||
return self.real_action
|
||||
|
||||
def __call__(self, parser, namespace, values, option_string):
|
||||
"""Implement the action.
|
||||
|
||||
Emits the deprecation warning message (only once for any given
|
||||
option string), then calls the real action (if any).
|
||||
|
||||
:param parser: The ``argparse.ArgumentParser`` instance.
|
||||
:param namespace: The ``argparse.Namespace`` object which
|
||||
should have an attribute set.
|
||||
:param values: Any arguments provided to the option.
|
||||
:param option_string: The option string that was used.
|
||||
"""
|
||||
|
||||
action = self._get_action(parser)
|
||||
|
||||
# Only emit the deprecation warning once per option
|
||||
if option_string not in self.emitted:
|
||||
if self.use:
|
||||
print(_('WARNING: Option "%(option)s" is deprecated; '
|
||||
'%(use)s') % {
|
||||
'option': option_string,
|
||||
'use': self.use,
|
||||
}, file=sys.stderr)
|
||||
else:
|
||||
print(_('WARNING: Option "%(option)s" is deprecated') %
|
||||
{'option': option_string}, file=sys.stderr)
|
||||
self.emitted.add(option_string)
|
||||
|
||||
if action:
|
||||
action(parser, namespace, values, option_string)
|
||||
|
||||
|
||||
def positive_non_zero_float(text):
|
||||
if text is None:
|
||||
return None
|
||||
@ -313,24 +461,32 @@ class OpenStackComputeShell(object):
|
||||
action='store_true',
|
||||
help=_("Print call timing info."))
|
||||
|
||||
parser.add_argument(
|
||||
'--os-auth-token',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
'--os_username',
|
||||
action=DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed '
|
||||
'in novaclient 3.3.0.') % '--os-username',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
'--os_password',
|
||||
action=DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed '
|
||||
'in novaclient 3.3.0.') % '--os-password',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
'--os_tenant_name',
|
||||
action=DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed '
|
||||
'in novaclient 3.3.0.') % '--os-tenant-name',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
'--os_auth_url',
|
||||
action=DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed '
|
||||
'in novaclient 3.3.0.') % '--os-auth-url',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
@ -340,6 +496,9 @@ class OpenStackComputeShell(object):
|
||||
help=_('Defaults to env[OS_REGION_NAME].'))
|
||||
parser.add_argument(
|
||||
'--os_region_name',
|
||||
action=DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed '
|
||||
'in novaclient 3.3.0.') % '--os-region-name',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
@ -349,6 +508,9 @@ class OpenStackComputeShell(object):
|
||||
help=argparse.SUPPRESS)
|
||||
parser.add_argument(
|
||||
'--os_auth_system',
|
||||
action=DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed '
|
||||
'in novaclient 3.3.0.') % '--os-auth-system',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
@ -357,6 +519,9 @@ class OpenStackComputeShell(object):
|
||||
help=_('Defaults to compute for most actions.'))
|
||||
parser.add_argument(
|
||||
'--service_type',
|
||||
action=DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed '
|
||||
'in novaclient 3.3.0.') % '--service-type',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
@ -366,6 +531,9 @@ class OpenStackComputeShell(object):
|
||||
help=_('Defaults to env[NOVA_SERVICE_NAME].'))
|
||||
parser.add_argument(
|
||||
'--service_name',
|
||||
action=DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed '
|
||||
'in novaclient 3.3.0.') % '--service-name',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
@ -375,6 +543,9 @@ class OpenStackComputeShell(object):
|
||||
help=_('Defaults to env[NOVA_VOLUME_SERVICE_NAME].'))
|
||||
parser.add_argument(
|
||||
'--volume_service_name',
|
||||
action=DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed '
|
||||
'in novaclient 3.3.0.') % '--volume-service-name',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
@ -391,6 +562,9 @@ class OpenStackComputeShell(object):
|
||||
|
||||
parser.add_argument(
|
||||
'--endpoint-type',
|
||||
action=DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed '
|
||||
'in novaclient 3.3.0.') % '--os-endpoint-type',
|
||||
help=argparse.SUPPRESS)
|
||||
# NOTE(dtroyer): We can't add --endpoint_type here due to argparse
|
||||
# thinking usage-list --end is ambiguous; but it
|
||||
@ -408,6 +582,9 @@ class OpenStackComputeShell(object):
|
||||
'"X.latest", defaults to env[OS_COMPUTE_API_VERSION].'))
|
||||
parser.add_argument(
|
||||
'--os_compute_api_version',
|
||||
action=DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed '
|
||||
'in novaclient 3.3.0.') % '--os-compute-api-version',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
parser.add_argument(
|
||||
@ -417,8 +594,12 @@ class OpenStackComputeShell(object):
|
||||
default=utils.env('NOVACLIENT_BYPASS_URL'),
|
||||
help="Use this API endpoint instead of the Service Catalog. "
|
||||
"Defaults to env[NOVACLIENT_BYPASS_URL].")
|
||||
parser.add_argument('--bypass_url',
|
||||
help=argparse.SUPPRESS)
|
||||
parser.add_argument(
|
||||
'--bypass_url',
|
||||
action=DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed '
|
||||
'in novaclient 3.3.0.') % '--bypass-url',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
# The auth-system-plugins might require some extra options
|
||||
novaclient.auth_plugin.load_auth_system_opts(parser)
|
||||
@ -544,10 +725,18 @@ class OpenStackComputeShell(object):
|
||||
if '--endpoint_type' in argv:
|
||||
spot = argv.index('--endpoint_type')
|
||||
argv[spot] = '--endpoint-type'
|
||||
# NOTE(Vek): Not emitting a warning here, as that will
|
||||
# occur when "--endpoint-type" is processed
|
||||
|
||||
# For backwards compat with old os-auth-token parameter
|
||||
if '--os-auth-token' in argv:
|
||||
spot = argv.index('--os-auth-token')
|
||||
argv[spot] = '--os-token'
|
||||
print(_('WARNING: Option "%(option)s" is deprecated; %(use)s') % {
|
||||
'option': '--os-auth-token',
|
||||
'use': _('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--os-token',
|
||||
}, file=sys.stderr)
|
||||
|
||||
(args, args_list) = parser.parse_known_args(argv)
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import argparse
|
||||
import distutils.version as dist_version
|
||||
import re
|
||||
import sys
|
||||
@ -76,6 +77,261 @@ def _create_ver_list(versions):
|
||||
return {'versions': {'values': versions}}
|
||||
|
||||
|
||||
class DeprecatedActionTest(utils.TestCase):
|
||||
@mock.patch.object(argparse.Action, '__init__', return_value=None)
|
||||
def test_init_emptyhelp_nouse(self, mock_init):
|
||||
result = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest', a=1, b=2, c=3)
|
||||
|
||||
self.assertEqual(result.emitted, set())
|
||||
self.assertEqual(result.use, None)
|
||||
self.assertEqual(result.real_action_args,
|
||||
('option_strings', 'dest', 'Deprecated',
|
||||
{'a': 1, 'b': 2, 'c': 3}))
|
||||
self.assertEqual(result.real_action, None)
|
||||
mock_init.assert_called_once_with(
|
||||
'option_strings', 'dest', help='Deprecated', a=1, b=2, c=3)
|
||||
|
||||
@mock.patch.object(novaclient.shell.argparse.Action, '__init__',
|
||||
return_value=None)
|
||||
def test_init_emptyhelp_withuse(self, mock_init):
|
||||
result = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest', use='use this instead', a=1, b=2, c=3)
|
||||
|
||||
self.assertEqual(result.emitted, set())
|
||||
self.assertEqual(result.use, 'use this instead')
|
||||
self.assertEqual(result.real_action_args,
|
||||
('option_strings', 'dest',
|
||||
'Deprecated; use this instead',
|
||||
{'a': 1, 'b': 2, 'c': 3}))
|
||||
self.assertEqual(result.real_action, None)
|
||||
mock_init.assert_called_once_with(
|
||||
'option_strings', 'dest', help='Deprecated; use this instead',
|
||||
a=1, b=2, c=3)
|
||||
|
||||
@mock.patch.object(argparse.Action, '__init__', return_value=None)
|
||||
def test_init_withhelp_nouse(self, mock_init):
|
||||
result = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest', help='some help', a=1, b=2, c=3)
|
||||
|
||||
self.assertEqual(result.emitted, set())
|
||||
self.assertEqual(result.use, None)
|
||||
self.assertEqual(result.real_action_args,
|
||||
('option_strings', 'dest',
|
||||
'some help (Deprecated)',
|
||||
{'a': 1, 'b': 2, 'c': 3}))
|
||||
self.assertEqual(result.real_action, None)
|
||||
mock_init.assert_called_once_with(
|
||||
'option_strings', 'dest', help='some help (Deprecated)',
|
||||
a=1, b=2, c=3)
|
||||
|
||||
@mock.patch.object(novaclient.shell.argparse.Action, '__init__',
|
||||
return_value=None)
|
||||
def test_init_withhelp_withuse(self, mock_init):
|
||||
result = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest', help='some help',
|
||||
use='use this instead', a=1, b=2, c=3)
|
||||
|
||||
self.assertEqual(result.emitted, set())
|
||||
self.assertEqual(result.use, 'use this instead')
|
||||
self.assertEqual(result.real_action_args,
|
||||
('option_strings', 'dest',
|
||||
'some help (Deprecated; use this instead)',
|
||||
{'a': 1, 'b': 2, 'c': 3}))
|
||||
self.assertEqual(result.real_action, None)
|
||||
mock_init.assert_called_once_with(
|
||||
'option_strings', 'dest',
|
||||
help='some help (Deprecated; use this instead)',
|
||||
a=1, b=2, c=3)
|
||||
|
||||
@mock.patch.object(argparse.Action, '__init__', return_value=None)
|
||||
def test_init_suppresshelp_nouse(self, mock_init):
|
||||
result = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest', help=argparse.SUPPRESS, a=1, b=2, c=3)
|
||||
|
||||
self.assertEqual(result.emitted, set())
|
||||
self.assertEqual(result.use, None)
|
||||
self.assertEqual(result.real_action_args,
|
||||
('option_strings', 'dest', argparse.SUPPRESS,
|
||||
{'a': 1, 'b': 2, 'c': 3}))
|
||||
self.assertEqual(result.real_action, None)
|
||||
mock_init.assert_called_once_with(
|
||||
'option_strings', 'dest', help=argparse.SUPPRESS, a=1, b=2, c=3)
|
||||
|
||||
@mock.patch.object(novaclient.shell.argparse.Action, '__init__',
|
||||
return_value=None)
|
||||
def test_init_suppresshelp_withuse(self, mock_init):
|
||||
result = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest', help=argparse.SUPPRESS,
|
||||
use='use this instead', a=1, b=2, c=3)
|
||||
|
||||
self.assertEqual(result.emitted, set())
|
||||
self.assertEqual(result.use, 'use this instead')
|
||||
self.assertEqual(result.real_action_args,
|
||||
('option_strings', 'dest', argparse.SUPPRESS,
|
||||
{'a': 1, 'b': 2, 'c': 3}))
|
||||
self.assertEqual(result.real_action, None)
|
||||
mock_init.assert_called_once_with(
|
||||
'option_strings', 'dest', help=argparse.SUPPRESS, a=1, b=2, c=3)
|
||||
|
||||
@mock.patch.object(argparse.Action, '__init__', return_value=None)
|
||||
def test_init_action_nothing(self, mock_init):
|
||||
result = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest', real_action='nothing', a=1, b=2, c=3)
|
||||
|
||||
self.assertEqual(result.emitted, set())
|
||||
self.assertEqual(result.use, None)
|
||||
self.assertEqual(result.real_action_args, False)
|
||||
self.assertEqual(result.real_action, None)
|
||||
mock_init.assert_called_once_with(
|
||||
'option_strings', 'dest', help='Deprecated', a=1, b=2, c=3)
|
||||
|
||||
@mock.patch.object(argparse.Action, '__init__', return_value=None)
|
||||
def test_init_action_string(self, mock_init):
|
||||
result = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest', real_action='store', a=1, b=2, c=3)
|
||||
|
||||
self.assertEqual(result.emitted, set())
|
||||
self.assertEqual(result.use, None)
|
||||
self.assertEqual(result.real_action_args,
|
||||
('option_strings', 'dest', 'Deprecated',
|
||||
{'a': 1, 'b': 2, 'c': 3}))
|
||||
self.assertEqual(result.real_action, 'store')
|
||||
mock_init.assert_called_once_with(
|
||||
'option_strings', 'dest', help='Deprecated', a=1, b=2, c=3)
|
||||
|
||||
@mock.patch.object(argparse.Action, '__init__', return_value=None)
|
||||
def test_init_action_other(self, mock_init):
|
||||
action = mock.Mock()
|
||||
result = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest', real_action=action, a=1, b=2, c=3)
|
||||
|
||||
self.assertEqual(result.emitted, set())
|
||||
self.assertEqual(result.use, None)
|
||||
self.assertEqual(result.real_action_args, False)
|
||||
self.assertEqual(result.real_action, action.return_value)
|
||||
mock_init.assert_called_once_with(
|
||||
'option_strings', 'dest', help='Deprecated', a=1, b=2, c=3)
|
||||
action.assert_called_once_with(
|
||||
'option_strings', 'dest', help='Deprecated', a=1, b=2, c=3)
|
||||
|
||||
@mock.patch.object(sys, 'stderr', six.StringIO())
|
||||
def test_get_action_nolookup(self):
|
||||
action_class = mock.Mock()
|
||||
parser = mock.Mock(**{
|
||||
'_registry_get.return_value': action_class,
|
||||
})
|
||||
obj = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest', real_action='nothing', const=1)
|
||||
obj.real_action = 'action'
|
||||
|
||||
result = obj._get_action(parser)
|
||||
|
||||
self.assertEqual(result, 'action')
|
||||
self.assertEqual(obj.real_action, 'action')
|
||||
self.assertFalse(parser._registry_get.called)
|
||||
self.assertFalse(action_class.called)
|
||||
self.assertEqual(sys.stderr.getvalue(), '')
|
||||
|
||||
@mock.patch.object(sys, 'stderr', six.StringIO())
|
||||
def test_get_action_lookup_noresult(self):
|
||||
parser = mock.Mock(**{
|
||||
'_registry_get.return_value': None,
|
||||
})
|
||||
obj = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest', real_action='store', const=1)
|
||||
|
||||
result = obj._get_action(parser)
|
||||
|
||||
self.assertEqual(result, None)
|
||||
self.assertEqual(obj.real_action, None)
|
||||
parser._registry_get.assert_called_once_with(
|
||||
'action', 'store')
|
||||
self.assertEqual(sys.stderr.getvalue(),
|
||||
'WARNING: Programming error: Unknown real action '
|
||||
'"store"\n')
|
||||
|
||||
@mock.patch.object(sys, 'stderr', six.StringIO())
|
||||
def test_get_action_lookup_withresult(self):
|
||||
action_class = mock.Mock()
|
||||
parser = mock.Mock(**{
|
||||
'_registry_get.return_value': action_class,
|
||||
})
|
||||
obj = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest', real_action='store', const=1)
|
||||
|
||||
result = obj._get_action(parser)
|
||||
|
||||
self.assertEqual(result, action_class.return_value)
|
||||
self.assertEqual(obj.real_action, action_class.return_value)
|
||||
parser._registry_get.assert_called_once_with(
|
||||
'action', 'store')
|
||||
action_class.assert_called_once_with(
|
||||
'option_strings', 'dest', help='Deprecated', const=1)
|
||||
self.assertEqual(sys.stderr.getvalue(), '')
|
||||
|
||||
@mock.patch.object(sys, 'stderr', six.StringIO())
|
||||
@mock.patch.object(novaclient.shell.DeprecatedAction, '_get_action')
|
||||
def test_call_unemitted_nouse(self, mock_get_action):
|
||||
obj = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest')
|
||||
|
||||
obj('parser', 'namespace', 'values', 'option_string')
|
||||
|
||||
self.assertEqual(obj.emitted, set(['option_string']))
|
||||
mock_get_action.assert_called_once_with('parser')
|
||||
mock_get_action.return_value.assert_called_once_with(
|
||||
'parser', 'namespace', 'values', 'option_string')
|
||||
self.assertEqual(sys.stderr.getvalue(),
|
||||
'WARNING: Option "option_string" is deprecated\n')
|
||||
|
||||
@mock.patch.object(sys, 'stderr', six.StringIO())
|
||||
@mock.patch.object(novaclient.shell.DeprecatedAction, '_get_action')
|
||||
def test_call_unemitted_withuse(self, mock_get_action):
|
||||
obj = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest', use='use this instead')
|
||||
|
||||
obj('parser', 'namespace', 'values', 'option_string')
|
||||
|
||||
self.assertEqual(obj.emitted, set(['option_string']))
|
||||
mock_get_action.assert_called_once_with('parser')
|
||||
mock_get_action.return_value.assert_called_once_with(
|
||||
'parser', 'namespace', 'values', 'option_string')
|
||||
self.assertEqual(sys.stderr.getvalue(),
|
||||
'WARNING: Option "option_string" is deprecated; '
|
||||
'use this instead\n')
|
||||
|
||||
@mock.patch.object(sys, 'stderr', six.StringIO())
|
||||
@mock.patch.object(novaclient.shell.DeprecatedAction, '_get_action')
|
||||
def test_call_emitted_nouse(self, mock_get_action):
|
||||
obj = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest')
|
||||
obj.emitted.add('option_string')
|
||||
|
||||
obj('parser', 'namespace', 'values', 'option_string')
|
||||
|
||||
self.assertEqual(obj.emitted, set(['option_string']))
|
||||
mock_get_action.assert_called_once_with('parser')
|
||||
mock_get_action.return_value.assert_called_once_with(
|
||||
'parser', 'namespace', 'values', 'option_string')
|
||||
self.assertEqual(sys.stderr.getvalue(), '')
|
||||
|
||||
@mock.patch.object(sys, 'stderr', six.StringIO())
|
||||
@mock.patch.object(novaclient.shell.DeprecatedAction, '_get_action')
|
||||
def test_call_emitted_withuse(self, mock_get_action):
|
||||
obj = novaclient.shell.DeprecatedAction(
|
||||
'option_strings', 'dest', use='use this instead')
|
||||
obj.emitted.add('option_string')
|
||||
|
||||
obj('parser', 'namespace', 'values', 'option_string')
|
||||
|
||||
self.assertEqual(obj.emitted, set(['option_string']))
|
||||
mock_get_action.assert_called_once_with('parser')
|
||||
mock_get_action.return_value.assert_called_once_with(
|
||||
'parser', 'namespace', 'values', 'option_string')
|
||||
self.assertEqual(sys.stderr.getvalue(), '')
|
||||
|
||||
|
||||
class ParserTest(utils.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
@ -43,6 +43,7 @@ from novaclient import client
|
||||
from novaclient import exceptions
|
||||
from novaclient.i18n import _
|
||||
from novaclient.openstack.common import cliutils
|
||||
from novaclient import shell
|
||||
from novaclient import utils
|
||||
from novaclient.v2 import availability_zones
|
||||
from novaclient.v2 import quotas
|
||||
@ -376,6 +377,9 @@ def _boot(cs, args):
|
||||
default=None,
|
||||
type=int,
|
||||
metavar='<number>',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "--min-count" and "--max-count"; this option will be removed '
|
||||
'in novaclient 3.3.0.'),
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--min-count',
|
||||
@ -412,6 +416,9 @@ def _boot(cs, args):
|
||||
the command keypair-add."))
|
||||
@cliutils.arg(
|
||||
'--key_name',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--key-name',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg('name', metavar='<name>', help=_('Name for the new server.'))
|
||||
@cliutils.arg(
|
||||
@ -421,6 +428,9 @@ def _boot(cs, args):
|
||||
help=_("user data file to pass to be exposed by the metadata server."))
|
||||
@cliutils.arg(
|
||||
'--user_data',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--user-data',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--availability-zone',
|
||||
@ -429,6 +439,9 @@ def _boot(cs, args):
|
||||
help=_("The availability zone for server placement."))
|
||||
@cliutils.arg(
|
||||
'--availability_zone',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--availability-zone',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--security-groups',
|
||||
@ -437,6 +450,9 @@ def _boot(cs, args):
|
||||
help=_("Comma separated list of security group names."))
|
||||
@cliutils.arg(
|
||||
'--security_groups',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--security-groups',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--block-device-mapping',
|
||||
@ -447,7 +463,10 @@ def _boot(cs, args):
|
||||
"<dev-name>=<id>:<type>:<size(GB)>:<delete-on-terminate>."))
|
||||
@cliutils.arg(
|
||||
'--block_device_mapping',
|
||||
action='append',
|
||||
real_action='append',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--block-device-mapping',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--block-device',
|
||||
@ -1288,6 +1307,9 @@ def do_image_delete(cs, args):
|
||||
help=_('Only return servers that match reservation-id.'))
|
||||
@cliutils.arg(
|
||||
'--reservation_id',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--reservation-id',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--ip',
|
||||
@ -1315,6 +1337,9 @@ def do_image_delete(cs, args):
|
||||
help=_('Search with regular expression match by server name.'))
|
||||
@cliutils.arg(
|
||||
'--instance_name',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--instance-name',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--status',
|
||||
@ -1356,6 +1381,9 @@ def do_image_delete(cs, args):
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--all-tenants',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--tenant',
|
||||
@ -1561,6 +1589,9 @@ def do_reboot(cs, args):
|
||||
help=_("Set the provided admin password on the rebuilt server."))
|
||||
@cliutils.arg(
|
||||
'--rebuild_password',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--rebuild-password',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--poll',
|
||||
@ -2132,6 +2163,9 @@ def _translate_volume_attachments_keys(collection):
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--all-tenants',
|
||||
help=argparse.SUPPRESS)
|
||||
def do_volume_list(cs, args):
|
||||
"""DEPRECATED: List all the volumes."""
|
||||
@ -2171,6 +2205,9 @@ def do_volume_show(cs, args):
|
||||
help=_('Optional snapshot ID to create the volume from. (Default=None)'))
|
||||
@cliutils.arg(
|
||||
'--snapshot_id',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--snapshot-id',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--image-id',
|
||||
@ -2184,6 +2221,9 @@ def do_volume_show(cs, args):
|
||||
help=_('Optional volume name. (Default=None)'))
|
||||
@cliutils.arg(
|
||||
'--display_name',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--display-name',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--display-description',
|
||||
@ -2192,6 +2232,9 @@ def do_volume_show(cs, args):
|
||||
help=_('Optional volume description. (Default=None)'))
|
||||
@cliutils.arg(
|
||||
'--display_description',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--display-description',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--volume-type',
|
||||
@ -2200,6 +2243,9 @@ def do_volume_show(cs, args):
|
||||
help=_('Optional volume type. (Default=None)'))
|
||||
@cliutils.arg(
|
||||
'--volume_type',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--volume-type',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--availability-zone', metavar='<availability-zone>',
|
||||
@ -2338,6 +2384,9 @@ def do_volume_snapshot_show(cs, args):
|
||||
help=_('Optional snapshot name. (Default=None)'))
|
||||
@cliutils.arg(
|
||||
'--display_name',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--display-name',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--display-description',
|
||||
@ -2346,6 +2395,9 @@ def do_volume_snapshot_show(cs, args):
|
||||
help=_('Optional snapshot description. (Default=None)'))
|
||||
@cliutils.arg(
|
||||
'--display_description',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--display-description',
|
||||
help=argparse.SUPPRESS)
|
||||
def do_volume_snapshot_create(cs, args):
|
||||
"""DEPRECATED: Add a new snapshot."""
|
||||
@ -2462,8 +2514,16 @@ def do_get_rdp_console(cs, args):
|
||||
|
||||
@cliutils.arg('server', metavar='<server>', help=_('Name or ID of server.'))
|
||||
@cliutils.arg(
|
||||
'--console_type', default='serial',
|
||||
'--console-type',
|
||||
default='serial',
|
||||
help=_('Type of serial console, default="serial".'))
|
||||
@cliutils.arg(
|
||||
'--console_type',
|
||||
default='serial',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--console-type',
|
||||
help=argparse.SUPPRESS)
|
||||
def do_get_serial_console(cs, args):
|
||||
"""Get a serial console to a server."""
|
||||
if args.console_type not in ('serial',):
|
||||
@ -2741,6 +2801,9 @@ def do_dns_delete_domain(cs, args):
|
||||
'in the specified availability zone.'))
|
||||
@cliutils.arg(
|
||||
'--availability_zone',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--availability-zone',
|
||||
help=argparse.SUPPRESS)
|
||||
def do_dns_create_private_domain(cs, args):
|
||||
"""Create the specified DNS domain."""
|
||||
@ -2925,6 +2988,9 @@ def do_secgroup_delete(cs, args):
|
||||
nargs='?',
|
||||
type=int,
|
||||
const=1,
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--all-tenants',
|
||||
help=argparse.SUPPRESS)
|
||||
def do_secgroup_list(cs, args):
|
||||
"""List security groups for the current tenant."""
|
||||
@ -3054,6 +3120,9 @@ def _keypair_create(cs, args, name, pub_key):
|
||||
help=_('Path to a public ssh key.'))
|
||||
@cliutils.arg(
|
||||
'--pub_key',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--pub-key',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--key-type',
|
||||
@ -3666,7 +3735,10 @@ def _print_aggregate_details(aggregate):
|
||||
help=_('True in case of block_migration. (Default=False:live_migration)'))
|
||||
@cliutils.arg(
|
||||
'--block_migrate',
|
||||
action='store_true',
|
||||
real_action='store_true',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--block-migrate',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--disk-over-commit',
|
||||
@ -3676,7 +3748,10 @@ def _print_aggregate_details(aggregate):
|
||||
help=_('Allow overcommit. (Default=False)'))
|
||||
@cliutils.arg(
|
||||
'--disk_over_commit',
|
||||
action='store_true',
|
||||
real_action='store_true',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--disk-over-commit',
|
||||
help=argparse.SUPPRESS)
|
||||
def do_live_migration(cs, args):
|
||||
"""Migrate running server to a new machine."""
|
||||
@ -4276,6 +4351,9 @@ def do_quota_defaults(cs, args):
|
||||
@cliutils.arg(
|
||||
'--floating_ips',
|
||||
type=int,
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--floating-ips',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--fixed-ips',
|
||||
@ -4292,6 +4370,9 @@ def do_quota_defaults(cs, args):
|
||||
@cliutils.arg(
|
||||
'--metadata_items',
|
||||
type=int,
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--metadata-items',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--injected-files',
|
||||
@ -4302,6 +4383,9 @@ def do_quota_defaults(cs, args):
|
||||
@cliutils.arg(
|
||||
'--injected_files',
|
||||
type=int,
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--injected-files',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--injected-file-content-bytes',
|
||||
@ -4312,6 +4396,9 @@ def do_quota_defaults(cs, args):
|
||||
@cliutils.arg(
|
||||
'--injected_file_content_bytes',
|
||||
type=int,
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--injected-file-content-bytes',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--injected-file-path-bytes',
|
||||
@ -4417,6 +4504,9 @@ def do_quota_class_show(cs, args):
|
||||
@cliutils.arg(
|
||||
'--floating_ips',
|
||||
type=int,
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--floating-ips',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--fixed-ips',
|
||||
@ -4433,6 +4523,9 @@ def do_quota_class_show(cs, args):
|
||||
@cliutils.arg(
|
||||
'--metadata_items',
|
||||
type=int,
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--metadata-items',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--injected-files',
|
||||
@ -4443,6 +4536,9 @@ def do_quota_class_show(cs, args):
|
||||
@cliutils.arg(
|
||||
'--injected_files',
|
||||
type=int,
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--injected-files',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--injected-file-content-bytes',
|
||||
@ -4453,6 +4549,9 @@ def do_quota_class_show(cs, args):
|
||||
@cliutils.arg(
|
||||
'--injected_file_content_bytes',
|
||||
type=int,
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use "%s"; this option will be removed in '
|
||||
'novaclient 3.3.0.') % '--injected-file-content-bytes',
|
||||
help=argparse.SUPPRESS)
|
||||
@cliutils.arg(
|
||||
'--injected-file-path-bytes',
|
||||
@ -4744,7 +4843,10 @@ def do_secgroup_delete_default_rule(cs, args):
|
||||
@cliutils.arg(
|
||||
'--policy',
|
||||
default=[],
|
||||
action='append',
|
||||
real_action='append',
|
||||
action=shell.DeprecatedAction,
|
||||
use=_('use positional parameters; this option will be removed in '
|
||||
'novaclient 3.3.0.'),
|
||||
help=argparse.SUPPRESS)
|
||||
def do_server_group_create(cs, args):
|
||||
"""Create a new server group with the specified details."""
|
||||
|
Loading…
x
Reference in New Issue
Block a user