Preparing your UI interface for Zabbix API using React component
Hello! It all started with the integration of the telephone platform into the corporate site.
WEB development impressed with a variety of approaches and implementation methods. The technology stack is replete with diversity, the choice of tools determines the development style, modularity or ossification of the project.
I’ll write about the telephone platform next time. A strong bias in VoIP-specifics will distract from the main thing - the methods of developing a modern SPA application.
The article will describe the process of introducing a third-party service into an existing working environment.
Today let's play with the Zabbix-API .
Live demo
Those who ten years ago implemented WEB-interactive by means of CGI-scripts on the server side, and want to understand modern approaches. If you had to invent your own APIs, to document what happened - the solution is below.
Initial configuration of Zabbix is done through the integrated WEB-interface. Routine usually comes down to simply adding hosts to a group.
We keep records of equipment (adding hosts) in our own system on a corporate website.
The development of a corporate system is usually done by a separate team.
The user interaction is classically described by the MVC working scheme with its variations. Studying the materiel there were candidates Vue , Ember , Meteor , Angular , ReactJS .
It came to be understood that most frameworks / libraries are trying to implement the full MVC ecosystem with front-end and back-end implementations , call this the “full stack”.
React is just “V” from “MVC”. I didn’t want to plunge into another’s ecosystem, but I liked the simple drawer very much. The prospect was pleased over time to jump into React Native : one code for Web, IOS, Android. And by connecting Reduxshould get full stack. Separately pleased with JSX, killer feature IMHO.
The React JSX developer brain is a syntax add-on for JavaScript that visually simplifies working with browser DOM elements.
Inveterate web developers scolded him for mixing HTML markup and JavaScript code. I am not a seasoned developer and I consider JSX a great solution.
At first it seemed convenient to write in "browser" JavaScript. True, there it is inconvenient to break the project into modules and load the necessary ones. The problem was solved by the Bower package manager . There is its own philosophy, Bower takes care that the versions of the modules do not conflict with each other.
In practice, it turned out that all the necessary tools are available as npm packages. If the desired module is not available as an npm package, Bower is a good addition.
Total. We write on Node, we use the npm package manager.
NodeJS is server-side JavaScript, not browser-based. Good people came up with the Browserify transporter, which remakes the Node code into a browser version.
Browsers do not have a high update speed of the built-in JavaScript engine. I would like to use all the “sugar” of modern JavasScript, hence another tool - Babel . A transporter that can work with the latest versions of ECMAScript . And yet, it is he who will recognize the JSX syntax.
In addition to working with JavaScript, the modern WEB-page makes heavy use of CSS , which has moved to a new level of SASS abstractions . Own fonts and pictures are loaded. HTML text can be scattered across various files. As a result, the construction of the final project comes down to ten actions on various files scattered across the file system in a variety of ways.
Gulp is a collector. In fact, it’s a regular Node script in which the processing of the source files of the project is automated.
I chose Gulp, at one time I liked the principle of its work: stream processing, it is fast. He beat Grunt , and I also got an Insayt article , on the basis of which I made my gulpfile.js .
Alternatively, it makes sense to consider webpack , I did not try.
It is worth noting here - we have listed the main tools for developing front end. Now it's the turn of the back end.
But first, we will formulate the principle of operation of our future React-component and Zabbix-API.
It would be possible to pile up all the logic on the front end, but this is bad:
Total. We need a “smart” back end with its own API.
When integrating into the telephone platform, the first "rake" was completed. My own API server was written. He worked. Successfully “steered” softswitch, accepted REST requests which in essence were not REST. There was no documentation on the format, methods and parameters of the requests.
This situation has generated interest, is it possible to somehow formalize the API so that the documentation is generated automatically? I liked the OpenAPI approach .
The bottom line is that first you need to write a specification file in which all methods, fields, response formats, etc. will be described. Then, based on this file, you can generate a ready-made API server. The list of languages is impressive, we will do on NodeJS.
Since the specification file is standard, tools have already been invented for it: Swagger, ReDoc , OA Viewer , ... more here . The issue with the documentation is resolved automatically - this is the specification file.
Soon we will begin to write executable code. The scripts will be in NodeJS. Any language evolves, versions change, it would be nice to try the result on different versions of the language. Each language has special tools for "juggling" versions.
I act more radically. There is great LXC technology that offers very easy virtualization at the Linux kernel level. It would be a sin not to use it. In the case of other OSs, there is a specificity, the developers took into account the nuances and created the Docker product .
We will build the necessary development environment in the necessary Docker container.
The project is available on Github.
We call the back end server “zabbix-reactor-node”. We look through the specification file. Check the host field.
If we deploy the server on our machine
The server is built using the swagger editor based on "zabbix-api.yaml". The structure is as follows:
index.js - start script
Methods
controllers / - scripts responsible for processing API requests
This is where our interactions with the Zabbix-API are filled with logic.
The “node-back” directory will be scrolled into the Docker container: go to it.
We start "zabbix-reactor-node". We pass the environment variables ZX_URL, ZX_USER, ZX_PASS into the container - we drive in our own, if we have our own Zabbix. As an example, you can use my test Zabbix:
Older versions of zabbix can accept requests at a different URL. We look at Zabbix doc.
Then all the actions inside the container.
Jump out of the container: Ctrl + P + Q
Check if SwaggerUI is available - http: // localhost: 8002 / spec-ui /
In the “token” field, enter “test”. There will be an authorization token, the node-back / sub_modules / aaa_handle.js script is engaged in its verification.
We want to open access only to certain Host groups on Zabbix. To do this, create a separate user, react_user.
Building a development environment, let's call it “zabbix-react-front”.
The "web-front" directory will be scrolled into the Docker container: go to it.
Run zabbix-react-front:
Then all the actions inside the container.
The components are located in the web-front / src / js / components directory, they have their own dependencies.
Install:
We collect the project in the web-front / build directory
Jump out of the container: Ctrl + P + Q
Check the operation of the component - http: // localhost: 8003 /
So we got to work with the components. Let's see what is running now.
We work with the following file structure:
web-front / src / index.jsx - JSX script with components
web-front / src / components / - directory with components
web-front / src / components / zabbix-react-component.js - exported classes. Available as npm zabbix-react-component package .
From this place you can safely sculpt your components, increase functionality.
As an example, I attached a tool that is in Nagios but not in Zabbix. Automatic construction of a network map based on the source-target meta-information in the description of network elements.
We look at the component HostGraph. To store information I use in the Zabbix Host tab “Host inventory” field “Notes”. There, in the JSON format, we enter the bundles of the "source-target" elements. For visualization I used the d3 project - Force-Directed Graph .
Now we have in our hands the development environment, front-end and back-end. Javascript knowledge and NodeJS specifics are enough to work.
The API is documented and available for testing by third-party front-end developers. The API server is not specifically tied to Zabbix, this is a general solution. Integration to any system is possible.
Ready-made React components that perform standard CRUD functions are compiled . Components are freed from the complexity of interacting with integrated systems, only mapping.
WEB development impressed with a variety of approaches and implementation methods. The technology stack is replete with diversity, the choice of tools determines the development style, modularity or ossification of the project.
I’ll write about the telephone platform next time. A strong bias in VoIP-specifics will distract from the main thing - the methods of developing a modern SPA application.
The article will describe the process of introducing a third-party service into an existing working environment.
Today let's play with the Zabbix-API .
Live demo
Who will be interested
Those who ten years ago implemented WEB-interactive by means of CGI-scripts on the server side, and want to understand modern approaches. If you had to invent your own APIs, to document what happened - the solution is below.
We set the task
Initial configuration of Zabbix is done through the integrated WEB-interface. Routine usually comes down to simply adding hosts to a group.
We keep records of equipment (adding hosts) in our own system on a corporate website.
- It would be nice to integrate Zabbix's routine tasks into your existing accounting environment. Minimize the number of parameters, ideally one “add” button
The development of a corporate system is usually done by a separate team.
- It would be nice to give them functionality in the form of a ready-made module. Ideally, a couple of lines of code "import ..." and "render ..."
- Try to use a modern technology stack, preferably standard interaction interfaces
Technology stack
ReactJS
The user interaction is classically described by the MVC working scheme with its variations. Studying the materiel there were candidates Vue , Ember , Meteor , Angular , ReactJS .
It came to be understood that most frameworks / libraries are trying to implement the full MVC ecosystem with front-end and back-end implementations , call this the “full stack”.
React is just “V” from “MVC”. I didn’t want to plunge into another’s ecosystem, but I liked the simple drawer very much. The prospect was pleased over time to jump into React Native : one code for Web, IOS, Android. And by connecting Reduxshould get full stack. Separately pleased with JSX, killer feature IMHO.
Jsx
The React JSX developer brain is a syntax add-on for JavaScript that visually simplifies working with browser DOM elements.
Inveterate web developers scolded him for mixing HTML markup and JavaScript code. I am not a seasoned developer and I consider JSX a great solution.
NodeJS
At first it seemed convenient to write in "browser" JavaScript. True, there it is inconvenient to break the project into modules and load the necessary ones. The problem was solved by the Bower package manager . There is its own philosophy, Bower takes care that the versions of the modules do not conflict with each other.
In practice, it turned out that all the necessary tools are available as npm packages. If the desired module is not available as an npm package, Bower is a good addition.
Total. We write on Node, we use the npm package manager.
Browserify
NodeJS is server-side JavaScript, not browser-based. Good people came up with the Browserify transporter, which remakes the Node code into a browser version.
Babel
Browsers do not have a high update speed of the built-in JavaScript engine. I would like to use all the “sugar” of modern JavasScript, hence another tool - Babel . A transporter that can work with the latest versions of ECMAScript . And yet, it is he who will recognize the JSX syntax.
Gulp
In addition to working with JavaScript, the modern WEB-page makes heavy use of CSS , which has moved to a new level of SASS abstractions . Own fonts and pictures are loaded. HTML text can be scattered across various files. As a result, the construction of the final project comes down to ten actions on various files scattered across the file system in a variety of ways.
Gulp is a collector. In fact, it’s a regular Node script in which the processing of the source files of the project is automated.
I chose Gulp, at one time I liked the principle of its work: stream processing, it is fast. He beat Grunt , and I also got an Insayt article , on the basis of which I made my gulpfile.js .
Alternatively, it makes sense to consider webpack , I did not try.
It is worth noting here - we have listed the main tools for developing front end. Now it's the turn of the back end.
But first, we will formulate the principle of operation of our future React-component and Zabbix-API.
goal
- Reduce front-back interaction to simple REST requests
- To concentrate all logic of interaction with Zabbix-server on the back end
- Preferred standard interface + documentation
It would be possible to pile up all the logic on the front end, but this is bad:
- Zabbix-API will have to be open to all client browsers. It is safer to open a separate resource with a limited set of actions
- We create a general solution that can work with radically different systems: SNMP sensors, telnet sessions, with server OS resources, and so on. (Zabbix is just one of the implementations). The browser just does not have this functionality
Total. We need a “smart” back end with its own API.
A little more technology
Openapi
When integrating into the telephone platform, the first "rake" was completed. My own API server was written. He worked. Successfully “steered” softswitch, accepted REST requests which in essence were not REST. There was no documentation on the format, methods and parameters of the requests.
This situation has generated interest, is it possible to somehow formalize the API so that the documentation is generated automatically? I liked the OpenAPI approach .
The bottom line is that first you need to write a specification file in which all methods, fields, response formats, etc. will be described. Then, based on this file, you can generate a ready-made API server. The list of languages is impressive, we will do on NodeJS.
Since the specification file is standard, tools have already been invented for it: Swagger, ReDoc , OA Viewer , ... more here . The issue with the documentation is resolved automatically - this is the specification file.
Docker
Soon we will begin to write executable code. The scripts will be in NodeJS. Any language evolves, versions change, it would be nice to try the result on different versions of the language. Each language has special tools for "juggling" versions.
I act more radically. There is great LXC technology that offers very easy virtualization at the Linux kernel level. It would be a sin not to use it. In the case of other OSs, there is a specificity, the developers took into account the nuances and created the Docker product .
We will build the necessary development environment in the necessary Docker container.
Let's get started
The project is available on Github.
git clone https://github.com/ars-anosov/zabbix-react.git
zabbix-reactor-node
We call the back end server “zabbix-reactor-node”. We look through the specification file. Check the host field.
less zabbix-react/node-back/api/zabbix-api.yaml
If we deploy the server on our machine
host: 'localhost:8002'
The server is built using the swagger editor based on "zabbix-api.yaml". The structure is as follows:
index.js - start script
var app = require('connect')()
var swaggerTools = require('swagger-tools')
var http = require('http')
- http - WEB server
- connect with middleware swagger-tools - request processing
// Route validated requests to appropriate controller
app.use(middleware.swaggerRouter(options));
// Serve the Swagger documents and Swagger UI
app.use(middleware.swaggerUi({
apiDocs: '/spec/swagger.json',
swaggerUi: '/spec-ui'
Methods
- middleware.swaggerRouter - a router that forwards requests to the appropriate controller in the zabbix-react / node-back / controllers directory
- middleware.swaggerUi is a SwaggerUI tool. This is our API documentation. It allows you to run test REST requests.
controllers / - scripts responsible for processing API requests
Configuration.js
Data.js
config_host_del.js
config_host_get.js
config_host_post.js
config_host_put.js
config_hostgroup_get.js
data_hostlink_get.js
This is where our interactions with the Zabbix-API are filled with logic.
The “node-back” directory will be scrolled into the Docker container: go to it.
cd zabbix-react/node-back/
We start "zabbix-reactor-node". We pass the environment variables ZX_URL, ZX_USER, ZX_PASS into the container - we drive in our own, if we have our own Zabbix. As an example, you can use my test Zabbix:
docker run \
--name zabbix-reactor-node \
-v $PWD:/zabbix-reactor-node \
-w /zabbix-reactor-node \
--publish=8002:8002 \
--env="ZX_URL=http://zabbix-server.react.com.ru/api_jsonrpc.php" \
--env="ZX_USER=guest" \
--env="ZX_PASS=" \
-it \
node:8 bash
Older versions of zabbix can accept requests at a different URL. We look at Zabbix doc.
Then all the actions inside the container.
npm install
node index.js $ZX_URL $ZX_USER $ZX_PASS
Jump out of the container: Ctrl + P + Q
Check if SwaggerUI is available - http: // localhost: 8002 / spec-ui /
In the “token” field, enter “test”. There will be an authorization token, the node-back / sub_modules / aaa_handle.js script is engaged in its verification.
Zabbix settings
We want to open access only to certain Host groups on Zabbix. To do this, create a separate user, react_user.
- Administration / User groups - add the user group "react_user_group"
- Administration / User groups / Permissions - add Host groups with which react_user will be allowed to work. We expose Read-write.
- Administration / Users - add a user, include in the user group created in paragraph 1
- Administration / Users / Permissions - User type set "Zabbix Admin"
zabbix-react-front
Building a development environment, let's call it “zabbix-react-front”.
The "web-front" directory will be scrolled into the Docker container: go to it.
cd zabbix-react/web-front/
Run zabbix-react-front:
docker run \
--name zabbix-react-front \
-v $PWD:/web-front \
-w /web-front \
--publish=8003:8003 \
-it \
node:8 bash
Then all the actions inside the container.
# глобально устанавливаем gulp-cli
npm install -g gulp-cli
# Теперь все необходимое (транспайлеры, утилиты, плагины)
npm install
The components are located in the web-front / src / js / components directory, they have their own dependencies.
Install:
npm run install-components
We collect the project in the web-front / build directory
gulp
Jump out of the container: Ctrl + P + Q
Check the operation of the component - http: // localhost: 8003 /
zabbix-react-component
So we got to work with the components. Let's see what is running now.
- zabbix-reactor-node - OpenAPI server, open for receiving REST requests at http: // localhost: 8002 / ...
- zabbix-react-front - livereload-web server for displaying the React component, draws on http: // localhost: 8003 /
We work with the following file structure:
web-front / src / index.jsx - JSX script with components
import React from 'react';
import ReactDOM from 'react-dom'
import { OpenApiSwagger, HostConfig, HostGraph } from './components/zabbix-react-component'
window.localStorage.setItem('token', 'test')
const specUrl = 'http://localhost:8002/spec/swagger.json'
const swg = new OpenApiSwagger(specUrl)
swg.connect((client, err) => {
if (err) {
ReactDOM.render(
no spec - {specUrl} !,
document.getElementById('root')
)
}
else {
ReactDOM.render(
,
document.getElementById('root')
)
}
})
- specUrl - path to the specification file on zabbix-reactor-node
web-front / src / components / - directory with components
web-front / src / components / zabbix-react-component.js - exported classes. Available as npm zabbix-react-component package .
export { OpenApiSwagger } from './OpenApiSwagger.js'
export { HostConfig } from './HostConfig.jsx'
export { HostGraph } from './HostGraph.jsx'
From this place you can safely sculpt your components, increase functionality.
As an example, I attached a tool that is in Nagios but not in Zabbix. Automatic construction of a network map based on the source-target meta-information in the description of network elements.
We look at the component HostGraph. To store information I use in the Zabbix Host tab “Host inventory” field “Notes”. There, in the JSON format, we enter the bundles of the "source-target" elements. For visualization I used the d3 project - Force-Directed Graph .
Conclusion
Now we have in our hands the development environment, front-end and back-end. Javascript knowledge and NodeJS specifics are enough to work.
The API is documented and available for testing by third-party front-end developers. The API server is not specifically tied to Zabbix, this is a general solution. Integration to any system is possible.
Ready-made React components that perform standard CRUD functions are compiled . Components are freed from the complexity of interacting with integrated systems, only mapping.