diff --git a/public_html/deployment/classes/rollout_base.class.php b/public_html/deployment/classes/rollout_base.class.php index ee86f5de1eb3acea4f935351f1c0918ab9a1d80f..e54e97e09e2afdd948344a16b46337f250e1755f 100644 --- a/public_html/deployment/classes/rollout_base.class.php +++ b/public_html/deployment/classes/rollout_base.class.php @@ -1,5 +1,6 @@ <?php require_once 'rollout.interface.php'; +require_once 'cache.class.php'; /** * rollout_base class that will beextended in a rollout plugin @@ -117,6 +118,30 @@ class rollout_base implements iRolloutplugin{ : 'plugins[rollout]['.$this->getId().']' ); } + + /** + * get Data from a callback function and store it in a cache + * The response type depends on the callback function + * + * @param string $sFunctionname name of the callback function + * @param string $sKey name of the key; "project" or name of phase + * @param integr $iTtl ttl value = how many seconds to use cache + * @param integr $iTtlOnError ttl value = how many seconds to use cache if there was no response + * @return type + */ + protected function _getCallback($sFunctionname, $sKey, $iTtl=15,$iTtlOnError=10){ + $oCache=new AhCache('rollout-'.$this->getId(), 'callback-'.$sFunctionname.'-'.$sKey); + if($oCache->isExpired()){ + $aMydata= call_user_func(array($this, $sFunctionname)); + // echo "$sFunctionname fresh ".($aMydata ? "OK": "false")." - storing for $iTtl sec<br>"; + $oCache->write($aMydata, ($aMydata ? $iTtl : $iTtlOnError)); + } else { + // echo "$sFunctionname from cache ... ".$oCache->iExpired()." sec <br>"; + $aMydata=$oCache->read(); + } + // echo '<pre>'.print_r($aMydata, 1).'</pre>'; die(__METHOD__); + return $aMydata; + } /** * render a form by given form elementes * @param array $aFormdata array of form elements @@ -186,6 +211,27 @@ class rollout_base implements iRolloutplugin{ ? htmlentities($aDefaultValues[$sVarname]) : (isset($aVarinfos['default']) ? $aVarinfos['default'] : 'N.A.') ); + + // if a callback was set for this variable + if(isset($aVarinfos['callback'])){ + $aCallbackData=$this->_getCallback( + $aVarinfos['callback'], + (isset($aVarinfos['per_scope']) && $aVarinfos['per_scope'] ? $sKey : ''), + (isset($aVarinfos['ttl']) ? $aVarinfos['ttl'] : 60) + ); + if(!$aCallbackData){ + $aVarinfos['type']='text'; + } else { + $aEffectiveConfig=$this->getConfig($sPhase); + // echo $sKey.' ... '; print_r($aEffectiveConfig[$sVarname]); echo '<br>'; + if(isset($aEffectiveConfig[$sVarname]) && isset($aCallbackData[$aEffectiveConfig[$sVarname]])){ + $aCallbackData[$aEffectiveConfig[$sVarname]]['selected']='selected'; + // wenn value = defaultvalue, dann value auf '' setzen + } + // print_r($aCallbackData[$sVarname]); echo "<br>"; + } + // echo '<pre>'.$sCallbackfunktion .' = '. print_r($aMydata,1 ).'</pre>'; + } switch ($aVarinfos['type']) { case "password": $sMyPlaceholder=(isset($aDefaultValues[$sVarname]) @@ -205,6 +251,20 @@ class rollout_base implements iRolloutplugin{ 'placeholder' => $sMyPlaceholder ); break; + case "select": + $aOptions=$aCallbackData; + $aFormdata[]=array( + 'type' => $aVarinfos['type'], + 'name' => $sPrefixName.'['.$sVarname.']', + 'label' => $this->_t($sVarname.'-label'), + 'title' => $this->_t($sVarname.'-hint'), + + 'validate' => 'isastring', + 'options' => $aOptions, + + 'placeholder' => $sMyPlaceholder + ); + break; case "text": $aFormdata[]=array( 'type' => $aVarinfos['type'], diff --git a/public_html/deployment/plugins/rollout/awx/info.json b/public_html/deployment/plugins/rollout/awx/info.json index 79294a6d96722625da4cd04c12ebd2eff73b9135..611f37b8bef10329dcea83c6aead4fbb83b5d52a 100644 --- a/public_html/deployment/plugins/rollout/awx/info.json +++ b/public_html/deployment/plugins/rollout/awx/info.json @@ -22,8 +22,11 @@ "default": "example: my-very-secret-password" }, "jobtemplate": { - "type": "text", - "default": "36" + "type": "select", + "default": "36", + "callback": "getAwxJobTemplates", + "ttl": 120, + "per_scope": false }, "tags": { "type": "text", @@ -38,12 +41,15 @@ "extravars": { "type": "text", "default": "example: { data in JSON syntax here }" - } + } }, "phase": { "inventory": { - "type": "text", - "default": "example: hosts/Appname/preview" + "type": "select", + "default": "example: 5", + "callback": "getAwxInventories", + "ttl": 10, + "per_scope": false } } } diff --git a/public_html/deployment/plugins/rollout/awx/rollout_awx.php b/public_html/deployment/plugins/rollout/awx/rollout_awx.php index 2aa41d829b95f3ab65ca52cd68f38e32d80f173b..5c3e4ffab5137130b858056cca7710e8cf950b3f 100644 --- a/public_html/deployment/plugins/rollout/awx/rollout_awx.php +++ b/public_html/deployment/plugins/rollout/awx/rollout_awx.php @@ -18,6 +18,128 @@ class rollout_awx extends rollout_base { return true; } + /** + * 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 _httpRequest($aRequest=false, $iTimeout = 5) { + + if (!function_exists("curl_init")) { + die("ERROR: PHP CURL module is not installed."); + } + $aConfig=$this->getConfig(); + + + $ch = curl_init($aConfig['url'].$aRequest['url']); + + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $aRequest['method']); + if ($this->_aRequest['method']==='POST'){ + curl_setopt($ch, CURLOPT_POSTFIELDS, $aRequest['postdata']); + } + + if ($aConfig['user']){ + curl_setopt($ch, CURLOPT_USERPWD, $aConfig['user'].':'.$aConfig['password']); + } + + if (isset($aConfig['ignore-ssl-error']) && $aConfig['ignore-ssl-error']){ + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); + } + + curl_setopt($ch, CURLOPT_TIMEOUT, $iTimeout); + curl_setopt($ch, CURLOPT_USERAGENT, 'IML Deployment :: rollout plugin awx ' . __CLASS__); + curl_setopt($ch, CURLOPT_HEADER,1); + curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); + + $res = curl_exec($ch); + + $aReturn=array('info'=>curl_getinfo($ch), 'error'=>curl_error($ch)); + curl_close($ch); + + $sHeader=substr($res, 0, $aReturn['info']['header_size']); + $aReturn['header']=explode("\n", $sHeader); + $aReturn['body']=str_replace($sHeader, "", $res); + + // print_r($aReturn); + return $aReturn; + } + + + + /** + * get AWX Job Templates and return them as array for select box + * [id] => array('value' => [ID], 'label' => [PLAYBOOK] [ID]) + * @return array + */ + static public function getAwxInventories(){ + $aResponse=$this->_httpRequest(array( + 'url'=>'/inventories/?order_by=name', + 'method'=>'GET', + ) + ); + + if(!isset($aResponse['info']['http_code']) || $aResponse['info']['http_code']!==200){ + return false; + } + + $aData=json_decode($aResponse['body'], 1); + $aReturn=array(); + + foreach ($aData['results'] as $aItem){ + $aReturn[$aItem['id']]= [ + 'value'=>$aItem['id'], + 'label'=>$aItem['name'].' (id: '.$aItem['id'].')' + ]; + } + /* + echo '<pre>RETURN: '; + print_r($aReturn); + die(__METHOD__); + */ + + return $aReturn; + } + /** + * get AWX Job Templates and return them as array for select box + * [id] => array('value' => [ID], 'label' => [PLAYBOOK] [ID]) + * @return array + */ + static public function getAwxJobTemplates(){ + $aResponse=$this->_httpRequest(array( + 'url'=>'/job_templates/?order_by=playbook', + 'method'=>'GET', + ) + ); + + if(!isset($aResponse['info']['http_code']) || $aResponse['info']['http_code']!==200){ + return false; + } + + $aData=json_decode($aResponse['body'], 1); + $aReturn=array(); + + foreach ($aData['results'] as $aItem){ + $aReturn[$aItem['id']]= [ + 'value'=>$aItem['id'], + 'label'=>$aItem['playbook'].' (id: '.$aItem['id'].')' + ]; + } + /* + echo '<pre>RETURN: '; + print_r($aReturn); + die(__METHOD__); + */ + + return $aReturn; + } + /** * check access to a deploy target */