UNPKG

@trusthab/composable-resources

Version:

migrating https://github.com/knetikmedia/hab-api/tree/integration/app/resources/composable

285 lines (254 loc) 6.98 kB
const Mustache = require('mustache'); const _ = require('lodash'); const composer = require('../mixin_loader'); const DEFAULT_OPERATOR = '>'; const OPERATIONS = { '==': (a, b) => a === b, '!=': (a, b) => a !== b, '>': (a, b) => a > b, '<': (a, b) => a < b, '>=': (a, b) => a >= b, '<=': (a, b) => a <= b }; const SUPPORTED_COMPARISON_OPERATORS = Object.keys(OPERATIONS); module.exports = (App) => { class MetricResource { static mixins() { return [ // Functionality 'Validatable', 'Templatable', // ORMish 'Persistable', 'KnetikCloudPersistence' ]; } static simpleProperties() { return true; } static fields() { return { template: { type: 'text', schema_ignore: true }, id: { type: 'integer', or: ['null'], path: 'id' }, location_id: { type: 'text', or: ['null'], path: 'data.location_id' }, location_type: { type: 'text', path: 'data.location_type' }, name: { type: 'text', or: ['null'], path: 'name' }, machine_name: { type: 'text', or: ['null'], path: 'data.machine_name' }, category: { type: 'text', or: ['null'], path: 'data.category' }, alerts_enabled: { type: 'boolean', path: 'data.alerts_enabled' }, enabled: { type: 'boolean', path: 'data.enabled' }, alert_period: { type: 'integer', path: 'data.alert_period' }, threshold_info: { type: 'double', path: 'data.threshold_info' }, threshold_warning: { type: 'double', path: 'data.threshold_warning' }, threshold_urgent: { type: 'double', path: 'data.threshold_urgent' }, threshold_critical: { type: 'double', path: 'data.threshold_critical' }, show_total: { type: 'boolean', or: ['null'], path: 'data.show_total' }, display_order: { type: 'integer', or: ['null'], path: 'data.display_order' }, status: { type: 'text', or: ['null'], path: 'status', get_method: 'getStatus' }, value: { type: 'float', get_method: 'getValue' }, total: { type: 'float', get_method: 'getTotal' }, operator: { type: 'text', or: ['null'], path: 'data.operator' }, expression_template: { type: 'text', or: ['null'], path: 'data.expression_template' }, expression: { type: 'text', or: ['null'], get_method: 'getExpression' }, precision: { type: 'integer', or: ['null'], path: 'data.precision' }, editable: { type: 'boolean', or: ['null'], path: 'data.editable' }, diagnostic_url: { type: 'text', or: ['null'], get_method: 'getDiagnosticUrl' }, created_at: { type: 'integer', or: ['null'], path: 'created_date' }, updated_at: { type: 'integer', or: ['null'], path: 'updated_date' }, unit: { type: 'text', or: ['null'], path: 'data.unit' }, ymin: { type: 'integer', or: ['null'], path: 'data.ymin' }, ymax: { type: 'integer', or: ['null'], path: 'data.ymax' }, version: { type: 'integer', or: ['null'], path: 'data.version' } }; } getExpression(threshold) { const { machine_name, location_type } = this; const expression_template = _.get(this._delegate, 'data.expression_template'); const params = { app_id: App.app_id }; if (this.location_id) { params[`${location_type}_id`] = this.location_id; } let param_str = ''; param_str = Object.keys(params).map((key) => { const val = params[key]; return `${key}="${val}"`; }).join(','); param_str = `{ ${param_str} }`; const properties = { param_str, machine_name }; if (threshold) { properties.operator = this.operator; properties.threshold = threshold; } return Mustache.render(expression_template, properties); } getDiagnosticUrl() { const query = encodeURIComponent(this.getExpression()); const host = process.env.PROMETHEUS_API_HOST.replace('api/v1', 'graph'); return `${host}?g0.range_input=1h&g0.expr=${query}&g0.tab=0`; } getTotal() { const total = this.get('total'); return this.show_total ? total : '--'; } getValue() { const value = this.get('value'); return _.isFinite(value) ? value : '--'; } getStatus() { const { enabled, alerts_enabled, value } = this; const operator = SUPPORTED_COMPARISON_OPERATORS.includes(this.operator) ? this.operator : DEFAULT_OPERATOR; if (!enabled) { return null; } if (!alerts_enabled || !_.isFinite(value)) { return 'none'; } const { threshold_critical, threshold_urgent, threshold_warning, threshold_info } = this; if (_.isFinite(threshold_critical) && OPERATIONS[operator](value, threshold_critical)) { return 'critical'; } if (_.isFinite(threshold_urgent) && OPERATIONS[operator](value, threshold_urgent)) { return 'urgent'; } if (_.isFinite(threshold_warning) && OPERATIONS[operator](value, threshold_warning)) { return 'warning'; } if (_.isFinite(threshold_info) && OPERATIONS[operator](value, threshold_info)) { return 'info'; } return 'none'; } static knetikCloudMethods() { return { search: { index: 'objects', template: 'alarms' }, find: { api: 'ObjectsApi', method: 'getObjectItem', paramsBuilder: id => ['alarms', id] }, create: { api: 'ObjectsApi', method: 'createObjectItem', paramsBuilder: params => ['alarms', { objectItem: params }] }, update: { api: 'ObjectsApi', method: 'updateObjectItem', paramsBuilder: (id, params) => ['alarms', id, { objectItem: params }] } }; } static customFilters() { return require('./metric_filters')(App); } } return composer(MetricResource, App); };