From 1ae9a17fdc8604d0bb963826d128666e5234a077 Mon Sep 17 00:00:00 2001 From: nook24 Date: Mon, 8 May 2023 15:20:46 +0200 Subject: [PATCH 01/54] ITC-2986 Move config options to env vars --- composer.json | 1 - config/app.php | 18 +++++++++--------- config/bootstrap.php | 26 -------------------------- 3 files changed, 9 insertions(+), 36 deletions(-) diff --git a/composer.json b/composer.json index ab8c808515..cc9e4d076a 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,6 @@ "erusev/parsedown": "^1.7", "erusev/parsedown-extra": "^0.8", "freedsx/ldap": "^0.5.0", - "friendsofcake/cakepdf": "4.0.0-beta", "friendsofcake/cakephp-csvview": "^4.0", "guiguiboy/php-cli-progress-bar": "^0.0.4", "guzzlehttp/guzzle": "^7.4", diff --git a/config/app.php b/config/app.php index 9b81b90cec..a4d67d990b 100644 --- a/config/app.php +++ b/config/app.php @@ -74,7 +74,7 @@ * You should treat it as extremely sensitive data. */ 'Security' => [ - 'salt' => 'cf4515a2c1833f4aed69591f81598da0124cbd460449b2812495a64d8d70aadc' + 'salt' => env('OITC_SECURITY_SALT', 'cf4515a2c1833f4aed69591f81598da0124cbd460449b2812495a64d8d70aadc') ], /** @@ -105,8 +105,8 @@ 'serialize' => true, 'prefix' => 'oitc_', 'duration' => '+30 minute', - 'host' => '127.0.0.1', - 'port' => 6379 + 'host' => env('OITC_REDIS_HOST', '127.0.0.1'), + 'port' => env('OITC_REDIS_PORT', 6379) ], 'permissions' => [ @@ -114,8 +114,8 @@ 'serialize' => true, 'prefix' => 'permissions_', 'duration' => '+600 seconds', - 'host' => '127.0.0.1', - 'port' => 6379 + 'host' => env('OITC_REDIS_HOST', '127.0.0.1'), + 'port' => env('OITC_REDIS_PORT', 6379) ], 'long_time_cache' => [ @@ -123,8 +123,8 @@ 'serialize' => true, 'prefix' => 'ltc_', 'duration' => '+24 hours', - 'host' => '127.0.0.1', - 'port' => 6379 + 'host' => env('OITC_REDIS_HOST', '127.0.0.1'), + 'port' => env('OITC_REDIS_PORT', 6379) ], /** @@ -203,7 +203,7 @@ */ 'Error' => [ 'errorLevel' => E_ALL, - 'exceptionRenderer' => \Cake\Error\ExceptionRenderer::class, + 'exceptionRenderer' => \Cake\Error\Renderer\WebExceptionRenderer::class, 'skipLog' => [], 'log' => true, 'trace' => true, @@ -280,6 +280,6 @@ * To use database sessions, load the SQL file located at config/schema/sessions.sql */ 'Session' => [ - 'defaults' => env('SESSION_DEFAULTS', 'php'), + 'defaults' => env('OITC_SESSION_DEFAULTS', 'php'), ], ]; diff --git a/config/bootstrap.php b/config/bootstrap.php index 73d943b9f2..e8309af3c8 100644 --- a/config/bootstrap.php +++ b/config/bootstrap.php @@ -243,29 +243,3 @@ //Inflector::rules('uninflected', ['dontinflectme']); //Inflector::rules('transliteration', ['/å/' => 'aa']); - -//Configure CakePHP and WkHtmlToPdf -//default path of apt-get install wkhtmltopdf (Mostly old and broken) -$WkHtmlToPdfBinary = '/usr/bin/wkhtmltopdf'; -if (file_exists('/usr/local/bin/wkhtmltopdf')) { - //Installed from deb file from https://wkhtmltopdf.org/ (newer version and working) - $WkHtmlToPdfBinary = '/usr/local/bin/wkhtmltopdf'; -} -Configure::write('CakePdf', [ - 'engine' => [ - 'className' => 'CakePdf.WkHtmlToPdf', - // Mac OS X / Linux is usually like: - 'binary' => $WkHtmlToPdfBinary, - // On Windows environmnent you NEED to use the path like - // old fashioned MS-DOS Paths, otherwise you will keep getting: - // WKHTMLTOPDF didn't return any data - // 'binary' => 'C:\\Progra~1\\wkhtmltopdf\\bin\\wkhtmltopdf.exe', - // 'cwd' => 'C:\\Progra~1\\wkhtmltopdf\\bin', - 'options' => [ - 'print-media-type' => true, - 'outline' => true, - 'dpi' => 96, - 'enable-local-file-access' => true, - ], - ], -]); From f0b1b8b7519ebffe3a25ae980245301ab55edd4e Mon Sep 17 00:00:00 2001 From: nook24 Date: Mon, 8 May 2023 15:40:24 +0200 Subject: [PATCH 02/54] ITC-2986 Grab config from environment --- config/app.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/app.php b/config/app.php index a4d67d990b..e1b257eb52 100644 --- a/config/app.php +++ b/config/app.php @@ -106,7 +106,7 @@ 'prefix' => 'oitc_', 'duration' => '+30 minute', 'host' => env('OITC_REDIS_HOST', '127.0.0.1'), - 'port' => env('OITC_REDIS_PORT', 6379) + 'port' => filter_var(env('OITC_REDIS_PORT', 6379), FILTER_VALIDATE_INT) ], 'permissions' => [ @@ -115,7 +115,7 @@ 'prefix' => 'permissions_', 'duration' => '+600 seconds', 'host' => env('OITC_REDIS_HOST', '127.0.0.1'), - 'port' => env('OITC_REDIS_PORT', 6379) + 'port' => filter_var(env('OITC_REDIS_PORT', 6379), FILTER_VALIDATE_INT) ], 'long_time_cache' => [ @@ -124,7 +124,7 @@ 'prefix' => 'ltc_', 'duration' => '+24 hours', 'host' => env('OITC_REDIS_HOST', '127.0.0.1'), - 'port' => env('OITC_REDIS_PORT', 6379) + 'port' => filter_var(env('OITC_REDIS_PORT', 6379), FILTER_VALIDATE_INT) ], /** From 100d03eb8377a5098a5c489f8fa1de90257de445 Mon Sep 17 00:00:00 2001 From: nook24 Date: Tue, 9 May 2023 09:40:06 +0200 Subject: [PATCH 03/54] ITC-2986 Add option to generate config files inside of docker containers --- CONTAINER_SETUP.sh | 241 ++++++++++++++++++ src/Command/ConfigGeneratorShellCommand.php | 32 ++- .../ConfigGenerator/AfterExport.php | 28 +- .../ConfigGenerator/ConfigInterface.php | 2 +- .../ContainerConfigInterface.php | 35 +++ .../ConfigGenerator/DbBackend.php | 12 +- .../openITCOCKPIT/ConfigGenerator/Gearman.php | 32 ++- .../ConfigGenerator/GeneratorRegistry.php | 22 ++ .../ConfigGenerator/NSTAMaster.php | 28 +- .../ConfigGenerator/PerfdataBackend.php | 12 +- .../ConfigGenerator/PhpFpmOitc.php | 24 +- 11 files changed, 452 insertions(+), 16 deletions(-) create mode 100644 CONTAINER_SETUP.sh create mode 100644 src/itnovum/openITCOCKPIT/ConfigGenerator/ContainerConfigInterface.php diff --git a/CONTAINER_SETUP.sh b/CONTAINER_SETUP.sh new file mode 100644 index 0000000000..5daa1b1a1a --- /dev/null +++ b/CONTAINER_SETUP.sh @@ -0,0 +1,241 @@ +#!/bin/bash +# This SETUP Script should ONLY BE USED WHEN running inside of an container like for example Docker + +if ! [ $(id -u) = 0 ]; then + echo "You need to run this script as root user or via sudo!" + exit 1 +fi + +# Enable debug mode so that CakePHP will create missing folders +# https://github.com/it-novum/openITCOCKPIT/issues/1446 +# https://github.com/cakephp/migrations/issues/565 +export OITC_DEBUG=1 + +APPDIR="/opt/openitc/frontend" + +INIFILE=/opt/openitc/etc/mysql/mysql.cnf +DUMPINIFILE=/opt/openitc/etc/mysql/dump.cnf +BASHCONF=/opt/openitc/etc/mysql/bash.conf + +DEBIANCNF=/etc/mysql/debian.cnf + +MYSQL_USER="openitcockpit" +MYSQL_DATABASE="openitcockpit" +MYSQL_PASSWORD=$(pwgen -s -1 16) + +PHPVersion=$(php -r "echo substr(PHP_VERSION, 0, 3);") + +OSVERSION=$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2) +OS_BASE="debian" + +echo "Copy required system files" +cp ${APPDIR}/system/nginx/ssl_options_$OSVERSION /etc/nginx/openitc/ssl_options.conf +cp ${APPDIR}/system/nginx/ssl_cert.conf /etc/nginx/openitc/ssl_cert.conf +echo "# This file will NOT be overwritten during an update" >> /etc/nginx/openitc/custom.conf +chmod +x /usr/bin/oitc + +echo "Create required system folders" +mkdir -p /opt/openitc/etc/{mysql,grafana,carbon,frontend,nagios,nsta} +mkdir -p /opt/openitc/nagios/etc/config +mkdir -p /opt/openitc/etc/nagios/nagios.cfg.d + +chown www-data:www-data /opt/openitc/logs/frontend +chown nagios:www-data /opt/openitc/nagios/etc/config +chown nagios:www-data /opt/openitc/etc/nagios/nagios.cfg.d +chmod 775 /opt/openitc/logs/frontend + +chown www-data:www-data /opt/openitc/frontend/tmp + +mkdir -p /opt/openitc/frontend/webroot/img/charts +chown www-data:www-data /opt/openitc/frontend/webroot/img/charts + +if [[ -d /opt/openitc/frontend/plugins/MapModule/webroot/img/ ]]; then + chown -R www-data:www-data /opt/openitc/frontend/plugins/MapModule/webroot/img/ +fi + +#mkdir -p /opt/openitc/var/prometheus +#chown nagios:nagios /opt/openitc/var/prometheus +#mkdir -p /opt/openitc/var/prometheus/victoria-metrics + +echo "---------------------------------------------------------------" +echo "Import openITCOCKPIT Core database schema" +oitc migrations migrate + + +echo "---------------------------------------------------------------" +echo "Load default database" +oitc migrations seed + +echo "Running openITCOCKPIT Module database migration/s" +for PLUGIN in $(ls -1 "${APPDIR}/plugins"); do + if [[ "$PLUGIN" == *Module ]]; then + if [[ -d "${APPDIR}/plugins/${PLUGIN}/config/Migrations" ]]; then + echo "Running openITCOCKPIT ${PLUGIN} database migration" + oitc migrations migrate -p "${PLUGIN}" + fi + + if [[ -d "${APPDIR}/plugins/${PLUGIN}/config/Seeds" ]]; then + num_files=$(find "${APPDIR}/plugins/${PLUGIN}/config/Seeds" -mindepth 1 -iname "*.php" -type f | wc -l) + if [[ "$num_files" -gt 0 ]]; then + echo "Importing default records for ${PLUGIN} into database" + oitc migrations seed -p "${PLUGIN}" + fi + fi + + fi +done + +if [ -d "${APPDIR}/plugins/CheckmkModule/src" ]; then + oitc checkmkNagiosExport --init +fi + +echo "---------------------------------------------------------------" +echo "Create new WebSocket Key" +WEBSOCKET_KEY=$(php -r "echo bin2hex(openssl_random_pseudo_bytes(80, \$cstrong));") +mysql "--defaults-extra-file=${INIFILE}" -e "UPDATE systemsettings SET \`systemsettings\`.\`value\`='${WEBSOCKET_KEY}' WHERE \`key\`='SUDO_SERVER.API_KEY';" + +if [ ! -f /opt/openitc/etc/grafana/admin_password ]; then + echo "Generate new Grafana password for user 'admin'" + pwgen 10 1 > /opt/openitc/etc/grafana/admin_password +fi + +oitc config_generator_shell --generate-container + +echo "---------------------------------------------------------------" +echo "Configure Grafana" + +ADMIN_PASSWORD=$(cat /opt/openitc/etc/grafana/admin_password) + +if [ ! -f /opt/openitc/etc/grafana/api_key ]; then + echo "Create new Grafana API Key for openITCOCKPIT" + COUNTER=0 + + set +e + while [ "$COUNTER" -lt 30 ]; do + echo "Try to connect to Grafana API..." + #Is Grafana Server Online? + STATUSCODE=$(curl --noproxy 'grafana' "http://$OITC_GRAFANA_URL/api/admin/stats" -XGET -uadmin:$ADMIN_PASSWORD -H 'Content-Type: application/json' -I 2>/dev/null | head -n 1 | cut -d$' ' -f2) + + if [ "$STATUSCODE" == "200" ]; then + API_KEY=$(curl --noproxy 'grafana' "http://$OITC_GRAFANA_URL/api/auth/keys" -XPOST -uadmin:$ADMIN_PASSWORD -H 'Content-Type: application/json' -d '{"role":"Editor","name":"openITCOCKPIT"}' | jq -r '.key') + echo "$API_KEY" >/opt/openitc/etc/grafana/api_key + break + fi + COUNTER=$((COUNTER + 1)) + sleep 1 + done + + if [ ! -f /opt/openitc/etc/grafana/api_key ]; then + echo "ERROR!" + echo "Could not create API key for Grafana" + fi + set -e +fi + +echo "Check if Graphite Datasource exists in Grafana" +DS_STATUSCODE=$(curl --noproxy 'grafana' "http://$OITC_GRAFANA_URL/api/datasources/name/Graphite" -XGET -uadmin:$ADMIN_PASSWORD -H 'Content-Type: application/json' -I 2>/dev/null | head -n 1 | cut -d$' ' -f2) +if [ "$DS_STATUSCODE" == "404" ]; then + echo "Create Graphite as default Datasource for Grafana" + RESPONSE=$(curl --noproxy 'grafana' "http://$OITC_GRAFANA_URL/api/datasources" -XPOST -uadmin:$ADMIN_PASSWORD -H 'Content-Type: application/json' -d '{ + "name":"Graphite", + "type":"graphite", + "url":"http://graphite-web:8080", + "access":"proxy", + "basicAuth":false, + "isDefault": true, + "jsonData": { + "graphiteVersion": 1.1 + } + }') + echo $RESPONSE | jq . +fi +echo "Ok: Graphite datasource exists." + +echo "Check if Prometheus/VictoriaMetrics Datasource exists in Grafana" +DS_STATUSCODE=$(curl --noproxy 'grafana' "http://$OITC_GRAFANA_URL/api/datasources/name/Prometheus" -XGET -uadmin:$ADMIN_PASSWORD -H 'Content-Type: application/json' -I 2>/dev/null | head -n 1 | cut -d$' ' -f2) +if [ "$DS_STATUSCODE" == "404" ]; then + echo "Create Prometheus/VictoriaMetrics Datasource for Grafana" + RESPONSE=$(curl --noproxy 'grafana' "http://$OITC_GRAFANA_URL/api/datasources" -XPOST -uadmin:$ADMIN_PASSWORD -H 'Content-Type: application/json' -d '{ + "name":"Prometheus", + "type":"prometheus", + "url":"http://victoriametrics:8428", + "access":"proxy", + "basicAuth":false, + "isDefault": false, + "jsonData": {} + }') + echo $RESPONSE | jq . +fi +echo "Ok: Prometheus/VictoriaMetrics datasource exists." + +if [ -f /opt/openitc/etc/grafana/api_key ]; then + echo "Check for Grafana Configuration in openITCOCKPIT database" + API_KEY=$(cat /opt/openitc/etc/grafana/api_key) + set +e + COUNT=$(mysql "--defaults-extra-file=$INIFILE" -e "SELECT COUNT(*) FROM grafana_configurations;" -B -s 2>/dev/null) + if [ "$?" == 0 ] && [ "$COUNT" == 0 ]; then + echo "Create missing default configuration." + mysql --defaults-extra-file=${INIFILE} -e "INSERT INTO grafana_configurations (api_url, api_key, graphite_prefix, use_https, use_proxy, ignore_ssl_certificate, dashboard_style, created, modified) VALUES('grafana.docker', '${API_KEY}', 'openitcockpit', 1, 0, 1, 'light', '2018-12-05 08:42:55', '2018-12-05 08:42:55');" + fi + set -e +fi + +echo "---------------------------------------------------------------" +echo "Scan and import ACL objects. This will take a while..." +oitc Acl.acl_extras aco_sync + + +oitc compress + +oitc setup --fast + +oitc nagios_export + +if [[ -d "/opt/openitc/nagios/rollout" ]]; then + if [[ ! -f "/opt/openitc/nagios/rollout/resource.cfg" ]]; then + ln -s /opt/openitc/nagios/etc/resource.cfg /opt/openitc/nagios/rollout/resource.cfg + fi +fi + +echo "Enabling webserver configuration" +ln -s /etc/nginx/sites-available/openitc /etc/nginx/sites-enabled/openitc +rm -f /etc/nginx/sites-enabled/default + +#systemctl restart\ +# statusengine.service\ +# nagios.service\ +# nginx.service\ +# sudo_server.service\ +# oitc_cmd.service\ +# gearman_worker.service\ +# push_notification.service\ +# openitcockpit-node.service\ +# oitc_cronjobs.timer + +#echo "Detected PHP Version: ${PHPVersion} try to restart php-fpm" +# +#set +e +#systemctl is-enabled --quiet php${PHPVersion}-fpm.service &>/dev/null +#RC=$? +#if [ $RC -eq 0 ]; then +# #Is it php7.3-fpm-service ? +# systemctl restart php${PHPVersion}-fpm.service +#else +# # Is it just php-fpm.service? +# systemctl is-enabled --quiet php-fpm.service +# RC=$? +# if [ $RC -eq 0 ]; then +# systemctl restart php-fpm.service +# else +# echo "ERROR: could not detect php-fpm systemd service file. You need to restart php-fpm manualy" +# fi +#fi +#set -e + +#Set default permissions, check for always allowed permissions and dependencies +oitc roles --enable-defaults --admin + +date > /opt/openitc/etc/.installation_done + +#/opt/openitc/frontend/UPDATE.sh + diff --git a/src/Command/ConfigGeneratorShellCommand.php b/src/Command/ConfigGeneratorShellCommand.php index 088c973f6b..b4408075a2 100644 --- a/src/Command/ConfigGeneratorShellCommand.php +++ b/src/Command/ConfigGeneratorShellCommand.php @@ -54,9 +54,10 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar $parser = parent::buildOptionParser($parser); $parser->addOptions([ - 'generate' => ['help' => "Will generate all configuration files from database", 'boolean' => true, 'default' => false], - 'reload' => ['help' => "Reload services, where a new configuration file was generated for", 'boolean' => true, 'default' => false], - 'migrate' => ['help' => 'Will migrate existing configuration files to database', 'boolean' => true, 'default' => false] + 'generate' => ['help' => "Will generate all configuration files from database", 'boolean' => true, 'default' => false], + 'generate-container' => ['help' => "Will generate all configuration files from environment variables. Only use this option if openITCOCKPIT is running inside a container.", 'boolean' => true, 'default' => false], + 'reload' => ['help' => "Reload services, where a new configuration file was generated for", 'boolean' => true, 'default' => false], + 'migrate' => ['help' => 'Will migrate existing configuration files to database', 'boolean' => true, 'default' => false] ]); return $parser; @@ -82,6 +83,7 @@ public function execute(Arguments $args, ConsoleIo $io) { } if ($args->getOption('generate')) { + // Full installation of openITCOCKPIT (via apt, dnf or git clone) $hadJob = true; if ($args->getOption('reload')) { $this->generateAndReload($io); @@ -90,6 +92,12 @@ public function execute(Arguments $args, ConsoleIo $io) { } } + if ($args->getOption('generate-container')) { + // openITCOCKPIT is running inside a docker container + $hadJob = true; + $this->generateFromEnvironmentVariables($io); + } + if (!$hadJob) { $this->displayHelp($this->getOptionParser(), $args, $io); } @@ -113,6 +121,24 @@ private function generate(ConsoleIo $io) { } } + /** + * @param ConsoleIo $io + */ + private function generateFromEnvironmentVariables(ConsoleIo $io) { + $io->out('Generate all configuration files from environment variables... '); + /** @var ConfigurationFilesTable $ConfigurationFilesTable */ + $ConfigurationFilesTable = TableRegistry::getTableLocator()->get('ConfigurationFiles'); + + $GeneratorRegistry = new GeneratorRegistry(); + + foreach ($GeneratorRegistry->getAllConfigFilesForContainer() as $ConfigFileObject) { + /** @var ConfigInterface $ConfigFileObject */ + $io->out(sprintf('Generate %s ', $ConfigFileObject->getLinkedOutfile()), 0); + $ConfigFileObject->writeToFile($ConfigFileObject->getValuesFromEnvironment()); + $io->success('Ok'); + } + } + /** * @param ConsoleIo $io */ diff --git a/src/itnovum/openITCOCKPIT/ConfigGenerator/AfterExport.php b/src/itnovum/openITCOCKPIT/ConfigGenerator/AfterExport.php index ceda60280f..95be86342b 100644 --- a/src/itnovum/openITCOCKPIT/ConfigGenerator/AfterExport.php +++ b/src/itnovum/openITCOCKPIT/ConfigGenerator/AfterExport.php @@ -25,9 +25,10 @@ namespace itnovum\openITCOCKPIT\ConfigGenerator; +use App\itnovum\openITCOCKPIT\ConfigGenerator\ContainerConfigInterface; use Cake\Core\Configure; -class AfterExport extends ConfigGenerator implements ConfigInterface { +class AfterExport extends ConfigGenerator implements ConfigInterface, ContainerConfigInterface { protected $templateDir = 'config'; @@ -91,6 +92,31 @@ public function getHelpText($key) { return ''; } + public function getValuesFromEnvironment() { + return [ + [ + 'key' => 'username', + 'value' => env('OITC_AFTER_EXPORT_SSH_USERNAME', 'nagios'), + ], + [ + 'key' => 'private_key', + 'value' => env('OITC_AFTER_EXPORT_SSH_PRIVATE_KEY', '/var/lib/nagios/.ssh/id_rsa'), + ], + [ + 'key' => 'public_key', + 'value' => env('OITC_AFTER_EXPORT_SSH_PUBLIC_KEY', '/var/lib/nagios/.ssh/id_rsa.pub'), + ], + [ + 'key' => 'restart_command', + 'value' => env('OITC_AFTER_EXPORT_RESTART_COMMAND', 'sudo /opt/openitc/nagios/bin/restart-monitoring.sh'), + ], + [ + 'key' => 'remote_port', + 'value' => env('OITC_AFTER_EXPORT_SSH_REMOTE_PORT', 22), + ] + ]; + } + /** * Save the configuration as text file on disk * diff --git a/src/itnovum/openITCOCKPIT/ConfigGenerator/ConfigInterface.php b/src/itnovum/openITCOCKPIT/ConfigGenerator/ConfigInterface.php index f181edc592..19fead003b 100644 --- a/src/itnovum/openITCOCKPIT/ConfigGenerator/ConfigInterface.php +++ b/src/itnovum/openITCOCKPIT/ConfigGenerator/ConfigInterface.php @@ -72,4 +72,4 @@ public function getDbKey(); */ public function migrate($dbRecords); -} \ No newline at end of file +} diff --git a/src/itnovum/openITCOCKPIT/ConfigGenerator/ContainerConfigInterface.php b/src/itnovum/openITCOCKPIT/ConfigGenerator/ContainerConfigInterface.php new file mode 100644 index 0000000000..c916a29ed1 --- /dev/null +++ b/src/itnovum/openITCOCKPIT/ConfigGenerator/ContainerConfigInterface.php @@ -0,0 +1,35 @@ + +// +// This file is dual licensed +// +// 1. +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 3 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// 2. +// If you purchased an openITCOCKPIT Enterprise Edition you can use this file +// under the terms of the openITCOCKPIT Enterprise Edition license agreement. +// License agreement and license key will be shipped with the order +// confirmation. + +namespace App\itnovum\openITCOCKPIT\ConfigGenerator; + + +interface ContainerConfigInterface { + + /** + * @return array + */ + public function getValuesFromEnvironment(); + +} diff --git a/src/itnovum/openITCOCKPIT/ConfigGenerator/DbBackend.php b/src/itnovum/openITCOCKPIT/ConfigGenerator/DbBackend.php index 2b4b5ddf2c..f8af3a30ea 100644 --- a/src/itnovum/openITCOCKPIT/ConfigGenerator/DbBackend.php +++ b/src/itnovum/openITCOCKPIT/ConfigGenerator/DbBackend.php @@ -25,9 +25,10 @@ namespace itnovum\openITCOCKPIT\ConfigGenerator; +use App\itnovum\openITCOCKPIT\ConfigGenerator\ContainerConfigInterface; use Cake\Core\Configure; -class DbBackend extends ConfigGenerator implements ConfigInterface { +class DbBackend extends ConfigGenerator implements ConfigInterface, ContainerConfigInterface { protected $templateDir = 'config'; @@ -104,6 +105,15 @@ public function getHelpText($key) { return ''; } + public function getValuesFromEnvironment() { + return [ + [ + 'key' => 'dbbackend', + 'value' => env('OITC_DB_BACKEND', 'Statusengine3'), + ] + ]; + } + /** * Save the configuration as text file on disk * diff --git a/src/itnovum/openITCOCKPIT/ConfigGenerator/Gearman.php b/src/itnovum/openITCOCKPIT/ConfigGenerator/Gearman.php index a9ef80eba8..44050813fd 100644 --- a/src/itnovum/openITCOCKPIT/ConfigGenerator/Gearman.php +++ b/src/itnovum/openITCOCKPIT/ConfigGenerator/Gearman.php @@ -4,9 +4,10 @@ namespace itnovum\openITCOCKPIT\ConfigGenerator; +use App\itnovum\openITCOCKPIT\ConfigGenerator\ContainerConfigInterface; use Cake\Core\Configure; -class Gearman extends ConfigGenerator implements ConfigInterface { +class Gearman extends ConfigGenerator implements ConfigInterface, ContainerConfigInterface { /** @var string */ protected $templateDir = 'config'; /** @var string */ @@ -20,8 +21,8 @@ class Gearman extends ConfigGenerator implements ConfigInterface { /** @var array */ protected $defaults = [ 'string' => [ - 'address' => '127.0.0.1', - 'pidfile' => '/var/run/oitc_gearmanworker.pid', + 'address' => '127.0.0.1', + 'pidfile' => '/var/run/oitc_gearmanworker.pid', ], 'int' => [ 'port' => 4730, @@ -52,10 +53,10 @@ public function customValidationRules($data) { */ public function getHelpText($key) { $help = [ - 'address' => __('The host address where the gearman-job-server is running.'), - 'pidfile' => __('Process id file used by the gearman_worker.'), - 'port' => __('Port number of gearman-job-server.'), - 'worker' => __('Number of gearman_worker processes.') + 'address' => __('The host address where the gearman-job-server is running.'), + 'pidfile' => __('Process id file used by the gearman_worker.'), + 'port' => __('Port number of gearman-job-server.'), + 'worker' => __('Number of gearman_worker processes.') ]; if (isset($help[$key])) { @@ -65,6 +66,23 @@ public function getHelpText($key) { return ''; } + public function getValuesFromEnvironment() { + return [ + [ + 'key' => 'address', + 'value' => env('OITC_GEARMAN_ADDRESS', 'gearmand'), + ], + [ + 'key' => 'port', + 'value' => env('OITC_GEARMAN_PORT', 4730), + ], + [ + 'key' => 'worker', + 'value' => env('OITC_GEARMAM_WORKER', 5), + ] + ]; + } + /** * @param array $dbRecords * @return bool|int diff --git a/src/itnovum/openITCOCKPIT/ConfigGenerator/GeneratorRegistry.php b/src/itnovum/openITCOCKPIT/ConfigGenerator/GeneratorRegistry.php index 235a23500d..412bce71b2 100644 --- a/src/itnovum/openITCOCKPIT/ConfigGenerator/GeneratorRegistry.php +++ b/src/itnovum/openITCOCKPIT/ConfigGenerator/GeneratorRegistry.php @@ -33,6 +33,8 @@ class GeneratorRegistry { /** + * This function is used, when openITCOCKPIT is running on Bare-metal server / a Virtual Maschine and is + * installed via the package manager like apt or dnf * @return array */ public function getAllConfigFiles() { @@ -65,6 +67,26 @@ public function getAllConfigFiles() { return $configFiles; } + /** + * This function is used, when openITCOCKPIT is running inside a container like Docker, Podman etc. + * In this case, we don't need most of the config files, because the corresponding containers will generate + * configuration files (if necessary) by themselves. + * ITC-2986 + * @return array + */ + public function getAllConfigFilesForContainer(){ + $configFiles = [ + new AfterExport(), + new DbBackend(), + new PerfdataBackend(), + new Gearman(), + new NSTAMaster(), + new PhpFpmOitc() + ]; + + return $configFiles; + } + /** * @return array */ diff --git a/src/itnovum/openITCOCKPIT/ConfigGenerator/NSTAMaster.php b/src/itnovum/openITCOCKPIT/ConfigGenerator/NSTAMaster.php index 76b89a2f2d..52d95d7a6f 100644 --- a/src/itnovum/openITCOCKPIT/ConfigGenerator/NSTAMaster.php +++ b/src/itnovum/openITCOCKPIT/ConfigGenerator/NSTAMaster.php @@ -25,6 +25,7 @@ namespace itnovum\openITCOCKPIT\ConfigGenerator; +use App\itnovum\openITCOCKPIT\ConfigGenerator\ContainerConfigInterface; use itnovum\openITCOCKPIT\Core\System\Health\MonitoringEngine; /** @@ -32,7 +33,7 @@ * NSTA written in Go by Johannes * @package itnovum\openITCOCKPIT\ConfigGenerator */ -class NSTAMaster extends ConfigGenerator implements ConfigInterface { +class NSTAMaster extends ConfigGenerator implements ConfigInterface,ContainerConfigInterface { protected $templateDir = 'NSTA'; @@ -96,6 +97,31 @@ public function getHelpText($key) { return ''; } + public function getValuesFromEnvironment() { + return [ + [ + 'key' => 'listen_http', + 'value' => env('OITC_NSTA_LISTEN_HTTP', '127.0.0.1:7473'), + ], + [ + 'key' => 'listen_https', + 'value' => env('OITC_NSTA_LISTEN_HTTPS', '127.0.0.1:7474'), + ], + [ + 'key' => 'tls_key', + 'value' => env('OITC_NSTA_TLS_KEY', '/etc/ssl/private/ssl-cert-snakeoil.key'), + ], + [ + 'key' => 'tls_cert', + 'value' => env('OITC_NSTA_TLS_CERT', '/etc/ssl/certs/ssl-cert-snakeoil.pem'), + ], + [ + 'key' => 'use_nginx_proxy', + 'value' => env('OITC_NSTA_USE_NGINX_PROXY', 1), + ] + ]; + } + /** * Save the configuration as text file on disk * diff --git a/src/itnovum/openITCOCKPIT/ConfigGenerator/PerfdataBackend.php b/src/itnovum/openITCOCKPIT/ConfigGenerator/PerfdataBackend.php index 98ed1a5aee..588566b5e0 100644 --- a/src/itnovum/openITCOCKPIT/ConfigGenerator/PerfdataBackend.php +++ b/src/itnovum/openITCOCKPIT/ConfigGenerator/PerfdataBackend.php @@ -25,9 +25,10 @@ namespace itnovum\openITCOCKPIT\ConfigGenerator; +use App\itnovum\openITCOCKPIT\ConfigGenerator\ContainerConfigInterface; use Cake\Core\Configure; -class PerfdataBackend extends ConfigGenerator implements ConfigInterface { +class PerfdataBackend extends ConfigGenerator implements ConfigInterface,ContainerConfigInterface { protected $templateDir = 'config'; @@ -105,6 +106,15 @@ public function getHelpText($key) { return ''; } + public function getValuesFromEnvironment() { + return [ + [ + 'key' => 'perfdatabackend', + 'value' => env('OITC_PERFDATA_BACKEND', 'Whisper'), + ] + ]; + } + /** * Save the configuration as text file on disk * diff --git a/src/itnovum/openITCOCKPIT/ConfigGenerator/PhpFpmOitc.php b/src/itnovum/openITCOCKPIT/ConfigGenerator/PhpFpmOitc.php index 7491d0cbb0..9e592313a8 100644 --- a/src/itnovum/openITCOCKPIT/ConfigGenerator/PhpFpmOitc.php +++ b/src/itnovum/openITCOCKPIT/ConfigGenerator/PhpFpmOitc.php @@ -4,9 +4,10 @@ namespace itnovum\openITCOCKPIT\ConfigGenerator; +use App\itnovum\openITCOCKPIT\ConfigGenerator\ContainerConfigInterface; use Cake\Core\Configure; -class PhpFpmOitc extends ConfigGenerator implements ConfigInterface { +class PhpFpmOitc extends ConfigGenerator implements ConfigInterface, ContainerConfigInterface { /** @var string */ protected $templateDir = 'PhpFpmOitc'; /** @var string */ @@ -86,6 +87,27 @@ public function getHelpText($key) { return ''; } + public function getValuesFromEnvironment() { + return [ + [ + 'key' => 'max_children', + 'value' => env('OITC_PHP_FPM_PM_MAX_CHILDREN', 5), + ], + [ + 'key' => 'start_servers', + 'value' => env('OITC_PHP_FPM_PM_START_SERVERS', 2), + ], + [ + 'key' => 'min_spare_servers', + 'value' => env('OITC_PHP_FPM_PM_MIN_SPARE_SERVERS', 1), + ], + [ + 'key' => 'max_spare_servers', + 'value' => env('OITC_PHP_FPM_PM_MAX_SPARE_SERVERS', 3), + ] + ]; + } + /** * @param array $dbRecords * @return bool|int From e708e438d39fa405fc61e7de590314f13dba2e50 Mon Sep 17 00:00:00 2001 From: nook24 Date: Tue, 9 May 2023 10:47:38 +0200 Subject: [PATCH 04/54] ITC-2986 Generate config files from env --- CONTAINER_SETUP.sh | 6 ------ .../ConfigGenerator/ConfigGenerator.php | 7 +++++++ system/usr/bin/oitc | 12 ++++++------ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/CONTAINER_SETUP.sh b/CONTAINER_SETUP.sh index 5daa1b1a1a..48eb37afdc 100644 --- a/CONTAINER_SETUP.sh +++ b/CONTAINER_SETUP.sh @@ -17,12 +17,6 @@ INIFILE=/opt/openitc/etc/mysql/mysql.cnf DUMPINIFILE=/opt/openitc/etc/mysql/dump.cnf BASHCONF=/opt/openitc/etc/mysql/bash.conf -DEBIANCNF=/etc/mysql/debian.cnf - -MYSQL_USER="openitcockpit" -MYSQL_DATABASE="openitcockpit" -MYSQL_PASSWORD=$(pwgen -s -1 16) - PHPVersion=$(php -r "echo substr(PHP_VERSION, 0, 3);") OSVERSION=$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2) diff --git a/src/itnovum/openITCOCKPIT/ConfigGenerator/ConfigGenerator.php b/src/itnovum/openITCOCKPIT/ConfigGenerator/ConfigGenerator.php index e01b005589..914253675b 100644 --- a/src/itnovum/openITCOCKPIT/ConfigGenerator/ConfigGenerator.php +++ b/src/itnovum/openITCOCKPIT/ConfigGenerator/ConfigGenerator.php @@ -300,6 +300,13 @@ public function mergeDbResultWithDefaultConfiguration($dbRecords) { private function flatDbResult($dbResult) { $result = []; foreach ($dbResult as $record) { + // ITC-2986 make default settings from environment variable look like from the database + if(!isset($record['ConfigurationFile'])){ + $record = [ + 'ConfigurationFile' => $record + ]; + } + $result[$record['ConfigurationFile']['key']] = $record['ConfigurationFile']['value']; } return $result; diff --git a/system/usr/bin/oitc b/system/usr/bin/oitc index 779b7af2c3..ea1bc09d39 100644 --- a/system/usr/bin/oitc +++ b/system/usr/bin/oitc @@ -1,10 +1,10 @@ #!/bin/bash - -preserveEnvSupportsList=$(sudo --help |grep "preserve-env" | wc -l) -if [[ $preserveEnvSupportsList -gt 1 ]]; then - sudo -g www-data --preserve-env=OITC_DEBUG /opt/openitc/frontend/bin/cake "$@" -else +# ITC-2986 keep all environment variables for config generation inside of docker containers +##preserveEnvSupportsList=$(sudo --help |grep "preserve-env" | wc -l) +##if [[ $preserveEnvSupportsList -gt 1 ]]; then +## sudo -g www-data --preserve-env=OITC_DEBUG /opt/openitc/frontend/bin/cake "$@" +##else # Old sudo version that does not support list of environment variables to preserve # Added with 9bb78048656f 2017-08-03 sudo -g www-data --preserve-env /opt/openitc/frontend/bin/cake "$@" -fi +##fi From 511af336b61b8ca256e488a751b88f807b41184b Mon Sep 17 00:00:00 2001 From: nook24 Date: Tue, 9 May 2023 11:07:04 +0200 Subject: [PATCH 05/54] ITC-2986 add missing config files in container --- CONTAINER_SETUP.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CONTAINER_SETUP.sh b/CONTAINER_SETUP.sh index 48eb37afdc..e3d2617a34 100644 --- a/CONTAINER_SETUP.sh +++ b/CONTAINER_SETUP.sh @@ -23,6 +23,9 @@ OSVERSION=$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2) OS_BASE="debian" echo "Copy required system files" +rsync -K -a ${APPDIR}/system/etc/. /etc/ # we use rsync because the destination can be a symlink on RHEL +chown root:root /etc +cp -r ${APPDIR}/system/usr/. /usr/ cp ${APPDIR}/system/nginx/ssl_options_$OSVERSION /etc/nginx/openitc/ssl_options.conf cp ${APPDIR}/system/nginx/ssl_cert.conf /etc/nginx/openitc/ssl_cert.conf echo "# This file will NOT be overwritten during an update" >> /etc/nginx/openitc/custom.conf From 1a0dfb2415e851697cd38679e7be5d6c13e5fbbb Mon Sep 17 00:00:00 2001 From: nook24 Date: Tue, 9 May 2023 14:50:06 +0200 Subject: [PATCH 06/54] ITC-2986 Wait for Statusengine --- CONTAINER_SETUP.sh | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/CONTAINER_SETUP.sh b/CONTAINER_SETUP.sh index e3d2617a34..f0f2679e33 100644 --- a/CONTAINER_SETUP.sh +++ b/CONTAINER_SETUP.sh @@ -50,6 +50,34 @@ if [[ -d /opt/openitc/frontend/plugins/MapModule/webroot/img/ ]]; then chown -R www-data:www-data /opt/openitc/frontend/plugins/MapModule/webroot/img/ fi +# It is important that the statusengine-worker container is already up and running and has created all +# the Statusengine related MySQL tables, because the setup will add partitions to the tables +echo "Checking if Statusengine Tables where already created..." +COUNTER=0 +MYSQL_ONLINE=0 + +set +e +while [ "$COUNTER" -lt 30 ]; do + #Is Grafana Server Online? + OUTPUT=$(mysql "--defaults-extra-file=$INIFILE" -e "SELECT 1 FROM statusengine_nodes;" -B -s 2>/dev/null) + + if [ "$OUTPUT" ]; then + echo "Tables are present." + MYSQL_ONLINE=1 + break + fi + echo "Waiting for Statusengine to create tables..." + COUNTER=$((COUNTER + 1)) + sleep 1 +done + +if [[ "$MYSQL_ONLINE" == 0 ]]; then + echo "ERROR!" + echo "Statusengine tables are missing! ABORT!" + exit 1 +fi +set -e + #mkdir -p /opt/openitc/var/prometheus #chown nagios:nagios /opt/openitc/var/prometheus #mkdir -p /opt/openitc/var/prometheus/victoria-metrics From 7007a2820cee83f971283b30ba0e926a7356d210 Mon Sep 17 00:00:00 2001 From: nook24 Date: Tue, 9 May 2023 15:44:53 +0200 Subject: [PATCH 07/54] ITC-2986 Add ne IS_CONTAINER constant --- config/app.php | 5 +++++ config/bootstrap.php | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/config/app.php b/config/app.php index e1b257eb52..cc95e823dc 100644 --- a/config/app.php +++ b/config/app.php @@ -17,6 +17,11 @@ */ 'debug' => filter_var(env('OITC_DEBUG', false), FILTER_VALIDATE_BOOLEAN), + /** + * If set to true, openITCOCKPIT is running inside a container like Docker + */ + 'container' => filter_var(env('IS_CONTAINER', false), FILTER_VALIDATE_BOOLEAN), + /** * Configure basic information about the application. * diff --git a/config/bootstrap.php b/config/bootstrap.php index e8309af3c8..b73f6fa9ae 100644 --- a/config/bootstrap.php +++ b/config/bootstrap.php @@ -112,6 +112,13 @@ } } +if (!defined('IS_CONTAINER')) { + if (Configure::read('container') === true) { + define('IS_CONTAINER', true); + } else { + define('IS_CONTAINER', false); + } +} /* * Load an environment local configuration file to provide overrides to your configuration. From b0daa9b62eee750a3da84271ba450e74110314db Mon Sep 17 00:00:00 2001 From: nook24 Date: Tue, 9 May 2023 15:45:16 +0200 Subject: [PATCH 08/54] ITC-2986 Fix MonitoringEngine class when running in container --- .../Core/System/Health/MonitoringEngine.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php b/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php index bf0b426a1e..bb1307d498 100644 --- a/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php +++ b/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php @@ -138,6 +138,10 @@ class MonitoringEngine { private $delimiter = '|'; public function __construct() { + if (IS_CONTAINER) { + // We always use Naemon for containers + return 'Naemon Core Container'; + } Configure::load('nagios'); exec(Configure::read('nagios.basepath') . Configure::read('nagios.bin') . Configure::read('nagios.nagios_bin') . ' --version | head -n 2', $output); @@ -155,6 +159,11 @@ public function getMonitoringEngine() { * @return bool */ public function isNaemon() { + if (IS_CONTAINER) { + // We always use Naemon for containers + return true; + } + $monitoringEngine = strtolower($this->monitoringEngine); if (preg_match('/naemon/', $monitoringEngine)) { return true; @@ -187,12 +196,12 @@ public function getNagiostatsCommand() { /** * @return array|false */ - public function runNagiostats(){ + public function runNagiostats() { exec($this->getNagiostatsCommand(), $output); - // Nagios and Naemon add the delimiter also the the end of the string - // this is bad, because explode will create and empty value in the array - // and this throw a warning in array_combine + // Nagios and Naemon add the delimiter also the the end of the string + // this is bad, because explode will create and empty value in the array + // and this throw a warning in array_combine $result = explode($this->delimiter, $output[0]); $result_sizeof = sizeof($result); if (sizeof($this->MRTG) < $result_sizeof) { From ee165a61d97f03e67e2f71b2805d5487fb614067 Mon Sep 17 00:00:00 2001 From: nook24 Date: Tue, 9 May 2023 16:06:39 +0200 Subject: [PATCH 09/54] ITC-2986 Pass IS_CONTAINER constant to config file generator and keep env variables in php-fpm --- src/config_templates/PhpFpmOitc/oitc.conf.tpl | 4 ++++ src/itnovum/openITCOCKPIT/ConfigGenerator/ConfigGenerator.php | 1 + 2 files changed, 5 insertions(+) diff --git a/src/config_templates/PhpFpmOitc/oitc.conf.tpl b/src/config_templates/PhpFpmOitc/oitc.conf.tpl index 42ef8bfbb2..1e6834bc2a 100644 --- a/src/config_templates/PhpFpmOitc/oitc.conf.tpl +++ b/src/config_templates/PhpFpmOitc/oitc.conf.tpl @@ -375,7 +375,11 @@ pm.max_spare_servers = {{max_spare_servers}} ; Setting to "no" will make all environment variables available to PHP code ; via getenv(), $_ENV and $_SERVER. ; Default Value: yes +{% if IS_CONTAINER %} +clear_env = no +{% else %} ;clear_env = no +{% endif %} ; Limits the extensions of the main script FPM will allow to parse. This can ; prevent configuration mistakes on the web server side. You should only limit diff --git a/src/itnovum/openITCOCKPIT/ConfigGenerator/ConfigGenerator.php b/src/itnovum/openITCOCKPIT/ConfigGenerator/ConfigGenerator.php index 914253675b..b2760160fa 100644 --- a/src/itnovum/openITCOCKPIT/ConfigGenerator/ConfigGenerator.php +++ b/src/itnovum/openITCOCKPIT/ConfigGenerator/ConfigGenerator.php @@ -351,6 +351,7 @@ protected function saveConfigFile($configToExport) { $FileHeader = new FileHeader(); $configToExport['STATIC_FILE_HEADER'] = $FileHeader->getHeader($this->commentChar); + $configToExport['IS_CONTAINER'] = IS_CONTAINER; $configDir = dirname($this->realOutfile); if (!is_dir($configDir)) { From a716d63113bfc2fe44f1b34d0284d29d44706532 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 10 May 2023 11:21:07 +0200 Subject: [PATCH 10/54] ITC-2986 Add graphite web config --- .../ConfigGenerator/GeneratorRegistry.php | 1 + .../ConfigGenerator/GraphiteWeb.php | 29 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/itnovum/openITCOCKPIT/ConfigGenerator/GeneratorRegistry.php b/src/itnovum/openITCOCKPIT/ConfigGenerator/GeneratorRegistry.php index 412bce71b2..71b16c984e 100644 --- a/src/itnovum/openITCOCKPIT/ConfigGenerator/GeneratorRegistry.php +++ b/src/itnovum/openITCOCKPIT/ConfigGenerator/GeneratorRegistry.php @@ -80,6 +80,7 @@ public function getAllConfigFilesForContainer(){ new DbBackend(), new PerfdataBackend(), new Gearman(), + new GraphiteWeb(), new NSTAMaster(), new PhpFpmOitc() ]; diff --git a/src/itnovum/openITCOCKPIT/ConfigGenerator/GraphiteWeb.php b/src/itnovum/openITCOCKPIT/ConfigGenerator/GraphiteWeb.php index 8e5eebd51b..fe3c46a807 100644 --- a/src/itnovum/openITCOCKPIT/ConfigGenerator/GraphiteWeb.php +++ b/src/itnovum/openITCOCKPIT/ConfigGenerator/GraphiteWeb.php @@ -25,7 +25,9 @@ namespace itnovum\openITCOCKPIT\ConfigGenerator; -class GraphiteWeb extends ConfigGenerator implements ConfigInterface { +use App\itnovum\openITCOCKPIT\ConfigGenerator\ContainerConfigInterface; + +class GraphiteWeb extends ConfigGenerator implements ConfigInterface,ContainerConfigInterface { protected $templateDir = 'config'; @@ -98,6 +100,31 @@ public function getHelpText($key) { return ''; } + public function getValuesFromEnvironment() { + return [ + [ + 'key' => 'graphite_web_host', + 'value' => env('OITC_GRAPHITE_WEB_ADDRESS', '127.0.0.1'), + ], + [ + 'key' => 'graphite_prefix', + 'value' => env('OITC_GRAPHITE_PREFIX', 'openitcockpit'), + ], + [ + 'key' => 'graphite_web_port', + 'value' => env('OITC_GRAPHITE_WEB_PORT', 8888), + ], + [ + 'key' => 'use_https', + 'value' => env('OITC_GRAPHITE_USE_HTTPS', 0), + ], + [ + 'key' => 'use_proxy', + 'value' => env('OITC_GRAPHITE_USE_PROXY', 0), + ] + ]; + } + /** * Save the configuration as text file on disk * From 8fbb1ea815c6cf9f11c5f5ec38cbbdd6c40c6e40 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 10 May 2023 13:59:43 +0200 Subject: [PATCH 11/54] ITC-2986 Do not show query handler error when running in container --- src/Controller/AngularController.php | 6 ++++-- src/Template/Angular/queryhandler.php | 2 +- src/itnovum/openITCOCKPIT/Monitoring/QueryHandler.php | 10 +++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Controller/AngularController.php b/src/Controller/AngularController.php index 307ef29209..f926bbdd8a 100644 --- a/src/Controller/AngularController.php +++ b/src/Controller/AngularController.php @@ -1003,8 +1003,9 @@ public function queryhandler() { $QueryHandler = new QueryHandler($SystemsettingsTable->getQueryHandlerPath()); $this->set('QueryHandler', [ - 'exists' => $QueryHandler->exists(), - 'path' => $QueryHandler->getPath() + 'exists' => $QueryHandler->exists(), + 'path' => $QueryHandler->getPath(), + 'isContainer' => $QueryHandler->isContainer() ]); $this->viewBuilder()->setOption('serialize', ['QueryHandler']); @@ -1258,6 +1259,7 @@ public function regexHelperTooltip() { //Return HTML Template for PaginatorDirective return; } + public function ackTooltip() { //Only ship HTML template return; diff --git a/src/Template/Angular/queryhandler.php b/src/Template/Angular/queryhandler.php index 6f4bd5b032..b0bb219a4d 100644 --- a/src/Template/Angular/queryhandler.php +++ b/src/Template/Angular/queryhandler.php @@ -1,4 +1,4 @@ -
+

