
Zabbix Instance
|
In the first skill builder in this series, we offered step-by-step instructions for setting up RESTmon.
In this skill builder, the second of this two-part series, we’ll offer instructions for using a deployed RESTmon instance to feed information into DX Operational Intelligence.
For a tutorial video you can refer to this course in the Broadcom Enterprise Software Academy.
Prerequisites
1. Zabbix instance deployed
We will use the Zabbix instance (zabbix.broadcom.com) to create a schema using a live problem.
For our example, we will try to use RESTmon’s PUSH schema to pass information from Zabbix to DX Operational Intelligence.
|
Step 1: Define a Media Type
This step will allow us to create the media type that will be used for RESTmon.
Media types are the delivery channels used for sending notifications and alerts from Zabbix. For our example, we will be using webhooks.
Let us create a media type for RESTmon.
Step 1.1 Navigate to Administration > Media types

Click “Create media type”
Step 1.1.1 Define the Name and Type

For name, use “Message for Restmon”. For type, use “ Webhook”.

Define the webhook variables as attributes key and value pairs (use the existing value as is). The macros used are from the Zabbix official documentation.
Points to Remember
restmon_endpoint
|
In this case, it is the endpoint URL I am using.
http://restmon.demo:30125/restmon/api/v1/logs?profileName=zabbix&schemaName=zabbix
|
restmon_password
|
The configured password
|
restmon_username
|
The username configured to access the swagger-ui
|

Define the script by clicking the edit button. (You can refer to more Webhook Script examples here.)
These scripts are based on plain JavaScript.
try { // variables declared var params = JSON.parse(value), //JSONObject parse request = new CurlHttpRequest(), data, response;
// Information about the event data = { event_id: params.event_id, event_name: params.event_name, event_severity: params.event_severity, host_name: params.host_name, host_ip: params.host_ip, event_status: params.event_status };
data = JSON.stringify(data);
Zabbix.Log(4, '[ DX-RESTmon Webhook ] Sending request: ' + params.restmon_endpoint + '\n' + data);
request.AddHeader('Content-Type: application/json') request.AddHeader('Authorization: Basic ' + btoa(params.restmon_username + ':' + params.restmon_password)); response = request.Post(params.restmon_endpoint, data);
Zabbix.Log(4, '[ DX-RESTmon Webhook ] Received status code ' + request.Status() + '\n');
if (request.Status() != 200) { throw request.Status(); } return 'OK'; } catch (error) { Zabbix.Log(4, '[ DX-RESTmon Webhook ] DX-RESTmon notification failed: ' + error); throw 'DX-RESTmon notification failed: ' + error; }
|
Step 1.1.2 Define the Message Template
You can learn more about message templates in the Zabbix documentation.

Step 1.1.3 Message Options
Use the values as shown in the image below. The default retry attempts are 3. You can change it to whatever suits your case best.

Step 1.1.4 Test Media Type

If you test this Media type and if the RESTmon configuration is correct, you will see a log message in the restmon.log.
2021-10-16 09:42:24,957 [http-nio-8080-exec-8] DEBUG ProfileHandler:1611 - zabbix~~zabbix: Received payload - { "event_id": "{EVENT.ID}", "event_name": "{EVENT.NAME}", "event_severity": "{EVENT.SEVERITY}", "host_name": "{HOST.NAME}", "host_ip": "{HOST.IP}", "event_status": "{EVENT.STATUS}" }
|
In a real-time scenario, you should receive a message like that below.
{ "event_id": "346", "event_name": "Zabbix agent is not available (for 3m)", "event_severity": "Average", "host_name": "lvndev011524.bpc.broadcom.net", "host_ip": "10.74.146.11", "event_status": "PROBLEM" }
|
Message Received at RESTmon
We will use the values from this JSON response. For example, we can refer the “event_name” from the example above using $['event_name']. Similarly, we can assign “host_name” using $[`host_name`].
Once the media type has been defined and configured, go to Administration > Users and assign the webhook media to the existing user. Ideally, the recommendation is for a dedicated user that represents the webhook.


Configuring: Alert Actions
Actions determine which notifications should be sent via the webhook (more details are available in the Zabbix documentation). They can be defined in response to events of all supported types. In our case, we will be using Trigger Actions.
Adding Action

Navigate to Actions > Trigger actions and click “create actions.”

Define Name
Use any meaningful name that you want to give to this action.
Define Conditions
Conditions are set when configuring an action. (For more information, refer to official Zabbix documentation.)

Finally, the action will appear like the image below.

