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