diff --git a/public_html/deployment/classes/formgen.class.php b/public_html/deployment/classes/formgen.class.php
index 7ca0a12b2389eeddd55be692fea0c535580cc843..0e1ea574d1ed829579ef5bc0d279687aab368dc9 100644
--- a/public_html/deployment/classes/formgen.class.php
+++ b/public_html/deployment/classes/formgen.class.php
@@ -164,7 +164,7 @@ class formgen {
                     $sFormElement.="\n".'<div class="checkbox">';
                     $s = preg_replace('/\W/iu', '', $sId . $idOption);
                     $sOptionId = preg_replace('/[äöüß]/i', '', $s);
-                    $sFormElement.='    <input type="checkbox" id="' . $sOptionId . '" value="' . $idOption . '" ';
+                    $sFormElement.='    <input type="checkbox" id="' . $sOptionId . '" value="' . (isset($aOptionData["value"]) ? $aOptionData["value"] : $idOption) . '" ';
                     $sFormElement.=$this->_addHtmlAtrributes(explode(",", "$sDefaultAttributes,checked"), $aOptionData);
                     $sFormElement.=' name="' . $elementData["name"] . '[]"';
                     $sFormElement.='/><label for="' . $sOptionId . '">' . $aOptionData["label"] . '</label></div>';
@@ -200,7 +200,7 @@ class formgen {
                     $sFormElement.="\n".'<div class="radio">';
                     $s = preg_replace('/\W/iu', '', $sId . $idOption);
                     $sOptionId = preg_replace('/[äöüß]/i', '', $s);
-                    $sFormElement.='    <input type="radio" id="' . $sOptionId . '" value="' . $idOption . '" ';
+                    $sFormElement.='    <input type="radio" id="' . $sOptionId . '" value="' . (isset($aOptionData["value"]) ? $aOptionData["value"] : $idOption) . '" ';
                     $sFormElement.=$this->_addHtmlAtrributes(explode(",", "$sDefaultAttributes,checked,disabled"), $aOptionData);
                     $sFormElement.=" " . $this->_addHtmlAtrributes(explode(",", "name"), $elementData);
                     $sFormElement.='/><label for="' . $sOptionId . '">' . $aOptionData["label"] . '</label></div>';
@@ -231,7 +231,7 @@ class formgen {
                 foreach ($elementData["options"] as $idOption => $aOptionData) {
                     $s = preg_replace('/\W/iu', '', $sId . $idOption);
                     $sOptionId = preg_replace('/[äöüß]/i', '', $s);
-                    $sFormElement.='    <option value="' . $idOption . '" ';
+                    $sFormElement.='    <option value="' . (isset($aOptionData["value"]) ? $aOptionData["value"] : $idOption) . '" ';
                     $sFormElement.=$this->_addHtmlAtrributes(explode(",", "$sDefaultAttributes,selected"), $aOptionData);
                     $sFormElement.='>' . $aOptionData["label"] . '</option>' . "\n";
                 }
diff --git a/public_html/deployment/classes/rollout_base.class.php b/public_html/deployment/classes/rollout_base.class.php
index ee86f5de1eb3acea4f935351f1c0918ab9a1d80f..2a7e6017503c4448a92fa0b39fff4335b929dc67 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,39 @@ 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>';
+                    
+                    // mark entry as active ... for select and radio
+                    if(isset($aEffectiveConfig[$sVarname]) && isset($aCallbackData[$aEffectiveConfig[$sVarname]])){
+                        $aCallbackData[$aEffectiveConfig[$sVarname]]['selected']='selected';
+                        $aCallbackData[$aEffectiveConfig[$sVarname]]['checked']='checked';
+                        $aCallbackData[$aEffectiveConfig[$sVarname]]['label'].=' <<<';
+                    } elseif ($aVarinfos['type']==='select') {
+                        $aCallbackData=array_merge(array('NO_SELECTED_ITEM_YET'=>array('value'=>'', 'label'=>'...')), $aCallbackData);
+                    }
+ 
+                    // wenn value = defaultvalue, dann value auf '' setzen (damit bei Default vom Scope
+                    // davor ein Leerstring übergeben wird - analog onfocusout im Text Input
+                    if (isset($aCallbackData[$aDefaultValues[$sVarname]])){
+                        $aCallbackData[$aDefaultValues[$sVarname]]['value']='';
+                        $aCallbackData[$aDefaultValues[$sVarname]]['label'].=' (*)';
+                    } 
+                    // print_r($aCallbackData[$sVarname]); echo "<br>";
+                }
+                // echo '<pre>'.$sCallbackfunktion .' = '. print_r($aMydata,1 ).'</pre>';
+            }
             switch ($aVarinfos['type']) {
                 case "password":
                     $sMyPlaceholder=(isset($aDefaultValues[$sVarname]) 
@@ -201,10 +259,24 @@ class rollout_base implements iRolloutplugin{
                         // 'required' => 'required',
                         'validate' => 'isastring',
                         // 'size' => 25,
-                        // 'placeholder' => (isset($this->_aCfgGlobal[$sVarname]) ? $this->_aCfgGlobal[$sVarname] : '') . ' | '.$aDefaultValues[$sVarname],
                         'placeholder' => $sMyPlaceholder       
                     );
                     break;
+                case "select":
+                case "radio":
+                    $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'],
@@ -221,7 +293,6 @@ class rollout_base implements iRolloutplugin{
                         // 'required' => 'required',
                         'validate' => 'isastring',
                         // 'size' => 25,
-                        // 'placeholder' => (isset($this->_aCfgGlobal[$sVarname]) ? $this->_aCfgGlobal[$sVarname] : '') . ' | '.$aDefaultValues[$sVarname],
                         'placeholder' => $sMyPlaceholder       
                     );
                     break;
diff --git a/public_html/deployment/plugins/rollout/awx/info.json b/public_html/deployment/plugins/rollout/awx/info.json
index 79294a6d96722625da4cd04c12ebd2eff73b9135..c1c0ec9ddc37a5ea8cf71a8887c62cebec6f09d5 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": "",
+                "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": "",
+                "callback": "getAwxInventories",
+                "ttl": 120,
+                "per_scope": false
             }     
         }
     }
