From 20cdc46a948a85bd9b49d4b35b007a1794276afb Mon Sep 17 00:00:00 2001 From: Angus Salkeld Date: Tue, 3 Apr 2012 15:39:29 +1000 Subject: [PATCH] Add support for the Output section. Implements issue #51 To see the outputs run "heat describe " Signed-off-by: Angus Salkeld --- heat/engine/api/v1/stacks.py | 12 ++++++------ heat/engine/parser.py | 27 +++++++++++++++++++++++++++ heat/engine/resources.py | 18 ++++++++++++++---- 3 files changed, 47 insertions(+), 10 deletions(-) diff --git a/heat/engine/api/v1/stacks.py b/heat/engine/api/v1/stacks.py index 894a7d4718..d8a6dc2f84 100644 --- a/heat/engine/api/v1/stacks.py +++ b/heat/engine/api/v1/stacks.py @@ -53,8 +53,8 @@ class StacksController(object): mem['stack_name'] = s mem['created_at'] = 'now' try: - mem['template_description'] = stack_db[s]['Description'] - mem['stack_status'] = stack_db[s]['StackStatus'] + mem['template_description'] = stack_db[s].t['Description'] + mem['stack_status'] = stack_db[s].t['StackStatus'] except: mem['template_description'] = 'No description' mem['stack_status'] = 'unknown' @@ -71,13 +71,13 @@ class StacksController(object): mem['creation_at'] = 'TODO' mem['updated_at'] = 'TODO' mem['NotificationARNs'] = 'TODO' - mem['Outputs'] = [{'Description': 'TODO', 'OutputKey': 'TODO', 'OutputValue': 'TODO' }] - mem['Parameters'] = stack_db[id]['Parameters'] + mem['Outputs'] = stack_db[id].get_outputs() + mem['Parameters'] = stack_db[id].t['Parameters'] mem['StackStatusReason'] = 'TODO' mem['TimeoutInMinutes'] = 'TODO' try: - mem['TemplateDescription'] = stack_db[id]['Description'] - mem['StackStatus'] = stack_db[id]['StackStatus'] + mem['TemplateDescription'] = stack_db[id].t['Description'] + mem['StackStatus'] = stack_db[id].t['StackStatus'] except: mem['TemplateDescription'] = 'No description' mem['StackStatus'] = 'unknown' diff --git a/heat/engine/parser.py b/heat/engine/parser.py index c13b6bd0a5..6932658543 100644 --- a/heat/engine/parser.py +++ b/heat/engine/parser.py @@ -32,6 +32,11 @@ class Stack: self.maps = self.t['Mappings'] else: self.maps = {} + if self.t.has_key('Outputs'): + self.outputs = self.t['Outputs'] + else: + self.outputs = {} + self.res = {} self.doc = None self.name = stack_name @@ -107,6 +112,28 @@ class Stack: for r in self.t['Resources']: self.resources[r].stop() + def get_outputs(self): + self.resolve_static_refs(self.outputs) + self.resolve_find_in_map(self.outputs) + self.resolve_attributes(self.outputs) + self.resolve_joins(self.outputs) + + outs = [] + for o in self.outputs: + out = {} + if self.outputs[o].has_key('Description'): + out['Description'] = self.outputs[o]['Description'] + else: + out['Description'] = 'No description given' + out['OutputKey'] = o + if self.outputs[o].has_key('Value'): + out['OutputValue'] = self.outputs[o]['Value'] + else: + out['OutputValue'] = '' + outs.append(out) + + return outs + def calulate_dependencies(self, s, r): if isinstance(s, dict): for i in s: diff --git a/heat/engine/resources.py b/heat/engine/resources.py index 87ddf11d77..a4649d8620 100644 --- a/heat/engine/resources.py +++ b/heat/engine/resources.py @@ -244,6 +244,7 @@ class Instance(Resource): def __init__(self, name, json_snippet, stack): super(Instance, self).__init__(name, json_snippet, stack) + self.ipaddress = '0.0.0.0' if not self.t['Properties'].has_key('AvailabilityZone'): self.t['Properties']['AvailabilityZone'] = 'nova' @@ -262,14 +263,18 @@ class Instance(Resource): def FnGetAtt(self, key): - print '%s.GetAtt(%s)' % (self.name, key) + res = 'not-this-surely' if key == 'AvailabilityZone': - return unicode(self.t['Properties']['AvailabilityZone']) + res = self.t['Properties']['AvailabilityZone'] + elif key == 'PublicIp': + res = self.ipaddress else: - # TODO PrivateDnsName, PublicDnsName, PrivateIp, PublicIp - return unicode('not-this-surely') + logger.warn('%s.GetAtt(%s) is not handled' % (self.name, key)) + # TODO(asalkeld) PrivateDnsName, PublicDnsName & PrivateIp + + return unicode(res) def start(self): def _null_callback(p, n, out): @@ -341,6 +346,11 @@ class Instance(Resource): if server.status == 'ACTIVE': self.state_set(self.CREATE_COMPLETE) self.instance_id = server.id + + # just record the first ipaddress + for n in server.networks: + self.ipaddress = server.networks[n][0] + break else: self.state_set(self.CREATE_FAILED)