diff --git a/config/config_custom.php.dist b/config/config_custom.php.dist index b8ea8520b2b2a29e848145447f904319e5d89a3b..50c09d5c8769a35144225b26528d2078b8234068 100644 --- a/config/config_custom.php.dist +++ b/config/config_custom.php.dist @@ -91,6 +91,7 @@ return [ 'rollout'=>[ 'default'=>[], + /* 'ssh'=>[ 'user'=>'imldeployment', 'privatekey'=>'', @@ -99,13 +100,13 @@ return [ 'command'=>'/usr/local/bin/puppetrun.sh', ], 'awx'=>[ - 'url'=>'https://awx.sys.iml.unibe.ch/api/v2', // no ending "/" - 'user'=>'api-ci', - 'password'=>'awRSbdB2rkViaBXBKOvtr11DEoZJSqHceih1hEE4awrjIO1wuArKu85WmetsRp63', + 'url'=>'https://awx.example.com/api/v2', // no ending "/" + 'user'=>'ciserver', + 'password'=>'ciserver', 'jobtemplate'=>'36', 'tags'=>'rollout', - // 'ignore-ssl-error'=>false, ], + */ ], ], @@ -128,6 +129,42 @@ return [ ], ], ], + + // ---------------------------------------------------------------------- + // APPMONITOR + // see <https://os-docs.iml.unibe.ch/appmonitor/> + // ---------------------------------------------------------------------- + + "appmonitor" => [ + + // notification + + // email notification for this application + /* + "email" => [ + "sysadmin@example.com" + ], + */ + // email notification for this application + /* + "slack" => [ + ["#sysadmins", "https://hooks.slack.com/services/AAA/BBB/CCC" ] + ], + */ + + // limit access to appmonitor client to specific IP addresses + /* + "ip" => [ + '127.0.0.1', + '::1', + '10.0.2.2', + ], + */ + + // limit access to appmonitor client to specific token + // "token" => ["token", "1234567890"], + + // ---------------------------------------------------------------------- ]; \ No newline at end of file diff --git a/config/inc_projects_config.php b/config/inc_projects_config.php index 0345ab7affa26af284cbbff71d9e6cc83aca0136..17cfa94e3e59fee88a94805e1f903765c5ff42ef 100644 --- a/config/inc_projects_config.php +++ b/config/inc_projects_config.php @@ -1,4 +1,10 @@ <?php +/** + * Array of global configuration for CI server + * @var array + */ +$aConfig = []; +global $aConfig; $aConfig = include('config_defaults.php'); if (file_exists(__DIR__.'/config_custom.php')){ diff --git a/hooks/templates/config_custom.php.erb b/hooks/templates/config_custom.php.erb index 01e109e323cf18997723d7657af460f1907b7dc9..28c3d1dcfec11e8da093675b2d1f89eccfc9678d 100644 --- a/hooks/templates/config_custom.php.erb +++ b/hooks/templates/config_custom.php.erb @@ -103,15 +103,35 @@ return [ ], /* - 'foreman' => array( + 'foreman' => [ 'api'=>'<%= @replace["foreman-url"] %>', // with ending "/" 'user'=>'<%= @replace["foreman-user"] %>', 'password'=>'<%= @replace["foreman-password"] %>', 'ignore-ssl-error'=><%= @replace["foreman-ignore-ssl-error"] %>, // 'varname-replace'=>'ci-replacement', - ), + ], */ // ---------------------------------------------------------------------- + // APPMONITOR + // see <https://os-docs.iml.unibe.ch/appmonitor/> + // ---------------------------------------------------------------------- + + "appmonitor" => [ + + // notification + + // email notification for this application + "email" => [<%= @replace["appmonitor-email-to"] %>], + + "slack" => [<%= @replace["appmonitor-slack"] %>], + + // limit access to appmonitor client to specific IP addresses + "ip" => [<%= @replace["appmonitor-ip"] %>], + + // limit access to appmonitor client to specific token + "token" => [<%= @replace["appmonitor-token"] %>], + + // ---------------------------------------------------------------------- ]; \ No newline at end of file diff --git a/public_html/appmonitor/general_include.php b/public_html/appmonitor/general_include.php index bdd129b19018a17c8f27d750d304e9198ccf12bb..b7530759bed2059dace5d912f142a0816c344d6e 100644 --- a/public_html/appmonitor/general_include.php +++ b/public_html/appmonitor/general_include.php @@ -7,6 +7,7 @@ * @author: Axel Hahn * ---------------------------------------------------------------------- * 2018-06-30 v0.1 + * 2024-09-04 php8 only: short array syntax; use data from ci server config file */ // ---------------------------------------------------------------------- @@ -17,28 +18,31 @@ // check local ips and IML networks (includes the monitor) // appmonitor is not available on EDUROAM or VPN -$oMonitor->checkIp(array( - '127.0.0.1', - '::1', - '10.0.2.2', - '130.92.30.11', - '130.92.30.44', - '130.92.79.49', -)); +if(isset($aConfig['appmonitor']['ip']) && count($aConfig['appmonitor']['ip'])){ + $oMonitor->checkIp($aConfig['appmonitor']['ip']); +} // --- check a token // an incoming request must have the GET param "token=123" // $oMonitor->checkTokem('token', '123'); - +if(isset($aConfig['appmonitor']['token']) && count($aConfig['appmonitor']['token'])){ + $oMonitor->checkToken($aConfig['appmonitor']['token'][0], $aConfig['appmonitor']['token'][1]); +} // ---------------------------------------------------------------------- // NOTIFICATION // ---------------------------------------------------------------------- -// $oMonitor->addEmail('sysadmin@example.com'); -// $oMonitor->addSlackWebhook(array("mywebhook"=> "https://hooks.slack.com/services/(...)")); -$oMonitor->addEmail('axel.hahn@iml.unibe.ch'); - +if(isset($aConfig['appmonitor']['email']) && count($aConfig['appmonitor']['email'])){ + foreach($aConfig['appmonitor']['email'] as $sEmailTo){ + $oMonitor->addEmail($sEmailTo); + } +} +if(isset($aConfig['appmonitor']['slack']) && count($aConfig['appmonitor']['slack'])){ + foreach($aConfig['appmonitor']['slack'] as $aSlackTarget){ + $oMonitor->addSlackWebhook($aSlackTarget[0], $aSlackTarget[1]); + } +} // ---------------------------------------------------------------------- // set a tag with phase @@ -46,7 +50,9 @@ $oMonitor->addEmail('axel.hahn@iml.unibe.ch'); $sHost=$_SERVER['HTTP_HOST']; $sHost2=php_uname("n"); $sMyPhase='live'; -foreach (array('dev', 'preview', 'stage', 'demo') as $sPhase){ + +// foreach (array('dev', 'preview', 'stage', 'demo') as $sPhase){ +foreach (array_keys($aConfig['phases']) as $sPhase){ if( strstr($sHost.'.', $sPhase)!==false || strstr($sHost.'-', $sPhase)!==false diff --git a/public_html/appmonitor/index.php b/public_html/appmonitor/index.php index 15011824790473dfd0a5dbd6d1d82c227ef4566f..422c047b54f93e304b1a7d104fe718326e08edc4 100644 --- a/public_html/appmonitor/index.php +++ b/public_html/appmonitor/index.php @@ -1,46 +1,69 @@ <?php - +/** + * IML APPMONITOR CHECKS FOR CI SERVER + * + * @author: Axel Hahn + * + * ------------------------------------------------------------------ + * 2014-10-24 v0.1 + * ... + * 2024-09-04 php8 only: short array syntax + */ require_once('classes/appmonitor-client.class.php'); + + require_once(__DIR__.'/../deployment/classes/project.class.php'); $oMonitor = new appmonitor(); - -$oMonitor->addCheck( - array( - "name" => "simple", - "description" => "Very simple test", - "check" => array( - "function" => "Simple", - "params" => array( - "result" => 0, - "value" => "The appmonitor client is reachable.", - ), - ), - ) -); $sCfgfile='../../config/inc_projects_config.php'; +require_once $sCfgfile; + +include('general_include.php'); // ---------------------------------------------------------------------- -// config file +// config files // ---------------------------------------------------------------------- $oMonitor->addCheck( - array( + [ "name" => "read config file", "description" => "Check if config file is readable", - "check" => array( + "check" => [ "function" => "File", - "params" => array( + "params" => [ "filename" => $sCfgfile, "file" => true, "readable" => true, - ), - ), - ) + ], + ], + ] ); -require_once $sCfgfile; + + +foreach ([ + "config/config_custom.php", + "config/config_defaults.php", + "config/inc_roles.php", +] as $sCfgfile) { + + $oMonitor->addCheck( + [ + "name" => "read config file $sCfgfile", + "description" => "Check if config file $sCfgfile is an existing file and is readable", + "check" => [ + "function" => "File", + "params" => [ + "filename" => "../../$sCfgfile", + "file" => true, + "readable" => true, + ], + ], + ] + ); +} + // echo '<pre>' . print_r($aConfig, 1) . '</pre>';die(); @@ -48,50 +71,50 @@ require_once $sCfgfile; // directories // ---------------------------------------------------------------------- -foreach (array( +foreach ([ - 'tmpDir'=>array('dir'=>$aConfig['tmpDir'], 'descr'=>'Temp Dir mit git Daten'), - 'configDir'=>array('dir'=>$aConfig['configDir'], 'descr'=>'Ablage der Programm-Config'), - 'dataDir'=>array('dir'=>$aConfig['dataDir'], 'descr'=>'Basisverzeichnis fue DB, Projekt-Configs, SSH-Keys'), - 'dataDir/database'=>array('dir'=>$aConfig['dataDir'].'/database', 'descr'=>'DB-Ablage (Sqlite)'), - 'dataDir/projects'=>array('dir'=>$aConfig['dataDir'].'/projects', 'descr'=>'Projekt-Configdateien'), - 'dataDir/sshkeys'=>array('dir'=>$aConfig['dataDir'].'/sshkeys', 'descr'=>'SSH Keys'), + 'tmpDir'=>['dir'=>$aConfig['tmpDir'], 'descr'=>'Temp Dir mit git Daten'], + 'configDir'=>['dir'=>$aConfig['configDir'], 'descr'=>'Ablage der Programm-Config'], + 'dataDir'=>['dir'=>$aConfig['dataDir'], 'descr'=>'Basisverzeichnis fue DB, Projekt-Configs, SSH-Keys'], + 'dataDir/database'=>['dir'=>$aConfig['dataDir'].'/database', 'descr'=>'DB-Ablage (Sqlite)'], + 'dataDir/projects'=>['dir'=>$aConfig['dataDir'].'/projects', 'descr'=>'Projekt-Configdateien'], + 'dataDir/sshkeys'=>['dir'=>$aConfig['dataDir'].'/sshkeys', 'descr'=>'SSH Keys'], - 'buildDir'=>array('dir'=>$aConfig['buildDir'], 'descr'=>'Basisverzeichnis fuer Builds'), - 'packageDir'=>array('dir'=>$aConfig['packageDir'], 'descr'=>'Basisverzeichnis der Pakete und Versionen'), - 'archiveDir'=>array('dir'=>$aConfig['archiveDir'], 'descr'=>'Ablage der gebuildeten Archive'), + 'buildDir'=>['dir'=>$aConfig['buildDir'], 'descr'=>'Basisverzeichnis fuer Builds'], + 'packageDir'=>['dir'=>$aConfig['packageDir'], 'descr'=>'Basisverzeichnis der Pakete und Versionen'], + 'archiveDir'=>['dir'=>$aConfig['archiveDir'], 'descr'=>'Ablage der gebuildeten Archive'], -) as $sKey=>$aItem) { +] as $sKey=>$aItem) { $oMonitor->addCheck( - array( + [ "name" => "dir $sKey", "description" => $aItem['descr'], "parent" => "read config file", - "check" => array( + "check" => [ "function" => "File", - "params" => array( + "params" => [ "filename" => $aItem['dir'], "dir" => true, "writable" => true, - ), - ), - ) + ], + ], + ] ); } $oMonitor->addCheck( - array( + [ "name" => "Free space in Archive dir ", "description" => "The file storage must have some space left", - "check" => array( + "check" => [ "function" => "Diskfree", "parent" => "read config file", - "params" => array( + "params" => [ "directory" => $aConfig['archiveDir'], "warning" => "2GB", "critical" => "500MB", - ), - ), - ) + ], + ], + ] ); // ---------------------------------------------------------------------- // count of Projects @@ -113,55 +136,55 @@ foreach ($oPrj->getProjects() as $sPrj) { $iInQueue+=$aProgress['hasQueue'] ? 1 : 0; } $oMonitor->addCheck( - array( + [ "name" => "ci projects", "description" => "Count of Projects in CI Webgui", "group" => "monitor", "parent" => "read config file", - "check" => array( + "check" => [ "function" => "Simple", - "params" => array( + "params" => [ "result" => $iProjectCount ? RESULT_OK : RESULT_ERROR, "value" => "found projects: $iProjectCount", "count" => $iProjectCount, "visual" => "simple", - ), - ), - ) + ], + ], + ] ); $oMonitor->addCheck( - array( + [ "name" => "ci inProgress", "description" => "Projects in progress", "group" => "monitor", "parent" => "read config file", - "check" => array( + "check" => [ "function" => "Simple", - "params" => array( + "params" => [ "result" => RESULT_OK, "value" => "found projects: $iInProgress", "count" => $iInProgress, "visual" => "simple", - ), - ), - ) + ], + ], + ] ); $oMonitor->addCheck( - array( + [ "name" => "ci hasqueue", "description" => "Waiting for install", "group" => "monitor", "parent" => "read config file", - "check" => array( + "check" => [ "function" => "Simple", - "params" => array( + "params" => [ "result" => RESULT_OK, "value" => "found projects: $iInQueue", "count" => $iInQueue, "visual" => "simple", - ), - ), - ) + ], + ], + ] ); include 'plugins/apps/shared_check_ssl.php'; @@ -176,32 +199,32 @@ if(isset($aConfig['foreman']['api'])){ require_once(__DIR__.'/../deployment/classes/foremanapi.class.php'); $oForeman = new ForemanApi($aConfig['foreman']); - foreach (array('hostgroups', 'hosts') as $sForemanKey){ - $aFData=$oForeman->read(array( - 'request' => array( - array($sForemanKey), - ), - 'response' => array( + foreach (['hostgroups', 'hosts'] as $sForemanKey){ + $aFData=$oForeman->read([ + 'request' => [ + [$sForemanKey], + ], + 'response' => [ 'id', 'title' - ), - )); + ], + ]); $oMonitor->addCheck( - array( + [ "name" => "Foreman $sForemanKey", "description" => "Count of Foreman $sForemanKey", "group" => "monitor", "parent" => "read config file", - "check" => array( + "check" => [ "function" => "Simple", - "params" => array( + "params" => [ "result" => count($aFData) ? RESULT_OK : RESULT_ERROR, "value" => "Count of found Foreman $sForemanKey: " . count($aFData)."; response status: ".$oForeman->getResponseStatus() . "; Http-Code ".$oForeman->getResponseInfo('http_code'), "count" => count($aFData), "visual" => "simple", - ), - ), - ) + ], + ], + ] ); } } @@ -220,16 +243,16 @@ if(isset($aConfig['plugins']['rollout']['awx'])){ } $oMonitor->addCheck( - array( + [ "name" => "AWX API", "description" => "check if AWX api is available", "group" => "network", "parent" => "read config file", - "check" => array( + "check" => [ "function" => "HttpContent", "params" => $aOpts, - ), - ) + ], + ] ); } @@ -252,56 +275,56 @@ if(count($aConfig['mirrorPackages'])){ exec($sCmd, $sOut, $iRc); $oMonitor->addCheck( - array( + [ "name" => "mirror target $sHostKey", "description" => "Sync target of generated packages", "group" => "network", "parent" => "read config file", - "check" => array( + "check" => [ "function" => "Simple", - "params" => array( + "params" => [ "result" => $iRc ? RESULT_ERROR : RESULT_OK, "value" => "Command [$sCmd] returns with exitcode $iRc; output: ".implode(" ", $sOut), - ), - ), - ) + ], + ], + ] ); } } -foreach(array( +foreach([ /* - array( + [ 'host'=>'gitlab.iml.unibe.ch', 'port'=>22, 'descr'=>'SSH port to Gitlab on gitlab.iml.unibe.ch' - ), + ], */ - array( + [ 'host'=>'git-repo.iml.unibe.ch', 'port'=>22, 'descr'=>'SSH port to Gitlab on git-repo.iml.unibe.ch' - ), - array( + ], + [ 'host'=>'github.com', 'port'=>22, 'descr'=>'SSH port to Github' - ), -) as $aDescr){ + ], +] as $aDescr){ $oMonitor->addCheck( - array( - "name" => 'port check '.$aDescr['host'].':'.$aDescr['port'], - "description" => $aDescr['descr'], - "group" => "cloud", - "parent" => "read config file", - "check" => array( - "function" => "PortTcp", - "params" => array( - "port"=>$aDescr['port'], - "host"=>$aDescr['host'], - ), - ), - ) + [ + "name" => 'port check '.$aDescr['host'].':'.$aDescr['port'], + "description" => $aDescr['descr'], + "group" => "cloud", + "parent" => "read config file", + "check" => [ + "function" => "PortTcp", + "params" => [ + "port"=>$aDescr['port'], + "host"=>$aDescr['host'], + ], + ], + ] ); } @@ -312,56 +335,56 @@ foreach(array( $sSqlitefile=$aConfig['dataDir'].'/database/logs.db'; $oMonitor->addCheck( - array( + [ "name" => "Sqlite DB for action logs", "description" => "Connect sqlite db ". basename($sSqlitefile), "parent" => "read config file", - "check" => array( + "check" => [ "function" => "SqliteConnect", - "params" => array( + "params" => [ "db"=>$sSqlitefile - ), - ), - ) + ], + ], + ] ); // ---------------------------------------------------------------------- // system stuff // ---------------------------------------------------------------------- $oMonitor->addCheck( - array( + [ "name" => "plugin Load", "description" => "current load", "parent" => false, - "check" => array( + "check" => [ "function" => "Loadmeter", - "params" => array( + "params" => [ "warning" => 1.0, "error" => 3, - ), - ), + ], + ], "worstresult" => RESULT_OK - ) + ] ); $oMonitor->addCheck( - array( + [ "name" => "plugin ApacheProcesses", "description" => "Apache processes", "parent" => false, - "check" => array( + "check" => [ "function" => "ApacheProcesses", - "params" => array( + "params" => [ "warning" => 50, "error" => 75, - ), - ), + ], + ], "worstresult" => RESULT_OK - ) + ] ); +// ---------------------------------------------------------------------- -// Gesamt-Ergebnis - ohne Param=aut. max. Wert nehmen $oMonitor->setResult(); - -// Ausgabe $oMonitor->render(); + +// ----------------------------------------------------------------------