diff --git a/public_html/deployment/plugins/rollout/awx/lang_de.json b/public_html/deployment/plugins/rollout/awx/lang_de.json
index 427a3f6f5a2df71bbe95d08a21c0b83c52692d66..ffa4d4efc03c9966d75805440b11a5bce1269d2f 100644
--- a/public_html/deployment/plugins/rollout/awx/lang_de.json
+++ b/public_html/deployment/plugins/rollout/awx/lang_de.json
@@ -18,7 +18,7 @@
     "extravars-label": "Extravars",
     "extravars-hint": "Extravars als JSON Syntax.",
 
-    "inventory-label": "Inventory ID",
+    "inventory-label": "Inventory",
     "inventory-hint": "AWX inventory zum Setzen der Phase und der zu installierenden Hosts",
 
     "endoffile": ""
diff --git a/public_html/deployment/plugins/rollout/awx/lang_en.json b/public_html/deployment/plugins/rollout/awx/lang_en.json
index 43b46920bcb402333d6841e7ab6d792b6709da16..e662c504847f94bf811cb3dff400a45cec0d4581 100644
--- a/public_html/deployment/plugins/rollout/awx/lang_en.json
+++ b/public_html/deployment/plugins/rollout/awx/lang_en.json
@@ -18,7 +18,7 @@
     "extravars-label": "Extravars",
     "extravars-hint": "Extravars in JSON syntax",
 
-    "inventory-label": "Inventory ID",
+    "inventory-label": "Inventory",
     "inventory-hint": "AWX inventory to define phase and set of hosts",
 
     "endoffile": ""
