Move _RESOURCE_KEYS down to class level

This will make it possible to find resource keys without having to
reference a specific template format module.

Change-Id: I1a2b3e36ecd20100c316ba9b2ce19aabe9c9ef70
This commit is contained in:
Jason Dunsmore 2016-06-14 15:17:45 -05:00
parent d727917262
commit 68fa82cbc5
4 changed files with 74 additions and 71 deletions

View File

@ -24,15 +24,6 @@ from heat.engine import rsrc_defn
from heat.engine import template
_RESOURCE_KEYS = (
RES_TYPE, RES_PROPERTIES, RES_METADATA, RES_DEPENDS_ON,
RES_DELETION_POLICY, RES_UPDATE_POLICY, RES_DESCRIPTION,
) = (
'Type', 'Properties', 'Metadata', 'DependsOn',
'DeletionPolicy', 'UpdatePolicy', 'Description',
)
class CfnTemplate(template.Template):
"""A stack template."""
@ -52,6 +43,14 @@ class CfnTemplate(template.Template):
SECTIONS_NO_DIRECT_ACCESS = set([PARAMETERS, VERSION, ALTERNATE_VERSION])
_RESOURCE_KEYS = (
RES_TYPE, RES_PROPERTIES, RES_METADATA, RES_DEPENDS_ON,
RES_DELETION_POLICY, RES_UPDATE_POLICY, RES_DESCRIPTION,
) = (
'Type', 'Properties', 'Metadata', 'DependsOn',
'DeletionPolicy', 'UpdatePolicy', 'Description',
)
functions = {
'Fn::FindInMap': cfn_funcs.FindInMap,
'Fn::GetAZs': cfn_funcs.GetAZs,
@ -105,45 +104,45 @@ class CfnTemplate(template.Template):
def validate_resource_definitions(self, stack):
resources = self.t.get(self.RESOURCES) or {}
allowed_keys = set(_RESOURCE_KEYS)
allowed_keys = set(self._RESOURCE_KEYS)
try:
for name, snippet in resources.items():
data = self.parse(stack, snippet)
if not self.validate_resource_key_type(RES_TYPE,
if not self.validate_resource_key_type(self.RES_TYPE,
six.string_types,
'string',
allowed_keys,
name, data):
args = {'name': name, 'type_key': RES_TYPE}
args = {'name': name, 'type_key': self.RES_TYPE}
msg = _('Resource %(name)s is missing '
'"%(type_key)s"') % args
raise KeyError(msg)
self.validate_resource_key_type(
RES_PROPERTIES,
self.RES_PROPERTIES,
(collections.Mapping, function.Function),
'object', allowed_keys, name, data)
self.validate_resource_key_type(
RES_METADATA,
self.RES_METADATA,
(collections.Mapping, function.Function),
'object', allowed_keys, name, data)
self.validate_resource_key_type(
RES_DEPENDS_ON,
self.RES_DEPENDS_ON,
collections.Sequence,
'list or string', allowed_keys, name, data)
self.validate_resource_key_type(
RES_DELETION_POLICY,
self.RES_DELETION_POLICY,
(six.string_types, function.Function),
'string', allowed_keys, name, data)
self.validate_resource_key_type(
RES_UPDATE_POLICY,
self.RES_UPDATE_POLICY,
(collections.Mapping, function.Function),
'object', allowed_keys, name, data)
self.validate_resource_key_type(
RES_DESCRIPTION,
self.RES_DESCRIPTION,
six.string_types,
'string', allowed_keys, name, data)
except TypeError as ex:
@ -155,11 +154,12 @@ class CfnTemplate(template.Template):
def rsrc_defn_item(name, snippet):
data = self.parse(stack, snippet)
depends = data.get(RES_DEPENDS_ON)
depends = data.get(self.RES_DEPENDS_ON)
if isinstance(depends, six.string_types):
depends = [depends]
deletion_policy = function.resolve(data.get(RES_DELETION_POLICY))
deletion_policy = function.resolve(
data.get(self.RES_DELETION_POLICY))
if deletion_policy is not None:
if deletion_policy not in self.deletion_policies:
msg = _('Invalid deletion policy "%s"') % deletion_policy
@ -168,13 +168,13 @@ class CfnTemplate(template.Template):
deletion_policy = self.deletion_policies[deletion_policy]
kwargs = {
'resource_type': data.get(RES_TYPE),
'properties': data.get(RES_PROPERTIES),
'metadata': data.get(RES_METADATA),
'resource_type': data.get(self.RES_TYPE),
'properties': data.get(self.RES_PROPERTIES),
'metadata': data.get(self.RES_METADATA),
'depends': depends,
'deletion_policy': deletion_policy,
'update_policy': data.get(RES_UPDATE_POLICY),
'description': data.get(RES_DESCRIPTION) or ''
'update_policy': data.get(self.RES_UPDATE_POLICY),
'description': data.get(self.RES_DESCRIPTION) or ''
}
defn = rsrc_defn.ResourceDefinition(name, **kwargs)
@ -188,17 +188,17 @@ class CfnTemplate(template.Template):
name = definition.name
hot_tmpl = definition.render_hot()
HOT_TO_CFN_ATTRS = {'type': RES_TYPE,
'properties': RES_PROPERTIES,
'metadata': RES_METADATA,
'depends_on': RES_DEPENDS_ON,
'deletion_policy': RES_DELETION_POLICY,
'update_policy': RES_UPDATE_POLICY}
HOT_TO_CFN_ATTRS = {'type': self.RES_TYPE,
'properties': self.RES_PROPERTIES,
'metadata': self.RES_METADATA,
'depends_on': self.RES_DEPENDS_ON,
'deletion_policy': self.RES_DELETION_POLICY,
'update_policy': self.RES_UPDATE_POLICY}
cfn_tmpl = dict((HOT_TO_CFN_ATTRS[k], v) for k, v in hot_tmpl.items())
if len(cfn_tmpl.get(RES_DEPENDS_ON, [])) == 1:
cfn_tmpl[RES_DEPENDS_ON] = cfn_tmpl[RES_DEPENDS_ON][0]
if len(cfn_tmpl.get(self.RES_DEPENDS_ON, [])) == 1:
cfn_tmpl[self.RES_DEPENDS_ON] = cfn_tmpl[self.RES_DEPENDS_ON][0]
if self.t.get(self.RESOURCES) is None:
self.t[self.RESOURCES] = {}

View File

@ -25,15 +25,6 @@ from heat.engine import rsrc_defn
from heat.engine import template
_RESOURCE_KEYS = (
RES_TYPE, RES_PROPERTIES, RES_METADATA, RES_DEPENDS_ON,
RES_DELETION_POLICY, RES_UPDATE_POLICY, RES_DESCRIPTION,
) = (
'type', 'properties', 'metadata', 'depends_on',
'deletion_policy', 'update_policy', 'description',
)
class HOTemplate20130523(template.Template):
"""A Heat Orchestration Template format stack template."""
@ -60,14 +51,22 @@ class HOTemplate20130523(template.Template):
cfn_template.CfnTemplate.RESOURCES: RESOURCES,
cfn_template.CfnTemplate.OUTPUTS: OUTPUTS}
_RESOURCE_KEYS = (
RES_TYPE, RES_PROPERTIES, RES_METADATA, RES_DEPENDS_ON,
RES_DELETION_POLICY, RES_UPDATE_POLICY, RES_DESCRIPTION,
) = (
'type', 'properties', 'metadata', 'depends_on',
'deletion_policy', 'update_policy', 'description',
)
_RESOURCE_HOT_TO_CFN_ATTRS = {
RES_TYPE: cfn_template.RES_TYPE,
RES_PROPERTIES: cfn_template.RES_PROPERTIES,
RES_METADATA: cfn_template.RES_METADATA,
RES_DEPENDS_ON: cfn_template.RES_DEPENDS_ON,
RES_DELETION_POLICY: cfn_template.RES_DELETION_POLICY,
RES_UPDATE_POLICY: cfn_template.RES_UPDATE_POLICY,
RES_DESCRIPTION: cfn_template.RES_DESCRIPTION}
RES_TYPE: cfn_template.CfnTemplate.RES_TYPE,
RES_PROPERTIES: cfn_template.CfnTemplate.RES_PROPERTIES,
RES_METADATA: cfn_template.CfnTemplate.RES_METADATA,
RES_DEPENDS_ON: cfn_template.CfnTemplate.RES_DEPENDS_ON,
RES_DELETION_POLICY: cfn_template.CfnTemplate.RES_DELETION_POLICY,
RES_UPDATE_POLICY: cfn_template.CfnTemplate.RES_UPDATE_POLICY,
RES_DESCRIPTION: cfn_template.CfnTemplate.RES_DESCRIPTION}
_HOT_TO_CFN_ATTRS = _RESOURCE_HOT_TO_CFN_ATTRS
_HOT_TO_CFN_ATTRS.update(
@ -166,7 +165,8 @@ class HOTemplate20130523(template.Template):
def _translate_resources(self, resources):
"""Get the resources of the template translated into CFN format."""
return self._translate_section(self.RESOURCES, RES_TYPE, resources,
return self._translate_section(self.RESOURCES, self.RES_TYPE,
resources,
self._RESOURCE_HOT_TO_CFN_ATTRS)
def get_section_name(self, section):
@ -193,40 +193,40 @@ class HOTemplate20130523(template.Template):
def validate_resource_definitions(self, stack):
resources = self.t.get(self.RESOURCES) or {}
allowed_keys = set(_RESOURCE_KEYS)
allowed_keys = set(self._RESOURCE_KEYS)
try:
for name, snippet in resources.items():
data = self.parse(stack, snippet)
if not self.validate_resource_key_type(RES_TYPE,
if not self.validate_resource_key_type(self.RES_TYPE,
six.string_types,
'string',
allowed_keys,
name, data):
args = {'name': name, 'type_key': RES_TYPE}
args = {'name': name, 'type_key': self.RES_TYPE}
msg = _('Resource %(name)s is missing '
'"%(type_key)s"') % args
raise KeyError(msg)
self.validate_resource_key_type(
RES_PROPERTIES,
self.RES_PROPERTIES,
(collections.Mapping, function.Function),
'object', allowed_keys, name, data)
self.validate_resource_key_type(
RES_METADATA,
self.RES_METADATA,
(collections.Mapping, function.Function),
'object', allowed_keys, name, data)
self.validate_resource_key_type(
RES_DEPENDS_ON,
self.RES_DEPENDS_ON,
collections.Sequence,
'list or string', allowed_keys, name, data)
self.validate_resource_key_type(
RES_DELETION_POLICY,
self.RES_DELETION_POLICY,
(six.string_types, function.Function),
'string', allowed_keys, name, data)
self.validate_resource_key_type(
RES_UPDATE_POLICY,
self.RES_UPDATE_POLICY,
(collections.Mapping, function.Function),
'object', allowed_keys, name, data)
except (TypeError, ValueError) as ex:
@ -240,11 +240,12 @@ class HOTemplate20130523(template.Template):
@classmethod
def rsrc_defn_from_snippet(cls, name, data):
depends = data.get(RES_DEPENDS_ON)
depends = data.get(cls.RES_DEPENDS_ON)
if isinstance(depends, six.string_types):
depends = [depends]
deletion_policy = function.resolve(data.get(RES_DELETION_POLICY))
deletion_policy = function.resolve(
data.get(cls.RES_DELETION_POLICY))
if deletion_policy is not None:
if deletion_policy not in cls.deletion_policies:
msg = _('Invalid deletion policy "%s"') % deletion_policy
@ -252,12 +253,12 @@ class HOTemplate20130523(template.Template):
else:
deletion_policy = cls.deletion_policies[deletion_policy]
kwargs = {
'resource_type': data.get(RES_TYPE),
'properties': data.get(RES_PROPERTIES),
'metadata': data.get(RES_METADATA),
'resource_type': data.get(cls.RES_TYPE),
'properties': data.get(cls.RES_PROPERTIES),
'metadata': data.get(cls.RES_METADATA),
'depends': depends,
'deletion_policy': deletion_policy,
'update_policy': data.get(RES_UPDATE_POLICY),
'update_policy': data.get(cls.RES_UPDATE_POLICY),
'description': None
}

View File

@ -2040,8 +2040,8 @@ class Resource(object):
hot_tmpl.HOTemplate20150430.OUTPUTS: outputs,
hot_tmpl.HOTemplate20150430.RESOURCES: {
res_name: {
hot_tmpl.RES_TYPE: res_type,
hot_tmpl.RES_PROPERTIES: props}}}
hot_tmpl.HOTemplate20150430.RES_TYPE: res_type,
hot_tmpl.HOTemplate20150430.RES_PROPERTIES: props}}}
else:
tmpl_dict = {
cfn_tmpl.CfnTemplate.ALTERNATE_VERSION: '2012-12-12',
@ -2049,8 +2049,8 @@ class Resource(object):
cfn_tmpl.CfnTemplate.PARAMETERS: params,
cfn_tmpl.CfnTemplate.RESOURCES: {
res_name: {
cfn_tmpl.RES_TYPE: res_type,
cfn_tmpl.RES_PROPERTIES: props}
cfn_tmpl.CfnTemplate.RES_TYPE: res_type,
cfn_tmpl.CfnTemplate.RES_PROPERTIES: props}
},
cfn_tmpl.CfnTemplate.OUTPUTS: outputs}

View File

@ -185,12 +185,14 @@ class ResourceChain(stack_resource.StackResource):
"""
resource_def = {
template.RES_TYPE: resource_type,
template.RES_PROPERTIES: self.properties[self.RESOURCE_PROPERTIES],
template.HOTemplate20130523.RES_TYPE: resource_type,
template.HOTemplate20130523.RES_PROPERTIES: self.properties[
self.RESOURCE_PROPERTIES],
}
if depends_on is not None:
resource_def[template.RES_DEPENDS_ON] = depends_on
resource_def[
template.HOTemplate20130523.RES_DEPENDS_ON] = depends_on
return template.HOTemplate20130523.rsrc_defn_from_snippet(
resource_name, resource_def)