Glance cache updates to support Keystone Essex.
Glance caching updates to support keystone service tenants: * Update glance-cache-manage so that it supports the same style OS_ environment variables and CLI options for auth that bin/glance does. * Updates registry/client so that it supports Keystone KSL style service tenants. As services no longer use admin_tokens this is a requirement to be able to use caching w/ KSL. Fixes LP Bug #949486. Change-Id: I8d0e56a9ec0d20ef56ed2ce8b860d987ae159e01
This commit is contained in:
parent
b43b676e58
commit
4d41027d21
47
bin/glance
47
bin/glance
@ -41,10 +41,10 @@ if os.path.exists(os.path.join(possible_topdir, 'glance', '__init__.py')):
|
||||
|
||||
gettext.install('glance', unicode=1)
|
||||
|
||||
from glance import version
|
||||
from glance import client as glance_client
|
||||
from glance.common import exception
|
||||
from glance.common import utils
|
||||
from glance import version
|
||||
|
||||
|
||||
SUCCESS = 0
|
||||
@ -784,43 +784,16 @@ def get_client(options):
|
||||
specified by the --host and --port options
|
||||
supplied to the CLI
|
||||
"""
|
||||
|
||||
if options.auth_url or os.getenv('OS_AUTH_URL'):
|
||||
force_strategy = 'keystone'
|
||||
else:
|
||||
force_strategy = None
|
||||
|
||||
creds = dict(username=options.username or \
|
||||
os.getenv('OS_AUTH_USER', os.getenv('OS_USERNAME')),
|
||||
password=options.password or \
|
||||
os.getenv('OS_AUTH_KEY', os.getenv('OS_PASSWORD')),
|
||||
tenant=options.tenant or \
|
||||
os.getenv('OS_AUTH_TENANT',
|
||||
os.getenv('OS_TENANT_NAME')),
|
||||
auth_url=options.auth_url or os.getenv('OS_AUTH_URL'),
|
||||
strategy=force_strategy or options.auth_strategy or \
|
||||
os.getenv('OS_AUTH_STRATEGY', 'noauth'),
|
||||
region=options.region or os.getenv('OS_REGION_NAME'),
|
||||
)
|
||||
|
||||
if creds['strategy'] == 'keystone' and not creds['auth_url']:
|
||||
msg = ("--auth_url option or OS_AUTH_URL environment variable "
|
||||
"required when keystone authentication strategy is enabled\n")
|
||||
raise exception.ClientConfigurationError(msg)
|
||||
|
||||
use_ssl = (options.use_ssl or (
|
||||
creds['auth_url'] is not None and
|
||||
creds['auth_url'].find('https') != -1))
|
||||
|
||||
client = (glance_client.ProgressClient if not options.is_silent_upload
|
||||
else glance_client.Client)
|
||||
|
||||
return client(host=options.host,
|
||||
return glance_client.get_client(host=options.host,
|
||||
port=options.port,
|
||||
use_ssl=use_ssl,
|
||||
auth_tok=options.auth_token or
|
||||
os.getenv('OS_TOKEN'),
|
||||
creds=creds,
|
||||
username=options.username,
|
||||
password=options.password,
|
||||
tenant=options.tenant,
|
||||
auth_url=options.auth_url,
|
||||
auth_strategy=options.auth_strategy,
|
||||
auth_token=options.auth_token,
|
||||
region=options.region,
|
||||
is_silent_upload=options.is_silent_upload,
|
||||
insecure=options.insecure)
|
||||
|
||||
|
||||
|
@ -38,9 +38,9 @@ if os.path.exists(os.path.join(possible_topdir, 'glance', '__init__.py')):
|
||||
gettext.install('glance', unicode=1)
|
||||
|
||||
from glance import client as glance_client
|
||||
from glance import version
|
||||
from glance.common import exception
|
||||
from glance.common import utils
|
||||
from glance import version
|
||||
|
||||
|
||||
SUCCESS = 0
|
||||
@ -259,19 +259,16 @@ def get_client(options):
|
||||
specified by the --host and --port options
|
||||
supplied to the CLI
|
||||
"""
|
||||
creds = dict(username=os.getenv('OS_AUTH_USER'),
|
||||
password=os.getenv('OS_AUTH_KEY'),
|
||||
tenant=os.getenv('OS_AUTH_TENANT'),
|
||||
auth_url=os.getenv('OS_AUTH_URL'),
|
||||
strategy=os.getenv('OS_AUTH_STRATEGY', 'noauth'))
|
||||
|
||||
use_ssl = (options.host.find('https') != -1 or (
|
||||
creds['auth_url'] is not None and
|
||||
creds['auth_url'].find('https') != -1))
|
||||
|
||||
return glance_client.Client(host=options.host, port=options.port,
|
||||
use_ssl=use_ssl, auth_tok=options.auth_token,
|
||||
creds=creds)
|
||||
return glance_client.get_client(host=options.host,
|
||||
port=options.port,
|
||||
username=options.username,
|
||||
password=options.password,
|
||||
tenant=options.tenant,
|
||||
auth_url=options.auth_url,
|
||||
auth_strategy=options.auth_strategy,
|
||||
auth_token=options.auth_token,
|
||||
region=options.region,
|
||||
insecure=options.insecure)
|
||||
|
||||
|
||||
def create_options(parser):
|
||||
@ -296,6 +293,34 @@ def create_options(parser):
|
||||
metavar="TOKEN", default=None,
|
||||
help="Authentication token to use to identify the "
|
||||
"client to the glance server")
|
||||
parser.add_option('-I', '--username', dest="username",
|
||||
metavar="USER", default=None,
|
||||
help="User name used to acquire an authentication token")
|
||||
parser.add_option('-K', '--password', dest="password",
|
||||
metavar="PASSWORD", default=None,
|
||||
help="Password used to acquire an authentication token")
|
||||
parser.add_option('-R', '--region', dest="region",
|
||||
metavar="REGION", default=None,
|
||||
help="Region name. When using keystone authentication "
|
||||
"version 2.0 or later this identifies the region "
|
||||
"name to use when selecting the service endpoint. A "
|
||||
"region name must be provided if more than one "
|
||||
"region endpoint is available")
|
||||
parser.add_option('-T', '--tenant', dest="tenant",
|
||||
metavar="TENANT", default=None,
|
||||
help="Tenant name")
|
||||
parser.add_option('-N', '--auth_url', dest="auth_url",
|
||||
metavar="AUTH_URL", default=None,
|
||||
help="Authentication URL")
|
||||
parser.add_option('-k', '--insecure', dest="insecure",
|
||||
default=False, action="store_true",
|
||||
help="Explicitly allow glance to perform \"insecure\" "
|
||||
"SSL (https) requests. The server's certificate will "
|
||||
"not be verified against any certificate authorities. "
|
||||
"This option should be used with caution.")
|
||||
parser.add_option('-S', '--auth_strategy', dest="auth_strategy",
|
||||
metavar="STRATEGY", default=None,
|
||||
help="Authentication strategy (keystone or noauth)")
|
||||
parser.add_option('-f', '--force', dest="force", metavar="FORCE",
|
||||
default=False, action="store_true",
|
||||
help="Prevent select actions from requesting "
|
||||
|
@ -36,5 +36,8 @@ registry_host = 0.0.0.0
|
||||
# Port the registry server is listening on
|
||||
registry_port = 9191
|
||||
|
||||
# Admin token to use if using Keystone
|
||||
# admin_token = 123
|
||||
# Auth settings if using Keystone
|
||||
# auth_url = http://127.0.0.1:5000/v2.0/
|
||||
# admin_tenant_name = %SERVICE_TENANT_NAME%
|
||||
# admin_user = %SERVICE_USER%
|
||||
# admin_password = %SERVICE_PASSWORD%
|
||||
|
@ -399,3 +399,51 @@ class ProgressClient(V1Client):
|
||||
return transfer_info
|
||||
|
||||
Client = V1Client
|
||||
|
||||
|
||||
def get_client(host, port=None, username=None,
|
||||
password=None, tenant=None,
|
||||
auth_url=None, auth_strategy=None,
|
||||
auth_token=None, region=None,
|
||||
is_silent_upload=False, insecure=False):
|
||||
"""
|
||||
Returns a new client Glance client object based on common kwargs.
|
||||
If an option isn't specified falls back to common environment variable
|
||||
defaults.
|
||||
"""
|
||||
|
||||
if auth_url or os.getenv('OS_AUTH_URL'):
|
||||
force_strategy = 'keystone'
|
||||
else:
|
||||
force_strategy = None
|
||||
|
||||
creds = dict(username=username or
|
||||
os.getenv('OS_AUTH_USER', os.getenv('OS_USERNAME')),
|
||||
password=password or
|
||||
os.getenv('OS_AUTH_KEY', os.getenv('OS_PASSWORD')),
|
||||
tenant=tenant or
|
||||
os.getenv('OS_AUTH_TENANT',
|
||||
os.getenv('OS_TENANT_NAME')),
|
||||
auth_url=auth_url or os.getenv('OS_AUTH_URL'),
|
||||
strategy=force_strategy or auth_strategy or
|
||||
os.getenv('OS_AUTH_STRATEGY', 'noauth'),
|
||||
region=region or os.getenv('OS_REGION_NAME'),
|
||||
)
|
||||
|
||||
if creds['strategy'] == 'keystone' and not creds['auth_url']:
|
||||
msg = ("--auth_url option or OS_AUTH_URL environment variable "
|
||||
"required when keystone authentication strategy is enabled\n")
|
||||
raise exception.ClientConfigurationError(msg)
|
||||
|
||||
use_ssl = (creds['auth_url'] is not None and
|
||||
creds['auth_url'].find('https') != -1)
|
||||
|
||||
client = (ProgressClient if not is_silent_upload else Client)
|
||||
|
||||
return client(host=host,
|
||||
port=port,
|
||||
use_ssl=use_ssl,
|
||||
auth_tok=auth_token or
|
||||
os.getenv('OS_TOKEN'),
|
||||
creds=creds,
|
||||
insecure=insecure)
|
||||
|
@ -211,7 +211,8 @@ class BaseClient(object):
|
||||
|
||||
def __init__(self, host, port=None, use_ssl=False, auth_tok=None,
|
||||
creds=None, doc_root=None, key_file=None,
|
||||
cert_file=None, ca_file=None, insecure=False):
|
||||
cert_file=None, ca_file=None, insecure=False,
|
||||
configure_via_auth=True):
|
||||
"""
|
||||
Creates a new client to some service.
|
||||
|
||||
@ -247,6 +248,7 @@ class BaseClient(object):
|
||||
self.auth_tok = auth_tok
|
||||
self.creds = creds or {}
|
||||
self.connection = None
|
||||
self.configure_via_auth = configure_via_auth
|
||||
# doc_root can be a nullstring, which is valid, and why we
|
||||
# cannot simply do doc_root or self.DEFAULT_DOC_ROOT below.
|
||||
self.doc_root = (doc_root if doc_root is not None
|
||||
@ -365,7 +367,7 @@ class BaseClient(object):
|
||||
self.auth_tok = auth_plugin.auth_token
|
||||
|
||||
management_url = auth_plugin.management_url
|
||||
if management_url:
|
||||
if management_url and self.configure_via_auth:
|
||||
self.configure_from_url(management_url)
|
||||
|
||||
@handle_unauthorized
|
||||
@ -385,7 +387,6 @@ class BaseClient(object):
|
||||
self._authenticate()
|
||||
|
||||
url = self._construct_url(action, params)
|
||||
|
||||
return self._do_request(method=method, url=url, body=body,
|
||||
headers=headers)
|
||||
|
||||
|
@ -26,6 +26,7 @@ import eventlet
|
||||
from glance.common import exception
|
||||
from glance.image_cache import ImageCache
|
||||
from glance import registry
|
||||
from glance.registry import context
|
||||
import glance.store
|
||||
import glance.store.filesystem
|
||||
import glance.store.http
|
||||
@ -45,10 +46,11 @@ class Prefetcher(object):
|
||||
glance.store.create_stores(conf)
|
||||
self.cache = ImageCache(conf)
|
||||
registry.configure_registry_client(conf)
|
||||
registry.configure_registry_admin_creds(conf)
|
||||
|
||||
def fetch_image_into_cache(self, image_id):
|
||||
ctx = registry.get_client_context(self.conf,
|
||||
is_admin=True, show_deleted=True)
|
||||
ctx = context.RequestContext(is_admin=True, show_deleted=True)
|
||||
|
||||
try:
|
||||
image_meta = registry.get_image_metadata(ctx, image_id)
|
||||
if image_meta['status'] != 'active':
|
||||
|
@ -26,6 +26,7 @@ import eventlet
|
||||
from glance.common import exception
|
||||
from glance.image_cache import ImageCache
|
||||
from glance import registry
|
||||
from glance.registry import context
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@ -37,10 +38,10 @@ class Queuer(object):
|
||||
self.conf = conf
|
||||
self.cache = ImageCache(conf)
|
||||
registry.configure_registry_client(conf)
|
||||
registry.configure_registry_admin_creds(conf)
|
||||
|
||||
def queue_image(self, image_id):
|
||||
ctx = \
|
||||
registry.get_client_context(conf, is_admin=True, show_deleted=True)
|
||||
ctx = context.RequestContext(is_admin=True, show_deleted=True)
|
||||
try:
|
||||
image_meta = registry.get_image_metadata(ctx, image_id)
|
||||
if image_meta['status'] != 'active':
|
||||
|
@ -20,6 +20,7 @@ Registry API
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
from glance.common import cfg
|
||||
from glance.common import exception
|
||||
@ -27,6 +28,7 @@ from glance.registry import client
|
||||
|
||||
logger = logging.getLogger('glance.registry')
|
||||
|
||||
_CLIENT_CREDS = None
|
||||
_CLIENT_HOST = None
|
||||
_CLIENT_PORT = None
|
||||
_CLIENT_KWARGS = {}
|
||||
@ -45,7 +47,14 @@ registry_client_opts = [
|
||||
cfg.StrOpt('registry_client_ca_file'),
|
||||
cfg.StrOpt('metadata_encryption_key'),
|
||||
]
|
||||
admin_token_opt = cfg.StrOpt('admin_token')
|
||||
registry_client_ctx_opts = [
|
||||
cfg.StrOpt('admin_user'),
|
||||
cfg.StrOpt('admin_password'),
|
||||
cfg.StrOpt('admin_tenant_name'),
|
||||
cfg.StrOpt('auth_url'),
|
||||
cfg.StrOpt('auth_strategy', default='noauth'),
|
||||
cfg.StrOpt('auth_region'),
|
||||
]
|
||||
|
||||
|
||||
def get_registry_addr(conf):
|
||||
@ -84,16 +93,33 @@ def configure_registry_client(conf):
|
||||
}
|
||||
|
||||
|
||||
def get_client_context(conf, **kwargs):
|
||||
conf.register_opt(admin_token_opt)
|
||||
from glance.common import context
|
||||
return context.RequestContext(auth_tok=conf.admin_token, **kwargs)
|
||||
def configure_registry_admin_creds(conf):
|
||||
global _CLIENT_CREDS
|
||||
conf.register_opts(registry_client_ctx_opts)
|
||||
|
||||
if conf.auth_url or os.getenv('OS_AUTH_URL'):
|
||||
strategy = 'keystone'
|
||||
else:
|
||||
strategy = conf.auth_strategy
|
||||
|
||||
_CLIENT_CREDS = {
|
||||
'user': conf.admin_user,
|
||||
'password': conf.admin_password,
|
||||
'username': conf.admin_user,
|
||||
'tenant': conf.admin_tenant_name,
|
||||
'auth_url': conf.auth_url,
|
||||
'strategy': strategy,
|
||||
'region': conf.auth_region,
|
||||
}
|
||||
|
||||
|
||||
def get_registry_client(cxt):
|
||||
global _CLIENT_KWARGS, _CLIENT_HOST, _CLIENT_PORT, _METADATA_ENCRYPTION_KEY
|
||||
global _CLIENT_CREDS, _CLIENT_KWARGS, _CLIENT_HOST, _CLIENT_PORT
|
||||
global _METADATA_ENCRYPTION_KEY
|
||||
kwargs = _CLIENT_KWARGS.copy()
|
||||
kwargs['auth_tok'] = cxt.auth_tok
|
||||
if _CLIENT_CREDS:
|
||||
kwargs['creds'] = _CLIENT_CREDS
|
||||
return client.RegistryClient(_CLIENT_HOST, _CLIENT_PORT,
|
||||
_METADATA_ENCRYPTION_KEY, **kwargs)
|
||||
|
||||
|
@ -40,7 +40,11 @@ class RegistryClient(BaseClient):
|
||||
:param metadata_encryption_key: Key used to encrypt 'location' metadata
|
||||
"""
|
||||
self.metadata_encryption_key = metadata_encryption_key
|
||||
BaseClient.__init__(self, host, port, **kwargs)
|
||||
# NOTE (dprince): by default base client overwrites host and port
|
||||
# settings when using keystone. configure_via_auth=False disables
|
||||
# this behaviour to ensure we still send requests to the Registry API
|
||||
BaseClient.__init__(self, host, port, configure_via_auth=False,
|
||||
**kwargs)
|
||||
|
||||
def decrypt_metadata(self, image_metadata):
|
||||
if (self.metadata_encryption_key is not None
|
||||
|
Loading…
Reference in New Issue
Block a user