diff --git a/public_html/deployment/plugins/rollout/awx/rollout_awx.php b/public_html/deployment/plugins/rollout/awx/rollout_awx.php
index 2aa41d829b95f3ab65ca52cd68f38e32d80f173b..7ec6f2dcbbdccc55fb6aaa1c42afff493c27894c 100644
--- a/public_html/deployment/plugins/rollout/awx/rollout_awx.php
+++ b/public_html/deployment/plugins/rollout/awx/rollout_awx.php
@@ -6,7 +6,7 @@
  * 
  * Run an Https POST request to AWX
  *
- * @author axel
+ * @author <axel.hahn@iml.unibe.ch>
  */
 class rollout_awx extends rollout_base {
 
@@ -18,6 +18,117 @@ 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 inventories and return them as array for select box
+     * [id] => array('value' => [ID], 'label' => [NAME] [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'].')'
+            ];
+        }
+
+        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=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'].'; '.$aItem['playbook'].')'
+            ];
+        }
+        return  $aReturn;
+    }
+    
     /**
      * check access to a deploy target
      */
@@ -26,6 +137,12 @@ class rollout_awx extends rollout_base {
         return true;
     }
 
+    /**
+     * get array with commands to execute to deploy a package
+     * 
+     * @param string  $sPhase  phase
+     * @return array
+     */
     public function getDeployCommands($sPhase){
         $aReturn=array();
         $aConfig=$this->getConfig($sPhase);
diff --git a/public_html/deployment/plugins/rollout/default/rollout_default.php b/public_html/deployment/plugins/rollout/default/rollout_default.php
index a8999a4495afeee275b36ce98a397c455cafdd7d..a98ca37ace98359cca07afc6bb9d46020a8ac266 100644
--- a/public_html/deployment/plugins/rollout/default/rollout_default.php
+++ b/public_html/deployment/plugins/rollout/default/rollout_default.php
@@ -5,7 +5,7 @@
  * 
  * no action
  *
- * @author axel
+ * @author <axel.hahn@iml.unibe.ch>
  */
 class rollout_default extends rollout_base {
 
@@ -25,10 +25,22 @@ class rollout_default extends rollout_base {
         return true;
     }
 
+    /**
+     * override general form renderer: show a single message that no
+     * configuration items exist
+     * 
+     * @return string
+     */
     public function renderFormdata4Project() {
         return $this->_t('no-cfg');
     }
 
+    /**
+     * override general form renderer: show a single message that no
+     * configuration items exist
+     * 
+     * @return string
+     */
     public function renderFormdata4Phase($sPhase) {
         return $this->_t('no-cfg');
     }    
diff --git a/public_html/deployment/plugins/rollout/ssh/rollout_ssh.php b/public_html/deployment/plugins/rollout/ssh/rollout_ssh.php
index 822d03756b0b43186e1ff21a0b49d6847c9c066e..f896fe92d73199bc46585ca547ae7ad820b6a7c2 100644
--- a/public_html/deployment/plugins/rollout/ssh/rollout_ssh.php
+++ b/public_html/deployment/plugins/rollout/ssh/rollout_ssh.php
@@ -6,7 +6,7 @@
  * 
  * Run a SSH command on remote targets
  *
- * @author axel
+ * @author <axel.hahn@iml.unibe.ch>
  */
 class rollout_ssh extends rollout_base {
 
@@ -26,6 +26,12 @@ class rollout_ssh extends rollout_base {
         return true;
     }
 
+    /**
+     * get array with commands to execute to deploy a package
+     * 
+     * @param string  $sPhase  phase
+     * @return array
+     */
     public function getDeployCommands($sPhase){
         $aReturn=array();
         $aConfig=$this->getConfig($sPhase);
@@ -45,99 +51,4 @@ class rollout_ssh extends rollout_base {
         return $aReturn;
     }
     
-    /**
-     * form fields for project settings
-     * @return type
-     */
-    public function __DISABLED__renderFormdata4Project() {
-        /*
-          $sReturn='';
-          $i=0;
-
-          $sNamePrefix='plugins[rollout]['.$this->getId().']';
-          $aValues=$this->getConfig();
-
-          $aFormdata=array(
-          array('type' => 'markup','value' => '<br>'.$this->_t('section-required').':'),
-          array(
-          'type' => 'text',
-          'name' => $sNamePrefix.'[user]',
-          'label' => $this->_t('user'),
-          'value' => $aValues['user'],
-          // 'required' => 'required',
-          'validate' => 'isastring',
-          'size' => 25,
-          'placeholder' => $this->_aCfgGlobal['user'],
-          ),
-          array(
-          'type' => 'text',
-          'name' => $sNamePrefix.'[command]',
-          'label' => $this->_t('command'),
-          'value' => $aValues['command'],
-          // 'required' => 'required',
-          'validate' => 'isastring',
-          // 'size' => 100,
-          'placeholder' => $this->_aCfgGlobal['command'],
-          ),
-          array('type' => 'markup','value' => '<br><br>'.$this->_t('section-optional').':'),
-          array(
-          'type' => 'text',
-          'name' => $sNamePrefix.'[privatekey]',
-          'label' => $this->_t('privatekey'),
-          'value' => $aValues['privatekey'],
-          // 'required' => 'required',
-          'validate' => 'isastring',
-          // 'size' => 100,
-          'placeholder' => $this->_aCfgGlobal['privatekey'],
-          ),
-          array('type' => 'markup','value' => '<br><br>'.$this->_t('section-commands').':'),
-          array(
-          'type' => 'text',
-          'name' => $sNamePrefix.'[addkeycommand]',
-          'label' => $this->_t('addkeycommand'),
-          'value' => $aValues['addkeycommand'],
-          // 'required' => 'required',
-          'validate' => 'isastring',
-          // 'size' => 100,
-          'placeholder' => $this->_aCfgGlobal['addkeycommand'],
-          ),
-          array(
-          'type' => 'text',
-          'name' => $sNamePrefix.'[testcommand]',
-          'label' => $this->_t('testcommand'),
-          'value' => $aValues['testcommand'],
-          // 'required' => 'required',
-          'validate' => 'isastring',
-          // 'size' => 100,
-          'placeholder' => $this->_aCfgGlobal['testcommand'],
-          ),
-          );
-         * 
-         */
-
-        return 'WIP: project based setup for plugin [' . $this->getId() . ']<br>'
-                . $this->_renderForm4Vars('global', false)
-                // . $this->_renderForm($aFormdata, 'project')
-                // .$sReturn
-                . '<pre>DEBUG: GLOBAL settings - $this->_aCfgGlobal = ' . print_r($this->_aCfgGlobal, 1) . '</pre>'
-                . '<pre>DEBUG: PROJECT settings - $this->getConfig() = ' . print_r($this->getConfig(), 1) . '</pre>'
-        // .'<pre>DEBUG: $this->_aCfgProject ... plugin = '.print_r($this->_aCfgProject, 1).'</pre>'
-        ;
-    }
-
-    /**
-     * form fields for project settings
-     * @return type
-     */
-    public function __DISABLED__renderFormdata4Phase($sMyPhase) {
-        return 'WIP: pase based setup for plugin [' . $this->getId() . '] in phase '.$sMyPhase.'<br>'
-            . $this->_renderForm4Vars('global', $sMyPhase)
-            // . $this->_renderForm($aFormdata, 'project')
-            // .$sReturn
-            . '<pre>DEBUG: GLOBAL settings - $this->_aCfgGlobal = ' . print_r($this->_aCfgGlobal, 1) . '</pre>'
-            . '<pre>DEBUG: PROJECT settings - $this->getConfig() = ' . print_r($this->getConfig(), 1) . '</pre>'
-            . '<pre>DEBUG: PHASE settings - $this->getConfig("'.$sMyPhase.'") = ' . print_r($this->getConfig($sMyPhase), 1) . '</pre>'
-            ;
-    }
-
 }