diff --git a/public_html/check-config.php b/public_html/check-config.php index e66c1f4f3002eaad0ce37295cb508b7223f683a3..e271c6324db2a5d61d5c2ef5f11e45dee294513a 100644 --- a/public_html/check-config.php +++ b/public_html/check-config.php @@ -1,3 +1,17 @@ +<!DOCTYPE html> +<html> +<head> +<style> + body{font-family: arial; background: #f8f8f8; color:#345;} + .box{border: 2px solid rgba(0,0,0,0.2); padding: 1em; margin-bottom: 1em;} + .ok{color:#383; background:#cfd;} + .error{color:#833; background:#fdd;} +</style> +</head> +<body> + +<h1>CI Server :: Config Check</h1> + <?php /* ###################################################################### @@ -10,120 +24,137 @@ ###################################################################### */ - // ---------------------------------------------------------------------- // functions // ---------------------------------------------------------------------- /** - * get html code to draw a colored box + * Get html code to draw a colored box + * * @param string $s message * @param string $sClass css class; one of ok|info|error * @return string */ -function drawbox($s, $sClass) { - return '<div class="box ' . $sClass . '">' . $s . '</div>'; +function drawbox(string $s, string $sClass): string +{ + return "<div class=\"box $sClass\">$s</div>"; } /** - * show an alert box with error message - * @param type $s - * @return type + * Show an alert box with error message + * + * @param string $s message to show + * @return string */ -function showerror($s) { +function showerror($s) +{ return drawbox($s, 'error'); } /** - * show green box with ok message - * @param type $s - * @return type + * Show green box with ok message + * + * @param string $s message to show + * @return string */ -function showok($s) { +function showok($s) +{ return drawbox($s, 'ok'); } /** - * check a directory if it exists and is writtable + * Check a directory if it exists and is writtable + * * @global array $aErrors found errors + * * @param string $sDir directory to check - * @param string $sKey key in config (for output only) - * @return boolean + * @param string $sKey key in config where this directory is defined (for error output only) + * @return string */ -function checkdir($sDir, $sKey = false) { +function checkdir(string $sDir, string $sKey = ''): string +{ global $aErrors; + $sReturn = ''; - echo 'check directory [' . $sDir . '] '; + $sReturn.="Check directory [$sDir] "; if (!is_dir($sDir)) { - echo '<span class="error">does not exist</span><br>'; - $aErrors[] = "* \$aConfig['$sKey'] points to a non existing directory (" . $sDir . ").\n"; - return false; + $sReturn.='<span class="error">does not exist</span><br>'; + $aErrors[] = "* \$aConfig['$sKey'] points to a non existing directory ($sDir).\n"; } else { if (!is_writable($sDir)) { - echo '<span class="error">not writable</span><br>'; - $aErrors[] = "* \$aConfig['$sKey'] = " . $sDir . " is NOT writable.\n"; - return false; + $sReturn.='<span class="error">not writable</span><br>'; + $aErrors[] = "* \$aConfig['$sKey'] = $sDir is NOT writable.\n"; } else { - echo '<span class="ok">OK</span> exists and is writable<br>'; - return true; + $sReturn.='<span class="ok">OK</span> exists and is writable<br>'; } } - return false; + return $sReturn; } /** - * check if a php module was found + * Check if a php module was found + * * @global array $aErrors found errors + * * @param array $aRequiredMods array with needed php modules; default: empty = list all current php modules - * @return boolean + * @return string */ -function checkModule($aRequiredMods=array()){ +function checkModule($aRequiredMods = []): string +{ global $aErrors; - $sReturn=''; - - $aAllMods=get_loaded_extensions(false); + $sReturn = ''; + + $aAllMods = get_loaded_extensions(false); asort($aAllMods); - if(!count($aRequiredMods)){ - echo '<strong>List of all installes php modules</strong><br>'; - foreach($aAllMods as $sMod){ - echo $sMod.'<br>'; + if (!count($aRequiredMods)) { + $sReturn.= '<strong>List of all installes php modules</strong><br>'; + foreach ($aAllMods as $sMod) { + $sReturn.= "$sMod<br>"; } } else { - foreach($aRequiredMods as $sMod){ - echo $sMod.' - '; - if(!array_search($sMod, $aAllMods)===false){ - echo '<span class="ok">OK</span> installed'; + foreach ($aRequiredMods as $sMod) { + $sReturn.="$sMod - "; + if (!array_search($sMod, $aAllMods) === false) { + $sReturn.='<span class="ok">OK</span> installed'; } else { - echo '<span class="error">does not exist</span>'; + $sReturn.='<span class="error">does not exist</span>'; $aErrors[] = "* php module $sMod was not found.\n"; } - echo '<br>'; + $sReturn.='<br>'; } } - return true; + return $sReturn; } /** - * check if a command can be executed + * Check if a command can be executed + * * @global array $aErrors found errors + * * @param array $aCommands array with key=command + value=description - * @return boolean + * @return string */ -function checkCommands($aCommands){ +function checkCommands(array $aCommands): string +{ global $aErrors; - foreach ($aCommands as $sCommand=>$sDescription){ - echo 'command ['.$sCommand.'] ('.$sDescription.') - '; - system("$sCommand", $iReturn); - - if($iReturn===0){ - echo '<span class="ok">OK</span> '; - } else { - echo '<span class="error">does not exist</span>'; - $aErrors[] = "* command $sCommand was not found or failed.\n"; - } - echo '<br>'; + $sReturn = ''; + + foreach ($aCommands as $sCommand => $sDescription) { + $sReturn.='command [' . $sCommand . '] (' . $sDescription . ') - '; + + $aOut=[]; + exec("$sCommand 2>&1", $aOut, $iReturn) . " "; + $sReturn.= implode("\n", $aOut) . "\n"; + + if ($iReturn === 0) { + $sReturn.='<span class="ok">OK</span> '; + } else { + $sReturn.='<span class="error">does not exist</span>'; + $aErrors[] = "* command $sCommand was not found or failed.\n"; + } + $sReturn.='<br>'; } - return true; + return $sReturn; } // ---------------------------------------------------------------------- @@ -132,15 +163,7 @@ function checkCommands($aCommands){ // // ---------------------------------------------------------------------- -echo ' -<style> - body{font-family: arial; background: #f8f8f8; color:#345;} - .box{border: 2px solid rgba(0,0,0,0.2); padding: 1em; margin-bottom: 1em;} - .ok{color:#383; background:#cfd;} - .error{color:#833; background:#fdd;} -</style> -<h1>Config Checker</h1> -'; +$sOut=""; $aErrors = array(); include("../config/inc_projects_config.php"); @@ -148,97 +171,86 @@ if (!isset($aConfig) || !is_array($aConfig)) { // echo showerror("\$aConfig does not exist. The config was not included before including " . __FILE__ . " in the request/ script."); $aErrors[] = "* \$aConfig does not exist. The config was not included before including " . __FILE__ . " in the request/ script."; } else { - + // ---------------------------------------------------------------------- - echo '<h2>Check keys with directories</h2>'; - foreach (array( - // 'appRootDir', - 'configDir', - 'workDir', - 'dataDir', - 'buildDir', - 'buildDefaultsDir', - 'packageDir', - 'archiveDir', - 'tmpDir', - ) as $sKey) { - checkdir($aConfig[$sKey], $sKey); + $sOut.='<h2>Check keys with directories</h2>'; + foreach ([ // 'appRootDir', + 'configDir', 'workDir', 'dataDir', 'buildDir', 'buildDefaultsDir', 'packageDir', 'archiveDir', 'tmpDir', ] as $sKey) { + $sOut.=checkdir($aConfig[$sKey], $sKey); } - - echo '<h2>Check subdirs of key dataDir</h2>'; - foreach (array( - $aConfig['dataDir'] . '/database', - $aConfig['dataDir'] . '/projects', - $aConfig['dataDir'] . '/sshkeys', - ) as $sDir2Check) { - checkdir($sDir2Check, 'dataDir + [subdir]'); + + $sOut.='<h2>Check subdirs of key dataDir</h2>'; + foreach (array($aConfig['dataDir'] . '/database', $aConfig['dataDir'] . '/projects', $aConfig['dataDir'] . '/sshkeys', ) as $sDir2Check) { + $sOut.=checkdir($sDir2Check, 'dataDir + [subdir]'); } - + // ---------------------------------------------------------------------- - echo '<h2>Check keys</h2>'; + $sOut.='<h2>Check keys</h2>'; // check required keys in the config - foreach (array( - 'auth', - 'build', - 'lang', - 'phases', - 'projects', - ) as $sKey) { - echo "Key [$sKey] "; + foreach (array('auth', 'build', 'lang', 'phases', 'projects', ) as $sKey) { + $sOut.="Key [$sKey] "; if (!array_key_exists($sKey, $aConfig)) { - echo '<span class="error">failed</span> missing key ['.$sKey.'] in config<br>'; + $sOut.="<span class=\"error\">failed</span> missing key [$sKey] in config<br>"; $aErrors[] = "* missing key [$sKey] in config\n"; } else { - echo '<span class="ok">OK</span> exists<br>'; + $sOut.='<span class="ok">OK</span> exists<br>'; } } } -echo '<h2>Check required PHP modules</h2>'; -echo 'PHP version: '.PHP_VERSION.'<br>' - . '<br>'; -checkModule(array( - 'PDO','curl', 'json', 'ldap', 'pdo_sqlite' -)); +$sOut.='<h2>Check required PHP modules</h2>'; +$sOut.='PHP version: ' . PHP_VERSION . '<br>' + . '<br>'; +$sOut.=checkModule([ + 'PDO', + 'curl', + 'json', + 'ldap', + 'pdo_sqlite' +]); -echo '<h2>Check executable commands</h2>' +$sOut.='<h2>Check executable commands</h2>' . '<p>remark: if the apache user has no login shell then all commands will fail.</p>'; -echo '<h3>basic tools</h3>'; -checkCommands(array( - 'which bash'=>'shell interpreter to execute hook scripts', - 'which cat'=>'show content of files', - 'which cp'=>'copy files', - 'which ln'=>'create softlinks for version handling', - 'which ls'=>'list files', - 'which mkdir'=>'create working directories', - 'which mv'=>'move files', - 'which ps'=>'process list', - 'which rm'=>'remove files and directories', -)); -echo '<h3>more tools</h3>'; -checkCommands(array( - 'which ssh'=>'connect with ssh for remote execution', - 'which rsync'=>'sync packages to puppet master', - 'which git'=>'connect to git repositories', -)); - -echo '<h3>tools for IML projects</h3>'; -checkCommands(array( - 'which uglifyjs'=>'compress js', - 'which yui-compressor'=>'compress js, css', - 'which nodejs'=>'Nodejs - Javascript v8', - 'which yarn'=>'nodejs package manager', -)); +$sOut.='<h3>basic tools</h3>'; +$sOut.=checkCommands([ + 'which bash' => 'shell interpreter to execute hook scripts', + 'which cat' => 'show content of files', + 'which cp' => 'copy files', + 'which ln' => 'create softlinks for version handling', + 'which ls' => 'list files', + 'which mkdir' => 'create working directories', + 'which mv' => 'move files', + 'which ps' => 'process list', + 'which rm' => 'remove files and directories', +]); +$sOut.='<h3>More tools</h3>'; +$sOut.=checkCommands([ + 'which ssh' => 'connect with ssh for remote execution', + 'which rsync' => 'sync packages to puppet master', + 'which git' => 'connect to git repositories', +]); + +$sOut.='<h3>tools for IML projects</h3>'; +$sOut.=checkCommands([ + 'which uglifyjs' => 'compress js', + 'which yui-compressor' => 'compress js, css', + 'which nodejs' => 'Nodejs - Javascript v8', + 'which yarn' => 'nodejs package manager', +]); -echo '<h2>Result</h2>'; if (count($aErrors)) { - echo showerror("FATAL ERROR in config.<br>" . implode("<br>\n", $aErrors)); + echo showerror("ERRORS were found:<br>" . implode("<br>\n", $aErrors)); } else { echo showok('OK, check was successfully finished.'); } - +echo '<h2>Result</h2>'; +echo $sOut; // do not enable - it shows passwords... // echo 'DEBUG: <pre>' . print_r($aConfig, 1) . '</pre>'; + +?> +</body> +</html> diff --git a/public_html/valuestore/classes/valuestore.class.php b/public_html/valuestore/classes/valuestore.class.php index 78913f0e0c37b74fd519c5910959d694bb82ac64..d31dc77f28e75c5d02e8630ffda14136c9f578bd 100644 --- a/public_html/valuestore/classes/valuestore.class.php +++ b/public_html/valuestore/classes/valuestore.class.php @@ -28,30 +28,69 @@ * @author hahn * * Axel: <axel.hahn@unibe.ch> + * * (...) - * 2024-09-03 Axel php8 only; added variable types; short array syntax + * 2024-09-04 Axel php8 only; added variable types; short array syntax */ class valuestore { + /** + * Project id + * @var string + */ public string $sProject = ''; + + /** + * Name of sPackage = project id in ci server + * @var string + */ public string $sPackage = ''; + + /** + * Phase; one of preview|stage|live + * @var string + */ public string $sPhase = ''; + + /** + * Name of place inside a phase; one of onhold|ready2install|deployed + * @var string + */ public string $sPlace = ''; + + /** + * Name of the host + * @var string + */ public string $sHost = ''; + + /** + * Name of the variable; eg. "version" + * @var string + */ public string $sVariable = ''; + + /** + * Value of the variable + * @var string + */ public string $sData = ''; + /** + * Flag: enable debug? + * @var bool + */ protected bool $_bDebug = true; /** - * filename of sqlite database file + * Filename of sqlite database file * @var string */ private string $_dbfile = ''; /** - * database connection + * Database connection * @var object */ protected object $_oDB; @@ -81,8 +120,21 @@ class valuestore );' ; - // hardcoded + /** + * List of allowed phases + * hardcoded :-/ + * + * @var array + */ protected array $_allowedPhases = ['preview', 'stage', 'live']; + + /** + * List of allowed places + * hardcoded :-/ + * + * @var array + */ + protected array $_allowedPlaces = ['onhold', 'ready2install', 'deployed']; // ---------------------------------------------------------------------- diff --git a/public_html/valuestore/index.php b/public_html/valuestore/index.php index 9da4fb06d263612a47028375867df729eb698cbe..25f2e794bd3b5e12529c9c4e9262f07c805598ce 100644 --- a/public_html/valuestore/index.php +++ b/public_html/valuestore/index.php @@ -4,8 +4,6 @@ * * VALUE HANDLER API * - * Syntax des Aufrufs (als GET Schreibweise; ein POST einzelner Variablen geht ebenso): - * * update * http://dev.ci.iml.unibe.ch:8002/valuestore/?action=update&package=player&phase=stage&place=deployed&host=stage01.player&variable=version&value=false * @@ -16,38 +14,49 @@ * * action=update (get-Funktionen muss ich später noch bauen) * project=[Projekt-ID (=Name des Package, das installiert wird); bei Versionen leer!] - * package=[Package-name] + * package=[Package-name] (Name des CI Projekts) * phase=(preview|stage|live) * host=[FQDN] * variable=version (andere noch nicht unterstützt/ vorgesehen) * value=[Versionsdaten] * * 2017-04-07 hahn first lines + * ... + * 2024-09-04 Axel <axel.hahn@unibe.ch> php8 only; added variable types; short array syntax */ // ---------------------------------------------------------------------- // functions // ---------------------------------------------------------------------- /** - * show an error message and quit with http status code 400 (Bad request) + * Show an error message and quit with http status code 400 (Bad request) + * * @param string $sMessage message to show - * @return boolean + * @return void */ -function quit($sMessage) { +function quit(string $sMessage): void +{ $sProtocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0'); header("$sProtocol 400: Bad request"); - die("<h1>Bad request</h1>" . $sMessage); - return false; + die( + "<h1>Bad request</h1> + <p>$sMessage.</p> + <hr> + <button onclick=\"history.back();\">back</button>" + ); } /** - * get a request param from GET and POST scope (POST has priority) and - * verify it with execution of a cleanup array + * Get a request param from GET and POST scope (POST has priority) and + * verify it with execution of a cleanup array. + * It returns false if thegiven key doesn't exist as parameter + * * @param string $sKey key to search for in GET or POST * @param string $sRegex4Cleanup regex for filtering - * @return type + * @return bool|int|string */ -function getParam($sKey, $sRegex4Cleanup = false) { +function getParam(string $sKey, string $sRegex4Cleanup = ''): bool|int|string +{ $sValue = false; if (array_key_exists($sKey, $_GET)) { $sValue = $_GET[$sKey]; @@ -66,29 +75,40 @@ function getParam($sKey, $sRegex4Cleanup = false) { return $sReturn; } -// ---------------------------------------------------------------------- -// check required params -// ---------------------------------------------------------------------- -/* -if (!$_GET || !count($_GET)) { - quit("no parameter was found."); -} +/** + * Throw an error if a given GET parameter has a given value. + * + * The purpose of this function is to prevent certain actions + * (like deleting a value) from being triggered by an URL. + * + * @param string $sVar name of the GET parameter to check + * @param string $sValue value of the GET parameter to check + * @return void */ - +function disallowGet(string $sVar, string $sValue): void +{ + if (isset($_GET[$sVar]) && $_GET[$sVar] == $sValue) { + quit("ERROR: $sVar = $sValue is not allowed with GET."); + } +} // ---------------------------------------------------------------------- // get vars // ---------------------------------------------------------------------- $sAction = getParam('action', '/[^a-z]/'); -if ($sAction !== "cleanup" - && $sAction !== "delete" - && $sAction !== "get" - && $sAction !== "show" - && $sAction !== "update" - ) { +if ( + $sAction !== "cleanup" + && $sAction !== "delete" + && $sAction !== "get" + && $sAction !== "show" + && $sAction !== "update" +) { quit("action is unknown or not implemented yet."); } +disallowGet('action', 'cleanup'); +disallowGet('action', 'delete'); +disallowGet('action', 'update'); $sProject = getParam('project', '/[^a-z\-\_0-9]/'); $sPackage = getParam('package', '/[^a-z\-\_0-9]/'); @@ -127,13 +147,12 @@ switch ($sAction) { } break; - break; case 'get': $oVersion->setProject($sProject, $sPackage, $sPhase, $sPlace, $sHost); header('Content-Type: application/json'); echo json_encode($oVersion->getVersion()); + return true; - break; case 'update': $oVersion->setProject($sProject, $sPackage, $sPhase, $sPlace, $sHost); if (!$sVarname) { @@ -143,7 +162,7 @@ switch ($sAction) { // case 'other-varname': case 'version': if ($oVersion->updateVar($sVarname, $sValue)) { - echo "OK: $sVarname was updated.".PHP_EOL."new value: $sValue".PHP_EOL; + echo "OK: $sVarname was updated." . PHP_EOL . "new value: $sValue" . PHP_EOL; } else { echo "ERROR: update for $sVarname failed."; } @@ -156,19 +175,18 @@ switch ($sAction) { break; case 'show': $oVersion->setProject($sProject, $sPackage, $sPhase, $sPlace, $sHost); - - echo '<h1>package ['.$sPackage.'] on '.$sHost.'</h1>' - . 'Host: '.$sHost.'<br>' - . 'package: '.$sPackage.'<br>' - . 'phase: '.$sPhase.'<br>' - . 'place: '.$sPlace.'<br>' - . '<br>' - . '<button onclick="history.back();">back</button><br>' - . '<hr>' - . '<pre>'.json_encode($oVersion->getVersion(), JSON_PRETTY_PRINT).'</pre>' - . '<hr>' - . '<button onclick="history.back();">back</button>' - . ''; + + echo '<h1>package [' . $sPackage . '] on ' . $sHost . '</h1>' + . 'Host: ' . $sHost . '<br>' + . 'package: ' . $sPackage . '<br>' + . 'phase: ' . $sPhase . '<br>' + . 'place: ' . $sPlace . '<br>' + . 'varaible: ' . $sVarname . '<br>' + . '<br>' + . '<button onclick="history.back();">back</button><br>' + . '<hr>' + . '<pre>' . json_encode($oVersion->getVersion(), JSON_PRETTY_PRINT) . '</pre>' + . ''; break; @@ -177,3 +195,5 @@ switch ($sAction) { quit("ERROR: the action is not supported."); break; } + +echo "<hr><button onclick=\"history.back();\">back</button>"; \ No newline at end of file