Add retries to Barbican secret create
Occasionally when Deckhand is creating secrets in Barbican, Barbican encounters an error in which a subsequent attempt at creating the secret would succeed. This patch set adds logic to the Deckhand Barbican driver to retry secret creates a configurable number of times to work around this Barbican issue. Change-Id: I52293195dd708255508949723d89117ce2e32b71
This commit is contained in:
parent
84661f9159
commit
460eb7fb6c
@ -13,8 +13,10 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import ast
|
import ast
|
||||||
|
import time
|
||||||
|
|
||||||
import barbicanclient
|
import barbicanclient
|
||||||
|
from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_serialization import base64
|
from oslo_serialization import base64
|
||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
@ -25,6 +27,7 @@ from deckhand.barbican import client_wrapper
|
|||||||
from deckhand import errors
|
from deckhand import errors
|
||||||
from deckhand import types
|
from deckhand import types
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -138,15 +141,43 @@ class BarbicanDriver(object):
|
|||||||
return payload
|
return payload
|
||||||
|
|
||||||
# Store secret_ref in database for `secret_doc`.
|
# Store secret_ref in database for `secret_doc`.
|
||||||
kwargs = {
|
secret_args = {
|
||||||
'name': secret_doc['metadata']['name'],
|
'name': secret_doc['metadata']['name'],
|
||||||
'secret_type': secret_type,
|
'secret_type': secret_type,
|
||||||
'payload': payload
|
'payload': payload
|
||||||
}
|
}
|
||||||
LOG.info('Storing encrypted document data in Barbican.')
|
|
||||||
|
|
||||||
|
LOG.info('Storing encrypted data in Barbican for document [{}, {}]'
|
||||||
|
.format(secret_doc.schema, secret_doc.name))
|
||||||
|
for i in range(CONF.secret_create_attempts):
|
||||||
|
LOG.debug('Creating secret in Barbican, attempt {} of {}'
|
||||||
|
.format((i + 1), CONF.secret_create_attempts))
|
||||||
|
try:
|
||||||
|
return self._do_create_secret(secret_args)
|
||||||
|
except Exception as e:
|
||||||
|
if i == (CONF.secret_create_attempts - 1):
|
||||||
|
# This was the last attempt, re-raise any error
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
# This was not the last attempt, suppress the error and
|
||||||
|
# try again after a brief sleep
|
||||||
|
sleep_amount = (i + 1)
|
||||||
|
LOG.error('Caught an error while trying to create a '
|
||||||
|
'secret in Barbican, will try again in {} second'
|
||||||
|
.format(sleep_amount))
|
||||||
|
time.sleep(sleep_amount)
|
||||||
|
|
||||||
|
def _do_create_secret(self, secret_args):
|
||||||
|
"""Using the cache construct, and the barbican client, create a secret
|
||||||
|
|
||||||
|
:param secret_args: Dict containing the data for the secret to create
|
||||||
|
:type secret_args: dict
|
||||||
|
:returns: Secret reference returned by Barbican
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
secret_ref = cache.lookup_by_payload(self.barbicanclient, **kwargs)
|
return cache.lookup_by_payload(self.barbicanclient,
|
||||||
|
**secret_args)
|
||||||
except (barbicanclient.exceptions.HTTPAuthError,
|
except (barbicanclient.exceptions.HTTPAuthError,
|
||||||
barbicanclient.exceptions.HTTPClientError) as e:
|
barbicanclient.exceptions.HTTPClientError) as e:
|
||||||
LOG.exception(str(e))
|
LOG.exception(str(e))
|
||||||
@ -162,8 +193,6 @@ class BarbicanDriver(object):
|
|||||||
'payload type is unsupported.', e.__class__.__name__)
|
'payload type is unsupported.', e.__class__.__name__)
|
||||||
raise errors.BarbicanServerException(details=str(e))
|
raise errors.BarbicanServerException(details=str(e))
|
||||||
|
|
||||||
return secret_ref
|
|
||||||
|
|
||||||
def _base64_decode_payload(self, payload):
|
def _base64_decode_payload(self, payload):
|
||||||
# If the secret_type is 'opaque' then this implies the
|
# If the secret_type is 'opaque' then this implies the
|
||||||
# payload was encoded to base64 previously. Reverse the
|
# payload was encoded to base64 previously. Reverse the
|
||||||
|
@ -88,7 +88,10 @@ default_opts = [
|
|||||||
"production."),
|
"production."),
|
||||||
cfg.BoolOpt('development_mode', default=False,
|
cfg.BoolOpt('development_mode', default=False,
|
||||||
help="Enables development mode, which disables Keystone "
|
help="Enables development mode, which disables Keystone "
|
||||||
"authentication. Do NOT use in production.")
|
"authentication. Do NOT use in production."),
|
||||||
|
cfg.IntOpt('secret_create_attempts', default=2,
|
||||||
|
help="How many times Deckhand should attempt to create a "
|
||||||
|
"secret in Barbican before raising an exception.")
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user