From eb9722aef0985c9058285c04e828eeb34ad8ce69 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Mon, 11 Apr 2016 22:21:19 +0300 Subject: [PATCH] Iss #182 - fixed template variables inside regex. --- src/datasource-zabbix/datasource.js | 51 ++++++++++++++++++++--------- src/datasource-zabbix/utils.js | 8 ++++- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/datasource-zabbix/datasource.js b/src/datasource-zabbix/datasource.js index 53d10d8..b2cc6b2 100644 --- a/src/datasource-zabbix/datasource.js +++ b/src/datasource-zabbix/datasource.js @@ -47,21 +47,8 @@ export class ZabbixAPIDatasource { this.templateSrv = templateSrv; this.alertSrv = alertSrv; - // If template variables are used in request, replace it using regex format - // and wrap with '/' for proper multi-value work. Example: - // $variable selected as a, b, c - // We use filter $variable - // $variable -> a|b|c -> /a|b|c/ - // /$variable/ -> /a|b|c/ -> /a|b|c/ - this.multiValueFormat = "regex"; - this.replaceTemplateVars = function(target, scopedVars) { - var regexPattern = /^\/.*\/$/; - var replacedTarget = this.templateSrv.replace(target, scopedVars, this.multiValueFormat); - if (target !== replacedTarget && !regexPattern.test(replacedTarget)) { - replacedTarget = '/' + replacedTarget + '/'; - } - return replacedTarget; - }; + // Use custom format for template variables + this.replaceTemplateVars = _.partial(replaceTemplateVars, this.templateSrv); console.log(this.zabbixCache); } @@ -445,3 +432,37 @@ function formatMetric(metricObj) { expandable: false }; } + +/** + * Custom formatter for template variables. + * Default Grafana "regex" formatter returns + * value1|value2 + * This formatter returns + * (value1|value2) + * This format needed for using in complex regex with + * template variables, for example + * /CPU $cpu_item.*time/ where $cpu_item is system,user,iowait + */ +function zabbixTemplateFormat(value, variable) { + if (typeof value === 'string') { + return utils.escapeRegex(value); + } + + var escapedValues = _.map(value, utils.escapeRegex); + return '(' + escapedValues.join('|') + ')'; +} + +/** If template variables are used in request, replace it using regex format + * and wrap with '/' for proper multi-value work. Example: + * $variable selected as a, b, c + * We use filter $variable + * $variable -> a|b|c -> /a|b|c/ + * /$variable/ -> /a|b|c/ -> /a|b|c/ + */ +function replaceTemplateVars(templateSrv, target, scopedVars) { + var replacedTarget = templateSrv.replace(target, scopedVars, zabbixTemplateFormat); + if (target !== replacedTarget && !utils.regexPattern.test(replacedTarget)) { + replacedTarget = '/' + replacedTarget + '/'; + } + return replacedTarget; +} diff --git a/src/datasource-zabbix/utils.js b/src/datasource-zabbix/utils.js index cf89a78..77ca3bc 100644 --- a/src/datasource-zabbix/utils.js +++ b/src/datasource-zabbix/utils.js @@ -23,7 +23,7 @@ export function expandItemName(name, key) { } // Pattern for testing regex -var regexPattern = /^\/(.*)\/([gmi]*)$/m; +export var regexPattern = /^\/(.*)\/([gmi]*)$/m; export function isRegex(str) { return regexPattern.test(str); @@ -36,6 +36,12 @@ export function buildRegex(str) { return new RegExp(pattern, flags); } +// Need for template variables replace +// From Grafana's templateSrv.js +export function escapeRegex(value) { + return value.replace(/[\\^$*+?.()|[\]{}\/]/g, '\\$&'); +} + export function parseInterval(interval) { var intervalPattern = /(^[\d]+)(y|M|w|d|h|m|s)/g; var momentInterval = intervalPattern.exec(interval);