diff --git a/public_html/deployment/classes/config-replacement.class.php b/public_html/deployment/classes/config-replacement.class.php index 600809472ae42a1b347a9ba65988e95ce38c1e38..7b3f3d75eff17e1e77204c4f24f063111e806b7d 100644 --- a/public_html/deployment/classes/config-replacement.class.php +++ b/public_html/deployment/classes/config-replacement.class.php @@ -8,53 +8,68 @@ require_once 'project.class.php'; /** * config-replacement class * reads templatefiles and scans its placeholders for replacements - * + * + * @deprecated It is used for Foreman replacements; TODO: remove this class + * * @author hahn * * 2024-08-23 v1.1 Axel Hahn fix php parser problems */ -class configreplacement { - +class configreplacement +{ + /** * project class * @var object */ protected $_oProject = false; - protected $_sPhase = false; - protected $_aForemanReplacements = false; - + /** + * Phase of rollout + * @var string + */ + protected $_sPhase = ''; + + /** + * Found replacements in Foreman + * @var array + */ + protected array $_aForemanReplacements = []; + + /** * Constructor * @param string $sProject optional: project id; you can use setProject() too */ - public function __construct($sProject = '') { - if ($sProject){ + public function __construct($sProject = '') + { + if ($sProject) { $this->setProject($sProject); } } - + /** - * get an array with a flat list of all templatefiles of a build + * Get an array with a flat list of all templatefiles of a build * @return boolean|array */ - public function getTemplatefiles(){ - if (!$this->_sPhase){ + public function getTemplatefiles(): bool|array + { + if (!$this->_sPhase) { return false; } - $aReturn = array(); + $aReturn = []; - $aBuildfiles=$this->_oProject->getBuildfilesByPlace($this->_sPhase, 'onhold'); - if (!$aBuildfiles){ - $aBuildfiles=$this->_oProject->getBuildfilesByPlace($this->_sPhase, 'ready2install'); + $aBuildfiles = $this->_oProject->getBuildfilesByPlace($this->_sPhase, 'onhold'); + if (!$aBuildfiles) { + $aBuildfiles = $this->_oProject->getBuildfilesByPlace($this->_sPhase, 'ready2install'); } - - if (!isset($aBuildfiles['types']['templates'])){ + + if (!isset($aBuildfiles['types']['templates'])) { return false; } - foreach ($aBuildfiles['types']['templates'] as $sFile){ - $aReturn[]=$aBuildfiles['dir'].'/'.$sFile; + foreach ($aBuildfiles['types']['templates'] as $sFile) { + $aReturn[] = $aBuildfiles['dir'] . '/' . $sFile; } return $aReturn; } @@ -63,78 +78,83 @@ class configreplacement { * get an array with all template files (basename) and its replacement fields * @return bool|array */ - public function getReplacements(){ - if (!$this->_sPhase){ + public function getReplacements(): bool|array + { + if (!$this->_sPhase) { return false; } - $aFiles=$this->getTemplatefiles(); - if (!$aFiles){ + $aFiles = $this->getTemplatefiles(); + if (!$aFiles) { return false; } - - $aReturn=array(); - foreach ($aFiles as $sFile){ + + $aReturn = []; + foreach ($aFiles as $sFile) { // $sFile always exists because it was read from filesystem - $sContent=file_get_contents($sFile); + $sContent = file_get_contents($sFile); preg_match_all('/\@replace\[[\'\"](.*)[\'\"]\]/U', $sContent, $aMatches); - $aReturn[$sFile]=$aMatches[1]; - } + $aReturn[$sFile] = $aMatches[1]; + } return $aReturn; } - + /** - * get effective hostgroup id of the current phase + * Get effective hostgroup id of the current phase * @return integer */ - public function getForemanHostgroup(){ - $aPrjConfig=$this->_oProject->getConfig(); + public function getForemanHostgroup(): int + { + $aPrjConfig = $this->_oProject->getConfig(); $iForemanHostgroupDefault = (int) $aPrjConfig['deploy']['foreman']['hostgroup']; $iForemanHostgroup = (int) $aPrjConfig['phases'][$this->_sPhase]['foreman-hostgroup']; - return ($iForemanHostgroup===OPTION_DEFAULT) ? $iForemanHostgroupDefault : $iForemanHostgroup; + return ($iForemanHostgroup === OPTION_DEFAULT) ? $iForemanHostgroupDefault : $iForemanHostgroup; } - + /** * get replacement definitions from foreman + * * @global array $aConfig + * * @return bool|array */ - protected function _getForemanReplacement(){ + protected function _getForemanReplacement(): bool|array + { global $aConfig; - + $sProject = $this->_oProject->getId(); // echo "DEBUG: project id = $sProject<br>"; - - if (!$this->_sPhase){ + + if (!$this->_sPhase) { return false; } - + // abort if no foreman connection was configured if (!isset($aConfig['foreman'])) { return false; } // return already cached result - if (isset($this->_aForemanReplacements[$sProject])){ + if (isset($this->_aForemanReplacements[$sProject])) { return $this->_aForemanReplacements[$sProject]; } - + // rebuilt - $this->_aForemanReplacements[$sProject]=false; - $iEffectiveHostgroup=$this->getForemanHostgroup(); + $this->_aForemanReplacements[$sProject] = false; + $iEffectiveHostgroup = $this->getForemanHostgroup(); // abort if no hostgroup was set - if($iEffectiveHostgroup<=0){ + if ($iEffectiveHostgroup <= 0) { return false; } require_once 'foremanapi.class.php'; - $oForeman=new ForemanApi($aConfig['foreman']); - + $oForeman = new ForemanApi($aConfig['foreman']); + // get a host of this phase - $aHosts=$oForeman->read(array( + $aHosts = $oForeman->read(array( 'request' => array( - array('hosts' ), + array('hosts'), ), 'filter' => array( 'hostgroup_id' => $iEffectiveHostgroup, @@ -142,102 +162,103 @@ class configreplacement { 'response' => array('name', 'id'), )); - $sHost=''; - $aHostsOfPhase=array(); - + $sHost = ''; + $aHostsOfPhase = array(); + // HACK: phases are part of the hostname .. but not "live" ... and special handling for demo - $aPrjConfig=$this->_oProject->getConfig(); - $bIsDemo=(isset($aPrjConfig['fileprefix']) - && !strpos($aPrjConfig['fileprefix'], 'demo')===false); - $sPhase=$bIsDemo ? 'demo' : $this->_sPhase; - foreach($aHosts as $aName){ - $sName=$aName['name']; - if (($sPhase==='live' && - ( - strpos($sName, 'preview')===false - && strpos($sName, 'stage')===false - && strpos($sName, 'demo')===false + $aPrjConfig = $this->_oProject->getConfig(); + $bIsDemo = (isset($aPrjConfig['fileprefix']) + && !strpos($aPrjConfig['fileprefix'], 'demo') === false); + $sPhase = $bIsDemo ? 'demo' : $this->_sPhase; + foreach ($aHosts as $aName) { + $sName = $aName['name']; + if ( + ($sPhase === 'live' && + ( + strpos($sName, 'preview') === false + && strpos($sName, 'stage') === false + && strpos($sName, 'demo') === false + ) ) - ) - || (strpos($sName, $sPhase)) - ){ - $sHost=$sHost ? $sHost : $sName; - $aHostsOfPhase[]=$sName; + || (strpos($sName, $sPhase)) + ) { + $sHost = $sHost ? $sHost : $sName; + $aHostsOfPhase[] = $sName; } } - + // get created yaml of this host - $sUrl=$aConfig['foreman']['api']."hosts/$sHost/externalNodes?name=$sHost"; - $aData=$oForeman->makeRequest(array( - 'url'=>$sUrl, - 'method'=>'GET', + $sUrl = $aConfig['foreman']['api'] . "hosts/$sHost/externalNodes?name=$sHost"; + $aData = $oForeman->makeRequest(array( + 'url' => $sUrl, + 'method' => 'GET', )); - + // HACK: minify YAML of the host ... because it is too large for SPYC parser? - $sPart="---\n"; - $bCopy=false; - foreach(explode("\n", $aData['body']) as $sLine){ - if($bCopy){ - if (strpos($sLine, ' ')===false){ - $bCopy=false; + $sPart = "---\n"; + $bCopy = false; + foreach (explode("\n", $aData['body']) as $sLine) { + if ($bCopy) { + if (strpos($sLine, ' ') === false) { + $bCopy = false; } else { // remove leading spaces and html entities... - $sNewLine= html_entity_decode(preg_replace('/^\ \ \ \ /', '', $sLine, 1)); - $sNewLine=str_replace(''{', "'{", $sNewLine); - $sNewLine=str_replace('}'', "}'", $sNewLine); - + $sNewLine = html_entity_decode(preg_replace('/^\ \ \ \ /', '', $sLine, 1)); + $sNewLine = str_replace(''{', "'{", $sNewLine); + $sNewLine = str_replace('}'', "}'", $sNewLine); + // fix json errors - $sNewLine=str_replace(', }', " }", $sNewLine); - $sNewLine=str_replace(',}', "}", $sNewLine); - $sPart.=$sNewLine."\n"; + $sNewLine = str_replace(', }', " }", $sNewLine); + $sNewLine = str_replace(',}', "}", $sNewLine); + $sPart .= $sNewLine . "\n"; } } - if($sLine===' iml-deployment-config:'){ - $bCopy=true; + if ($sLine === ' iml-deployment-config:') { + $bCopy = true; } // echo 'DEBUG: '.($bCopy ? 'COPY':'SKIP').$sLine.'<br>'; } - if (strstr($sPart, '|-')){ + if (strstr($sPart, '|-')) { echo 'WARNING: the chars "|-" were found:<br><pre> ' - .str_replace('|-', '<span class="replace">|-</span>', $sPart) - .'</pre><br>'; + . str_replace('|-', '<span class="replace">|-</span>', $sPart) + . '</pre><br>'; } - require_once __DIR__.'./../../vendor/spyc/spyc.php'; - + require_once __DIR__ . './../../vendor/spyc/spyc.php'; + // echo 'DEBUG: <pre>'.print_r(spyc_load($aData['body']), 1).'</pre>'; - $aYaml=spyc_load($sPart); + $aYaml = spyc_load($sPart); // echo 'DEBUG: <pre>'.print_r($aYaml, 1).'</pre>'; - - if (!isset($aYaml[$sProject])){ + + if (!isset($aYaml[$sProject])) { return false; } - foreach ($aYaml as $sPrjId=>$aProject){ - $aReturn=array(); - foreach ($aProject as $sFile=>$aParams){ - $aReturn[$sFile]=array(); - if (isset($aParams['target'])){ - $aReturn[$sFile]['target']=$aParams['target']; + foreach ($aYaml as $sPrjId => $aProject) { + $aReturn = array(); + foreach ($aProject as $sFile => $aParams) { + $aReturn[$sFile] = array(); + if (isset($aParams['target'])) { + $aReturn[$sFile]['target'] = $aParams['target']; } - if (isset($aParams['replace'])){ - $aReplace=json_decode($aParams['replace'], 1); - $aReturn[$sFile]['replace_source']=$aReplace; - foreach ($aReplace as $sVarname=>$value){ - if (isset($value['_'.$this->_sPhase.'_'])){ - $value=$value['_'.$this->_sPhase.'_']; + if (isset($aParams['replace'])) { + $aReplace = json_decode($aParams['replace'], 1); + $aReturn[$sFile]['replace_source'] = $aReplace; + foreach ($aReplace as $sVarname => $value) { + if (isset($value['_' . $this->_sPhase . '_'])) { + $value = $value['_' . $this->_sPhase . '_']; } - $aReturn[$sFile]['replace'][$sVarname]=$value; + $aReturn[$sFile]['replace'][$sVarname] = $value; } } } - $this->_aForemanReplacements[$sPrjId]=array( - 'phase'=>$this->_sPhase, - 'rules'=>$aReturn, - 'host'=>$sHost, - 'yaml'=>$sPart, - 'hostgroup'=>$iEffectiveHostgroup, - 'hostsall'=>$aHosts, - 'hostsphase'=>$aHostsOfPhase, + $this->_aForemanReplacements[$sPrjId] = array( + 'phase' => $this->_sPhase, + 'rules' => $aReturn, + 'host' => $sHost, + 'yaml' => $sPart, + 'hostgroup' => $iEffectiveHostgroup, + 'hostsall' => $aHosts, + 'hostsphase' => $aHostsOfPhase, ); } @@ -245,45 +266,47 @@ class configreplacement { } /** - * get foreman base url ... if foreman was activated in the setup + * Get foreman base url ... if foreman was activated in the setup * * @global array $aConfig ci config * @return string */ - private function _getForemanBaseUrl(){ + private function _getForemanBaseUrl(): string + { global $aConfig; return (isset($aConfig['foreman']['api'])) ? $aConfig['foreman']['api'] : false ; } - + /** * Get html code for links to edit each host of the current phase in foreman * It returns false if foreman is not activated or there is no phase. * * @return bool|string */ - public function getForemanlink2Host(){ - $sForemanurl=$this->_getForemanBaseUrl(); - if (!$sForemanurl){ + public function getForemanlink2Host(): bool|string + { + $sForemanurl = $this->_getForemanBaseUrl(); + if (!$sForemanurl) { return false; } - $aTmp=$this->_getForemanReplacement(); - if (!isset($aTmp['hostsphase'])){ + $aTmp = $this->_getForemanReplacement(); + if (!isset($aTmp['hostsphase'])) { return false; } require_once 'htmlguielements.class.php'; - $oHtml=new htmlguielements(); - $sReturn=''; - foreach ($aTmp['hostsphase'] as $sHost){ - $sReturn.=$oHtml->getLinkButton(array( - 'href'=>$sForemanurl.'hosts/'.$aTmp['host'], - 'target'=>'_foreman', - 'title'=>t('edit'), - 'icon'=>'host', - 'label'=>t('host').' '.$aTmp['host'], - )).' '; + $oHtml = new htmlguielements(); + $sReturn = ''; + foreach ($aTmp['hostsphase'] as $sHost) { + $sReturn .= $oHtml->getLinkButton(array( + 'href' => $sForemanurl . 'hosts/' . $aTmp['host'], + 'target' => '_foreman', + 'title' => t('edit'), + 'icon' => 'host', + 'label' => t('host') . ' ' . $aTmp['host'], + )) . ' '; } return $sReturn; } @@ -294,61 +317,66 @@ class configreplacement { * * @return bool|string */ - public function getForemanlink2Hostgroup(){ - $iEffectiveHostgroup=$this->getForemanHostgroup(); - if($iEffectiveHostgroup<=0){ + public function getForemanlink2Hostgroup(): bool|string + { + $iEffectiveHostgroup = $this->getForemanHostgroup(); + if ($iEffectiveHostgroup <= 0) { return false; } - $sForemanurl=$this->_getForemanBaseUrl(); - if (!$sForemanurl){ + $sForemanurl = $this->_getForemanBaseUrl(); + if (!$sForemanurl) { return false; } require_once 'htmlguielements.class.php'; - $oHtml=new htmlguielements(); + $oHtml = new htmlguielements(); return $oHtml->getLinkButton(array( - 'href'=>$sForemanurl.'hostgroups/'.$iEffectiveHostgroup.'/edit', - 'target'=>'_foreman', - 'title'=>t('edit'), - 'icon'=>'hostgroup', - 'label'=>sprintf(t('foreman-hostgroup-id'), $iEffectiveHostgroup), + 'href' => $sForemanurl . 'hostgroups/' . $iEffectiveHostgroup . '/edit', + 'target' => '_foreman', + 'title' => t('edit'), + 'icon' => 'hostgroup', + 'label' => sprintf(t('foreman-hostgroup-id'), $iEffectiveHostgroup), )); - + } - + /** * get replacements in foreman * @return bool|array */ - public function getForemanReplacements(){ + public function getForemanReplacements(): bool|array + { return $this->_getForemanReplacement(); } - + /** * switch to a project * @param string $sProject project id * @param string $sPhase optional: a phase; one of preview|stage|live + * @return boolean */ - public function setProject($sProject, $sPhase=false){ + public function setProject(string $sProject, string $sPhase = ''): bool + { $this->_oProject = new project($sProject); - $this->_aForemanReplacements=false; + $this->_aForemanReplacements = []; $this->setPhase($sPhase); return true; } - + /** - * set a phase of a project + * Set a phase of a project * @param string $sPhase name of valid phase * @return boolean */ - public function setPhase($sPhase=false){ - $this->_sPhase=false; - if (!$sPhase){ - $sPhase=$this->_oProject->getNextPhase(false); + public function setPhase(string $sPhase = ''): bool + { + $this->_sPhase = false; + if (!$sPhase) { + $sPhase = $this->_oProject->getNextPhase(false); } if (!$sPhase || !$this->_oProject->isActivePhase($sPhase)) { return false; } - $this->_sPhase=$sPhase; + $this->_sPhase = $sPhase; return true; } } diff --git a/public_html/deployment/classes/foremanapi.class.php b/public_html/deployment/classes/foremanapi.class.php index 3ecb6add339789032a42088e71c1e625a30f9ea4..4365b1a12907b2b53cec1d874663273a02a7db37 100644 --- a/public_html/deployment/classes/foremanapi.class.php +++ b/public_html/deployment/classes/foremanapi.class.php @@ -4,6 +4,8 @@ * * foreman access to API * + * @deprecated Foreman was too much hartcoded. TODO: remove this class + * * @example * in project class * $oForeman=new ForemanApi($this->_aConfig['foreman']);