def test_event_log_formatter(self): event1 = {'event_time': '2015-09-28T12:12:12', 'id': '123456789', 'resource_name': 'res_name', 'resource_status': 'CREATE_IN_PROGRESS', 'resource_status_reason': 'CREATE started'} event2 = {'event_time': '2015-09-28T12:12:22', 'id': '123456789', 'resource_name': 'res_name', 'resource_status': 'CREATE_COMPLETE', 'resource_status_reason': 'CREATE completed'} events_list = [hc_res.Resource(manager=None, info=event1), hc_res.Resource(manager=None, info=event2)] expected = ('2015-09-28 12:12:12 123456789 [res_name]: ' 'CREATE_IN_PROGRESS CREATE started\n' '2015-09-28 12:12:22 123456789 [res_name]: ' 'CREATE_COMPLETE CREATE completed') self.assertEqual(expected, utils.event_log_formatter(events_list)) self.assertEqual('', utils.event_log_formatter([])) notime_event = {'id': '123', 'resource_name': 'resname', 'resource_status': 'CREATE_COMPLETE', 'resource_status_reason': 'state changed'} notime_event_list = [hc_res.Resource(manager=None, info=notime_event)] self.assertEqual(' 123 [resname]: CREATE_COMPLETE state changed', utils.event_log_formatter(notime_event_list))
def test_event_log_formatter(self): event1 = { 'event_time': '2015-09-28T12:12:12', 'id': '123456789', 'resource_name': 'res_name', 'resource_status': 'CREATE_IN_PROGRESS', 'resource_status_reason': 'CREATE started' } event2 = { 'event_time': '2015-09-28T12:12:22', 'id': '123456789', 'resource_name': 'res_name', 'resource_status': 'CREATE_COMPLETE', 'resource_status_reason': 'CREATE completed' } events_list = [ hc_res.Resource(manager=None, info=event1), hc_res.Resource(manager=None, info=event2) ] expected = ('2015-09-28 12:12:12 [res_name]: ' 'CREATE_IN_PROGRESS CREATE started\n' '2015-09-28 12:12:22 [res_name]: ' 'CREATE_COMPLETE CREATE completed') self.assertEqual(expected, utils.event_log_formatter(events_list)) self.assertEqual('', utils.event_log_formatter([]))
def _wait_for_heat_complete(self, orchestration_client, stack_id, timeout): # Wait for the stack to go to COMPLETE. timeout_t = time.time() + 60 * timeout marker = None event_log_context = heat_utils.EventLogContext() kwargs = { 'sort_dir': 'asc', 'nested_depth': '6' } while True: time.sleep(2) events = event_utils.get_events( orchestration_client, stack_id=stack_id, event_args=kwargs, marker=marker) if events: marker = getattr(events[-1], 'id', None) events_log = heat_utils.event_log_formatter( events, event_log_context) print(events_log) status = orchestration_client.stacks.get(stack_id).status if status == 'FAILED': raise Exception('Stack create failed') if status == 'COMPLETE': break if time.time() > timeout_t: msg = 'Stack creation timeout: %d minutes elapsed' % (timeout) raise Exception(msg)
def poll_for_events(hc, stack_name, action=None, poll_period=5, marker=None, out=None): """Continuously poll events and logs for performed action on stack.""" if action: stop_status = ('%s_FAILED' % action, '%s_COMPLETE' % action) stop_check = lambda a: a in stop_status else: stop_check = lambda a: a.endswith('_COMPLETE') or a.endswith('_FAILED') no_event_polls = 0 msg_template = _("\n Stack %(name)s %(status)s \n") if not out: out = sys.stdout while True: events = get_events(hc, stack_id=stack_name, event_args={ 'sort_dir': 'asc', 'marker': marker }) if len(events) == 0: no_event_polls += 1 else: 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) out.write(events_log) out.write('\n') for event in events: # check if stack event was also received if getattr(event, 'resource_name', '') == stack_name: stack_status = getattr(event, 'resource_status', '') msg = msg_template % dict(name=stack_name, status=stack_status) if stop_check(stack_status): return stack_status, msg if no_event_polls >= 2: # after 2 polls with no events, fall back to a stack get stack = hc.stacks.get(stack_name) stack_status = stack.stack_status msg = msg_template % dict(name=stack_name, status=stack_status) if stop_check(stack_status): return stack_status, msg # go back to event polling again no_event_polls = 0 time.sleep(poll_period)
def poll_for_events(hc, stack_name, action=None, poll_period=5, marker=None, out=None, nested_depth=0): """Continuously poll events and logs for performed action on stack.""" if action: stop_status = ('%s_FAILED' % action, '%s_COMPLETE' % action) stop_check = lambda a: a in stop_status else: stop_check = lambda a: a.endswith('_COMPLETE') or a.endswith('_FAILED') no_event_polls = 0 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', 'marker': marker}) if len(events) == 0: no_event_polls += 1 else: 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, event_log_context) out.write(events_log) out.write('\n') for event in events: # check if stack event was also received if getattr(event, 'resource_name', '') == stack_name: stack_status = getattr(event, 'resource_status', '') msg = msg_template % dict( name=stack_name, status=stack_status) if stop_check(stack_status): return stack_status, msg if no_event_polls >= 2: # after 2 polls with no events, fall back to a stack get stack = hc.stacks.get(stack_name, resolve_outputs=False) stack_status = stack.stack_status msg = msg_template % dict( name=stack_name, status=stack_status) if stop_check(stack_status): return stack_status, msg # go back to event polling again no_event_polls = 0 time.sleep(poll_period)
def wait_for_events(ws, stack_name, out=None): """Receive events over the passed websocket and wait for final status.""" msg_template = _("\n Stack %(name)s %(status)s \n") if not out: out = sys.stdout event_log_context = utils.EventLogContext() while True: data = ws.recv()['body'] event = events_mod.Event(None, data['payload'], True) # Keep compatibility with the HTTP API event.event_time = data['timestamp'] event.resource_status = '%s_%s' % (event.resource_action, event.resource_status) events_log = utils.event_log_formatter([event], event_log_context) out.write(events_log) out.write('\n') if data['payload']['resource_name'] == stack_name: stack_status = data['payload']['resource_status'] if stack_status in ('COMPLETE', 'FAILED'): msg = msg_template % dict(name=stack_name, status=event.resource_status) return '%s_%s' % (event.resource_action, stack_status), msg
def wait_for_events(ws, stack_name, out=None): """Receive events over the passed websocket and wait for final status.""" msg_template = _("\n Stack %(name)s %(status)s \n") if not out: out = sys.stdout event_log_context = utils.EventLogContext() while True: data = ws.recv()['body'] event = events_mod.Event(None, data['payload'], True) # Keep compatibility with the HTTP API event.event_time = data['timestamp'] event.resource_status = '%s_%s' % (event.resource_action, event.resource_status) events_log = utils.event_log_formatter([event], event_log_context) out.write(events_log) out.write('\n') if data['payload']['resource_name'] == stack_name: stack_status = data['payload']['resource_status'] if stack_status in ('COMPLETE', 'FAILED'): msg = msg_template % dict( name=stack_name, status=event.resource_status) return '%s_%s' % (event.resource_action, stack_status), msg
def poll_for_events(hc, stack_name, action=None, poll_period=5, marker=None, out=None, nested_depth=0): """Continuously poll events and logs for performed action on stack.""" if action: stop_status = ('%s_FAILED' % action, '%s_COMPLETE' % action) stop_check = lambda a: a in stop_status # noqa: E731 else: stop_check = lambda a: a.endswith('_COMPLETE') or a.endswith( '_FAILED') # noqa E731 no_event_polls = 0 msg_template = _("\n Stack %(name)s %(status)s \n") if not out: out = sys.stdout event_log_context = utils.EventLogContext() def is_stack_event(event): if getattr(event, 'resource_name', '') != stack_name: return False phys_id = getattr(event, 'physical_resource_id', '') links = dict( (l.get('rel'), l.get('href')) for l in getattr(event, 'links', [])) stack_id = links.get('stack', phys_id).rsplit('/', 1)[-1] return stack_id == phys_id while True: events = get_events(hc, stack_id=stack_name, nested_depth=nested_depth, event_args={ 'sort_dir': 'asc', 'marker': marker }) if len(events) == 0: no_event_polls += 1 else: 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, event_log_context) out.write(events_log) out.write('\n') for event in events: # check if stack event was also received if is_stack_event(event): stack_status = getattr(event, 'resource_status', '') msg = msg_template % dict(name=stack_name, status=stack_status) if stop_check(stack_status): return stack_status, msg if no_event_polls >= 2: # after 2 polls with no events, fall back to a stack get stack = hc.stacks.get(stack_name, resolve_outputs=False) stack_status = stack.stack_status msg = msg_template % dict(name=stack_name, status=stack_status) if stop_check(stack_status): return stack_status, msg # go back to event polling again no_event_polls = 0 time.sleep(poll_period)
def emit_list(self, column_names, data, stdout, parsed_args): stdout.write(heat_utils.event_log_formatter(data)) stdout.write('\n')
def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) client = self.app.client_manager.orchestration columns = ['id', 'resource_status', 'resource_status_reason', 'event_time', 'physical_resource_id'] kwargs = { 'resource_name': parsed_args.resource, 'filters': heat_utils.format_parameters(parsed_args.filter), 'sort_dir': 'asc' } if parsed_args.resource and parsed_args.nested_depth: msg = _('--nested-depth cannot be specified with --resource') raise exc.CommandError(msg) if parsed_args.nested_depth: columns.append('stack_name') nested_depth = parsed_args.nested_depth else: nested_depth = 0 if parsed_args.follow: if parsed_args.formatter != 'log': msg = _('--follow can only be specified with --format log') raise exc.CommandError(msg) marker = parsed_args.marker try: event_log_context = heat_utils.EventLogContext() while True: events = event_utils.get_events( client, stack_id=parsed_args.stack, event_args=kwargs, nested_depth=nested_depth, marker=marker) if events: marker = getattr(events[-1], 'id', None) events_log = heat_utils.event_log_formatter( events, event_log_context) self.app.stdout.write(events_log) self.app.stdout.write('\n') time.sleep(5) # this loop never exits except (KeyboardInterrupt, EOFError): # ctrl-c, ctrl-d return [], [] events = event_utils.get_events( client, stack_id=parsed_args.stack, event_args=kwargs, nested_depth=nested_depth, marker=parsed_args.marker, limit=parsed_args.limit) if parsed_args.sort: sorts = [] for sort in parsed_args.sort: if sort.startswith(":"): sorts.append(":".join(["event_time", sort.lstrip(":")])) else: sorts.append(sort) events = utils.sort_items(events, ','.join(sorts)) if parsed_args.formatter == 'log': return [], events if len(events): if hasattr(events[0], 'resource_name'): columns.insert(0, 'resource_name') columns.append('logical_resource_id') else: columns.insert(0, 'logical_resource_id') return ( columns, (utils.get_item_properties(s, columns) for s in events) )
def test_event_log_formatter_resource_path(self): events = [{ 'resource_name': 'nested', 'event_time': '2016-09-05T04:10:24Z', 'links': [{ 'href': 'http://192.0.2.1:8004/v1/t/stacks/' 'nested/1bed5d4d-41d6-4451-b274-c073ebee375d', 'rel': 'stack' }], 'logical_resource_id': 'nested', 'resource_status': 'CREATE_IN_PROGRESS', 'resource_status_reason': 'Stack CREATE started', 'physical_resource_id': '1bed5d4d-41d6-4451-b274-c073ebee375d', }, { 'resource_name': 'rg1', 'event_time': '2016-09-05T04:10:24Z', 'links': [{ 'href': 'http://192.0.2.1:8004/v1/t/stacks/' 'nested/1bed5d4d-41d6-4451-b274-c073ebee375d', 'rel': 'stack' }], 'logical_resource_id': 'rg1', 'resource_status': 'CREATE_IN_PROGRESS', 'resource_status_reason': 'state changed', 'physical_resource_id': 'nested-rg1-m4zxcs4pra6t', 'id': '375c49ae-cefb-4fb3-8f4d-1d5f1b9e3e5d' }, { 'resource_name': 'nested-rg1-m4zxcs4pra6t', 'event_time': '2016-09-05T04:10:24Z', 'links': [{ 'href': 'http://192.0.2.1:8004/v1/t/stacks/' 'nested-rg1-m4zxcs4pra6t/' '3400bbad-a825-4226-ac23-c607846420db', 'rel': 'stack' }], 'logical_resource_id': 'nested-rg1-m4zxcs4pra6t', 'resource_status': 'CREATE_IN_PROGRESS', 'resource_status_reason': 'Stack CREATE started', 'physical_resource_id': '3400bbad-a825-4226-ac23-c607846420db', 'id': '7e521c84-cd35-4f4c-b0de-962bd3cc40a8' }, { 'resource_name': '1', 'event_time': '2016-09-05T04:10:24Z', 'links': [{ 'href': 'http://192.0.2.1:8004/v1/t/stacks/' 'nested-rg1-m4zxcs4pra6t/' '3400bbad-a825-4226-ac23-c607846420db', 'rel': 'stack' }], 'logical_resource_id': '1', 'resource_status': 'CREATE_IN_PROGRESS', 'resource_status_reason': 'state changed', 'physical_resource_id': 'nested-rg1-m4zxcs4pra6t-1-z6sgpq54n6e7', 'id': 'c6186c16-94ef-4214-a11a-7e3cc8a17f82' }] events_list = [hc_res.Resource(manager=None, info=event) for event in events] expected = '''\ 2016-09-05 04:10:24Z [nested]: \ CREATE_IN_PROGRESS Stack CREATE started 2016-09-05 04:10:24Z [nested.rg1]: \ CREATE_IN_PROGRESS state changed 2016-09-05 04:10:24Z [nested.rg1]: \ CREATE_IN_PROGRESS Stack CREATE started 2016-09-05 04:10:24Z [nested.rg1.1]: \ CREATE_IN_PROGRESS state changed''' self.assertEqual(expected, utils.event_log_formatter(events_list))
def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) client = self.app.client_manager.orchestration columns = ['id', 'resource_status', 'resource_status_reason', 'event_time', 'physical_resource_id'] kwargs = { 'resource_name': parsed_args.resource, 'limit': parsed_args.limit, 'marker': parsed_args.marker, 'filters': heat_utils.format_parameters(parsed_args.filter), 'sort_dir': 'asc' } if parsed_args.resource and parsed_args.nested_depth: msg = _('--nested-depth cannot be specified with --resource') raise exc.CommandError(msg) if parsed_args.nested_depth: # Until the API supports recursive event listing we'll have to do # the marker/limit filtering client-side del kwargs['marker'] del kwargs['limit'] columns.append('stack_name') nested_depth = parsed_args.nested_depth else: nested_depth = 0 if parsed_args.follow: if parsed_args.formatter != 'value': msg = _('--follow can only be specified with --format value') raise exc.CommandError(msg) marker = parsed_args.marker try: while True: kwargs['marker'] = marker events = event_utils.get_events( client, stack_id=parsed_args.stack, event_args=kwargs, nested_depth=nested_depth, marker=marker) if events: marker = getattr(events[-1], 'id', None) events_log = heat_utils.event_log_formatter(events) self.app.stdout.write(events_log) self.app.stdout.write('\n') time.sleep(5) # this loop never exits except (KeyboardInterrupt, EOFError): # ctrl-c, ctrl-d return [], [] events = event_utils.get_events( client, stack_id=parsed_args.stack, event_args=kwargs, nested_depth=nested_depth, marker=parsed_args.marker, limit=parsed_args.limit) if parsed_args.sort: events = utils.sort_items(events, ','.join(parsed_args.sort)) if parsed_args.formatter == 'value': events = heat_utils.event_log_formatter(events).split('\n') return [], [e.split(' ') for e in events] if len(events): if hasattr(events[0], 'resource_name'): columns.insert(0, 'resource_name') columns.append('logical_resource_id') else: columns.insert(0, 'logical_resource_id') return ( columns, (utils.get_item_properties(s, columns) for s in events) )
def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) client = self.app.client_manager.orchestration columns = ['id', 'resource_status', 'resource_status_reason', 'event_time', 'physical_resource_id'] kwargs = { 'resource_name': parsed_args.resource, 'filters': heat_utils.format_parameters(parsed_args.filter), 'sort_dir': 'asc' } if parsed_args.resource and parsed_args.nested_depth: msg = _('--nested-depth cannot be specified with --resource') raise exc.CommandError(msg) if parsed_args.nested_depth: columns.append('stack_name') nested_depth = parsed_args.nested_depth else: nested_depth = 0 if parsed_args.sort: sorts = [] sort_keys = [] for sort in parsed_args.sort: if sort.startswith(":"): sorts.append(":".join(["event_time", sort.lstrip(":")])) else: sorts.append(sort) sort_keys.append(sort.split(":")[0]) kwargs['sort_keys'] = sort_keys if ":" in parsed_args.sort[0]: kwargs['sort_dir'] = parsed_args.sort[0].split(":")[1] if parsed_args.follow: if parsed_args.formatter != 'log': msg = _('--follow can only be specified with --format log') raise exc.CommandError(msg) marker = parsed_args.marker try: event_log_context = heat_utils.EventLogContext() while True: events = event_utils.get_events( client, stack_id=parsed_args.stack, event_args=kwargs, nested_depth=nested_depth, marker=marker) if events: marker = getattr(events[-1], 'id', None) events_log = heat_utils.event_log_formatter( events, event_log_context) self.app.stdout.write(events_log) self.app.stdout.write('\n') time.sleep(5) # this loop never exits except (KeyboardInterrupt, EOFError): # ctrl-c, ctrl-d return [], [] events = event_utils.get_events( client, stack_id=parsed_args.stack, event_args=kwargs, nested_depth=nested_depth, marker=parsed_args.marker, limit=parsed_args.limit) if parsed_args.sort: events = utils.sort_items(events, ','.join(sorts)) if parsed_args.formatter == 'log': return [], events if len(events): if hasattr(events[0], 'resource_name'): columns.insert(0, 'resource_name') columns.append('logical_resource_id') else: columns.insert(0, 'logical_resource_id') return ( columns, (utils.get_item_properties(s, columns) for s in events) )
def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) client = self.app.client_manager.orchestration columns = [ 'id', 'resource_status', 'resource_status_reason', 'event_time', 'physical_resource_id' ] kwargs = { 'resource_name': parsed_args.resource, 'limit': parsed_args.limit, 'marker': parsed_args.marker, 'filters': heat_utils.format_parameters(parsed_args.filter), 'sort_dir': 'asc' } if parsed_args.resource and parsed_args.nested_depth: msg = _('--nested-depth cannot be specified with --resource') raise exc.CommandError(msg) if parsed_args.nested_depth: # Until the API supports recursive event listing we'll have to do # the marker/limit filtering client-side del kwargs['marker'] del kwargs['limit'] columns.append('stack_name') nested_depth = parsed_args.nested_depth else: nested_depth = 0 if parsed_args.follow: if parsed_args.formatter != 'value': msg = _('--follow can only be specified with --format value') raise exc.CommandError(msg) marker = parsed_args.marker try: while True: kwargs['marker'] = marker events = event_utils.get_events(client, stack_id=parsed_args.stack, event_args=kwargs, nested_depth=nested_depth, marker=marker) if events: marker = getattr(events[-1], 'id', None) events_log = heat_utils.event_log_formatter(events) self.app.stdout.write(events_log) self.app.stdout.write('\n') time.sleep(5) # this loop never exits except (KeyboardInterrupt, EOFError): # ctrl-c, ctrl-d return [], [] events = event_utils.get_events(client, stack_id=parsed_args.stack, event_args=kwargs, nested_depth=nested_depth, marker=parsed_args.marker, limit=parsed_args.limit) if parsed_args.sort: events = utils.sort_items(events, ','.join(parsed_args.sort)) if parsed_args.formatter == 'value': events = heat_utils.event_log_formatter(events).split('\n') return [], [e.split(' ') for e in events] if len(events): if hasattr(events[0], 'resource_name'): columns.insert(0, 'resource_name') columns.append('logical_resource_id') else: columns.insert(0, 'logical_resource_id') return (columns, (utils.get_item_properties(s, columns) for s in events))