diff --git a/glance/api/middleware/cache.py b/glance/api/middleware/cache.py index 710d4ea900..459cad8388 100644 --- a/glance/api/middleware/cache.py +++ b/glance/api/middleware/cache.py @@ -37,7 +37,7 @@ import glance.db from glance import image_cache import glance.openstack.common.log as logging from glance import notifier -from glance import registry +import glance.registry.client.v1.api as registry LOG = logging.getLogger(__name__) diff --git a/glance/api/v1/controller.py b/glance/api/v1/controller.py index 8b74e5db9d..84343df8b6 100644 --- a/glance/api/v1/controller.py +++ b/glance/api/v1/controller.py @@ -19,7 +19,7 @@ import webob.exc from glance.common import exception import glance.openstack.common.log as logging -from glance import registry +import glance.registry.client.v1.api as registry import glance.store as store LOG = logging.getLogger(__name__) diff --git a/glance/api/v1/images.py b/glance/api/v1/images.py index f247f09465..2d47e428c9 100644 --- a/glance/api/v1/images.py +++ b/glance/api/v1/images.py @@ -43,7 +43,7 @@ from glance.common import utils from glance.common import wsgi from glance import notifier import glance.openstack.common.log as logging -from glance import registry +import glance.registry.client.v1.api as registry from glance.store import (get_from_backend, get_size_from_backend, safe_delete_from_backend, diff --git a/glance/api/v1/members.py b/glance/api/v1/members.py index c6a9cbfa2b..f7e7aaa445 100644 --- a/glance/api/v1/members.py +++ b/glance/api/v1/members.py @@ -22,7 +22,7 @@ from glance.common import exception from glance.common import utils from glance.common import wsgi import glance.openstack.common.log as logging -from glance import registry +import glance.registry.client.v1.api as registry LOG = logging.getLogger(__name__) diff --git a/glance/image_cache/prefetcher.py b/glance/image_cache/prefetcher.py index 3f48ff7cb4..50c9fe1c31 100644 --- a/glance/image_cache/prefetcher.py +++ b/glance/image_cache/prefetcher.py @@ -25,7 +25,7 @@ from glance.common import exception from glance import context from glance.image_cache import base import glance.openstack.common.log as logging -from glance import registry +import glance.registry.client.v1.api as registry import glance.store diff --git a/glance/registry/__init__.py b/glance/registry/__init__.py index 0f52b4691b..a5c8c1d787 100644 --- a/glance/registry/__init__.py +++ b/glance/registry/__init__.py @@ -19,15 +19,8 @@ Registry API """ -import os - from oslo.config import cfg -from glance.common import exception -import glance.openstack.common.log as logging -from glance.registry import client - -LOG = logging.getLogger(__name__) registry_addr_opts = [ cfg.StrOpt('registry_host', default='0.0.0.0', @@ -35,170 +28,6 @@ registry_addr_opts = [ cfg.IntOpt('registry_port', default=9191, help=_('Port the registry server is listening on.')), ] -registry_client_opts = [ - cfg.StrOpt('registry_client_protocol', default='http', - help=_('The protocol to use for communication with the ' - 'registry server. Either http or https.')), - cfg.StrOpt('registry_client_key_file', - help=_('The path to the key file to use in SSL connections ' - 'to the registry server.')), - cfg.StrOpt('registry_client_cert_file', - help=_('The path to the cert file to use in SSL connections ' - 'to the registry server.')), - cfg.StrOpt('registry_client_ca_file', - help=_('The path to the certifying authority cert file to ' - 'use in SSL connections to the registry server.')), - cfg.BoolOpt('registry_client_insecure', default=False, - help=_('When using SSL in connections to the registry server, ' - 'do not require validation via a certifying ' - 'authority.')), - cfg.IntOpt('registry_client_timeout', default=600, - help=_('The period of time, in seconds, that the API server ' - 'will wait for a registry request to complete. A ' - 'value of 0 implies no timeout.')), -] -registry_client_ctx_opts = [ - cfg.StrOpt('admin_user', secret=True, - help=_('The administrators user name.')), - cfg.StrOpt('admin_password', secret=True, - help=_('The administrators password.')), - cfg.StrOpt('admin_tenant_name', secret=True, - help=_('The tenant name of the adminstrative user.')), - cfg.StrOpt('auth_url', - help=_('The URL to the keystone service.')), - cfg.StrOpt('auth_strategy', default='noauth', - help=_('The strategy to use for authentication.')), - cfg.StrOpt('auth_region', - help=_('The region for the authentication service.')), -] CONF = cfg.CONF CONF.register_opts(registry_addr_opts) -CONF.register_opts(registry_client_opts) -CONF.register_opts(registry_client_ctx_opts) -CONF.import_opt('metadata_encryption_key', 'glance.common.config') - -_CLIENT_CREDS = None -_CLIENT_HOST = None -_CLIENT_PORT = None -_CLIENT_KWARGS = {} -# AES key used to encrypt 'location' metadata -_METADATA_ENCRYPTION_KEY = None - - -def configure_registry_client(): - """ - Sets up a registry client for use in registry lookups - """ - global _CLIENT_KWARGS, _CLIENT_HOST, _CLIENT_PORT, _METADATA_ENCRYPTION_KEY - try: - host, port = CONF.registry_host, CONF.registry_port - except cfg.ConfigFileValueError: - msg = _("Configuration option was not valid") - LOG.error(msg) - raise exception.BadRegistryConnectionConfiguration(reason=msg) - except IndexError: - msg = _("Could not find required configuration option") - LOG.error(msg) - raise exception.BadRegistryConnectionConfiguration(reason=msg) - - _CLIENT_HOST = host - _CLIENT_PORT = port - _METADATA_ENCRYPTION_KEY = CONF.metadata_encryption_key - _CLIENT_KWARGS = { - 'use_ssl': CONF.registry_client_protocol.lower() == 'https', - 'key_file': CONF.registry_client_key_file, - 'cert_file': CONF.registry_client_cert_file, - 'ca_file': CONF.registry_client_ca_file, - 'insecure': CONF.registry_client_insecure, - 'timeout': CONF.registry_client_timeout, - } - - -def configure_registry_admin_creds(): - global _CLIENT_CREDS - - 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_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) - - -def get_images_list(context, **kwargs): - c = get_registry_client(context) - return c.get_images(**kwargs) - - -def get_images_detail(context, **kwargs): - c = get_registry_client(context) - return c.get_images_detailed(**kwargs) - - -def get_image_metadata(context, image_id): - c = get_registry_client(context) - return c.get_image(image_id) - - -def add_image_metadata(context, image_meta): - LOG.debug(_("Adding image metadata...")) - c = get_registry_client(context) - return c.add_image(image_meta) - - -def update_image_metadata(context, image_id, image_meta, - purge_props=False): - LOG.debug(_("Updating image metadata for image %s..."), image_id) - c = get_registry_client(context) - return c.update_image(image_id, image_meta, purge_props) - - -def delete_image_metadata(context, image_id): - LOG.debug(_("Deleting image metadata for image %s..."), image_id) - c = get_registry_client(context) - return c.delete_image(image_id) - - -def get_image_members(context, image_id): - c = get_registry_client(context) - return c.get_image_members(image_id) - - -def get_member_images(context, member_id): - c = get_registry_client(context) - return c.get_member_images(member_id) - - -def replace_members(context, image_id, member_data): - c = get_registry_client(context) - return c.replace_members(image_id, member_data) - - -def add_member(context, image_id, member_id, can_share=None): - c = get_registry_client(context) - return c.add_member(image_id, member_id, can_share=can_share) - - -def delete_member(context, image_id, member_id): - c = get_registry_client(context) - return c.delete_member(image_id, member_id) diff --git a/glance/registry/client/__init__.py b/glance/registry/client/__init__.py new file mode 100644 index 0000000000..d5d002224b --- /dev/null +++ b/glance/registry/client/__init__.py @@ -0,0 +1,16 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 OpenStack Foundation +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. diff --git a/glance/registry/client/v1/__init__.py b/glance/registry/client/v1/__init__.py new file mode 100644 index 0000000000..d5d002224b --- /dev/null +++ b/glance/registry/client/v1/__init__.py @@ -0,0 +1,16 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 OpenStack Foundation +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. diff --git a/glance/registry/client/v1/api.py b/glance/registry/client/v1/api.py new file mode 100644 index 0000000000..ed87d69acb --- /dev/null +++ b/glance/registry/client/v1/api.py @@ -0,0 +1,197 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010-2011 OpenStack, LLC +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +""" +Registry's Client API +""" + +import os + +from oslo.config import cfg + +from glance.common import exception +import glance.openstack.common.log as logging +from glance.registry.client.v1 import client + +LOG = logging.getLogger(__name__) + +registry_client_opts = [ + cfg.StrOpt('registry_client_protocol', default='http', + help=_('The protocol to use for communication with the ' + 'registry server. Either http or https.')), + cfg.StrOpt('registry_client_key_file', + help=_('The path to the key file to use in SSL connections ' + 'to the registry server.')), + cfg.StrOpt('registry_client_cert_file', + help=_('The path to the cert file to use in SSL connections ' + 'to the registry server.')), + cfg.StrOpt('registry_client_ca_file', + help=_('The path to the certifying authority cert file to ' + 'use in SSL connections to the registry server.')), + cfg.BoolOpt('registry_client_insecure', default=False, + help=_('When using SSL in connections to the registry server, ' + 'do not require validation via a certifying ' + 'authority.')), + cfg.IntOpt('registry_client_timeout', default=600, + help=_('The period of time, in seconds, that the API server ' + 'will wait for a registry request to complete. A ' + 'value of 0 implies no timeout.')), +] +registry_client_ctx_opts = [ + cfg.StrOpt('admin_user', secret=True, + help=_('The administrators user name.')), + cfg.StrOpt('admin_password', secret=True, + help=_('The administrators password.')), + cfg.StrOpt('admin_tenant_name', secret=True, + help=_('The tenant name of the adminstrative user.')), + cfg.StrOpt('auth_url', + help=_('The URL to the keystone service.')), + cfg.StrOpt('auth_strategy', default='noauth', + help=_('The strategy to use for authentication.')), + cfg.StrOpt('auth_region', + help=_('The region for the authentication service.')), +] + +CONF = cfg.CONF +CONF.register_opts(registry_client_opts) +CONF.register_opts(registry_client_ctx_opts) +CONF.import_opt('metadata_encryption_key', 'glance.common.config') + +_CLIENT_CREDS = None +_CLIENT_HOST = None +_CLIENT_PORT = None +_CLIENT_KWARGS = {} +# AES key used to encrypt 'location' metadata +_METADATA_ENCRYPTION_KEY = None + + +def configure_registry_client(): + """ + Sets up a registry client for use in registry lookups + """ + global _CLIENT_KWARGS, _CLIENT_HOST, _CLIENT_PORT, _METADATA_ENCRYPTION_KEY + try: + host, port = CONF.registry_host, CONF.registry_port + except cfg.ConfigFileValueError: + msg = _("Configuration option was not valid") + LOG.error(msg) + raise exception.BadRegistryConnectionConfiguration(reason=msg) + except IndexError: + msg = _("Could not find required configuration option") + LOG.error(msg) + raise exception.BadRegistryConnectionConfiguration(reason=msg) + + _CLIENT_HOST = host + _CLIENT_PORT = port + _METADATA_ENCRYPTION_KEY = CONF.metadata_encryption_key + _CLIENT_KWARGS = { + 'use_ssl': CONF.registry_client_protocol.lower() == 'https', + 'key_file': CONF.registry_client_key_file, + 'cert_file': CONF.registry_client_cert_file, + 'ca_file': CONF.registry_client_ca_file, + 'insecure': CONF.registry_client_insecure, + 'timeout': CONF.registry_client_timeout, + } + + +def configure_registry_admin_creds(): + global _CLIENT_CREDS + + 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_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) + + +def get_images_list(context, **kwargs): + c = get_registry_client(context) + return c.get_images(**kwargs) + + +def get_images_detail(context, **kwargs): + c = get_registry_client(context) + return c.get_images_detailed(**kwargs) + + +def get_image_metadata(context, image_id): + c = get_registry_client(context) + return c.get_image(image_id) + + +def add_image_metadata(context, image_meta): + LOG.debug(_("Adding image metadata...")) + c = get_registry_client(context) + return c.add_image(image_meta) + + +def update_image_metadata(context, image_id, image_meta, + purge_props=False): + LOG.debug(_("Updating image metadata for image %s..."), image_id) + c = get_registry_client(context) + return c.update_image(image_id, image_meta, purge_props) + + +def delete_image_metadata(context, image_id): + LOG.debug(_("Deleting image metadata for image %s..."), image_id) + c = get_registry_client(context) + return c.delete_image(image_id) + + +def get_image_members(context, image_id): + c = get_registry_client(context) + return c.get_image_members(image_id) + + +def get_member_images(context, member_id): + c = get_registry_client(context) + return c.get_member_images(member_id) + + +def replace_members(context, image_id, member_data): + c = get_registry_client(context) + return c.replace_members(image_id, member_data) + + +def add_member(context, image_id, member_id, can_share=None): + c = get_registry_client(context) + return c.add_member(image_id, member_id, can_share=can_share) + + +def delete_member(context, image_id, member_id): + c = get_registry_client(context) + return c.delete_member(image_id, member_id) diff --git a/glance/registry/client.py b/glance/registry/client/v1/client.py similarity index 99% rename from glance/registry/client.py rename to glance/registry/client/v1/client.py index 21ef86cdee..1759df6d89 100644 --- a/glance/registry/client.py +++ b/glance/registry/client/v1/client.py @@ -1,6 +1,6 @@ # vim: tabstop=4 shiftwidth=4 softtabstop=4 -# Copyright 2010 OpenStack, LLC +# Copyright 2013 OpenStack Foundation # All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); you may diff --git a/glance/store/scrubber.py b/glance/store/scrubber.py index 97e505f1a4..2b53d87a25 100644 --- a/glance/store/scrubber.py +++ b/glance/store/scrubber.py @@ -27,7 +27,7 @@ from glance.common import exception from glance.common import utils from glance import context import glance.openstack.common.log as logging -from glance import registry +import glance.registry.client.v1.api as registry from glance import store LOG = logging.getLogger(__name__) diff --git a/glance/tests/unit/test_cache_middleware.py b/glance/tests/unit/test_cache_middleware.py index 3c4791e5d0..4239b99b24 100644 --- a/glance/tests/unit/test_cache_middleware.py +++ b/glance/tests/unit/test_cache_middleware.py @@ -20,7 +20,7 @@ import webob import glance.api.middleware.cache from glance.common import exception from glance import context -from glance import registry +import glance.registry.client.v1.api as registry class TestCacheMiddlewareURLMatching(testtools.TestCase): diff --git a/glance/tests/unit/test_clients.py b/glance/tests/unit/test_clients.py index 4bae20e6d5..8df5e19700 100644 --- a/glance/tests/unit/test_clients.py +++ b/glance/tests/unit/test_clients.py @@ -25,7 +25,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 -from glance.registry import client as rclient +from glance.registry.client.v1.api import client as rclient from glance.tests.unit import base diff --git a/glance/tests/unit/test_http_store.py b/glance/tests/unit/test_http_store.py index 43ea833f52..5b84d405cd 100644 --- a/glance/tests/unit/test_http_store.py +++ b/glance/tests/unit/test_http_store.py @@ -20,7 +20,7 @@ import stubout from glance.common import exception from glance import context from glance.db.sqlalchemy import api as db_api -from glance.registry import configure_registry_client +from glance.registry.client.v1.api import configure_registry_client from glance.store import (delete_from_backend, safe_delete_from_backend) from glance.store.http import Store, MAX_REDIRECTS