Fail to create a stack calling Fn::GetAtt on Quantum resource
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
OpenStack Heat |
Fix Released
|
Medium
|
Steve Baker |
Bug Description
I have a template creating a Quantum port and an instance using that port. If I want to access a property of the Quantum port (such as the MAC address of the port) in the UserData of the instance, the stack creation fails .
As a side note, it is not possible today to get the private IP address because Fn::GetAtt(port, 'fixed_ips') returns a list of map.
$ heat stack-create -f CrossReferencin
400 Bad Request
The server could not comply with the request since it is either malformed or otherwise incorrect.
Remote error: StackValidation
Here is a template to reproduce the bug:
{
"AWSTemplateF
"Description" : "Test Quantum resources with very simple image",
"Parameters" : {
"KeyName" : {
"Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances",
"Type" : "String"
},
"NetworkUuid" : {
"Description" : "Network UUID",
"Type" : "String"
},
"InstanceType" : {
"Description" : "WebServer EC2 instance type",
"Type" : "String",
"Default" : "m1.nano",
"
"
}
},
"Resources" : {
"port": {
"Type": "OS::Quantum:
"Properties": {
}
},
"WebServerS
"Type" : "AWS::EC2:
"Properties" : {
]
}
},
"WebServer": {
"Type": "AWS::EC2:
"DependsOn" : "port",
"Properties": {
"ImageId" : "cirros-
"KeyName" : { "Ref" : "KeyName" },
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"echo \"Running userdata script at $(date)\" > /tmp/status\n",
"echo ", { "Fn::GetAtt" : [ "port", "mac_address" ] }, "\n"
]]}}
}
}
},
"Outputs" : {
"IP" : {
"Value" : { "Fn::GetAtt" : [ "port", "mac_address" ] },
"Description" : "IP"
}
}
}
heat-engine logs:
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser Traceback (most recent call last):
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser result = res.validate()
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser res = super(Instance, self).validate()
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser return self.properties
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser self[key]
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser value = self.resolve(
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser return resolve_
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser template.
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser data = t(data)
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser return _resolve(lambda k, v: k == 'Fn::GetAtt', handle_getatt, s)
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser return dict((k, recurse(v)) for k, v in snippet.items())
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser return dict((k, recurse(v)) for k, v in snippet.items())
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser recurse = lambda s: _resolve(match, handle, s)
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser return dict((k, recurse(v)) for k, v in snippet.items())
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser return dict((k, recurse(v)) for k, v in snippet.items())
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser recurse = lambda s: _resolve(match, handle, s)
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser return [recurse(v) for v in snippet]
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser recurse = lambda s: _resolve(match, handle, s)
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser return [recurse(v) for v in snippet]
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser recurse = lambda s: _resolve(match, handle, s)
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser return handle(recurse(v))
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser return resources[
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser self.resource_
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser ret = self.function(
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser return self.get(
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser headers=headers, params=params)
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser headers=headers, params=params)
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser self._handle_
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser exception_
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser File "/opt/stack/
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser message=message)
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser QuantumClientEx
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser
2013-05-15 10:48:50.263 24245 TRACE heat.engine.parser The resource could not be found.
Changed in heat: | |
assignee: | nobody → Steve Baker (steve-stevebaker) |
status: | New → Confirmed |
importance: | Undecided → Medium |
milestone: | none → havana-1 |
Changed in heat: | |
status: | Fix Committed → Fix Released |
tags: | added: grizzly-backport-potential |
Changed in heat: | |
milestone: | havana-1 → 2013.2 |
tags: | removed: grizzly-backport-potential |
no longer affects: | heat/grizzly |
Fix proposed to branch: master /review. openstack. org/29317
Review: https:/