diff --git a/src/itnovum/openITCOCKPIT/Monitoring/QueryHandler.php b/src/itnovum/openITCOCKPIT/Monitoring/QueryHandler.php index 8cb2e6546d..97936e25b6 100644 --- a/src/itnovum/openITCOCKPIT/Monitoring/QueryHandler.php +++ b/src/itnovum/openITCOCKPIT/Monitoring/QueryHandler.php @@ -106,6 +106,14 @@ public function getPath() { return $this->queryHandler; } + /** + * When openITCOCKPIT is running in a Docker container, it HAS NO ACCESS to the query handler socket + * @return bool + */ + public function isContainer(){ + return IS_CONTAINER; + } + /** * @return string */ @@ -190,4 +198,4 @@ private function terminate() { $this->query .= "\0"; } -} \ No newline at end of file +} From d6d7a0b0400fefc036ded644701c2149001e6a58 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 10 May 2023 14:52:19 +0200 Subject: [PATCH 12/54] ITC-2986 Add container check to Packetmanager --- src/Controller/PacketmanagerController.php | 43 +++++++----- src/Template/Packetmanager/index.php | 77 ++++++++++++++-------- 2 files changed, 76 insertions(+), 44 deletions(-) diff --git a/src/Controller/PacketmanagerController.php b/src/Controller/PacketmanagerController.php index da54e7281f..1cb52d6b20 100644 --- a/src/Controller/PacketmanagerController.php +++ b/src/Controller/PacketmanagerController.php @@ -91,26 +91,35 @@ public function index() { $installedModules = []; $output = []; - $LsbRelease = new LsbRelease(); - if ($LsbRelease->isDebianBased()) { - exec('dpkg -l |grep openitcockpit-module', $output, $rc); - //$output = $this->getTestDpkgOutput(); - } - - if ($LsbRelease->isRhelBased()) { - exec('dnf list installed | grep openitcockpit-module', $output, $rc); - //$output = $this->getTestDnfOutput(); - } + if (!IS_CONTAINER) { + $LsbRelease = new LsbRelease(); + if ($LsbRelease->isDebianBased()) { + exec('dpkg -l |grep openitcockpit-module', $output, $rc); + //$output = $this->getTestDpkgOutput(); + } - foreach ($output as $line) { - preg_match_all('/(openitcockpit\-module\-\w+)/', $line, $matches); - if (isset($matches[0][0])) { - $module = $matches[0][0]; - $installedModules[$module] = true; + if ($LsbRelease->isRhelBased()) { + exec('dnf list installed | grep openitcockpit-module', $output, $rc); + //$output = $this->getTestDnfOutput(); } - if (isset($matches)) { - unset($matches); + foreach ($output as $line) { + preg_match_all('/(openitcockpit\-module\-\w+)/', $line, $matches); + if (isset($matches[0][0])) { + $module = $matches[0][0]; + $installedModules[$module] = true; + } + + if (isset($matches)) { + unset($matches); + } + } + } else { + // Container based version of openITCOCKPIT have always all modules enabled + if (isset($result['data']['modules'])) { + foreach ($result['data']['modules'] as $module) { + $installedModules[$module['Module']['apt_name']] = true; + } } } diff --git a/src/Template/Packetmanager/index.php b/src/Template/Packetmanager/index.php index 527e04e170..d0ed9c8305 100755 --- a/src/Template/Packetmanager/index.php +++ b/src/Template/Packetmanager/index.php @@ -49,34 +49,57 @@ + + + element('repository_checker'); ?> + + getCodename() === 'bionic'): ?> +
+ × +

+ + +

+ + +
+ support@itsm.it-novum.com'); ?> +
+ + + getCodename() === 'buster'): ?> +
+ × +

+ + +

+ + +
+ support@itsm.it-novum.com'); ?> +
+ + + +
+
+
+ + + + +
+
+ + + +
+ + +
-element('repository_checker'); ?> - -getCodename() === 'bionic'): ?> -
- × -

- - -

- - -
- support@itsm.it-novum.com'); ?> -
- - -getCodename() === 'buster'): ?> -
- × -

- - -

