- PVSM.RU - https://www.pvsm.ru -
Всем привет!
Все началось с интеграции телефонной платформы в корпоративный сайт.
Будучи инженером VoIP телефонии, WEB-разработка поразила разнообразием подходов и методов реализации. Стек технологий пестрит разнообразием, выбор инструментов определяет стиль разработки, модульность или закостенелость проекта.
Про телефонную платформу я напишу в следующий раз. Сильный уклон в VoIP-специфику отвлечет от главного — методов разработки современного SPA [1]-приложения.
В статье будет описан процесс внедрения стороннего сервиса в существующую рабочую среду.
Сегодня поиграемся с Zabbix-API [2].
Live Demo [3]
Тем кто лет десять назад реализовал WEB-интерактив средствами CGI-скриптов на серверной стороне, и хочет понять современные подходы. Если Вам приходилось выдумывать собственные API-интерфейсы, заниматься документацией того что получилось — решение ниже.
Первичная настройка Zabbix ведется через встроенный WEB-интерфейс. Рутина обычно сводится к простому добавлению хостов в группу.
Учет оборудования (добавление хостов) мы ведем в собственной системе на корпоративном сайте.
Разработкой корпоративной системы обычно занимается отдельный коллектив.
Пользовательский интерактив классически описан схемой работы MVC [4] с ее вариациями. Изучая матчасть появились кандидаты Vue [5], Ember [6], Meteor [7], Angular [8], ReactJS [9].
Пришло понимание, что большинство фреймворков/библиотек пытается реализовать полную экосистему MVC с реализацией как на front-end так и back-end [10], называют это «full stack».
React — это только «V» от «MVC». Погружаться в чужую экосистему не хотелось, а вот простая рисовалка очень приглянулась. Порадовала перспектива со временем перескочить в React Native [11]: один код для Web, IOS, Android. А подключив Redux [12], должен получиться full stack. Отдельно порадовал JSX, киллер-фича IMHO.
JSX [13] -детище разработчиков React — синтаксическая надстройка над JavaScript, визуально упрощает работу с DOM [14]-элементами браузера.
Матерые WEB-разработчики ругают его за то, что он перемешивает HTML разметку и JavaScript код. Я не матерый разработчик и JSX считаю отличным решением.
Сначала казалось удобным писать на «браузерном» JavaScript. Правда там неудобно разбивать проект на модули и подгружать необходимые. Проблему решил пакетный менеджер Bower [15]. Там своя философия, Bower заботится чтобы версии модулей не конфликтовали друг с другом.
На практике оказалось что все необходимые инструменты доступны в виде npm [16] пакетов. Если нужный модуль не доступен в виде npm пакета, Bower хорошее дополнение.
Итог. Пишем на Node, используем пакетный менеджер npm.
NodeJS [17] это серверный JavaScript, не браузерный. Хорошие люди придумали транспайлер [18] Browserify [19] который переделывает Node-код в браузерный вариант.
Браузеры не отличаются высокой скоростью обновления встроенного JavaScript движка. Хотелось бы использовать весь «сахар» современного JavasScript, отсюда еще один инструмент — Babel [20]. Транспайлер который умеет работать с последними версиями ECMAScript [21]. А еще, именно он будет распознавать JSX-синтаксис.
Помимо работы с JavaScript современная WEB-страничка плотно использует CSS [22], которые перешли на новый уровень абстракций SASS [23]. Подгружаются собственные шрифты и картинки. HTML-текст может быть раскидан по различным файлам. В итоге, построение финального проекта сводится к десятку действий над различными файлами, разбросанными по файловой системе в разнообразном порядке.
Gulp [24] это сборщик. По сути, обычный Node скрипт, в котором автоматизированы действия обработки исходных файлов проекта.
Я выбрал Gulp, в свое время понравился принцип его работы: поточная обработка, это быстро. Он выигрывал у Grunt [25], а еще попалась статья Insayt [26], на базе которой я и сделал свой gulpfile.js [27].
В качестве альтернативы, есть смысл рассмотреть webpack [28], я не пробоавл.
Но сначала, сформулируем принцип работы нашей будущей React-компоненты и Zabbix-API.
Можно было бы взгромоздить всю логику на front end, но это плохо:
Итог. Нужен «умный» back end, имеющий свой API.
При интеграции в телефонную платформу были пройдены первые «грабли». Был написан свой собственный API-сервер. Он работал. Успешно «рулил» софтсвичем, принимал REST-запросы которые по сути не являлись REST. Никакой документации по формату, методам и параметрам запросов не было.
Такая ситуация породила интерес, можно ли как-то формализовать API-интерфейс, чтобы документация формировалась автоматически? Приглянулся подход OpenAPI [30].
Суть сводится к тому, что сначала надо написать файл спецификации, в котором будут описаны все методы, поля, форматы ответов и т.п. Потом на базе этого файла можно сгенерировать готовый API-сервер. Список языков впечатляет, мы сделаем на NodeJS.
Так-как файл спецификации стандартный, для него уже придуманы инструменты: Swagger [31], ReDoc [32], OA Viewer [33],… подробней здесь [34]. Вопрос с документацией решается автоматически — это и есть файл спецификации.
Совсем скоро мы начнем писать исполнимый код. Скрипты будут на языке NodeJS. Любой язык эволюционирует, меняются версии, было бы неплохо пробовать результат на разных версиях языка. В каждом языке есть спец.инструменты для «жонглирования» версиями.
Я поступаю радикальней. Есть отличная технология LXC [35], предлагающая очень легкую виртуализацию на уровне ядра Linux. Грех было бы ей не воспользоваться. В случае с другими ОС есть своя специфика, разработчики учли нюансы и создали продукт Docker [36].
Необходимую среду разработки мы будем строить в нужном Docker-контейнере.
Проект доступен на Github [37]
git clone https://github.com/ars-anosov/zabbix-react.git
Back end сервер назовем «zabbix-reactor-node». Просматриваем файл спецификации. Проверяем поле «host».
less zabbix-react/node-back/api/zabbix-api.yaml
Если разворачиваем сервер на своей машине
host: 'localhost:8002'
Сервер собран при помощи swagger editor [38] на базе «zabbix-api.yaml». Структура такова:
index.js — стартовый скрипт
var app = require('connect')()
var swaggerTools = require('swagger-tools')
var http = require('http')
// 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'
Методы:
controllers/ — скрипты отвечающие за обработку API-запросов
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
Именно здесь наполняем логикой наши взаимодействия с Zabbix-API.
В Docker-контейнер будет прокинута директория «node-back»: переходим в нее.
cd zabbix-react/node-back/
Запускаем «zabbix-reactor-node». Передаем в контейнер переменные окружения ZX_URL, ZX_USER, ZX_PASS — вбиваем свои, если есть свой Zabbix. В качестве примера можете использовать мой тестовый 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
Старые версии заббикса могут принимать запросы на другом URL. Смотрим Zabbix doc. [39]
Дальше все действия внутри контейнера.
npm install
node index.js $ZX_URL $ZX_USER $ZX_PASS
Выскочить из контейнера: Ctrl+P+Q
Проверяем доступноать SwaggerUI — http://localhost:8002/spec-ui/ [40]
В поле «token» вписываем «test». Здесь будет токен авторизации, его проверкой занимается скрипт node-back/sub_modules/aaa_handle.js.
Мы хотим открыть доступ только к определенным Host group на Zabbix. Для этого необходимо создать отдельного пользователя «react_user».
Строим среду разработку назовем ее «zabbix-react-front».
В Docker-контейнер будет прокинута директория «web-front»: переходим в нее.
cd zabbix-react/web-front/
Запускаем «zabbix-react-front»:
docker run
--name zabbix-react-front
-v $PWD:/web-front
-w /web-front
--publish=8003:8003
-it
node:8 bash
Дальше все действия внутри контейнера.
# глобально устанавливаем gulp-cli
npm install -g gulp-cli
# Теперь все необходимое (транспайлеры, утилиты, плагины)
npm install
Компоненты находятся в директории web-front/src/js/components, они имеют свои зависимости.
Устанавливаем:
npm run install-components
Собираем проект в директорию web-front/build
gulp
Выскочить из контейнера: Ctrl+P+Q
Проверяем работу компонент — http://localhost:8003/ [41]
Вот мы и добрались до работы с компонентами. Посмотрим что сейчас запущено.
Работаем со следующей структурой файлов:
web-front/src/index.jsx — JSX-скрипт с компонентами
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(
<div className='std-win'>no spec - <a href={specUrl}>{specUrl}</a> !</div>,
document.getElementById('root')
)
}
else {
ReactDOM.render(
<div>
<HostConfig swgClient={client} />
<HostGraph swgClient={client} />
</div>,
document.getElementById('root')
)
}
})
web-front/src/components/ — директория с компонентами
web-front/src/components/zabbix-react-component.js — экспортируемые классы
export { OpenApiSwagger } from './OpenApiSwagger.js'
export { HostConfig } from './HostConfig.jsx'
export { HostGraph } from './HostGraph.jsx'
С этого места можно смело ваять свои компоненты, наращивать функционал.
В качестве примера, приделал инструмент, который есть в Nagios [43] но отсутствует в Zabbix. Автоматическое построение карты сети на базе мета-информации «source-target» в описании элементов сети.
Смотрим компоненту HostGraph. Для хранения информации использую в Zabbix Host закладку «Host inventory» поле «Notes». Туда в JSON-формате заносим связки элементов «source-target». Для визуализации использовал проект d3 [44] — Force-Directed Graph [45].
Теперь у нас в руках находится среда разработки, front-end и back-end. Для работы достаточно знания JavaScript и специфики NodeJS.
API-документирован и доступен для тестирования сторонними front-end разработчиками. API-сервер не привязан именно к Zabbix, это общее решение. Возможна интеграция к любой системе.
Собраны готовые React-компоненты выполняющие стандартные CRUD [46] функции. Компоненты освобождены от сложностей взаимодействия с интегрируемыми системами, только отображение.
Автор: Арсений
Источник [47]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/nodejs/270000
Ссылки в тексте:
[1] SPA: https://ru.wikipedia.org/wiki/%D0%9E%D0%B4%D0%BD%D0%BE%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%B8%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5
[2] Zabbix-API: https://www.zabbix.com/documentation/3.2/manual/api
[3] Live Demo: http://zabbix.react.com.ru/
[4] MVC: https://ru.wikipedia.org/wiki/Model-View-Controller
[5] Vue: https://vuejs.org/
[6] Ember: https://www.emberjs.com/
[7] Meteor: https://www.meteor.com/
[8] Angular: https://angularjs.org/
[9] ReactJS: https://reactjs.org/
[10] front-end так и back-end: https://ru.wikipedia.org/wiki/Front_end_%D0%B8_back_end
[11] React Native: https://facebook.github.io/react-native/
[12] Redux: https://redux.js.org/
[13] JSX: https://reactjs.org/docs/introducing-jsx.html
[14] DOM: https://ru.wikipedia.org/wiki/Document_Object_Model
[15] Bower: https://bower.io/
[16] npm: https://www.npmjs.com/
[17] NodeJS: https://nodejs.org/en/
[18] транспайлер: https://en.wikipedia.org/wiki/Source-to-source_compiler
[19] Browserify: https://www.npmjs.com/package/browserify
[20] Babel: https://babeljs.io/
[21] ECMAScript: https://ru.wikipedia.org/wiki/ECMAScript
[22] CSS: https://ru.wikipedia.org/wiki/CSS
[23] SASS: https://ru.wikipedia.org/wiki/Sass
[24] Gulp: https://gulpjs.com/
[25] Grunt: https://gruntjs.com/
[26] Insayt: https://habrahabr.ru/users/insayt/
[27] gulpfile.js: https://github.com/ars-anosov/zabbix-react/blob/master/web-front/gulpfile.js
[28] webpack: https://webpack.js.org/
[29] REST: https://ru.wikipedia.org/wiki/REST
[30] OpenAPI: https://www.openapis.org/
[31] Swagger: http://petstore.swagger.io/
[32] ReDoc: http://rebilly.github.io/ReDoc/
[33] OA Viewer: https://koumoul.com/openapi-viewer
[34] здесь: https://github.com/OAI/OpenAPI-Specification/blob/master/IMPLEMENTATIONS.md
[35] LXC: https://ru.wikipedia.org/wiki/LXC
[36] Docker: https://www.docker.com/
[37] Github: https://github.com/ars-anosov/zabbix-react
[38] swagger editor: https://editor.swagger.io/
[39] Zabbix doc.: https://www.zabbix.com/documentation/2.2/ru/manual/api
[40] http://localhost:8002/spec-ui/: http://localhost:8002/spec-ui/
[41] http://localhost:8003/: http://localhost:8003/
[42] http://localhost:8002/...: http://localhost:8002/spec/swagger.json
[43] Nagios: https://www.nagios.org/
[44] d3: https://d3js.org/
[45] Force-Directed Graph: https://bl.ocks.org/mbostock/4062045
[46] CRUD: https://ru.wikipedia.org/wiki/CRUD
[47] Источник: https://habrahabr.ru/post/344040/?utm_source=habrahabr&utm_medium=rss&utm_campaign=sandbox
Нажмите здесь для печати.