Make passing user token to registry configurable

This patch adds CONF.use_user_token as a config option. When true, glance will
continue to use the user token when communicating with glance registry. When
false, glance will read admin credentials from the config and use those to
communicate with glance registry. Using admin credentials allow for
reauthentication when tokens expire and prevents requests from silently failing.

DocImpact
Fixes bug 1182536

Change-Id: Ia6b563677eb67d4069571c82b9dad3f025b6e9fb
This commit is contained in:
Alex Meade 2013-05-21 11:49:59 -04:00
parent 685382d3d8
commit be34808c7b
5 changed files with 169 additions and 4 deletions

View File

@ -20,6 +20,7 @@
# 577548-https-httplib-client-connection-with-certificate-v/
import collections
import copy
import errno
import functools
import httplib
@ -372,8 +373,12 @@ class BaseClient(object):
self._authenticate()
url = self._construct_url(action, params)
return self._do_request(method=method, url=url, body=body,
headers=headers)
# NOTE(ameade): We need to copy these kwargs since they can be altered
# in _do_request but we need the originals if handle_unauthenticated
# calls this function again.
return self._do_request(method=method, url=url,
body=copy.deepcopy(body),
headers=copy.deepcopy(headers))
def _construct_url(self, action, params=None):
"""

View File

@ -52,6 +52,9 @@ registry_client_opts = [
'value of 0 implies no timeout.')),
]
registry_client_ctx_opts = [
cfg.BoolOpt('use_user_token', default=True,
help=_('Whether to pass through the user token when '
'making requests to the registry.')),
cfg.StrOpt('admin_user', secret=True,
help=_('The administrators user name.')),
cfg.StrOpt('admin_password', secret=True,
@ -107,6 +110,9 @@ def configure_registry_client():
'timeout': CONF.registry_client_timeout,
}
if not CONF.use_user_token:
configure_registry_admin_creds()
def configure_registry_admin_creds():
global _CLIENT_CREDS
@ -131,7 +137,8 @@ def get_registry_client(cxt):
global _CLIENT_CREDS, _CLIENT_KWARGS, _CLIENT_HOST, _CLIENT_PORT
global _METADATA_ENCRYPTION_KEY
kwargs = _CLIENT_KWARGS.copy()
kwargs['auth_tok'] = cxt.auth_tok
if CONF.use_user_token:
kwargs['auth_tok'] = cxt.auth_tok
if _CLIENT_CREDS:
kwargs['creds'] = _CLIENT_CREDS
return client.RegistryClient(_CLIENT_HOST, _CLIENT_PORT,

View File

@ -53,6 +53,9 @@ registry_client_opts = [
]
registry_client_ctx_opts = [
cfg.BoolOpt('use_user_token', default=True,
help=_('Whether to pass through the user token when '
'making requests to the registry.')),
cfg.StrOpt('admin_user', secret=True,
help=_('The administrators user name.')),
cfg.StrOpt('admin_password', secret=True,
@ -104,6 +107,9 @@ def configure_registry_client():
'timeout': CONF.registry_client_timeout,
}
if not CONF.use_user_token:
configure_registry_admin_creds()
def configure_registry_admin_creds():
global _CLIENT_CREDS
@ -127,7 +133,8 @@ def configure_registry_admin_creds():
def get_registry_client(cxt):
global _CLIENT_CREDS, _CLIENT_KWARGS, _CLIENT_HOST, _CLIENT_PORT
kwargs = _CLIENT_KWARGS.copy()
kwargs['auth_tok'] = cxt.auth_tok
if CONF.use_user_token:
kwargs['auth_tok'] = cxt.auth_tok
if _CLIENT_CREDS:
kwargs['creds'] = _CLIENT_CREDS
return client.RegistryClient(_CLIENT_HOST, _CLIENT_PORT, **kwargs)

View File

@ -17,6 +17,9 @@
import copy
import datetime
import os
import mox
import testtools
@ -28,6 +31,7 @@ from glance.db.sqlalchemy import api as db_api
from glance.db.sqlalchemy import models as db_models
from glance.openstack.common import timeutils
from glance.openstack.common import uuidutils
import glance.registry.client.v1.api as rapi
from glance.registry.client.v1.api import client as rclient
from glance.tests.unit import base
@ -1067,6 +1071,7 @@ class TestRegistryV1Client(base.IsolatedUnitTest):
class TestBaseClient(testtools.TestCase):
"""
Test proper actions made for both valid and invalid requests
against a Registry service
@ -1088,3 +1093,69 @@ class TestBaseClient(testtools.TestCase):
self.assertEqual(expected['key_file'], actual['key_file'])
self.assertEqual(expected['cert_file'], actual['cert_file'])
self.assertEqual(expected['timeout'], actual['timeout'])
class TestRegistryV1ClientApi(base.IsolatedUnitTest):
def setUp(self):
"""Establish a clean test environment"""
super(TestRegistryV1ClientApi, self).setUp()
self.mox = mox.Mox()
reload(rapi)
def tearDown(self):
"""Clear the test environment"""
super(TestRegistryV1ClientApi, self).tearDown()
self.mox.UnsetStubs()
def test_configure_registry_client_not_using_use_user_token(self):
self.config(use_user_token=False)
self.mox.StubOutWithMock(rapi, 'configure_registry_admin_creds')
rapi.configure_registry_admin_creds()
self.mox.ReplayAll()
rapi.configure_registry_client()
self.mox.VerifyAll()
def test_configure_registry_admin_creds(self):
expected = {
'user': 'user',
'password': 'password',
'username': 'user',
'tenant': 'tenant',
'auth_url': None,
'strategy': 'configured_strategy',
'region': 'region',
}
self.config(admin_user=expected['user'])
self.config(admin_password=expected['password'])
self.config(admin_tenant_name=expected['tenant'])
self.config(auth_strategy=expected['strategy'])
self.config(auth_region=expected['region'])
self.stubs.Set(os, 'getenv', lambda x: None)
self.assertEquals(rapi._CLIENT_CREDS, None)
rapi.configure_registry_admin_creds()
self.assertEquals(rapi._CLIENT_CREDS, expected)
def test_configure_registry_admin_creds_with_auth_url(self):
expected = {
'user': 'user',
'password': 'password',
'username': 'user',
'tenant': 'tenant',
'auth_url': 'auth_url',
'strategy': 'keystone',
'region': 'region',
}
self.config(admin_user=expected['user'])
self.config(admin_password=expected['password'])
self.config(admin_tenant_name=expected['tenant'])
self.config(auth_url=expected['auth_url'])
self.config(auth_strategy='test_strategy')
self.config(auth_region=expected['region'])
self.assertEquals(rapi._CLIENT_CREDS, None)
rapi.configure_registry_admin_creds()
self.assertEquals(rapi._CLIENT_CREDS, expected)