- - -
- support@itsm.it-novum.com'); ?> +
From f10c6672cf3dbafeb5ad2746e03a7f6cc365f7b9 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 10 May 2023 15:33:09 +0200 Subject: [PATCH 13/54] ITC-2986 Disable config file editor when running in a container --- .../ConfigurationFilesController.php | 43 +++++++++++++------ src/Template/ConfigurationFiles/index.php | 23 ++++++++++ 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/src/Controller/ConfigurationFilesController.php b/src/Controller/ConfigurationFilesController.php index 972c122c80..b1c6bdb930 100644 --- a/src/Controller/ConfigurationFilesController.php +++ b/src/Controller/ConfigurationFilesController.php @@ -32,6 +32,7 @@ use Cake\Http\Exception\ForbiddenException; use Cake\Http\Exception\MethodNotAllowedException; use Cake\Http\Exception\NotFoundException; +use Cake\Http\Exception\ServiceUnavailableException; use Cake\ORM\TableRegistry; use itnovum\openITCOCKPIT\ConfigGenerator\ConfigInterface; use itnovum\openITCOCKPIT\ConfigGenerator\GeneratorRegistry; @@ -49,22 +50,24 @@ public function index() { } $configFilesForFrontend = []; - $GeneratorRegistry = new GeneratorRegistry(); - foreach ($GeneratorRegistry->getAllConfigFilesWithCategory() as $categoryName => $ConfigFileObjects) { - $category = [ - 'name' => $categoryName, - 'configFiles' => [] - ]; - - foreach ($ConfigFileObjects as $ConfigFileObject) { - /** @var ConfigInterface $ConfigFileObject */ - $category['configFiles'][] = [ - 'linkedOutfile' => $ConfigFileObject->getLinkedOutfile(), - 'dbKey' => $ConfigFileObject->getDbKey() + if (!IS_CONTAINER) { + $GeneratorRegistry = new GeneratorRegistry(); + foreach ($GeneratorRegistry->getAllConfigFilesWithCategory() as $categoryName => $ConfigFileObjects) { + $category = [ + 'name' => $categoryName, + 'configFiles' => [] ]; - } - $configFilesForFrontend[] = $category; + foreach ($ConfigFileObjects as $ConfigFileObject) { + /** @var ConfigInterface $ConfigFileObject */ + $category['configFiles'][] = [ + 'linkedOutfile' => $ConfigFileObject->getLinkedOutfile(), + 'dbKey' => $ConfigFileObject->getDbKey() + ]; + } + + $configFilesForFrontend[] = $category; + } } $this->set('configFileCategories', $configFilesForFrontend); @@ -80,6 +83,10 @@ public function edit($configFile = null) { return; } + if (IS_CONTAINER) { + throw new ServiceUnavailableException('Containerized installations are configured through environment variables'); + } + $GeneratorRegistry = new GeneratorRegistry(); foreach ($GeneratorRegistry->getAllConfigFiles() as $ConfigFileObject) { @@ -194,6 +201,10 @@ public function restorDefault($configFile) { throw new MethodNotAllowedException(); } + if (IS_CONTAINER) { + throw new ServiceUnavailableException('Containerized installations are configured through environment variables'); + } + $className = sprintf('itnovum\openITCOCKPIT\ConfigGenerator\%s', $configFile); if (!class_exists($className)) { throw new NotFoundException('Config file not found'); @@ -252,6 +263,10 @@ private function __sharedControllerAction($ConfigurationObjectClassName, $ShortC /** @var ConfigurationFilesTable $ConfigurationFilesTable */ $ConfigurationFilesTable = TableRegistry::getTableLocator()->get('ConfigurationFiles'); + if (IS_CONTAINER) { + throw new ServiceUnavailableException('Containerized installations are configured through environment variables'); + } + if ($this->request->is('get') && $this->isAngularJsRequest()) { $dbConfig = $ConfigurationFilesTable->getConfigValuesByConfigFile($ConfigurationObjectClassName->getDbKey()); $config = $ConfigurationObjectClassName->mergeDbResultWithDefaultConfiguration($dbConfig); diff --git a/src/Template/ConfigurationFiles/index.php b/src/Template/ConfigurationFiles/index.php index 37e701eb61..9fe498675e 100644 --- a/src/Template/ConfigurationFiles/index.php +++ b/src/Template/ConfigurationFiles/index.php @@ -50,6 +50,29 @@
+ + + +
+
+
+ + + + +
+
+ + + +
+ +
+ +
+
+ +
From 80dd6ba7ab9ddccb21bba24772a55f0a33f2fe00 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 10 May 2023 15:37:34 +0200 Subject: [PATCH 14/54] ITC-2986 Disable repo check on debugging page when inside a container --- src/Template/Administrators/debug.php | 62 ++++++++++++++------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/src/Template/Administrators/debug.php b/src/Template/Administrators/debug.php index efaeed16f7..de1d0f3b05 100755 --- a/src/Template/Administrators/debug.php +++ b/src/Template/Administrators/debug.php @@ -77,35 +77,36 @@ - -element('repository_checker'); ?> - -getCodename() === 'bionic'): ?> -
- × -

- - -

- - -
- support@itsm.it-novum.com'); ?> -
- - -getCodename() === 'buster'): ?> -
- × -

- - -

- - -
- support@itsm.it-novum.com'); ?> -
+ + element('repository_checker'); ?> + + getCodename() === 'bionic'): ?> +
+ × +

+ + +

+ + +
+ support@itsm.it-novum.com'); ?> +
+ + + getCodename() === 'buster'): ?> +
+ × +

+ + +

+ + +
+ support@itsm.it-novum.com'); ?> +
+
@@ -122,7 +123,8 @@
- Logo + Logo
From cc48b520a00608e22237d3b2f096ddc52aa78a26 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 10 May 2023 16:08:48 +0200 Subject: [PATCH 15/54] ITC-2986 Adjust grafana setup --- CONTAINER_SETUP.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTAINER_SETUP.sh b/CONTAINER_SETUP.sh index f0f2679e33..ba41922de3 100644 --- a/CONTAINER_SETUP.sh +++ b/CONTAINER_SETUP.sh @@ -200,7 +200,8 @@ if [ -f /opt/openitc/etc/grafana/api_key ]; then COUNT=$(mysql "--defaults-extra-file=$INIFILE" -e "SELECT COUNT(*) FROM grafana_configurations;" -B -s 2>/dev/null) if [ "$?" == 0 ] && [ "$COUNT" == 0 ]; then echo "Create missing default configuration." - mysql --defaults-extra-file=${INIFILE} -e "INSERT INTO grafana_configurations (api_url, api_key, graphite_prefix, use_https, use_proxy, ignore_ssl_certificate, dashboard_style, created, modified) VALUES('grafana.docker', '${API_KEY}', 'openitcockpit', 1, 0, 1, 'light', '2018-12-05 08:42:55', '2018-12-05 08:42:55');" + # This is different from the default SETUP.sh! + mysql --defaults-extra-file=${INIFILE} -e "INSERT INTO grafana_configurations (api_url, api_key, graphite_prefix, use_https, use_proxy, ignore_ssl_certificate, dashboard_style, created, modified) VALUES('${OITC_GRAFANA_HOSTNAME}', '${API_KEY}', 'openitcockpit', 1, 0, 1, 'light', '2018-12-05 08:42:55', '2018-12-05 08:42:55');" fi set -e fi From b2c33d5a8d8af79f98c20b2d597836cbd6c5b1c3 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 10 May 2023 16:28:59 +0200 Subject: [PATCH 16/54] ITC-2986 Adjust grafana setup --- CONTAINER_SETUP.sh | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/CONTAINER_SETUP.sh b/CONTAINER_SETUP.sh index ba41922de3..bbf011d4a8 100644 --- a/CONTAINER_SETUP.sh +++ b/CONTAINER_SETUP.sh @@ -119,10 +119,7 @@ echo "Create new WebSocket Key" WEBSOCKET_KEY=$(php -r "echo bin2hex(openssl_random_pseudo_bytes(80, \$cstrong));") mysql "--defaults-extra-file=${INIFILE}" -e "UPDATE systemsettings SET \`systemsettings\`.\`value\`='${WEBSOCKET_KEY}' WHERE \`key\`='SUDO_SERVER.API_KEY';" -if [ ! -f /opt/openitc/etc/grafana/admin_password ]; then - echo "Generate new Grafana password for user 'admin'" - pwgen 10 1 > /opt/openitc/etc/grafana/admin_password -fi +echo $OITC_GRAFANA_ADMIN_PASSWORD > /opt/openitc/etc/grafana/admin_password oitc config_generator_shell --generate-container @@ -139,10 +136,10 @@ if [ ! -f /opt/openitc/etc/grafana/api_key ]; then while [ "$COUNTER" -lt 30 ]; do echo "Try to connect to Grafana API..." #Is Grafana Server Online? - STATUSCODE=$(curl --noproxy 'grafana' "http://$OITC_GRAFANA_URL/api/admin/stats" -XGET -uadmin:$ADMIN_PASSWORD -H 'Content-Type: application/json' -I 2>/dev/null | head -n 1 | cut -d$' ' -f2) + STATUSCODE=$(curl --noproxy "$OITC_GRAFANA_HOSTNAME" "$OITC_GRAFANA_URL/api/admin/stats" -XGET -uadmin:$OITC_GRAFANA_ADMIN_PASSWORD -H 'Content-Type: application/json' -I 2>/dev/null | head -n 1 | cut -d$' ' -f2) if [ "$STATUSCODE" == "200" ]; then - API_KEY=$(curl --noproxy 'grafana' "http://$OITC_GRAFANA_URL/api/auth/keys" -XPOST -uadmin:$ADMIN_PASSWORD -H 'Content-Type: application/json' -d '{"role":"Editor","name":"openITCOCKPIT"}' | jq -r '.key') + API_KEY=$(curl --noproxy "$OITC_GRAFANA_HOSTNAME" "$OITC_GRAFANA_URL/api/auth/keys" -XPOST -uadmin:$OITC_GRAFANA_ADMIN_PASSWORD -H 'Content-Type: application/json' -d '{"role":"Editor","name":"openITCOCKPIT"}' | jq -r '.key') echo "$API_KEY" >/opt/openitc/etc/grafana/api_key break fi @@ -158,10 +155,10 @@ if [ ! -f /opt/openitc/etc/grafana/api_key ]; then fi echo "Check if Graphite Datasource exists in Grafana" -DS_STATUSCODE=$(curl --noproxy 'grafana' "http://$OITC_GRAFANA_URL/api/datasources/name/Graphite" -XGET -uadmin:$ADMIN_PASSWORD -H 'Content-Type: application/json' -I 2>/dev/null | head -n 1 | cut -d$' ' -f2) +DS_STATUSCODE=$(curl --noproxy "$OITC_GRAFANA_HOSTNAME" "$OITC_GRAFANA_URL/api/datasources/name/Graphite" -XGET -uadmin:$OITC_GRAFANA_ADMIN_PASSWORD -H 'Content-Type: application/json' -I 2>/dev/null | head -n 1 | cut -d$' ' -f2) if [ "$DS_STATUSCODE" == "404" ]; then echo "Create Graphite as default Datasource for Grafana" - RESPONSE=$(curl --noproxy 'grafana' "http://$OITC_GRAFANA_URL/api/datasources" -XPOST -uadmin:$ADMIN_PASSWORD -H 'Content-Type: application/json' -d '{ + RESPONSE=$(curl --noproxy "$OITC_GRAFANA_HOSTNAME" "$OITC_GRAFANA_URL/api/datasources" -XPOST -uadmin:$OITC_GRAFANA_ADMIN_PASSWORD -H 'Content-Type: application/json' -d '{ "name":"Graphite", "type":"graphite", "url":"http://graphite-web:8080", @@ -177,10 +174,10 @@ fi echo "Ok: Graphite datasource exists." echo "Check if Prometheus/VictoriaMetrics Datasource exists in Grafana" -DS_STATUSCODE=$(curl --noproxy 'grafana' "http://$OITC_GRAFANA_URL/api/datasources/name/Prometheus" -XGET -uadmin:$ADMIN_PASSWORD -H 'Content-Type: application/json' -I 2>/dev/null | head -n 1 | cut -d$' ' -f2) +DS_STATUSCODE=$(curl --noproxy "$OITC_GRAFANA_HOSTNAME" "$OITC_GRAFANA_URL/api/datasources/name/Prometheus" -XGET -uadmin:$OITC_GRAFANA_ADMIN_PASSWORD -H 'Content-Type: application/json' -I 2>/dev/null | head -n 1 | cut -d$' ' -f2) if [ "$DS_STATUSCODE" == "404" ]; then echo "Create Prometheus/VictoriaMetrics Datasource for Grafana" - RESPONSE=$(curl --noproxy 'grafana' "http://$OITC_GRAFANA_URL/api/datasources" -XPOST -uadmin:$ADMIN_PASSWORD -H 'Content-Type: application/json' -d '{ + RESPONSE=$(curl --noproxy "$OITC_GRAFANA_HOSTNAME" "$OITC_GRAFANA_URL/api/datasources" -XPOST -uadmin:$OITC_GRAFANA_ADMIN_PASSWORD -H 'Content-Type: application/json' -d '{ "name":"Prometheus", "type":"prometheus", "url":"http://victoriametrics:8428", From c1cac9cacbb93d68ec8d5bcbf39b6c9025711db1 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 10 May 2023 16:55:42 +0200 Subject: [PATCH 17/54] ITC-2986 Fix MonitoringEngine class when running in container --- .../openITCOCKPIT/Core/System/Health/MonitoringEngine.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php b/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php index bb1307d498..1cb54822e7 100644 --- a/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php +++ b/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php @@ -140,7 +140,8 @@ class MonitoringEngine { public function __construct() { if (IS_CONTAINER) { // We always use Naemon for containers - return 'Naemon Core Container'; + $this->monitoringEngine = 'Naemon Core Container'; + return; } Configure::load('nagios'); From f370a1bd175c861d3a89735333255ff4d6bb4331 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 10 May 2023 18:06:48 +0200 Subject: [PATCH 18/54] ITC-2986 Remote old grafana admin password --- CONTAINER_SETUP.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/CONTAINER_SETUP.sh b/CONTAINER_SETUP.sh index bbf011d4a8..4a5d5d0173 100644 --- a/CONTAINER_SETUP.sh +++ b/CONTAINER_SETUP.sh @@ -126,8 +126,6 @@ oitc config_generator_shell --generate-container echo "---------------------------------------------------------------" echo "Configure Grafana" -ADMIN_PASSWORD=$(cat /opt/openitc/etc/grafana/admin_password) - if [ ! -f /opt/openitc/etc/grafana/api_key ]; then echo "Create new Grafana API Key for openITCOCKPIT" COUNTER=0 From 9edf1b2a2f87a9cad7fefe7304025165fd22d7a7 Mon Sep 17 00:00:00 2001 From: nook24 Date: Thu, 11 May 2023 12:19:24 +0200 Subject: [PATCH 19/54] ITC-2986 Add Supervisor API wrapper --- composer.json | 2 + src/Command/SupervisorCommand.php | 81 +++ .../openITCOCKPIT/Supervisor/ApiException.php | 7 + .../openITCOCKPIT/Supervisor/XMLRPCApi.php | 557 ++++++++++++++++++ .../Command/SupervisorCommandTest.php | 50 ++ 5 files changed, 697 insertions(+) create mode 100644 src/Command/SupervisorCommand.php create mode 100644 src/itnovum/openITCOCKPIT/Supervisor/ApiException.php create mode 100644 src/itnovum/openITCOCKPIT/Supervisor/XMLRPCApi.php create mode 100644 tests/TestCase/Command/SupervisorCommandTest.php diff --git a/composer.json b/composer.json index cc9e4d076a..bb4416ea17 100644 --- a/composer.json +++ b/composer.json @@ -24,6 +24,7 @@ "require": { "php": ">=7.2", "ext-calendar": "*", + "ext-curl": "*", "ext-gd": "*", "ext-gearman": "*", "ext-json": "*", @@ -34,6 +35,7 @@ "ext-simplexml": "*", "ext-soap": "*", "ext-sockets": "*", + "ext-xmlrpc": "*", "ext-zip": "*", "azuyalabs/yasumi": "^2.2", "cakephp/authentication": "^2.0", diff --git a/src/Command/SupervisorCommand.php b/src/Command/SupervisorCommand.php new file mode 100644 index 0000000000..5fe54975ab --- /dev/null +++ b/src/Command/SupervisorCommand.php @@ -0,0 +1,81 @@ + +// +// This file is dual licensed +// +// 1. +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 3 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// + +// 2. +// If you purchased an openITCOCKPIT Enterprise Edition you can use this file +// under the terms of the openITCOCKPIT Enterprise Edition license agreement. +// License agreement and license key will be shipped with the order +// confirmation. + +declare(strict_types=1); + +namespace App\Command; + +use App\itnovum\openITCOCKPIT\Supervisor\XMLRPCApi; +use Cake\Command\Command; +use Cake\Console\Arguments; +use Cake\Console\ConsoleIo; +use Cake\Console\ConsoleOptionParser; + +/** + * Supervisor command. + */ +class SupervisorCommand extends Command { + /** + * Hook method for defining this command's option parser. + * + * @see https://book.cakephp.org/4/en/console-commands/commands.html#defining-arguments-and-options + * @param \Cake\Console\ConsoleOptionParser $parser The parser to be defined + * @return \Cake\Console\ConsoleOptionParser The built parser. + */ + public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { + $parser = parent::buildOptionParser($parser); + + return $parser; + } + + /** + * Implement this method with your command's logic. + * + * @param \Cake\Console\Arguments $args The command arguments. + * @param \Cake\Console\ConsoleIo $io The console io + * @return null|void|int The exit code or null for success + */ + public function execute(Arguments $args, ConsoleIo $io) { + + $SupervisorApi = new XMLRPCApi('supervisord', 'password', 'http://127.0.0.1:9001/RPC2'); + + try { + debug($SupervisorApi->getApiVersion()); + debug($SupervisorApi->getSupervisorVersion()); + debug($SupervisorApi->getIdentification()); + debug($SupervisorApi->getState()); + debug($SupervisorApi->getPID()); + debug($SupervisorApi->readLog()); + debug($SupervisorApi->listMethods()); + debug($SupervisorApi->methodHelp('supervisor.stopAllProcesses')); + debug($SupervisorApi->methodSignature('supervisor.stopAllProcesses')); + debug($SupervisorApi->getProcessInfo('sudo_server')); + debug($SupervisorApi->getAllProcessInfo()); + }catch (\Exception $e){ + debug($e->getMessage()); + } + + } +} diff --git a/src/itnovum/openITCOCKPIT/Supervisor/ApiException.php b/src/itnovum/openITCOCKPIT/Supervisor/ApiException.php new file mode 100644 index 0000000000..26b254ec52 --- /dev/null +++ b/src/itnovum/openITCOCKPIT/Supervisor/ApiException.php @@ -0,0 +1,7 @@ + +// +// This file is dual licensed +// +// 1. +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 3 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// 2. +// If you purchased an openITCOCKPIT Enterprise Edition you can use this file +// under the terms of the openITCOCKPIT Enterprise Edition license agreement. +// License agreement and license key will be shipped with the order +// confirmation. + +namespace App\itnovum\openITCOCKPIT\Supervisor; + +/** + * Helper class for easy communication with the Supervisor XML-RPC API + * Please notice: This class is a Wrapper for the API. Not all API methods are implemented. + * + * If you are missing methods, please see the docs and implement the missing method: + * http://supervisord.org/api.htm + * + * This class does not make use of any __call() Magic Methods. This makes sure that the IDE knows all + * methods and can provide useful autocomplete and knows about method signatures + */ +class XMLRPCApi { + + /** + * @var string + */ + private $username; + + /** + * @var string + */ + private $password; + + /** + * @var string + */ + private $url; + + + /** + * @param string $username + * @param string $password + * @param string $url Full API url with protocol and port like http://127.0.0.1:9001/RPC2 + */ + public function __construct(string $username, string $password, string $url = 'http://127.0.0.1:9001/RPC2') { + $this->username = $username; + $this->password = $password; + $this->url = $url; + } + + /** + * Send request to the XML-PRC API of Supervisor + * + * @param string $functionName API Method name you want to call + * @param mixed $functionArgs Args you want to pass to the API + * @return mixed|string + * @throws ApiException + */ + public function request(string $functionName, $functionArgs = null) { + $request = xmlrpc_encode_request($functionName, $functionArgs); + $header = []; + $header[] = 'Authorization: Basic ' . base64_encode($this->username . ':' . $this->password); + $header[] = "Content-type: text/xml"; + $header[] = "Content-length: " . strlen($request); + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $this->url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_TIMEOUT, 10); + curl_setopt($ch, CURLOPT_HTTPHEADER, $header); + curl_setopt($ch, CURLOPT_POSTFIELDS, $request); + curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, false); + curl_setopt($ch, CURLOPT_PROXY, ''); + + $data = curl_exec($ch); + + $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); + if ($status !== 200) { + throw new ApiException(sprintf('HTTP status code was: %s', $status)); + } + + if (curl_errno($ch)) { + throw new ApiException(curl_error($ch)); + } else { + curl_close($ch); + return xmlrpc_decode($data); + } + } + + /** + * Return the version of the RPC API used by supervisord + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.getAPIVersion + * @return string version id + * @throws ApiException + */ + public function getApiVersion() { + return $this->request('supervisor.getAPIVersion'); + } + + /** + * Return the version of the supervisor package in use by supervisord + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.getSupervisorVersion + * @return string version id + * @throws ApiException + */ + public function getSupervisorVersion() { + return $this->request('supervisor.getSupervisorVersion'); + } + + /** + * Return identifying string of supervisord + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.getIdentification + * @return string identifier identifying string + * @throws ApiException + */ + public function getIdentification() { + return $this->request('supervisor.getIdentification'); + } + + /** + * Return current state of supervisord as a struct + * + * | statecode | statename | Description | + * |-----------|------------|------------------------------------------------| + * | 2 | FATAL | Supervisor has experienced a serious error. | + * | 1 | RUNNING | Supervisor is working normally. | + * | 0 | RESTARTING | Supervisor is in the process of restarting. | + * | -1 | SHUTDOWN | Supervisor is in the process of shutting down. | + * + * Return + * [ + * 'statecode' => (int) 1, + * 'statename' => 'RUNNING' + * ] + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.getState + * @return array A struct with keys int statecode, string statename + * @throws ApiException + */ + public function getState() { + return $this->request('supervisor.getState'); + } + + /** + * Return the PID of supervisord + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.getPID + * @return int PID + * @throws ApiException + */ + public function getPID() { + return $this->request('supervisor.getPID'); + } + + /** + * Read length bytes from the main log starting at offset + * + * | Offset | Length | Behavior of readProcessLog | + * |------------------|----------|--------------------------------------------------------------------------------| + * | Negative | Not Zero | Bad arguments. This will raise the fault BAD_ARGUMENTS. | + * | Negative | Zero | This will return the tail of the log, or offset number of characters from the | + * | | | end of the log. For example, if offset = -4 and length = 0, then the last four | + * | | |characters will be returned from the end of the log. | + * | Zero or Positive | Negative | Bad arguments. This will raise the fault BAD_ARGUMENTS. | + * | Zero or Positive | Zero | All characters will be returned from the offset specified. | + * | Zero or Positive | Positive | A number of characters length will be returned from the offset. | + * + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.readLog + * + * @param int $offset offset to start reading from. + * @param int $length number of bytes to read from the log + * @return string result Bytes of log + * @throws ApiException + */ + public function readLog(int $offset = 0, int $length = 1024) { + return $this->request('supervisor.readLog', [$offset, $length]); + } + + /** + * Clear the main log + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.clearLog + * @return bool result always returns True unless error + * @throws ApiException + */ + public function clearLog() { + return $this->request('supervisor.clearLog'); + } + + /** + * Shut down the supervisor process + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.shutdown + * @return bool result always returns True unless error + * @throws ApiException + */ + public function shutdown() { + return $this->request('supervisor.shutdown'); + } + + /** + * Restart the supervisor process + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.restart + * @return bool result always return True unless error + * @throws ApiException + */ + public function restart() { + return $this->request('supervisor.restart'); + } + + /** + * Return an array listing the available method names + * + * @see http://supervisord.org/api.html#supervisor.xmlrpc.SystemNamespaceRPCInterface.listMethods + * @return array result An array of method names available (strings). + * @throws ApiException + */ + public function listMethods() { + return $this->request('system.listMethods'); + } + + /** + * Return a string showing the method’s documentation + * + * @see http://supervisord.org/api.html#supervisor.xmlrpc.SystemNamespaceRPCInterface.methodHelp + * @param string $method The name of the method + * @return string result The documentation for the method name. + * @throws ApiException + */ + public function methodHelp(string $method) { + return $this->request('system.methodHelp', [$method]); + } + + /** + * Return an array describing the method signature in the form [rtype, ptype, ptype…] where rtype is + * the return data type of the method, and ptypes are the parameter data types that the method accepts + * in method argument order. + * + * @see http://supervisord.org/api.html#supervisor.xmlrpc.SystemNamespaceRPCInterface.methodSignature + * @param string $method The name of the method + * @return array result The result. + * @throws ApiException + */ + public function methodSignature(string $method) { + return $this->request('system.methodSignature', [$method]); + } + + /** + * Get info about a process named name + * + * Returns + * [ + * 'name' => 'sudo_server', + * 'group' => 'sudo_server', + * 'start' => (int) 1683792729, + * 'stop' => (int) 0, + * 'now' => (int) 1683792818, + * 'state' => (int) 200, + * 'statename' => 'FATAL', + * 'spawnerr' => 'unknown error making dispatchers for 'sudo_server': ENXIO', + * 'exitstatus' => (int) 0, + * 'logfile' => '/dev/stdout', + * 'stdout_logfile' => '/dev/stdout', + * 'stderr_logfile' => '', + * 'pid' => (int) 0, + * 'description' => 'unknown error making dispatchers for 'sudo_server': ENXIO' + * ] + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.getProcessInfo + * @param string $name The name of the process (or ‘group:name’) + * @return array result A structure containing data about the process + * @throws ApiException + */ + public function getProcessInfo(string $name) { + return $this->request('supervisor.getProcessInfo', [$name]); + } + + /** + * Get info about all processes + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.getAllProcessInfo + * @return array result An array of process status results + * @throws ApiException + */ + public function getAllProcessInfo() { + return $this->request('supervisor.getAllProcessInfo'); + } + + /** + * Start a process + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.startProcess + * @param string $name Process name (or group:name, or group:*) + * @param boolean $wait Wait for process to be fully started + * @return boolean result Always true unless error + * @throws ApiException + */ + public function startProcess(string $name, bool $wait = true) { + return $this->request('supervisor.startProcess', [$name, $wait]); + } + + /** + * Start all processes listed in the configuration file + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.startAllProcesses + * @param boolean $wait Wait for each process to be fully started + * @return array result An array of process status info structs + * @throws ApiException + */ + public function startAllProcesses($wait = true) { + return $this->request('supervisor.startAllProcesses', [$wait]); + } + + /** + * Start all processes in the group named ‘name’ + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.startProcessGroup + * @param string $name The group name + * @param boolean $wait Wait for each process to be fully started + * @return array result An array of process status info structs + * @throws ApiException + */ + public function startProcessGroup(string $name, $wait = true) { + return $this->request('supervisor.startProcessGroup', [$name, $wait]); + } + + /** + * Stop a process named by name + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.stopProcess + * @param string $name The name of the process to stop (or ‘group:name’) + * @param boolean $wait Wait for the process to be fully stopped + * @return boolean result Always return True unless error + * @throws ApiException + */ + public function stopProcess(string $name, $wait = true) { + return $this->request('supervisor.stopProcess', [$name, $wait]); + } + + /** + * Stop all processes in the process list + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.stopAllProcesses + * @param boolean $wait Wait for each process to be fully stopped + * @return array result An array of process status info structs + * @throws ApiException + */ + public function stopAllProcesses($wait = true) { + return $this->request('supervisor.stopAllProcesses', [$wait]); + } + + /** + * Stop all processes in the process group named ‘name’ + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.stopProcessGroup + * @param string $name The group name + * @param boolean $wait Wait for each process to be fully stopped + * @return array result An array of process status info structs + * @throws ApiException + */ + public function stopProcessGroup(string $name, $wait = true) { + return $this->request('supervisor.stopProcessGroup', [$name, $wait]); + } + + /** + * Send an arbitrary UNIX signal to the process named by name + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.signalProcess + * @param string $name Name of the process to signal (or ‘group:name’) + * @param string|int $signal Signal to send, as name (‘HUP’) or number (‘1’) + * @return boolean + * @throws ApiException + */ + public function signalProcess(string $name, $signal) { + return $this->request('supervisor.signalProcess', [$name, $signal]); + } + + /** + * Send a signal to all processes in the process list + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.signalAllProcesses + * @param string|int $signal Signal to send, as name (‘HUP’) or number (‘1’) + * @return array An array of process status info structs + * @throws ApiException + */ + public function signalAllProcesses($signal) { + return $this->request('supervisor.signalAllProcesses', [$signal]); + } + + /** + * Send a signal to all processes in the group named ‘name’ + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.signalProcessGroup + * @param string $name The group name + * @param string|int $signal Signal to send, as name (‘HUP’) or number (‘1’) + * @return array + * @throws ApiException + */ + public function signalProcessGroup(string $name, $signal) { + return $this->request('supervisor.signalProcessGroup', [$name, $signal]); + } + + /** + * Send a string of chars to the stdin of the process name. If non-7-bit data is sent (unicode), + * it is encoded to utf-8 before being sent to the process’ stdin. If chars is not a string or + * is not unicode, raise INCORRECT_PARAMETERS. If the process is not running, raise NOT_RUNNING. + * If the process’ stdin cannot accept input (e.g. it was closed by the child process), raise NO_FILE. + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.sendProcessStdin + * @param string $name The process name to send to (or ‘group:name’) + * @param string $chars The character data to send to the process + * @return boolean result Always return True unless error + * @throws ApiException + */ + public function sendProcessStdin(string $name, string $chars) { + return $this->request('supervisor.sendProcessStdin', [$name, $chars]); + } + + /** + * Send an event that will be received by event listener subprocesses subscribing to the RemoteCommunicationEvent. + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.sendRemoteCommEvent + * @param string $type String for the “type” key in the event header + * @param string $data Data for the event body + * @return boolean Always return True unless error + * @throws ApiException + */ + public function sendRemoteCommEvent(string $type, string $data) { + return $this->request('supervisor.sendRemoteCommEvent', [$type, $data]); + } + + /** + * Reload the configuration. + * The result contains three arrays containing names of process groups: + * - added gives the process groups that have been added + * - changed gives the process groups whose contents have changed + * - removed gives the process groups that are no longer in the configuration + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.reloadConfig + * @return array result [[added, changed, removed]] + * @throws ApiException + */ + public function reloadConfig() { + return $this->request('supervisor.reloadConfig'); + } + + /** + * Read length bytes from name’s stdout log starting at offset + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.readProcessStdoutLog + * @param string $name the name of the process (or ‘group:name’) + * @param int $offset offset to start reading from + * @param int $length number of bytes to read from the log + * @return string result Bytes of log + * @throws ApiException + */ + public function readProcessStdoutLog(string $name, int $offset, int $length = 1024) { + return $this->request('supervisor.readProcessStdoutLog', [$name, $offset, $length]); + } + + /** + * Read length bytes from name’s stdout log starting at offset + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.readProcessStderrLog + * @param string $name the name of the process (or ‘group:name’) + * @param int $offset offset to start reading from + * @param int $length number of bytes to read from the log + * @return string result Bytes of log + * @throws ApiException + */ + public function readProcessStderrLog(string $name, int $offset, int $length = 1024) { + return $this->request('supervisor.readProcessStderrLog', [$name, $offset, $length]); + } + + /** + * Provides a more efficient way to tail the (stdout) log than readProcessStdoutLog(). Use readProcessStdoutLog() + * to read chunks and tailProcessStdoutLog() to tail. + * + * Requests (length) bytes from the (name)’s log, starting at (offset). If the total log size is greater + * than (offset + length), the overflow flag is set and the (offset) is automatically increased to position + * the buffer at the end of the log. If less than (length) bytes are available, the maximum number of available + * bytes will be returned. (offset) returned is always the last offset in the log +1. + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.tailProcessStdoutLog + * @param string $name the name of the process (or ‘group:name’) + * @param int $offset offset to start reading from + * @param int $length number of bytes to read from the log + * @return array result [string bytes, int offset, bool overflow] + * @throws ApiException + */ + public function tailProcessStdoutLog(string $name, int $offset, int $length = 1024) { + return $this->request('supervisor.tailProcessStdoutLog', [$name, $offset, $length]); + } + + /** + * Provides a more efficient way to tail the (stderr) log than readProcessStderrLog(). Use readProcessStderrLog() + * to read chunks and tailProcessStderrLog() to tail. + * + * Requests (length) bytes from the (name)’s log, starting at (offset). If the total log size is greater + * than (offset + length), the overflow flag is set and the (offset) is automatically increased to position + * the buffer at the end of the log. If less than (length) bytes are available, the maximum number of available + * bytes will be returned. (offset) returned is always the last offset in the log +1. + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.tailProcessStderrLog + * @param string $name the name of the process (or ‘group:name’) + * @param int $offset offset to start reading from + * @param int $length number of bytes to read from the log + * @return array result [string bytes, int offset, bool overflow] + * @throws ApiException + */ + public function tailProcessStderrLog(string $name, int $offset, int $length = 1024) { + return $this->request('supervisor.tailProcessStderrLog', [$name, $offset, $length]); + } + + /** + * Clear the stdout and stderr logs for the named process and reopen them. + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.clearProcessLogs + * @param string $name The name of the process (or ‘group:name’) + * @return boolean result Always True unless error + * @throws ApiException + */ + public function clearProcessLogs(string $name) { + return $this->request('supervisor.clearProcessLogs', [$name]); + } + + /** + * Clear all process log files + * + * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.clearProcessLogs + * @return array result An array of process status info structs + * @throws ApiException + */ + public function clearAllProcessLogs() { + return $this->request('supervisor.clearAllProcessLogs'); + } +} + diff --git a/tests/TestCase/Command/SupervisorCommandTest.php b/tests/TestCase/Command/SupervisorCommandTest.php new file mode 100644 index 0000000000..638c72b960 --- /dev/null +++ b/tests/TestCase/Command/SupervisorCommandTest.php @@ -0,0 +1,50 @@ +useCommandRunner(); + } + /** + * Test buildOptionParser method + * + * @return void + * @uses \App\Command\SupervisorCommand::buildOptionParser() + */ + public function testBuildOptionParser(): void + { + $this->markTestIncomplete('Not implemented yet.'); + } + + /** + * Test execute method + * + * @return void + * @uses \App\Command\SupervisorCommand::execute() + */ + public function testExecute(): void + { + $this->markTestIncomplete('Not implemented yet.'); + } +} From 6bea0cd6aacc655a5404382d3764acd170edd4bf Mon Sep 17 00:00:00 2001 From: nook24 Date: Thu, 11 May 2023 14:39:55 +0200 Subject: [PATCH 20/54] ITC-2986 Add Supervisorctl Class to controll supervisor from PHP and also SupervisorCommand to controll supervisor from CLI --- src/Command/SupervisorCommand.php | 112 +++++++++++++++--- .../Supervisor/Supervisorctl.php | 86 ++++++++++++++ .../openITCOCKPIT/Supervisor/XMLRPCApi.php | 16 ++- 3 files changed, 193 insertions(+), 21 deletions(-) create mode 100644 src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php diff --git a/src/Command/SupervisorCommand.php b/src/Command/SupervisorCommand.php index 5fe54975ab..99a809f9c2 100644 --- a/src/Command/SupervisorCommand.php +++ b/src/Command/SupervisorCommand.php @@ -27,11 +27,13 @@ namespace App\Command; +use App\itnovum\openITCOCKPIT\Supervisor\Supervisorctl; use App\itnovum\openITCOCKPIT\Supervisor\XMLRPCApi; use Cake\Command\Command; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; +use http\Exception\RuntimeException; /** * Supervisor command. @@ -47,6 +49,38 @@ class SupervisorCommand extends Command { public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { $parser = parent::buildOptionParser($parser); + $parser->addArgument('command', [ + 'help' => 'Command to execute', + 'required' => true, + 'choices' => ['start', 'stop', 'restart', 'status'], + ]); + + $parser->addArgument('service_name', [ + 'help' => 'Command to execute', + 'required' => true, + 'choices' => [ + // openITCOCKPIT background + 'oitc_cmd', + 'sudo_server', + 'gearman_worker', + 'event-collectd', //todo + 'push_notification', + 'prometheus_bridge', //todo + 'customalert_worker', //todo + + // Monitoring Engines + 'naemon', + 'prometheus', + 'nsta', + + // System + 'nginx', + 'php-fpm', + 'snmptrapd', + 'snmptt', + ], + ]); + return $parser; } @@ -58,23 +92,69 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar * @return null|void|int The exit code or null for success */ public function execute(Arguments $args, ConsoleIo $io) { + $command = $args->getArgument('command'); + $serviceName = $args->getArgument('service_name'); + + $Supervisorctl = new Supervisorctl(); + + switch ($command) { + case 'start': + $result = $Supervisorctl->start($serviceName); + if ($result === true) { + $io->out(sprintf('Service %s started ', $serviceName), 0); + $io->success('successfully.', 1); + break; + } + + print_r($result); + break; + + case 'stop': + $result = $Supervisorctl->stop($serviceName); + if ($result === true) { + $io->out(sprintf('Service %s stopped ', $serviceName), 0); + $io->success('successfully.', 1); + break; + } + + print_r($result); + break; + + case 'restart': + $result = $Supervisorctl->stop($serviceName); + if ($result === true) { + $io->out(sprintf('Service %s stopped ', $serviceName), 0); + $io->success('successfully.', 1); + } else { + print_r($result); + } + + $result = $Supervisorctl->start($serviceName); + if ($result === true) { + $io->out(sprintf('Service %s started ', $serviceName), 0); + $io->success('successfully.', 1); + } else { + print_r($result); + } + break; + + default: + $result = $Supervisorctl->status($serviceName); + if ($result['statename'] === 'RUNNING') { + $io->out(sprintf('Service %s is ', $serviceName), 0); + $io->success('running. ', 0); + $io->out($result['description']); + break; + } + + if ($result['statename'] === 'STOPPED') { + $io->out(sprintf('Service %s is ', $serviceName), 0); + $io->error('stopped.'); + break; + } - $SupervisorApi = new XMLRPCApi('supervisord', 'password', 'http://127.0.0.1:9001/RPC2'); - - try { - debug($SupervisorApi->getApiVersion()); - debug($SupervisorApi->getSupervisorVersion()); - debug($SupervisorApi->getIdentification()); - debug($SupervisorApi->getState()); - debug($SupervisorApi->getPID()); - debug($SupervisorApi->readLog()); - debug($SupervisorApi->listMethods()); - debug($SupervisorApi->methodHelp('supervisor.stopAllProcesses')); - debug($SupervisorApi->methodSignature('supervisor.stopAllProcesses')); - debug($SupervisorApi->getProcessInfo('sudo_server')); - debug($SupervisorApi->getAllProcessInfo()); - }catch (\Exception $e){ - debug($e->getMessage()); + // Unknown state + print_r($result); } } diff --git a/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php b/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php new file mode 100644 index 0000000000..d0fa0b48d5 --- /dev/null +++ b/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php @@ -0,0 +1,86 @@ +getSupervisorApiEndpointByServiceName($serviceName); + return $SupervisorApi->startProcess($serviceName); + } + + /** + * @param string $serviceName + * @return bool|string + * @throws ApiException + */ + public function stop(string $serviceName) { + $SupervisorApi = $this->getSupervisorApiEndpointByServiceName($serviceName); + return $SupervisorApi->stopProcess($serviceName); + } + + /** + * @param string $serviceName + * @return bool|string + * @throws ApiException + */ + public function restart(string $serviceName) { + $SupervisorApi = $this->getSupervisorApiEndpointByServiceName($serviceName); + $SupervisorApi->stopProcess($serviceName); + return $SupervisorApi->startProcess($serviceName); + } + + /** + * @param string $serviceName + * @return array|string + * @throws ApiException + */ + public function status(string $serviceName) { + $SupervisorApi = $this->getSupervisorApiEndpointByServiceName($serviceName); + return $SupervisorApi->getProcessInfo($serviceName); + } + + /** + * @param string $serviceName + * @return XMLRPCApi + * @throws \RuntimeException + */ + public function getSupervisorApiEndpointByServiceName(string $serviceName): XMLRPCApi { + $username = env('SUPERVISOR_USER', 'supervisord'); + $password = env('SUPERVISOR_PASSWORD', 'password'); + + switch ($serviceName) { + case 'naemon': + // Tell the Naemon Container to start|stop|restart Naemon + $url = sprintf( + 'http://%s:%s/RPC2', + env('OITC_NAEMON_HOSTNAME', 'naemon'), + env('SUPERVISOR_PORT', 9001) + ); + $SupervisorApi = new XMLRPCApi($username, $password, $url); + break; + + default: + // Service is running in the same container as openITCOCKPIT itslef + $SupervisorApi = new XMLRPCApi($username, $password, 'http://127.0.0.1:9001/RPC2'); + break; + } + + if (!isset($SupervisorApi) || !($SupervisorApi instanceof XMLRPCApi)) { + throw new \RuntimeException('No SupervisorAPI endpoint found for given service_name'); + } + + return $SupervisorApi; + } + +} + diff --git a/src/itnovum/openITCOCKPIT/Supervisor/XMLRPCApi.php b/src/itnovum/openITCOCKPIT/Supervisor/XMLRPCApi.php index 6e8ed242eb..f73363ded2 100644 --- a/src/itnovum/openITCOCKPIT/Supervisor/XMLRPCApi.php +++ b/src/itnovum/openITCOCKPIT/Supervisor/XMLRPCApi.php @@ -51,16 +51,22 @@ class XMLRPCApi { */ private $url; + /** + * Connection timeout in seconds + * @var + */ + private $timeout; /** * @param string $username * @param string $password * @param string $url Full API url with protocol and port like http://127.0.0.1:9001/RPC2 */ - public function __construct(string $username, string $password, string $url = 'http://127.0.0.1:9001/RPC2') { + public function __construct(string $username, string $password, string $url = 'http://127.0.0.1:9001/RPC2', $timeout = 60) { $this->username = $username; $this->password = $password; $this->url = $url; + $this->timeout = $timeout; } /** @@ -80,7 +86,7 @@ public function request(string $functionName, $functionArgs = null) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $this->url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_TIMEOUT, 10); + curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_POSTFIELDS, $request); curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, false); @@ -95,10 +101,10 @@ public function request(string $functionName, $functionArgs = null) { if (curl_errno($ch)) { throw new ApiException(curl_error($ch)); - } else { - curl_close($ch); - return xmlrpc_decode($data); } + + curl_close($ch); + return xmlrpc_decode($data); } /** From fc197f052d366cd1dd0fd0d3642afb52a7648e79 Mon Sep 17 00:00:00 2001 From: nook24 Date: Thu, 11 May 2023 16:50:42 +0200 Subject: [PATCH 21/54] ITC-2986 Implement restart of naemon --- src/Command/GearmanWorkerCommand.php | 201 ++++++++++++------ src/Command/SupervisorCommand.php | 1 + .../Supervisor/Supervisorctl.php | 1 + 3 files changed, 136 insertions(+), 67 deletions(-) diff --git a/src/Command/GearmanWorkerCommand.php b/src/Command/GearmanWorkerCommand.php index 3f2f467895..f35229c1fc 100644 --- a/src/Command/GearmanWorkerCommand.php +++ b/src/Command/GearmanWorkerCommand.php @@ -30,6 +30,7 @@ use App\itnovum\openITCOCKPIT\Database\Backup; use App\itnovum\openITCOCKPIT\Monitoring\Naemon\ExternalCommands; +use App\itnovum\openITCOCKPIT\Supervisor\Supervisorctl; use App\Model\Entity\Changelog; use App\Model\Table\AgentconfigsTable; use App\Model\Table\ChangelogsTable; @@ -1332,16 +1333,34 @@ public function launchExport($createBackup = 1) { $SystemsettingsTable = TableRegistry::getTableLocator()->get('Systemsettings'); $systemsettings = $SystemsettingsTable->findAsArray(); - $naemonBin = Configure::read('nagios.basepath') . Configure::read('nagios.bin') . Configure::read('nagios.nagios_bin'); - $naemonCfg = Configure::read('nagios.nagios_cfg'); - $cmd = sprintf( - 'sudo -u %s %s -v %s', - escapeshellarg($systemsettings['MONITORING']['MONITORING.USER']), - $naemonBin, - $naemonCfg - ); - $output = null; - exec($cmd, $output, $returncode); + $Supervisorctl = new Supervisorctl(); + + if(IS_CONTAINER){ + // Naemon is running inside a container - query remote supervisor to run "naemon -v naemon.cfg" + try { + $Supervisorctl->start('naemon-verify'); + sleep(2); + $result = $Supervisorctl->status('naemon-verify'); + debug($result); + + $returncode = $result['exitstatus'] ?? 1; + }catch (\Exception $e){ + Log::error($e->getMessage()); + $returncode = 1; + } + }else { + // Local running Naemon + $naemonBin = Configure::read('nagios.basepath') . Configure::read('nagios.bin') . Configure::read('nagios.nagios_bin'); + $naemonCfg = Configure::read('nagios.nagios_cfg'); + $cmd = sprintf( + 'sudo -u %s %s -v %s', + escapeshellarg($systemsettings['MONITORING']['MONITORING.USER']), + $naemonBin, + $naemonCfg + ); + $output = null; + exec($cmd, $output, $returncode); + } $verifyEntity->set('finished', 1); if ($returncode === 0) { //New configuration is valid :-) @@ -1350,85 +1369,133 @@ public function launchExport($createBackup = 1) { $ExportsTable->save($verifyEntity); //Reloading the monitoring system - - //Check if Naemon/Nagios is running. - //If Nagios is running, we reload the config, if not we need to restart - $entity = $ExportsTable->newEntity([ - 'task' => 'is_monitoring_engine_running', - 'text' => __('Check if monitoring engine is running') - ]); - $ExportsTable->save($entity); - exec($systemsettings['MONITORING']['MONITORING.STATUS'], $statusOutput, $statusRc); - $entity->set('finished', 1); - $entity->set('successfully', 1); - $ExportsTable->save($entity); - unset($entity); - - $isMonitoringRunning = false; - if ($statusRc === 0) { - //Nagios/Naemon is running (reload) + if(!IS_CONTAINER) { + //Check if Naemon/Nagios is running. + //If Nagios is running, we reload the config, if not we need to restart $entity = $ExportsTable->newEntity([ - 'task' => 'export_reload_monitoring', - 'text' => __('Reloading monitoring engine') + 'task' => 'is_monitoring_engine_running', + 'text' => __('Check if monitoring engine is running') ]); $ExportsTable->save($entity); - exec($systemsettings['MONITORING']['MONITORING.RELOAD'], $reloadOutput, $reloadRc); + exec($systemsettings['MONITORING']['MONITORING.STATUS'], $statusOutput, $statusRc); $entity->set('finished', 1); - $entity->set('successfully', 0); - if ($reloadRc === 0) { - $entity->set('successfully', 1); - $isMonitoringRunning = true; - } + $entity->set('successfully', 1); $ExportsTable->save($entity); unset($entity); - } else { - //Nagios/Naemon is stopped (restart) + + $isMonitoringRunning = false; + if ($statusRc === 0) { + //Nagios/Naemon is running (reload) + $entity = $ExportsTable->newEntity([ + 'task' => 'export_reload_monitoring', + 'text' => __('Reloading monitoring engine') + ]); + $ExportsTable->save($entity); + exec($systemsettings['MONITORING']['MONITORING.RELOAD'], $reloadOutput, $reloadRc); + $entity->set('finished', 1); + $entity->set('successfully', 0); + if ($reloadRc === 0) { + $entity->set('successfully', 1); + $isMonitoringRunning = true; + } + $ExportsTable->save($entity); + unset($entity); + } else { + //Nagios/Naemon is stopped (restart) + $entity = $ExportsTable->newEntity([ + 'task' => 'export_restart_monitoring', + 'text' => __('Restarting monitoring engine') + ]); + $ExportsTable->save($entity); + exec($systemsettings['MONITORING']['MONITORING.RESTART'], $restartOutput, $restartRc); + $entity->set('finished', 1); + $entity->set('successfully', 0); + if ($restartRc === 0) { + $entity->set('successfully', 1); + $isMonitoringRunning = true; + } + $ExportsTable->save($entity); + unset($entity); + } + + + if ($isMonitoringRunning) { + //Run After Export command + $entity = $ExportsTable->newEntity([ + 'task' => 'export_after_export_command', + 'text' => __('Execute after export command') + ]); + $output = null; + exec($systemsettings['MONITORING']['MONITORING.AFTER_EXPORT'], $output, $returncode); + + // Avoid "MySQL server has gone away" + $connection = $SystemsettingsTable->getConnection(); + $connection->disconnect(); + $connection->connect(); + + $entity->set('finished', 1); + $entity->set('successfully', 0); + if ($returncode == 0) { + $entity->set('successfully', 1); + $this->distributedMonitoringAfterExportCommand(); + $this->importModuleAfterExportCommand(); + } else { + $successfully = 0; + } + + $ExportsTable->save($entity); + unset($entity); + + } else { + $successfully = 0; + } + }else{ + // Containerized openITCOCKPIT + // Restart remote Naemon $entity = $ExportsTable->newEntity([ 'task' => 'export_restart_monitoring', - 'text' => __('Restarting monitoring engine') + 'text' => __('Restarting containerized monitoring engine') ]); $ExportsTable->save($entity); - exec($systemsettings['MONITORING']['MONITORING.RESTART'], $restartOutput, $restartRc); + $result = $Supervisorctl->restart('naemon'); + debug($result); $entity->set('finished', 1); $entity->set('successfully', 0); - if ($restartRc === 0) { + if($result === true){ $entity->set('successfully', 1); $isMonitoringRunning = true; } - $ExportsTable->save($entity); - unset($entity); - } + if ($isMonitoringRunning) { + //Run After Export command + $entity = $ExportsTable->newEntity([ + 'task' => 'export_after_export_command', + 'text' => __('Execute after export command') + ]); + $output = null; + exec($systemsettings['MONITORING']['MONITORING.AFTER_EXPORT'], $output, $returncode); - if ($isMonitoringRunning) { - //Run After Export command - $entity = $ExportsTable->newEntity([ - 'task' => 'export_after_export_command', - 'text' => __('Execute after export command') - ]); - $output = null; - exec($systemsettings['MONITORING']['MONITORING.AFTER_EXPORT'], $output, $returncode); + // Avoid "MySQL server has gone away" + $connection = $SystemsettingsTable->getConnection(); + $connection->disconnect(); + $connection->connect(); - // Avoid "MySQL server has gone away" - $connection = $SystemsettingsTable->getConnection(); - $connection->disconnect(); - $connection->connect(); + $entity->set('finished', 1); + $entity->set('successfully', 0); + if ($returncode == 0) { + $entity->set('successfully', 1); + $this->distributedMonitoringAfterExportCommand(); + $this->importModuleAfterExportCommand(); + } else { + $successfully = 0; + } + + $ExportsTable->save($entity); + unset($entity); - $entity->set('finished', 1); - $entity->set('successfully', 0); - if ($returncode == 0) { - $entity->set('successfully', 1); - $this->distributedMonitoringAfterExportCommand(); - $this->importModuleAfterExportCommand(); } else { $successfully = 0; } - - $ExportsTable->save($entity); - unset($entity); - - } else { - $successfully = 0; } } else { //Error with new configuration :-( diff --git a/src/Command/SupervisorCommand.php b/src/Command/SupervisorCommand.php index 99a809f9c2..75d13654f8 100644 --- a/src/Command/SupervisorCommand.php +++ b/src/Command/SupervisorCommand.php @@ -70,6 +70,7 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar // Monitoring Engines 'naemon', + 'naemon-verify', 'prometheus', 'nsta', diff --git a/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php b/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php index d0fa0b48d5..bdcacc70de 100644 --- a/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php +++ b/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php @@ -60,6 +60,7 @@ public function getSupervisorApiEndpointByServiceName(string $serviceName): XMLR switch ($serviceName) { case 'naemon': + case 'naemon-verify': // Tell the Naemon Container to start|stop|restart Naemon $url = sprintf( 'http://%s:%s/RPC2', From 895acc2495b1d2f4d7c79268545574c8f105b2e5 Mon Sep 17 00:00:00 2001 From: nook24 Date: Thu, 11 May 2023 17:07:33 +0200 Subject: [PATCH 22/54] ITC-2986 Fix status of naemon restart in container --- src/Command/GearmanWorkerCommand.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Command/GearmanWorkerCommand.php b/src/Command/GearmanWorkerCommand.php index f35229c1fc..8777cc0159 100644 --- a/src/Command/GearmanWorkerCommand.php +++ b/src/Command/GearmanWorkerCommand.php @@ -1341,8 +1341,6 @@ public function launchExport($createBackup = 1) { $Supervisorctl->start('naemon-verify'); sleep(2); $result = $Supervisorctl->status('naemon-verify'); - debug($result); - $returncode = $result['exitstatus'] ?? 1; }catch (\Exception $e){ Log::error($e->getMessage()); @@ -1458,13 +1456,13 @@ public function launchExport($createBackup = 1) { ]); $ExportsTable->save($entity); $result = $Supervisorctl->restart('naemon'); - debug($result); $entity->set('finished', 1); $entity->set('successfully', 0); if($result === true){ $entity->set('successfully', 1); $isMonitoringRunning = true; } + $ExportsTable->save($entity); if ($isMonitoringRunning) { //Run After Export command From bbbd447db03ae39069d372879a95380d59eb1fce Mon Sep 17 00:00:00 2001 From: nook24 Date: Thu, 11 May 2023 17:33:07 +0200 Subject: [PATCH 23/54] ITC-2986 Restart oitc_cmd via supervisor in after export task --- .../Core/MonitoringEngine/NagiosConfigGenerator.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/itnovum/openITCOCKPIT/Core/MonitoringEngine/NagiosConfigGenerator.php b/src/itnovum/openITCOCKPIT/Core/MonitoringEngine/NagiosConfigGenerator.php index 176849e95a..0ddb62f164 100644 --- a/src/itnovum/openITCOCKPIT/Core/MonitoringEngine/NagiosConfigGenerator.php +++ b/src/itnovum/openITCOCKPIT/Core/MonitoringEngine/NagiosConfigGenerator.php @@ -25,6 +25,7 @@ namespace itnovum\openITCOCKPIT\Core\MonitoringEngine; +use App\itnovum\openITCOCKPIT\Supervisor\Supervisorctl; use App\Lib\ExportTasks; use App\Lib\PluginExportTasks; use App\Model\Entity\CalendarHoliday; @@ -2718,7 +2719,13 @@ public function afterExportExternalTasks() { } //Restart oitc CMD to wipe old cached information - exec('systemctl restart oitc_cmd'); + if (IS_CONTAINER) { + $Supervisorctl = new Supervisorctl(); + $Supervisorctl->restart('oitc_cmd'); + } else { + exec('systemctl restart oitc_cmd'); + } + $ExportTasks = new ExportTasks(); foreach ($ExportTasks->getTasks() as $task) { From 6320a8590c492d69855d2769bdc7fdd1b1b878d8 Mon Sep 17 00:00:00 2001 From: nook24 Date: Thu, 11 May 2023 18:00:05 +0200 Subject: [PATCH 24/54] ITC-2986 Display output of naemon config verification errors when inside a container --- src/Command/GearmanWorkerCommand.php | 56 ++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/src/Command/GearmanWorkerCommand.php b/src/Command/GearmanWorkerCommand.php index 8777cc0159..5351010eee 100644 --- a/src/Command/GearmanWorkerCommand.php +++ b/src/Command/GearmanWorkerCommand.php @@ -753,26 +753,50 @@ public function runJob($job) { break; case 'export_verify_config': + if(!IS_CONTAINER) { + // Normal installation of openITCOCKPIT via apt, dnf or git + /** @var SystemsettingsTable $SystemsettingsTable */ + $SystemsettingsTable = TableRegistry::getTableLocator()->get('Systemsettings'); + $systemsettings = $SystemsettingsTable->findAsArray(); - /** @var SystemsettingsTable $SystemsettingsTable */ - $SystemsettingsTable = TableRegistry::getTableLocator()->get('Systemsettings'); - $systemsettings = $SystemsettingsTable->findAsArray(); + $naemonBin = Configure::read('nagios.basepath') . Configure::read('nagios.bin') . Configure::read('nagios.nagios_bin'); + $naemonCfg = Configure::read('nagios.nagios_cfg'); - $naemonBin = Configure::read('nagios.basepath') . Configure::read('nagios.bin') . Configure::read('nagios.nagios_bin'); - $naemonCfg = Configure::read('nagios.nagios_cfg'); + $cmd = sprintf( + 'sudo -u %s %s -v %s', + escapeshellarg($systemsettings['MONITORING']['MONITORING.USER']), + $naemonBin, + $naemonCfg + ); - $cmd = sprintf( - 'sudo -u %s %s -v %s', - escapeshellarg($systemsettings['MONITORING']['MONITORING.USER']), - $naemonBin, - $naemonCfg - ); + exec($cmd, $output, $returncode); + $return = [ + 'output' => $output, + 'returncode' => $returncode, + ]; + }else{ + // openITCOCKPIT is running in a container like docker + $Supervisorctl = new Supervisorctl(); + // Naemon is running in a remote container, so we can only communicate through the XML RCP API of Supervisor + $SupervisorApiEndpoint = $Supervisorctl->getSupervisorApiEndpointByServiceName('naemon-verify'); + + // Clear any old logs + $SupervisorApiEndpoint->clearAllProcessLogs(); + + //Run naemon-verify + $Supervisorctl->start('naemon-verify'); + sleep(1); + $result = $Supervisorctl->status('naemon-verify'); + $returncode = $result['exitstatus']; + $output = [ + $SupervisorApiEndpoint->readProcessStdoutLog('naemon-verify', 0,(1024*1000)) + ]; - exec($cmd, $output, $returncode); - $return = [ - 'output' => $output, - 'returncode' => $returncode, - ]; + $return = [ + 'output' => $output ?? ['Unknown'], + 'returncode' => $returncode ?? 1, + ]; + } break; case 'export_verify_prometheus_config': From 572b7b4c4cc02edd381c79bb38aa7c628d669a4b Mon Sep 17 00:00:00 2001 From: nook24 Date: Fri, 12 May 2023 08:16:38 +0200 Subject: [PATCH 25/54] ITC-2986 catch Exception to not crash in CONTAINER_SETUP.sh --- .../Core/MonitoringEngine/NagiosConfigGenerator.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/itnovum/openITCOCKPIT/Core/MonitoringEngine/NagiosConfigGenerator.php b/src/itnovum/openITCOCKPIT/Core/MonitoringEngine/NagiosConfigGenerator.php index 0ddb62f164..d7bc1a2ff1 100644 --- a/src/itnovum/openITCOCKPIT/Core/MonitoringEngine/NagiosConfigGenerator.php +++ b/src/itnovum/openITCOCKPIT/Core/MonitoringEngine/NagiosConfigGenerator.php @@ -2720,8 +2720,12 @@ public function afterExportExternalTasks() { //Restart oitc CMD to wipe old cached information if (IS_CONTAINER) { - $Supervisorctl = new Supervisorctl(); - $Supervisorctl->restart('oitc_cmd'); + try { + $Supervisorctl = new Supervisorctl(); + $Supervisorctl->restart('oitc_cmd'); + } catch (\Exception $e) { + Log::error('NagiosConfigGenerator: ' . $e->getMessage()); + } } else { exec('systemctl restart oitc_cmd'); } From 1e306e227d39d47cb8f728066541ee3f0e01751d Mon Sep 17 00:00:00 2001 From: nook24 Date: Fri, 12 May 2023 09:55:41 +0200 Subject: [PATCH 26/54] ITC-2986 fix packetmanager if --- src/Template/Packetmanager/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Template/Packetmanager/index.php b/src/Template/Packetmanager/index.php index d0ed9c8305..1a125a80bd 100755 --- a/src/Template/Packetmanager/index.php +++ b/src/Template/Packetmanager/index.php @@ -49,7 +49,7 @@ - + element('repository_checker'); ?> From e16d545aae63fc4ea1275256dcbca402aa7c4bc0 Mon Sep 17 00:00:00 2001 From: nook24 Date: Fri, 12 May 2023 11:11:36 +0200 Subject: [PATCH 27/54] ITC-2986 Port debugging and SystemHealth to containers --- src/Command/GearmanWorkerCommand.php | 107 +++++++------ src/Command/SupervisorCommand.php | 11 +- src/Command/SystemHealthCommand.php | 146 ++++++++++-------- src/Controller/AdministratorsController.php | 22 ++- src/Template/Administrators/debug.php | 3 + .../Supervisor/Supervisorctl.php | 30 ++++ .../openITCOCKPIT/Supervisor/XMLRPCApi.php | 13 ++ 7 files changed, 218 insertions(+), 114 deletions(-) diff --git a/src/Command/GearmanWorkerCommand.php b/src/Command/GearmanWorkerCommand.php index 5351010eee..ed6282725a 100644 --- a/src/Command/GearmanWorkerCommand.php +++ b/src/Command/GearmanWorkerCommand.php @@ -753,7 +753,7 @@ public function runJob($job) { break; case 'export_verify_config': - if(!IS_CONTAINER) { + if (!IS_CONTAINER) { // Normal installation of openITCOCKPIT via apt, dnf or git /** @var SystemsettingsTable $SystemsettingsTable */ $SystemsettingsTable = TableRegistry::getTableLocator()->get('Systemsettings'); @@ -774,7 +774,7 @@ public function runJob($job) { 'output' => $output, 'returncode' => $returncode, ]; - }else{ + } else { // openITCOCKPIT is running in a container like docker $Supervisorctl = new Supervisorctl(); // Naemon is running in a remote container, so we can only communicate through the XML RCP API of Supervisor @@ -789,7 +789,7 @@ public function runJob($job) { $result = $Supervisorctl->status('naemon-verify'); $returncode = $result['exitstatus']; $output = [ - $SupervisorApiEndpoint->readProcessStdoutLog('naemon-verify', 0,(1024*1000)) + $SupervisorApiEndpoint->readProcessStdoutLog('naemon-verify', 0, (1024 * 1000)) ]; $return = [ @@ -922,49 +922,68 @@ public function runJob($job) { 'isNodeJsServerRunning' => false ]; - exec($systemsetting['MONITORING']['MONITORING.STATUS'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $state['isNagiosRunning'] = true; - } + if (IS_CONTAINER === false) { + // Normal installation of openITCOCKPIT via apt, dnf or git + exec($systemsetting['MONITORING']['MONITORING.STATUS'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $state['isNagiosRunning'] = true; + } - exec($systemsetting['INIT']['INIT.NDO_STATUS'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $state['isNdoRunning'] = true; - } + exec($systemsetting['INIT']['INIT.NDO_STATUS'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $state['isNdoRunning'] = true; + } - exec($systemsetting['INIT']['INIT.STATUSENIGNE_STATUS'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $state['isStatusengineRunning'] = true; - } + exec($systemsetting['INIT']['INIT.STATUSENIGNE_STATUS'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $state['isStatusengineRunning'] = true; + } - exec($systemsetting['INIT']['INIT.NPCD_STATUS'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $state['isNpcdRunning'] = true; - } + exec($systemsetting['INIT']['INIT.NPCD_STATUS'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $state['isNpcdRunning'] = true; + } - exec($systemsetting['INIT']['INIT.OITC_CMD_STATUS'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $state['isOitcCmdRunning'] = true; - } + exec($systemsetting['INIT']['INIT.OITC_CMD_STATUS'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $state['isOitcCmdRunning'] = true; + } - exec($systemsetting['INIT']['INIT.SUDO_SERVER_STATUS'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $state['isSudoServerRunning'] = true; - } + exec($systemsetting['INIT']['INIT.SUDO_SERVER_STATUS'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $state['isSudoServerRunning'] = true; + } - exec($systemsetting['INIT']['INIT.NSTA_STATUS'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $state['isNstaRunning'] = true; - } + exec($systemsetting['INIT']['INIT.NSTA_STATUS'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $state['isNstaRunning'] = true; + } - exec($systemsetting['INIT']['INIT.PUSH_NOTIFICATION'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $state['isPushNotificationRunning'] = true; - } + exec($systemsetting['INIT']['INIT.PUSH_NOTIFICATION'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $state['isPushNotificationRunning'] = true; + } + + exec($systemsetting['INIT']['INIT.OPENITCOCKPIT_NODE'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $state['isNodeJsServerRunning'] = true; + } + } else { + // openITCOCKPIT is running inside a container like docker + $Supervisorctl = new Supervisorctl(); + $state = [ + 'isNagiosRunning' => false, + 'isNdoRunning' => false, + 'isStatusengineRunning' => $Supervisorctl->isRunning('statusengine'), + 'isNpcdRunning' => false, + 'isOitcCmdRunning' => $Supervisorctl->isRunning('oitc_cmd'), + 'isSudoServerRunning' => $Supervisorctl->isRunning('sudo_server'), + 'isNstaRunning' => $Supervisorctl->isRunning('nsta'), + 'isGearmanWorkerRunning' => true, + 'isPushNotificationRunning' => $Supervisorctl->isRunning('push_notification'), + 'isNodeJsServerRunning' => $Supervisorctl->isRunning('openitcockpit-node') + ]; - exec($systemsetting['INIT']['INIT.OPENITCOCKPIT_NODE'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $state['isNodeJsServerRunning'] = true; } $return = $state; @@ -1359,18 +1378,18 @@ public function launchExport($createBackup = 1) { $Supervisorctl = new Supervisorctl(); - if(IS_CONTAINER){ + if (IS_CONTAINER) { // Naemon is running inside a container - query remote supervisor to run "naemon -v naemon.cfg" try { $Supervisorctl->start('naemon-verify'); sleep(2); $result = $Supervisorctl->status('naemon-verify'); $returncode = $result['exitstatus'] ?? 1; - }catch (\Exception $e){ + } catch (\Exception $e) { Log::error($e->getMessage()); $returncode = 1; } - }else { + } else { // Local running Naemon $naemonBin = Configure::read('nagios.basepath') . Configure::read('nagios.bin') . Configure::read('nagios.nagios_bin'); $naemonCfg = Configure::read('nagios.nagios_cfg'); @@ -1391,7 +1410,7 @@ public function launchExport($createBackup = 1) { $ExportsTable->save($verifyEntity); //Reloading the monitoring system - if(!IS_CONTAINER) { + if (!IS_CONTAINER) { //Check if Naemon/Nagios is running. //If Nagios is running, we reload the config, if not we need to restart $entity = $ExportsTable->newEntity([ @@ -1471,7 +1490,7 @@ public function launchExport($createBackup = 1) { } else { $successfully = 0; } - }else{ + } else { // Containerized openITCOCKPIT // Restart remote Naemon $entity = $ExportsTable->newEntity([ @@ -1482,7 +1501,7 @@ public function launchExport($createBackup = 1) { $result = $Supervisorctl->restart('naemon'); $entity->set('finished', 1); $entity->set('successfully', 0); - if($result === true){ + if ($result === true) { $entity->set('successfully', 1); $isMonitoringRunning = true; } diff --git a/src/Command/SupervisorCommand.php b/src/Command/SupervisorCommand.php index 75d13654f8..83f7c5966a 100644 --- a/src/Command/SupervisorCommand.php +++ b/src/Command/SupervisorCommand.php @@ -28,12 +28,10 @@ namespace App\Command; use App\itnovum\openITCOCKPIT\Supervisor\Supervisorctl; -use App\itnovum\openITCOCKPIT\Supervisor\XMLRPCApi; use Cake\Command\Command; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; -use http\Exception\RuntimeException; /** * Supervisor command. @@ -59,6 +57,9 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar 'help' => 'Command to execute', 'required' => true, 'choices' => [ + // If you edit this like, also make sure to edit + // Supervisorctl::getSupervisorApiEndpointByServiceName() + // openITCOCKPIT background 'oitc_cmd', 'sudo_server', @@ -74,6 +75,12 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar 'prometheus', 'nsta', + // Statusengine + 'statusengine', + + // puppeteer / PDF generation + 'openitcockpit-node', + // System 'nginx', 'php-fpm', diff --git a/src/Command/SystemHealthCommand.php b/src/Command/SystemHealthCommand.php index 87786653b2..70ee077fec 100644 --- a/src/Command/SystemHealthCommand.php +++ b/src/Command/SystemHealthCommand.php @@ -27,6 +27,7 @@ namespace App\Command; +use App\itnovum\openITCOCKPIT\Supervisor\Supervisorctl; use App\Model\Table\SystemsettingsTable; use Cake\Console\Arguments; use Cake\Console\Command; @@ -133,70 +134,91 @@ public function fetchInformation() { $errorRedirect = ' 2> /dev/null'; - - exec($systemsetting['MONITORING']['MONITORING.STATUS'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $data['isNagiosRunning'] = true; - } - - exec($systemsetting['INIT']['INIT.NDO_STATUS'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $data['isNdoRunning'] = true; - } - - exec($systemsetting['INIT']['INIT.STATUSENIGNE_STATUS'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $data['isStatusengineRunning'] = true; - } - - exec($systemsetting['INIT']['INIT.NPCD_STATUS'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $data['isNpcdRunning'] = true; - } - - exec($systemsetting['INIT']['INIT.OITC_CMD_STATUS'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $data['isOitcCmdRunning'] = true; - } - - exec($systemsetting['INIT']['INIT.SUDO_SERVER_STATUS'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $data['isSudoServerRunning'] = true; - } - - exec($systemsetting['INIT']['INIT.NSTA_STATUS'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $data['isNstaRunning'] = true; - } - - exec($systemsetting['INIT']['INIT.PUSH_NOTIFICATION'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $data['isPushNotificationRunning'] = true; + if(IS_CONTAINER === false) { + // Normal installation of openITCOCKPIT via apt, dnf or git + exec($systemsetting['MONITORING']['MONITORING.STATUS'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $data['isNagiosRunning'] = true; + } + + exec($systemsetting['INIT']['INIT.NDO_STATUS'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $data['isNdoRunning'] = true; + } + + exec($systemsetting['INIT']['INIT.STATUSENIGNE_STATUS'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $data['isStatusengineRunning'] = true; + } + + exec($systemsetting['INIT']['INIT.NPCD_STATUS'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $data['isNpcdRunning'] = true; + } + + exec($systemsetting['INIT']['INIT.OITC_CMD_STATUS'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $data['isOitcCmdRunning'] = true; + } + + exec($systemsetting['INIT']['INIT.SUDO_SERVER_STATUS'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $data['isSudoServerRunning'] = true; + } + + exec($systemsetting['INIT']['INIT.NSTA_STATUS'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $data['isNstaRunning'] = true; + } + + exec($systemsetting['INIT']['INIT.PUSH_NOTIFICATION'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $data['isPushNotificationRunning'] = true; + } + + exec($systemsetting['INIT']['INIT.OPENITCOCKPIT_NODE'] . $errorRedirect, $output, $returncode); + if ($returncode == 0) { + $data['isNodeJsServerRunning'] = true; + } + + if (file_exists('/opt/openitc/nagios/bin/ndo2db')) { + $data['isNdoInstalled'] = true; + } + + //if (file_exists('/opt/openitc/statusengine2/cakephp/app/Console/Command/StatusengineLegacyShell.php')) { + // $data['isStatusengineInstalled'] = true; + //} + + //$statusengineConfig = '/opt/openitc/statusengine2/cakephp/app/Config/Statusengine.php'; + //if (file_exists($statusengineConfig)) { + // require_once $statusengineConfig; + // if (isset($config['process_perfdata'])) { + // if ($config['process_perfdata'] === true) { + // $data['isStatusenginePerfdataProcessor'] = true; + // } + // } + //} + }else{ + // openITCOCKPIT is running inside a container like docker + $Supervisorctl = new Supervisorctl(); + $data = [ + 'isNagiosRunning' => $Supervisorctl->isRunning('naemon'), + 'isNdoRunning' => false, + 'isStatusengineRunning' => $Supervisorctl->isRunning('statusengine'), + 'isNpcdRunning' => false, + 'isOitcCmdRunning' => $Supervisorctl->isRunning('oitc_cmd'), + 'isSudoServerRunning' => $Supervisorctl->isRunning('sudo_server'), + 'isNstaRunning' => $Supervisorctl->isRunning('nsta'), + 'isGearmanWorkerRunning' => $Supervisorctl->isRunning('gearman_worker'), + 'isNdoInstalled' => false, + 'isStatusengineInstalled' => true, //NDOUtils are not supported anymore + 'isStatusenginePerfdataProcessor' => true, //NPCD is not supported anymore + 'isDistributeModuleInstalled' => false, + 'isPushNotificationRunning' => $Supervisorctl->isRunning('push_notification'), + 'isNodeJsServerRunning' => $Supervisorctl->isRunning('openitcockpit-node') + ]; } - exec($systemsetting['INIT']['INIT.OPENITCOCKPIT_NODE'] . $errorRedirect, $output, $returncode); - if ($returncode == 0) { - $data['isNodeJsServerRunning'] = true; - } - - if (file_exists('/opt/openitc/nagios/bin/ndo2db')) { - $data['isNdoInstalled'] = true; - } - - //if (file_exists('/opt/openitc/statusengine2/cakephp/app/Console/Command/StatusengineLegacyShell.php')) { - // $data['isStatusengineInstalled'] = true; - //} - - //$statusengineConfig = '/opt/openitc/statusengine2/cakephp/app/Config/Statusengine.php'; - //if (file_exists($statusengineConfig)) { - // require_once $statusengineConfig; - // if (isset($config['process_perfdata'])) { - // if ($config['process_perfdata'] === true) { - // $data['isStatusenginePerfdataProcessor'] = true; - // } - // } - //} - if (Plugin::isLoaded('DistributeModule')) { $data['isDistributeModuleInstalled'] = true; } diff --git a/src/Controller/AdministratorsController.php b/src/Controller/AdministratorsController.php index 25263150c7..6fc4c1cba4 100644 --- a/src/Controller/AdministratorsController.php +++ b/src/Controller/AdministratorsController.php @@ -127,6 +127,15 @@ function debug() { //NPCD is not supported anymore! $isStatusenginePerfdataProcessor = true; + if (IS_CONTAINER) { + // We are running inside a container and are therefore a recent version of openITCOCKPIT. + // NDO and NPCD support was dropped with openITCOCKPIT 3.x (at least 2 years before container support) + // so there is absolutely no way we have one of those two installed. + // Honestly speaking the checking for NDO and NPCD should be removed anyway! + $isStatusengineInstalled = true; + $isStatusenginePerfdataProcessor = true; + } + $processInformation = [ 'gearmanReachable' => $gearmanReachable, 'isGearmanWorkerRunning' => $isGearmanWorkerRunning, @@ -139,9 +148,9 @@ function debug() { //Collect server information $LsbRelease = new LsbRelease(); - if($LsbRelease->isDebianBased()){ + if ($LsbRelease->isDebianBased()) { $osVersion = sprintf('%s %s (%s)', $LsbRelease->getVendor(), $LsbRelease->getVersion(), $LsbRelease->getCodename()); - }else{ + } else { $osVersion = $LsbRelease->getCodename(); } @@ -159,7 +168,8 @@ function debug() { 'php_version' => PHP_VERSION, 'php_memory_limit' => str_replace('M', '', get_cfg_var('memory_limit')) . 'MB', 'php_max_execution_time' => ini_get('max_execution_time'), - 'php_extensions' => get_loaded_extensions() + 'php_extensions' => get_loaded_extensions(), + 'containerized' => (IS_CONTAINER) ? __('Yes') : __('No') ]; //Collect CPU load history @@ -200,7 +210,7 @@ function debug() { $gearmanStatus = []; $output = null; if ($gearmanReachable) { - exec('gearadmin --status', $output); + exec('gearadmin --status -h ' . escapeshellarg(env('OITC_GEARMAN_ADDRESS', 'localhost')), $output); //Parse output $trash = array_pop($output); foreach ($output as $line) { @@ -357,8 +367,8 @@ public function testMail() { $Mailer->setEmailFormat('both'); $Mailer->setAttachments([ 'logo.png' => [ - 'file' => $Logo->getSmallLogoDiskPath(), - 'mimetype' => 'image/png', + 'file' => $Logo->getSmallLogoDiskPath(), + 'mimetype' => 'image/png', 'contentId' => '100' ] ]); diff --git a/src/Template/Administrators/debug.php b/src/Template/Administrators/debug.php index de1d0f3b05..2a2d534df5 100755 --- a/src/Template/Administrators/debug.php +++ b/src/Template/Administrators/debug.php @@ -433,6 +433,9 @@
:
{{serverInformation.kernel}}
+
:
+
{{serverInformation.containerized}}
+
:
{{serverInformation.php_version}}
diff --git a/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php b/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php index bdcacc70de..065a95e418 100644 --- a/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php +++ b/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php @@ -2,6 +2,8 @@ namespace App\itnovum\openITCOCKPIT\Supervisor; +use Cake\Log\Log; + /** * Wrapper class that has the goal to provide simmilar features such as `systemctl status nginx` * but via supervisor @@ -55,6 +57,9 @@ public function status(string $serviceName) { * @throws \RuntimeException */ public function getSupervisorApiEndpointByServiceName(string $serviceName): XMLRPCApi { + // If you edit this like, also make sure to edit + // SupervisorCommand::buildOptionParser() + $username = env('SUPERVISOR_USER', 'supervisord'); $password = env('SUPERVISOR_PASSWORD', 'password'); @@ -70,6 +75,16 @@ public function getSupervisorApiEndpointByServiceName(string $serviceName): XMLR $SupervisorApi = new XMLRPCApi($username, $password, $url); break; + case 'statusengine': + // Tell the Naemon Container to start|stop|restart Naemon + $url = sprintf( + 'http://%s:%s/RPC2', + env('OITC_STATUSENGINE_WORKER_HOSTNAME', 'statusengine-worker'), + env('SUPERVISOR_PORT', 9001) + ); + $SupervisorApi = new XMLRPCApi($username, $password, $url); + break; + default: // Service is running in the same container as openITCOCKPIT itslef $SupervisorApi = new XMLRPCApi($username, $password, 'http://127.0.0.1:9001/RPC2'); @@ -83,5 +98,20 @@ public function getSupervisorApiEndpointByServiceName(string $serviceName): XMLR return $SupervisorApi; } + public function isRunning(string $serviceName): bool { + try { + $SupervisorApi = $this->getSupervisorApiEndpointByServiceName($serviceName); + $result = $SupervisorApi->getProcessInfo($serviceName); + if (isset($result['statename']) && $result['statename'] === 'STARTING' || $result['statename'] === 'RUNNING') { + // We consider STARTING as running is this case as the process itself is started + return true; + } + } catch (\Exception $e) { + Log::error($e->getMessage()); + } + + return false; + } + } diff --git a/src/itnovum/openITCOCKPIT/Supervisor/XMLRPCApi.php b/src/itnovum/openITCOCKPIT/Supervisor/XMLRPCApi.php index f73363ded2..8314dd9a60 100644 --- a/src/itnovum/openITCOCKPIT/Supervisor/XMLRPCApi.php +++ b/src/itnovum/openITCOCKPIT/Supervisor/XMLRPCApi.php @@ -291,6 +291,19 @@ public function methodSignature(string $method) { * 'description' => 'unknown error making dispatchers for 'sudo_server': ENXIO' * ] * + * Process States + * | Statename | Code | Description | + * |-----------|------|-----------------------------------------------------------------------------------------| + * | STOPPED | 0 | The process has been stopped due to a stop request or has never been started. | + * | STARTING | 10 | The process is starting due to a start request. | + * | RUNNING | 20 | The process is running. | + * | BACKOFF | 30 | The process entered the STARTING state but subsequently exited too quickly | + * | | | (before the time defined in startsecs) to move to the RUNNING state. | + * | STOPPING | 40 | The process is stopping due to a stop request. | + * | EXITED | 100 | The process exited from the RUNNING state (expectedly or unexpectedly). | + * | FATAL | 200 | The process could not be started successfully. | + * | UNKNOWN | 1000 | The process is in an unknown state (supervisord programming error). | + * * @see http://supervisord.org/api.html#supervisor.rpcinterface.SupervisorNamespaceRPCInterface.getProcessInfo * @param string $name The name of the process (or ‘group:name’) * @return array result A structure containing data about the process From bcbe0659031f0332a75e4f1fe7ff6a4435c6cbd5 Mon Sep 17 00:00:00 2001 From: nook24 Date: Fri, 12 May 2023 14:15:10 +0200 Subject: [PATCH 28/54] ITC-2986 Add naemon stats --- src/Command/GearmanWorkerCommand.php | 2 +- src/Command/SupervisorCommand.php | 1 + .../Core/System/Health/MonitoringEngine.php | 25 ++++++++++++++++--- .../Supervisor/Supervisorctl.php | 1 + 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/Command/GearmanWorkerCommand.php b/src/Command/GearmanWorkerCommand.php index ed6282725a..0abe63cef3 100644 --- a/src/Command/GearmanWorkerCommand.php +++ b/src/Command/GearmanWorkerCommand.php @@ -972,7 +972,7 @@ public function runJob($job) { // openITCOCKPIT is running inside a container like docker $Supervisorctl = new Supervisorctl(); $state = [ - 'isNagiosRunning' => false, + 'isNagiosRunning' => $Supervisorctl->isRunning('naemon'), 'isNdoRunning' => false, 'isStatusengineRunning' => $Supervisorctl->isRunning('statusengine'), 'isNpcdRunning' => false, diff --git a/src/Command/SupervisorCommand.php b/src/Command/SupervisorCommand.php index 83f7c5966a..77171249a2 100644 --- a/src/Command/SupervisorCommand.php +++ b/src/Command/SupervisorCommand.php @@ -72,6 +72,7 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar // Monitoring Engines 'naemon', 'naemon-verify', + 'naemon-stats', 'prometheus', 'nsta', diff --git a/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php b/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php index 1cb54822e7..db6c3e00b2 100644 --- a/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php +++ b/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php @@ -25,7 +25,9 @@ namespace itnovum\openITCOCKPIT\Core\System\Health; +use App\itnovum\openITCOCKPIT\Supervisor\Supervisorctl; use Cake\Core\Configure; +use Cake\Log\Log; class MonitoringEngine { @@ -140,7 +142,7 @@ class MonitoringEngine { public function __construct() { if (IS_CONTAINER) { // We always use Naemon for containers - $this->monitoringEngine = 'Naemon Core Container'; + $this->monitoringEngine = 'Naemon Core Container'; return; } @@ -198,9 +200,26 @@ public function getNagiostatsCommand() { * @return array|false */ public function runNagiostats() { - exec($this->getNagiostatsCommand(), $output); + $output = []; + if (IS_CONTAINER) { + // Naemon is running inside a container - query remote supervisor to run "naemon -v naemon.cfg" + try { + $Supervisorctl = new Supervisorctl(); + $SupervisorEndpoint = $Supervisorctl->getSupervisorApiEndpointByServiceName('naemon-state'); + $SupervisorEndpoint->clearProcessLogs('naemon-stats'); + $Supervisorctl->start('naemon-stats'); + $output = [ + $SupervisorEndpoint->readProcessStdoutLog('naemon-stats', 0, (1024 * 1000)) + ]; + } catch (\Exception $e) { + Log::error($e->getMessage()); + } + } else { + // Local running Naemon + exec($this->getNagiostatsCommand(), $output); + } - // Nagios and Naemon add the delimiter also the the end of the string + // Nagios and Naemon add the delimiter also to the end of the string // this is bad, because explode will create and empty value in the array // and this throw a warning in array_combine $result = explode($this->delimiter, $output[0]); diff --git a/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php b/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php index 065a95e418..1c14792380 100644 --- a/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php +++ b/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php @@ -66,6 +66,7 @@ public function getSupervisorApiEndpointByServiceName(string $serviceName): XMLR switch ($serviceName) { case 'naemon': case 'naemon-verify': + case 'naemon-stats': // Tell the Naemon Container to start|stop|restart Naemon $url = sprintf( 'http://%s:%s/RPC2', From a68550c9544e2c65cd0565b64b35c79cd96c0617 Mon Sep 17 00:00:00 2001 From: nook24 Date: Fri, 12 May 2023 14:33:20 +0200 Subject: [PATCH 29/54] ITC-2986 Fix remote execution of naemon status --- .../openITCOCKPIT/Core/System/Health/MonitoringEngine.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php b/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php index db6c3e00b2..cf42a54699 100644 --- a/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php +++ b/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php @@ -205,8 +205,10 @@ public function runNagiostats() { // Naemon is running inside a container - query remote supervisor to run "naemon -v naemon.cfg" try { $Supervisorctl = new Supervisorctl(); - $SupervisorEndpoint = $Supervisorctl->getSupervisorApiEndpointByServiceName('naemon-state'); - $SupervisorEndpoint->clearProcessLogs('naemon-stats'); + $SupervisorEndpoint = $Supervisorctl->getSupervisorApiEndpointByServiceName('naemon-stats'); + // https://github.com/Supervisor/supervisor/issues/804 + //$SupervisorEndpoint->clearProcessLogs('naemon-stats'); + $SupervisorEndpoint->clearAllProcessLogs(); $Supervisorctl->start('naemon-stats'); $output = [ $SupervisorEndpoint->readProcessStdoutLog('naemon-stats', 0, (1024 * 1000)) From 89f7d270a4f94abc17c3342b9561ee772def613f Mon Sep 17 00:00:00 2001 From: nook24 Date: Fri, 12 May 2023 14:47:13 +0200 Subject: [PATCH 30/54] ITC-2986 Fix remote execution of naemon status --- .../openITCOCKPIT/Core/System/Health/MonitoringEngine.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php b/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php index cf42a54699..da34ca303c 100644 --- a/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php +++ b/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php @@ -210,6 +210,7 @@ public function runNagiostats() { //$SupervisorEndpoint->clearProcessLogs('naemon-stats'); $SupervisorEndpoint->clearAllProcessLogs(); $Supervisorctl->start('naemon-stats'); + sleep(1); $output = [ $SupervisorEndpoint->readProcessStdoutLog('naemon-stats', 0, (1024 * 1000)) ]; @@ -227,7 +228,7 @@ public function runNagiostats() { $result = explode($this->delimiter, $output[0]); $result_sizeof = sizeof($result); if (sizeof($this->MRTG) < $result_sizeof) { - if ($result[$result_sizeof - 1] == '') { + if (trim($result[$result_sizeof - 1]) == '') { unset($result[$result_sizeof - 1]); } } From bd05ab7144439aa7bf4143b2e0a862a039295c69 Mon Sep 17 00:00:00 2001 From: nook24 Date: Fri, 12 May 2023 15:03:23 +0200 Subject: [PATCH 31/54] ITC-2986 Fix Redis Connection in SystemHealth cronjob --- src/Command/SystemHealthCommand.php | 10 +++++++--- src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php | 8 +++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Command/SystemHealthCommand.php b/src/Command/SystemHealthCommand.php index 70ee077fec..2526a41793 100644 --- a/src/Command/SystemHealthCommand.php +++ b/src/Command/SystemHealthCommand.php @@ -134,7 +134,7 @@ public function fetchInformation() { $errorRedirect = ' 2> /dev/null'; - if(IS_CONTAINER === false) { + if (IS_CONTAINER === false) { // Normal installation of openITCOCKPIT via apt, dnf or git exec($systemsetting['MONITORING']['MONITORING.STATUS'] . $errorRedirect, $output, $returncode); if ($returncode == 0) { @@ -198,7 +198,7 @@ public function fetchInformation() { // } // } //} - }else{ + } else { // openITCOCKPIT is running inside a container like docker $Supervisorctl = new Supervisorctl(); $data = [ @@ -228,8 +228,12 @@ public function fetchInformation() { public function saveToCache($data) { $data['update'] = time(); + + $redisHost = env('OITC_REDIS_HOST', '127.0.0.1'); + $redisPort = filter_var(env('OITC_REDIS_PORT', 6379), FILTER_VALIDATE_INT); + $Redis = new \Redis(); - $Redis->connect('127.0.0.1', 6379); + $Redis->connect($redisHost, $redisPort); $Redis->setex('permissions_system_health', 60 * 3, serialize($data)); } } diff --git a/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php b/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php index 1c14792380..dc6bcf0891 100644 --- a/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php +++ b/src/itnovum/openITCOCKPIT/Supervisor/Supervisorctl.php @@ -103,9 +103,11 @@ public function isRunning(string $serviceName): bool { try { $SupervisorApi = $this->getSupervisorApiEndpointByServiceName($serviceName); $result = $SupervisorApi->getProcessInfo($serviceName); - if (isset($result['statename']) && $result['statename'] === 'STARTING' || $result['statename'] === 'RUNNING') { - // We consider STARTING as running is this case as the process itself is started - return true; + if (isset($result['statename'])) { + if($result['statename'] === 'STARTING' || $result['statename'] === 'RUNNING') { + // We consider STARTING as running is this case as the process itself is started + return true; + } } } catch (\Exception $e) { Log::error($e->getMessage()); From d8c62c64bb32ff966dff0462c15a5823a743de82 Mon Sep 17 00:00:00 2001 From: nook24 Date: Fri, 12 May 2023 15:16:28 +0200 Subject: [PATCH 32/54] ITC-2986 Fix SystemHealth cronjob --- src/Command/SystemHealthCommand.php | 40 +++++++++++++++-------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/Command/SystemHealthCommand.php b/src/Command/SystemHealthCommand.php index 2526a41793..3f441c72d3 100644 --- a/src/Command/SystemHealthCommand.php +++ b/src/Command/SystemHealthCommand.php @@ -96,6 +96,27 @@ public function fetchInformation() { 'isNodeJsServerRunning' => false ]; + if (IS_CONTAINER) { + // openITCOCKPIT is running inside a container like docker + $Supervisorctl = new Supervisorctl(); + $data = [ + 'isNagiosRunning' => $Supervisorctl->isRunning('naemon'), + 'isNdoRunning' => false, + 'isStatusengineRunning' => $Supervisorctl->isRunning('statusengine'), + 'isNpcdRunning' => false, + 'isOitcCmdRunning' => $Supervisorctl->isRunning('oitc_cmd'), + 'isSudoServerRunning' => $Supervisorctl->isRunning('sudo_server'), + 'isNstaRunning' => $Supervisorctl->isRunning('nsta'), + 'isGearmanWorkerRunning' => $Supervisorctl->isRunning('gearman_worker'), + 'isNdoInstalled' => false, + 'isStatusengineInstalled' => true, //NDOUtils are not supported anymore + 'isStatusenginePerfdataProcessor' => true, //NPCD is not supported anymore + 'isDistributeModuleInstalled' => false, + 'isPushNotificationRunning' => $Supervisorctl->isRunning('push_notification'), + 'isNodeJsServerRunning' => $Supervisorctl->isRunning('openitcockpit-node') + ]; + } + /** @var SystemsettingsTable $SystemsettingsTable */ $SystemsettingsTable = TableRegistry::getTableLocator()->get('Systemsettings'); $systemsetting = $SystemsettingsTable->findAsArray(); @@ -198,25 +219,6 @@ public function fetchInformation() { // } // } //} - } else { - // openITCOCKPIT is running inside a container like docker - $Supervisorctl = new Supervisorctl(); - $data = [ - 'isNagiosRunning' => $Supervisorctl->isRunning('naemon'), - 'isNdoRunning' => false, - 'isStatusengineRunning' => $Supervisorctl->isRunning('statusengine'), - 'isNpcdRunning' => false, - 'isOitcCmdRunning' => $Supervisorctl->isRunning('oitc_cmd'), - 'isSudoServerRunning' => $Supervisorctl->isRunning('sudo_server'), - 'isNstaRunning' => $Supervisorctl->isRunning('nsta'), - 'isGearmanWorkerRunning' => $Supervisorctl->isRunning('gearman_worker'), - 'isNdoInstalled' => false, - 'isStatusengineInstalled' => true, //NDOUtils are not supported anymore - 'isStatusenginePerfdataProcessor' => true, //NPCD is not supported anymore - 'isDistributeModuleInstalled' => false, - 'isPushNotificationRunning' => $Supervisorctl->isRunning('push_notification'), - 'isNodeJsServerRunning' => $Supervisorctl->isRunning('openitcockpit-node') - ]; } if (Plugin::isLoaded('DistributeModule')) { From afa622f8ce3522f78e53f2b2d3227db3e8bf53b7 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 17 May 2023 09:02:18 +0200 Subject: [PATCH 33/54] ITC-2986 Add env var OITC_PUPPETEER_ADDRESS for contianers --- plugins/PuppeteerPdf/src/Pdf/PuppeteerClient.php | 5 +++++ src/itnovum/openITCOCKPIT/Core/NodeJS/ChartRenderClient.php | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/plugins/PuppeteerPdf/src/Pdf/PuppeteerClient.php b/plugins/PuppeteerPdf/src/Pdf/PuppeteerClient.php index 7cee1fe2b8..8bb9e9e951 100644 --- a/plugins/PuppeteerPdf/src/Pdf/PuppeteerClient.php +++ b/plugins/PuppeteerPdf/src/Pdf/PuppeteerClient.php @@ -26,6 +26,11 @@ class PuppeteerClient { private $address = 'http://127.0.0.1:7084/'; public function __construct() { + $address = env('OITC_PUPPETEER_ADDRESS', null); + if (empty(!$address)) { + $this->address = $address; + } + $this->Client = new Client([ 'base_uri' => $this->address, 'proxy' => [ diff --git a/src/itnovum/openITCOCKPIT/Core/NodeJS/ChartRenderClient.php b/src/itnovum/openITCOCKPIT/Core/NodeJS/ChartRenderClient.php index 5115c6975e..9170eba059 100644 --- a/src/itnovum/openITCOCKPIT/Core/NodeJS/ChartRenderClient.php +++ b/src/itnovum/openITCOCKPIT/Core/NodeJS/ChartRenderClient.php @@ -70,6 +70,11 @@ class ChartRenderClient { private $endTimestamp = 0; public function __construct() { + $address = env('OITC_PUPPETEER_ADDRESS', null); + if (empty(!$address)) { + $this->address = $address; + } + $this->Client = new Client([ 'base_uri' => $this->address, 'proxy' => [ From 2bbc3e204c0ec2cd81b2d3794694a20d8d89195f Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 17 May 2023 13:32:23 +0200 Subject: [PATCH 34/54] ITC-2986 Implement Binaryd for one-shot commands --- src/Command/GearmanWorkerCommand.php | 44 ++++++++------ src/Command/SupervisorCommand.php | 2 - .../Core/System/Health/MonitoringEngine.php | 15 ++--- .../openITCOCKPIT/Supervisor/BinarydAPI.php | 59 +++++++++++++++++++ .../openITCOCKPIT/Supervisor/Binarydctl.php | 42 +++++++++++++ .../Supervisor/Supervisorctl.php | 2 - 6 files changed, 131 insertions(+), 33 deletions(-) create mode 100644 src/itnovum/openITCOCKPIT/Supervisor/BinarydAPI.php create mode 100644 src/itnovum/openITCOCKPIT/Supervisor/Binarydctl.php diff --git a/src/Command/GearmanWorkerCommand.php b/src/Command/GearmanWorkerCommand.php index 0abe63cef3..76bc340660 100644 --- a/src/Command/GearmanWorkerCommand.php +++ b/src/Command/GearmanWorkerCommand.php @@ -30,6 +30,7 @@ use App\itnovum\openITCOCKPIT\Database\Backup; use App\itnovum\openITCOCKPIT\Monitoring\Naemon\ExternalCommands; +use App\itnovum\openITCOCKPIT\Supervisor\Binarydctl; use App\itnovum\openITCOCKPIT\Supervisor\Supervisorctl; use App\Model\Entity\Changelog; use App\Model\Table\AgentconfigsTable; @@ -776,21 +777,20 @@ public function runJob($job) { ]; } else { // openITCOCKPIT is running in a container like docker - $Supervisorctl = new Supervisorctl(); + $Binarydctl = new Binarydctl(); // Naemon is running in a remote container, so we can only communicate through the XML RCP API of Supervisor - $SupervisorApiEndpoint = $Supervisorctl->getSupervisorApiEndpointByServiceName('naemon-verify'); - - // Clear any old logs - $SupervisorApiEndpoint->clearAllProcessLogs(); + $BinarydEndpoint = $Binarydctl->getBinarydApiEndpointByServiceName('naemon-verify'); //Run naemon-verify - $Supervisorctl->start('naemon-verify'); - sleep(1); - $result = $Supervisorctl->status('naemon-verify'); - $returncode = $result['exitstatus']; - $output = [ - $SupervisorApiEndpoint->readProcessStdoutLog('naemon-verify', 0, (1024 * 1000)) - ]; + try{ + $result = $BinarydEndpoint->executeJson('naemon-verify'); + $returncode = $result['rc'] ?? 1; + $output = [ + $result['stdout'] ?? '' + ]; + }catch (\Exception $e){ + Log::error($e->getMessage()); + } $return = [ 'output' => $output ?? ['Unknown'], @@ -1380,14 +1380,20 @@ public function launchExport($createBackup = 1) { if (IS_CONTAINER) { // Naemon is running inside a container - query remote supervisor to run "naemon -v naemon.cfg" - try { - $Supervisorctl->start('naemon-verify'); - sleep(2); - $result = $Supervisorctl->status('naemon-verify'); - $returncode = $result['exitstatus'] ?? 1; - } catch (\Exception $e) { + // openITCOCKPIT is running in a container like docker + $Binarydctl = new Binarydctl(); + // Naemon is running in a remote container, so we can only communicate through the XML RCP API of Supervisor + $BinarydEndpoint = $Binarydctl->getBinarydApiEndpointByServiceName('naemon-verify'); + + //Run naemon-verify + try{ + $result = $BinarydEndpoint->executeJson('naemon-verify'); + $returncode = $result['rc'] ?? 1; + $output = [ + $result['stdout'] ?? '' + ]; + }catch (\Exception $e){ Log::error($e->getMessage()); - $returncode = 1; } } else { // Local running Naemon diff --git a/src/Command/SupervisorCommand.php b/src/Command/SupervisorCommand.php index 77171249a2..42f2d7d2c5 100644 --- a/src/Command/SupervisorCommand.php +++ b/src/Command/SupervisorCommand.php @@ -71,8 +71,6 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar // Monitoring Engines 'naemon', - 'naemon-verify', - 'naemon-stats', 'prometheus', 'nsta', diff --git a/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php b/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php index da34ca303c..d249f5d0f2 100644 --- a/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php +++ b/src/itnovum/openITCOCKPIT/Core/System/Health/MonitoringEngine.php @@ -25,6 +25,7 @@ namespace itnovum\openITCOCKPIT\Core\System\Health; +use App\itnovum\openITCOCKPIT\Supervisor\Binarydctl; use App\itnovum\openITCOCKPIT\Supervisor\Supervisorctl; use Cake\Core\Configure; use Cake\Log\Log; @@ -204,16 +205,10 @@ public function runNagiostats() { if (IS_CONTAINER) { // Naemon is running inside a container - query remote supervisor to run "naemon -v naemon.cfg" try { - $Supervisorctl = new Supervisorctl(); - $SupervisorEndpoint = $Supervisorctl->getSupervisorApiEndpointByServiceName('naemon-stats'); - // https://github.com/Supervisor/supervisor/issues/804 - //$SupervisorEndpoint->clearProcessLogs('naemon-stats'); - $SupervisorEndpoint->clearAllProcessLogs(); - $Supervisorctl->start('naemon-stats'); - sleep(1); - $output = [ - $SupervisorEndpoint->readProcessStdoutLog('naemon-stats', 0, (1024 * 1000)) - ]; + $Binarydctl = new Binarydctl(); + $BinarydEndpoint = $Binarydctl->getBinarydApiEndpointByServiceName('naemon-stats'); + $result = $BinarydEndpoint->execute('naemon-stats'); + $output = [$result]; } catch (\Exception $e) { Log::error($e->getMessage()); } diff --git a/src/itnovum/openITCOCKPIT/Supervisor/BinarydAPI.php b/src/itnovum/openITCOCKPIT/Supervisor/BinarydAPI.php new file mode 100644 index 0000000000..c47ee9b40a --- /dev/null +++ b/src/itnovum/openITCOCKPIT/Supervisor/BinarydAPI.php @@ -0,0 +1,59 @@ + +// +// Licensed under The MIT License +// + + +namespace App\itnovum\openITCOCKPIT\Supervisor; + +use GuzzleHttp\Client; +use GuzzleHttp\Exception\ClientException; +use GuzzleHttp\Exception\ConnectException; +use GuzzleHttp\RequestOptions; +use itnovum\openITCOCKPIT\Core\NodeJS\ErrorPdf; + +class BinarydAPI { + + /** + * @var Client + */ + private $Client; + + public function __construct(string $address) { + $this->Client = new Client([ + 'base_uri' => $address, + 'proxy' => [ + 'http' => false, + 'https' => false + ] + ]); + } + + /** + * Executes the command and returns the RAW output + * + * @param string $programName + * @return string + * @throws \GuzzleHttp\Exception\GuzzleException + */ + public function execute(string $programName) { + $response = $this->Client->get('/' . $programName); + return $response->getBody()->getContents(); + } + + + /** + * Executes the command via the /json/ API of binaryd + * This returns the output and return code + * + * @param string $programName + * @return array + * @throws \GuzzleHttp\Exception\GuzzleException + */ + public function executeJson(string $programName) { + $response = $this->Client->get('/json/' . $programName); + $result = $response->getBody()->getContents(); + return json_decode($result, true); + } +} diff --git a/src/itnovum/openITCOCKPIT/Supervisor/Binarydctl.php b/src/itnovum/openITCOCKPIT/Supervisor/Binarydctl.php new file mode 100644 index 0000000000..9632f581fd --- /dev/null +++ b/src/itnovum/openITCOCKPIT/Supervisor/Binarydctl.php @@ -0,0 +1,42 @@ + Date: Wed, 17 May 2023 15:56:17 +0200 Subject: [PATCH 35/54] ITC-2986 Add update.sh --- CONTAINER_SETUP.sh | 34 +--- CONTAINER_UPDATE.sh | 407 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 408 insertions(+), 33 deletions(-) create mode 100644 CONTAINER_UPDATE.sh diff --git a/CONTAINER_SETUP.sh b/CONTAINER_SETUP.sh index 4a5d5d0173..4ee2cf4ac3 100644 --- a/CONTAINER_SETUP.sh +++ b/CONTAINER_SETUP.sh @@ -222,41 +222,9 @@ echo "Enabling webserver configuration" ln -s /etc/nginx/sites-available/openitc /etc/nginx/sites-enabled/openitc rm -f /etc/nginx/sites-enabled/default -#systemctl restart\ -# statusengine.service\ -# nagios.service\ -# nginx.service\ -# sudo_server.service\ -# oitc_cmd.service\ -# gearman_worker.service\ -# push_notification.service\ -# openitcockpit-node.service\ -# oitc_cronjobs.timer - -#echo "Detected PHP Version: ${PHPVersion} try to restart php-fpm" -# -#set +e -#systemctl is-enabled --quiet php${PHPVersion}-fpm.service &>/dev/null -#RC=$? -#if [ $RC -eq 0 ]; then -# #Is it php7.3-fpm-service ? -# systemctl restart php${PHPVersion}-fpm.service -#else -# # Is it just php-fpm.service? -# systemctl is-enabled --quiet php-fpm.service -# RC=$? -# if [ $RC -eq 0 ]; then -# systemctl restart php-fpm.service -# else -# echo "ERROR: could not detect php-fpm systemd service file. You need to restart php-fpm manualy" -# fi -#fi -#set -e - #Set default permissions, check for always allowed permissions and dependencies oitc roles --enable-defaults --admin -date > /opt/openitc/etc/.installation_done +date > /opt/openitc/var/.installation_done -#/opt/openitc/frontend/UPDATE.sh diff --git a/CONTAINER_UPDATE.sh b/CONTAINER_UPDATE.sh new file mode 100644 index 0000000000..996166036c --- /dev/null +++ b/CONTAINER_UPDATE.sh @@ -0,0 +1,407 @@ +#!/bin/bash +if [[ $1 == "--help" ]]; then + echo "Supported parameters:" + echo "--rights Reset file permissions" + echo "--cc Clear model cache" + + exit 0 +fi + +# Enable debug mode so that CakePHP will create missing folders +# https://github.com/it-novum/openITCOCKPIT/issues/1446 +# https://github.com/cakephp/migrations/issues/565 +export OITC_DEBUG=1 + +APPDIR="/opt/openitc/frontend" +INIFILE=/opt/openitc/etc/mysql/mysql.cnf +DUMPINIFILE=/opt/openitc/etc/mysql/dump.cnf +BASHCONF=/opt/openitc/etc/mysql/bash.conf + +if [[ ! -f "$BASHCONF" ]]; then + MYSQL_USER=openitcockpit + MYSQL_DATABASE=openitcockpit + MYSQL_PASSWORD= + MYSQL_HOST=localhost + MYSQL_PORT=3306 + eval $(php -r "require '$APPDIR/src/itnovum/openITCOCKPIT/Database/MysqlConfigFileParserForCli.php'; \$mcp = new MysqlConfigFileParserForCli(); \$r = \$mcp->parse_mysql_cnf('/opt/openitc/etc/mysql/mysql.cnf'); echo \$r['shell'];") + + echo "dbc_dbuser='${MYSQL_USER}'" >$BASHCONF + echo "dbc_dbpass='${MYSQL_PASSWORD}'" >>$BASHCONF + echo "dbc_dbserver='${MYSQL_HOST}'" >>$BASHCONF + echo "dbc_dbport='${MYSQL_PORT}'" >>$BASHCONF + echo "dbc_dbname='${MYSQL_DATABASE}'" >>$BASHCONF +fi + +. /opt/openitc/etc/mysql/bash.conf + + +echo "Create mysqldump of your current database" +BACKUP_TIMESTAMP=$(date '+%Y-%m-%d_%H-%M-%S') +BACKUP_DIR='/opt/openitc/nagios/backup' +mkdir -p $BACKUP_DIR +#If you have mysql binlog enabled uses this command: +#mysqldump --defaults-extra-file=${DUMPINIFILE} --databases $dbc_dbname --flush-privileges --single-transaction --master-data=1 --flush-logs --triggers --routines --events --hex-blob \ + +# ITC-2921 +# MySQL Bug: https://bugs.mysql.com/bug.php?id=109685 +# As with mysqldump 8.0.32 --single-transaction requires RELOAD or FLUSH_TABLES privilege(s) which the openitcockpit user does not have +# So for now the workaround is to remove "--single-transaction" +mysqldump --defaults-extra-file=${DUMPINIFILE} --databases $dbc_dbname --flush-privileges --triggers --routines --no-tablespaces --events --hex-blob \ + --ignore-table=$dbc_dbname.nagios_acknowledgements \ + --ignore-table=$dbc_dbname.nagios_commands \ + --ignore-table=$dbc_dbname.nagios_commenthistory \ + --ignore-table=$dbc_dbname.nagios_comments \ + --ignore-table=$dbc_dbname.nagios_configfiles \ + --ignore-table=$dbc_dbname.nagios_configfilevariables \ + --ignore-table=$dbc_dbname.nagios_conninfo \ + --ignore-table=$dbc_dbname.nagios_contact_addresses \ + --ignore-table=$dbc_dbname.nagios_contact_notificationcommands \ + --ignore-table=$dbc_dbname.nagios_contactgroup_members \ + --ignore-table=$dbc_dbname.nagios_contactgroups \ + --ignore-table=$dbc_dbname.nagios_contactnotificationmethods \ + --ignore-table=$dbc_dbname.nagios_contactnotifications \ + --ignore-table=$dbc_dbname.nagios_contacts \ + --ignore-table=$dbc_dbname.nagios_contactstatus \ + --ignore-table=$dbc_dbname.nagios_customvariables \ + --ignore-table=$dbc_dbname.nagios_customvariablestatus \ + --ignore-table=$dbc_dbname.nagios_dbversion \ + --ignore-table=$dbc_dbname.nagios_downtimehistory \ + --ignore-table=$dbc_dbname.nagios_eventhandlers \ + --ignore-table=$dbc_dbname.nagios_externalcommands \ + --ignore-table=$dbc_dbname.nagios_flappinghistory \ + --ignore-table=$dbc_dbname.nagios_host_contactgroups \ + --ignore-table=$dbc_dbname.nagios_host_contacts \ + --ignore-table=$dbc_dbname.nagios_host_parenthosts \ + --ignore-table=$dbc_dbname.nagios_hostchecks \ + --ignore-table=$dbc_dbname.nagios_hostdependencies \ + --ignore-table=$dbc_dbname.nagios_hostescalation_contactgroups \ + --ignore-table=$dbc_dbname.nagios_hostescalation_contacts \ + --ignore-table=$dbc_dbname.nagios_hostescalations \ + --ignore-table=$dbc_dbname.nagios_hostgroup_members \ + --ignore-table=$dbc_dbname.nagios_hostgroups \ + --ignore-table=$dbc_dbname.nagios_hosts \ + --ignore-table=$dbc_dbname.nagios_hoststatus \ + --ignore-table=$dbc_dbname.nagios_instances \ + --ignore-table=$dbc_dbname.nagios_logentries \ + --ignore-table=$dbc_dbname.nagios_notifications \ + --ignore-table=$dbc_dbname.nagios_processevents \ + --ignore-table=$dbc_dbname.nagios_programstatus \ + --ignore-table=$dbc_dbname.nagios_runtimevariables \ + --ignore-table=$dbc_dbname.nagios_scheduleddowntime \ + --ignore-table=$dbc_dbname.nagios_service_contactgroups \ + --ignore-table=$dbc_dbname.nagios_service_contacts \ + --ignore-table=$dbc_dbname.nagios_service_parentservices \ + --ignore-table=$dbc_dbname.nagios_servicechecks \ + --ignore-table=$dbc_dbname.nagios_servicedependencies \ + --ignore-table=$dbc_dbname.nagios_serviceescalation_contactgroups \ + --ignore-table=$dbc_dbname.nagios_serviceescalation_contacts \ + --ignore-table=$dbc_dbname.nagios_serviceescalations \ + --ignore-table=$dbc_dbname.nagios_servicegroup_members \ + --ignore-table=$dbc_dbname.nagios_servicegroups \ + --ignore-table=$dbc_dbname.nagios_services \ + --ignore-table=$dbc_dbname.nagios_servicestatus \ + --ignore-table=$dbc_dbname.nagios_statehistory \ + --ignore-table=$dbc_dbname.nagios_systemcommands \ + --ignore-table=$dbc_dbname.nagios_timedeventqueue \ + --ignore-table=$dbc_dbname.nagios_timedevents \ + --ignore-table=$dbc_dbname.nagios_timeperiod_timeranges \ + --ignore-table=$dbc_dbname.nagios_timeperiods \ + --ignore-table=$dbc_dbname.statusengine_dbversion \ + --ignore-table=$dbc_dbname.statusengine_host_acknowledgements \ + --ignore-table=$dbc_dbname.statusengine_host_downtimehistory \ + --ignore-table=$dbc_dbname.statusengine_host_notifications \ + --ignore-table=$dbc_dbname.statusengine_host_scheduleddowntimes \ + --ignore-table=$dbc_dbname.statusengine_host_statehistory \ + --ignore-table=$dbc_dbname.statusengine_hostchecks \ + --ignore-table=$dbc_dbname.statusengine_hoststatus \ + --ignore-table=$dbc_dbname.statusengine_logentries \ + --ignore-table=$dbc_dbname.statusengine_nodes \ + --ignore-table=$dbc_dbname.statusengine_perfdata \ + --ignore-table=$dbc_dbname.statusengine_service_acknowledgements \ + --ignore-table=$dbc_dbname.statusengine_service_downtimehistory \ + --ignore-table=$dbc_dbname.statusengine_service_notifications \ + --ignore-table=$dbc_dbname.statusengine_service_scheduleddowntimes \ + --ignore-table=$dbc_dbname.statusengine_service_statehistory \ + --ignore-table=$dbc_dbname.statusengine_servicechecks \ + --ignore-table=$dbc_dbname.statusengine_servicestatus \ + --ignore-table=$dbc_dbname.statusengine_tasks \ + --ignore-table=$dbc_dbname.statusengine_users \ + --ignore-table=$dbc_dbname.customalerts \ + --ignore-table=$dbc_dbname.customalert_statehistory \ + --ignore-table=$dbc_dbname.sla_availability_status_hosts_log \ + --ignore-table=$dbc_dbname.sla_availability_status_services_log \ + --ignore-table=$dbc_dbname.sla_host_outages \ + --ignore-table=$dbc_dbname.sla_service_outages \ + >$BACKUP_DIR/openitcockpit_dump_$BACKUP_TIMESTAMP.sql + +echo "---------------------------------------------------------------" +echo "Convert MySQL Tables from utf8_general_ci to utf8mb4_general_ci..." + +# Disabled - this takes ages! +#mysql --defaults-extra-file=${INIFILE} -e "ALTER DATABASE ${dbc_dbname} CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" + +mysql --defaults-extra-file=${INIFILE} --batch --skip-column-names -e "SELECT TABLE_NAME FROM \`information_schema\`.\`TABLES\` WHERE \`TABLE_SCHEMA\`='${dbc_dbname}' AND \`TABLE_NAME\` NOT LIKE 'nagios_%' AND \`TABLE_COLLATION\`='utf8_general_ci'" | while read TABLE_NAME; do + echo "ALTER TABLE \`${TABLE_NAME}\` CONVERT TO CHARACTER SET utf8mb4; ✔" + mysql --defaults-extra-file=${INIFILE} -e "ALTER TABLE \`${TABLE_NAME}\` CONVERT TO CHARACTER SET utf8mb4;" +done + +echo "Running openITCOCKPIT Core database migration" +oitc migrations migrate + +oitc migrations seed + +echo "Running openITCOCKPIT Module database migration/s" +for PLUGIN in $(ls -1 "${APPDIR}/plugins"); do + if [[ "$PLUGIN" == *Module ]]; then + if [[ -d "${APPDIR}/plugins/${PLUGIN}/config/Migrations" ]]; then + echo "Running openITCOCKPIT ${PLUGIN} database migration" + oitc migrations migrate -p "${PLUGIN}" + fi + + if [[ -d "${APPDIR}/plugins/${PLUGIN}/config/Seeds" ]]; then + num_files=$(find "${APPDIR}/plugins/${PLUGIN}/config/Seeds" -mindepth 1 -iname "*.php" -type f | wc -l) + if [[ "$num_files" -gt 0 ]]; then + echo "Importing default records for ${PLUGIN} into database" + oitc migrations seed -p "${PLUGIN}" + fi + fi + + fi +done + +echo "---------------------------------------------------------------" +echo "Import extended openitcockpit-update module scripts ..." + +MODULE_SCRIPS_LOCK_DIR="/opt/openitc/var/updatesh_module_locks/" +MODULES_DIR="${APPDIR}/plugins/" +DEDICATED_MODULE_SCRIPTS_DIR_NAME="updateScripts" +LOADED_MODULE_SCRIPTS=() + +# include module scripts class header +echo "Import ${APPDIR}/bin/updatesh_module_scripts/system.h.sh" +. ${APPDIR}/bin/updatesh_module_scripts/system.h.sh ${APPDIR}/bin/updatesh_module_scripts/ +moduleList=($(ls -A1 $MODULES_DIR*/$DEDICATED_MODULE_SCRIPTS_DIR_NAME/*)) +for entry in "${moduleList[@]}" +do + if [[ $entry =~ \.h.sh$ ]]; then + echo "Import $entry" + shortName=`basename $entry` + realName=${shortName/".h.sh"/""} + path=${entry/$shortName/""} + LOADED_MODULE_SCRIPTS+=($realName) + . $entry $path + fi +done + +if type "system.property" &> /dev/null; then + system.property lockDir = $MODULE_SCRIPS_LOCK_DIR + system.property modulesDir = $MODULES_DIR + system.initialize +fi + +for Module in "${LOADED_MODULE_SCRIPTS[@]}"; do + if [ "$Module" != "system" ]; then + if type "${Module}" &> /dev/null; then + # create class object + ${Module} module + + # set required variables + module.property name = "${Module}" + module.property dbIniFile = "${Module}" + + module.initialize + fi + fi +done + +echo "---------------------------------------------------------------" +echo "Convert MySQL Tables from utf8_general_ci to utf8mb4_general_ci..." + +# Disabled - this takes ages! +#mysql --defaults-extra-file=${INIFILE} -e "ALTER DATABASE ${dbc_dbname} CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" + +mysql --defaults-extra-file=${INIFILE} --batch --skip-column-names -e "SELECT TABLE_NAME FROM \`information_schema\`.\`TABLES\` WHERE \`TABLE_SCHEMA\`='${dbc_dbname}' AND \`TABLE_NAME\` NOT LIKE 'nagios_%' AND \`TABLE_COLLATION\`='utf8_general_ci'" | while read TABLE_NAME; do + echo "ALTER TABLE \`${TABLE_NAME}\` CONVERT TO CHARACTER SET utf8mb4; ✔" + mysql --defaults-extra-file=${INIFILE} -e "ALTER TABLE \`${TABLE_NAME}\` CONVERT TO CHARACTER SET utf8mb4;" +done + +#Compress and minify javascript files +oitc compress + +#Acc ALC dependencies config for itc core +echo "---------------------------------------------------------------" +echo "Scan for new user permissions. This will take a while..." +oitc Acl.acl_extras aco_sync + +#Set default permissions, check for always allowed permissions and dependencies +oitc roles --enable-defaults --admin + +echo "Checking that a server certificate for the openITCOCKPIT Monitoring Agent exists" +oitc agent --generate-server-ca + +# ITC-1911 +echo "Cleanup for invalid parent hosts on satellite instance" +oitc ParentHostsVisibilityCleaning + +for i in "$@"; do + case $i in + --cc) + echo "Clear out Model Cache /opt/openitc/frontend/tmp/cache/models/" + rm -rf /opt/openitc/frontend/tmp/cache/models/* + echo "Clear out CLI Model Cache /opt/openitc/frontend/tmp/cli/cache/cli/models/" + rm -rf /opt/openitc/frontend/tmp/cli/cache/cli/models/* + echo "Clear out Nagios Model Cache /opt/openitc/frontend/tmp/nagios/cache/nagios/models/" + rm -rf /opt/openitc/frontend/tmp/nagios/cache/nagios/models/* + ;; + + --rights) + oitc rights + ;; + + *) + #No default at the moment + ;; + esac +done + +echo "Flush redis cache" +redis-cli -h $OITC_REDIS_HOST -p $OITC_REDIS_PORT FLUSHALL +echo "" + +echo "Copy required system files" +rsync -K -a ${APPDIR}/system/etc/. /etc/ +chown root:root /etc +cp -r ${APPDIR}/system/usr/. /usr/ +cp ${APPDIR}/system/nginx/ssl_options_$OSVERSION /etc/nginx/openitc/ssl_options.conf +# only ensure that the files exist +touch /etc/nginx/openitc/ssl_cert.conf +touch /etc/nginx/openitc/custom.conf + + +chmod +x /usr/bin/oitc + +echo "Create required system folders" +mkdir -p /opt/openitc/etc/{mysql,grafana,carbon,frontend,nagios,nsta} +mkdir -p /opt/openitc/nagios/etc/config +mkdir -p /opt/openitc/etc/nagios/nagios.cfg.d + +chown www-data:www-data /opt/openitc/logs/frontend +chown nagios:www-data /opt/openitc/nagios/etc/config +chown nagios:www-data /opt/openitc/etc/nagios/nagios.cfg.d +chmod 775 /opt/openitc/logs/frontend + +chown www-data:www-data /opt/openitc/frontend/tmp + +mkdir -p /opt/openitc/frontend/webroot/img/charts +chown www-data:www-data /opt/openitc/frontend/webroot/img/charts + +if [[ -d /opt/openitc/frontend/plugins/MapModule/webroot/img/ ]]; then + chown -R www-data:www-data /opt/openitc/frontend/plugins/MapModule/webroot/img/ +fi + +if getent group ssl-cert &>/dev/null; then + if [ -z "$(groups nagios | grep ssl-cert)" ]; then + usermod -aG ssl-cert nagios + fi +fi + +oitc config_generator_shell --generate +oitc nagios_export --resource + +if [[ -d "/opt/openitc/nagios/rollout" ]]; then + if [[ ! -f "/opt/openitc/nagios/rollout/resource.cfg" ]]; then + ln -s /opt/openitc/nagios/etc/resource.cfg /opt/openitc/nagios/rollout/resource.cfg + fi +fi + +echo $OITC_GRAFANA_ADMIN_PASSWORD > /opt/openitc/etc/grafana/admin_password + +if [ -f /opt/openitc/etc/grafana/api_key ]; then + echo "Check if Grafana is reachable" + COUNTER=0 + + set +e + while [ "$COUNTER" -lt 30 ]; do + echo "Try to connect to Grafana API..." + #Is Grafana Server Online? + STATUSCODE=$(curl --noproxy "$OITC_GRAFANA_HOSTNAME" "$OITC_GRAFANA_URL/api/admin/stats" -XGET -uadmin:$OITC_GRAFANA_ADMIN_PASSWORD -H 'Content-Type: application/json' -I 2>/dev/null | head -n 1 | cut -d$' ' -f2) + + if [ "$STATUSCODE" == "200" ]; then + echo "Check if Prometheus/VictoriaMetrics Datasource exists in Grafana" + DS_STATUSCODE=$(curl --noproxy "$OITC_GRAFANA_HOSTNAME" "$OITC_GRAFANA_URL/api/datasources/name/Prometheus" -XGET -uadmin:$OITC_GRAFANA_ADMIN_PASSWORD -H 'Content-Type: application/json' -I 2>/dev/null | head -n 1 | cut -d$' ' -f2) + + if [ "$DS_STATUSCODE" == "404" ]; then + echo "Create Prometheus/VictoriaMetrics Datasource for Grafana" + RESPONSE=$(curl --noproxy "$OITC_GRAFANA_HOSTNAME" "$OITC_GRAFANA_URL/api/datasources" -XPOST -uadmin:$OITC_GRAFANA_ADMIN_PASSWORD -H 'Content-Type: application/json' -d '{ + "name":"Prometheus", + "type":"prometheus", + "url":"http://victoriametrics:8428", + "access":"proxy", + "basicAuth":false, + "isDefault": false, + "jsonData": {} + }') + echo $RESPONSE | jq . + fi + echo "Ok: Prometheus/VictoriaMetrics datasource exists." + COUNTER=9999 # break while loop bc bash where break does not brake + break + fi + COUNTER=$((COUNTER + 1)) + sleep 1 + done + + if [ ! -f /opt/openitc/etc/grafana/api_key ]; then + echo "ERROR!" + echo "Could not connect to Grafana" + fi + set -e +fi + +oitc supervisor restart sudo_server +oitc supervisor restart oitc_cmd +oitc supervisor restart gearman_worker +oitc supervisor restart push_notification + +echo "Restart monitoring engine" +oitc supervisor restart naemon + +# Restart services if they are running +#for srv in openitcockpit-graphing.service nginx.service nsta.service event-collectd.service; do +# if systemctl is-active --quiet $srv; then +# echo "Restart service: $srv" +# systemctl restart $srv +# fi +#done + +oitc supervisor restart nginx +oitc supervisor restart php-fpm + +set +e +systemctl is-enabled --quiet php${PHPVersion}-fpm.service &>/dev/null + +for Module in "${LOADED_MODULE_SCRIPTS[@]}"; do + if [ "$Module" != "system" ]; then + if type "${Module}" &> /dev/null; then + # create class object + ${Module} module + + # set required variables + module.property name = "${Module}" + module.property dbIniFile = "${Module}" + + module.finish + fi + fi +done + +# Set filesystem permissions after all is done - again +chown www-data:www-data /opt/openitc/logs/frontend +oitc rights +chown nagios:nagios /opt/openitc/logs/frontend/nagios +chown www-data:www-data /opt/openitc/frontend/ +chmod 775 /opt/openitc/logs/frontend +chmod 775 /opt/openitc/logs/frontend/nagios +chown www-data:www-data /opt/openitc/frontend/tmp +chown nagios:nagios -R /opt/openitc/frontend/tmp/nagios + From 1e52689816959ef9fabdbcea7c00d834aaa73ec5 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 17 May 2023 16:00:23 +0200 Subject: [PATCH 36/54] ITC-2986 Add update.sh --- CONTAINER_UPDATE.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/CONTAINER_UPDATE.sh b/CONTAINER_UPDATE.sh index 996166036c..68f5e1174d 100644 --- a/CONTAINER_UPDATE.sh +++ b/CONTAINER_UPDATE.sh @@ -358,11 +358,6 @@ if [ -f /opt/openitc/etc/grafana/api_key ]; then set -e fi -oitc supervisor restart sudo_server -oitc supervisor restart oitc_cmd -oitc supervisor restart gearman_worker -oitc supervisor restart push_notification - echo "Restart monitoring engine" oitc supervisor restart naemon @@ -374,9 +369,6 @@ oitc supervisor restart naemon # fi #done -oitc supervisor restart nginx -oitc supervisor restart php-fpm - set +e systemctl is-enabled --quiet php${PHPVersion}-fpm.service &>/dev/null From 9bff7c3cb463ec44a54621a9049b4b9cd140891e Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 17 May 2023 16:12:14 +0200 Subject: [PATCH 37/54] ITC-2986 Add update.sh --- CONTAINER_SETUP.sh | 2 -- CONTAINER_UPDATE.sh | 5 ++++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CONTAINER_SETUP.sh b/CONTAINER_SETUP.sh index 4ee2cf4ac3..c43bc26e6b 100644 --- a/CONTAINER_SETUP.sh +++ b/CONTAINER_SETUP.sh @@ -17,8 +17,6 @@ INIFILE=/opt/openitc/etc/mysql/mysql.cnf DUMPINIFILE=/opt/openitc/etc/mysql/dump.cnf BASHCONF=/opt/openitc/etc/mysql/bash.conf -PHPVersion=$(php -r "echo substr(PHP_VERSION, 0, 3);") - OSVERSION=$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2) OS_BASE="debian" diff --git a/CONTAINER_UPDATE.sh b/CONTAINER_UPDATE.sh index 68f5e1174d..e35f7d217d 100644 --- a/CONTAINER_UPDATE.sh +++ b/CONTAINER_UPDATE.sh @@ -17,6 +17,9 @@ INIFILE=/opt/openitc/etc/mysql/mysql.cnf DUMPINIFILE=/opt/openitc/etc/mysql/dump.cnf BASHCONF=/opt/openitc/etc/mysql/bash.conf +OSVERSION=$(grep VERSION_CODENAME /etc/os-release | cut -d= -f2) +OS_BASE="debian" + if [[ ! -f "$BASHCONF" ]]; then MYSQL_USER=openitcockpit MYSQL_DATABASE=openitcockpit @@ -305,7 +308,7 @@ if getent group ssl-cert &>/dev/null; then fi fi -oitc config_generator_shell --generate +oitc config_generator_shell --generate-container oitc nagios_export --resource if [[ -d "/opt/openitc/nagios/rollout" ]]; then From b48b6d7f52c6c1403adf29219c9c0cfc1920a472 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 17 May 2023 16:24:25 +0200 Subject: [PATCH 38/54] ITC-2986 Add update.sh --- CONTAINER_UPDATE.sh | 3 --- .../updateScripts/NagiosModule.class.sh | 18 +++++++++++++----- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/CONTAINER_UPDATE.sh b/CONTAINER_UPDATE.sh index e35f7d217d..f6ff87bb31 100644 --- a/CONTAINER_UPDATE.sh +++ b/CONTAINER_UPDATE.sh @@ -253,8 +253,6 @@ for i in "$@"; do rm -rf /opt/openitc/frontend/tmp/cache/models/* echo "Clear out CLI Model Cache /opt/openitc/frontend/tmp/cli/cache/cli/models/" rm -rf /opt/openitc/frontend/tmp/cli/cache/cli/models/* - echo "Clear out Nagios Model Cache /opt/openitc/frontend/tmp/nagios/cache/nagios/models/" - rm -rf /opt/openitc/frontend/tmp/nagios/cache/nagios/models/* ;; --rights) @@ -398,5 +396,4 @@ chown www-data:www-data /opt/openitc/frontend/ chmod 775 /opt/openitc/logs/frontend chmod 775 /opt/openitc/logs/frontend/nagios chown www-data:www-data /opt/openitc/frontend/tmp -chown nagios:nagios -R /opt/openitc/frontend/tmp/nagios diff --git a/plugins/NagiosModule/updateScripts/NagiosModule.class.sh b/plugins/NagiosModule/updateScripts/NagiosModule.class.sh index 7c5678a4ad..63bf21d58f 100644 --- a/plugins/NagiosModule/updateScripts/NagiosModule.class.sh +++ b/plugins/NagiosModule/updateScripts/NagiosModule.class.sh @@ -32,9 +32,15 @@ NagiosModule.initialize() { NagiosModule.installIfNeeded() { echo "Run $(NagiosModule.property name) update" - chown nagios:www-data -R /opt/openitc/nagios/etc - chown nagios:www-data -R /opt/openitc/nagios/var - chown nagios:www-data -R /opt/openitc/nagios/share + if [ -d "/opt/openitc/nagios/etc" ]; then + chown nagios:www-data -R /opt/openitc/nagios/etc + fi + if [ -d "/opt/openitc/nagios/var" ]; then + chown nagios:www-data -R /opt/openitc/nagios/var + fi + if [ -d "/opt/openitc/nagios/share" ]; then + chown nagios:www-data -R /opt/openitc/nagios/share + fi system.lock $(NagiosModule.property name) "installed" $(NagiosModule.property disableFileLock) if [ $(NagiosModule.property disableFileLock) == 1 ]; then @@ -56,8 +62,10 @@ NagiosModule.installIfNeeded() { NagiosModule.install() { if [ -f "/opt/openitc/etc/nagios/nagios.cfg" ]; then - echo "Start service: nagios.service" - systemctl start nagios.service + if [ ! -z IS_CONTAINER ]; then + echo "Start service: nagios.service" + systemctl start nagios.service + fi fi } From 24be454cfd9133dae64172033849a9b3f4c64604 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 17 May 2023 16:27:27 +0200 Subject: [PATCH 39/54] ITC-2986 Add update.sh --- CONTAINER_UPDATE.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CONTAINER_UPDATE.sh b/CONTAINER_UPDATE.sh index f6ff87bb31..41b11d86d8 100644 --- a/CONTAINER_UPDATE.sh +++ b/CONTAINER_UPDATE.sh @@ -37,6 +37,13 @@ fi . /opt/openitc/etc/mysql/bash.conf +echo "Copy required system files" +rsync -K -a ${APPDIR}/system/etc/. /etc/ # we use rsync because the destination can be a symlink on RHEL +chown root:root /etc +cp -r ${APPDIR}/system/usr/. /usr/ +cp ${APPDIR}/system/nginx/ssl_options_$OSVERSION /etc/nginx/openitc/ssl_options.conf +cp ${APPDIR}/system/nginx/ssl_cert.conf /etc/nginx/openitc/ssl_cert.conf +chmod +x /usr/bin/oitc echo "Create mysqldump of your current database" BACKUP_TIMESTAMP=$(date '+%Y-%m-%d_%H-%M-%S') From 89a0035cc9f723f5c2b8fb3edbc0a95256f7b4da Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 17 May 2023 16:35:48 +0200 Subject: [PATCH 40/54] ITC-2986 Add update.sh --- CONTAINER_UPDATE.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/CONTAINER_UPDATE.sh b/CONTAINER_UPDATE.sh index 41b11d86d8..6bcfc23c6f 100644 --- a/CONTAINER_UPDATE.sh +++ b/CONTAINER_UPDATE.sh @@ -369,16 +369,7 @@ fi echo "Restart monitoring engine" oitc supervisor restart naemon -# Restart services if they are running -#for srv in openitcockpit-graphing.service nginx.service nsta.service event-collectd.service; do -# if systemctl is-active --quiet $srv; then -# echo "Restart service: $srv" -# systemctl restart $srv -# fi -#done - set +e -systemctl is-enabled --quiet php${PHPVersion}-fpm.service &>/dev/null for Module in "${LOADED_MODULE_SCRIPTS[@]}"; do if [ "$Module" != "system" ]; then From 17ae4a9fb7b2629bcc9a8971dfd64939a8c2a0f1 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 17 May 2023 16:40:21 +0200 Subject: [PATCH 41/54] ITC-2986 Add update.sh --- .../updateScripts/Statusengine3Module.class.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/Statusengine3Module/updateScripts/Statusengine3Module.class.sh b/plugins/Statusengine3Module/updateScripts/Statusengine3Module.class.sh index 14d5e0aa49..051accbbe7 100644 --- a/plugins/Statusengine3Module/updateScripts/Statusengine3Module.class.sh +++ b/plugins/Statusengine3Module/updateScripts/Statusengine3Module.class.sh @@ -63,9 +63,11 @@ Statusengine3Module.uninstall(){ Statusengine3Module.finish(){ if [ $(system.moduleSrcDirExists $(Statusengine3Module.property name)) == 1 ]; then - if systemctl is-active --quiet statusengine.service; then - echo "Restart service: statusengine.service" - systemctl restart statusengine.service + if [ ! -z IS_CONTAINER ]; then + if systemctl is-active --quiet statusengine.service; then + echo "Restart service: statusengine.service" + systemctl restart statusengine.service + fi fi fi } From 908a9367e73db2bd7bc1f60c24f52083fd9541d1 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 17 May 2023 16:57:19 +0200 Subject: [PATCH 42/54] ITC-2986 Add update.sh --- .../updateScripts/NagiosModule.class.sh | 10 ++++------ .../updateScripts/Statusengine3Module.class.sh | 14 ++++++-------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/plugins/NagiosModule/updateScripts/NagiosModule.class.sh b/plugins/NagiosModule/updateScripts/NagiosModule.class.sh index 63bf21d58f..4607d4cf55 100644 --- a/plugins/NagiosModule/updateScripts/NagiosModule.class.sh +++ b/plugins/NagiosModule/updateScripts/NagiosModule.class.sh @@ -61,12 +61,10 @@ NagiosModule.installIfNeeded() { } NagiosModule.install() { - if [ -f "/opt/openitc/etc/nagios/nagios.cfg" ]; then - if [ ! -z IS_CONTAINER ]; then - echo "Start service: nagios.service" - systemctl start nagios.service - fi - fi + #if [ -f "/opt/openitc/etc/nagios/nagios.cfg" ]; then + # echo "Start service: nagios.service" + # systemctl start nagios.service + #fi } NagiosModule.uninstall() { diff --git a/plugins/Statusengine3Module/updateScripts/Statusengine3Module.class.sh b/plugins/Statusengine3Module/updateScripts/Statusengine3Module.class.sh index 051accbbe7..151b164783 100644 --- a/plugins/Statusengine3Module/updateScripts/Statusengine3Module.class.sh +++ b/plugins/Statusengine3Module/updateScripts/Statusengine3Module.class.sh @@ -62,12 +62,10 @@ Statusengine3Module.uninstall(){ } Statusengine3Module.finish(){ - if [ $(system.moduleSrcDirExists $(Statusengine3Module.property name)) == 1 ]; then - if [ ! -z IS_CONTAINER ]; then - if systemctl is-active --quiet statusengine.service; then - echo "Restart service: statusengine.service" - systemctl restart statusengine.service - fi - fi - fi + #if [ $(system.moduleSrcDirExists $(Statusengine3Module.property name)) == 1 ]; then + # if systemctl is-active --quiet statusengine.service; then + # echo "Restart service: statusengine.service" + # systemctl restart statusengine.service + # fi + #fi } From 057e17b6f05926b27cfa29dcbbb96717267b270d Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 17 May 2023 17:05:35 +0200 Subject: [PATCH 43/54] ITC-2986 Add update.sh --- plugins/NagiosModule/updateScripts/NagiosModule.class.sh | 1 + .../updateScripts/Statusengine3Module.class.sh | 1 + 2 files changed, 2 insertions(+) diff --git a/plugins/NagiosModule/updateScripts/NagiosModule.class.sh b/plugins/NagiosModule/updateScripts/NagiosModule.class.sh index 4607d4cf55..0a3756777a 100644 --- a/plugins/NagiosModule/updateScripts/NagiosModule.class.sh +++ b/plugins/NagiosModule/updateScripts/NagiosModule.class.sh @@ -61,6 +61,7 @@ NagiosModule.installIfNeeded() { } NagiosModule.install() { + echo "NagiosModule.install" #if [ -f "/opt/openitc/etc/nagios/nagios.cfg" ]; then # echo "Start service: nagios.service" # systemctl start nagios.service diff --git a/plugins/Statusengine3Module/updateScripts/Statusengine3Module.class.sh b/plugins/Statusengine3Module/updateScripts/Statusengine3Module.class.sh index 151b164783..9ee0c7d6f4 100644 --- a/plugins/Statusengine3Module/updateScripts/Statusengine3Module.class.sh +++ b/plugins/Statusengine3Module/updateScripts/Statusengine3Module.class.sh @@ -62,6 +62,7 @@ Statusengine3Module.uninstall(){ } Statusengine3Module.finish(){ + echo "Statusengine3Module.finish" #if [ $(system.moduleSrcDirExists $(Statusengine3Module.property name)) == 1 ]; then # if systemctl is-active --quiet statusengine.service; then # echo "Restart service: statusengine.service" From 74fd8b37dbb039d70573280ed6ea172ad2b6c843 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 17 May 2023 17:16:00 +0200 Subject: [PATCH 44/54] ITC-2986 Add update.sh --- CONTAINER_UPDATE.sh | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/CONTAINER_UPDATE.sh b/CONTAINER_UPDATE.sh index 6bcfc23c6f..d6d69489ca 100644 --- a/CONTAINER_UPDATE.sh +++ b/CONTAINER_UPDATE.sh @@ -371,20 +371,21 @@ oitc supervisor restart naemon set +e -for Module in "${LOADED_MODULE_SCRIPTS[@]}"; do - if [ "$Module" != "system" ]; then - if type "${Module}" &> /dev/null; then - # create class object - ${Module} module - - # set required variables - module.property name = "${Module}" - module.property dbIniFile = "${Module}" - - module.finish - fi - fi -done +# todo fix this +#for Module in "${LOADED_MODULE_SCRIPTS[@]}"; do +# if [ "$Module" != "system" ]; then +# if type "${Module}" &> /dev/null; then +# # create class object +# ${Module} module +# +# # set required variables +# module.property name = "${Module}" +# module.property dbIniFile = "${Module}" +# +# module.finish +# fi +# fi +#done # Set filesystem permissions after all is done - again chown www-data:www-data /opt/openitc/logs/frontend From eda219441a3226f11edc6e32ca82ad393db2783c Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 17 May 2023 17:37:09 +0200 Subject: [PATCH 45/54] ITC-2986 Add update.sh --- CONTAINER_UPDATE.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/CONTAINER_UPDATE.sh b/CONTAINER_UPDATE.sh index d6d69489ca..d9335037f2 100644 --- a/CONTAINER_UPDATE.sh +++ b/CONTAINER_UPDATE.sh @@ -388,11 +388,12 @@ set +e #done # Set filesystem permissions after all is done - again -chown www-data:www-data /opt/openitc/logs/frontend -oitc rights -chown nagios:nagios /opt/openitc/logs/frontend/nagios -chown www-data:www-data /opt/openitc/frontend/ -chmod 775 /opt/openitc/logs/frontend -chmod 775 /opt/openitc/logs/frontend/nagios -chown www-data:www-data /opt/openitc/frontend/tmp +#todo fix if realy required +#chown www-data:www-data /opt/openitc/logs/frontend +#oitc rights +#chown nagios:nagios /opt/openitc/logs/frontend/nagios +#chown www-data:www-data /opt/openitc/frontend/ +#chmod 775 /opt/openitc/logs/frontend +#chmod 775 /opt/openitc/logs/frontend/nagios +#chown www-data:www-data /opt/openitc/frontend/tmp From 32a0a7fc303b141c7c7bac731186327a3fa03332 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 17 May 2023 17:48:50 +0200 Subject: [PATCH 46/54] ITC-2986 Add update.sh --- CONTAINER_UPDATE.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTAINER_UPDATE.sh b/CONTAINER_UPDATE.sh index d9335037f2..80ce7a41d4 100644 --- a/CONTAINER_UPDATE.sh +++ b/CONTAINER_UPDATE.sh @@ -369,6 +369,10 @@ fi echo "Restart monitoring engine" oitc supervisor restart naemon +echo "Enabling webserver configuration" +ln -s /etc/nginx/sites-available/openitc /etc/nginx/sites-enabled/openitc +rm -f /etc/nginx/sites-enabled/default + set +e # todo fix this From 629c0e7f92262b4d0b354b9ecb06f691e638ed3a Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 17 May 2023 19:11:03 +0200 Subject: [PATCH 47/54] ITC-2986 Fix nginx config --- CONTAINER_SETUP.sh | 4 +++- CONTAINER_UPDATE.sh | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CONTAINER_SETUP.sh b/CONTAINER_SETUP.sh index c43bc26e6b..6e255f54bd 100644 --- a/CONTAINER_SETUP.sh +++ b/CONTAINER_SETUP.sh @@ -217,7 +217,9 @@ if [[ -d "/opt/openitc/nagios/rollout" ]]; then fi echo "Enabling webserver configuration" -ln -s /etc/nginx/sites-available/openitc /etc/nginx/sites-enabled/openitc +if [[ ! -f "/etc/nginx/sites-enabled/openitc" ]]; then + ln -s /etc/nginx/sites-available/openitc /etc/nginx/sites-enabled/openitc +fi rm -f /etc/nginx/sites-enabled/default #Set default permissions, check for always allowed permissions and dependencies diff --git a/CONTAINER_UPDATE.sh b/CONTAINER_UPDATE.sh index 80ce7a41d4..c3c5be68fc 100644 --- a/CONTAINER_UPDATE.sh +++ b/CONTAINER_UPDATE.sh @@ -370,7 +370,9 @@ echo "Restart monitoring engine" oitc supervisor restart naemon echo "Enabling webserver configuration" -ln -s /etc/nginx/sites-available/openitc /etc/nginx/sites-enabled/openitc +if [[ ! -f "/etc/nginx/sites-enabled/openitc" ]]; then + ln -s /etc/nginx/sites-available/openitc /etc/nginx/sites-enabled/openitc +fi rm -f /etc/nginx/sites-enabled/default set +e From 0ba5aaf0422f4e94ac669cc24c6c4f5f2c51f096 Mon Sep 17 00:00:00 2001 From: nook24 Date: Tue, 23 May 2023 08:37:22 +0200 Subject: [PATCH 48/54] ITC-2986 Add local path for logs, cache and tmp files when running inside a workhorse container like mod_gearman --- config/paths.php | 112 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 88 insertions(+), 24 deletions(-) diff --git a/config/paths.php b/config/paths.php index 25b428485c..62650c56a2 100644 --- a/config/paths.php +++ b/config/paths.php @@ -61,6 +61,10 @@ $isCli = PHP_SAPI === 'cli'; +// This var determins if openITCOCKPIT is running inside a workhorse container like mod_gearman +// It yes, we use different path for logfiles and caching to avoid permission issues +$isWorkhorseContainer = filter_var(env('IS_WORKHORSE_CONTAINER', false), FILTER_VALIDATE_BOOLEAN); + /* * Path to the tests directory. */ @@ -69,47 +73,107 @@ /* * Path to the temporary files directory. */ -if ($isCli === false) { - // www-data - define('TMP', ROOT . DS . 'tmp' . DS); +if ($isWorkhorseContainer === false) { + // Default installation of openITCOCKPIT via apt, dnf or git + // Also used if openITCOCKPIT is running inside a container like docker + if ($isCli === false) { + // www-data + define('TMP', ROOT . DS . 'tmp' . DS); + } else { + // root or nagios + if ($_SERVER['USER'] !== 'root') { + //nagios user or so + define('TMP', ROOT . DS . 'tmp' . DS . 'nagios' . DS); + } else { + //root user + define('TMP', ROOT . DS . 'tmp' . DS . 'cli' . DS); + } + } } else { - // root or nagios - if ($_SERVER['USER'] !== 'root') { - //nagios user or so - define('TMP', ROOT . DS . 'tmp' . DS . 'nagios' . DS); + // This openITCOCKPIT is running inside a workhorse container like mod_gearman + // The primary job of this container is only to provide the openITCOCKPIT CLI backend to be able + // to execute notification commands or the evc check plugin + if ($isCli === false) { + // www-data + define('TMP', DS . 'tmp' . DS . 'openitcockpit' . DS . 'tmp'); // /tmp/openitcockpit/tmp/ } else { - //root user - define('TMP', ROOT . DS . 'tmp' . DS . 'cli' . DS); + // root or nagios + if ($_SERVER['USER'] !== 'root') { + //nagios user or so + define('TMP', DS . 'tmp' . DS . 'openitcockpit' . DS . 'tmp' . DS . 'nagios' . DS); // /tmp/openitcockpit/tmp/nagios + } else { + //root user + define('TMP', DS . 'tmp' . DS . 'openitcockpit' . DS . 'tmp' . DS . 'cli' . DS); // /tmp/openitcockpit/tmp/cli + } } } + /* * Path to the logs directory. */ -if ($isCli === false) { - //www-data - define('LOGS', ROOT . DS . 'logs' . DS); +if ($isWorkhorseContainer === false) { + // Default installation of openITCOCKPIT via apt, dnf or git + // Also used if openITCOCKPIT is running inside a container like docker + if ($isCli === false) { + //www-data + define('LOGS', ROOT . DS . 'logs' . DS); + } else { + if ($_SERVER['USER'] !== 'root') { + define('LOGS', ROOT . DS . 'logs' . DS . 'nagios' . DS); + } else { + define('LOGS', ROOT . DS . 'logs' . DS); + } + } } else { - if ($_SERVER['USER'] !== 'root') { - define('LOGS', ROOT . DS . 'logs' . DS . 'nagios' . DS); + // This openITCOCKPIT is running inside a workhorse container like mod_gearman + // The primary job of this container is only to provide the openITCOCKPIT CLI backend to be able + // to execute notification commands or the evc check plugin + if ($isCli === false) { + //www-data + define('LOGS', DS . 'tmp' . DS . 'openitcockpit' . DS . 'logs' . DS); // /tmp/openitcockpit/logs/ } else { - define('LOGS', ROOT . DS . 'logs' . DS); + if ($_SERVER['USER'] !== 'root') { + define('LOGS', DS . 'tmp' . DS . 'openitcockpit' . DS . 'logs' . DS . 'nagios' . DS); // /tmp/openitcockpit/logs/nagios + } else { + define('LOGS', DS . 'tmp' . DS . 'openitcockpit' . DS . 'logs' . DS); // /tmp/openitcockpit/logs/ + } } } /* * Path to the cache files directory. It can be shared between hosts in a multi-server setup. */ -if ($isCli === false) { - //www-data - define('CACHE', TMP . 'cache' . DS); -} else { - if ($_SERVER['USER'] !== 'root') { - //nagios user or so - define('CACHE', TMP . 'cache' . DS . 'nagios' . DS); +if ($isWorkhorseContainer === false) { + // Default installation of openITCOCKPIT via apt, dnf or git + // Also used if openITCOCKPIT is running inside a container like docker + if ($isCli === false) { + //www-data + define('CACHE', TMP . 'cache' . DS); + } else { + if ($_SERVER['USER'] !== 'root') { + //nagios user or so + define('CACHE', TMP . 'cache' . DS . 'nagios' . DS); + } else { + //root user + define('CACHE', TMP . 'cache' . DS . 'cli' . DS); + } + } +}else{ + // This openITCOCKPIT is running inside a workhorse container like mod_gearman + // The primary job of this container is only to provide the openITCOCKPIT CLI backend to be able + // to execute notification commands or the evc check plugin + if ($isCli === false) { + //www-data + define('CACHE', DS . 'tmp' . DS . 'openitcockpit' . DS . 'cache' . DS); // /tmp/openitcockpit/cache/ } else { - //root user - define('CACHE', TMP . 'cache' . DS . 'cli' . DS); + if ($_SERVER['USER'] !== 'root') { + //nagios user or so + define('CACHE', DS . 'tmp' . DS . 'openitcockpit' . DS . 'cache' . DS . 'nagios' . DS); // /tmp/openitcockpit/cache/nagios/ + } else { + //root user + define('CACHE', DS . 'tmp' . DS . 'openitcockpit' . DS . 'cache' . DS . 'cli' . DS); // /tmp/openitcockpit/cache/cli/ + } } } From 7779d5b005a846557e1a1b6032c929cc327fa082 Mon Sep 17 00:00:00 2001 From: nook24 Date: Tue, 23 May 2023 20:39:07 +0200 Subject: [PATCH 49/54] ITC-2986 Make sure that is defined --- config/paths.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/paths.php b/config/paths.php index 62650c56a2..935b8ef17e 100644 --- a/config/paths.php +++ b/config/paths.php @@ -73,6 +73,12 @@ /* * Path to the temporary files directory. */ + +if(!isset($_SERVER['USER'])){ + // Must be inside a container or some other scatchy setup + $_SERVER['USER'] = 'root'; +} + if ($isWorkhorseContainer === false) { // Default installation of openITCOCKPIT via apt, dnf or git // Also used if openITCOCKPIT is running inside a container like docker From 6a0ddbc609c16975144659bf498c4dff3d5d62b5 Mon Sep 17 00:00:00 2001 From: nook24 Date: Tue, 23 May 2023 21:09:15 +0200 Subject: [PATCH 50/54] ITC-2986 Make sure that is defined --- config/paths.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/config/paths.php b/config/paths.php index 935b8ef17e..650412835d 100644 --- a/config/paths.php +++ b/config/paths.php @@ -74,9 +74,13 @@ * Path to the temporary files directory. */ -if(!isset($_SERVER['USER'])){ +if (!isset($_SERVER['USER'])) { // Must be inside a container or some other scatchy setup $_SERVER['USER'] = 'root'; + if (getmyuid() > 0) { + // Probably we are nagios? + $_SERVER['USER'] = 'nagios'; + } } if ($isWorkhorseContainer === false) { @@ -165,7 +169,7 @@ define('CACHE', TMP . 'cache' . DS . 'cli' . DS); } } -}else{ +} else { // This openITCOCKPIT is running inside a workhorse container like mod_gearman // The primary job of this container is only to provide the openITCOCKPIT CLI backend to be able // to execute notification commands or the evc check plugin From 775a438d81128deb4194f115ee059fafd1fa2c15 Mon Sep 17 00:00:00 2001 From: nook24 Date: Wed, 31 May 2023 14:08:55 +0200 Subject: [PATCH 51/54] ITC-2986 Make SystemId container ready --- src/Command/SetupCommand.php | 3 +++ src/Template/Statistics/index.php | 6 +++++- .../System/Health/StatisticsCollector.php | 3 ++- .../Core/System/Health/SystemId.php | 21 +++++++++++++++---- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/Command/SetupCommand.php b/src/Command/SetupCommand.php index 31db1dc224..da37ac1e43 100644 --- a/src/Command/SetupCommand.php +++ b/src/Command/SetupCommand.php @@ -37,6 +37,7 @@ use Cake\ORM\TableRegistry; use Cake\Validation\Validation; use itnovum\openITCOCKPIT\Core\DbBackend; +use itnovum\openITCOCKPIT\Core\System\Health\SystemId; use itnovum\openITCOCKPIT\SetupShell\MailConfigurator; use itnovum\openITCOCKPIT\SetupShell\MailConfigValue; use itnovum\openITCOCKPIT\SetupShell\MailConfigValueInt; @@ -167,6 +168,8 @@ public function execute(Arguments $args, ConsoleIo $io) { } + // Generate new SystemId + $SystemId = new SystemId(); $this->io->out(''); $this->io->hr(); $this->io->success(__('You can now open the web frontend in your browser and login. Have a nice day!')); diff --git a/src/Template/Statistics/index.php b/src/Template/Statistics/index.php index 77cb0f286a..9bd3ab25b0 100644 --- a/src/Template/Statistics/index.php +++ b/src/Template/Statistics/index.php @@ -132,7 +132,11 @@
- /opt/openitc/etc/system-id. + + /opt/openitc/var/system-id + + /opt/openitc/etc/system-id. +
diff --git a/src/itnovum/openITCOCKPIT/Core/System/Health/StatisticsCollector.php b/src/itnovum/openITCOCKPIT/Core/System/Health/StatisticsCollector.php index a9bf89f471..9e91b70014 100644 --- a/src/itnovum/openITCOCKPIT/Core/System/Health/StatisticsCollector.php +++ b/src/itnovum/openITCOCKPIT/Core/System/Health/StatisticsCollector.php @@ -100,7 +100,8 @@ public function getData() { 'version' => $LsbRelease->getVersion(), 'codename' => $LsbRelease->getCodename() ], - 'mysql' => $MysqlHealth->getAllMetrics() + 'mysql' => $MysqlHealth->getAllMetrics(), + 'containerized' => (IS_CONTAINER) ? true : false ]; } diff --git a/src/itnovum/openITCOCKPIT/Core/System/Health/SystemId.php b/src/itnovum/openITCOCKPIT/Core/System/Health/SystemId.php index 6f604468e8..f02a7e0f8d 100644 --- a/src/itnovum/openITCOCKPIT/Core/System/Health/SystemId.php +++ b/src/itnovum/openITCOCKPIT/Core/System/Health/SystemId.php @@ -29,15 +29,28 @@ class SystemId { + /** + * @var string|null + */ private $systemId = null; + /** + * @var string + */ + private $basePath = '/opt/openitc/etc'; + public function __construct() { - if (file_exists('/opt/openitc/etc/system-id')) { - $this->systemId = trim(file_get_contents('/opt/openitc/etc/system-id')); + if (IS_CONTAINER) { + // This is by default a docker volume so the ID will be persistent + $this->basePath = '/opt/openitc/var'; + } + + if (file_exists($this->basePath . DS . 'system-id')) { + $this->systemId = trim(file_get_contents($this->basePath . DS . 'system-id')); return; } else { - if (is_writable('/opt/openitc/etc')) { - $file = fopen('/opt/openitc/etc/system-id', 'w+'); + if (is_writable($this->basePath)) { + $file = fopen($this->basePath . DS . 'system-id', 'w+'); $this->systemId = UUID::v4(); fwrite($file, $this->systemId); fclose($file); From 88e34c306db89a0b5e55dbee9b520156f39e910f Mon Sep 17 00:00:00 2001 From: nook24 Date: Thu, 1 Jun 2023 15:39:26 +0200 Subject: [PATCH 52/54] ITC-2986 Rewirte IS_CONTAINER === false if statements --- src/Command/GearmanWorkerCommand.php | 12 ++++++------ src/Controller/ConfigurationFilesController.php | 2 +- src/Controller/PacketmanagerController.php | 2 +- src/Template/Administrators/debug.php | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Command/GearmanWorkerCommand.php b/src/Command/GearmanWorkerCommand.php index 84c24df3a9..e1899474dd 100644 --- a/src/Command/GearmanWorkerCommand.php +++ b/src/Command/GearmanWorkerCommand.php @@ -754,7 +754,7 @@ public function runJob($job) { break; case 'export_verify_config': - if (!IS_CONTAINER) { + if (IS_CONTAINER === false) { // Normal installation of openITCOCKPIT via apt, dnf or git /** @var SystemsettingsTable $SystemsettingsTable */ $SystemsettingsTable = TableRegistry::getTableLocator()->get('Systemsettings'); @@ -782,13 +782,13 @@ public function runJob($job) { $BinarydEndpoint = $Binarydctl->getBinarydApiEndpointByServiceName('naemon-verify'); //Run naemon-verify - try{ + try { $result = $BinarydEndpoint->executeJson('naemon-verify'); $returncode = $result['rc'] ?? 1; $output = [ $result['stdout'] ?? '' ]; - }catch (\Exception $e){ + } catch (\Exception $e) { Log::error($e->getMessage()); } @@ -1386,13 +1386,13 @@ public function launchExport($createBackup = 1) { $BinarydEndpoint = $Binarydctl->getBinarydApiEndpointByServiceName('naemon-verify'); //Run naemon-verify - try{ + try { $result = $BinarydEndpoint->executeJson('naemon-verify'); $returncode = $result['rc'] ?? 1; $output = [ $result['stdout'] ?? '' ]; - }catch (\Exception $e){ + } catch (\Exception $e) { Log::error($e->getMessage()); } } else { @@ -1416,7 +1416,7 @@ public function launchExport($createBackup = 1) { $ExportsTable->save($verifyEntity); //Reloading the monitoring system - if (!IS_CONTAINER) { + if (IS_CONTAINER === false) { //Check if Naemon/Nagios is running. //If Nagios is running, we reload the config, if not we need to restart $entity = $ExportsTable->newEntity([ diff --git a/src/Controller/ConfigurationFilesController.php b/src/Controller/ConfigurationFilesController.php index b1c6bdb930..a0168da13c 100644 --- a/src/Controller/ConfigurationFilesController.php +++ b/src/Controller/ConfigurationFilesController.php @@ -50,7 +50,7 @@ public function index() { } $configFilesForFrontend = []; - if (!IS_CONTAINER) { + if (IS_CONTAINER === false) { $GeneratorRegistry = new GeneratorRegistry(); foreach ($GeneratorRegistry->getAllConfigFilesWithCategory() as $categoryName => $ConfigFileObjects) { $category = [ diff --git a/src/Controller/PacketmanagerController.php b/src/Controller/PacketmanagerController.php index 1cb52d6b20..f8673b3c0c 100644 --- a/src/Controller/PacketmanagerController.php +++ b/src/Controller/PacketmanagerController.php @@ -91,7 +91,7 @@ public function index() { $installedModules = []; $output = []; - if (!IS_CONTAINER) { + if (IS_CONTAINER === false) { $LsbRelease = new LsbRelease(); if ($LsbRelease->isDebianBased()) { exec('dpkg -l |grep openitcockpit-module', $output, $rc); diff --git a/src/Template/Administrators/debug.php b/src/Template/Administrators/debug.php index 2a2d534df5..0aeb56e628 100755 --- a/src/Template/Administrators/debug.php +++ b/src/Template/Administrators/debug.php @@ -77,7 +77,7 @@ - + element('repository_checker'); ?> getCodename() === 'bionic'): ?> From e458e774bad6b80043300e36b8205484a7f78648 Mon Sep 17 00:00:00 2001 From: nook24 Date: Thu, 1 Jun 2023 15:42:20 +0200 Subject: [PATCH 53/54] ITC-2986 Fix address check of PuppeteerClient --- plugins/PuppeteerPdf/src/Pdf/PuppeteerClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/PuppeteerPdf/src/Pdf/PuppeteerClient.php b/plugins/PuppeteerPdf/src/Pdf/PuppeteerClient.php index 8bb9e9e951..6740e1d8d0 100644 --- a/plugins/PuppeteerPdf/src/Pdf/PuppeteerClient.php +++ b/plugins/PuppeteerPdf/src/Pdf/PuppeteerClient.php @@ -27,7 +27,7 @@ class PuppeteerClient { public function __construct() { $address = env('OITC_PUPPETEER_ADDRESS', null); - if (empty(!$address)) { + if (!empty($address)) { $this->address = $address; } From 0cf8945e9c763aef2b4e04468674957840d1dab2 Mon Sep 17 00:00:00 2001 From: nook24 Date: Thu, 1 Jun 2023 15:54:40 +0200 Subject: [PATCH 54/54] ITC-2986 Fix address check of ChartRenderClient --- src/itnovum/openITCOCKPIT/Core/NodeJS/ChartRenderClient.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/itnovum/openITCOCKPIT/Core/NodeJS/ChartRenderClient.php b/src/itnovum/openITCOCKPIT/Core/NodeJS/ChartRenderClient.php index 9170eba059..7dbed571e8 100644 --- a/src/itnovum/openITCOCKPIT/Core/NodeJS/ChartRenderClient.php +++ b/src/itnovum/openITCOCKPIT/Core/NodeJS/ChartRenderClient.php @@ -71,7 +71,7 @@ class ChartRenderClient { public function __construct() { $address = env('OITC_PUPPETEER_ADDRESS', null); - if (empty(!$address)) { + if (!empty($address)) { $this->address = $address; }