diff --git a/README.md b/README.md index 4b6acff59b1aa227e82a3dc450046cfc677f307b..b122ae2c52f74c689e51e65817d0278cf2306340 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,8 @@ This application is an Add-ons for ISPConfig used for VPS Management (Proxmox) - Shutdown - Reset - Hard Stop (unplug the power) - + - Change network states (enable / disable) + - Display : - Power status - Uptime @@ -37,6 +38,8 @@ This application is an Add-ons for ISPConfig used for VPS Management (Proxmox) + + ## How To implement this module - Create Proxmox user for ISPConfig communication with PVEVMUser right - Assign VMs to this user @@ -46,6 +49,7 @@ This application is an Add-ons for ISPConfig used for VPS Management (Proxmox) - $conf["pve_password"] = 'password'; - $conf["pve_link"] = 'hostname / ip of your cluster head'; - $conf["pve_realm"] = 'realm'; + - Please do not use your Proxmox root user ! - Create MySQL table for this module -> misc/vm_proxmox.sql - If you are on multi-servers setup you have to do this on each server @@ -53,7 +57,6 @@ This application is an Add-ons for ISPConfig used for VPS Management (Proxmox) ## ToDo - Admin function : - Snapshot (add / remove) - - Networks : Enable / Disable - Display: - Vps console integration (stuck for the moment ... :( ) diff --git a/ajax_config.php b/ajax_config.php new file mode 100755 index 0000000000000000000000000000000000000000..4b0ed4ec7e74e94dff6cca9e0d45388e3d92444b --- /dev/null +++ b/ajax_config.php @@ -0,0 +1,92 @@ +auth->check_module_permissions('proxmox'); + +$prox_id = $app->functions->intval($_REQUEST['id']); + +if($_POST && !empty($prox_id)) +{ + // Verify assignation VM + if($_SESSION["s"]["user"]["typ"] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) + { + $client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]); + $vm = $app->db->queryOneRecord("SELECT vm_containers, vm_id FROM proxmox_vm WHERE id = $prox_id AND sys_groupid = $client_group_id"); + } + else + { + $vm = $app->db->queryOneRecord("SELECT vm_containers, vm_id FROM proxmox_vm WHERE id = $prox_id"); + } + + $vm_containers = $vm['vm_containers']; + $vm_id = $app->functions->intval($vm['vm_id']); + + if(isset($vm_id) && isset($vm_containers)) + { + $pve2 = new PVE2_API($conf["pve_link"], $conf["pve_username"], $conf["pve_realm"], $conf["pve_password"]); + + if ($pve2) { + if ($pve2->login()) { + + $vm_temp = $pve2->get("/cluster/resources"); + $key = array_search($vm_id, array_column( $vm_temp , 'vmid')); + $vm_pvesvr = $vm_temp[$key]['node']; + + // Get VM configurations + $vm_config = $pve2->get("/nodes/{$vm_pvesvr}/{$vm_containers}/{$vm_id}/config"); + $vm_interface = $vm_config[$_REQUEST['interface']]; + + $interface_settings = explode(',', $vm_config[$_REQUEST['interface']] ); + + if( ($key = array_search('link_down=1',$interface_settings)) !== false ) + { + unset($interface_settings[$key]); + } + else + { + $interface_settings[] = 'link_down=1'; + } + + /* + * Post new network vm configuration + * For change VM configurations your Proxmox user need VM.Config.Network right (PVEVMAdmin vs PVEVMUser) + */ + $vm_interface = array($_REQUEST['interface'] => implode(",", $interface_settings)); + $vm_config = $pve2->post("/nodes/{$vm_pvesvr}/{$vm_containers}/{$vm_id}/config", $vm_interface ); + + // TODO : return to vm information with succes or error message + // echo (!empty( $vm_config ) ? 'Ok' : 'NOK' ); + + } else { + echo "Login to Proxmox Host failed.\n"; + exit; + } + } else { + echo "Could not create PVE2_API object.\n"; + exit; + } + } +} + +$app->uses('listform_actions'); +$app->listform_actions->onLoad(); +?> diff --git a/ajax_graph.php b/ajax_graph.php index d0dfba12cf301356cc946b269bdf7b3c78c35f87..5760adec8171c6d9869fd6ca768a0bdc5f93651d 100755 --- a/ajax_graph.php +++ b/ajax_graph.php @@ -1,4 +1,8 @@ functions->intval($_SESSION["s"]["user"]["default_group"]); - + // Verify assignation VM if($_SESSION["s"]["user"]["typ"] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) { + $client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]); $vm = $app->db->queryOneRecord("SELECT vm_containers, vm_id FROM proxmox_vm WHERE id = $prox_id AND sys_groupid = $client_group_id"); } else @@ -29,7 +32,6 @@ if($_POST) $vm_containers = $vm['vm_containers']; $vm_id = $app->functions->intval($vm['vm_id']); - if(isset($vm_pvesvr) && isset($vm_id) && isset($vm_containers)) { $pve2 = new PVE2_API($conf["pve_link"], $conf["pve_username"], $conf["pve_realm"], $conf["pve_password"]); @@ -97,5 +99,4 @@ if($_POST) } } - ?> diff --git a/form/proxmox_vm_informations.tform.php b/form/proxmox_vm_informations.tform.php index 622b3917279091c40c956b2c1672d39f0f70fb97..e78aef9bd51954ed1ff166f28115cf39f9e02ec3 100755 --- a/form/proxmox_vm_informations.tform.php +++ b/form/proxmox_vm_informations.tform.php @@ -59,6 +59,7 @@ $form["tabs"]['informations'] = array ( 'title' => "Informations", // Need to translate with variable 'width' => 100, 'template' => "templates/proxmox_vm_informations.htm", + 'readonly' => true, 'fields' => array ( //################################# // Begin Datatable fields @@ -85,57 +86,7 @@ $form["tabs"]['graphics'] = array ( 'title' => "Graphics", // Need to translate with variable 'width' => 100, 'template' => "templates/proxmox_vm_graphiques.htm", - 'readonly' => false, - /* - 'fields' => array ( - //################################# - // Begin Datatable fields - //################################# - 'id' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'TEXT', - 'default' => '', - 'value' => '', - 'separator' => '', - 'width' => '30', - 'maxlength' => '255', - 'rows' => '', - 'cols' => '', - 'searchable' => 2 - ), - - //################################# - // ENDE Datatable fields - //################################# - )*/ + 'readonly' => true, ); -$form["tabs"]['networks'] = array ( - 'title' => "Networks", // Need to translate with variable - 'width' => 100, - 'template' => "templates/proxmox_vm_networks.htm", - 'readonly' => false, - /* - 'fields' => array ( - //################################# - // Begin Datatable fields - //################################# - 'id' => array ( - 'datatype' => 'INTEGER', - 'formtype' => 'TEXT', - 'default' => '', - 'value' => '', - 'separator' => '', - 'width' => '30', - 'maxlength' => '255', - 'rows' => '', - 'cols' => '', - 'searchable' => 2 - ), - - //################################# - // ENDE Datatable fields - //################################# - )*/ -); ?> diff --git a/lib/lang/ca_proxmox_vm.lng b/lib/lang/ca_proxmox_vm.lng index fd12e2a569c16a5b94e42cfcc20bddccd5f9805a..3cce0fd52ead93b8e80f37d6f0feaa0df00dcfa6 100755 --- a/lib/lang/ca_proxmox_vm.lng +++ b/lib/lang/ca_proxmox_vm.lng @@ -41,9 +41,14 @@ $wb["vm_confirm_kill"] = 'Stopper la machine virtuelle ?'; $wb["vm_confirm_shutdown"] = 'Arreter la machine virtuelle ?'; $wb["vm_select_timeframe_txt"] = 'Merci de choisir une période' ; $wb["vm_interface_txt"] = 'Interface'; -$wb["vm_bridge_txt"] = 'Mode'; -$wb["vm_rate_txt"] = 'Limitation (Mb/s)'; +$wb["vm_bridge_txt"] = 'Bridge Name'; +$wb["vm_rate_txt"] = 'Max rate (Mb/s)'; $wb["vm_tag_txt"] = 'Vlan'; -$wb["vm_link_txt"] = 'Désactivé'; +$wb["vm_disconnect_txt"] = 'Désactivé'; +$wb["vm_mac_txt"] = 'Adresse mac'; +$wb["vm_mode_txt"] = 'Mode'; +$wb["vm_model_txt"] = 'Model'; +$wb["vm_firewall_txt"] = 'Firewall'; +$wb["vm_queues_txt"] = 'Multiqueues'; ?> diff --git a/lib/lang/en_proxmox_vm.lng b/lib/lang/en_proxmox_vm.lng index 5bfdde64bede7965c6089aacd18a56447964bf3e..1dc3c3414eae24867e376697c0fb53748d8feb70 100755 --- a/lib/lang/en_proxmox_vm.lng +++ b/lib/lang/en_proxmox_vm.lng @@ -1,5 +1,5 @@ diff --git a/lib/lang/fr_proxmox_vm.lng b/lib/lang/fr_proxmox_vm.lng index 3a4a171d5d0fb6bd130a7799cb524fea8a07049f..0113507233b1355e1869093e1f48ab7cdcac9bc9 100755 --- a/lib/lang/fr_proxmox_vm.lng +++ b/lib/lang/fr_proxmox_vm.lng @@ -41,9 +41,13 @@ $wb["vm_confirm_kill"] = 'Stopper la machine virtuelle ?'; $wb["vm_confirm_shutdown"] = 'Arreter la machine virtuelle ?'; $wb["vm_select_timeframe_txt"] = 'Merci de choisir une période' ; $wb["vm_interface_txt"] = 'Interface'; -$wb["vm_bridge_txt"] = 'Mode'; -$wb["vm_rate_txt"] = 'Limitation (Mb/s)'; +$wb["vm_bridge_txt"] = 'Bridge name'; +$wb["vm_rate_txt"] = 'Max rate (Mb/s)'; $wb["vm_tag_txt"] = 'Vlan'; -$wb["vm_link_txt"] = 'Désactivé'; - +$wb["vm_disconnect_txt"] = 'Désactivé'; +$wb["vm_mac_txt"] = 'Adresse mac'; +$wb["vm_mode_txt"] = 'Mode'; +$wb["vm_model_txt"] = 'Model'; +$wb["vm_firewall_txt"] = 'Firewall'; +$wb["vm_queues_txt"] = 'Multiqueues'; ?> diff --git a/misc/admin_task_history.png b/misc/admin_task_history.png new file mode 100644 index 0000000000000000000000000000000000000000..1fd8a5dda91f34271e524aed47dd3e40315a5962 Binary files /dev/null and b/misc/admin_task_history.png differ diff --git a/misc/admin_vue_1.png b/misc/admin_vue_1.png index b89f833825bf72ffdb1c630c2574cf8ac2004a0b..2c07cc4cb121910bfadf1f0b6e0a388e1e7e289f 100644 Binary files a/misc/admin_vue_1.png and b/misc/admin_vue_1.png differ diff --git a/misc/graph_vue_1.png b/misc/graph_vue_1.png index ab97be44aac81f03de8074741579a494a5f492e5..7353d2c616cee4ce1204c6b20ebcef251abc80cc 100644 Binary files a/misc/graph_vue_1.png and b/misc/graph_vue_1.png differ diff --git a/proxmox_action.php b/proxmox_action.php index 07557f937559b65e41565afee506e07d82dac94f..016984d38472acd6053af0f497e5ae0930a29d00 100755 --- a/proxmox_action.php +++ b/proxmox_action.php @@ -1,6 +1,6 @@ functions->intval($_SESSION["s"]["user"]["default_group"]); + // Verify assignation VM - if($_SESSION["s"]["user"]["typ"] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) { + if($_SESSION["s"]["user"]["typ"] != 'admin' && !$app->auth->has_clients($_SESSION['s']['user']['userid'])) + { + $client_group_id = $app->functions->intval($_SESSION["s"]["user"]["default_group"]); $vm = $app->db->queryOneRecord("SELECT vm_containers, vm_id FROM proxmox_vm WHERE id = $prox_id AND sys_groupid = $client_group_id"); } else diff --git a/proxmox_vm_del.php b/proxmox_vm_del.php index e223b123e8e730cb0a4c2d1f76b78571c0d70540..3bb60c371e158e66e25f8dd4e0c793f234bcd796 100755 --- a/proxmox_vm_del.php +++ b/proxmox_vm_del.php @@ -1,30 +1,7 @@ onLoad(); -?> \ No newline at end of file +?> diff --git a/proxmox_vm_informations.php b/proxmox_vm_informations.php index 3a8a1da9f79aaa8a5294a9ee083853b34d537e08..f69b4c4fd689a7582d7b5563c612fd79f76bcc5b 100755 --- a/proxmox_vm_informations.php +++ b/proxmox_vm_informations.php @@ -1,5 +1,8 @@ auth->check_module_permissions('proxmox'); - // Loading classes $app->uses('tpl,tform,tform_actions'); $app->load('tform'); -print_r($_REQUEST); - class page_action extends tform_actions { function onShowEnd() { global $app, $conf; - - //$vm_info['vm_id'] = $app->functions->intval($this->dataRecord['vm_id']); - + $pve2 = new PVE2_API($conf["pve_link"], $conf["pve_username"], $conf["pve_realm"], $conf["pve_password"]); if ($pve2) { @@ -41,7 +39,6 @@ class page_action extends tform_actions { $vm_id = $app->functions->intval($this->dataRecord['vm_id']); $vm_containers = $this->dataRecord['vm_containers'] ; - $vm_temp = $pve2->get("/cluster/resources"); $key = array_search($vm_id, array_column( $vm_temp , 'vmid')); $vm_pvesvr = $vm_temp[$key]['node']; @@ -49,48 +46,16 @@ class page_action extends tform_actions { $app->tpl->setVar("vm_id", $vm_id); $app->tpl->setVar("vm_pvesvr", $vm_pvesvr); - switch($_REQUEST['next_tab']) { case 'graphics': //DO SOMETHING HERE break; - case 'networks': - $vm_config = $pve2->get("/nodes/{$vm_pvesvr}/{$vm_containers}/{$vm_id}/config"); - - $keys = array_keys($vm_config); - $net_temp = preg_grep('/^net[0-9]+/',$keys); - - - echo '
';
-						$arr_net = array();
-						foreach($net_temp as $net)
-						{
-							$settings_temp = explode(',', $vm_config[$net]);
-							
-							$arr_net[$net]['interface'] = $net;
-							
-							foreach($settings_temp as $settings )
-							{
-								list($k, $v) = explode('=', $settings);
-								$arr_net[$net]['checked'] = ($k == 'link_down' && $v == 1 ? 'checked' : '');
-								$arr_net[$net][$k] = $v;
-							}
-						}
-						
-						$app->tpl->setloop('networks', $arr_net);
-						
-						
-					print_r($arr_net);
-						echo '
'; - - - break; case 'informations': default: $vm_status = $pve2->get("/nodes/{$vm_pvesvr}/{$vm_containers}/{$vm_id}/status/current"); - + if ($vm_status != false) { $app->tpl->setVar("vm_name", $vm_status['name']); @@ -109,12 +74,37 @@ class page_action extends tform_actions { { $app->error($app->tform->wordbook["vm_err_assignation"]); } - break; + $vm_config = $pve2->get("/nodes/{$vm_pvesvr}/{$vm_containers}/{$vm_id}/config"); + + $keys = array_keys($vm_config); + $net_temp = preg_grep('/^net[0-9]+/',$keys); + + $arr_net = array(); + foreach($net_temp as $net) + { + $settings_temp = explode(',', $vm_config[$net]); + + $arr_net[$net]['interface'] = $net; + + foreach($settings_temp as $settings ) + { + list($k, $v) = explode('=', $settings); + + if (preg_match('/(e1000|vmxnet3|virtio|rtl8139)/i', $k ) ) + { + $arr_net[$net]['mac'] = $v; + } + $arr_net[$net]['link_state'] = ($k == 'link_down' && $v == 1 ? 'Yes' : 'No'); + $arr_net[$net][$k] = $v; + } + } + + $app->tpl->setloop('networks', $arr_net); + + break; } - - } else { //print("Login to Proxmox Host failed.\n"); $app->error($app->tform->wordbook["vm_err_login"]); @@ -128,34 +118,8 @@ class page_action extends tform_actions { parent::onShowEnd(); } - - /* - function onSubmit() { - global $app, $conf; - - parent::onSubmit(); - } - - - - function onAfterInsert() { - global $app, $conf; - - } - - function onBeforeUpdate() { - global $app, $conf; - - } - - function onAfterUpdate() { - global $app, $conf; - - } - */ } - $page = new page_action; $page->onLoad(); diff --git a/proxmox_vm_list.php b/proxmox_vm_list.php index addfb52edb19aed17613af8585b99c6463690afd..2c751383c0a3b98daa48802df980386ae00bd8de 100755 --- a/proxmox_vm_list.php +++ b/proxmox_vm_list.php @@ -1,4 +1,9 @@ auth->check_module_permissions('proxmox'); // Loading classes $app->uses('tpl'); +$template = 'templates/proxmox_vm_logs.htm'; + +// Loading the template +$app->uses('tpl'); +$app->tpl->newTemplate("form.tpl.htm"); +$app->tpl->setInclude('content_tpl', $template); + $pve2 = new PVE2_API($conf["pve_link"], $conf["pve_username"], $conf["pve_realm"], $conf["pve_password"]); if ($pve2) { if ($pve2->login()) { - - $template = 'templates/proxmox_vm_logs.htm'; - - // Loading the template - $app->uses('tpl'); - $app->tpl->newTemplate("form.tpl.htm"); - $app->tpl->setInclude('content_tpl', $template); - - $title = $app->lng("task_title_txt"); - $start_time = $app->lng("start_time_txt"); - $end_time = $app->lng("end_time_txt"); - $username = $app->lng("username_txt"); - $description = $app->lng("description_txt"); - $status = $app->lng("status_txt"); - - $app->tpl->setVar("task_title_txt", $title); - $app->tpl->setVar("start_time_txt", $start_time); - $app->tpl->setVar("end_time_txt", $end_time); - $app->tpl->setVar("username_txt", $username); - $app->tpl->setVar("description_txt", $description); - $app->tpl->setVar("status_txt", $status); + + $app->tpl->setVar("task_title_txt", $app->lng("task_title_txt") ); + $app->tpl->setVar("start_time_txt", $app->lng("start_time_txt") ); + $app->tpl->setVar("end_time_txt", $app->lng("end_time_txt") ); + $app->tpl->setVar("username_txt", $app->lng("username_txt") ); + $app->tpl->setVar("description_txt", $app->lng("description_txt") ); + $app->tpl->setVar("status_txt", $app->lng("status_txt") ); $tasks_history = $pve2->get("/cluster/tasks"); @@ -54,11 +51,9 @@ if ($pve2) { } $app->tpl->setloop('task_logs', $tasks_logs); - - - $app->tpl_defaults(); - $app->tpl->pparse(); } } +$app->tpl_defaults(); +$app->tpl->pparse(); ?> diff --git a/templates/proxmox_vm_graphiques.htm b/templates/proxmox_vm_graphiques.htm index 89c88f4d9c87d3da8eb58ac227db22ba32a3c2ac..80dd0d96aadfad9258a55171c2c3c46133412133 100755 --- a/templates/proxmox_vm_graphiques.htm +++ b/templates/proxmox_vm_graphiques.htm @@ -9,64 +9,59 @@