View File

@ -23,6 +23,9 @@ the registry's driver tests will be added.
import copy
import datetime
import os
import mox
from glance.common import config
from glance.common import exception
@ -31,6 +34,7 @@ from glance.db.sqlalchemy import api as db_api
from glance.db.sqlalchemy import models as db_models
from glance.openstack.common import timeutils
from glance.openstack.common import uuidutils
import glance.registry.client.v2.api as rapi
from glance.registry.client.v2.api import client as rclient
from glance.registry.api import v2 as rserver
from glance.tests.unit import base
@ -773,3 +777,74 @@ class TestRegistryV2Client(base.IsolatedUnitTest):
self.client.image_member_delete(memb_id=member['id'])
memb_list = self.client.image_member_find(member='pattieblack')
self.assertEquals(len(memb_list), 0)
class TestRegistryV2ClientApi(base.IsolatedUnitTest):
"""
Test proper actions made for both valid and invalid requests
against a Registry service
"""
def setUp(self):
"""Establish a clean test environment"""
super(TestRegistryV2ClientApi, self).setUp()
self.mox = mox.Mox()
reload(rapi)
def tearDown(self):
"""Clear the test environment"""
super(TestRegistryV2ClientApi, self).tearDown()
self.mox.UnsetStubs()
def test_configure_registry_client_not_using_use_user_token(self):
self.config(use_user_token=False)
self.mox.StubOutWithMock(rapi, 'configure_registry_admin_creds')
rapi.configure_registry_admin_creds()
self.mox.ReplayAll()
rapi.configure_registry_client()
self.mox.VerifyAll()
def test_configure_registry_admin_creds(self):
expected = {
'user': 'user',
'password': 'password',
'username': 'user',
'tenant': 'tenant',
'auth_url': None,
'strategy': 'configured_strategy',
'region': 'region',
}
self.config(admin_user=expected['user'])
self.config(admin_password=expected['password'])
self.config(admin_tenant_name=expected['tenant'])
self.config(auth_strategy=expected['strategy'])
self.config(auth_region=expected['region'])
self.stubs.Set(os, 'getenv', lambda x: None)
self.assertEquals(rapi._CLIENT_CREDS, None)
rapi.configure_registry_admin_creds()
self.assertEquals(rapi._CLIENT_CREDS, expected)
def test_configure_registry_admin_creds_with_auth_url(self):
expected = {
'user': 'user',
'password': 'password',
'username': 'user',
'tenant': 'tenant',
'auth_url': 'auth_url',
'strategy': 'keystone',
'region': 'region',
}
self.config(admin_user=expected['user'])
self.config(admin_password=expected['password'])
self.config(admin_tenant_name=expected['tenant'])
self.config(auth_url=expected['auth_url'])
self.config(auth_strategy='test_strategy')
self.config(auth_region=expected['region'])
self.assertEquals(rapi._CLIENT_CREDS, None)
rapi.configure_registry_admin_creds()
self.assertEquals(rapi._CLIENT_CREDS, expected)