Add Operations
In this step, you can select the “Send Only to” option as well. Depending on your requirements, you can either can select a specific media type or choose all.



RESTmon schema guide
RESTmon has two building blocks:
- Profile. Every product that RESTmon works on has its dedicated profile. A profile is a JSON document that has the connection information and polling details.
- Schema. Schema is a JSON document that contains the API details and parsing logic that is written in JavaScript. It has a defined basic structure.
Adding a Profile
Let’s add the profile for the Zabbix product.
Step 1: Adding Profile: Zabbix
{ "profile": { "name": "zabbix", "active": "yes", "schema": "zabbix", "streaming": "yes", "inventory_topology_fullsync_interval_mins": "1440", "topology_ttl_mins": "2880", "polling_interval_secs": 1, "batch_size": 9000, "batch_wait_time_milli": 3000 }, "monitored_groups": { "Events": "yes", "Topology": "yes" } }
|

Step 1.1: Response
{ "Status": "profile is added with profileName zabbix and schemaName zabbix" }
|

Step 1.2: Check the Profile Has Been Added by Listing

The response will show the profile added.

Step 2: Add/Upload a Schema
Once the profile has been, it is time add a schema. You can add a schema via the SwaggerUI or manually create a file in the config directory.
Step 2.1 Upload Schema Template
This is the foundation step, which we will keep adding to.

If the upload is successful, it will create a file “zabbix_schema.json” in the schema folder.
Read more about definition here.
Step 2.2: Response of Upload

Look in the mounted directory. The file contents will also confirm settings.
> cat zabbix_schema.json
{ "zabbix": { "definition": { "resource_category": "", "auth": "", "uploadedBy": "TENANT", "updatedBy": "", "version": "2.1", "xml_ns": "", "name": "zabbix", "type": "" }, "urls": [], "topology": [], "alarms": [] } }
|
Step 3: Topology
To create a service and use the AIOps platform’s analytics capabilities, the entities must be ingested to DX Operational Intelligence. The collection of these entities and the relationship between them is represented as a graph (TAS model) for the given monitored product.
Let’s start by adding an empty block in topology (Step 2.1).
The contents should be similar to the following.
{ "xml_ns": "", "url": "", "isDeltaTopology": "true", "group": "Topology", "layer": "CUSTOM", "attributes": { "oi": { } } }
|
Components
- isDeltaTopology. Enables calculation of only delta topology.
- group. Group name to be monitored. Please refer to the profile definition we enabled above (Topology, Events).
- layer. Here, the association has to be applied can be CUSTOM, INFRASTRUCTURE, INFRASTRUCTURE_UIM
To correlate the ingested third-party data with the Broadcom products, you must set the normalized attributes and the correlation attributes at the tenant level in the metadata vertex for a tenant.
Next, it is time to fill in some attributes.
“oi”—DX Operational Intelligence Attributes
For topology mapping you need to define the following attributes.
ci_unique_id
|
Unique element being monitored
|
$[‘host_name’]
|
type
|
You can find more in the official documentation but to name a few:
EXTERNAL, BUSINESSTRANSACTION, EJB, EJBCLIENT, DATABASE, HOST etc
|
HOST
|
product
|
Indicates the product name—in our case we will use a static value: “Zabbix Broadcom”
|
Zabbix Broadcom
|
name
|
Name of the topology entity
|
$[‘host_name’]
|
hostname
|
Name of the host where the entity is deployed
|
$[‘host_name’]
|
ipAddresses
|
IP addreses that is linked to the entity
|
$[‘host_ip’]
|
Referring to the sample JSON response we got in the RESTMon (refer to sample message above), we will use the JSON parser reference variables to fill in the values.
"oi": { "ci_unique_id": "$['host_name']", "type": "HOST", "product": "Zabbix Broadcom", "name": "$['host_name']", "hostname": "$['host_name']", "Display Name": "$['host_name']", "ipAddresses": "$['host_ip']" }
|
You can use the PUT API from Swagger to update these schemas.
POST /restmon/api/v1/schema/{schemaName}
|
{ "zabbix": { "definition": { "resource_category": "Zabbix Product Streaming schema.", "auth": "", "uploadedBy": "TENANT", "updatedBy": "Saurabh Sharma", "version": "2.1", "xml_ns": "", "name": "zabbix", "type": "" }, "urls": [], "topology": [ { "xml_ns": "", "url": "", "isDeltaTopology": "true", "group": "Topology", "layer": "CUSTOM", "attributes": { "oi": { "ci_unique_id": "$['host_name']", "type": "HOST", "product": "Zabbix Broadcom", "name": "$['host_name']", "hostname": "$['host_name']", "Display Name": "$['host_name']", "ipAddresses": "$['host_ip']" } } } ], "alarms": [] } }
|
If you log into DX Operational Intelligence and go to Monitored Inventory you can see the entity ingested.

