Refactor selecting values from an attribute

Move the code to select particular keys/indices from an attribute value out
of the get_attr intrinsic functions and into the attributes module as a
separate function.

Change-Id: I16135159027cc52e8da74a4b5863fc8a8595d582
This commit is contained in:
Zane Bitter 2014-07-15 10:21:56 -04:00
parent ba09b20034
commit cacdb47993
2 changed files with 26 additions and 16 deletions

View File

@ -174,3 +174,27 @@ class Attributes(collections.Mapping):
def __repr__(self):
return ("Attributes for %s:\n\t" % self._resource_name +
'\n\t'.join(self._attributes.values()))
def select_from_attribute(attribute_value, path):
'''
Select an element from an attribute value.
:param attribute_value: the attribute value.
:param path: a list of path components to select from the attribute.
:returns: the selected attribute component value.
'''
def get_path_component(collection, key):
if not isinstance(collection, (collections.Mapping,
collections.Sequence)):
raise TypeError(_("Can't traverse attribute path"))
if not isinstance(key, (basestring, int)):
raise TypeError(_('Path components in attributes must be strings'))
return collection[key]
try:
return reduce(get_path_component, path, attribute_value)
except (KeyError, IndexError, TypeError):
return None

View File

@ -14,6 +14,7 @@
import collections
from heat.common import exception
from heat.engine import attributes
from heat.engine.cfn import functions as cfn_funcs
from heat.engine import function
@ -116,22 +117,7 @@ class GetAtt(cfn_funcs.GetAtt):
return None
path_components = function.resolve(self._path_components)
def get_path_component(collection, key):
if not isinstance(collection, (collections.Mapping,
collections.Sequence)):
raise TypeError(_('"%s" can\'t traverse path') % self.fn_name)
if not isinstance(key, (basestring, int)):
raise TypeError(_('Path components in "%s" '
'must be strings') % self.fn_name)
return collection[key]
try:
return reduce(get_path_component, path_components, attribute)
except (KeyError, IndexError, TypeError):
return None
return attributes.select_from_attribute(attribute, path_components)
class Replace(cfn_funcs.Replace):