Merge "Check if v2 is available and fallback"
This commit is contained in:
@@ -91,7 +91,10 @@ class _BaseHTTPClient(object):
|
||||
if not resp.ok:
|
||||
LOG.debug("Request returned failure status %s." % resp.status_code)
|
||||
raise exc.from_response(resp, resp.content)
|
||||
elif resp.status_code == requests.codes.MULTIPLE_CHOICES:
|
||||
elif (resp.status_code == requests.codes.MULTIPLE_CHOICES and
|
||||
resp.request.path_url != '/versions'):
|
||||
# NOTE(flaper87): Eventually, we'll remove the check on `versions`
|
||||
# which is a bug (1491350) on the server.
|
||||
raise exc.from_response(resp)
|
||||
|
||||
content_type = resp.headers.get('Content-Type')
|
||||
|
@@ -553,7 +553,7 @@ class OpenStackImagesShell(object):
|
||||
client = glanceclient.Client(api_version, endpoint, **kwargs)
|
||||
return client
|
||||
|
||||
def _cache_schemas(self, options, home_dir='~/.glanceclient'):
|
||||
def _cache_schemas(self, options, client, home_dir='~/.glanceclient'):
|
||||
homedir = os.path.expanduser(home_dir)
|
||||
path_prefix = homedir
|
||||
if options.os_auth_url:
|
||||
@@ -573,16 +573,11 @@ class OpenStackImagesShell(object):
|
||||
schema_file_paths = [os.path.join(path_prefix, x + '_schema.json')
|
||||
for x in ['image', 'namespace', 'resource_type']]
|
||||
|
||||
client = None
|
||||
failed_download_schema = 0
|
||||
for resource, schema_file_path in zip(resources, schema_file_paths):
|
||||
if (not os.path.exists(schema_file_path)) or options.get_schema:
|
||||
try:
|
||||
if not client:
|
||||
client = self._get_versioned_client('2', options,
|
||||
force_auth=True)
|
||||
schema = client.schemas.get(resource)
|
||||
|
||||
with open(schema_file_path, 'w') as f:
|
||||
f.write(json.dumps(schema.raw()))
|
||||
except Exception:
|
||||
@@ -624,8 +619,21 @@ class OpenStackImagesShell(object):
|
||||
"Supported values are %s" % SUPPORTED_VERSIONS)
|
||||
utils.exit(msg=msg)
|
||||
|
||||
if api_version == 2:
|
||||
switch_version = self._cache_schemas(options)
|
||||
if not options.os_image_api_version and api_version == 2:
|
||||
switch_version = True
|
||||
client = self._get_versioned_client('2', options,
|
||||
force_auth=True)
|
||||
|
||||
resp, body = client.http_client.get('/versions')
|
||||
|
||||
for version in body['versions']:
|
||||
if version['id'].startswith('v2'):
|
||||
# NOTE(flaper87): We know v2 is enabled in the server,
|
||||
# which means we should be able to get the schemas and
|
||||
# move on.
|
||||
switch_version = self._cache_schemas(options, client)
|
||||
break
|
||||
|
||||
if switch_version:
|
||||
print('WARNING: The client is falling back to v1 because'
|
||||
' the accessing to v2 failed. This behavior will'
|
||||
|
@@ -80,7 +80,7 @@ class SimpleReadOnlyGlanceClientTest(base.ClientTestBase):
|
||||
params=param_image_id)
|
||||
|
||||
def test_help(self):
|
||||
help_text = self.glance('help')
|
||||
help_text = self.glance('--os-image-api-version 2 help')
|
||||
lines = help_text.split('\n')
|
||||
self.assertFirstLineStartsWith(lines, 'usage: glance')
|
||||
|
||||
|
@@ -147,17 +147,18 @@ class ShellTest(testutils.TestCase):
|
||||
|
||||
def test_help_unknown_command(self):
|
||||
shell = openstack_shell.OpenStackImagesShell()
|
||||
argstr = 'help foofoo'
|
||||
argstr = '--os-image-api-version 2 help foofoo'
|
||||
self.assertRaises(exc.CommandError, shell.main, argstr.split())
|
||||
|
||||
def test_help(self):
|
||||
shell = openstack_shell.OpenStackImagesShell()
|
||||
argstr = 'help'
|
||||
argstr = '--os-image-api-version 2 help'
|
||||
actual = shell.main(argstr.split())
|
||||
self.assertEqual(0, actual)
|
||||
|
||||
def test_help_on_subcommand_error(self):
|
||||
self.assertRaises(exc.CommandError, shell, 'help bad')
|
||||
self.assertRaises(exc.CommandError, shell,
|
||||
'--os-image-api-version 2 help bad')
|
||||
|
||||
def test_help_v2_no_schema(self):
|
||||
shell = openstack_shell.OpenStackImagesShell()
|
||||
@@ -185,7 +186,9 @@ class ShellTest(testutils.TestCase):
|
||||
def test_cert_and_key_args_interchangeable(self,
|
||||
mock_versioned_client):
|
||||
# make sure --os-cert and --os-key are passed correctly
|
||||
args = '--os-cert mycert --os-key mykey image-list'
|
||||
args = ('--os-image-api-version 2 '
|
||||
'--os-cert mycert '
|
||||
'--os-key mykey image-list')
|
||||
shell(args)
|
||||
assert mock_versioned_client.called
|
||||
((api_version, args), kwargs) = mock_versioned_client.call_args
|
||||
@@ -193,7 +196,9 @@ class ShellTest(testutils.TestCase):
|
||||
self.assertEqual('mykey', args.os_key)
|
||||
|
||||
# make sure we get the same thing with --cert-file and --key-file
|
||||
args = '--cert-file mycertfile --key-file mykeyfile image-list'
|
||||
args = ('--os-image-api-version 2 '
|
||||
'--cert-file mycertfile '
|
||||
'--key-file mykeyfile image-list')
|
||||
glance_shell = openstack_shell.OpenStackImagesShell()
|
||||
glance_shell.main(args.split())
|
||||
assert mock_versioned_client.called
|
||||
@@ -381,6 +386,34 @@ class ShellTest(testutils.TestCase):
|
||||
msg = 'Unable to import module. Re-run with --debug for more info.'
|
||||
self.assertEqual(msg, str(e))
|
||||
|
||||
@mock.patch('glanceclient.v2.client.Client')
|
||||
@mock.patch('glanceclient.v1.images.ImageManager.list')
|
||||
def test_shell_v1_fallback_from_v2(self, v1_imgs, v2_client):
|
||||
self.make_env()
|
||||
cli2 = mock.MagicMock()
|
||||
v2_client.return_value = cli2
|
||||
cli2.http_client.get.return_value = (None, {'versions': []})
|
||||
args = 'image-list'
|
||||
glance_shell = openstack_shell.OpenStackImagesShell()
|
||||
glance_shell.main(args.split())
|
||||
self.assertFalse(cli2.schemas.get.called)
|
||||
self.assertTrue(v1_imgs.called)
|
||||
|
||||
@mock.patch.object(openstack_shell.OpenStackImagesShell,
|
||||
'_cache_schemas')
|
||||
@mock.patch('glanceclient.v2.client.Client')
|
||||
def test_shell_no_fallback_from_v2(self, v2_client, cache_schemas):
|
||||
self.make_env()
|
||||
cli2 = mock.MagicMock()
|
||||
v2_client.return_value = cli2
|
||||
cli2.http_client.get.return_value = (None,
|
||||
{'versions': [{'id': 'v2'}]})
|
||||
cache_schemas.return_value = False
|
||||
args = 'image-list'
|
||||
glance_shell = openstack_shell.OpenStackImagesShell()
|
||||
glance_shell.main(args.split())
|
||||
self.assertTrue(cli2.images.list.called)
|
||||
|
||||
@mock.patch('glanceclient.v1.client.Client')
|
||||
def test_auth_plugin_invocation_without_username_with_v1(self, v1_client):
|
||||
self.make_env(exclude='OS_USERNAME')
|
||||
@@ -477,7 +510,7 @@ class ShellTestWithKeystoneV3Auth(ShellTest):
|
||||
self.assertRaises(exc.CommandError, glance_shell.main, args.split())
|
||||
|
||||
def test_bash_completion(self):
|
||||
stdout, stderr = self.shell('bash_completion')
|
||||
stdout, stderr = self.shell('--os-image-api-version 2 bash_completion')
|
||||
# just check we have some output
|
||||
required = [
|
||||
'--status',
|
||||
@@ -542,8 +575,9 @@ class ShellCacheSchemaTest(testutils.TestCase):
|
||||
}
|
||||
schema_odict = OrderedDict(self.schema_dict)
|
||||
|
||||
self.shell._cache_schemas(self._make_args(options),
|
||||
home_dir=self.cache_dir)
|
||||
args = self._make_args(options)
|
||||
client = self.shell._get_versioned_client('2', args, force_auth=True)
|
||||
self.shell._cache_schemas(args, client, home_dir=self.cache_dir)
|
||||
|
||||
self.assertEqual(12, open.mock_calls.__len__())
|
||||
self.assertEqual(mock.call(self.cache_files[0], 'w'),
|
||||
@@ -564,8 +598,9 @@ class ShellCacheSchemaTest(testutils.TestCase):
|
||||
}
|
||||
schema_odict = OrderedDict(self.schema_dict)
|
||||
|
||||
self.shell._cache_schemas(self._make_args(options),
|
||||
home_dir=self.cache_dir)
|
||||
args = self._make_args(options)
|
||||
client = self.shell._get_versioned_client('2', args, force_auth=True)
|
||||
self.shell._cache_schemas(args, client, home_dir=self.cache_dir)
|
||||
|
||||
self.assertEqual(12, open.mock_calls.__len__())
|
||||
self.assertEqual(mock.call(self.cache_files[0], 'w'),
|
||||
@@ -585,8 +620,9 @@ class ShellCacheSchemaTest(testutils.TestCase):
|
||||
'os_auth_url': self.os_auth_url
|
||||
}
|
||||
|
||||
client = mock.MagicMock()
|
||||
self.shell._cache_schemas(self._make_args(options),
|
||||
home_dir=self.cache_dir)
|
||||
client, home_dir=self.cache_dir)
|
||||
|
||||
os.path.exists.assert_any_call(self.prefix_path)
|
||||
os.path.exists.assert_any_call(self.cache_files[0])
|
||||
@@ -604,6 +640,8 @@ class ShellCacheSchemaTest(testutils.TestCase):
|
||||
|
||||
self.client.schemas.get.return_value = Exception()
|
||||
|
||||
client = mock.MagicMock()
|
||||
switch_version = self.shell._cache_schemas(self._make_args(options),
|
||||
client,
|
||||
home_dir=self.cache_dir)
|
||||
self.assertEqual(switch_version, True)
|
||||
|
Reference in New Issue
Block a user