Merge "Log warning when API version is not specified for the ironic tool"

This commit is contained in:
Jenkins
2017-07-24 16:15:33 +00:00
committed by Gerrit Code Review
5 changed files with 61 additions and 24 deletions

View File

@@ -39,6 +39,13 @@ from ironicclient import exc
LATEST_API_VERSION = ('1', 'latest') LATEST_API_VERSION = ('1', 'latest')
MISSING_VERSION_WARNING = (
"You are using the default API version of the 'ironic' command "
"This is currently API version %s. In the future, the default will be "
"the latest API version understood by both API and CLI. You can preserve "
"the current behavior by passing the --ironic-api-version argument with "
"the desired version or using the IRONIC_API_VERSION environment variable."
)
class IronicShell(object): class IronicShell(object):
@@ -153,8 +160,8 @@ class IronicShell(object):
help=argparse.SUPPRESS) help=argparse.SUPPRESS)
parser.add_argument('--ironic-api-version', parser.add_argument('--ironic-api-version',
default=cliutils.env( default=cliutils.env('IRONIC_API_VERSION',
'IRONIC_API_VERSION', default='1'), default=None),
help=_('Accepts 1.x (where "x" is microversion) ' help=_('Accepts 1.x (where "x" is microversion) '
'or "latest", Defaults to ' 'or "latest", Defaults to '
'env[IRONIC_API_VERSION] or 1')) 'env[IRONIC_API_VERSION] or 1'))
@@ -294,6 +301,11 @@ class IronicShell(object):
if api_version == 'latest': if api_version == 'latest':
return LATEST_API_VERSION return LATEST_API_VERSION
else: else:
if api_version is None:
print(MISSING_VERSION_WARNING % http.DEFAULT_VER,
file=sys.stderr)
api_version = '1'
try: try:
versions = tuple(int(i) for i in api_version.split('.')) versions = tuple(int(i) for i in api_version.split('.'))
except ValueError: except ValueError:

View File

@@ -126,7 +126,7 @@ class FunctionalTestBase(base.ClientTestBase):
return base.execute(cmd, action, flags, params, return base.execute(cmd, action, flags, params,
cli_dir=self.client.cli_dir) cli_dir=self.client.cli_dir)
def _ironic(self, action, flags='', params=''): def _ironic(self, action, flags='', params='', merge_stderr=False):
"""Execute ironic command for the given action. """Execute ironic command for the given action.
:param action: the cli command to run using Ironic :param action: the cli command to run using Ironic
@@ -135,6 +135,8 @@ class FunctionalTestBase(base.ClientTestBase):
:type flags: string :type flags: string
:param params: any optional positional args to use :param params: any optional positional args to use
:type params: string :type params: string
:param merge_stderr: whether to merge stderr into the result
:type merge_stderr: bool
""" """
flags += ' --os-endpoint-type publicURL' flags += ' --os-endpoint-type publicURL'
if hasattr(self, 'os_auth_token'): if hasattr(self, 'os_auth_token'):
@@ -148,7 +150,8 @@ class FunctionalTestBase(base.ClientTestBase):
'value': getattr(self, domain_attr) 'value': getattr(self, domain_attr)
} }
return self.client.cmd_with_auth('ironic', return self.client.cmd_with_auth('ironic',
action, flags, params) action, flags, params,
merge_stderr=merge_stderr)
def _ironic_osc(self, action, flags='', params='', merge_stderr=False): def _ironic_osc(self, action, flags='', params='', merge_stderr=False):
"""Execute baremetal commands via OpenStack Client.""" """Execute baremetal commands via OpenStack Client."""

View File

@@ -67,3 +67,11 @@ class IronicClientHelp(base.FunctionalTestBase):
self.assertIn(caption, output) self.assertIn(caption, output)
for string in subcommands: for string in subcommands:
self.assertIn(string, output) self.assertIn(string, output)
def test_warning_on_api_version(self):
result = self._ironic('help', merge_stderr=True)
self.assertIn('You are using the default API version', result)
result = self._ironic('help', flags='--ironic-api-version 1.9',
merge_stderr=True)
self.assertNotIn('You are using the default API version', result)

View File

