def test_send(self): created_time = timeutils.utcnow() st = mock.Mock() st.state = ('x', 'f') st.status = st.state[0] st.action = st.state[1] st.name = 'fred' st.status_reason = 'this is why' st.created_time = created_time st.context = self.ctx st.id = 'hay-are-en' updated_time = timeutils.utcnow() st.updated_time = updated_time st.tags = ['tag1', 'tag2'] st.t = mock.MagicMock() st.t.__getitem__.return_value = 'for test' st.t.DESCRIPTION = 'description' notify = self.patchobject(notification, 'notify') notification.stack.send(st) notify.assert_called_once_with( self.ctx, 'stack.f.error', 'ERROR', { 'state_reason': 'this is why', 'user_id': 'test_username', 'username': '******', 'user_identity': 'test_user_id', 'stack_identity': 'hay-are-en', 'stack_name': 'fred', 'tenant_id': 'test_tenant_id', 'create_at': heat_timeutils.isotime(created_time), 'state': 'x_f', 'description': 'for test', 'tags': ['tag1', 'tag2'], 'updated_at': heat_timeutils.isotime(updated_time) })
def test_alarm(self): """Confirm we can create an alarm and trigger it.""" # create metric metric = self.metric_client.metric.create({ 'name': 'my_metric', 'archive_policy_name': 'high', }) # create the stack parameters = {'metric_id': metric['id']} stack_identifier = self.stack_create(template=self.template, parameters=parameters) measures = [{'timestamp': timeutils.isotime(datetime.datetime.now()), 'value': 100}, {'timestamp': timeutils.isotime( datetime.datetime.now() + datetime.timedelta( minutes=1)), 'value': 100}] # send measures(should cause the alarm to fire) self.metric_client.metric.add_measures(metric['id'], measures) # confirm we get a scaleup. # Note: there is little point waiting more than 60s+time to scale up. self.assertTrue(test.call_until_true( 120, 2, self.check_instance_count, stack_identifier, 2)) # cleanup metric self.metric_client.metric.delete(metric['id'])
def test_send(self): stack = self._mock_stack() notify = self.patchobject(notification, 'notify') notification.autoscaling.send(stack, adjustment='x', adjustment_type='y', capacity='5', groupname='c', message='fred', suffix='the-end') notify.assert_called_once_with( self.ctx, 'autoscaling.the-end', 'INFO', {'state_reason': 'this is why', 'user_id': 'test_username', 'username': '******', 'user_identity': 'test_user_id', 'stack_identity': 'hay-are-en', 'stack_name': 'fred', 'tenant_id': 'test_tenant_id', 'create_at': heat_timeutils.isotime(stack.created_time), 'description': 'for test', 'tags': ['tag1', 'tag2'], 'updated_at': heat_timeutils.isotime(stack.updated_time), 'state': 'x_f', 'adjustment_type': 'y', 'groupname': 'c', 'capacity': '5', 'message': 'fred', 'adjustment': 'x'})
def format_software_deployment(sd): if sd is None: return result = { rpc_api.SOFTWARE_DEPLOYMENT_ID: sd.id, rpc_api.SOFTWARE_DEPLOYMENT_SERVER_ID: sd.server_id, rpc_api.SOFTWARE_DEPLOYMENT_INPUT_VALUES: sd.input_values, rpc_api.SOFTWARE_DEPLOYMENT_OUTPUT_VALUES: sd.output_values, rpc_api.SOFTWARE_DEPLOYMENT_ACTION: sd.action, rpc_api.SOFTWARE_DEPLOYMENT_STATUS: sd.status, rpc_api.SOFTWARE_DEPLOYMENT_STATUS_REASON: sd.status_reason, rpc_api.SOFTWARE_DEPLOYMENT_CONFIG_ID: sd.config.id, rpc_api.SOFTWARE_DEPLOYMENT_CREATION_TIME: heat_timeutils.isotime(sd.created_at), } if sd.updated_at: result[rpc_api.SOFTWARE_DEPLOYMENT_UPDATED_TIME] = ( heat_timeutils.isotime(sd.updated_at)) return result
def test_send(self): created_time = timeutils.utcnow() st = mock.Mock() st.state = ('x', 'f') st.status = st.state[0] st.action = st.state[1] st.name = 'fred' st.status_reason = 'this is why' st.created_time = created_time st.context = self.ctx st.id = 'hay-are-en' updated_time = timeutils.utcnow() st.updated_time = updated_time st.tags = ['tag1', 'tag2'] st.t = mock.MagicMock() st.t.__getitem__.return_value = 'for test' st.t.DESCRIPTION = 'description' notify = self.patchobject(notification, 'notify') notification.stack.send(st) notify.assert_called_once_with( self.ctx, 'stack.f.error', 'ERROR', {'state_reason': 'this is why', 'user_id': 'test_username', 'username': '******', 'user_identity': 'test_user_id', 'stack_identity': 'hay-are-en', 'stack_name': 'fred', 'tenant_id': 'test_tenant_id', 'create_at': heat_timeutils.isotime(created_time), 'state': 'x_f', 'description': 'for test', 'tags': ['tag1', 'tag2'], 'updated_at': heat_timeutils.isotime(updated_time)})
def format_stack_db_object(stack): """Return a summary representation of the given stack. Given a stack versioned db object, return a representation of the given stack for a stack listing. """ updated_time = heat_timeutils.isotime(stack.updated_at) created_time = heat_timeutils.isotime(stack.created_at) deleted_time = heat_timeutils.isotime(stack.deleted_at) tags = None if stack.tags: tags = [t.tag for t in stack.tags] info = { rpc_api.STACK_ID: dict(stack.identifier()), rpc_api.STACK_NAME: stack.name, rpc_api.STACK_DESCRIPTION: '', rpc_api.STACK_ACTION: stack.action, rpc_api.STACK_STATUS: stack.status, rpc_api.STACK_STATUS_DATA: stack.status_reason, rpc_api.STACK_CREATION_TIME: created_time, rpc_api.STACK_UPDATED_TIME: updated_time, rpc_api.STACK_DELETION_TIME: deleted_time, rpc_api.STACK_OWNER: stack.username, rpc_api.STACK_PARENT: stack.owner_id, rpc_api.STACK_USER_PROJECT_ID: stack.stack_user_project_id, rpc_api.STACK_TAGS: tags, } return info
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' updated_at = heat_timeutils.isotime(stack.updated_time) result = { rpc_api.NOTIFY_TENANT_ID: stack.context.tenant_id, rpc_api.NOTIFY_USER_ID: stack.context.username, # deprecated: please use rpc_api.NOTIFY_USERID for user id or # rpc_api.NOTIFY_USERNAME for user name. rpc_api.NOTIFY_USERID: stack.context.user_id, rpc_api.NOTIFY_USERNAME: stack.context.username, rpc_api.NOTIFY_STACK_ID: stack.id, rpc_api.NOTIFY_STACK_NAME: stack.name, rpc_api.NOTIFY_STATE: state, rpc_api.NOTIFY_STATE_REASON: stack.status_reason, rpc_api.NOTIFY_CREATE_AT: heat_timeutils.isotime(stack.created_time), rpc_api.NOTIFY_TAGS: stack.tags, rpc_api.NOTIFY_UPDATE_AT: updated_at } if stack.t is not None: result[rpc_api.NOTIFY_DESCRIPTION] = stack.t[stack.t.DESCRIPTION] return result
def test_alarm(self): """Confirm we can create an alarm and trigger it.""" # create metric metric = self.metric_client.metric.create({ 'name': 'my_metric', 'archive_policy_name': 'high', }) # create the stack parameters = {'metric_id': metric['id']} stack_identifier = self.stack_create(template=self.template, parameters=parameters) measures = [{ 'timestamp': timeutils.isotime(datetime.datetime.now()), 'value': 100 }, { 'timestamp': timeutils.isotime(datetime.datetime.now() + datetime.timedelta(minutes=1)), 'value': 100 }] # send measures(should cause the alarm to fire) self.metric_client.metric.add_measures(metric['id'], measures) # confirm we get a scaleup. # Note: there is little point waiting more than 60s+time to scale up. self.assertTrue( test.call_until_true(120, 2, self.check_instance_count, stack_identifier, 2)) # cleanup metric self.metric_client.metric.delete(metric['id'])
def test_send(self): stack = self._mock_stack() notify = self.patchobject(notification, 'notify') notification.autoscaling.send(stack, adjustment='x', adjustment_type='y', capacity='5', groupname='c', message='fred', suffix='the-end') notify.assert_called_once_with( self.ctx, 'autoscaling.the-end', 'INFO', { 'state_reason': 'this is why', 'user_id': 'test_username', 'username': '******', 'user_identity': 'test_user_id', 'stack_identity': 'hay-are-en', 'stack_name': 'fred', 'tenant_id': 'test_tenant_id', 'create_at': heat_timeutils.isotime(stack.created_time), 'description': 'for test', 'tags': ['tag1', 'tag2'], 'updated_at': heat_timeutils.isotime(stack.updated_time), 'state': 'x_f', 'adjustment_type': 'y', 'groupname': 'c', 'capacity': '5', 'message': 'fred', 'adjustment': 'x' })
def format_watch(watch): updated_time = heat_timeutils.isotime(watch.updated_at or timeutils.utcnow()) result = { rpc_api.WATCH_ACTIONS_ENABLED: watch.rule.get(rpc_api.RULE_ACTIONS_ENABLED), rpc_api.WATCH_ALARM_ACTIONS: watch.rule.get(rpc_api.RULE_ALARM_ACTIONS), rpc_api.WATCH_TOPIC: watch.rule.get(rpc_api.RULE_TOPIC), rpc_api.WATCH_UPDATED_TIME: updated_time, rpc_api.WATCH_DESCRIPTION: watch.rule.get(rpc_api.RULE_DESCRIPTION), rpc_api.WATCH_NAME: watch.name, rpc_api.WATCH_COMPARISON: watch.rule.get(rpc_api.RULE_COMPARISON), rpc_api.WATCH_DIMENSIONS: watch.rule.get(rpc_api.RULE_DIMENSIONS) or [], rpc_api.WATCH_PERIODS: watch.rule.get(rpc_api.RULE_PERIODS), rpc_api.WATCH_INSUFFICIENT_ACTIONS: watch.rule.get(rpc_api.RULE_INSUFFICIENT_ACTIONS), rpc_api.WATCH_METRIC_NAME: watch.rule.get(rpc_api.RULE_METRIC_NAME), rpc_api.WATCH_NAMESPACE: watch.rule.get(rpc_api.RULE_NAMESPACE), rpc_api.WATCH_OK_ACTIONS: watch.rule.get(rpc_api.RULE_OK_ACTIONS), rpc_api.WATCH_PERIOD: watch.rule.get(rpc_api.RULE_PERIOD), rpc_api.WATCH_STATE_REASON: watch.rule.get(rpc_api.RULE_STATE_REASON), rpc_api.WATCH_STATE_REASON_DATA: watch.rule.get(rpc_api.RULE_STATE_REASON_DATA), rpc_api.WATCH_STATE_UPDATED_TIME: heat_timeutils.isotime( watch.rule.get(rpc_api.RULE_STATE_UPDATED_TIME, timeutils.utcnow())), rpc_api.WATCH_STATE_VALUE: watch.state, rpc_api.WATCH_STATISTIC: watch.rule.get(rpc_api.RULE_STATISTIC), rpc_api.WATCH_THRESHOLD: watch.rule.get(rpc_api.RULE_THRESHOLD), rpc_api.WATCH_UNIT: watch.rule.get(rpc_api.RULE_UNIT), rpc_api.WATCH_STACK_ID: watch.stack_id } return result
def test_format_software_deployment(self): deployment = self._dummy_software_deployment() result = api.format_software_deployment(deployment) self.assertIsNotNone(result) self.assertEqual(deployment.id, result['id']) self.assertEqual(deployment.config.id, result['config_id']) self.assertEqual(deployment.server_id, result['server_id']) self.assertEqual(deployment.input_values, result['input_values']) self.assertEqual(deployment.output_values, result['output_values']) self.assertEqual(deployment.action, result['action']) self.assertEqual(deployment.status, result['status']) self.assertEqual(deployment.status_reason, result['status_reason']) self.assertEqual(heat_timeutils.isotime(self.now), result['creation_time']) self.assertEqual(heat_timeutils.isotime(self.now), result['updated_time'])
def format_stack(stack, preview=False, resolve_outputs=True): """Return a representation of the given stack. Return a representation of the given stack that matches the API output expectations. """ updated_time = heat_timeutils.isotime(stack.updated_time) created_time = heat_timeutils.isotime(stack.created_time or timeutils.utcnow()) deleted_time = heat_timeutils.isotime(stack.deleted_time) info = { rpc_api.STACK_NAME: stack.name, rpc_api.STACK_ID: dict(stack.identifier()), rpc_api.STACK_CREATION_TIME: created_time, rpc_api.STACK_UPDATED_TIME: updated_time, rpc_api.STACK_DELETION_TIME: deleted_time, rpc_api.STACK_NOTIFICATION_TOPICS: [], # TODO(therve) Not implemented rpc_api.STACK_PARAMETERS: stack.parameters.map(six.text_type), rpc_api.STACK_DESCRIPTION: stack.t[stack.t.DESCRIPTION], rpc_api.STACK_TMPL_DESCRIPTION: stack.t[stack.t.DESCRIPTION], rpc_api.STACK_CAPABILITIES: [], # TODO(?) Not implemented yet rpc_api.STACK_DISABLE_ROLLBACK: stack.disable_rollback, rpc_api.STACK_TIMEOUT: stack.timeout_mins, rpc_api.STACK_OWNER: stack.username, rpc_api.STACK_PARENT: stack.owner_id, rpc_api.STACK_USER_PROJECT_ID: stack.stack_user_project_id, rpc_api.STACK_TAGS: stack.tags, } if not preview: update_info = { rpc_api.STACK_ACTION: stack.action or '', rpc_api.STACK_STATUS: stack.status or '', rpc_api.STACK_STATUS_DATA: stack.status_reason, } info.update(update_info) # allow users to view the outputs of stacks if (not (stack.action == stack.DELETE and stack.status == stack.COMPLETE) and resolve_outputs): info[rpc_api.STACK_OUTPUTS] = format_stack_outputs(stack.outputs, resolve_value=True) return info
def format_stack_resource(resource, detail=True, with_props=False, with_attr=None): """Return a representation of the given resource. Return a representation of the given resource that matches the API output expectations. """ created_time = heat_timeutils.isotime(resource.created_time) last_updated_time = heat_timeutils.isotime(resource.updated_time or resource.created_time) res = { rpc_api.RES_UPDATED_TIME: last_updated_time, rpc_api.RES_CREATION_TIME: created_time, rpc_api.RES_NAME: resource.name, rpc_api.RES_PHYSICAL_ID: resource.resource_id or '', rpc_api.RES_ACTION: resource.action, rpc_api.RES_STATUS: resource.status, rpc_api.RES_STATUS_DATA: resource.status_reason, rpc_api.RES_TYPE: resource.type(), rpc_api.RES_ID: dict(resource.identifier()), rpc_api.RES_STACK_ID: dict(resource.stack.identifier()), rpc_api.RES_STACK_NAME: resource.stack.name, rpc_api.RES_REQUIRED_BY: resource.required_by(), } if resource.has_nested(): res[rpc_api.RES_NESTED_STACK_ID] = dict(resource.nested_identifier()) if resource.stack.parent_resource_name: res[rpc_api.RES_PARENT_RESOURCE] = resource.stack.parent_resource_name if detail: res[rpc_api.RES_DESCRIPTION] = resource.t.description res[rpc_api.RES_METADATA] = resource.metadata_get() if with_attr is not False: res[rpc_api.RES_ATTRIBUTES] = format_resource_attributes( resource, with_attr) if with_props: res[rpc_api.RES_PROPERTIES] = format_resource_properties(resource) return res
def format_stack_resource(resource, detail=True, with_props=False, with_attr=None): """Return a representation of the given resource. Return a representation of the given resource that matches the API output expectations. """ created_time = heat_timeutils.isotime(resource.created_time) last_updated_time = heat_timeutils.isotime( resource.updated_time or resource.created_time) res = { rpc_api.RES_UPDATED_TIME: last_updated_time, rpc_api.RES_CREATION_TIME: created_time, rpc_api.RES_NAME: resource.name, rpc_api.RES_PHYSICAL_ID: resource.resource_id or '', rpc_api.RES_ACTION: resource.action, rpc_api.RES_STATUS: resource.status, rpc_api.RES_STATUS_DATA: resource.status_reason, rpc_api.RES_TYPE: resource.type(), rpc_api.RES_ID: dict(resource.identifier()), rpc_api.RES_STACK_ID: dict(resource.stack.identifier()), rpc_api.RES_STACK_NAME: resource.stack.name, rpc_api.RES_REQUIRED_BY: resource.required_by(), } if resource.has_nested(): res[rpc_api.RES_NESTED_STACK_ID] = dict(resource.nested_identifier()) if resource.stack.parent_resource_name: res[rpc_api.RES_PARENT_RESOURCE] = resource.stack.parent_resource_name if detail: res[rpc_api.RES_DESCRIPTION] = resource.t.description res[rpc_api.RES_METADATA] = resource.metadata_get() if with_attr is not False: res[rpc_api.RES_ATTRIBUTES] = format_resource_attributes( resource, with_attr) if with_props: res[rpc_api.RES_PROPERTIES] = format_resource_properties( resource) return res
def test_format_software_config(self): config = self._dummy_software_config() result = api.format_software_config(config) self.assertIsNotNone(result) self.assertEqual([{'name': 'bar'}], result['inputs']) self.assertEqual([{'name': 'result'}], result['outputs']) self.assertEqual([{'name': 'result'}], result['outputs']) self.assertEqual({}, result['options']) self.assertEqual(heat_timeutils.isotime(self.now), result['creation_time'])
def format_snapshot(snapshot): if snapshot is None: return result = { rpc_api.SNAPSHOT_ID: snapshot.id, rpc_api.SNAPSHOT_NAME: snapshot.name, rpc_api.SNAPSHOT_STATUS: snapshot.status, rpc_api.SNAPSHOT_STATUS_REASON: snapshot.status_reason, rpc_api.SNAPSHOT_DATA: snapshot.data, rpc_api.SNAPSHOT_CREATION_TIME: heat_timeutils.isotime(snapshot.created_at), } return result
def format_watch(watch): updated_time = heat_timeutils.isotime(watch.updated_at or timeutils.utcnow()) result = { rpc_api.WATCH_ACTIONS_ENABLED: watch.rule.get( rpc_api.RULE_ACTIONS_ENABLED), rpc_api.WATCH_ALARM_ACTIONS: watch.rule.get( rpc_api.RULE_ALARM_ACTIONS), rpc_api.WATCH_TOPIC: watch.rule.get(rpc_api.RULE_TOPIC), rpc_api.WATCH_UPDATED_TIME: updated_time, rpc_api.WATCH_DESCRIPTION: watch.rule.get(rpc_api.RULE_DESCRIPTION), rpc_api.WATCH_NAME: watch.name, rpc_api.WATCH_COMPARISON: watch.rule.get(rpc_api.RULE_COMPARISON), rpc_api.WATCH_DIMENSIONS: watch.rule.get( rpc_api.RULE_DIMENSIONS) or [], rpc_api.WATCH_PERIODS: watch.rule.get(rpc_api.RULE_PERIODS), rpc_api.WATCH_INSUFFICIENT_ACTIONS: watch.rule.get(rpc_api.RULE_INSUFFICIENT_ACTIONS), rpc_api.WATCH_METRIC_NAME: watch.rule.get(rpc_api.RULE_METRIC_NAME), rpc_api.WATCH_NAMESPACE: watch.rule.get(rpc_api.RULE_NAMESPACE), rpc_api.WATCH_OK_ACTIONS: watch.rule.get(rpc_api.RULE_OK_ACTIONS), rpc_api.WATCH_PERIOD: watch.rule.get(rpc_api.RULE_PERIOD), rpc_api.WATCH_STATE_REASON: watch.rule.get(rpc_api.RULE_STATE_REASON), rpc_api.WATCH_STATE_REASON_DATA: watch.rule.get(rpc_api.RULE_STATE_REASON_DATA), rpc_api.WATCH_STATE_UPDATED_TIME: heat_timeutils.isotime( watch.rule.get(rpc_api.RULE_STATE_UPDATED_TIME, timeutils.utcnow())), rpc_api.WATCH_STATE_VALUE: watch.state, rpc_api.WATCH_STATISTIC: watch.rule.get(rpc_api.RULE_STATISTIC), rpc_api.WATCH_THRESHOLD: watch.rule.get(rpc_api.RULE_THRESHOLD), rpc_api.WATCH_UNIT: watch.rule.get(rpc_api.RULE_UNIT), rpc_api.WATCH_STACK_ID: watch.stack_id } return result
def test_format_stack_resource(self): self.stack.created_time = datetime(2015, 8, 3, 17, 5, 1) self.stack.updated_time = datetime(2015, 8, 3, 17, 6, 2) res = self.stack['generic1'] resource_keys = set(( rpc_api.RES_CREATION_TIME, rpc_api.RES_UPDATED_TIME, rpc_api.RES_NAME, rpc_api.RES_PHYSICAL_ID, rpc_api.RES_ACTION, rpc_api.RES_STATUS, rpc_api.RES_STATUS_DATA, rpc_api.RES_TYPE, rpc_api.RES_ID, rpc_api.RES_STACK_ID, rpc_api.RES_STACK_NAME, rpc_api.RES_REQUIRED_BY, )) resource_details_keys = resource_keys.union(set(( rpc_api.RES_DESCRIPTION, rpc_api.RES_METADATA, rpc_api.RES_ATTRIBUTES, ))) formatted = api.format_stack_resource(res, True) self.assertEqual(resource_details_keys, set(formatted.keys())) formatted = api.format_stack_resource(res, False) self.assertEqual(resource_keys, set(formatted.keys())) self.assertEqual(heat_timeutils.isotime(self.stack.created_time), formatted[rpc_api.RES_CREATION_TIME]) self.assertEqual(heat_timeutils.isotime(self.stack.updated_time), formatted[rpc_api.RES_UPDATED_TIME]) self.assertEqual(res.INIT, formatted[rpc_api.RES_ACTION])
def format_software_config(sc, detail=True): if sc is None: return result = { rpc_api.SOFTWARE_CONFIG_ID: sc.id, rpc_api.SOFTWARE_CONFIG_NAME: sc.name, rpc_api.SOFTWARE_CONFIG_GROUP: sc.group, rpc_api.SOFTWARE_CONFIG_CREATION_TIME: heat_timeutils.isotime(sc.created_at) } if detail: result[rpc_api.SOFTWARE_CONFIG_CONFIG] = sc.config['config'] result[rpc_api.SOFTWARE_CONFIG_INPUTS] = sc.config['inputs'] result[rpc_api.SOFTWARE_CONFIG_OUTPUTS] = sc.config['outputs'] result[rpc_api.SOFTWARE_CONFIG_OPTIONS] = sc.config['options'] return result
def format_event(event, stack_identifier, root_stack_identifier=None): result = { rpc_api.EVENT_ID: dict(event.identifier(stack_identifier)), rpc_api.EVENT_STACK_ID: dict(stack_identifier), rpc_api.EVENT_STACK_NAME: stack_identifier.stack_name, rpc_api.EVENT_TIMESTAMP: heat_timeutils.isotime(event.created_at), rpc_api.EVENT_RES_NAME: event.resource_name, rpc_api.EVENT_RES_PHYSICAL_ID: event.physical_resource_id, rpc_api.EVENT_RES_ACTION: event.resource_action, rpc_api.EVENT_RES_STATUS: event.resource_status, rpc_api.EVENT_RES_STATUS_DATA: event.resource_status_reason, rpc_api.EVENT_RES_TYPE: event.resource_type, rpc_api.EVENT_RES_PROPERTIES: event.resource_properties, } if root_stack_identifier: result[rpc_api.EVENT_ROOT_STACK_ID] = dict(root_stack_identifier) return result
def format_software_config(sc, detail=True, include_project=False): if sc is None: return result = { rpc_api.SOFTWARE_CONFIG_ID: sc.id, rpc_api.SOFTWARE_CONFIG_NAME: sc.name, rpc_api.SOFTWARE_CONFIG_GROUP: sc.group, rpc_api.SOFTWARE_CONFIG_CREATION_TIME: heat_timeutils.isotime(sc.created_at) } if detail: result[rpc_api.SOFTWARE_CONFIG_CONFIG] = sc.config['config'] result[rpc_api.SOFTWARE_CONFIG_INPUTS] = sc.config['inputs'] result[rpc_api.SOFTWARE_CONFIG_OUTPUTS] = sc.config['outputs'] result[rpc_api.SOFTWARE_CONFIG_OPTIONS] = sc.config['options'] if include_project: result[rpc_api.SOFTWARE_CONFIG_PROJECT] = sc.tenant return result
def format_watch_data(wd, rule_names): # 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: LOG.error("Unexpected number of keys in watch_data.data!") return result = { rpc_api.WATCH_DATA_ALARM: rule_names.get(wd.watch_rule_id), rpc_api.WATCH_DATA_METRIC: metric_name, rpc_api.WATCH_DATA_TIME: heat_timeutils.isotime(wd.created_at), rpc_api.WATCH_DATA_NAMESPACE: namespace, rpc_api.WATCH_DATA: metric_data } return result