diff --git a/public_html/deployment/classes/deploy-foreman.class.php b/public_html/deployment/classes/deploy-foreman.class.php deleted file mode 100644 index 6964963958790d985af20af850aead1d72d23323..0000000000000000000000000000000000000000 --- a/public_html/deployment/classes/deploy-foreman.class.php +++ /dev/null @@ -1,496 +0,0 @@ -<?php -/** - * deployForeman - * - * foreman access to API - * - * @example - * in project class - * $oForeman=new deployForeman($this->_aConfig['foreman']); - * - * // enable debugging - * $oForeman->setDebug(1); - * - * // self check - * $oForeman->selfcheck(); die(__FUNCTION__); - * - * // read operating systems and get id and title only - * $aForemanHostgroups=$oForeman->read(array( - * 'request'=>array( - * array('operatingsystems'), - * ), - * 'response'=>array( - * 'id','title' - * ), - * )); - * - * // read details for operating systems #4 - * $aForemanHostgroups=$oForeman->read(array( - * 'request'=>array( - * array('operatingsystems', 4), - * ), - * )); - * - * - * $aOptions ... can contain optional subkeys - * - request - * [] list of array(keyword [,id]) - * - filter (array) - * - search (string) - * - page (string) - * - per_page (string) - * - response (array) - * - list of keys, i.e. array('id', 'title') - - * @author hahn - */ -class deployForeman { - - protected $_aCfg=array(); - protected $_bDebug = false; - - protected $_aAllowedUrls=array( - 'api/'=>array( - ''=>array(), - 'architectures'=>array(), - 'audits'=>array('methods'=>array('GET')), - 'auth_source_ldaps'=>array(), - 'bookmarks'=>array(), - 'common_parameters'=>array(), - 'compliance'=>array(), - 'compute_attributes'=>array(), - 'compute_profiles'=>array(), - 'compute_resources'=>array(), - 'config_groups'=>array(), - 'config_reports'=>array(), - 'config_templates'=>array(), - 'dashboard'=>array('methods'=>array('GET')), - 'domains'=>array(), - 'environments'=>array(), - 'fact_values'=>array(), - 'filters'=>array(), - 'hosts'=>array(), - 'hostgroups'=>array(), - 'job_invocations'=>array(), - 'job_templates'=>array(), - 'locations'=>array(), - 'mail_notifications'=>array(), - 'media'=>array(), - 'models'=>array(), - 'operatingsystems'=>array('methods'=>array('GET')), - 'orchestration'=>array(), - 'organizations'=>array(), - 'permissions'=>array(), - 'plugins'=>array(), - 'provisioning_templates'=>array(), - 'ptables'=>array(), - 'puppetclasses'=>array(), - 'realms'=>array(), - 'remote_execution_features'=>array(), - 'reports'=>array(), - 'roles'=>array(), - 'settings'=>array(), - 'smart_class_parameters'=>array(), - 'smart_proxies'=>array(), - 'smart_variables'=>array(), - 'statistics'=>array('methods'=>array('GET')), - 'status'=>array('methods'=>array('GET')), - 'subnets'=>array(), - 'template_combinations'=>array(), - 'template_kinds'=>array('methods'=>array('GET')), - 'templates'=>array(), - 'usergroups'=>array(), - 'users'=>array(), - // ... - ), - 'api/v2/'=>array( - 'discovered_hosts'=>array(), - 'discovery_rules'=>array(), - ), - 'foreman_tasks/api/'=>array( - 'recurring_logics'=>array(), - 'tasks'=>array(), - ), - ); - - - protected $_aRequest=array(); - - - // ---------------------------------------------------------------------- - // constructor - // ---------------------------------------------------------------------- - - - public function __construct($aCfg) { - if(!isset($aCfg['api'])){ - die("ERROR: class ".__CLASS__." must be initialized with an array containing api config for foreman."); - return false; - } - $this->_aCfg=$aCfg; - - return true; - } - - // ---------------------------------------------------------------------- - // private functions - // ---------------------------------------------------------------------- - /** - * add a log messsage - * @global object $oLog - * @param string $sMessage messeage text - * @param string $sLevel warnlevel of the given message - * @return bool - */ - protected function log($sMessage, $sLevel = "info") { - global $oCLog; - return $oCLog->add(basename(__FILE__) . " class " . __CLASS__ . " - " . $sMessage, $sLevel); - } - - /** - * search url prefix in $this->_aAllowedUrls by given key - * @param type $sFunction - * @return type - */ - protected function _guessPrefixUrl($sFunction=false){ - $sReturn=''; - if (!$sFunction){ - $sFunction=$this->_aRequest['request'][0][0]; - } - foreach($this->_aAllowedUrls as $sPrefix=>$aUrls){ - foreach(array_keys($aUrls) as $sKeyword){ - if ($sFunction==$sKeyword){ - $sReturn=$sPrefix; - break; - } - } - } - return $sReturn; - } - - /** - * generate an url for foreman API request based on option keys - * @return string - */ - protected function _generateUrl(){ - if(!isset($this->_aRequest['request'])){ - die('ERROR: missing key [request]'); - } - $sReturn=$this->_aCfg['api']; - - $sPrefix=$this->_guessPrefixUrl(); - $sReturn.=$sPrefix; - - foreach($this->_aRequest['request'] as $aReqItem){ - if (!isset($this->_aAllowedUrls[$sPrefix][$aReqItem[0]])){ - echo 'WARNING: wrong item: [' . $aReqItem[0]."]<br>\n"; - } - $sReturn.=$aReqItem[0] ? $aReqItem[0].'/' : ''; - if(count($aReqItem)>1){ - $sReturn.=(int)$aReqItem[1].'/'; - } - } - return $sReturn; - } - - /** - * add parameter for search and paging in an foreman API URL - * - * @return string - */ - protected function _generateParams(){ - if (!isset($this->_aRequest['filter'])){ - return ''; - } - $sReturn='?'; - - // TODO: "sort by" and "sort order" ... need to be added here ... somehow - foreach(array('page', 'per_page', 'search') as $sParam){ - if (isset($this->_aRequest['filter'][$sParam])){ - $sReturn.='&'.$sParam.'='.urlencode($this->_aRequest['filter'][$sParam]); - } - } - return $sReturn; - } - - /** - * make an http get request and return the response body - * it is called by _makeRequest - * $aRequest contains subkeys - * - url - * - method; one of GET|POST|PUT|DELETE - * - postdata; for POST only - * - * @param array $aRequest arrayurl for Foreman API - * @return string - */ - protected function _httpCall($aRequest=false, $iTimeout = 5) { - if ($aRequest){ - $this->_aRequest=$aRequest; - } - $this->log(__FUNCTION__ . " start <pre>".print_r($this->_aRequest,1)."</pre>"); - if (!function_exists("curl_init")) { - die("ERROR: PHP CURL module is not installed."); - } - - $sApiUser=isset($this->_aCfg['user']) ? $this->_aCfg['user'] : false; - $sApiPassword=isset($this->_aCfg['password']) ? $this->_aCfg['password'] : false; - - // $sFullUrl=$sApiUrl.$this->_aRequest['url']; - $sFullUrl=$this->_aRequest['url']; - $this->log(__FUNCTION__ . " ".$this->_aRequest['method']." " . $this->_aRequest['url']); - $ch = curl_init($this->_aRequest['url']); - - curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->_aRequest['method']); - if ($this->_aRequest['method']==='POST'){ - curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_aRequest['postdata']); - } - curl_setopt($ch, CURLOPT_HEADER, 1); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); - curl_setopt($ch, CURLOPT_TIMEOUT, $iTimeout); - curl_setopt($ch, CURLOPT_USERAGENT, 'IML Deployment GUI :: ' . __CLASS__); - if ($sApiUser){ - curl_setopt($ch, CURLOPT_USERPWD, $sApiUser.":".$sApiPassword); - } - - $res = curl_exec($ch); - $aReturn=array('info'=>curl_getinfo($ch), 'error'=>curl_error($ch)); - curl_close($ch); - $this->log(__FUNCTION__ . " status ".$aReturn['info']['http_code'].' '.$this->_aRequest['method']." $sFullUrl"); - - $sHeader=substr($res, 0, $aReturn['info']['header_size']); - $aReturn['header']=explode("\n", $sHeader); - $aReturn['body']=str_replace($sHeader, "", $res); - - return $aReturn; - } - - /** - * write debug infos if enabled - * @param string $sMessage - * @return boolean - */ - protected function _writeDebug($sMessage){ - if ($this->_bDebug){ - echo "DEBUG :: ".__CLASS__." :: $sMessage<br>\n"; - } - return true; - } - - // ---------------------------------------------------------------------- - // public functions :: low level - // ---------------------------------------------------------------------- - - /** - * make an http(s) request to foreman and scan result for http code and - * content in response json; method returns an array with subkeys - * - info: curl info array - * - error: curl error message - * - header: http response headers - * - body: http response body - * - _json: parsed json data from response body - * - _OK: flag if result is OK and complete - * - _status: info - * - * * $aRequest contains subkeys - * - function --> to extract method and generate url - * - method; one of GET|POST|PUT|DELETE - * - postdata; for POST only - - * @param array $aRequest arrayurl for Foreman API - * @return array - */ - public function makeRequest($aRequest=false) { - if ($aRequest){ - $this->_aRequest=$aRequest; - } - $sStatus='unknown'; - $bOk=false; - - - // prevent missing data because of paging - if ($this->_aRequest['method']==='GET' && !isset($this->_aRequest['filter']['per_page'])){ - $this->_aRequest['filter']['per_page']=1000; - } - // TODO check postdata - if ($this->_aRequest['method']==='POST' && ( - !isset($this->_aRequest['postdata']) - || !is_array($this->_aRequest['postdata']) - || !count($this->_aRequest['postdata']) - ) - ){ - die("ERROR in ".__CLASS__."::".__FUNCTION__.": missing data to make a POST request"); - } - - $this->_aRequest['url']=$this->_generateUrl().$this->_generateParams(); - - // ----- request - $this->_writeDebug(__FUNCTION__ . ' start request <pre>'.print_r($this->_aRequest,1).'</pre>'); - $aReturn=$this->_httpCall(); - - // ----- check result - // check status - $iStatuscode=$aReturn['info']['http_code']; - if ($iStatuscode===0){ - $sStatus='wrong host'; - } - if ($iStatuscode>=200 && $iStatuscode<400){ - $sStatus='OK'; - $bOk=true; - } - if ($iStatuscode>=400 && $iStatuscode<500){ - $sStatus='error'; - } - if ($iStatuscode===404){ - $sStatus='wrong url'; - } - - // check result json - if($bOk){ - $aJson=json_decode($aReturn['body'], 1); - if (is_array($aJson)){ - if (isset($aJson['total']) && $aJson['total'] > $aJson['per_page']){ - $bOk=false; - $sStatus='Http OK, but incomplete results (paging)'; - } - $aReturn['_json']=$aJson; - } else { - $bOk=false; - $sStatus='Http OK, but wrong response'; - } - } - $aReturn['_OK']=$bOk; - $aReturn['_status']=$sStatus; - $this->_writeDebug(__FUNCTION__ . ' result of request <pre>'.print_r($aReturn,1).'</pre>'); - - return $aReturn; - } - - /** - * filter output for the response based on values $this->_aRequest['response'] - * @param array $aData response of $this->makeRequest(); - * @return array - */ - protected function _filterOutput($aData){ - if(!isset($this->_aRequest['response'])){ - return $aData; - } - $aTmp=isset($aData['_json']['results']) ? $aData['_json']['results'] : array($aData['_json']); - if(!count($aTmp)){ - return array(); - } - $aReturn=array(); - foreach($aTmp as $aItem){ - $aReturn[] = array_filter($aItem, function($key) { - return array_search($key, $this->_aRequest['response']) !==false; - }, ARRAY_FILTER_USE_KEY - ); - } - return $aReturn; - } - - - // ---------------------------------------------------------------------- - // public foreman functions - // ---------------------------------------------------------------------- - - /** - * enable/ disable debugging - * @param boolean $bNewDebugFlag new value; true|false - * @return boolean - */ - public function setDebug($bNewDebugFlag){ - return $this->_bDebug=$bNewDebugFlag; - } - - /** - * check for missing config entries - * @return type - */ - public function selfcheck() { - $sOut=''; - $sWarning=''; - $sOut.="<h1>selfcheck</h1>"; - $aApi=$this->read(array('request'=>array(array('')))); - if($aApi['_OK']){ - foreach($aApi['_json']['links'] as $sKey=>$aCalls){ - $sOut.="<h2>$sKey</h2><ul>"; - foreach ($aCalls as $sLabel=>$sUrl){ - $sOut.="<li>$sLabel .. $sUrl "; - $aTmp=preg_split('#\/#', $sUrl); - $sDir2=count($aTmp)>2 ? $aTmp[2] : '??'; - $sDir3=count($aTmp)>3 ? $aTmp[3] : '??'; - $sOut.="..... " - . ($this->_guessPrefixUrl($sDir2).$this->_guessPrefixUrl($sDir3) - ?'<span style="background:#cfc">OK</span>' - :'<span style="background:#fcc">miss</span>' - ) . ' ' . $sDir2.', '.$sDir3 . "</li>\n"; - if (!($this->_guessPrefixUrl($sDir2).$this->_guessPrefixUrl($sDir3))){ - $sWarning.="<li>$sKey - $sLabel - $sUrl</li>"; - } - } - $sOut.="</ul>"; - } - } else { - $sOut.='ERROR: unable to connect to foreman or missing permissions.<br>'; - } - if ($sWarning){ - echo 'WARNINGS:<ol>'.$sWarning.'</ol>'; - } - echo $sOut; - return true; - } - - // ---------------------------------------------------------------------- - // public foreman API CRUD functions - // ---------------------------------------------------------------------- - - /** - * TODO: create - * @param array $aOptions - */ - public function create($aOptions){ - } - /** - * GETTER - * $aOptions ... can contain optional subkeys - * - request - * [] list of array(keyword [,id]) - * - filter (array) - * - search (string) - * - page (string) - * - per_page (string) - * - response (array) - * - list of keys, i.e. array('id', 'title') - * - * @param array $aOptions - * @return array - */ - public function read($aOptions){ - $this->_aRequest=$aOptions; - $this->_aRequest['method']='GET'; - $aData=$this->makeRequest(); - if (!$aData['_OK']){ - return false; - } - return $this->_filterOutput($aData); - } - - /** - * TODO - * @param type $aOptions - */ - public function update($aOptions){ - - } - - /** - * TODO - * @param type $aOptions - */ - public function delete($aOptions){ - - } - -}