def format_stack(stack): ''' Return a representation of the given stack that matches the API output expectations. ''' info = { STACK_NAME: stack.name, STACK_ID: dict(stack.identifier()), STACK_CREATION_TIME: timeutils.isotime(stack.created_time), STACK_UPDATED_TIME: timeutils.isotime(stack.updated_time), STACK_NOTIFICATION_TOPICS: [], # TODO Not implemented yet STACK_PARAMETERS: stack.parameters.map(str), STACK_DESCRIPTION: stack.t[template.DESCRIPTION], STACK_TMPL_DESCRIPTION: stack.t[template.DESCRIPTION], STACK_STATUS: stack.state, STACK_STATUS_DATA: stack.state_description, STACK_CAPABILITIES: [], # TODO Not implemented yet STACK_DISABLE_ROLLBACK: True, # TODO Not implemented yet STACK_TIMEOUT: stack.timeout_mins, } # only show the outputs on a completely created or updated stack if stack.state in (stack.CREATE_COMPLETE, stack.UPDATE_COMPLETE): info[STACK_OUTPUTS] = format_stack_outputs(stack, stack.outputs) return info
def format_stack(stack, preview=False): ''' Return a representation of the given stack that matches the API output expectations. ''' updated_time = stack.updated_time and timeutils.isotime(stack.updated_time) info = { api.STACK_NAME: stack.name, api.STACK_ID: dict(stack.identifier()), api.STACK_CREATION_TIME: timeutils.isotime(stack.created_time), api.STACK_UPDATED_TIME: updated_time, api.STACK_NOTIFICATION_TOPICS: [], # TODO Not implemented yet api.STACK_PARAMETERS: stack.parameters.map(str), api.STACK_DESCRIPTION: stack.t[stack.t.DESCRIPTION], api.STACK_TMPL_DESCRIPTION: stack.t[stack.t.DESCRIPTION], api.STACK_CAPABILITIES: [], # TODO Not implemented yet api.STACK_DISABLE_ROLLBACK: stack.disable_rollback, api.STACK_TIMEOUT: stack.timeout_mins, api.STACK_OWNER: stack.username, api.STACK_PARENT: stack.owner_id, } if not preview: update_info = { api.STACK_ACTION: stack.action or '', api.STACK_STATUS: stack.status or '', api.STACK_STATUS_DATA: stack.status_reason, } info.update(update_info) # allow users to view the outputs of stacks if (stack.action != stack.DELETE and stack.status != stack.IN_PROGRESS): info[api.STACK_OUTPUTS] = format_stack_outputs(stack, stack.outputs) return info
def format_stack(stack): ''' Return a representation of the given stack that matches the API output expectations. ''' updated_time = stack.updated_time and timeutils.isotime(stack.updated_time) info = { api.STACK_NAME: stack.name, api.STACK_ID: dict(stack.identifier()), api.STACK_CREATION_TIME: timeutils.isotime(stack.created_time), api.STACK_UPDATED_TIME: updated_time, api.STACK_NOTIFICATION_TOPICS: [], # TODO Not implemented yet api.STACK_PARAMETERS: stack.parameters.map(str), api.STACK_DESCRIPTION: stack.t[stack.t.DESCRIPTION], api.STACK_TMPL_DESCRIPTION: stack.t[stack.t.DESCRIPTION], api.STACK_ACTION: stack.action or '', api.STACK_STATUS: stack.status or '', api.STACK_STATUS_DATA: stack.status_reason, api.STACK_CAPABILITIES: [], # TODO Not implemented yet api.STACK_DISABLE_ROLLBACK: stack.disable_rollback, api.STACK_TIMEOUT: stack.timeout_mins, } # only show the outputs on a completely created or updated stack if (stack.action != stack.DELETE and stack.status == stack.COMPLETE): info[api.STACK_OUTPUTS] = format_stack_outputs(stack, stack.outputs) return info
def format_stack(stack): ''' Return a representation of the given stack that matches the API output expectations. ''' info = { STACK_NAME: stack.name, STACK_ID: dict(stack.identifier()), STACK_CREATION_TIME: timeutils.isotime(stack.created_time), STACK_UPDATED_TIME: timeutils.isotime(stack.updated_time), STACK_NOTIFICATION_TOPICS: [], # TODO Not implemented yet STACK_PARAMETERS: stack.parameters.map(str), STACK_DESCRIPTION: stack.t[template.DESCRIPTION], STACK_TMPL_DESCRIPTION: stack.t[template.DESCRIPTION], STACK_STATUS: stack.state, STACK_STATUS_DATA: stack.state_description, STACK_CAPABILITIES: [], # TODO Not implemented yet STACK_DISABLE_ROLLBACK: stack.disable_rollback, STACK_TIMEOUT: stack.timeout_mins, } # only show the outputs on a completely created or updated stack if stack.state in (stack.CREATE_COMPLETE, stack.UPDATE_COMPLETE): info[STACK_OUTPUTS] = format_stack_outputs(stack, stack.outputs) return info
def format_stack(stack): ''' Return a representation of the given stack that matches the API output expectations. ''' info = { api.STACK_NAME: stack.name, api.STACK_ID: dict(stack.identifier()), api.STACK_CREATION_TIME: timeutils.isotime(stack.created_time), api.STACK_UPDATED_TIME: timeutils.isotime(stack.updated_time), api.STACK_NOTIFICATION_TOPICS: [], # TODO Not implemented yet api.STACK_PARAMETERS: stack.parameters.map(str), api.STACK_DESCRIPTION: stack.t[template.DESCRIPTION], api.STACK_TMPL_DESCRIPTION: stack.t[template.DESCRIPTION], api.STACK_ACTION: stack.action or '', api.STACK_STATUS: stack.status or '', api.STACK_STATUS_DATA: stack.status_reason, api.STACK_CAPABILITIES: [], # TODO Not implemented yet api.STACK_DISABLE_ROLLBACK: stack.disable_rollback, api.STACK_TIMEOUT: stack.timeout_mins, } # only show the outputs on a completely created or updated stack if (stack.action != stack.DELETE and stack.status == stack.COMPLETE): info[api.STACK_OUTPUTS] = format_stack_outputs(stack, stack.outputs) return info
def format_stack(stack): ''' Return a representation of the given stack that matches the API output expectations. ''' updated_time = stack.updated_time and timeutils.isotime(stack.updated_time) info = { api.STACK_NAME: stack.name, api.STACK_ID: dict(stack.identifier()), api.STACK_CREATION_TIME: timeutils.isotime(stack.created_time), api.STACK_UPDATED_TIME: updated_time, api.STACK_NOTIFICATION_TOPICS: [], # TODO Not implemented yet api.STACK_PARAMETERS: stack.parameters.map(str), api.STACK_DESCRIPTION: stack.t[stack.t.DESCRIPTION], api.STACK_TMPL_DESCRIPTION: stack.t[stack.t.DESCRIPTION], api.STACK_ACTION: stack.action or '', api.STACK_STATUS: stack.status or '', api.STACK_STATUS_DATA: stack.status_reason, api.STACK_CAPABILITIES: [], # TODO Not implemented yet api.STACK_DISABLE_ROLLBACK: stack.disable_rollback, api.STACK_TIMEOUT: stack.timeout_mins, api.STACK_OWNER: stack.username, api.STACK_PARENT: stack.owner_id, } # allow users to view the outputs of stacks if (stack.action != stack.DELETE and stack.status != stack.IN_PROGRESS): info[api.STACK_OUTPUTS] = format_stack_outputs(stack, stack.outputs) return info
def format_watch(watch): result = { WATCH_ACTIONS_ENABLED: watch.rule.get(RULE_ACTIONS_ENABLED), WATCH_ALARM_ACTIONS: watch.rule.get(RULE_ALARM_ACTIONS), WATCH_TOPIC: watch.rule.get(RULE_TOPIC), WATCH_UPDATED_TIME: timeutils.isotime(watch.updated_at), WATCH_DESCRIPTION: watch.rule.get(RULE_DESCRIPTION), WATCH_NAME: watch.name, WATCH_COMPARISON: watch.rule.get(RULE_COMPARISON), WATCH_DIMENSIONS: watch.rule.get(RULE_DIMENSIONS) or [], WATCH_PERIODS: watch.rule.get(RULE_PERIODS), WATCH_INSUFFICIENT_ACTIONS: watch.rule.get(RULE_INSUFFICIENT_ACTIONS), WATCH_METRIC_NAME: watch.rule.get(RULE_METRIC_NAME), WATCH_NAMESPACE: watch.rule.get(RULE_NAMESPACE), WATCH_OK_ACTIONS: watch.rule.get(RULE_OK_ACTIONS), WATCH_PERIOD: watch.rule.get(RULE_PERIOD), WATCH_STATE_REASON: watch.rule.get(RULE_STATE_REASON), WATCH_STATE_REASON_DATA: watch.rule.get(RULE_STATE_REASON_DATA), WATCH_STATE_UPDATED_TIME: timeutils.isotime( watch.rule.get(RULE_STATE_UPDATED_TIME)), WATCH_STATE_VALUE: watch.state, WATCH_STATISTIC: watch.rule.get(RULE_STATISTIC), WATCH_THRESHOLD: watch.rule.get(RULE_THRESHOLD), WATCH_UNIT: watch.rule.get(RULE_UNIT), WATCH_STACK_ID: watch.stack_id } return result
def format_watch(watch): result = { api.WATCH_ACTIONS_ENABLED: watch.rule.get(api.RULE_ACTIONS_ENABLED), api.WATCH_ALARM_ACTIONS: watch.rule.get(api.RULE_ALARM_ACTIONS), api.WATCH_TOPIC: watch.rule.get(api.RULE_TOPIC), api.WATCH_UPDATED_TIME: timeutils.isotime(watch.updated_at), api.WATCH_DESCRIPTION: watch.rule.get(api.RULE_DESCRIPTION), api.WATCH_NAME: watch.name, api.WATCH_COMPARISON: watch.rule.get(api.RULE_COMPARISON), api.WATCH_DIMENSIONS: watch.rule.get(api.RULE_DIMENSIONS) or [], api.WATCH_PERIODS: watch.rule.get(api.RULE_PERIODS), api.WATCH_INSUFFICIENT_ACTIONS: watch.rule.get(api.RULE_INSUFFICIENT_ACTIONS), api.WATCH_METRIC_NAME: watch.rule.get(api.RULE_METRIC_NAME), api.WATCH_NAMESPACE: watch.rule.get(api.RULE_NAMESPACE), api.WATCH_OK_ACTIONS: watch.rule.get(api.RULE_OK_ACTIONS), api.WATCH_PERIOD: watch.rule.get(api.RULE_PERIOD), api.WATCH_STATE_REASON: watch.rule.get(api.RULE_STATE_REASON), api.WATCH_STATE_REASON_DATA: watch.rule.get(api.RULE_STATE_REASON_DATA), api.WATCH_STATE_UPDATED_TIME: timeutils.isotime( watch.rule.get(api.RULE_STATE_UPDATED_TIME)), api.WATCH_STATE_VALUE: watch.state, api.WATCH_STATISTIC: watch.rule.get(api.RULE_STATISTIC), api.WATCH_THRESHOLD: watch.rule.get(api.RULE_THRESHOLD), api.WATCH_UNIT: watch.rule.get(api.RULE_UNIT), api.WATCH_STACK_ID: watch.stack_id } return result
def create_test_stack(self): test_template = {'HeatTemplateFormatVersion': '2012-12-12', 'Parameters': {'Foo': {'Type': 'String'}, 'Pass': {'Type': 'String', 'NoEcho': True}}, 'Resources': {'TestResource': {'Type': 'GenericResource', 'Properties': {'Foo': 'abc'}}}, 'Outputs': {'food': {'Value': {'Fn::GetAtt': ['TestResource', 'foo']}}}} template = parser.Template(test_template) self.ctx = utils.dummy_context() self.ctx.tenant_id = 'test_tenant' env = environment.Environment() env.load({u'parameters': {u'Foo': 'user_data', u'Pass': '******'}}) self.stack_name = utils.random_name() stack = parser.Stack(self.ctx, self.stack_name, template, env=env, disable_rollback=True) self.stack = stack stack.store() self.created_time = stack.created_time self.create_at = timeutils.isotime(self.created_time) stack.create() self.expected = {} for action in ('create', 'suspend', 'delete'): self.make_mocks(action)
def format_stack_resource(resource, detail=True): ''' Return a representation of the given resource that matches the API output expectations. ''' last_updated_time = resource.updated_time or resource.created_time res = { api.RES_UPDATED_TIME: timeutils.isotime(last_updated_time), api.RES_NAME: resource.name, api.RES_PHYSICAL_ID: resource.resource_id or '', api.RES_ACTION: resource.action, api.RES_STATUS: resource.status, api.RES_STATUS_DATA: resource.status_reason, api.RES_TYPE: resource.type(), api.RES_ID: dict(resource.identifier()), api.RES_STACK_ID: dict(resource.stack.identifier()), api.RES_STACK_NAME: resource.stack.name, api.RES_REQUIRED_BY: resource.required_by(), } if (hasattr(resource, 'nested') and callable(resource.nested) and resource.nested()): res[api.RES_NESTED_STACK_ID] = dict(resource.nested().identifier()) if detail: res[api.RES_DESCRIPTION] = resource.t.description res[api.RES_METADATA] = resource.metadata_get() return res
def format_stack_resource(resource, detail=True, with_props=False): ''' Return a representation of the given resource that matches the API output expectations. ''' last_updated_time = resource.updated_time or resource.created_time res = { api.RES_UPDATED_TIME: timeutils.isotime(last_updated_time), api.RES_NAME: resource.name, api.RES_PHYSICAL_ID: resource.resource_id or '', api.RES_ACTION: resource.action, api.RES_STATUS: resource.status, api.RES_STATUS_DATA: resource.status_reason, api.RES_TYPE: resource.type(), api.RES_ID: dict(resource.identifier()), api.RES_STACK_ID: dict(resource.stack.identifier()), api.RES_STACK_NAME: resource.stack.name, api.RES_REQUIRED_BY: resource.required_by(), } if (hasattr(resource, 'nested') and callable(resource.nested) and resource.nested()): res[api.RES_NESTED_STACK_ID] = dict(resource.nested().identifier()) if resource.stack.parent_resource: res[api.RES_PARENT_RESOURCE] = resource.stack.parent_resource.name if detail: res[api.RES_DESCRIPTION] = resource.t.description res[api.RES_METADATA] = resource.metadata_get() if with_props: res[api.RES_SCHEMA_PROPERTIES] = format_resource_properties(resource) return res
def format_stack_resource(resource, detail=True): ''' Return a representation of the given resource that matches the API output expectations. ''' last_updated_time = resource.updated_time or resource.created_time res = { api.RES_UPDATED_TIME: timeutils.isotime(last_updated_time), api.RES_NAME: resource.name, api.RES_PHYSICAL_ID: resource.resource_id or '', api.RES_METADATA: resource.metadata, api.RES_ACTION: resource.action, api.RES_STATUS: resource.status, api.RES_STATUS_DATA: resource.status_reason, api.RES_TYPE: resource.t['Type'], api.RES_ID: dict(resource.identifier()), api.RES_STACK_ID: dict(resource.stack.identifier()), api.RES_STACK_NAME: resource.stack.name, api.RES_REQUIRED_BY: resource.required_by(), } if detail: res[api.RES_DESCRIPTION] = resource.parsed_template('Description', '') res[api.RES_METADATA] = resource.metadata if getattr(resource, 'nested', None) is not None: res[api.RES_MEMBERS] = [ r.resource_id for r in resource.nested().resources.itervalues() ] return res
def format_stack_resource(resource, detail=True): ''' Return a representation of the given resource that matches the API output expectations. ''' last_updated_time = resource.updated_time or resource.created_time res = { api.RES_UPDATED_TIME: timeutils.isotime(last_updated_time), api.RES_NAME: resource.name, api.RES_PHYSICAL_ID: resource.resource_id or '', api.RES_METADATA: resource.metadata, api.RES_ACTION: resource.action, api.RES_STATUS: resource.status, api.RES_STATUS_DATA: resource.status_reason, api.RES_TYPE: resource.t['Type'], api.RES_ID: dict(resource.identifier()), api.RES_STACK_ID: dict(resource.stack.identifier()), api.RES_STACK_NAME: resource.stack.name, api.RES_REQUIRED_BY: resource.required_by(), } if detail: res[api.RES_DESCRIPTION] = resource.parsed_template('Description', '') res[api.RES_METADATA] = resource.metadata return res
def format_event(context, event): stack = parser.Stack.load(context, stack=event.stack) result = { EVENT_ID: event.id, EVENT_STACK_ID: dict(stack.identifier()), EVENT_STACK_NAME: stack.name, EVENT_TIMESTAMP: timeutils.isotime(event.created_at), EVENT_RES_NAME: event.logical_resource_id, EVENT_RES_PHYSICAL_ID: event.physical_resource_id, EVENT_RES_STATUS: event.name, EVENT_RES_STATUS_DATA: event.resource_status_reason, EVENT_RES_TYPE: event.resource_type, EVENT_RES_PROPERTIES: event.resource_properties, } return result
def format_event(context, event): stack = parser.Stack.load(context, event.stack.id) result = { EVENT_ID: event.id, EVENT_STACK_ID: dict(stack.identifier()), EVENT_STACK_NAME: stack.name, EVENT_TIMESTAMP: timeutils.isotime(event.created_at), EVENT_RES_NAME: event.logical_resource_id, EVENT_RES_PHYSICAL_ID: event.physical_resource_id, EVENT_RES_STATUS: event.name, EVENT_RES_STATUS_DATA: event.resource_status_reason, EVENT_RES_TYPE: event.resource_type, EVENT_RES_PROPERTIES: event.resource_properties, } return result
def format_event(event): stack_identifier = event.stack.identifier() result = { EVENT_ID: dict(event.identifier()), EVENT_STACK_ID: dict(stack_identifier), EVENT_STACK_NAME: stack_identifier.stack_name, EVENT_TIMESTAMP: timeutils.isotime(event.timestamp), EVENT_RES_NAME: event.resource.name, EVENT_RES_PHYSICAL_ID: event.physical_resource_id, EVENT_RES_STATUS: event.new_state, EVENT_RES_STATUS_DATA: event.reason, EVENT_RES_TYPE: event.resource.type(), EVENT_RES_PROPERTIES: event.resource_properties, } return result
def format_event(event): stack_identifier = event.stack.identifier() result = { api.EVENT_ID: dict(event.identifier()), api.EVENT_STACK_ID: dict(stack_identifier), api.EVENT_STACK_NAME: stack_identifier.stack_name, api.EVENT_TIMESTAMP: timeutils.isotime(event.timestamp), api.EVENT_RES_NAME: event.resource_name, api.EVENT_RES_PHYSICAL_ID: event.physical_resource_id, api.EVENT_RES_ACTION: event.action, api.EVENT_RES_STATUS: event.status, api.EVENT_RES_STATUS_DATA: event.reason, api.EVENT_RES_TYPE: event.resource_type, api.EVENT_RES_PROPERTIES: event.resource_properties, } return result
def create_autoscaling_stack_and_get_group(self): env = environment.Environment() env.load({u'parameters': {u'KeyName': 'foo', 'ImageId': 'cloudimage'}}) t = template_format.parse(as_template) template = parser.Template(t) self.stack_name = utils.random_name() stack = parser.Stack(self.ctx, self.stack_name, template, env=env, disable_rollback=True) stack.store() self.created_time = stack.created_time self.create_at = timeutils.isotime(self.created_time) stack.create() self.stack = stack group = stack['WebServerGroup'] self.assertEqual((group.CREATE, group.COMPLETE), group.state) return group
def format_notification_body(stack): # some other possibilities here are: # - template name # - template size # - resource count if stack.status is not None and stack.action is not None: state = '_'.join(stack.state) else: state = 'Unknown' result = { api.NOTIFY_TENANT_ID: stack.context.tenant_id, api.NOTIFY_USER_ID: stack.context.user, api.NOTIFY_STACK_ID: stack.identifier().arn(), api.NOTIFY_STACK_NAME: stack.name, api.NOTIFY_STATE: state, api.NOTIFY_STATE_REASON: stack.status_reason, api.NOTIFY_CREATE_AT: timeutils.isotime(stack.created_time), } return result
def format_stack_resource(resource): ''' Return a representation of the given resource that matches the API output expectations. ''' last_updated_time = resource.updated_time or resource.created_time res = { RES_DESCRIPTION: resource.parsed_template().get('Description', ''), RES_UPDATED_TIME: timeutils.isotime(last_updated_time), RES_NAME: resource.name, RES_PHYSICAL_ID: resource.resource_id or '', RES_METADATA: resource.metadata, RES_STATUS: resource.state, RES_STATUS_DATA: resource.state_description, RES_TYPE: resource.t['Type'], RES_STACK_ID: dict(resource.stack.identifier()), RES_STACK_NAME: resource.stack.name, } return res
def format_stack_resource(resource): ''' Return a representation of the given resource that matches the API output expectations. ''' last_updated_time = resource.updated_time or resource.created_time res = { RES_DESCRIPTION: resource.parsed_template().get('Description', ''), RES_UPDATED_TIME: timeutils.isotime(last_updated_time), RES_NAME: resource.name, RES_PHYSICAL_ID: resource.instance_id or '', RES_METADATA: resource.metadata, RES_STATUS: resource.state, RES_STATUS_DATA: resource.state_description, RES_TYPE: resource.t['Type'], RES_STACK_ID: dict(resource.stack.identifier()), RES_STACK_NAME: resource.stack.name, } return res
def format_watch_data(wd): # Demangle DB format data into something more easily used in the API # We are expecting a dict with exactly two items, Namespace and # a metric key namespace = wd.data['Namespace'] metric = [(k, v) for k, v in wd.data.items() if k != 'Namespace'] if len(metric) == 1: metric_name, metric_data = metric[0] else: logger.error("Unexpected number of keys in watch_data.data!") return result = { WATCH_DATA_ALARM: wd.watch_rule.name, WATCH_DATA_METRIC: metric_name, WATCH_DATA_TIME: timeutils.isotime(wd.created_at), WATCH_DATA_NAMESPACE: namespace, WATCH_DATA: metric_data } return result
def create_test_stack(self): test_template = { "Parameters": {"Foo": {"Type": "String"}, "Pass": {"Type": "String", "NoEcho": True}}, "Resources": {"TestResource": {"Type": "GenericResource", "Properties": {"Foo": "abc"}}}, "Outputs": {"food": {"Value": {"Fn::GetAtt": ["TestResource", "foo"]}}}, } template = parser.Template(test_template) self.ctx = utils.dummy_context() self.ctx.tenant_id = "test_tenant" env = environment.Environment() env.load({u"parameters": {u"Foo": "user_data", u"Pass": "******"}}) self.stack_name = utils.random_name() stack = parser.Stack(self.ctx, self.stack_name, template, env=env, disable_rollback=True) self.stack = stack stack.store() self.created_time = stack.created_time self.create_at = timeutils.isotime(self.created_time) stack.create() self.expected = {} for action in ("create", "suspend", "delete"): self.make_mocks(action)
def format_stack_resource(resource, detail=True): """ Return a representation of the given resource that matches the API output expectations. """ last_updated_time = resource.updated_time or resource.created_time res = { RES_UPDATED_TIME: timeutils.isotime(last_updated_time), RES_NAME: resource.name, RES_PHYSICAL_ID: resource.resource_id or "", RES_METADATA: resource.metadata, RES_STATUS: resource.state, RES_STATUS_DATA: resource.state_description, RES_TYPE: resource.t["Type"], RES_ID: dict(resource.identifier()), RES_STACK_ID: dict(resource.stack.identifier()), RES_STACK_NAME: resource.stack.name, } if detail: res[RES_DESCRIPTION] = resource.parsed_template("Description", "") res[RES_METADATA] = resource.metadata return res