Remove endpoint_type from configuration
python-swiftclient stopped supporting the temp url structure used when radosgw was set as the endpoint_type in ocata, meaning only Newton and older versions of python-swiftclient will work. Newton is deprecated, so remove the option. This breaks the deprecation cycle, but since it has been not working for so long it needs to just be dropped. Change-Id: Ibdc93b049b7e1ae34cac9e1f599786439c46a685
This commit is contained in:
parent
9e63f0e97f
commit
e9e4d8870c
@ -8,7 +8,7 @@ Overview
|
||||
========
|
||||
Ceph project is a powerful distributed storage system. It contains object store
|
||||
and provides a RADOS Gateway Swift API which is compatible with OpenStack Swift
|
||||
API. These two APIs use different formats for their temporary URLs.
|
||||
API.
|
||||
|
||||
Ironic added support for RADOS Gateway temporary URL in the Mitaka release.
|
||||
|
||||
@ -17,56 +17,56 @@ Configure Ironic and Glance with RADOS Gateway
|
||||
|
||||
#. Install Ceph storage with RADOS Gateway. See `Ceph documentation <http://docs.ceph.com/docs>`_.
|
||||
|
||||
#. Create RADOS Gateway credentials for Glance by executing the following
|
||||
commands on the RADOS Gateway admin host::
|
||||
#. Configure RADOS Gateway to use keystone for authentication. See
|
||||
`Integrating with OpenStack Keystone <http://docs.ceph.com/docs/master/radosgw/keystone/>`_
|
||||
|
||||
sudo radosgw-admin user create --uid="GLANCE_USERNAME" --display-name="User for Glance"
|
||||
#. Register RADOS Gateway endpoint in the keystone catalog, with the same
|
||||
format swift uses, as the ``object-store`` service. URL example:
|
||||
|
||||
sudo radosgw-admin subuser create --uid=GLANCE_USERNAME --subuser=GLANCE_USERNAME:swift --access=full
|
||||
``http://rados.example.com:8080/swift/v1/AUTH_$(project_id)s``.
|
||||
|
||||
sudo radosgw-admin key create --subuser=GLANCE_USERNAME:swift --key-type=swift --secret=STORE_KEY
|
||||
In the ceph configuration, make sure radosgw is configured with the
|
||||
following value::
|
||||
|
||||
sudo radosgw-admin user modify --uid=GLANCE_USERNAME --temp-url-key=TEMP_URL_KEY
|
||||
|
||||
Replace GLANCE_USERNAME with a user name for Glance access, and replace
|
||||
STORE_KEY and TEMP_URL_KEY with suitable keys.
|
||||
|
||||
Note: Do not use "--gen-secret" CLI parameter because it will cause the
|
||||
"radosgw-admin" utility to generate keys with slash symbols which do not
|
||||
work with Glance.
|
||||
rgw swift account in url = True
|
||||
|
||||
#. Configure Glance API service for RADOS Swift API as backend. Edit the
|
||||
configuration file for the Glance API service (is typically located at
|
||||
``/etc/glance/glance-api.conf``). Replace RADOS_IP and PORT with the IP/port
|
||||
of the RADOS Gateway API service::
|
||||
``/etc/glance/glance-api.conf``)::
|
||||
|
||||
[glance_store]
|
||||
|
||||
stores = file, http, swift
|
||||
default_store = swift
|
||||
swift_store_auth_version = 1
|
||||
swift_store_auth_address = http://RADOS_IP:PORT/auth/1.0
|
||||
swift_store_user = GLANCE_USERNAME:swift
|
||||
swift_store_key = STORE_KEY
|
||||
default_swift_reference=ref1
|
||||
swift_store_config_file=/etc/glance/glance-swift-creds.conf
|
||||
swift_store_container = glance
|
||||
swift_store_create_container_on_put = True
|
||||
|
||||
In the file referenced in ``swift_store_config_file`` option, add the
|
||||
following::
|
||||
|
||||
[ref1]
|
||||
user = <service project>:<service user name>
|
||||
key = <service user password>
|
||||
user_domain_id = default
|
||||
project_domain_id = default
|
||||
auth_version = 3
|
||||
auth_address = http://keystone.example.com/identity
|
||||
|
||||
Values for user and key options correspond to keystone credentials for
|
||||
RADOS Gateway service user.
|
||||
|
||||
Note: RADOS Gateway uses FastCGI protocol for interacting with HTTP server.
|
||||
Read your HTTP server documentation if you want to enable HTTPS support.
|
||||
|
||||
#. Restart Glance API service and upload all needed images.
|
||||
|
||||
#. Change Ironic configuration file on the conductor host(s) as follows::
|
||||
#. If you're using custom container name in RADOS, change Ironic configuration
|
||||
file on the conductor host(s) as follows::
|
||||
|
||||
[glance]
|
||||
|
||||
swift_container = glance
|
||||
swift_api_version = v1
|
||||
swift_endpoint_url = http://RADOS_IP:PORT
|
||||
swift_temp_url_key = TEMP_URL_KEY
|
||||
|
||||
[deploy]
|
||||
|
||||
object_store_endpoint_type = radosgw
|
||||
|
||||
#. Restart Ironic conductor service(s).
|
||||
|
@ -382,7 +382,6 @@ glance:
|
||||
swift_temp_url_duration = 3600
|
||||
swift_temp_url_expected_download_start_delay = 0
|
||||
swift_temp_url_key = ***
|
||||
temp_url_endpoint_type = swift
|
||||
timeout = None
|
||||
|
||||
ilo:
|
||||
|
@ -61,8 +61,8 @@ Configuration drive storage in an object store
|
||||
|
||||
Under normal circumstances, the configuration drive can be stored in the
|
||||
Bare Metal service when the size is less than 64KB. Optionally, if the size
|
||||
is larger than 64KB there is support to store it in swift or radosgw backed
|
||||
object store. Both swift and radosgw use swift-style APIs.
|
||||
is larger than 64KB there is support to store it in a swift endpoint. Both
|
||||
swift and radosgw use swift-style APIs.
|
||||
|
||||
The following option in ``/etc/ironic/ironic.conf`` enables swift as an object
|
||||
store backend to store config drive. This uses the Identity service to
|
||||
@ -83,7 +83,6 @@ instead. ::
|
||||
...
|
||||
|
||||
configdrive_use_object_store = True
|
||||
object_store_endpoint_type = radosgw
|
||||
|
||||
[swift]
|
||||
...
|
||||
|
@ -67,7 +67,6 @@ and Object Storage service as described below.
|
||||
|
||||
[glance]
|
||||
|
||||
temp_url_endpoint_type = swift
|
||||
swift_endpoint_url = http://openstack/swift
|
||||
swift_account = AUTH_bc39f1d9dcf9486899088007789ae643
|
||||
swift_container = glance
|
||||
|
@ -149,20 +149,6 @@ class GlanceImageService(base_image_service.BaseImageService,
|
||||
endpoint_url = re.sub('/v1/AUTH_[^/]+/?$', '', endpoint_url)
|
||||
|
||||
key = CONF.glance.swift_temp_url_key
|
||||
if CONF.deploy.object_store_endpoint_type == 'radosgw':
|
||||
chunks = urlparse.urlsplit(CONF.glance.swift_endpoint_url)
|
||||
if not chunks.path:
|
||||
endpoint_url = urlparse.urljoin(
|
||||
endpoint_url, 'swift')
|
||||
elif chunks.path != '/swift':
|
||||
raise exc.InvalidParameterValue(
|
||||
_('Swift endpoint URL should only contain scheme, '
|
||||
'hostname, optional port and optional /swift path '
|
||||
'without trailing slash; provided value is: %s')
|
||||
% endpoint_url)
|
||||
|
||||
template = '/{api_version}/{container}/{object_id}'
|
||||
else:
|
||||
account = CONF.glance.swift_account
|
||||
if not account:
|
||||
swift_session = swift.get_swift_session()
|
||||
@ -197,11 +183,6 @@ class GlanceImageService(base_image_service.BaseImageService,
|
||||
|
||||
def _validate_temp_url_config(self):
|
||||
"""Validate the required settings for a temporary URL."""
|
||||
if (not CONF.glance.swift_temp_url_key
|
||||
and CONF.deploy.object_store_endpoint_type != 'swift'):
|
||||
raise exc.MissingParameterValue(_(
|
||||
'Swift temporary URLs require a shared secret to be created. '
|
||||
'You must provide "swift_temp_url_key" as a config option.'))
|
||||
if (CONF.glance.swift_temp_url_duration
|
||||
< CONF.glance.swift_temp_url_expected_download_start_delay):
|
||||
raise exc.InvalidParameterValue(_(
|
||||
|
@ -44,17 +44,12 @@ class SwiftAPI(object):
|
||||
"""Underlying Swift connection object."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the connection with swift or radosgw
|
||||
"""Initialize the connection with swift
|
||||
|
||||
:raises: ConfigInvalid if required keystone authorization credentials
|
||||
with swift are missing.
|
||||
"""
|
||||
params = {'retries': CONF.swift.swift_max_retries}
|
||||
if CONF.deploy.object_store_endpoint_type == 'radosgw':
|
||||
params.update({'authurl': CONF.swift.auth_url,
|
||||
'user': CONF.swift.username,
|
||||
'key': CONF.swift.password})
|
||||
else:
|
||||
# NOTE(pas-ha) swiftclient still (as of 3.3.0) does not use
|
||||
# (adapter-based) SessionClient, and uses the passed in session
|
||||
# only to resolve endpoint and get a token,
|
||||
@ -69,8 +64,7 @@ class SwiftAPI(object):
|
||||
# with service auth
|
||||
params['session'] = session = get_swift_session()
|
||||
adapter = keystone.get_adapter('swift', session=session)
|
||||
params['os_options'] = {
|
||||
'object_storage_url': adapter.get_endpoint()}
|
||||
params['os_options'] = {'object_storage_url': adapter.get_endpoint()}
|
||||
# deconstruct back session-related options
|
||||
params['timeout'] = session.timeout
|
||||
if session.verify is False:
|
||||
|
@ -87,8 +87,6 @@ class BaseConductorManager(object):
|
||||
:raises: DriverLoadError if an enabled driver cannot be loaded.
|
||||
:raises: DriverNameConflict if a classic driver and a dynamic driver
|
||||
are both enabled and have the same name.
|
||||
:raises: ConfigInvalid if required config options for connection with
|
||||
radosgw are missing while storing config drive.
|
||||
"""
|
||||
if self._started:
|
||||
raise RuntimeError(_('Attempt to start an already running '
|
||||
@ -151,18 +149,6 @@ class BaseConductorManager(object):
|
||||
|
||||
self._collect_periodic_tasks(admin_context)
|
||||
|
||||
# Check for required config options if object_store_endpoint_type is
|
||||
# radosgw
|
||||
if (CONF.deploy.configdrive_use_object_store
|
||||
and CONF.deploy.object_store_endpoint_type == "radosgw"):
|
||||
if (None in (CONF.swift.auth_url, CONF.swift.username,
|
||||
CONF.swift.password)):
|
||||
msg = _("Parameters missing to make a connection with "
|
||||
"radosgw. Ensure that [swift]/auth_url, "
|
||||
"[swift]/username, and [swift]/password are all "
|
||||
"configured.")
|
||||
raise exception.ConfigInvalid(msg)
|
||||
|
||||
# clear all target_power_state with locks by this conductor
|
||||
self.dbapi.clear_node_target_power_state(self.host)
|
||||
# clear all locks held by this conductor before registering
|
||||
|
@ -3191,14 +3191,14 @@ def _get_configdrive_obj_name(node):
|
||||
def _store_configdrive(node, configdrive):
|
||||
"""Handle the storage of the config drive.
|
||||
|
||||
If configured, the config drive data are uploaded to swift or radosgw.
|
||||
If configured, the config drive data are uploaded to a swift endpoint.
|
||||
The Node's instance_info is updated to include either the temporary
|
||||
Swift URL from the upload, or if no upload, the actual config drive data.
|
||||
|
||||
:param node: an Ironic node object.
|
||||
:param configdrive: A gzipped and base64 encoded configdrive.
|
||||
:raises: SwiftOperationError if an error occur when uploading the
|
||||
config drive to swift or radosgw.
|
||||
config drive to the swift endpoint.
|
||||
:raises: ConfigInvalid if required keystone authorization credentials
|
||||
with swift are missing.
|
||||
|
||||
|
@ -79,15 +79,7 @@ opts = [
|
||||
deprecated_name='configdrive_use_swift',
|
||||
help=_('Whether to upload the config drive to object store. '
|
||||
'Set this option to True to store config drive '
|
||||
'in swift or radosgw.')),
|
||||
cfg.StrOpt('object_store_endpoint_type',
|
||||
default='swift',
|
||||
deprecated_group='glance',
|
||||
deprecated_name='temp_url_endpoint_type',
|
||||
choices=[('swift', _('use Object Storage service')),
|
||||
('radosgw', _('use RADOS object store'))],
|
||||
help=_('Type of object store endpoint type to be '
|
||||
'used as a backend')),
|
||||
'in a swift endpoint.')),
|
||||
]
|
||||
|
||||
|
||||
|
@ -68,7 +68,7 @@ opts = [
|
||||
'swift_endpoint_url',
|
||||
help=_('The "endpoint" (scheme, hostname, optional port) for '
|
||||
'the Swift URL of the form '
|
||||
'"endpoint_url/api_version/[account/]container/object_id". '
|
||||
'"endpoint_url/api_version/account/container/object_id". '
|
||||
'Do not include trailing "/". '
|
||||
'For example, use "https://swift.example.com". If using RADOS '
|
||||
'Gateway, endpoint may also contain /swift path; if it does '
|
||||
@ -79,7 +79,7 @@ opts = [
|
||||
default='v1',
|
||||
help=_('The Swift API version to create a temporary URL for. '
|
||||
'Defaults to "v1". Swift temporary URL format: '
|
||||
'"endpoint_url/api_version/[account/]container/object_id"')),
|
||||
'"endpoint_url/api_version/account/container/object_id"')),
|
||||
cfg.StrOpt(
|
||||
'swift_account',
|
||||
help=_('The account that Glance uses to communicate with '
|
||||
@ -89,7 +89,7 @@ opts = [
|
||||
'If not set, the default value is calculated based on the ID '
|
||||
'of the project used to access Swift (as set in the [swift] '
|
||||
'section). Swift temporary URL format: '
|
||||
'"endpoint_url/api_version/[account/]container/object_id"')),
|
||||
'"endpoint_url/api_version/account/container/object_id"')),
|
||||
cfg.StrOpt(
|
||||
'swift_container',
|
||||
default='glance',
|
||||
@ -97,7 +97,7 @@ opts = [
|
||||
'images in. Defaults to "glance", which is the default '
|
||||
'in glance-api.conf. '
|
||||
'Swift temporary URL format: '
|
||||
'"endpoint_url/api_version/[account/]container/object_id"')),
|
||||
'"endpoint_url/api_version/account/container/object_id"')),
|
||||
cfg.IntOpt('swift_store_multiple_containers_seed',
|
||||
default=0,
|
||||
help=_('This should match a config by the same name in the '
|
||||
|
@ -23,7 +23,6 @@ from keystoneauth1 import loading as kaloading
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
from oslo_utils import uuidutils
|
||||
from six.moves.urllib import parse as urlparse
|
||||
import testtools
|
||||
|
||||
from ironic.common import context
|
||||
@ -686,65 +685,6 @@ class TestGlanceSwiftTempURL(base.TestCase):
|
||||
self.service.swift_temp_url, image_info)
|
||||
self.assertFalse(tempurl_mock.called)
|
||||
|
||||
@mock.patch('swiftclient.utils.generate_temp_url', autospec=True)
|
||||
def test_swift_temp_url_radosgw(self, tempurl_mock):
|
||||
self.config(object_store_endpoint_type='radosgw', group='deploy')
|
||||
path = ('/v1'
|
||||
'/glance'
|
||||
'/757274c4-2856-4bd2-bb20-9a4a231e187b')
|
||||
tempurl_mock.return_value = (
|
||||
path + '?temp_url_sig=hmacsig&temp_url_expires=1400001200')
|
||||
|
||||
self.service._validate_temp_url_config = mock.Mock()
|
||||
|
||||
temp_url = self.service.swift_temp_url(image_info=self.fake_image)
|
||||
|
||||
self.assertEqual(
|
||||
(urlparse.urljoin(CONF.glance.swift_endpoint_url, 'swift')
|
||||
+ tempurl_mock.return_value),
|
||||
temp_url)
|
||||
tempurl_mock.assert_called_with(
|
||||
path=path,
|
||||
seconds=CONF.glance.swift_temp_url_duration,
|
||||
key=CONF.glance.swift_temp_url_key,
|
||||
method='GET')
|
||||
|
||||
@mock.patch('swiftclient.utils.generate_temp_url', autospec=True)
|
||||
def test_swift_temp_url_radosgw_endpoint_with_swift(self, tempurl_mock):
|
||||
self.config(swift_endpoint_url='https://swift.radosgw.com/swift',
|
||||
group='glance')
|
||||
self.config(object_store_endpoint_type='radosgw', group='deploy')
|
||||
path = ('/v1'
|
||||
'/glance'
|
||||
'/757274c4-2856-4bd2-bb20-9a4a231e187b')
|
||||
tempurl_mock.return_value = (
|
||||
path + '?temp_url_sig=hmacsig&temp_url_expires=1400001200')
|
||||
|
||||
self.service._validate_temp_url_config = mock.Mock()
|
||||
|
||||
temp_url = self.service.swift_temp_url(image_info=self.fake_image)
|
||||
|
||||
self.assertEqual(
|
||||
CONF.glance.swift_endpoint_url + tempurl_mock.return_value,
|
||||
temp_url)
|
||||
tempurl_mock.assert_called_with(
|
||||
path=path,
|
||||
seconds=CONF.glance.swift_temp_url_duration,
|
||||
key=CONF.glance.swift_temp_url_key,
|
||||
method='GET')
|
||||
|
||||
@mock.patch('swiftclient.utils.generate_temp_url', autospec=True)
|
||||
def test_swift_temp_url_radosgw_endpoint_invalid(self, tempurl_mock):
|
||||
self.config(swift_endpoint_url='https://swift.radosgw.com/eggs/',
|
||||
group='glance')
|
||||
self.config(object_store_endpoint_type='radosgw', group='deploy')
|
||||
self.service._validate_temp_url_config = mock.Mock()
|
||||
|
||||
self.assertRaises(exception.InvalidParameterValue,
|
||||
self.service.swift_temp_url,
|
||||
self.fake_image)
|
||||
self.assertFalse(tempurl_mock.called)
|
||||
|
||||
@mock.patch('swiftclient.utils.generate_temp_url', autospec=True)
|
||||
def test_swift_temp_url_multiple_containers(self, tempurl_mock):
|
||||
|
||||
@ -778,20 +718,8 @@ class TestGlanceSwiftTempURL(base.TestCase):
|
||||
def test__validate_temp_url_config(self):
|
||||
self.service._validate_temp_url_config()
|
||||
|
||||
def test__validate_temp_url_key_no_exception(self):
|
||||
def test__validate_temp_url_no_key_no_exception(self):
|
||||
self.config(swift_temp_url_key=None, group='glance')
|
||||
self.config(object_store_endpoint_type='swift', group='deploy')
|
||||
self.service._validate_temp_url_config()
|
||||
|
||||
def test__validate_temp_url_key_exception(self):
|
||||
self.config(swift_temp_url_key=None, group='glance')
|
||||
self.config(object_store_endpoint_type='radosgw', group='deploy')
|
||||
self.assertRaises(exception.MissingParameterValue,
|
||||
self.service._validate_temp_url_config)
|
||||
|
||||
def test__validate_temp_url_no_account_exception_radosgw(self):
|
||||
self.config(swift_account=None, group='glance')
|
||||
self.config(object_store_endpoint_type='radosgw', group='deploy')
|
||||
self.service._validate_temp_url_config()
|
||||
|
||||
def test__validate_temp_url_endpoint_less_than_download_delay(self):
|
||||
|
@ -57,30 +57,6 @@ class SwiftTestCase(base.TestCase):
|
||||
os_options={'object_storage_url': 'http://example.com/objects'}
|
||||
)
|
||||
|
||||
def test___init___radosgw(self, connection_mock, swift_session_mock):
|
||||
"""Check if client is properly initialized with radosgw"""
|
||||
|
||||
auth_url = 'http://1.2.3.4'
|
||||
username = 'foo'
|
||||
password = 'foo_password'
|
||||
CONF.set_override('object_store_endpoint_type', 'radosgw',
|
||||
group='deploy')
|
||||
opts = [cfg.StrOpt('auth_url'), cfg.StrOpt('username'),
|
||||
cfg.StrOpt('password')]
|
||||
CONF.register_opts(opts, group='swift')
|
||||
|
||||
CONF.set_override('auth_url', auth_url, group='swift')
|
||||
CONF.set_override('username', username, group='swift')
|
||||
CONF.set_override('password', password, group='swift')
|
||||
|
||||
swift.SwiftAPI()
|
||||
params = {'authurl': auth_url,
|
||||
'user': username,
|
||||
'key': password,
|
||||
'retries': 2}
|
||||
connection_mock.assert_called_once_with(**params)
|
||||
self.assertFalse(swift_session_mock.called)
|
||||
|
||||
@mock.patch.object(__builtin__, 'open', autospec=True)
|
||||
def test_create_object(self, open_mock, connection_mock, keystone_mock):
|
||||
swiftapi = swift.SwiftAPI()
|
||||
|
@ -262,28 +262,6 @@ class StartStopTestCase(mgr_utils.ServiceSetUpMixin, db_base.DbTestCase):
|
||||
self.service.del_host()
|
||||
self.assertTrue(wait_mock.called)
|
||||
|
||||
def test_start_fails_on_missing_config_for_configdrive(self):
|
||||
"""Check to fail conductor on missing config options"""
|
||||
|
||||
missing_parameters_error = ("Parameters missing to make a "
|
||||
"connection with radosgw")
|
||||
CONF.set_override('configdrive_use_object_store', True,
|
||||
group='deploy')
|
||||
CONF.set_override('object_store_endpoint_type', 'radosgw',
|
||||
group='deploy')
|
||||
params = {'auth_url': 'http://1.2.3.4',
|
||||
'username': 'foo', 'password': 'foo_pass'}
|
||||
CONF.register_opts((cfg.StrOpt(x) for x in params),
|
||||
group='swift')
|
||||
for key, value in params.items():
|
||||
test_params = params.copy()
|
||||
test_params[key] = None
|
||||
for test_key, test_value in test_params.items():
|
||||
CONF.set_override(key, test_value, group='swift')
|
||||
with self.assertRaisesRegex(exception.ConfigInvalid,
|
||||
missing_parameters_error):
|
||||
self._start_service()
|
||||
|
||||
def test_conductor_shutdown_flag(self):
|
||||
self._start_service()
|
||||
self.assertFalse(self.service._shutdown)
|
||||
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
The ``swift/endpoint_type`` configuration option is now removed.
|
||||
python-swiftclient 3.2.0 (Ocata) and above removed support for the native
|
||||
URL type used by radosgw. Since using a ``swift/endpoint_type`` value of
|
||||
``radosgw`` would fail anyway, it is removed. Deployers must now configure
|
||||
ceph with ``rgw swift account in url = True``. This must be set before
|
||||
upgrading to this release.
|
Loading…
Reference in New Issue
Block a user