Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
![Логотип программы "DevOps Report Manager" Логотип программы "DevOps Report Manager"](https://habrastorage.org/r/w1560/getpro/habr/upload_files/b7d/2b9/3a2/b7d2b93a270899e97d161b0787bf1ebd.png)
Здравствуйте, меня зовут Павел.
Я работал системным администратором с 2010 года в разных компаниях, в 2019 году решил сменить сферу деятельности на DevOps‑инженера.
Проработав некоторое время DevOps‑инженером, понял, что сотрудникам нужна программа, которая создавала бы в виде таблицы ёмкие отчёты о том, какие версии сборки программы установлены, на каких тестовых стендах и в каком состоянии эти сборки находятся на момент составления отчёта, с учётом того, что их можно было бы рассылать по email команде разработчиков.
Работая в компании, этот вариант отчёта я создал в виде джобы в Jenkins (Pipeline + Bash), отчёт создавался только для определённых тестовых стендов и для определённой программы.
Через некоторое время появилась мысль создать свою универсальную кроссплатформенную программу на Java для простого создания DevOps‑отчётов.
Для профессии DevOps‑инженера нужно было знать Java. Написание своей программы было бы неким стимулом для его изучения, поэтому я решил приступить к учёбе и по возможности создавать свою программу.
Почитав на просторах интернета статьи о лицензировании при использовании JDK и Open JDK, чтобы не было проблем с авторскими правами, я принял решение использовать Open JDK Amazon Corretto 11.
В качестве GUI интерфейса выбрал JavaFX.
Программу назвал «DevOps Report Manager».
Далее, вооружившись книгой «Java Руководство для начинающих» и Интернетом, начал создавать первую часть программы.
Первая часть программы, которая строит отчёты по содержанию веб программного контекста у программ
Для простоты установки программы было принято решение не использовать базы данных, а хранить настройки в зашифрованном виде в текстовом файле.
Настройки активации полной версии программы (без ограничений по количеству серверов) решил хранить в отдельном зашифрованном файле для простоты использования в корпоративной среде.
В качестве алгоритма шифрования использовал AES 256.
Минимальную длину пароля установил в 4 символа, максимальную — в 256 символов.
Все файлы настроек, логов и отчётов программы решил хранить в домашней директории пользователя в папке DevOps Report Manager files и соответствующих подпапках Settings, Logs, Reports.
Логи реализовал с помощью Logger, подумал, что для этой программы не нужно хранить много файлов, сделал так, чтобы логи хранились в одном файле и чтобы он заменялся по достижении примерно 7 МБ.
Сделал, чтобы файл определённого вида отчёта заменялся каждый раз, когда создаётся данный отчёт.
Так же в программе есть некая защита от «дурака», выглядящая как некоторые ограничения по количеству знаков для заполнения форм и таблиц.
Через несколько месяцев первая часть программы была создана.
Программа строила отчёты в виде симпатичной таблицы в едином HTML‑файле для удобства пересылки по почте.
В HTML‑файле присутствует JavaScript для работы интерактивной таблицы отчёта.
Также в программе присутствовал вариант отчёта в формате EML (в полном и сокращённом виде).
В EML‑формате отчёт менее красивый, потому что используется HTML version 1.0, который накладывает свои ограничения на оформление страниц.
Отчёт создаётся, если у программы есть web программный контекст в HTML‑ или Json‑формате примерно такого вида { «programName»: «Test_1», «programVersion»: «1.0.0», «standIP»: «127.0.0.1» } , и если путь до программного контекста был примерно такого вида https://адрес:порт/имя программы/… путь до контекста программы.
В качестве параметров program name и program version нужно использовать соответствующие названия параметров в программном контексте (не значения параметров).
К примеру в контексте «programName»: «Test_1»,
«programName» — это название параметра;
«Test_1» — это значение параметра.
Если в настройках программы указать название несуществующего параметра и создать отчёт, программа в отчёте напишет «check settings».
Ниже представлен скриншот первой части программы (третья вкладка программы).
![Program Context Report Program Context Report](https://habrastorage.org/r/w1560/getpro/habr/upload_files/0ce/afe/94e/0ceafe94eb502ad785f7d5d8b574c367.png)
Ниже представлен анимированный gif-скриншот с вариантом отчёта в HTML-формате (если кликнуть на текст программного контекста, откроется его страница).
![Program Context Report (HTML + JavaScript) Program Context Report (HTML + JavaScript)](https://habrastorage.org/getpro/habr/upload_files/0ff/fb8/4a1/0fffb84a12c2916ab721c29ca8fa2105.gif)
Ниже представлен анимированный gif‑скриншот с вариантом полного и сокращённого отчёта в EML‑формате (для простоты навигации по документу создал якорные ссылки).
![Program Context Report (EML Full report и EML Short report) Program Context Report (EML Full report и EML Short report)](https://habrastorage.org/getpro/habr/upload_files/c42/3f7/9e3/c423f79e3e7c5f478e955e1c6f52ca6e.gif)
В процессе создания первой части программы появлялись мысли, что нужно сделать ещё две: для составления отчётов Docker и Kubernetes
Начиная размышлять, каким образом можно собирать данные с серверов, я придумал вариант с разовым подключением к серверу по ssh, выполнением нужного набора команд, копированием всего вывода из консоли в переменную и дальнейшим парсингом текста из переменной с помощью регулярных выражений.
В дальнейшем в некоторых отчётах, если много контейнеров или подов, пришлось сделать так, чтобы программа могла подключаться к серверу два раза.
Для подключения к серверам по SSH решил использовать открытую библиотеку SSH клиента JSch.
Для подключения по SSH есть возможность использовать User и Password, использовать SSH key в формате PEM, использовать SSH key в формате PEM и SSH key Password.
Для некой безопасности чтения полей user и ssh key in pem format сделал их блокировку по паролю.
Для составления отчётов добавил возможность выполнения команд с правами Sudo.
В данных частях программы значительно усложняется алгоритм вывода в таблицу данных, потому что контейнеров и подов значительно больше, чем один, и у каждого может быть своё состояние.
Для Docker-контейнеров было принято решение создать следующие примерные виды состояний:
![Ошибка подключения к серверу; Ошибка подключения к серверу;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/a6c/f65/27c/a6cf6527cdfdb861db1b78fd71c29155.png)
![На сервере нет данной команды, или у пользователя нет прав на запуск данной команды; На сервере нет данной команды, или у пользователя нет прав на запуск данной команды;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/57f/baa/cfe/57fbaacfe1b3773d5b96393626a60915.png)
![Все контейнеры в состоянии создан; Все контейнеры в состоянии создан;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/9e9/136/3a7/9e91363a75066367751bfecfc260b2d0.png)
![Все контейнеры в состоянии неизвестно; *](https://habrastorage.org/r/w1560/getpro/habr/upload_files/87e/245/c75/87e245c75525be589a92b465c76b8138.png)
![Несколько контейнеров в состоянии создан или неизвестно; Несколько контейнеров в состоянии создан или неизвестно;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/ce9/ccb/e20/ce9ccbe20d0db90ffa5824e023f5ea4b.png)
![Все контейнеры не найдены; Все контейнеры не найдены;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/e0e/649/9bd/e0e6499bd61b25f74b06a7f5b769f4f3.png)
![Все контейнеры в состоянии остановлен; Все контейнеры в состоянии остановлен;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/670/5d4/57b/6705d457ba4a3056d0460a531820c20a.png)
![Несколько контейнеров в состоянии остановлен или пауза; Несколько контейнеров в состоянии остановлен или пауза;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/ddb/3c2/d6c/ddb3c2d6ce993e1fe239be51b10603a5.png)
![Несколько контейнеров в состоянии остановлен или создан; Несколько контейнеров в состоянии остановлен или создан;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/c86/4c6/e63/c864c6e636b275427a8311908f2c8cdb.png)
![Несколько контейнеров в состоянии остановлен или неизвестно; Несколько контейнеров в состоянии остановлен или неизвестно;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/f1d/6ca/b7c/f1d6cab7cb2a22adc9672925ba1b0201.png)
![Все контейнеры в состоянии пауза; Все контейнеры в состоянии пауза;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/b60/87e/13e/b6087e13ed36ccbe238279bb0b44cb94.png)
![Все контейнеры в состоянии работает; Все контейнеры в состоянии работает;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/5ee/912/cac/5ee912cace40e2f66282fd53866a444f.png)
![Несколько контейнеров в состоянии работает или пауза; Несколько контейнеров в состоянии работает или пауза;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/2fe/572/94f/2fe57294fdb67b12b96dd01d4d850fe6.png)
![Несколько контейнеров в состоянии работает или остановлен; Несколько контейнеров в состоянии работает или остановлен;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/ded/e89/473/dede894738e16a6848e88f184a916d36.png)
![Несколько контейнеров в состоянии работает или создан; Несколько контейнеров в состоянии работает или создан;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/700/3d4/214/7003d4214aef11e90828d6e3e3839189.png)
![Несколько контейнеров в состоянии работает или неизвестно. Несколько контейнеров в состоянии работает или неизвестно.](https://habrastorage.org/r/w1560/getpro/habr/upload_files/953/0ff/821/9530ff8216cc5db157c30f1fdf95d3db.png)
Для Kubernetes-подов было принято решение создать следующие примерные виды состояний:
![Ошибка подключения к серверу; Ошибка подключения к серверу;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/35c/a5c/131/35ca5c1311b3d6360c781767e931010c.png)
![На сервере нет данной команды или у пользователя нет прав на запуск данной команды; На сервере нет данной команды или у пользователя нет прав на запуск данной команды;](https://habrastorage.org/r/w1560/getpro/habr/upload_files/ff1/05e/630/ff105e630dbba8516a7fd7def852d6fb.png)
![Все поды в состоянии (Unknown); Все поды в состоянии (Unknown);](https://habrastorage.org/r/w1560/getpro/habr/upload_files/28d/c3a/862/28dc3a862babff9f0b19613834758320.png)
![Все поды в состоянии (Unknown); Все поды в состоянии (Unknown);](https://habrastorage.org/r/w1560/getpro/habr/upload_files/383/6c1/7bf/3836c17bf18b066440f5b565a8da350b.png)
![Все поды в состоянии (Pending илиWaiting илиContainerCreating); Все поды в состоянии (Pending илиWaiting илиContainerCreating);](https://habrastorage.org/r/w1560/getpro/habr/upload_files/70b/e7a/397/70be7a397dc7a57fe4e4129c4e2446d0.png)
![Несколько подов в состоянии (Pending илиWaiting илиContainerCreating) или (Unknown); Несколько подов в состоянии (Pending илиWaiting илиContainerCreating) или (Unknown);](https://habrastorage.org/r/w1560/getpro/habr/upload_files/1ed/5c2/d14/1ed5c2d142dc01db310057feef969b85.png)
![Все поды в состоянии (Failed или Terminating илиTerminated или CrashLoopBackOff или ImagePullBackOff); Все поды в состоянии (Failed или Terminating илиTerminated или CrashLoopBackOff или ImagePullBackOff);](https://habrastorage.org/r/w1560/getpro/habr/upload_files/059/6c0/2bf/0596c02bf776c854f5ef16f5e62002b4.png)
![Несколько подов в состоянии (Failed или Terminating илиTerminated или CrashLoopBackOff или ImagePullBackOff) или (Pending илиWaiting илиContainerCreating); Несколько подов в состоянии (Failed или Terminating илиTerminated или CrashLoopBackOff или ImagePullBackOff) или (Pending илиWaiting илиContainerCreating);](https://habrastorage.org/r/w1560/getpro/habr/upload_files/2cf/078/10d/2cf07810dd6bfea69db5e939e7ce03d6.png)
![Несколько подов в состоянии (Failed или Terminating или Terminated или CrashLoopBackOff или ImagePullBackOff) или (Unknown); Несколько подов в состоянии (Failed или Terminating или Terminated или CrashLoopBackOff или ImagePullBackOff) или (Unknown);](https://habrastorage.org/r/w1560/getpro/habr/upload_files/65f/381/004/65f3810048efaa266506527638a584ba.png)
![Все поды в состоянии (Running или Succeeded или Completed); Все поды в состоянии (Running или Succeeded или Completed);](https://habrastorage.org/r/w1560/getpro/habr/upload_files/45e/c29/a9c/45ec29a9c745eae38024807ee4dc0759.png)
![Несколько подов в состоянии (Running или Succeeded или Completed) или (Pending илиWaiting илиContainerCreating); Несколько подов в состоянии (Running или Succeeded или Completed) или (Pending илиWaiting илиContainerCreating);](https://habrastorage.org/r/w1560/getpro/habr/upload_files/780/ccf/e66/780ccfe6610e37797bdd966a432fe45c.png)
![Несколько подов в состоянии (Running или Succeeded или Completed) или (Unknown); Несколько подов в состоянии (Running или Succeeded или Completed) или (Unknown);](https://habrastorage.org/r/w1560/getpro/habr/upload_files/243/bd8/955/243bd8955150025c81a33e863bcfa6f9.png)
![Несколько подов в состоянии (Running илиSucceeded или Completed) или (Failed или Terminating илиTerminated или CrashLoopBackOff или ImagePullBackOff); Несколько подов в состоянии (Running илиSucceeded или Completed) или (Failed или Terminating илиTerminated или CrashLoopBackOff или ImagePullBackOff);](https://habrastorage.org/r/w1560/getpro/habr/upload_files/b48/de9/35b/b48de935b3af5a39592e35819d556a75.png)
Если же появляется 3 или больше разных состояний контейнера или пода, тогда общий статус выбирается в сторону «больших ошибок».
В любом случае нужно смотреть подробное техническое описание в таблице отчёта.
Вторая часть программы для создания отчётов Docker
К сожалению, у Docker я не нашёл команд для расширенных отчётов по контейнерам (docker inspect не то), к примеру, как по подам у Kubernetes, поэтому в качестве дополнительной технической информации в отчётах Docker в программе используется информация по статам контейнеров и о сервере Docker.
Ниже представлен анимированный gif-скриншот с переключением интерфейса с Docker Image отчётов на Docker Compose отчёты.
![Docker Report (Image / Compose) Docker Report (Image / Compose)](https://habrastorage.org/getpro/habr/upload_files/2d7/d96/f53/2d7d96f53d8429837c19a278c9591c26.gif)
Вторая часть программы состоит из двух частей:
Генерация отчётов Docker создаёт отчёт о состоянии контейнеров Docker по названию Image name и по названию Image tag.
Ниже представлен анимированный gif-скриншот с вариантом отчёта в HTML-формате.
![Docker report by image name and image tag (HTML + JavaScript) Docker report by image name and image tag (HTML + JavaScript)](https://habrastorage.org/getpro/habr/upload_files/993/8fc/a52/9938fca52656acf53e7281c4da162f4f.gif)
Ниже представлен анимированный gif-скриншот с вариантом полного и сокращённого отчёта в EML-формате (для простоты навигации по документу создал якорные ссылки).
![Docker report by image name and image tag (EML Full report and Short report) Docker report by image name and image tag (EML Full report and Short report)](https://habrastorage.org/getpro/habr/upload_files/82d/38a/287/82d38a287c1dc1eb8354668e6a4a875e.gif)
Генерация отчётов Docker Compose создаёт отчёт о состоянии Docker project по названию Project name.
Ниже представлен анимированный gif-скриншот с вариантом отчёта в HTML-формате.
![Docker report by project name (HTML + JavaScript) Docker report by project name (HTML + JavaScript)](https://habrastorage.org/getpro/habr/upload_files/5e3/dee/1a2/5e3dee1a20c2a0a9d26a0ea2d728e501.gif)
Ниже представлен анимированный gif-скриншот с вариантом полного и сокращённого отчёта в EML-формате (для простоты навигации по документу создал якорные ссылки).
![Docker report by project name (EML Full report and Short report) Docker report by project name (EML Full report and Short report)](https://habrastorage.org/getpro/habr/upload_files/a28/6e1/f95/a286e1f95f96e82dd90cd689a8f9b0ea.gif)
Третья часть программы для создания отчётов Kubernetes
В качестве дополнительной информации по Kubernetes в зависимости от вида отчёта в моей программе присутствуют такие данные, как:
подробная информация о поде;
подробная информация о деплойменте;
информация о сервисах;
информация о ингресс‑контроллерах;
подробная информация о нодах кластера.
Ниже представлен анимированный gif‑скриншот с переключением интерфейса с Kubernetes Image отчётов на Kubernetes Applications отчёты.
![Kubernetes Report (Image / Application) Kubernetes Report (Image / Application)](https://habrastorage.org/getpro/habr/upload_files/1ad/bf9/786/1adbf978644ca1cb0bf69806c884514f.gif)
Третья часть программы состоит также из двух частей:
Генерация отчётов Kubernetes создаёт отчёт о состоянии подов Kubernetes по названию Image name, названию Image tag и Namespace.
Ниже представлен анимированный gif‑скриншот с вариантом отчёта в HTML‑формате.
![Kubernetes report by image name (HTML + JavaScript) Kubernetes report by image name (HTML + JavaScript)](https://habrastorage.org/getpro/habr/upload_files/e80/292/b80/e80292b806d557af62513cc71151fa4b.gif)
Ниже представлен анимированный gif-скриншот с вариантом полного и сокращённого отчёта в EML-формате (для простоты навигации по документу создал якорные ссылки).
![Kubernetes report by image name (EML Full report and Short report) Kubernetes report by image name (EML Full report and Short report)](https://habrastorage.org/getpro/habr/upload_files/2b9/d1b/e64/2b9d1be6465d81c9138663b851f08dd4.gif)
Генерация отчётов Kubernetes Application создаёт отчёт о состоянии подов Kubernetes по названию Application name, Application version (необязательный параметр), названию параметра Part‑of (необязательный параметр) и по названию Namespace.
Ниже представлен анимированный gif-скриншот с вариантом отчёта в HTML-формате.
![Kubernetes report by application name (HTML + JavaScript) Kubernetes report by application name (HTML + JavaScript)](https://habrastorage.org/getpro/habr/upload_files/6b7/4c3/23b/6b74c323bc3dabbaf1eaba347bedac31.gif)
Ниже представлен анимированный gif-скриншот с вариантом полного и сокращённого отчёта в EML-формате (для простоты навигации по документу создал якорные ссылки).
![Kubernetes report by application name (EML Full report and Short report) Kubernetes report by application name (EML Full report and Short report)](https://habrastorage.org/getpro/habr/upload_files/121/105/926/121105926eb42556d825fdee435c0b7c.gif)
Бэкап, экспорт и импорт файла настроек программы
![Верхнее мен Верхнее мен](https://habrastorage.org/r/w1560/getpro/habr/upload_files/e68/a49/13f/e68a4913f96e35580c8632a14d5270b3.png)
Для того чтобы можно было делать бэкап файла настроек или делиться файлом настроек программы между сотрудниками без передачи своего пароля, создал возможность сброса пароля при экспорте настроек.
![Экспорт настроек программы Экспорт настроек программы](https://habrastorage.org/r/w1560/getpro/habr/upload_files/c80/c58/205/c80c582058fc91a3144a572154cc223f.png)
Для загрузки файла экспортируемых настроек нужно будет выполнить его импорт (по завершении импорта файла настроек программа закроется).
![Импорт настроек программы Импорт настроек программы](https://habrastorage.org/r/w1560/getpro/habr/upload_files/fa6/1c4/389/fa61c43894f297208c9613e60c4cd491.png)
Если сотрудник хочет изменить пароль в переданном ему файле настроек, ему нужно будет у себя на компьютере сбросить пароль при экспорте настроек программы и потом импортировать данный файл настроек программы.
Обзор функциональности некоторых кнопок программы
![](https://habrastorage.org/r/w1560/getpro/habr/upload_files/dfb/9bf/245/dfb9bf24509c6c3689c6418a501cd08a.png)
Для просмотра нужного отчёта в нужном формате необходимо выбрать соответствующую вкладку, к примеру Docker report, далее выбрать нужный формат отчёта, к примеру EML, и нажать на кнопку «Open file».
Для сброса настроек в текущей вкладке нужно нажать на кнопку «Reset» и набрать пароль.
Для сброса всех настроек всех вкладок и сброса пароля нужно нажать на кнопку «Reset all» и набрать пароль, затем 2 раза набрать новый.
Для того чтобы сохранить изменения в текущей вкладке, нужно нажать на кнопку «Save» и набрать пароль.
Для того чтобы сохранить изменения настроек на всех вкладках, нужно нажать на кнопку «Save all» и набрать пароль.
Обзор функциональности кнопок закрытия программы
Для проверки изменений настроек программы и запроса на сохранение изменений настроек перед закрытием программы нажмите на кнопку «Exit» или на кнопку «X» в правом верхнем углу окна.
В качестве изменений настроек программы сохраняются положения всех кнопок переключателей во вкладках программы, кроме кнопки переключателя «Block / Unblock» (блокировка и разблокировка видимости полей user и ssh key in pem format).
Сочетание клавиш Alt + F4 показывает диалог о закрытии программы без сохранения изменений настроек.
Итог
В итоге на первую версию программы «DevOps Report Manager» ушло примерно 19 месяцев.
Для некой защиты авторских прав зарегистрировал программу в Роспатенте.
Далее для программы создал сайт.
После создания первой версии программы появились идеи по новой функциональности, поэтому, возможно, позже будет выпущена новая версия.
Всем спасибо.