diff options
author | Vyacheslav Khaliev <vyacheslav.khaliev@zabbix.com> | 2022-10-07 12:41:35 +0300 |
---|---|---|
committer | Vyacheslav Khaliev <vyacheslav.khaliev@zabbix.com> | 2022-10-07 12:41:35 +0300 |
commit | dc119333f86f65a374fd6c4d957dd96a4dd42a4e (patch) | |
tree | 4b257689879966d297bef19707fc2bda480109ee | |
parent | 8ffaab423ec5f37fb0545a0dc2f972420e9d9389 (diff) |
.........T [ZBXNEXT-6844] reworked devices discovery in Cisco Meraki template
-rw-r--r-- | templates/net/meraki_http/README.md | 11 | ||||
-rw-r--r-- | templates/net/meraki_http/template_net_meraki_http.yaml | 327 |
2 files changed, 240 insertions, 98 deletions
diff --git a/templates/net/meraki_http/README.md b/templates/net/meraki_http/README.md index 18c03ed35d4..f76eb9bdb8d 100644 --- a/templates/net/meraki_http/README.md +++ b/templates/net/meraki_http/README.md @@ -33,6 +33,8 @@ No specific Zabbix configuration is required. |Name|Description|Default| |----|-----------|-------| |{$MERAKI.API.URL} |<p>Cisco Meraki Dashboard API URL. e.g api.meraki.com/api/v1</p> |`api.meraki.com/api/v1` | +|{$MERAKI.DEVICE.NAME.MATCHES} |<p>This macro is used in devices discovery. Can be overridden on the host or linked template level.</p> |`.+` | +|{$MERAKI.DEVICE.NAME.NOT_MATCHES} |<p>This macro is used in devices discovery. Can be overridden on the host or linked template level.</p> |`CHANGE_IF_NEEDED` | |{$MERAKI.HTTP_PROXY} |<p>HTTP proxy for API requests. You can specify it using the format [protocol://][username[:password]@]proxy.example.com[:port]. See documentation at https://www.zabbix.com/documentation/6.0/manual/config/items/itemtypes/http</p> |`` | |{$MERAKI.ORGANIZATION.NAME.MATCHES} |<p>This macro is used in organizations discovery. Can be overridden on the host or linked template level.</p> |`.+` | |{$MERAKI.ORGANIZATION.NAME.NOT_MATCHES} |<p>This macro is used in organizations discovery. Can be overridden on the host or linked template level.</p> |`CHANGE_IF_NEEDED` | @@ -46,18 +48,21 @@ There are no template links in this template. |Name|Description|Type|Key and additional info| |----|-----------|----|----| -|Organizations discovery |<p>-</p> |DEPENDENT |meraki.organization.discovery<p>**Filter**:</p> <p>- {#NAME} MATCHES_REGEX `{$MERAKI.ORGANIZATION.NAME.MATCHES}`</p><p>- {#NAME} NOT_MATCHES_REGEX `{$MERAKI.ORGANIZATION.NAME.NOT_MATCHES}`</p> | +|Devices discovery |<p>-</p> |DEPENDENT |meraki.devices.discovery<p>**Preprocessing**:</p><p>- JSONPATH: `$.devices`</p><p>**Filter**:</p> <p>- {#NAME} MATCHES_REGEX `{$MERAKI.DEVICE.NAME.MATCHES}`</p><p>- {#NAME} NOT_MATCHES_REGEX `{$MERAKI.DEVICE.NAME.NOT_MATCHES}`</p> | +|Organizations discovery |<p>-</p> |DEPENDENT |meraki.organization.discovery<p>**Preprocessing**:</p><p>- JSONPATH: `$.organizations`</p><p>**Filter**:</p> <p>- {#NAME} MATCHES_REGEX `{$MERAKI.ORGANIZATION.NAME.MATCHES}`</p><p>- {#NAME} NOT_MATCHES_REGEX `{$MERAKI.ORGANIZATION.NAME.NOT_MATCHES}`</p> | ## Items collected |Group|Name|Description|Type|Key and additional info| |-----|----|-----------|----|---------------------| -|Zabbix raw items |Meraki: Get list of the organizations |<p>Item for gathering all the organizations from Meraki API"</p> |HTTP_AGENT |meraki.get.organizations | +|Zabbix raw items |Meraki: Get data |<p>Item for gathering all the organizations and devices from Meraki API"</p> |SCRIPT |meraki.get.data<p>**Expression**:</p>`The text is too long. Please see the template.` | +|Zabbix raw items |Meraki: Data item errors |<p>Item for gathering all the data item errors.</p> |DEPENDENT |meraki.get.data.errors<p>**Preprocessing**:</p><p>- JSONPATH: `$.error`</p><p>- DISCARD_UNCHANGED_HEARTBEAT: `1h`</p> | ## Triggers |Name|Description|Expression|Severity|Dependencies and additional info| |----|-----------|----|----|----| +|Meraki: There are errors in 'Get data' metric |<p>-</p> |`length(last(/Cisco Meraki dashboard by HTTP/meraki.get.data.errors))>0` |WARNING | | ## Feedback @@ -97,7 +102,6 @@ There are no template links in this template. |Name|Description|Type|Key and additional info| |----|-----------|----|----| -|Devices discovery |<p>-</p> |DEPENDENT |meraki.devices.discovery | |Uplinks discovery |<p>-</p> |DEPENDENT |meraki.uplinks.discovery<p>**Preprocessing**:</p><p>- JSONPATH: `$.uplinks`</p> | |VPN stats discovery |<p>-</p> |DEPENDENT |meraki.vpn.stats.discovery<p>**Preprocessing**:</p><p>- JSONPATH: `$.vpnStats`</p> | @@ -130,7 +134,6 @@ There are no template links in this template. |Zabbix raw items |Meraki: Networks item errors |<p>Item for gathering all the networks item errors.</p> |DEPENDENT |meraki.get.networks.errors<p>**Preprocessing**:</p><p>- JSONPATH: `$.error`</p><p>- DISCARD_UNCHANGED_HEARTBEAT: `1h`</p> | |Zabbix raw items |Meraki: Get list of the vpn stats |<p>Item for gathering all the vpn stats of the organization.</p> |SCRIPT |meraki.get.vpn.stats<p>**Expression**:</p>`The text is too long. Please see the template.` | |Zabbix raw items |Meraki: VPN item errors |<p>Item for gathering all the vpn item errors.</p> |DEPENDENT |meraki.get.vpn.stats.errors<p>**Preprocessing**:</p><p>- JSONPATH: `$.error`</p><p>- DISCARD_UNCHANGED_HEARTBEAT: `1h`</p> | -|Zabbix raw items |Meraki: Get list of the devices |<p>Item for gathering all the devices of organization from Meraki API.</p> |HTTP_AGENT |meraki.get.devices | |Zabbix raw items |Meraki: Get list of configuration changes |<p>Item for viewing the Change Log for your organization.\nGathering once per 20m by default.</p> |HTTP_AGENT |meraki.get.configuration.changes<p>**Preprocessing**:</p><p>- DISCARD_UNCHANGED_HEARTBEAT: `2h`</p> | |Zabbix raw items |Meraki: Get list of adaptive policy aggregate statistics |<p>Item for adaptive policy aggregate statistics for an organization.</p> |HTTP_AGENT |meraki.get.adaptive.policy | |Zabbix raw items |Meraki: Get licenses info |<p>Return an overview of the license state for an organization.</p> |HTTP_AGENT |meraki.get.licenses | diff --git a/templates/net/meraki_http/template_net_meraki_http.yaml b/templates/net/meraki_http/template_net_meraki_http.yaml index 5b7f34d79a6..dac89d08b12 100644 --- a/templates/net/meraki_http/template_net_meraki_http.yaml +++ b/templates/net/meraki_http/template_net_meraki_http.yaml @@ -1,6 +1,6 @@ zabbix_export: version: '6.0' - date: '2022-10-05T15:00:07Z' + date: '2022-10-07T09:28:00Z' groups: - uuid: a571c0d144b14fd4a87a9d9b2aa9fcd6 @@ -26,28 +26,235 @@ zabbix_export: name: 'Templates/Network devices' items: - - uuid: d1a5f3c79a604bae98c314d2aed64ff4 - name: 'Meraki: Get list of the organizations' - type: HTTP_AGENT - key: meraki.get.organizations + uuid: aa00e906cf56488db52554a3acbe148e + name: 'Meraki: Get data' + type: SCRIPT + key: meraki.get.data delay: 1h history: '0' trends: '0' value_type: TEXT - description: 'Item for gathering all the organizations from Meraki API"' - timeout: 30s - url: 'https://{$MERAKI.API.URL}/organizations' - http_proxy: '{$MERAKI.HTTP_PROXY}' - headers: + params: | + var params = JSON.parse(value); + + var request = new HttpRequest(); + + request.addHeader('X-Cisco-Meraki-API-Key:' + params.token); + + var response, + error_msg = '', + organizations = [], + devices = []; + + function getHttpData(url) { + response = request.get(url); + Zabbix.log(4, '[ Meraki API ] [ ' + url + ' ] Received response with status code ' + request.getStatus() + ': ' + response); + + if (response !== null) { + try { + response = JSON.parse(response); + } + catch (error) { + throw 'Failed to parse response received from Meraki API. Check debug log for more information.'; + } + } + + if (request.getStatus() !== 200) { + if (response.errors) { + throw response.errors.join(', '); + } else { + throw 'Failed to receive data: invalid response status code.'; + } + } + + if (typeof (response) !== 'object' || response === null) { + throw 'Cannot process response data: received data is not an object.'; + } + + return response; + }; + + try { + + if (params.token === '{' + '$MERAKI.TOKEN}') { + throw 'Please change {' + '$MERAKI.TOKEN} macro with the proper value.'; + } + + if (params.url.indexOf('http://') === -1 && params.url.indexOf('https://') === -1) { + params.url = 'https://' + params.url; + } + + if (!params.url.endsWith('/')) { + params.url += '/'; + } + + if (typeof params.httpproxy !== 'undefined' && params.httpproxy !== '') { + request.setProxy(params.httpproxy); + } + + organizations = getHttpData(params.url + '/organizations'); + + if (Array.isArray(organizations) && organizations.length > 0) { + for (i in organizations) { + if ('id' in organizations[i]) { + organization_devices = getHttpData(params.url + '/organizations/' + encodeURIComponent(organizations[i].id) + '/devices'); + + if (Array.isArray(organization_devices) && organization_devices.length > 0) { + for (j in organization_devices) { + organization_devices[j].organizationId = organizations[i].id; + + devices.push(organization_devices[j]); + } + } + } + } + } + + } catch (error) { + error_msg = error; + }; + + return JSON.stringify({ + 'organizations': organizations, + 'devices': devices, + 'error': error_msg.toString() + }); + description: 'Item for gathering all the organizations and devices from Meraki API"' + timeout: 60s + parameters: - - name: X-Cisco-Meraki-API-Key + name: token value: '{$MERAKI.TOKEN}' + - + name: url + value: '{$MERAKI.API.URL}' + - + name: httpproxy + value: '{$MERAKI.HTTP_PROXY}' tags: - tag: component value: raw + - + uuid: 6fdd764d820341e7bd2a24f42802c58a + name: 'Meraki: Data item errors' + type: DEPENDENT + key: meraki.get.data.errors + delay: '0' + history: 7d + trends: '0' + value_type: TEXT + description: 'Item for gathering all the data item errors.' + preprocessing: + - + type: JSONPATH + parameters: + - $.error + - + type: DISCARD_UNCHANGED_HEARTBEAT + parameters: + - 1h + master_item: + key: meraki.get.data + tags: + - + tag: component + value: error + triggers: + - + uuid: 2bf9355f548e4e9b9b8581fb43f175fe + expression: 'length(last(/Cisco Meraki dashboard by HTTP/meraki.get.data.errors))>0' + name: 'Meraki: There are errors in ''Get data'' metric' + priority: WARNING + tags: + - + tag: scope + value: availability discovery_rules: - + uuid: 6488b49e692e4fe8b6a1c57f56b6ba7d + name: 'Devices discovery' + type: DEPENDENT + key: meraki.devices.discovery + delay: '0' + filter: + conditions: + - + macro: '{#NAME}' + value: '{$MERAKI.DEVICE.NAME.MATCHES}' + formulaid: A + - + macro: '{#NAME}' + value: '{$MERAKI.DEVICE.NAME.NOT_MATCHES}' + operator: NOT_MATCHES_REGEX + formulaid: B + host_prototypes: + - + uuid: 86d599f384d94b368508a170911213ec + host: '{#NAME}' + name: '[{#PRODUCT_TYPE}] {#NAME}' + group_links: + - + group: + name: Templates/Applications + templates: + - + name: 'Cisco Meraki device by HTTP' + macros: + - + macro: '{$MAC}' + value: '{#MAC}' + description: 'MAC address of the device.' + - + macro: '{$NETWORK.ID}' + value: '{#NETWORK.ID}' + description: 'Network ID of the device.' + - + macro: '{$ORGANIZATION_ID}' + value: '{#ORGANIZATION_ID}' + description: 'Organization ID of the device.' + - + macro: '{$SERIAL}' + value: '{#SERIAL}' + description: 'Serial number of the device.' + tags: + - + tag: model + value: '{#MODEL}' + - + tag: serial-number + value: '{#SERIAL}' + master_item: + key: meraki.get.data + timeout: 30s + lld_macro_paths: + - + lld_macro: '{#MAC}' + path: $.mac + - + lld_macro: '{#MODEL}' + path: $.model + - + lld_macro: '{#NAME}' + path: $.name + - + lld_macro: '{#NETWORK.ID}' + path: $.networkId + - + lld_macro: '{#ORGANIZATION_ID}' + path: $.organizationId + - + lld_macro: '{#PRODUCT_TYPE}' + path: $.productType + - + lld_macro: '{#SERIAL}' + path: $.serial + preprocessing: + - + type: JSONPATH + parameters: + - $.devices + - uuid: 30f38d19659646009ca436d48f9598b0 name: 'Organizations discovery' type: DEPENDENT @@ -85,7 +292,7 @@ zabbix_export: value: '{#ID}' description: 'ID of the organization.' master_item: - key: meraki.get.organizations + key: meraki.get.data lld_macro_paths: - lld_macro: '{#ID}' @@ -99,6 +306,11 @@ zabbix_export: - lld_macro: '{#URL}' path: $.url + preprocessing: + - + type: JSONPATH + parameters: + - $.organizations tags: - tag: class @@ -112,6 +324,14 @@ zabbix_export: value: api.meraki.com/api/v1 description: 'Cisco Meraki Dashboard API URL. e.g api.meraki.com/api/v1' - + macro: '{$MERAKI.DEVICE.NAME.MATCHES}' + value: .+ + description: 'This macro is used in devices discovery. Can be overridden on the host or linked template level.' + - + macro: '{$MERAKI.DEVICE.NAME.NOT_MATCHES}' + value: CHANGE_IF_NEEDED + description: 'This macro is used in devices discovery. Can be overridden on the host or linked template level.' + - macro: '{$MERAKI.HTTP_PROXY}' description: 'HTTP proxy for API requests. You can specify it using the format [protocol://][username[:password]@]proxy.example.com[:port]. See documentation at https://www.zabbix.com/documentation/6.0/manual/config/items/itemtypes/http' - @@ -305,7 +525,7 @@ zabbix_export: value: '{$MERAKI.API.URL}' - name: organizationId - value: '{$ID}' + value: '{$ORGANIZATION_ID}' - name: httpproxy value: '{$MERAKI.HTTP_PROXY}' @@ -603,27 +823,6 @@ zabbix_export: tag: scope value: security - - uuid: 9c8a5029accf46ecb247d004023a85e6 - name: 'Meraki: Get list of the devices' - type: HTTP_AGENT - key: meraki.get.devices - delay: 3m - history: '0' - trends: '0' - value_type: TEXT - description: 'Item for gathering all the devices of organization from Meraki API.' - timeout: 60s - url: 'https://{$MERAKI.API.URL}/organizations/{$ID}/devices' - http_proxy: '{$MERAKI.HTTP_PROXY}' - headers: - - - name: X-Cisco-Meraki-API-Key - value: '{$MERAKI.TOKEN}' - tags: - - - tag: component - value: raw - - uuid: 3306da0ec0d749829db2f5f42e4e7876 name: 'Meraki: Get licenses info' type: HTTP_AGENT @@ -1163,66 +1362,6 @@ zabbix_export: value: policy discovery_rules: - - uuid: 5c251303ef8849e49130726a3b7a7c1d - name: 'Devices discovery' - type: DEPENDENT - key: meraki.devices.discovery - delay: '0' - host_prototypes: - - - uuid: bca6b2016f80470fb303760430e3a96a - host: '{#NAME}' - name: '[{#PRODUCT_TYPE}] {#NAME}' - group_links: - - - group: - name: Templates/Applications - templates: - - - name: 'Cisco Meraki device by HTTP' - macros: - - - macro: '{$MAC}' - value: '{#MAC}' - description: 'MAC address of the device.' - - - macro: '{$NETWORK.ID}' - value: '{#NETWORK.ID}' - description: 'Network ID of the device.' - - - macro: '{$SERIAL}' - value: '{#SERIAL}' - description: 'Serial number of the device.' - tags: - - - tag: model - value: '{#MODEL}' - - - tag: serial-number - value: '{#SERIAL}' - master_item: - key: meraki.get.devices - timeout: 30s - lld_macro_paths: - - - lld_macro: '{#MAC}' - path: $.mac - - - lld_macro: '{#MODEL}' - path: $.model - - - lld_macro: '{#NAME}' - path: $.name - - - lld_macro: '{#NETWORK.ID}' - path: $.networkId - - - lld_macro: '{#PRODUCT_TYPE}' - path: $.productType - - - lld_macro: '{#SERIAL}' - path: $.serial - - uuid: 03d6aeb2bc3d473b9aab87acd0e08f8c name: 'Uplinks discovery' type: DEPENDENT |