From 24285a9483ea6258fbdcd77f0169941542c7bfbd Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Thu, 23 Mar 2023 14:40:22 +0100 Subject: [PATCH] Fix item tag filter, #1594 --- pkg/zabbix/methods.go | 29 ++++++++++--------- pkg/zabbix/utils.go | 14 +++++++++ src/datasource/utils.ts | 10 ++++--- .../zabbix_api/zabbixAPIConnector.ts | 6 ++-- 4 files changed, 39 insertions(+), 20 deletions(-) diff --git a/pkg/zabbix/methods.go b/pkg/zabbix/methods.go index 4c21d5575..9f110b207 100644 --- a/pkg/zabbix/methods.go +++ b/pkg/zabbix/methods.go @@ -2,7 +2,6 @@ package zabbix import ( "context" - "regexp" "strconv" "strings" @@ -243,8 +242,15 @@ func (ds *Zabbix) GetItemTags(ctx context.Context, groupFilter string, hostFilte allItems, err = ds.GetAllItems(ctx, hostids, nil, itemType, showDisabled, "") var allTags []ItemTag + tagsMap := make(map[string]ItemTag) for _, item := range allItems { - allTags = append(allTags, item.Tags...) + for _, itemTag := range item.Tags { + tagStr := itemTagToString(itemTag) + tagsMap[tagStr] = itemTag + } + } + for _, t := range tagsMap { + allTags = append(allTags, t) } return filterTags(allTags, tagFilter) @@ -376,18 +382,15 @@ func (ds *Zabbix) GetAllItems(ctx context.Context, hostids []string, appids []st params["selectTags"] = "extend" if len(itemTagFilter) > 0 { allTags := strings.Split(itemTagFilter, ",") - re := regexp.MustCompile(`(?m).*?([a-zA-Z0-9\s\-_]*):\s*([a-zA-Z0-9\-_\/:]*)`) - var tagsParams []map[string]string - for i := 0; i < len(allTags); i++ { - res := re.FindAllStringSubmatch(allTags[i], -1) - for i := range res { - tagParam := map[string]string{ - "tag": res[i][1], - "value": res[i][2], - "operator": "1", - } - tagsParams = append(tagsParams, tagParam) + tagsParams := make([]map[string]string, 0) + for _, tagStr := range allTags { + tag := parseItemTag(tagStr) + tagParam := map[string]string{ + "tag": tag.Tag, + "value": tag.Value, + "operator": "1", } + tagsParams = append(tagsParams, tagParam) } params["tags"] = tagsParams params["evaltype"] = 2 diff --git a/pkg/zabbix/utils.go b/pkg/zabbix/utils.go index d5612f1e5..1e3cfa102 100644 --- a/pkg/zabbix/utils.go +++ b/pkg/zabbix/utils.go @@ -100,3 +100,17 @@ func itemTagToString(tag ItemTag) string { return tag.Tag } } + +func parseItemTag(tagStr string) ItemTag { + tag := ItemTag{} + firstIdx := strings.Index(tagStr, ":") + if firstIdx > 0 { + tag.Tag = strings.TrimSpace(tagStr[:firstIdx]) + if firstIdx < len(tagStr)-1 { + tag.Value = strings.TrimSpace(tagStr[firstIdx+1:]) + } + } else { + tag.Tag = strings.TrimSpace(tagStr) + } + return tag +} diff --git a/src/datasource/utils.ts b/src/datasource/utils.ts index aa7fcd045..f3a905ea8 100644 --- a/src/datasource/utils.ts +++ b/src/datasource/utils.ts @@ -433,10 +433,12 @@ export function parseTags(tagStr: string): any[] { // Parses string representation of tag into the object export function parseItemTag(tagStr: string): ZBXItemTag { const itemTag: ZBXItemTag = { tag: '', value: '' }; - const tagParts = tagStr.split(': '); - itemTag.tag = tagParts[0]; - if (tagParts[1]) { - itemTag.value = tagParts[1]; + const firstIdx = tagStr.indexOf(':'); + if (firstIdx > 0) { + itemTag.tag = tagStr.slice(0, firstIdx).trim(); + itemTag.value = tagStr.slice(Math.min(firstIdx + 1, tagStr.length)).trim(); + } else { + itemTag.tag = tagStr.trim(); } return itemTag; } diff --git a/src/datasource/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts b/src/datasource/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts index a745ed991..7712cc065 100644 --- a/src/datasource/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts +++ b/src/datasource/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts @@ -7,6 +7,7 @@ import { ShowProblemTypes, ZBXProblem, ZBXTrigger } from '../../../types'; import { APIExecuteScriptResponse, JSONRPCError, ZBXScript } from './types'; import { BackendSrvRequest, getBackendSrv } from '@grafana/runtime'; import { rangeUtil } from '@grafana/data'; +import { parseItemTag } from '../../../utils'; const DEFAULT_ZABBIX_VERSION = '3.0.0'; @@ -206,10 +207,9 @@ export class ZabbixAPIConnector { if (itemTagFilter) { const allTags = itemTagFilter.split(','); let tagsParam = []; - const regex = /.*?([a-zA-Z0-9\s\-_]*):\s*([a-zA-Z0-9\-_\/:]*)/; for (let i = 0; i < allTags.length; i++) { - const matches = allTags[i].match(regex); - tagsParam.push({ tag: matches[1].replace('/', ''), value: matches[2].trim(), operator: '1' }); + const tag = parseItemTag(allTags[i]); + tagsParam.push({ tag: tag.tag, value: tag.value, operator: '1' }); } params.tags = tagsParam; // Use OR eval type