{tmpl_var name="toolsarea_head_txt"}

-
-
- -
- -
-
- -
- -
- -
- -
+
+ +
+ +
+
+ +
+ +
+ +
+ +
-
diff --git a/templates/proxmox_vm_informations.htm b/templates/proxmox_vm_informations.htm index dab5aaa493d1eba353dd6cbc85cf1633ea4ad0ab..333e8a792f52aaa83837bcec26306189e6e1af3a 100755 --- a/templates/proxmox_vm_informations.htm +++ b/templates/proxmox_vm_informations.htm @@ -1,5 +1,5 @@ - - + + + diff --git a/templates/proxmox_vm_interfaces.htm b/templates/proxmox_vm_interfaces.htm new file mode 100755 index 0000000000000000000000000000000000000000..9d2b945d3986bc36e835cd4728016b5274523479 --- /dev/null +++ b/templates/proxmox_vm_interfaces.htm @@ -0,0 +1,93 @@ + +

+ + +
+ +
+
+ +
+ +
+
+ + +
+ +
+
+ +
+ +
+
+ + +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
{tmpl_var name='vm_firewall'}
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
{tmpl_var name='vm_link_down'}
+
+ + + +
+ + +
+ + + diff --git a/templates/proxmox_vm_list.htm b/templates/proxmox_vm_list.htm index 11daab87ee395a6d32b9a86d4b2fcad250ad94a7..400b700a89e06682a92f3a6584061165e8422ea4 100755 --- a/templates/proxmox_vm_list.htm +++ b/templates/proxmox_vm_list.htm @@ -7,9 +7,6 @@ - - -

@@ -39,7 +36,7 @@
{tmpl_var name="vm_name"} {tmpl_var name="vm_description"} - + diff --git a/templates/proxmox_vm_networks.htm b/templates/proxmox_vm_networks.htm deleted file mode 100755 index aa749818322fc7f7f906ea9b0bc8f8d947b548c7..0000000000000000000000000000000000000000 --- a/templates/proxmox_vm_networks.htm +++ /dev/null @@ -1,44 +0,0 @@ - - - - -

- -
-
- - Here Network configuration - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{tmpl_var name="interface"}{tmpl_var name="bridge"}{tmpl_var name="rate"}{tmpl_var name="tag"}
- - -
-