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)
|
gettext.install('glance', unicode=1)
|
||||||
|
|
||||||
from glance import version
|
|
||||||
from glance import client as glance_client
|
from glance import client as glance_client
|
||||||
from glance.common import exception
|
from glance.common import exception
|
||||||
from glance.common import utils
|
from glance.common import utils
|
||||||
|
from glance import version
|
||||||
|
|
||||||
|
|
||||||
SUCCESS = 0
|
SUCCESS = 0
|
||||||
@ -784,43 +784,16 @@ def get_client(options):
|
|||||||
specified by the --host and --port options
|
specified by the --host and --port options
|
||||||
supplied to the CLI
|
supplied to the CLI
|
||||||
"""
|
"""
|
||||||
|
return glance_client.get_client(host=options.host,
|
||||||
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,
|
|
||||||
port=options.port,
|
port=options.port,
|
||||||
use_ssl=use_ssl,
|
username=options.username,
|
||||||
auth_tok=options.auth_token or
|
password=options.password,
|
||||||
os.getenv('OS_TOKEN'),
|
tenant=options.tenant,
|
||||||
creds=creds,
|
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)
|
insecure=options.insecure)
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,9 +38,9 @@ if os.path.exists(os.path.join(possible_topdir, 'glance', '__init__.py')):
|
|||||||
gettext.install('glance', unicode=1)
|
gettext.install('glance', unicode=1)
|
||||||
|
|
||||||
from glance import client as glance_client
|
from glance import client as glance_client
|
||||||
from glance import version
|
|
||||||
from glance.common import exception
|
from glance.common import exception
|
||||||
from glance.common import utils
|
from glance.common import utils
|
||||||
|
from glance import version
|
||||||
|
|
||||||
|
|
||||||
SUCCESS = 0
|
SUCCESS = 0
|
||||||
@ -259,19 +259,16 @@ def get_client(options):
|
|||||||
specified by the --host and --port options
|
specified by the --host and --port options
|
||||||
supplied to the CLI
|
supplied to the CLI
|
||||||
"""
|
"""
|
||||||
creds = dict(username=os.getenv('OS_AUTH_USER'),
|
return glance_client.get_client(host=options.host,
|
||||||
password=os.getenv('OS_AUTH_KEY'),
|
port=options.port,
|
||||||
tenant=os.getenv('OS_AUTH_TENANT'),
|
username=options.username,
|
||||||
auth_url=os.getenv('OS_AUTH_URL'),
|
password=options.password,
|
||||||
strategy=os.getenv('OS_AUTH_STRATEGY', 'noauth'))
|
tenant=options.tenant,
|
||||||
|
auth_url=options.auth_url,
|
||||||
use_ssl = (options.host.find('https') != -1 or (
|
auth_strategy=options.auth_strategy,
|
||||||
creds['auth_url'] is not None and
|
auth_token=options.auth_token,
|
||||||
creds['auth_url'].find('https') != -1))
|
region=options.region,
|
||||||
|
insecure=options.insecure)
|
||||||
return glance_client.Client(host=options.host, port=options.port,
|
|
||||||
use_ssl=use_ssl, auth_tok=options.auth_token,
|
|
||||||
creds=creds)
|
|
||||||
|
|
||||||
|
|
||||||
def create_options(parser):
|
def create_options(parser):
|
||||||
@ -296,6 +293,34 @@ def create_options(parser):
|
|||||||
metavar="TOKEN", default=None,
|
metavar="TOKEN", default=None,
|
||||||
help="Authentication token to use to identify the "
|
help="Authentication token to use to identify the "
|
||||||
"client to the glance server")
|
"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",
|
parser.add_option('-f', '--force', dest="force", metavar="FORCE",
|
||||||
default=False, action="store_true",
|
default=False, action="store_true",
|
||||||
help="Prevent select actions from requesting "
|
help="Prevent select actions from requesting "
|
||||||
|
@ -36,5 +36,8 @@ registry_host = 0.0.0.0
|
|||||||
# Port the registry server is listening on
|
# Port the registry server is listening on
|
||||||
registry_port = 9191
|
registry_port = 9191
|
||||||
|
|
||||||
# Admin token to use if using Keystone
|
# Auth settings if using Keystone
|
||||||
# admin_token = 123
|
# 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
|
return transfer_info
|
||||||
|
|
||||||
Client = V1Client
|
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,
|
def __init__(self, host, port=None, use_ssl=False, auth_tok=None,
|
||||||
creds=None, doc_root=None, key_file=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.
|
Creates a new client to some service.
|
||||||
|
|
||||||
@ -247,6 +248,7 @@ class BaseClient(object):
|
|||||||
self.auth_tok = auth_tok
|
self.auth_tok = auth_tok
|
||||||
self.creds = creds or {}
|
self.creds = creds or {}
|
||||||
self.connection = None
|
self.connection = None
|
||||||
|
self.configure_via_auth = configure_via_auth
|
||||||
# doc_root can be a nullstring, which is valid, and why we
|
# doc_root can be a nullstring, which is valid, and why we
|
||||||
# cannot simply do doc_root or self.DEFAULT_DOC_ROOT below.
|
# cannot simply do doc_root or self.DEFAULT_DOC_ROOT below.
|
||||||
self.doc_root = (doc_root if doc_root is not None
|
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
|
self.auth_tok = auth_plugin.auth_token
|
||||||
|
|
||||||
management_url = auth_plugin.management_url
|
management_url = auth_plugin.management_url
|
||||||
if management_url:
|
if management_url and self.configure_via_auth:
|
||||||
self.configure_from_url(management_url)
|
self.configure_from_url(management_url)
|
||||||
|
|
||||||
@handle_unauthorized
|
@handle_unauthorized
|
||||||
@ -385,7 +387,6 @@ class BaseClient(object):
|
|||||||
self._authenticate()
|
self._authenticate()
|
||||||
|
|
||||||
url = self._construct_url(action, params)
|
url = self._construct_url(action, params)
|
||||||
|
|
||||||
return self._do_request(method=method, url=url, body=body,
|
return self._do_request(method=method, url=url, body=body,
|
||||||
headers=headers)
|
headers=headers)
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ import eventlet
|
|||||||
from glance.common import exception
|
from glance.common import exception
|
||||||
from glance.image_cache import ImageCache
|
from glance.image_cache import ImageCache
|
||||||
from glance import registry
|
from glance import registry
|
||||||
|
from glance.registry import context
|
||||||
import glance.store
|
import glance.store
|
||||||
import glance.store.filesystem
|
import glance.store.filesystem
|
||||||
import glance.store.http
|
import glance.store.http
|
||||||
@ -45,10 +46,11 @@ class Prefetcher(object):
|
|||||||
glance.store.create_stores(conf)
|
glance.store.create_stores(conf)
|
||||||
self.cache = ImageCache(conf)
|
self.cache = ImageCache(conf)
|
||||||
registry.configure_registry_client(conf)
|
registry.configure_registry_client(conf)
|
||||||
|
registry.configure_registry_admin_creds(conf)
|
||||||
|
|
||||||
def fetch_image_into_cache(self, image_id):
|
def fetch_image_into_cache(self, image_id):
|
||||||
ctx = registry.get_client_context(self.conf,
|
ctx = context.RequestContext(is_admin=True, show_deleted=True)
|
||||||
is_admin=True, show_deleted=True)
|
|
||||||
try:
|
try:
|
||||||
image_meta = registry.get_image_metadata(ctx, image_id)
|
image_meta = registry.get_image_metadata(ctx, image_id)
|
||||||
if image_meta['status'] != 'active':
|
if image_meta['status'] != 'active':
|
||||||
|
@ -26,6 +26,7 @@ import eventlet
|
|||||||
from glance.common import exception
|
from glance.common import exception
|
||||||
from glance.image_cache import ImageCache
|
from glance.image_cache import ImageCache
|
||||||
from glance import registry
|
from glance import registry
|
||||||
|
from glance.registry import context
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -37,10 +38,10 @@ class Queuer(object):
|
|||||||
self.conf = conf
|
self.conf = conf
|
||||||
self.cache = ImageCache(conf)
|
self.cache = ImageCache(conf)
|
||||||
registry.configure_registry_client(conf)
|
registry.configure_registry_client(conf)
|
||||||
|
registry.configure_registry_admin_creds(conf)
|
||||||
|
|
||||||
def queue_image(self, image_id):
|
def queue_image(self, image_id):
|
||||||
ctx = \
|
ctx = context.RequestContext(is_admin=True, show_deleted=True)
|
||||||
registry.get_client_context(conf, is_admin=True, show_deleted=True)
|
|
||||||
try:
|
try:
|
||||||
image_meta = registry.get_image_metadata(ctx, image_id)
|
image_meta = registry.get_image_metadata(ctx, image_id)
|
||||||
if image_meta['status'] != 'active':
|
if image_meta['status'] != 'active':
|
||||||
|
@ -20,6 +20,7 @@ Registry API
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
from glance.common import cfg
|
from glance.common import cfg
|
||||||
from glance.common import exception
|
from glance.common import exception
|
||||||
@ -27,6 +28,7 @@ from glance.registry import client
|
|||||||
|
|
||||||
logger = logging.getLogger('glance.registry')
|
logger = logging.getLogger('glance.registry')
|
||||||
|
|
||||||
|
_CLIENT_CREDS = None
|
||||||
_CLIENT_HOST = None
|
_CLIENT_HOST = None
|
||||||
_CLIENT_PORT = None
|
_CLIENT_PORT = None
|
||||||
_CLIENT_KWARGS = {}
|
_CLIENT_KWARGS = {}
|
||||||
@ -45,7 +47,14 @@ registry_client_opts = [
|
|||||||
cfg.StrOpt('registry_client_ca_file'),
|
cfg.StrOpt('registry_client_ca_file'),
|
||||||
cfg.StrOpt('metadata_encryption_key'),
|
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):
|
def get_registry_addr(conf):
|
||||||
@ -84,16 +93,33 @@ def configure_registry_client(conf):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_client_context(conf, **kwargs):
|
def configure_registry_admin_creds(conf):
|
||||||
conf.register_opt(admin_token_opt)
|
global _CLIENT_CREDS
|
||||||
from glance.common import context
|
conf.register_opts(registry_client_ctx_opts)
|
||||||
return context.RequestContext(auth_tok=conf.admin_token, **kwargs)
|
|
||||||
|
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):
|
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 = _CLIENT_KWARGS.copy()
|
||||||
kwargs['auth_tok'] = cxt.auth_tok
|
kwargs['auth_tok'] = cxt.auth_tok
|
||||||
|
if _CLIENT_CREDS:
|
||||||
|
kwargs['creds'] = _CLIENT_CREDS
|
||||||
return client.RegistryClient(_CLIENT_HOST, _CLIENT_PORT,
|
return client.RegistryClient(_CLIENT_HOST, _CLIENT_PORT,
|
||||||
_METADATA_ENCRYPTION_KEY, **kwargs)
|
_METADATA_ENCRYPTION_KEY, **kwargs)
|
||||||
|
|
||||||
|
@ -40,7 +40,11 @@ class RegistryClient(BaseClient):
|
|||||||
:param metadata_encryption_key: Key used to encrypt 'location' metadata
|
:param metadata_encryption_key: Key used to encrypt 'location' metadata
|
||||||
"""
|
"""
|
||||||
self.metadata_encryption_key = metadata_encryption_key
|
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):
|
def decrypt_metadata(self, image_metadata):
|
||||||
if (self.metadata_encryption_key is not None
|
if (self.metadata_encryption_key is not None
|
||||||
|
Loading…
Reference in New Issue
Block a user