Strip disabled resources from depends_on in add_resource()

When we add a resource to a template using add_resource(), strip any
references to resources that are not present in the template from
'depends_on'. This means that resources that are present and depended on
but conditionally disabled in the source template will not be depended
on in the destination template, where they're not present at all (and
thus would cause errors when the template is used).

Change-Id: I58a64cd523cc0d1da8cd39793f0c839189458d99
Closes-Bug: #1701677
Related-Bug: #1649900
This commit is contained in:
Zane Bitter 2017-06-30 12:23:15 -04:00
parent bdddeee602
commit c25034f5cd
4 changed files with 43 additions and 9 deletions

View File

@ -150,14 +150,23 @@ class CfnTemplateBase(template_common.CommonTemplate):
name = definition.name
hot_tmpl = definition.render_hot()
if self.t.get(self.RESOURCES) is None:
self.t[self.RESOURCES] = {}
cfn_tmpl = dict((self.HOT_TO_CFN_RES_ATTRS[k], v)
for k, v in hot_tmpl.items())
if len(cfn_tmpl.get(self.RES_DEPENDS_ON, [])) == 1:
cfn_tmpl[self.RES_DEPENDS_ON] = cfn_tmpl[self.RES_DEPENDS_ON][0]
dep_list = cfn_tmpl.get(self.RES_DEPENDS_ON, [])
if len(dep_list) == 1:
dep_res = cfn_tmpl[self.RES_DEPENDS_ON][0]
if dep_res in self.t[self.RESOURCES]:
cfn_tmpl[self.RES_DEPENDS_ON] = dep_res
else:
del cfn_tmpl[self.RES_DEPENDS_ON]
elif dep_list:
cfn_tmpl[self.RES_DEPENDS_ON] = [d for d in dep_list
if d in self.t[self.RESOURCES]]
if self.t.get(self.RESOURCES) is None:
self.t[self.RESOURCES] = {}
self.t[self.RESOURCES][name] = cfn_tmpl
def add_output(self, definition):

View File

@ -266,7 +266,14 @@ class HOTemplate20130523(template_common.CommonTemplate):
if self.t.get(self.RESOURCES) is None:
self.t[self.RESOURCES] = {}
self.t[self.RESOURCES][name] = definition.render_hot()
rendered = definition.render_hot()
dep_list = rendered.get(self.RES_DEPENDS_ON)
if dep_list:
rendered[self.RES_DEPENDS_ON] = [d for d in dep_list
if d in self.t[self.RESOURCES]]
self.t[self.RESOURCES][name] = rendered
def add_output(self, definition):
if self.t.get(self.OUTPUTS) is None:

View File

@ -1931,15 +1931,24 @@ conditions:
foo: bar
resource2:
type: AWS::EC2::Instance
resource3:
type: AWS::EC2::Instance
depends_on:
- resource1
- dummy
- resource2
''')
source = template.Template(hot_tpl)
empty = template.Template(copy.deepcopy(hot_tpl_empty))
stack = parser.Stack(utils.dummy_context(), 'test_stack', source)
for defn in six.itervalues(source.resource_definitions(stack)):
for rname, defn in sorted(source.resource_definitions(stack).items()):
empty.add_resource(defn)
self.assertEqual(hot_tpl['resources'], empty.t['resources'])
expected = copy.deepcopy(hot_tpl['resources'])
expected['resource1']['depends_on'] = []
expected['resource3']['depends_on'] = ['resource1', 'resource2']
self.assertEqual(expected, empty.t['resources'])
def test_add_output(self):
hot_tpl = template_format.parse('''

View File

@ -1419,15 +1419,24 @@ class TemplateTest(common.HeatTestCase):
foo: bar
resource2:
Type: AWS::EC2::Instance
resource3:
Type: AWS::EC2::Instance
DependsOn:
- resource1
- dummy
- resource2
''')
source = template.Template(cfn_tpl)
empty = template.Template(copy.deepcopy(empty_template))
stk = stack.Stack(self.ctx, 'test_stack', source)
for defn in six.itervalues(source.resource_definitions(stk)):
for rname, defn in sorted(source.resource_definitions(stk).items()):
empty.add_resource(defn)
self.assertEqual(cfn_tpl['Resources'], empty.t['Resources'])
expected = copy.deepcopy(cfn_tpl['Resources'])
del expected['resource1']['DependsOn']
expected['resource3']['DependsOn'] = ['resource1', 'resource2']
self.assertEqual(expected, empty.t['Resources'])
def test_add_output(self):
cfn_tpl = template_format.parse('''