encryption_api_url requires a version
If the value configured for encryption_api_url does not include the barbican API version, then some calls from cinder will fail. This can mean that encrypted volumes cannot be deleted. To prevent this happening raise an exception if the configured value for encryption_api_url does not include the barbican version. Change-Id: I1a4c9b9e93d7d189a3cdf1469e8bb87817473da5 Closes-Bug: #1501780
This commit is contained in:
parent
7fb767f2d6
commit
f16d13e4ca
|
@ -20,6 +20,7 @@ Key manager implementation for Barbican
|
|||
import array
|
||||
import base64
|
||||
import binascii
|
||||
import re
|
||||
|
||||
from barbicanclient import client as barbican_client
|
||||
from keystoneclient.auth import identity
|
||||
|
@ -37,6 +38,8 @@ CONF = cfg.CONF
|
|||
CONF.import_opt('encryption_auth_url', 'cinder.keymgr.key_mgr', group='keymgr')
|
||||
CONF.import_opt('encryption_api_url', 'cinder.keymgr.key_mgr', group='keymgr')
|
||||
LOG = logging.getLogger(__name__)
|
||||
URL_PATTERN = re.compile(
|
||||
"(?P<url_base>http[s]?://[^/]*)[/]?(?P<url_version>(v[0-9.]+)?).*")
|
||||
|
||||
|
||||
class BarbicanKeyManager(key_mgr.KeyManager):
|
||||
|
@ -44,10 +47,33 @@ class BarbicanKeyManager(key_mgr.KeyManager):
|
|||
|
||||
def __init__(self):
|
||||
self._base_url = CONF.keymgr.encryption_api_url
|
||||
# the barbican endpoint can't have the '/v1' on the end
|
||||
self._barbican_endpoint = self._base_url.rpartition('/')[0]
|
||||
self._parse_barbican_api_url()
|
||||
self._barbican_client = None
|
||||
|
||||
def _parse_barbican_api_url(self):
|
||||
"""Setup member variables to reference the Barbican URL.
|
||||
|
||||
The key manipulation functions in this module need to use the
|
||||
barbican URL with the version appended. But the barbicanclient
|
||||
Client() class needs the URL without the version appended.
|
||||
So set up a member variables here for each case.
|
||||
"""
|
||||
m = URL_PATTERN.search(self._base_url)
|
||||
if m is None:
|
||||
raise exception.KeyManagerError(_(
|
||||
"Invalid url: must be in the form "
|
||||
"'http[s]://<ipaddr>|<fqdn>[:port]/<version>', "
|
||||
"url specified is: %s"), self._base_url)
|
||||
url_info = dict(m.groupdict())
|
||||
if 'url_version' not in url_info or url_info['url_version'] == "":
|
||||
raise exception.KeyManagerError(_(
|
||||
"Invalid barbican api url: version is required, "
|
||||
"e.g. 'http[s]://<ipaddr>|<fqdn>[:port]/<version>' "
|
||||
"url specified is: %s") % self._base_url)
|
||||
# We will also need the barbican API URL without the '/v1'.
|
||||
# So save that now.
|
||||
self._barbican_endpoint = url_info['url_base']
|
||||
|
||||
def _get_barbican_client(self, ctxt):
|
||||
"""Creates a client to connect to the Barbican service.
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ class BarbicanKeyManagerTestCase(test_key_mgr.KeyManagerTestCase):
|
|||
self.pre_hex = "AIDxQp2++uAbKaTVDMXFYIu8PIugJGqkK0JLqkU0rhY="
|
||||
self.hex = ("0080f1429dbefae01b29a4d50cc5c5608bbc3c8ba0246aa42b424baa4"
|
||||
"534ae16")
|
||||
self.original_api_url = CONF.keymgr.encryption_api_url
|
||||
self.addCleanup(self._restore)
|
||||
|
||||
def _restore(self):
|
||||
|
@ -64,6 +65,8 @@ class BarbicanKeyManagerTestCase(test_key_mgr.KeyManagerTestCase):
|
|||
keymgr_key.SymmetricKey = self.original_key
|
||||
if hasattr(self, 'original_base64'):
|
||||
base64.b64encode = self.original_base64
|
||||
if hasattr(self, 'original_api_url'):
|
||||
CONF.keymgr.encryption_api_url = self.original_api_url
|
||||
|
||||
def _build_mock_barbican(self):
|
||||
self.mock_barbican = mock.MagicMock(name='mock_barbican')
|
||||
|
@ -271,3 +274,17 @@ class BarbicanKeyManagerTestCase(test_key_mgr.KeyManagerTestCase):
|
|||
mock_session.assert_called_once_with(auth=mock_auth)
|
||||
mock_client.assert_called_once_with(session=mock_sess,
|
||||
endpoint=mock_endpoint)
|
||||
|
||||
def test_parse_barbican_api_url(self):
|
||||
# assert that the correct format is handled correctly
|
||||
CONF.keymgr.encryption_api_url = "http://host:port/v1/"
|
||||
dummy = barbican.BarbicanKeyManager()
|
||||
self.assertEqual(dummy._barbican_endpoint, "http://host:port")
|
||||
|
||||
# assert that invalid api url formats will raise an exception
|
||||
CONF.keymgr.encryption_api_url = "http://host:port/"
|
||||
self.assertRaises(exception.KeyManagerError,
|
||||
barbican.BarbicanKeyManager)
|
||||
CONF.keymgr.encryption_api_url = "http://host:port/secrets"
|
||||
self.assertRaises(exception.KeyManagerError,
|
||||
barbican.BarbicanKeyManager)
|
||||
|
|
Loading…
Reference in New Issue