diff options
Diffstat (limited to 'heatclient/common')
-rw-r--r-- | heatclient/common/event_utils.py | 3 | ||||
-rw-r--r-- | heatclient/common/utils.py | 72 |
2 files changed, 72 insertions, 3 deletions
diff --git a/heatclient/common/event_utils.py b/heatclient/common/event_utils.py index 6acbbd6..c0bc42e 100644 --- a/heatclient/common/event_utils.py +++ b/heatclient/common/event_utils.py @@ -179,6 +179,7 @@ def poll_for_events(hc, stack_name, action=None, poll_period=5, marker=None, msg_template = _("\n Stack %(name)s %(status)s \n") if not out: out = sys.stdout + event_log_context = utils.EventLogContext() while True: events = get_events(hc, stack_id=stack_name, nested_depth=nested_depth, event_args={'sort_dir': 'asc', @@ -190,7 +191,7 @@ def poll_for_events(hc, stack_name, action=None, poll_period=5, marker=None, no_event_polls = 0 # set marker to last event that was received. marker = getattr(events[-1], 'id', None) - events_log = utils.event_log_formatter(events) + events_log = utils.event_log_formatter(events, event_log_context) out.write(events_log) out.write('\n') diff --git a/heatclient/common/utils.py b/heatclient/common/utils.py index a36ab38..f2b20f1 100644 --- a/heatclient/common/utils.py +++ b/heatclient/common/utils.py @@ -97,16 +97,84 @@ def print_dict(d, formatters=None): print(pt.get_string(sortby='Property')) -def event_log_formatter(events): +class EventLogContext(object): + + def __init__(self): + # key is a stack id or the name of the nested stack, value is a tuple + # of the parent stack id, and the name of the resource in the parent + # stack + self.id_to_res_info = {} + + def prepend_paths(self, resource_path, stack_id): + if stack_id not in self.id_to_res_info: + return + stack_id, res_name = self.id_to_res_info.get(stack_id) + if res_name in self.id_to_res_info: + # do a double lookup to skip the ugly stack name that doesn't + # correspond to an actual resource name + n_stack_id, res_name = self.id_to_res_info.get(res_name) + resource_path.insert(0, res_name) + self.prepend_paths(resource_path, n_stack_id) + elif res_name: + resource_path.insert(0, res_name) + + def build_resource_name(self, event): + res_name = getattr(event, 'resource_name') + + # Contribute this event to self.id_to_res_info to assist with + # future calls to build_resource_name + + def get_stack_id(): + for l in getattr(event, 'links', []): + if l.get('rel') == 'stack': + if 'href' not in l: + return None + stack_link = l['href'] + return stack_link.split('/')[-1] + + stack_id = get_stack_id() + if not stack_id: + return res_name + phys_id = getattr(event, 'physical_resource_id') + status = getattr(event, 'resource_status') + + is_stack_event = stack_id == phys_id + if is_stack_event: + # this is an event for a stack + self.id_to_res_info[stack_id] = (stack_id, res_name) + elif phys_id and status == 'CREATE_IN_PROGRESS': + # this might be an event for a resource which creates a stack + self.id_to_res_info[phys_id] = (stack_id, res_name) + + # Now build this resource path based on previous calls to + # build_resource_name + resource_path = [] + if res_name and not is_stack_event: + resource_path.append(res_name) + self.prepend_paths(resource_path, stack_id) + + return '.'.join(resource_path) + + +def event_log_formatter(events, event_log_context=None): """Return the events in log format.""" event_log = [] log_format = ("%(event_time)s " "[%(rsrc_name)s]: %(rsrc_status)s %(rsrc_status_reason)s") + + # It is preferable for a context to be passed in, but there might be enough + # events in this call to build a better resource name, so create a context + # anyway + if event_log_context is None: + event_log_context = EventLogContext() + for event in events: + rsrc_name = event_log_context.build_resource_name(event) + event_time = getattr(event, 'event_time', '') log = log_format % { 'event_time': event_time.replace('T', ' '), - 'rsrc_name': getattr(event, 'resource_name', ''), + 'rsrc_name': rsrc_name, 'rsrc_status': getattr(event, 'resource_status', ''), 'rsrc_status_reason': getattr(event, 'resource_status_reason', '') } |