In the RESTmon logs, you will notice a log entry similar to the message below.
2021-10-17 14:50:42,259 [pool-3-thread-10] DEBUG SendToTAS:755 - body: "graph": { "vertices": [ { "externalId": "CUSTOM:6D85F3FC-2EF8-4471-8804-BE3B74D6785C$$Zabbix Broadcom$$lvndev011524.bpc.broadcom.net", "attributes": { "ci_unique_id": " XXXXXXXXX.broadcom.net ", "hostname": " XXXXXXXXX.broadcom.net ", "hostNames": [ "XXXXXXXXX.broadcom.net" ], "type": "HOST", "product": "Zabbix Broadcom", "name": " XXXXXXXXX.broadcom.net ", "Display Name": " XXXXXXXXX.broadcom.net ", "ipAddresses": [ "10.74.146.11" ] }, "startTime": 1634396921477, "endTime": 1634655042258 },
|
The next step is to add correlation to the topology block.
You can attain a rule-based edge creation by defining the correlation metadata about the different DX OI monitored products.
There are two types of correlation that are available
- Compaction
- Association
Why do we need it?
It is useful when two different vertices from two different sources depict the same object. Refer to the original example mentioned in the TechDocs. [link needs updating]
{ "xml_ns": "", "url": "", "isDeltaTopology": "true", "group": "Topology", "layer": "CONNECTOR_METADATA", "attributes": { "oi": { "ci_unique_id": "Zabbix_HOST", "name": "Zabbix Compaction Rule", "type": "SERVICE_UI_CONFIG", "compactionRules": [ { "sourceTasVertices": { "attributeFilters": [ { "attributeName": "product", "attributeValues": [ "Zabbix Broadcom " ], "operator": "IN" }, { "attributeName": "type", "attributeValues": [ "HOST" ], "operator": "IN" } ], "layer": "CUSTOM" }, "matchingAttributeNames": [ "ipAddresses", "macAddresses", "hostname" ], "matchingAttributeTypes": [ "IP_ADDRESS", "MAC_ADDRESS", "ACN_HOST" ] } ] } } }
|
Key Points
ci_unique_id
|
Unique identifier for the defined rule
|
layer
|
Indicates the TAS layer to which the metadata is to be ingested – CONNECTOR_METADATA
|
name
|
Description about the rule
|
type
|
Type of the TAS vertex – SERVICE_UI_CONFIG
|
compactionRules
|
Array of rules
|
sourceTasVertices
|
Vertices on which compaction will be applied
|
attributeFilters
|
An array of possible filters. In our case we use two:
{ "attributeName": "product", "attributeValues": [ "Zabbix Broadcom " ], "operator": "IN" },
and
{ "attributeName": "type", "attributeValues": [ "HOST" ], "operator": "IN" }
attributeName: `type`, `product`
attributeValues: The possible values
operator: How to compare
|
layer
|
For RESTmon this value has to be CUSTOM
|
matchingAttributeTypes |
Which attributes can be used for comparing with this attribute in this product.
|
Time to add an empty alarm section to the Schema.
Step 4: Alarms
Read more about alarms in the official documentation.
{ "xml_ns": "", "url": "", "group": "", "attributes": { "oi": { "status": "Alarm Status can be new, updated or closed", "timestamp": "Alarm timestamp", "host": "Hostname to attach Alarm too", "alarmType": "Alarm Type name", "product": "", "product_version": "", "summary": "", "severity": "", "severity_conversion": "", "metric_name": "", "metric_type": "", "configuration_item": "", "configuration_item_type": "", "ci_unique_id": "", "message": "", "alarm_unique_id": "" } } }
|
group
|
Replace with a Group name to enable or disable collection using profile in RESTmon.json
|
alarmType
|
Type of alarm. It is monitoring a host so - `Infra`
|
alarm_unique_id
|
Unique value identifying the Alarm
|
product
|
Zabbix Broadcom
|
product_version
|
Version of the product – 5.0
|
summary
|
Information about the alarm - $[‘event_name’]
|
severity
|
It is used by severity conversion
|
severity_conversion
|
Mapping based on severity level
|
metric_name
|
Not used
|
metric_type
|
Not used
|
configuration_item
|
CI of the entity against which alarm is issued—Not Used
|
configuration_item_type
|
Type of CI—Not Used
|
host
|
Hostname = $[‘host_name’]
|
message
|
Content of alarm = $[‘event_name’]
|
attributes
|
"attributes": { "oi": { "alarmType": "Infra", "alarm_unique_id": "$['event_id']", "ci_unique_id": "$['host_name']", "configuration_item": "", "configuration_item_type": "", "host": "$['host_name']", "message": "$['event_name']", "metric_name": "", "metric_type": "", "product": "Zabbix Broadcom", "product_version": "5.0", "severity": "$['event_severity']", "severity_conversion": "Disaster:Critical,High:Major,Average:Minor,Default:Information", "status": "#(function() {var data=[]; if(root.event_status=='RESOLVED') { data.push('closed');} else { data.push('new');} return data;})();", "summary": "$['event_name']", "timestamp": "%timestamp" } }
|
Status Field
The payload comes as we had defined in the script added to the media type.
response = request.Post(params.restmon_endpoint, data);
|
To define the status, we will employ Java Script to evaluate the payload and assign it as “new” or “closed.”
If you are new to writing this script, you can use any browser (console) to evaluate the payload and return the value as desired.
For our case, I am using a Firefox browser and will simulate the payload as a variable before using the final script.

Let’s define a function “fn()” in the console, which can be reached by using the web developer tool.

We will refer the log as it comes in to RESTmon.
2021-10-18 07:14:37,248 [http-nio-8080-exec-10] DEBUG ProfileHandler:1611 - zabbix~~zabbix: Received payload - {"event_id":"417","event_name":"Zabbix server: Utilization of discoverer processes over 75%","event_severity":"High","host_name":"XXXXXXX. broadcom.net","host_ip":"10.74.146.11","event_status":"RESOLVED"}
|
The payload is formatted as indicated below.
{ "event_id": "417", "event_name": "Zabbix server: Utilization of discoverer processes over 75%", "event_severity": "High", "host_name": "XXXXXXX. broadcom.net", "host_ip": "10.74.146.11", "event_status": "RESOLVED" }
|
Based on the event_status in the data, we will define our script.
Script
Step 1: Define function.
Step 2: Define local data variable.
var i = ‘{ "event_id": "417", "event_name": "Zabbix server: Utilization of discoverer processes over 75%", "event_severity": "High", "host_name": "XXXXXXX. broadcom.net", "host_ip": "10.74.146.11", "event_status": "RESOLVED" }’;
|
Step 3: Parse into a JSON object.
Step 4: Define a local variable to hold the result.
Step 5: Do a conditional check.

if (r.event_status == ‘RESOLVED’) { d.push(‘closed’); } else { d.push(‘new); } return d;
|
Close the function.
You can call this function from the console by invoking “fn();” and it should return the variable “d” which you can check.

You can also use console.log to check the status on the console itself while evaluating.
Change the values to see both “closed” and “new” status.
If required, you can also use JJS to do the same.

Refer to Parsing methods for more details.
Finally, the status field is updated as indicated below.
"status": "#(function() { var data=[]; if(root.event_status=='RESOLVED') { data.push('closed'); } else { data.push('new'); } return data; }) ();" |
This completes your schema. Next, upload and restart the pod or deactivate/activate the schema to let RESTmon start processing it.
Complete Schema
{ "zabbix": { "definition": { "resource_category": "", "auth": "", "uploadedBy": "TENANT", "updatedBy": "", "version": "2.1", "xml_ns": "", "name": "zabbix", "type": "" }, "urls": [], "topology": [ { "xml_ns": "", "url": "", "isDeltaTopology": "true", "group": "Topology", "layer": "CUSTOM", "attributes": { "oi": { "ci_unique_id": "$['host_name']", "type": "HOST", "product": "Zabbix Broadcom", "name": "$['host_name']", "hostname": "$['host_name']", "Display Name": "$['host_name']", "ipAddresses": "$['host_ip']" } }, "fieldId": "AB822A2CE81F4FA0BAB2AD1F802A2D57" }, { "xml_ns": "", "url": "", "isDeltaTopology": "true", "group": "Topology", "layer": "CONNECTOR_METADATA", "attributes": { "oi": { "ci_unique_id": "Zabbix_HOST", "name": "Zabbix Compaction Rule", "type": "SERVICE_UI_CONFIG", "compactionRules": [ { "sourceTasVertices": { "attributeFilters": [ { "attributeName": "product", "attributeValues": [ "Zabbix Broadcom" ], "operator": "IN" }, { "attributeName": "type", "attributeValues": [ "HOST" ], "operator": "IN" } ], "layer": "CUSTOM" }, "matchingAttributeNames": [ "ipAddresses", "macAddresses", "hostname" ], "matchingAttributeTypes": [ "IP_ADDRESS", "MAC_ADDRESS", "ACN_HOST" ] } ] } }, "fieldId": "C92557D0FD844CB8B40D5386DA7FE4D0" } ], "alarms": [ { "xml_ns": "", "url": "", "group": "Events", "attributes": { "oi": { "status": "#(function() {var data=[]; if(root.event_status=='RESOLVED') { data.push('closed');} else { data.push('new');} return data;})();", "timestamp": "%timestamp", "host": "$['host_name']", "alarmType": "Infra", "product": "Zabbix Broadcom", "product_version": "5.0", "summary": "$['event_name']", "severity": "$['event_severity']", "severity_conversion": "Disaster:Critical,High:Major,Average:Minor,Default:Information", "metric_name": "", "metric_type": "", "configuration_item": "", "configuration_item_type": "", "ci_unique_id": "$['host_name']", "message": "$['event_name']", "alarm_unique_id": "$['event_id']" } }, "fieldId": "5A345F279C4E4BE68AAEED224AB4A9AE" } ], "inventory": [], "metrics": [], "calculated_methods": [], "calculated_metrics": [], "groups": [], "change_events": [] } }
|
If the alarm is processed successfully, you will see a log similar to that below.
{ "documents" : [ { "header" : { "tenant_id" : "6XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "product_id" : "ao", "doc_type_id" : "itoa_alarms_custom", "doc_type_version" : "1", "unique_id" : "$['alarm_unique_id']" }, "body" : [ { "timestamp" : "2021-10-16T15:08:44+0000", "startTime" : "2021-10-16T15:08:44+0000", "severity" : "major", "host" : "XXXXXXXXXXXXXXXX.broadcom.net", "alarmType" : "Infra", "product" : "Zabbix Broadcom", "product_version" : "5.0", "summary" : "Zabbix server: Utilization of discoverer processes over 75%", "ci_unique_id" : "XXXXXXXXXXXXXXXXX.broadcom.net", "message" : "Zabbix server: Utilization of discoverer processes over 75%", "alarm_unique_id" : "56a73c0e2e0184c4b984e9bda701dca9", "status" : "new" } ] } ] }
|
In DX Operational Intelligence, you can log in and see any alarms pushed.


Polling Schema
You can also build a polling schema in the same way you created the streaming schema.
There are some variations that you must be cautious about, which are covered briefly in the sections below.
Things You Must Know
- Zabbix API and how it works. You can use Postman, Insomnia, or any other tool to invoke these URLs and see them in action before you embed them in the schema.
- How HTTP POST, GET, and PUT methods work and pass payloads.
- Using JSON path parser to build your expressions.
Polling data from third-party applications using REST APIs.
In general, the Zabbix API allows you to retrieve and modify the configuration of Zabbix and provides access to historical data. (Read more on this in the Zabbix documentation [v4.0])
Let’s try and define a poll schema for Zabbix. (Refer to the link)
Profile: zabbixbroadcom
Attribute
|
Description
|
name
|
zabbixbroadcom
|
active
|
No (initial value)
|
schema
|
zabbixbroadcom
|
polling_interval_secs
|
We will use 2 minutes (120)
|
Please compare the difference between this view and the streaming profiles defined in Step 1.
Add the section “restapiconnectdetails” which is a mandatory section for a polling schema.
Attribute
|
Description
|
type
|
https
|
hostname
|
zabbix.broadcom.com
|
username
|
Saurabh
|
password
|
Password value for the username
|
"restapiconnectdetails" : { "type" : "http", You can use http or https here "hostname" : "zabbix.broadcom.com", The machine you are trying to connect that Hosts the zabbix instance "port" : "80", The port it is listening on "authentication" : "none", Refer to link "username" : "Saurabh", "password" : "Password", "realmdomain" : "", "token" : "", "httptimeout" : "30000", "checkcert" : "no" }
|
In my example, the profile looks like the image below.
{ "profile" : { "name" : "zabbixbroadcom", You can choose any name "active" : "no", Will activate once I define the schema and other values "schema" : "zabbixbroadcom", Name of the schema "polling_interval_secs" : "120", Interval for poll "inventory_topology_fullsync_interval_mins" : "1440", "topology_ttl_mins" : "2880" },
"restapiconnectdetails" : { "type" : "http", "hostname" : "zabbix.broadcom.net", "port" : "80", "authentication" : "none", "username" : "<Admin>", "password" : "<Password>", "realmdomain" : "", "token" : "", "httptimeout" : "30000", "checkcert" : "no" }, "monitored_groups" : { "Events" : "yes", "Topology" : "yes", “Items”: “yes” } }
|
With the definition in place, let’s create the schema or UPLOAD using the Swagger UI.
Schema: zaabixbroadcom_schema.json
Next, let’s work out the schema.
It has a section “urls”. While we did not need this in the streaming area, this is required to pull information from Zabbix.
Template “definition”
{ "zabbixbroadcom": { "urls": [], "alarms": [], "calculated_methods": [], "calculated_metrics": [], "definition": { "auth": "none", "name": "zabbixbroadcom", "resource_category": null, "type": "https", "updatedBy": "Saurabh Sharma", "uploadedBy": "TENANT", "version": "21.3.1", "xml_ns": "" }, "groups": [], "inventory": [], "metrics": [], "topology": [] } }
|
URLs define the REST endpoint, which you can specify to have invoked to gather information. (More details are available here)
Posting Schema

If you are invoking via Swagger, you should see an appropriate response as follows.

As per the Zabbix documentation, before you can access any data inside of Zabbix, you'll need to log in and obtain an authentication token.
Refer to the Zabbix documentation here.
1. You need to invoke the following URL: zabbix/api_jsonrpc.php
The Zabbix API allows you to programmatically retrieve and modify the configuration of Zabbix and provides access to historical data.
2. The payload is as defined in the following example.
{ "jsonrpc": "2.0", "method": "user.login", "params": { "user": "Admin", "password": "<password>" }, "id": 1, "auth": null }
|

3. In my case, the output is as follows.
{ "jsonrpc": "2.0", "result": "2e7f1287dc4fac1a246bd66fab47ecbe", "id": 1 }
|
The result identifies the token to be used in subsequent calls. We will use it as tokens. (See the section below.)
- jsonrpc. The version of the JSON-RPC protocol.
- result. The data returned by the method (`user.login`)
- id. Identifier of the corresponding request.
4. Use the Result: $[‘result’]
Pass it to the next step for which you need a JSON path builder, such as https://jsonpath.com/
"urls": [ { "id": "login", "body": { "id": 1, "jsonrpc": "2.0", "method": "user.login", "params": { "password": "%password", "user": "%username" } }, "httpHeaders": { "Content-Type": "application/json-rpc" }, "method": "post", "src": "", "tokens": { "usertoken": "$['result']" }, "url": "/zabbix/api_jsonrpc.php", "var": "", "xml_ns": "" }, { "id": "hosts", "body": { "auth": "%usertoken", "id": 1, "jsonrpc": "2.0", "method": "host.get", "params": { "output": [ "hostid", "host" ], "selectInterfaces": [ "interfaceid", "ip", "dns" ] } }, "httpHeaders": { "Content-Type": "application/json-rpc" }, "method": "post", "src": "login", "url": "/zabbix/api_jsonrpc.php", "var": "", "xml_ns": "" } ]
|
The values defined are as follows.
Attribute
|
Description
|
id
|
Unique name: User Identifier that helps to identify the section. In my case the first one is called login, as I am fetching the token.
|
method
|
HTTP POST method: “post”
|
src
|
Identifies sibling URL, which for login is none so kept it as empty
|
url
|
URL to invoke: /zabbix/api_jsonrpc.php
Read more in the Zabbix documentation
|
tokens
|
Block that defines the `usertoken` that will be referenced in other blocks.
|
httpHeaders
|
Headers required for the request
"httpHeaders": { "Content-Type": "application/json-rpc" }
|
body
|
JSON body that needs to be passed (as mentioned in the zabbix documentation)
"body": { "id": 1, "jsonrpc": "2.0", "method": "user.login", "params": { "password": "%password", "user": "%username" } },
It identifies the method
"method": "user.login"
The param that are being passed
"params": { "password": "%password", "user": "%username" }
|
5. Get Host Details
In the same way we have looked for “login” and parsed the token, you can fetch the hosts.
{ "id": "hosts", "body": { "auth": "%usertoken", "id": 1, "jsonrpc": "2.0", "method": "host.get", "params": { "output": [ "hostid", "host" ], "selectInterfaces": [ "interfaceid", "ip", "dns" ] } }, "httpHeaders": { "Content-Type": "application/json-rpc" }, "method": "post", "src": "login", "url": "/zabbix/api_jsonrpc.php", "var": "", "xml_ns": "" }
|
Attributes
|
Description
|
body
|
Body has the auth and passes the %usertoken populated from login
|
src
|
Is a sibling to `login` as it uses the %usertoken
|
params
|
Based on the Zabbix documentation
"params": { "output": [ "hostid", "host" ], "selectInterfaces": [ "interfaceid", "ip", "dns" ] }
In my case the sample response as evaluated in insomnia (API evaluator tool) is as follows.
{ "jsonrpc": "2.0", "result": [ { "hostid": "10084", "host": "lvndev011524.bpc.broadcom.net", "interfaces": [ { "interfaceid": "1", "ip": "10.74.146.11", "dns": "lvndev011524.bpc.broadcom.net" } ] }, { "hostid": "10432", "host": "ibnqa003969.bpc.broadcom.net", "interfaces": [ { "interfaceid": "2", "ip": "10.80.241.78", "dns": "ibnqa003969.bpc.broadcom.net" } ] }, { "hostid": "10434", "host": "ibnqa003970.bpc.broadcom.net", "interfaces": [ { "interfaceid": "4", "ip": "10.80.241.80", "dns": "ibnqa003970.bpc.broadcom.net" } ] }, { "hostid": "10435", "host": "node2.kubernetes.cluster", "interfaces": [ { "interfaceid": "5", "ip": "10.80.120.148", "dns": "ibndev003277.bpc.broadcom.net" } ] } ], "id": 2 }
|
As in the case of streaming, the call and the result would be available in the restmon.log.
2021-11-08 10:36:06,900 [AsyncHttpClient-3-4] DEBUG ResponseHandler:217 - url: /zabbix/api_jsonrpc.php , response: {"jsonrpc":"2.0","result":[{"hostid":"10084","host":"lvndev011524.bpc.broadcom.net","interfaces":[{"interfaceid":"1","ip":"10.74.146.11","dns":"lvndev011524.bpc.broadcom.net"}]},{"hostid":"10432","host":"ibnqa003969.bpc.broadcom.net","interfaces":[{"interfaceid":"2","ip":"10.80.241.78","dns":"ibnqa003969.bpc.broadcom.net"}]},{"hostid":"10434","host":"ibnqa003970.bpc.broadcom.net","interfaces":[{"interfaceid":"4","ip":"10.80.241.80","dns":"ibnqa003970.bpc.broadcom.net"}]},{"hostid":"10435","host":"node2.kubernetes.cluster","interfaces":[{"interfaceid":"5","ip":"10.80.120.148","dns":"ibndev003277.bpc.broadcom.net"}]}],"id":1}
|

6. Define Topology
Once the above details are defined, you can now move to the topology section.

"topology": [ { "xml_ns": "", "url": "hosts", "attributes": { "oi": { "Display Name": "$['result'][*]['host']", "ci_unique_id": "$['result'][*]['hostid']", "hostname": "$['result'][*]['host']", "ipAddresses": "$['result'][*]['interfaces'][*]['ip']", "macAddresses": "", "name": "$['result'][*]['host']", "product": "Zabbix Broadcom Com", "product_version": "4.0", "type": "HOST" } }, "group": "Topology", "layer": "CUSTOM" } ]
|

7. Add Other Sections
You can continue to stitch together the schema for alarms, metrics, and inventory and build the schema.
Final Schema: zabbixbroadcom
{ "zabbixbroadcom": { "definition": { "auth": "none", "name": "zabbixbroadcom", "resource_category": null, "type": "https", "updatedBy": "Saurabh Sharma", "uploadedBy": "TENANT", "version": "21.3.1", "xml_ns": "" }, "urls": [ { "id": "login", "body": { "id": 1, "jsonrpc": "2.0", "method": "user.login", "params": { "password": "%password", "user": "%username" } }, "httpHeaders": { "Content-Type": "application/json-rpc" }, "method": "post", "src": "", "tokens": { "usertoken": "$['result']" }, "url": "/zabbix/api_jsonrpc.php", "var": "", "xml_ns": "" }, { "id": "hosts", "body": { "auth": "%usertoken", "id": 1, "jsonrpc": "2.0", "method": "host.get", "params": { "output": [ "hostid", "host" ], "selectInterfaces": [ "interfaceid", "ip", "dns" ] } }, "httpHeaders": { "Content-Type": "application/json-rpc" }, "method": "post", "src": "login", "url": "/zabbix/api_jsonrpc.php", "var": "", "xml_ns": "" }, { "id": "items", "body": { "auth": "%usertoken", "id": 1, "jsonrpc": "2.0", "method": "item.get", "params": { "monitored": true, "output": "extend", "selectHosts": "extend", "sortfield": "name" } }, "httpHeaders": { "Content-Type": "application/json-rpc" }, "method": "post", "src": "login", "url": "/zabbix/api_jsonrpc.php", "var": "", "xml_ns": "" }, { "id": "problems", "body": { "auth": "%usertoken", "id": 1, "jsonrpc": "2.0", "method": "problem.get", "params": { "output": "extend" } }, "httpHeaders": { "Content-Type": "application/json-rpc" }, "method": "post", "src": "login", "url": "/zabbix/api_jsonrpc.php", "var": "", "xml_ns": "" }, { "id": "events", "body": { "auth": "%usertoken", "id": 1, "jsonrpc": "2.0", "method": "event.get", "params": { "eventids": "%var", "output": "extend", "selectHosts": "extend" } }, "httpHeaders": { "Content-Type": "application/json-rpc" }, "method": "post", "src": "problems", "url": "/zabbix/api_jsonrpc.php", "var": "$['result'][*]['eventid']", "xml_ns": "" } ], "topology": [ { "xml_ns": "", "url": "hosts", "attributes": { "oi": { "Display Name": "$['result'][*]['host']", "ci_unique_id": "$['result'][*]['hostid']", "hostname": "$['result'][*]['host']", "ipAddresses": "$['result'][*]['interfaces'][*]['ip']", "macAddresses": "", "name": "$['result'][*]['host']", "product": "Zabbix Broadcom Com", "product_version": "4.0", "type": "HOST" } }, "group": "Topology", "layer": "CUSTOM" } ], "alarms": [ { "xml_ns": "", "url": "events", "group": "Events", "attributes": { "oi": { "timestamp": "$['result'][*]['clock']", "alarmType": "Infra", "host": "$['result'][*]['hosts'][0]['host']", "ip": "", "product": "Zabbix Broadcom Com", "product_version": "4.0", "summary": "$['result'][*]['name']", "severity": "$['result'][*]['severity']", "severity_conversion": "5:critical,4:major,3:minor,Default:information", "configuration_item": "$['result'][*]['hosts'][0]['host']", "configuration_item_type": "Zabbix.Hosts", "ci_unique_id": "$['result'][*]['hosts'][0]['hostid']", "message": "$['result'][*]['name']", "alarm_unique_id": "$['result'][*]['eventid']", "tags": [ "Zabbix", "Events" ] } } } ], "calculated_methods": [], "calculated_metrics": [], "change_events": [], "groups": [], "inventory": [ { "xml_ns": "", "url": "hosts", "group": "Topology", "attributes": { "oi": { "ci_unique_id": "$['result'][*]['hostid']", "host": "$['result'][*]['host']", "product": "Zabbix Broadcom Com", "product_version": "4.0", "configuration_item_type": "Zabbix.Hosts", "display_name": "$['result'][*]['host']", "ip": "$['result'][*]['interfaces'][*]['ip']", "tags": [ "Zabbix", "ExcludeFromTAS" ] } } } ], "metrics": [ { "calculation": "", "xml_ns": "", "group": "Items", "attributes": { "oi": { "metric_name": "$['result'][*][?(@.value_type == '3' || @.value_type == '0')]['name']", "metric_type": "hosts", "metric_unique_id": "$['result'][*][?(@.value_type == '3' || @.value_type == '0')]['hostid']%//%:%//%$['result'][*][?(@.value_type == '3' || @.value_type == '0')]['itemid']", "metric_unit": "$['result'][*][?(@.value_type == '3' || @.value_type == '0')]['units']", "type": "2", "configuration_item_type": "Zabbix.Hosts", "configuration_item": "$['result'][*][?(@.value_type == '3' || @.value_type == '0')]['hosts'][0]['host']", "ci_unique_id": "$['result'][*][?(@.value_type == '3' || @.value_type == '0')]['hosts'][0]['hostid']", "host": "$['result'][*][?(@.value_type == '3' || @.value_type == '0')]['hosts'][0]['host']", "ip": "", "mac": "", "product": "Zabbix Broadcom Com", "product_version": "4.0", "tags": [ "Zabbix", "$['result'][*][?(@.value_type == '3' || @.value_type == '0')]['name']" ] } }, "value": "$['result'][*][?(@.value_type == '3' || @.value_type == '0')]['lastvalue']", "url": "items" } ] } }
|
Validate the data in DX Operational Intelligence.