@@ -74,19 +74,18 @@ class ShellTest(utils.BaseTestCase):
super(ShellTest, self).setUp() super(ShellTest, self).setUp()
def shell(self, argstr): def shell(self, argstr):
orig = sys.stdout with mock.patch.object(sys, 'stdout', six.StringIO()):
try: with mock.patch.object(sys, 'stderr', six.StringIO()):
sys.stdout = six.StringIO() try:
_shell = ironic_shell.IronicShell() _shell = ironic_shell.IronicShell()
_shell.main(argstr.split()) _shell.main(argstr.split())
except SystemExit: except SystemExit:
exc_type, exc_value, exc_traceback = sys.exc_info() exc_type, exc_value, exc_traceback = sys.exc_info()
self.assertEqual(0, exc_value.code) self.assertEqual(0, exc_value.code)
finally: finally:
out = sys.stdout.getvalue() out = sys.stdout.getvalue()
sys.stdout.close() err = sys.stderr.getvalue()
sys.stdout = orig return out, err
return out
def test_help_unknown_command(self): def test_help_unknown_command(self):
self.assertRaises(exc.CommandError, self.shell, 'help foofoo') self.assertRaises(exc.CommandError, self.shell, 'help foofoo')
@@ -99,7 +98,7 @@ class ShellTest(utils.BaseTestCase):
'for help on a specific command', 'for help on a specific command',
] ]
for argstr in ['--help', 'help']: for argstr in ['--help', 'help']:
help_text = self.shell(argstr) help_text = self.shell(argstr)[0]
for r in required: for r in required:
self.assertThat(help_text, self.assertThat(help_text,
matchers.MatchesRegex(r, matchers.MatchesRegex(r,
@@ -114,7 +113,7 @@ class ShellTest(utils.BaseTestCase):
'help chassis-show', 'help chassis-show',
] ]
for argstr in argstrings: for argstr in argstrings:
help_text = self.shell(argstr) help_text = self.shell(argstr)[0]
for r in required: for r in required:
self.assertThat(help_text, self.assertThat(help_text,
matchers.MatchesRegex(r, self.re_options)) matchers.MatchesRegex(r, self.re_options))
@@ -129,7 +128,7 @@ class ShellTest(utils.BaseTestCase):
'help node-create', 'help node-create',
] ]
for argstr in argstrings: for argstr in argstrings:
help_text = self.shell(argstr) help_text = self.shell(argstr)[0]
for r in required: for r in required:
self.assertThat(help_text, self.assertThat(help_text,
matchers.MatchesRegex(r, self.re_options)) matchers.MatchesRegex(r, self.re_options))
@@ -144,7 +143,7 @@ class ShellTest(utils.BaseTestCase):
'help port-create', 'help port-create',
] ]
for argstr in argstrings: for argstr in argstrings:
help_text = self.shell(argstr) help_text = self.shell(argstr)[0]
for r in required: for r in required:
self.assertThat(help_text, self.assertThat(help_text,
matchers.MatchesRegex(r, self.re_options)) matchers.MatchesRegex(r, self.re_options))
@@ -236,7 +235,7 @@ class ShellTest(utils.BaseTestCase):
self.fail('CommandError not raised') self.fail('CommandError not raised')
def test_bash_completion(self): def test_bash_completion(self):
stdout = self.shell('bash-completion') stdout = self.shell('bash-completion')[0]
# just check we have some output # just check we have some output
required = [ required = [
'.*--driver_info', '.*--driver_info',
@@ -249,8 +248,12 @@ class ShellTest(utils.BaseTestCase):
matchers.MatchesRegex(r, self.re_options)) matchers.MatchesRegex(r, self.re_options))
def test_ironic_api_version(self): def test_ironic_api_version(self):
self.shell('--ironic-api-version 1.2 help') err = self.shell('--ironic-api-version 1.2 help')[1]
self.shell('--ironic-api-version latest help') self.assertFalse(err)
err = self.shell('--ironic-api-version latest help')[1]
self.assertFalse(err)
self.assertRaises(exc.CommandError, self.assertRaises(exc.CommandError,
self.shell, '--ironic-api-version 1.2.1 help') self.shell, '--ironic-api-version 1.2.1 help')
@@ -258,6 +261,10 @@ class ShellTest(utils.BaseTestCase):
self.assertRaises(exceptions.UnsupportedVersion, self.assertRaises(exceptions.UnsupportedVersion,
self.shell, '--ironic-api-version 0.8 help') self.shell, '--ironic-api-version 0.8 help')
def test_warning_on_no_version(self):
err = self.shell('help')[1]
self.assertIn('You are using the default API version', err)
class TestCase(testtools.TestCase): class TestCase(testtools.TestCase):

View File

@@ -0,0 +1,7 @@
---
deprecations:
- |
Currently, the default API version for the ``ironic`` tool is fixed to be
1.9. In the Queens release, it will be changed to the latest version
understood by both the client and the server. In this release a warning is
logged, if no explicit version is provided.