From 058d6f5a7b8a3e9dd24208ad729006c0c81e1057 Mon Sep 17 00:00:00 2001 From: Omar Zarrouki Date: Mon, 25 Nov 2024 17:27:50 +0100 Subject: [PATCH 1/6] adding user macros names values query type to filter hosts in zabbix --- Makefile | 2 +- debug-backend.sh | 0 devenv/zas-agent/run_zas_agent.sh | 0 docs/make-docs | 0 go.mod | 17 +- go.sum | 16 ++ pkg/datasource/models.go | 3 + .../components/VariableQueryEditor.tsx | 94 +++++++++- src/datasource/datasource.ts | 13 +- src/datasource/specs/datasource.spec.ts | 12 +- src/datasource/types.ts | 7 + .../zabbix_api/zabbixAPIConnector.ts | 18 ++ src/datasource/zabbix/types.ts | 2 +- src/datasource/zabbix/zabbix.ts | 171 +++++++++++++++--- 14 files changed, 301 insertions(+), 54 deletions(-) mode change 100755 => 100644 debug-backend.sh mode change 100755 => 100644 devenv/zas-agent/run_zas_agent.sh mode change 100755 => 100644 docs/make-docs diff --git a/Makefile b/Makefile index 85c06e18c..6314170b0 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ install: yarn install --pure-lockfile # Backend go install -v ./pkg/ - GO111MODULE=off go get -u golang.org/x/lint/golint + # GO111MODULE=off go get -u golang.org/x/lint/golint deps-go: go install -v ./pkg/ diff --git a/debug-backend.sh b/debug-backend.sh old mode 100755 new mode 100644 diff --git a/devenv/zas-agent/run_zas_agent.sh b/devenv/zas-agent/run_zas_agent.sh old mode 100755 new mode 100644 diff --git a/docs/make-docs b/docs/make-docs old mode 100755 new mode 100644 diff --git a/go.mod b/go.mod index 880689b35..9863ddbb0 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/alexanderzobnin/grafana-zabbix -go 1.22.1 +go 1.22.0 + +toolchain go1.23.3 require ( github.com/bitly/go-simplejson v0.5.1 @@ -9,7 +11,7 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible github.com/prometheus/client_golang v1.20.5 github.com/stretchr/testify v1.9.0 - golang.org/x/net v0.30.0 + golang.org/x/net v0.31.0 gotest.tools v2.2.0+incompatible ) @@ -88,11 +90,12 @@ require ( go.opentelemetry.io/otel/trace v1.31.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect - golang.org/x/mod v0.17.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect - golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect + golang.org/x/lint v0.0.0-20241112194109-818c5a804067 // indirect + golang.org/x/mod v0.22.0 // indirect + golang.org/x/sync v0.9.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/text v0.20.0 // indirect + golang.org/x/tools v0.27.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect diff --git a/go.sum b/go.sum index 1f1dc4dca..85d59b9ab 100644 --- a/go.sum +++ b/go.sum @@ -237,21 +237,30 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/lint v0.0.0-20241112194109-818c5a804067 h1:adDmSQyFTCiv19j015EGKJBoaa7ElV0Q1Wovb/4G7NA= +golang.org/x/lint v0.0.0-20241112194109-818c5a804067/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= +golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191020152052-9984515f0562/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -267,16 +276,23 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= +golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/datasource/models.go b/pkg/datasource/models.go index 6f3cc1b65..d066d3b84 100644 --- a/pkg/datasource/models.go +++ b/pkg/datasource/models.go @@ -54,6 +54,9 @@ type QueryModel struct { Application QueryFilter `json:"application"` ItemTag QueryFilter `json:"itemTag"` Item QueryFilter `json:"item"` + UserMacro QueryFilter `json:"userMacro"` + + // Item ID mode ItemIDs string `json:"itemids,omitempty"` diff --git a/src/datasource/components/VariableQueryEditor.tsx b/src/datasource/components/VariableQueryEditor.tsx index c6086f32d..7295b7d3b 100644 --- a/src/datasource/components/VariableQueryEditor.tsx +++ b/src/datasource/components/VariableQueryEditor.tsx @@ -13,6 +13,8 @@ export class ZabbixVariableQueryEditor extends PureComponent { - const { queryType, group, host, application, itemTag, item } = this.state; - const queryModel = { queryType, group, host, application, itemTag, item }; + const { queryType, group, host, application, itemTag, item, userMacroName , userMacroValue } = this.state; + const queryModel = { queryType, group, host, application, itemTag, item, userMacroName, userMacroValue }; this.props.onChange(queryModel, `Zabbix - ${queryType}`); }; @@ -81,14 +85,14 @@ export class ZabbixVariableQueryEditor extends PureComponent - {selectedQueryType.value !== VariableQueryTypes.Group && ( + {( selectedQueryType.value === VariableQueryTypes.Application || + selectedQueryType.value === VariableQueryTypes.ItemTag || + selectedQueryType.value === VariableQueryTypes.Item || + selectedQueryType.value === VariableQueryTypes.ItemValues || + selectedQueryType.value === VariableQueryTypes.Host ) && ( )} + + {(selectedQueryType.value === VariableQueryTypes.Application || selectedQueryType.value === VariableQueryTypes.ItemTag || selectedQueryType.value === VariableQueryTypes.Item || - selectedQueryType.value === VariableQueryTypes.ItemValues) && ( + selectedQueryType.value === VariableQueryTypes.ItemValues ) && ( <> {supportsItemTags && ( @@ -173,6 +183,75 @@ export class ZabbixVariableQueryEditor extends PureComponent )} + + + )} + + {selectedQueryType.value === VariableQueryTypes.UserMacroName && ( + + + this.handleQueryUpdate(evt, 'userMacroName')} + onBlur={this.handleQueryChange} + /> + + + )} + + {selectedQueryType.value === VariableQueryTypes.UserMacroValue && ( + <> + + + + this.handleQueryUpdate(evt, 'userMacroName')} + onBlur={this.handleQueryChange} + /> + + + + + + this.handleQueryUpdate(evt, 'userMacroValue')} + onBlur={this.handleQueryChange} + /> + + + + + + )} + + {selectedQueryType.value === VariableQueryTypes.Host && ( + <> + + + this.handleQueryUpdate(evt, 'userMacroName')} + onBlur={this.handleQueryChange} + /> + + + + + + this.handleQueryUpdate(evt, 'userMacroValue')} + onBlur={this.handleQueryChange} + /> + + )} @@ -188,3 +267,4 @@ export class ZabbixVariableQueryEditor extends PureComponent { it('should return hosts', (done) => { const tests = [ - { query: '*.*', expect: ['/.*/', '/.*/'] }, - { query: '.', expect: ['', ''] }, - { query: 'Backend.*', expect: ['Backend', '/.*/'] }, - { query: 'Back*.', expect: ['Back*', ''] }, + { query: '*.*', expect: ['/.*/', '/.*/',null, null] }, + { query: '.', expect: ['', '', null,null] }, + { query: 'Backend.*', expect: ['Backend', '/.*/', null,null] }, + { query: 'Back*.', expect: ['Back*', '',null,null] }, ]; for (const test of tests) { ctx.ds.metricFindQuery(test.query); - expect(ctx.ds.zabbix.getHosts).toBeCalledWith(test.expect[0], test.expect[1]); + expect(ctx.ds.zabbix.getHosts).toBeCalledWith(test.expect[0], test.expect[1],test.expect[2],test.expect[3]); ctx.ds.zabbix.getHosts.mockClear(); } done(); @@ -315,7 +315,7 @@ describe('ZabbixDatasource', () => { let query = '*.*'; ctx.ds.metricFindQuery(query); - expect(ctx.ds.zabbix.getHosts).toBeCalledWith('/.*/', '/.*/'); + expect(ctx.ds.zabbix.getHosts).toBeCalledWith('/.*/','/.*/',null,null); done(); }); }); diff --git a/src/datasource/types.ts b/src/datasource/types.ts index c1f50e9b9..df55e0e13 100644 --- a/src/datasource/types.ts +++ b/src/datasource/types.ts @@ -72,6 +72,9 @@ export interface VariableQuery { itemTag?: string; item?: string; macro?: string; + userMacro?: String; + userMacroName?: string; + userMacroValue?: string; } export type LegacyVariableQuery = VariableQuery | string; @@ -84,6 +87,10 @@ export enum VariableQueryTypes { ItemTag = 'itemTag', Item = 'item', ItemValues = 'itemValues', + UserMacro = 'userMacro', + UserMacroName = 'userMacroName', + UserMacroValue = 'userMacroValue', + } export interface ProblemDTO { diff --git a/src/datasource/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts b/src/datasource/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts index 845e08a44..49d6cd476 100644 --- a/src/datasource/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts +++ b/src/datasource/zabbix/connectors/zabbix_api/zabbixAPIConnector.ts @@ -148,6 +148,15 @@ export class ZabbixAPIConnector { return this.request('hostgroup.get', params); } + getUserMacrosByGroup(groupids) { + const params = { + output: ['hostmacroid', 'macro', 'value', 'hostid'], + groupids: groupids, + }; + + return this.request('usermacro.get', params); + } + getHosts(groupids): Promise { const params: any = { output: ['hostid', 'name', 'host'], @@ -245,6 +254,15 @@ export class ZabbixAPIConnector { return this.request('usermacro.get', params); } + getMacrosByGroup(groupids) { + const params = { + output: 'extend', + groupids: groupids, + }; + + return this.request('usermacro.get', params); + } + getUserMacros(hostmacroids) { const params = { output: 'extend', diff --git a/src/datasource/zabbix/types.ts b/src/datasource/zabbix/types.ts index 32c216603..926081db0 100644 --- a/src/datasource/zabbix/types.ts +++ b/src/datasource/zabbix/types.ts @@ -18,7 +18,7 @@ export interface ZabbixConnector { getVersion: () => Promise; getGroups: (groupFilter?) => any; - getHosts: (groupFilter?, hostFilter?) => any; + getHosts: (groupFilter?, hostFilter?, userMacroName?, userMacroValue?) => any; getApps: (groupFilter?, hostFilter?, appFilter?) => any; getUMacros: (groupFilter?, hostFilter?, macroFilter?) => any; getItems: (groupFilter?, hostFilter?, appFilter?, itemTagFilter?, itemFilter?, options?) => any; diff --git a/src/datasource/zabbix/zabbix.ts b/src/datasource/zabbix/zabbix.ts index 805256bbf..53da097ef 100644 --- a/src/datasource/zabbix/zabbix.ts +++ b/src/datasource/zabbix/zabbix.ts @@ -33,6 +33,9 @@ const REQUESTS_TO_PROXYFY = [ 'getAlerts', 'getHostAlerts', 'getUserMacros', + 'getUMacrosVariable', + 'getUserMacrosNames', + 'getUserMacrosValues', 'getHostICAlerts', 'getHostPCAlerts', 'getAcknowledges', @@ -58,6 +61,7 @@ const REQUESTS_TO_CACHE = [ 'getItems', 'getMacros', 'getUMacros', + 'getUserMacros', 'getItemsByIDs', 'getITService', 'getProxies', @@ -206,7 +210,7 @@ export class Zabbix implements ZabbixConnector { * } * } * ``` - */ + n*/ testDataSource() { let zabbixVersion; let dbConnectorStatus; @@ -314,9 +318,7 @@ export class Zabbix implements ZabbixConnector { return this.getAllGroups().then((groups) => findByFilter(groups, groupFilter)); } - /** - * Get list of host belonging to given groups. - */ + getAllHosts(groupFilter): Promise { return this.getGroups(groupFilter).then((groups) => { const groupids = _.map(groups, 'groupid'); @@ -324,10 +326,84 @@ export class Zabbix implements ZabbixConnector { }); } - getHosts(groupFilter?, hostFilter?): Promise { - return this.getAllHosts(groupFilter).then((hosts) => findByFilter(hosts, hostFilter)); + async getAllMacros(groupFilter, hostFilter?) { + const hosts = await this.getHosts(groupFilter, hostFilter); + const hostids = hosts?.map((h) => h.hostid); + return this.zabbixAPI.getMacros(hostids); + } + + getAllMacrosByGroup(groupFilter): Promise { + return this.getGroups(groupFilter).then((groups) => { + const groupids = _.map(groups, 'groupid'); + return this.zabbixAPI.getMacrosByGroup(groupids); + }); + } + + + + async getUMacrosVariable(groupFilter, macroFilter? + ) { + const allMacros = await this.getAllMacrosByGroup(groupFilter); + const filteredMacros = filterByMQuery(allMacros, macroFilter); + console.log('Filtered Macros:', filteredMacros); + + return filteredMacros; + } + + getUserMacrosNames(groupFilter, userMacroName?) { + return this.getUMacrosVariable(groupFilter, userMacroName).then((macros) => { + const names = _.map(macros, 'macro'); + return _.uniq(names).map((name) => ({ name })); + }); + + } + + getUserMacrosValues(groupFilter, userMacroName?, userMacroValue?) { + return this.getUMacrosVariable(groupFilter, { name: userMacroName, value: userMacroValue }).then((macros) => { + const values = _.map(macros, 'value'); + return _.uniq(values).map((value) => ({ name: value })); + }); + } + + + async getUMacros(groupFilter?, hostFilter?, macroFilter?) { + const allMacros = await this.getAllMacros(groupFilter, hostFilter); + return filterByMQuery(allMacros, macroFilter); + } + + // getHosts now supports filtering on user macros (name,value) + + async getHosts(groupFilter?: string, hostFilter?: string, userMacroName?: string, userMacroValue?: string): Promise { + // Ensure userMacroName and userMacroValue are not empty or undefined + const macroFilter = (userMacroName && userMacroName.trim() !== '') || (userMacroValue && userMacroValue.trim() !== '') + ? { name: userMacroName || '', value: userMacroValue || '' } + : null; + + // console.log("macroFilter before getAllHosts: ", macroFilter); + + const hosts = await this.getAllHosts(groupFilter); + + if (macroFilter) { + const macros = await this.getUMacrosVariable(groupFilter, macroFilter); + // console.log('Macros:', macros); + // console.log('Macro Filter:', macroFilter); + + const filteredHosts = hosts.filter((host) => { + const hostMacros = macros.filter((macro) => macro.hostid === host.hostid); + // console.log('Host Macros:', hostMacros); + return filterByMQuery(hostMacros, macroFilter).length > 0; + }); + console.log('Filtered Hosts:', filteredHosts); + return findByFilter(filteredHosts, hostFilter); + } + + return findByFilter(hosts, hostFilter); + } + + + /** * Get list of applications belonging to given groups and hosts. */ @@ -360,16 +436,7 @@ export class Zabbix implements ZabbixConnector { }); } - async getAllMacros(groupFilter, hostFilter) { - const hosts = await this.getHosts(groupFilter, hostFilter); - const hostids = hosts?.map((h) => h.hostid); - return this.zabbixAPI.getMacros(hostids); - } - async getUMacros(groupFilter?, hostFilter?, macroFilter?) { - const allMacros = await this.getAllMacros(groupFilter, hostFilter); - return filterByMQuery(allMacros, macroFilter); - } async getItemTags(groupFilter?, hostFilter?, itemTagFilter?) { const items = await this.getAllItems(groupFilter, hostFilter, null, null, {}); @@ -732,12 +799,22 @@ function filterByName(list, name) { } } -function filterByMacro(list, name) { - const finded = _.filter(list, { macro: name }); - if (finded) { - return finded; + + +function filterByMacro(list, filter) { + if (typeof filter === 'string') { + // Filter is a macro name (string) + return _.filter(list, (zbx_obj) => zbx_obj.macro === filter); + } else if (typeof filter === 'object' && filter !== null) { + // Filter is an object { name, value } + return _.filter(list, (zbx_obj) => { + const nameMatch = filter.name !== undefined && filter.name !== '' ? zbx_obj.macro === filter.name : true; + const valueMatch = filter.value !== undefined && filter.value !== '' ? zbx_obj.value === filter.value : true; + return nameMatch && valueMatch; + }); } else { - return []; + // Invalid or empty filter, return the entire list + return list; } } @@ -748,12 +825,6 @@ function filterByRegex(list, regex) { }); } -function filterByMRegex(list, regex) { - const filterPattern = utils.buildRegex(regex); - return _.filter(list, (zbx_obj) => { - return filterPattern.test(zbx_obj?.macro); - }); -} function findByFilter(list, filter) { if (utils.isRegex(filter)) { @@ -771,11 +842,53 @@ function filterByQuery(list, filter) { } } + +function filterByMRegex(list, filter) { + if (typeof filter === 'string') { + // Filter is a macro name regex + const namePattern = utils.buildRegex(filter); + return _.filter(list, (zbx_obj) => namePattern.test(zbx_obj.macro)); + } else if (typeof filter === 'object' && filter !== null) { + // Filter is an object { name, value } + return _.filter(list, (zbx_obj) => { + const nameMatch = filter.name !== undefined && filter.name !== '' + ? utils.isRegex(filter.name) + ? utils.buildRegex(filter.name).test(zbx_obj.macro) + : zbx_obj.macro === filter.name + : true; + + const valueMatch = filter.value !== undefined && filter.value !== '' + ? utils.isRegex(filter.value) + ? utils.buildRegex(filter.value).test(zbx_obj.value) + : zbx_obj.value === filter.value + : true; + + return nameMatch && valueMatch; + }); + } else { + // Invalid or empty filter, return the entire list + return list; + } +} + function filterByMQuery(list, filter) { - if (utils.isRegex(filter)) { - return filterByMRegex(list, filter); + if (typeof filter === 'string') { + // Filter is a string (macro name or regex) + return utils.isRegex(filter) ? filterByMRegex(list, filter) : filterByMacro(list, filter); + } else if (typeof filter === 'object' && filter !== null) { + // Filter is an object { name, value } + const isNameRegex = filter.name && utils.isRegex(filter.name); + const isValueRegex = filter.value && utils.isRegex(filter.value); + + if ((filter.name && filter.name !== '') || (filter.value && filter.value !== '')) { + return isNameRegex || isValueRegex ? filterByMRegex(list, filter) : filterByMacro(list, filter); + } else { + // Both name and value are empty strings, return the entire list + return list; + } } else { - return filterByMacro(list, filter); + // Invalid or empty filter, return the entire list + return list; } } From 2403376f4fba5714ed9011d550db8016bd37cc44 Mon Sep 17 00:00:00 2001 From: Omar Zarrouki Date: Mon, 25 Nov 2024 18:01:13 +0100 Subject: [PATCH 2/6] removing variables displays --- src/datasource/zabbix/zabbix.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/datasource/zabbix/zabbix.ts b/src/datasource/zabbix/zabbix.ts index 53da097ef..56c51ea76 100644 --- a/src/datasource/zabbix/zabbix.ts +++ b/src/datasource/zabbix/zabbix.ts @@ -345,8 +345,6 @@ export class Zabbix implements ZabbixConnector { ) { const allMacros = await this.getAllMacrosByGroup(groupFilter); const filteredMacros = filterByMQuery(allMacros, macroFilter); - console.log('Filtered Macros:', filteredMacros); - return filteredMacros; } From 7aa14d42b010931b9f26d167ff52d0bd3835ff20 Mon Sep 17 00:00:00 2001 From: ozarrouki Date: Thu, 5 Dec 2024 15:22:51 +0100 Subject: [PATCH 3/6] Update Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6314170b0..d989ed5f9 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ install: yarn install --pure-lockfile # Backend go install -v ./pkg/ - # GO111MODULE=off go get -u golang.org/x/lint/golint + # GO111MODULE=off go get -u golang.org/x/lint/golint deps-go: go install -v ./pkg/ From 9875db248d12e3864d17349357246866e0acf6c7 Mon Sep 17 00:00:00 2001 From: Omar Zarrouki Date: Thu, 5 Dec 2024 15:59:58 +0100 Subject: [PATCH 4/6] reverting changes and removing comments --- Makefile | 2 +- go.mod | 17 +++++++---------- go.sum | 16 ---------------- pkg/datasource/models.go | 3 --- src/datasource/zabbix/zabbix.ts | 6 ------ 5 files changed, 8 insertions(+), 36 deletions(-) diff --git a/Makefile b/Makefile index d989ed5f9..6314170b0 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ install: yarn install --pure-lockfile # Backend go install -v ./pkg/ - # GO111MODULE=off go get -u golang.org/x/lint/golint + # GO111MODULE=off go get -u golang.org/x/lint/golint deps-go: go install -v ./pkg/ diff --git a/go.mod b/go.mod index 9863ddbb0..880689b35 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,6 @@ module github.com/alexanderzobnin/grafana-zabbix -go 1.22.0 - -toolchain go1.23.3 +go 1.22.1 require ( github.com/bitly/go-simplejson v0.5.1 @@ -11,7 +9,7 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible github.com/prometheus/client_golang v1.20.5 github.com/stretchr/testify v1.9.0 - golang.org/x/net v0.31.0 + golang.org/x/net v0.30.0 gotest.tools v2.2.0+incompatible ) @@ -90,12 +88,11 @@ require ( go.opentelemetry.io/otel/trace v1.31.0 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect - golang.org/x/lint v0.0.0-20241112194109-818c5a804067 // indirect - golang.org/x/mod v0.22.0 // indirect - golang.org/x/sync v0.9.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/text v0.20.0 // indirect - golang.org/x/tools v0.27.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect diff --git a/go.sum b/go.sum index 85d59b9ab..1f1dc4dca 100644 --- a/go.sum +++ b/go.sum @@ -237,30 +237,21 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= -golang.org/x/lint v0.0.0-20241112194109-818c5a804067 h1:adDmSQyFTCiv19j015EGKJBoaa7ElV0Q1Wovb/4G7NA= -golang.org/x/lint v0.0.0-20241112194109-818c5a804067/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= -golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191020152052-9984515f0562/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -276,23 +267,16 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= -golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/datasource/models.go b/pkg/datasource/models.go index d066d3b84..6f3cc1b65 100644 --- a/pkg/datasource/models.go +++ b/pkg/datasource/models.go @@ -54,9 +54,6 @@ type QueryModel struct { Application QueryFilter `json:"application"` ItemTag QueryFilter `json:"itemTag"` Item QueryFilter `json:"item"` - UserMacro QueryFilter `json:"userMacro"` - - // Item ID mode ItemIDs string `json:"itemids,omitempty"` diff --git a/src/datasource/zabbix/zabbix.ts b/src/datasource/zabbix/zabbix.ts index 56c51ea76..fb6cba67b 100644 --- a/src/datasource/zabbix/zabbix.ts +++ b/src/datasource/zabbix/zabbix.ts @@ -377,21 +377,15 @@ export class Zabbix implements ZabbixConnector { ? { name: userMacroName || '', value: userMacroValue || '' } : null; - // console.log("macroFilter before getAllHosts: ", macroFilter); const hosts = await this.getAllHosts(groupFilter); if (macroFilter) { const macros = await this.getUMacrosVariable(groupFilter, macroFilter); - // console.log('Macros:', macros); - // console.log('Macro Filter:', macroFilter); - const filteredHosts = hosts.filter((host) => { const hostMacros = macros.filter((macro) => macro.hostid === host.hostid); - // console.log('Host Macros:', hostMacros); return filterByMQuery(hostMacros, macroFilter).length > 0; }); - console.log('Filtered Hosts:', filteredHosts); return findByFilter(filteredHosts, hostFilter); } From 0b57c66a3bab1eb92623b63240d32ec46d97de10 Mon Sep 17 00:00:00 2001 From: Omar Zarrouki Date: Thu, 5 Dec 2024 16:08:00 +0100 Subject: [PATCH 5/6] reverting Makefie --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6314170b0..85c06e18c 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ install: yarn install --pure-lockfile # Backend go install -v ./pkg/ - # GO111MODULE=off go get -u golang.org/x/lint/golint + GO111MODULE=off go get -u golang.org/x/lint/golint deps-go: go install -v ./pkg/ From 4fb58639051554e9a1f390b960cb45c5487dcbfd Mon Sep 17 00:00:00 2001 From: Omar Zarrouki Date: Tue, 10 Dec 2024 15:32:57 +0100 Subject: [PATCH 6/6] reverting changes on sh files --- debug-backend.sh | 2 +- devenv/zas-agent/run_zas_agent.sh | 2 +- docs/make-docs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/debug-backend.sh b/debug-backend.sh index 469b037ba..d419dab01 100644 --- a/debug-backend.sh +++ b/debug-backend.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash if [ "$1" == "-h" ]; then echo "Usage: ${BASH_SOURCE[0]} [plugin process name] [port]" exit diff --git a/devenv/zas-agent/run_zas_agent.sh b/devenv/zas-agent/run_zas_agent.sh index 3256f6678..cd2d9fca9 100644 --- a/devenv/zas-agent/run_zas_agent.sh +++ b/devenv/zas-agent/run_zas_agent.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/bin/bash # Run redis server first # cd /zas/redis-3.2.9/src/ diff --git a/docs/make-docs b/docs/make-docs index 34d470156..c88acd7ed 100644 --- a/docs/make-docs +++ b/docs/make-docs @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/sh # The source of this file is https://raw.githubusercontent.com/grafana/writers-toolkit/main/docs/make-docs. # # `make-docs` procedure changelog #