Handle errors calculating dep_attrs for nested get_attr
Ensure that in convergence we can calculate the dep_attrs of a resource, including the attributes referenced in outputs, even if: - One of the resource's attributes is referenced in an ouput; and - The attribute path itself also contains a get_attr function; and - The attribute referenced by the inner get_attr function in the output is not referenced by any resources. Since the attributes referenced only in outputs (and not in resources) are not passed to dependent resources in the NodeData, the data required to resolve the inner get_attr function is not available. Therefore getting the dep_attrs for the relevant resource from the output definition would fail. The next patch does so during the calculation of the NodeData, and any resulting exception is not caught (bug 1703043), so the stack would end up stuck IN_PROGRESS. To avoid this, ignore any errors resolving attribute path components in the course of calculating the dep_attrs of a given resource. This may mean that an attribute value required for the outputs is not stored in the database, but it can still be resolved live later. Change-Id: I2ed1e3dacd371e36656559ba92dfada05df0ceba Related-Bug: #1660831
This commit is contained in:
parent
91018c890d
commit
b902d93ade
@ -16,6 +16,7 @@ import hashlib
|
||||
import itertools
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
import six
|
||||
from six.moves.urllib import parse as urlparse
|
||||
@ -27,6 +28,9 @@ from heat.common.i18n import _
|
||||
from heat.engine import attributes
|
||||
from heat.engine import function
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
opts = [
|
||||
cfg.IntOpt('limit_iterators',
|
||||
default=200,
|
||||
@ -182,9 +186,17 @@ class GetAttThenSelect(function.Function):
|
||||
raise exception.InvalidTemplateReference(resource=resource_name,
|
||||
key=path)
|
||||
|
||||
def _attr_path(self):
|
||||
return function.resolve(self._attribute)
|
||||
|
||||
def dep_attrs(self, resource_name):
|
||||
if self._res_name() == resource_name:
|
||||
attrs = [function.resolve(self._attribute)]
|
||||
try:
|
||||
attrs = [self._attr_path()]
|
||||
except Exception as exc:
|
||||
LOG.debug("Ignoring exception calculating required attributes"
|
||||
": %s %s", type(exc).__name__, six.text_type(exc))
|
||||
attrs = []
|
||||
else:
|
||||
attrs = []
|
||||
return itertools.chain(super(GetAttThenSelect,
|
||||
@ -266,18 +278,13 @@ class GetAtt(GetAttThenSelect):
|
||||
else:
|
||||
return None
|
||||
|
||||
def dep_attrs(self, resource_name):
|
||||
if self._res_name() == resource_name:
|
||||
path = function.resolve(self._path_components)
|
||||
attr = [function.resolve(self._attribute)]
|
||||
if path:
|
||||
attrs = [tuple(attr + path)]
|
||||
else:
|
||||
attrs = attr
|
||||
def _attr_path(self):
|
||||
path = function.resolve(self._path_components)
|
||||
attr = function.resolve(self._attribute)
|
||||
if path:
|
||||
return tuple([attr] + path)
|
||||
else:
|
||||
attrs = []
|
||||
return itertools.chain(function.dep_attrs(self.args, resource_name),
|
||||
attrs)
|
||||
return attr
|
||||
|
||||
|
||||
class GetAttAllAttributes(GetAtt):
|
||||
@ -311,16 +318,10 @@ class GetAttAllAttributes(GetAtt):
|
||||
raise TypeError(_('Argument to "%s" must be a list') %
|
||||
self.fn_name)
|
||||
|
||||
def dep_attrs(self, resource_name):
|
||||
"""Check if there is no attribute_name defined, return empty chain."""
|
||||
if self._attribute is not None:
|
||||
return super(GetAttAllAttributes, self).dep_attrs(resource_name)
|
||||
elif self._res_name() == resource_name:
|
||||
attrs = [attributes.ALL_ATTRIBUTES]
|
||||
else:
|
||||
attrs = []
|
||||
return itertools.chain(function.dep_attrs(self.args,
|
||||
resource_name), attrs)
|
||||
def _attr_path(self):
|
||||
if self._attribute is None:
|
||||
return attributes.ALL_ATTRIBUTES
|
||||
return super(GetAttAllAttributes, self)._attr_path()
|
||||
|
||||
def result(self):
|
||||
if self._attribute is None:
|
||||
|
Loading…
Reference in New Issue
Block a user