Служба для управления инфраструктурой с помощью Telegram бота или infrabot.io

    https://www.youtube.com/watch?v=wXhTHyIgQ_U

    Пятница, закончился рабочий день. Радостный, в преддверии двух дней отдыха, а именно субботы и воскресенья, так же, как и мои коллеги собрался я и пошел домой. Добираться до дома та еще задача, так как в связи с сильным ростом заболевших COVID-19, государством было принято решение внести разного рода ряд ограничений, в том числе и ограничение временной остановки работы метрополитена, соответственно все хлынули к виду общественного транспорта – автобусам. Это в свою очередь вызвало гораздо большую переполненность самих автобусов и увеличило загруженность и без того загруженных дорог. Поэтому, если раньше на дорогу уходило 30-40 минут, то сейчас полтора часа. По очевидным причинам в автобусе тоже не разгуляться, стоишь еле стиснутый в углу, пытаешься еле удержаться, хотя и иногда, держась покрепче, не упав ни на кого, залипнуть в телефоне удается. До дома еще добираться час и 20 минут и тут поступает сообщение в общую группу IT в WhatsApp-е, о просьбе разблокировать пользователя. После быстрого ping-а коллег, с некоторыми Request timed out стало ясно, что относительно только у меня, находящегося в переполненным до упора автобусе, есть возможность подключиться и разблокировать пользователя. Проклиная все на свете, подключился через VPN с телефона, еле-еле, кое-как разблокировал пользователя в течении 10-15 минут и сразу отчитался о разблокировке в группе.

    В тот же день ближе к 11 часам вечера, во время поглощения музыкального контента, в тот самый пик припева песни, опять пришло сообщение в чат о просьбе разблокировки другого пользователя. Выбора не было — пришлось подключиться и разблокировать, но впечатление от прослушивания испортилось.

    Казалось бы, вот уже точно все. Теперь можно спокойно, не думать ни о чем, отдохнуть и уже прийти в понедельник свежий на работу.

    Так на следующий день, в субботу, опять сообщение в группу, о другом пользователе – разблокируйте плиз!!1!11. Но сообщение это я увидел через час полтора так, как телефон был далеко, не услышал звук уведомления или еще что-то, но благо коллеги вмешались и разблокировали пользователя, но спустя 40 минут после того, как поступил запрос. Быстрый SSH коллег показал, что сообщение ими было рассмотрено сразу, но по определенным уважительным причинам они не могли разблокировать прям вот здесь и сейчас.

    Так больше не может продолжаться решил я! Ведь должен же быть какой-то быстрый способ решения такого рода спонтанных задач вне рабочего времени, при чем чтобы это могли делать сотрудники тех поддержки тоже!

    Усердно думаем. Гуглим


    Был проведен усердный поиск в чертогах разума, проведены сложные математические вычисления астрономического масштаба. В результате процесса даже было пару BSOD, Seg fault и Memory overflow мозга. На весь процесс было потрачено 10 секунд, по истечении которого я сдался и обратился за помощью в гугл.

    Небольшой поиск по гуглу не дал вменяемых результатов, может я плохо искал, но навел меня на это и это, и на парочку репозиториев (1, 2) на гитхабе.

    Тогда я пришел к выводу, что самый лучший и относительно простой способ быстрого решения каких-либо небольших задач вне рабочего времени это использование Telegram бота. Отправил ему команду, он выполнил, отчитался о результате и проблема решена, и времени на это ушло пару секунд, и без лишней возни.

    Сперва я попытался воспользоваться разработками авторов выше указанных статей, но спустя некоторое время пришел к выводу, что они не очень годятся по следующим причинам:

    • Хоть и документация API Telegram достаточная и сам API простой, но приходится в коде в PowerShell много играться со строковыми значениями, передаваемыми в переменную API строки. Не то чтобы, сложно, но не очень удобно, код загромождается и можно запутаться особенно когда что-то типа:

      $($URL_get)?offset=$($($data.update_id)+1)
    • Скрипт сам все время не будет работать в фоне, поэтому надо или весь функционал пихать в while($true) или, запускать планировщиком задач Windows через каждые несколько секунд, что не является очень хорошим решением. Увеличение времени запуска, будет означать, что бот не будет реагировать на наши запросы сразу, а именно время реакции будет как минимум равно времени интервала запуска, а может и больше;
    • Увеличение понимаемых ботом команд, автоматически ведет к увеличению объёма кода скрипта, где последующий траблшутинг ее усложняется. К тому же, не все коллеги обладают одинаковыми способностями скриптинга. Кто-то на «ты» со скриптами, а кому-то запись while ($true) понимается с трудом, а банальный if-else приведет к непонятным ошибкам. Должен быть какой-то более легкий способ обеспечения\добавления функциональности для бота;
    • Не у всех одинаковые представления о том, как должен быть оформлен код. Этот пункт не очень-то уж и важен, но по мне он существенен. Становится трудно читать разные куски кода, когда они оформлены коряво, по моему мнению, но совершенно хорошо читаемые для другого;

    Поразмышляв немного я пришел к выводу, что тут не обойтись без создания своего приложения и простой скриптинг тут не поможет.

    Взвесив все возможные варианты, я решил написать приложение на .NET Core 5.0, который позволит запускать его как и на Windows, так и на Linux, а в будущем, можно будет и контейнер Docker собрать (пока не знаю, как это правильно сделать, буду очень благодарен за подсказки в этом направлении). Всю разработку вел в Visual Studio Code с установкой плагинов для разработки на C#, чего вполне хватило для всего. Ставить тяжелую Visual Studio не было желания.

    Определение плана


    Цель без плана — это просто желание! (Антуан де Сент-Экзюпери)

    Поэтому расписал следующий план:

    • Приложение должно уметь работать как и с запуска из консоли, так и как служба Windows. Возможность запуска как служба Windows, позволит запускать от имени ограниченной учетной записи (не админ) или даже с Active Directory Managed Service Account;
    • Для обеспечения добавления неограниченного количества команд для понимания для бота без изменения исходного кода приложения, должно быть место куда можно будет их добавлять и приложение должно уметь его читать и понимать, а значит нам нужен config файл. Форму хранения выбрал в формате json;
    • Приложение должно обеспечить возможность настройки доступа к отправке команд боту, а также к каждой команде по отдельности. Например, бот будет реагировать на команды только от указанных пользователей Telegram-а – сисадминов организации, но допустим условный доступ к команде перезагрузки сервера будет иметь только менеджер;
    • Приложение должно уметь запускать PowerShell, отправить ему на выполнение наш скрипт с аргументами, получить от него результат работы (output) и показать его пользователю;
    • Должна быть GUI утилита, которая позволит «кнопками» менять, удалять или добавлять настройки в config.json файле, так как не всем охота лезть в дебри конфигурационного файла. Для создания такого приложения, выбрал технологию Windows Presentation Foundation (WPF) (sorry but I hate Electron), которое позволит с легкостью создать адаптивный интерфейс (привет XAML);

    Разработка


    Если бы строители работали так же, как программисты кодят, то любая птица, присевшая отдохнуть на крыше дома, могла бы стать причиной гибели цивилизации.

    Создание проекта для C# в Visual Studio Code достаточно проста. В терминале переходим в пустую папку, и пишем команду:

    dotnet new console

    Будут созданы все необходимые файлы в том числе Program.cs, который является минимальным Hello World консольным приложением, то есть основной входной точкой для нашего приложения.

    Для того чтобы он мог поддерживать запуск как служба windows, я поставил Nuget пакет System.ServiceProcess.ServiceController с помощью команды:

    dotnet add package System.ServiceProcess.ServiceController --version 5.0.0

    а за тем добавил следующую минимальную конструкцию в Program.cs:

    конструкция
    public const string ServiceName = "InfraBot.IO";
    
    public class Service : ServiceBase
    {
          public Service() { ServiceName = Program.ServiceName; }
          protected override void OnStart(string[] args) { Program.Start(args); }
          protected override void OnStop() { Program.Stop(); }
    }
    
    static void Main(string[] args)
    {
          if (!Environment.UserInteractive)
          {
                // running as service
                using (var service = new Service())
                {
                      ServiceBase.Run(service);
                }
          }
          else
          {
                 // running as console app
                 Start(args);
                 Stop();
          }
    }
    
    private static void Start(string[] args)
    {
          // Execute when app or service starts
    }
    
    private static void Stop()
    {
          // Execute when app or service closes
    }
    


    Как видно из примера, объём кода небольшой, но позволяет добиться многого.
    За тем поставил Nuget пакеты Newtonsoft.Json и Telegram.Bot

    dotnet add package Newtonsoft.Json --version 12.0.3
    dotnet add package Telegram.Bot --version 15.7.1
    

    Для десериализации конфигурационного файла создал три класса:

    • Config.cs — описывает все глобальные настройки для нашего бота и содержит в себе массив из доступных команд;
    • Command.cs — описывает все параметры команды, которое бот может выполнять и содержит в себе массив из стандарных ответов отображаемых пользователю;
    • ExecuteResult.cs — описывает все стандарные ответы, один из которых будет отправлен пользователю на основе полученного результата от выполненного скрипта;

    Минимальный код требуемый для работы бота взял отсюда.

    код бота
    static ITelegramBotClient botClient;
    private static void Start(string[] args)
    {
          botClient = new TelegramBotClient(commandCenter.GetTelegramToken());
          var me = botClient.GetMeAsync().Result;
          if (Environment.UserInteractive)
          {
                Console.WriteLine($"I am user {me.Id} and my name is {me.FirstName}");
          }
          botClient.OnMessage += Bot_OnMessage;
          botClient.StartReceiving();
          Console.Read();
    }
    
    static async void Bot_OnMessage(object sender, MessageEventArgs e)
    {
          // Executed when message received from Bot
          if (e.Message.Text != null)
          {
                Console.WriteLine($"Received a text message in chat {e.Message.Chat.Id}.");
    
                await botClient.SendTextMessageAsync(
                      chatId: e.Message.Chat,
                      text:   "You said:\n" + e.Message.Text
                );
          }
    }
    


    Как можно понять по коду, все принятые сообщения от бота обрабатываются в функции Bot_OnMessage. Сперва весь код обработки команд я написал в нем, но потом понял, что файл Program.cs слишком сильно захламляется, и для будущей разаработки лучше всего будет создать отдельный класс CommandCenter и в нём уже все полученное должным образом обрабатывать.

    Добавлять в статью весь этот класс бессмысленно, так как он довольно громоздкий, желающие смогут сами посмотреть на него на гитхабе, но тем не менее на уровне псевдокода распишу как он работает:

    псевдокод CommandCenter
    public CommandCenter()
    {
          // Читаем содержимое файла config.json в папке где лежит запускемый Executable
          readConfigFile();
          // С помощью библиотеки Newtonsoft.Json читаем файл и десериализеум его с помощью наших классов Command, Config, ExecuteResult
          jsonDeserialize();
    }
    
    public async Task ExecuteCommand(ITelegramBotClient botClient, object sender, MessageEventArgs e)
    {
          // Блокируем дальнейшее выполнение если пользователь не в списке глобальных разрешенных Чат групп или не в списке разрешенных пользователей. Если в конфиге включен запись логов то записываем в лог об этом 
          blockIfUserIsInAllowedChatsList();
          blockIfUserIsInAllowedUsersList();
    
          // Проходимся циклом по всем командам прописанным в нашем конфиге
          foreach (Command command in config.telegram_commands)
          {
                // Если полученный текст от юзера начинается со значения параметра  "command_starts_with" команды, и полученное сообщение от разрешенного чата или группы телегам этой команды (параметры "command_allowed_users_id", "command_allowed_chats_id"), то продолжаем дальнейшую обработку
                if (userStartsWith(our_command) && userOrChatHasAccessToThisCommand())
                {
                      // Делим всю полученную команду от пользователя на части где разделитель " " (пробел). Если вторая часть команды знак "?", то отправляем пользователю значение "command_help_manual" и останавливаем дальнейшее выполнение
                      splitCommad();
                      checkIfUserNeedManual();
                      
                      // Читаем массив чисел "command_data_id". Он показывает какая часть команды содержит информацию, которую надо отправить как аргумент нашему PowerShell скрипту. Если в массиве больше одного числа, то он собирает аргументы по указанной очереди. Например: 
                      // 
                      // /checkconnection server01 port 443
                      // В приведенном примере:
                      // индекс 1 - будет иметь значение checkconnection
                      //        2 - будет иметь значение server0
                      //        3 - будет иметь значение port
                      //        4 - будет иметь значение 443
                      // Если в массиве "command_data_id" указать "4, 2, 3", то собранный аргумент, который будет передан скрипту PowerShell будет:
                      //        443 server0 port
                      // Очевидно, что приведенный пример "4, 2, 3" не имеет логики. Лучше всего будет написать "2, 4":
                      //        server0 443
                      string buildedArgument = buildArgumentToScript();
                      
                      // Запускаем PowerShell, отправляя ему расположение нашего файла указанного в параметре "command_execute_file" с собранными аргуменами
                      runPowerShellWithOurScriptWithArguments(buildedArgument);
                       
                      // Проходимся по каждому шаблону стандартных ответов из конфига
                      foreach (ExecuteResult executeresult in command.command_execute_results)
                      {
                            // Если значение параметра "result_checktype" ответов:
                            //         1 - Результат от скрипта проверяется на равенство (Equals) с параметром "result_value"
                            //         2 - Результат от скрипта содержит (Contains) значение параметра "result_value"
                            //         3 - Результат от скрипта начинается (Starts With) со значением параметра "result_value"
                            //         4 - Результат от скрипта заканчивается на (Ends With) значение параметра "result_value"
                            // Если хотя бы один из этих четырех проверок заканивается с успехом, то пользователю отправляется соответсвующее значение параметра "result_output". Если в строковом значении параметра "result_output" содержится "{DATA}" , то он заменяется значением аргумента отправленного скрипту, а "{RESULT}" - заменяется значением (output-ом) от полученного после выполнения нашего скрипта
                            doCheckSendUserAnswer();
                      }
                }
          }
    }
    


    После создания такого функционала, пришла идея, что этого все еще не достаточно.

    А что если у меня нет аргументов передаваемых скрипту и мне нужно, чтобы бот отправил обратно весь полученный резльтат, например результат команды ipconfig? А что если я не хочу PowerShell скрипты, а хочу свое кастомное приложение и чтобы тоже могло работать как и с аргументами с кастомными ответами, так и вовсе без них с выводом всего результата?

    Поэтому в настройки команд был добавлен параметр command_execute_type определяющий тип команды. Если его значение:

    • 1 — свое приложение со своими ответами, который умеет принимать аргументы;
    • 2 — свое приложение без ответов и без аргументов, где весь output отправляется пользователю;
    • 3 — PowerShell скрипт со своими ответами, который умеет принимать аргументы;
    • 4 — PowerShell скрипт без ответов и без аргументов, где весь output отправляется пользователю;

    Дополнительные команды


    Идея о дополнительных командах пришла во время разработки. Ниже короткая информация о них:

    • /emergency — аварийное завершение работы приложения в случае ЧП. Можно настроить доступ к этой команде;
    • /getcommands — показывает весь список доступных команд с их коротким описанием, который указывается в параметре «command_help_short». Если у команды значение «command_show_in_get_commands_list» true, то команда не будет отображена в списке. Имеется возможность настроить доступ к этой команде;
    • /reloadconfig — заного считывает файл конфигурации. Позволяет применять обновленную конфигуацию без перезагрузки приложения. Можно настроить доступ к этой команде;
    • /remindme — Показывает указанный текст с напоминанием в указанное время. Доступ к этой команде можно настроить;

    Примеры команд с PowerShell скриптом


    Сисадмины очень любят лопать воздушно-пузырчатую пленку, потому что каждая пупырышка — это глаз пользователя!

    В зависимости от типа команды, скрипт с конфигурацией может выглядеть по разному.

    Пример 1


    Предположим, что мы хотим создать команду для перезагрузки сервера и мы хотим использовать для этого PowerShell скрипт. Очевидно, что наша команда (в том числе и скрипт) должен принимать один аргумент в, котором указывается DNS имя или IP сервера. Пример команды:

    /restartserver server01
    или
    /restartserver 10.120.20.15

    В зависимости от результата выполнения скрипта, бот должен показать нам соответствующее сообщение. Таким образом конфигурация в файле config.json будет выглядеть следующим образом:

    конфигурация в config.json
    {
          "command_starts_with": "/restartserver",
          "command_data_id": [
                2
          ],
          "command_execute_file": "C:\\Program Files\\infrabot.io\\tools\\my_restart_server_script.ps1",
          "command_help_manual": "Restarts specified server. Write `/restartserver server01` to restart server",
          "command_help_short": "Restarts specified server",
          "command_default_error": "Server`{DATA}` was not restarted! Unexpected error! Result: {RESULT}",
          "command_execute_type": 3,
          "command_allowed_users_id": [],
          "command_allowed_chats_id": [],
          "command_show_in_get_commands_list": true,
          "command_execute_results": [
                {
                      "result_value": "0",
                      "result_output": "Server `{DATA}` was not restarted! Server name or IP was not sent as an argument to script",
                      "result_checktype": 1
                },
                {
                      "result_value": "1",
                      "result_output": "Server `{DATA}` have been restarted!",
                      "result_checktype": 1
                },
                {
                      "result_value": "2",
                      "result_output": "Server `{DATA}` was not restarted! Error occured! Output result from script is the following: {RESULT}!",
                      "result_checktype": 1
                }
          ]
    }
    


    Как можно понять по конфигурации, бот при получении команды начинающейся с "/restartserver" (command_starts_with), отправит на выполнение в PowerShell наш скрипт (command_execute_file), где аргументом будет вторая часть команды (после пробела) (command_data_id). В зависимости от полученного результата от скрипта, бот покажет нужный текст (command_execute_results). Если нужного случая в результатах не найдется, то бот покажет стандартную ошибку (command_default_error). При вызове команды "/restartserver ?" будет показан мануал для команды (command_help_manual). При вызове команды "/getcommands", эта команда будет отображена в списке доступных команд вместе с коротким описанием (command_help_short) так, как включено отображение этой команды в общем списке команд (command_show_in_get_commands_list).

    Сам скрипт будет иметь следующую форму:

    PowerShell скрипт
    
    If ($args.Count -gt 0) 
    {
          $arg1 = $args[0]
          try 
          {
                $CredentialUser = "DOMAIN\admin_user"
                $CredentialPassword = ConvertTo-SecureString "my_super_password" -AsPlainText -Force
                $Credential = New-Object System.Management.Automation.PSCredential ($CredentialUser, $CredentialPassword)
                Restart-Computer -ComputerName $arg1 -Credential $Credential -ErrorAction Stop
                Write-Host -NoNewline 1
          }
          catch 
          {
                Write-Host -NoNewline 2
          }
    }
    else 
    {
          Write-Host -NoNewline 0
    }
    


    Пример 2


    Во втором примере мы хотим создать команду, которая не получает никаких аргументов, а просто показывает пользователю весь результат ipconfig от скрипта.
    Тогда конфигурация в файле config.json, будет выглядеть следующим образом:

    конфигурация в config.json
    {
          "command_starts_with": "/gethostipconfig",
          "command_data_id": [
                0
          ],
          "command_execute_file": "C:\\Program Files\\infrabot.io\\tools\\GetHostIpConfig.ps1",
          "command_help_manual": "Shows IPCONFIG of the host where BOT works. Write `/gethostipconfig` to get host IPCONFIG",
          "command_help_short": "Shows IPCONFIG of the host where BOT works",
          "command_default_error": "",
          "command_execute_type": 4,
          "command_allowed_users_id": [],
          "command_allowed_chats_id": [],
          "command_show_in_get_commands_list": true,
          "command_execute_results": []
    }
    


    Как видно из примера, список стандартных ответов (command_execute_results) пуст. Смысл что-то определять если нам нужен весь результат выполнения ipconfig? Для четвертого типа команд (command_execute_type), бот будет игнорировать записи в стандартных результатах (command_execute_results).

    Скрипт для этого случая будет простым:

    PowerShell скрипт
    
    ipconfig
    


    Пример 3


    В данном примере мы рассмотрим случай, если наша команда может принять не один, а даже несколько аргументов, но результат от выполнения нужно отобразить как есть (как во втором примере). В таком случае конфигурация будет следующая:

    конфигурация в config.json
    {
          "command_starts_with": "/somesupercommand",
          "command_data_id": [
                2, 3
          ],
          "command_execute_file": "C:\\Program Files\\infrabot.io\\tools\\my_super_script.ps1",
          "command_help_manual": "Does some super stuff. Write `/somesupercommand server01 443` to do super stuff",
          "command_help_short": "Does some super stuff",
          "command_default_error": "Super staff with `{DATA}` was not done! Unexpected error! Result: {RESULT}",
          "command_execute_type": 3,
          "command_allowed_users_id": [],
          "command_allowed_chats_id": [],
          "command_show_in_get_commands_list": true,
          "command_execute_results": [
                {
                      "result_value": "0",
                      "result_output": "Cool stuff with `{DATA}` was not performed! Arguments were not sent to script",
                      "result_checktype": 1
                },
                {
                      "result_value": "2",
                      "result_output": "Cool stuff with `{DATA}` was not performed! Error occured!",
                      "result_checktype": 1
                },
                {
                      "result_value": "",
                      "result_output": "{RESULT}",
                      "result_checktype": 2
                }
          ]
    }
    


    Так, как бот выполняет проверку ответов по очереди указанном в списке (command_execute_results), то этапы проверки будут следующими:

    • «result_value»: «0» — Из-за того, что result_checktype указан как 1 (Равно значению), то вывод от скрипта будет проверен со значением «0» на равенство и в случе успеха отобазиться текст из result_output;
    • «result_value»: «2» — Из-за того, что result_checktype указан как 1 (Равно значению), то вывод от скрипта будет проверен со значением «2» на равенство и в случе успеха отобазиться текст из result_output;
    • «result_value»: "" — Из-за того, что result_checktype указан как 2 (Содержит), то вывод от скрипта будет проверен со значением "" на содержание, которое всегда будет истиной. Так как в result_output указано {RESULT}, то весь output скрипта после выполнения будет показан как есть. Здесь важно эту запись всегда писать в конце вариантов ответов так, как из-за того, что результат проверки всегда будет положительным, она не будет давать выполняться остальным проверкам после себя;


    Скрипт для этого случая будет таковым:

    PowerShell скрипт
    
    If ($args.Count -gt 1) 
    {
          $arg1 = $args[0]
          $arg2 = $args[1]
          try 
          {
                # MY super code
                Write-Host "some cool output"
          }
          catch 
          {
                Write-Host -NoNewline 2
          }
    }
    else 
    {
          Write-Host -NoNewline 0
    }
    


    Примечание


    Вполне может быть, что в вашей организации применены жесткие ограничительные политики выполнения PowerShell скриптов. По умолчанию Бот запускает PowerShell по ExecutionPolicy Unrestricted (параметр telegram_powershell_executionpolicy) для текущей сессии. Эту настройку я рекомендую сменить на более безопасную ExecutionPolicy AllSigned, но вы заранее должны будете все свои скрипты подписывать сертификатом, иначе они не будут работать. Для соблюдения политики безопасности вашей организации вы можете сменить эту настройку на нужную вам в конфигурационном файле.



    Все выше написанное верно также и для своего приложения. В параметр command_execute_file в этом случае необходимо вписать путь до своего исполняемого файла.

    В теории вы можете даже написать свой крутой скриптовый интерпретатор и в него уже посылать соответствующие ему скрипты. Для этого необходимо указать путь до исполняемого файла вашего интерпретатора в telegram_powershell_path, очистить содержимое параметра telegram_powershell_executionpolicy, и в своем приложении создать понимание аргумента "-File", который принимает путь до выполняемого скрипта.

    GUI Configurator


    image

    Думаю не имеет смысла приводить исходный код в статье, тем более он достаточно банальный и громоздкий. Хоть и реализация приложения страдает, и не лишена багов, но свою задачу она выполняет. Среди сложностей, с которыми я столкнулся во время создания этого приложения, это логика того, как правильно записывать обратно полученную информацию в нужную часть конфига потому, что информация может быть динамическим массивом и иногда в, котором тоже может быть еще один динамический массив (все в ListBox-ах). И эти Binding-и в ListBox-ах меня изрядно помучали.

    infrabot.io


    После проделанной работы я решил создать на основе всего выше созданного свой opensource стартап проект. Очевидно, что идея не новая и есть много других вариантов и альтернатив. Но тем не менее мне показалось, что сделанными наработками поделиться будет не лишним и я надеюсь оно кому-нибудь понадобится и выручит не один раз.

    Название для стартапа выбирал долго, потом в два раза больше потратил времени на поиск свободного домена под сильно ограниченный бюджет. Пару раз приходилось отказываться от выбранного имени из-за занятого домена с таким же именем, а порой цена за свободный домен доходила до пару тысяч долларов. Эти провайдеры регистрации доменных имен — торговцы воздухом…

    В конце концов остановился на infrabot.io, арендовал VPS сервер, написал вебсайт на Java Servlet-ах и выполнил кучу разных действий для приведения всего к нормальному виду. Пару раз приходилось все полностью переделывать потому, что не устраивал полученный результат. В какие-то моменты приходили оптимистичные мысли «А зачем я все это делаю?», «Кому это гуано, кроме как мне, нужно?», «Столько работы, а отдача может быть отрицательная и скорее всего так будет..», «Теперь я по-настоящему понимаю, что такое стартап и когда ты делаешь все один», «OMG еще надо думать как это раскручивать, статью писать, может не надо!?!?». Но тем не менее удалось справиться с оптимистичными мыслями и сосредоточится просто на мыслях, на том, что надо просто всё взять и сделать.

    На данный момент на сайте присутствует полная документация на все функции с примерами и мануалами для успешной настройки приложения.

    Раздел «Addons Store» (Магазин дополнений) в процессе разработки (не знаю как правильно загружать файлы с HTML формы в JSP). В этом разделе каждый сможет поделиться своими скриптами со своими конфигами, чтобы любой желающий смог поставить себе уже готовые скрипты на все случаи жизни. Пока добавление туда скриптов осуществляется вручную, мною.

    Если у вас есть\будут какие-либо свои дополнения, которыми вы бы хотели поделиться, вы можете отправить их мне на адрес addons@infrabot.io, чтобы я их выложил на сайте.

    Планы по развитию и поддержке созданного большие, но на данный момент roadmap выглядит следующим образом:

    • Возможность установки плагинов просто копированием файла плагина в нужную директорию. На данный момент установку скриптов, конфигов надо делать вручную;
    • Возможность создания задания для выполнения любой доступной команды из конфига в указанное время;
    • Увеличение доступных стандартных команд;
    • Улучшение дизайна и кода приложения GUI Configurator;
    • Возможность добавлять плагин с сайта в конфигурационный файл с настройками прямо из GUI Configurator;
    • Возможность создавать плагин со своими настройками прямо в GUI Configurator;
    • Поиск возможных багов и улучшение логики работы основного приложения (рефакторинг);
    • Убрать блокировку основного потока приложения, если какой-то скрипт задерживается с ответом. На данный момент бот не будет реагировать на следующую команду, пока предыдущая не завершилась. Если честно не знаю как это исправить, но есть догадки , которые могут быть ошибочными;

    А что по поводу проблемы в начале статьи спросите вы? Ну как минимум я (и не только я) могу разблокировывать\отключать\включать\сбрасывать пароль пользователя по требованию используя Telegram бота. 1 секунда — проблема решена. Конечно же со временем бот «стал понимать» больше команд. Перезагрузка некоторых критических сервисов когда они застряли (в том числе и на Linux), перезагрузка виртуальных машин Windows (используя WinRM) и Linux (используя SSH), перезагрузка виртуальных машин и физических хостов VmWare (используя VmWare PowerCLI), перезагрузка некоторых проблемных PaloAlto IPSec VPN туннелей и всякого разного — в одну команду находясь в переполненном автобусе ;)

    Прикрепляю в конце статьи ссылки и дополнительную информацию:

    Веб сайт: infrabot.io
    Адрес для контакта и предложений: infrabot@infrabot.io
    Адрес для отправки своих плагинов: addons@infrabot.io
    infrabot GitHub Repository: infrabot-io/infrabot
    GUI Configurator GitHub Repository: infrabot-io/infrabot-gui-tool

    Конец! Спасибо, что дочитали до конца!
    Реклама
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее

    Комментарии 2

      0
      Управляющее приложение должно быть в единственном экземпляре на замкнутый контур? Для работы, скажем, с двумя независимыми офисами потребуется 2 отдельных бота и 2 инсталляции приложения?
        0
        Управляющее приложение должно быть в единственном экземпляре на замкнутый контур?

        И да и нет. Зависит от случая.

        Для работы, скажем, с двумя независимыми офисами потребуется 2 отдельных бота и 2 инсталляции приложения?

        Да, для работы независимых офисов требуется две инсталяции приложения (сколько угодно много для любого количества офисов), но бот может быть один. Главное чтобы команды нигде не были идентичными, а то инсталяции с одинаковыми командами будут выполнять одно и то же.

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое