36 Commits

Author SHA1 Message Date
Luke S Thompson
a0decccb50 Version bump from v1.2.1 to v1.2.2 2023-09-15 09:48:22 +10:00
Luke S Thompson
eb7c0914f8 v1.2.2 into CHANGELOG, final check 2023-09-15 09:46:57 +10:00
Luke S Thompson
2d2755bb81 New GUI Tabs ahead of v1.2.3 2023-09-15 09:44:14 +10:00
Luke S Thompson
201d7f6f29 Adjust method: un/suspend/term; 30 sec term. sleep 2023-09-14 20:37:02 +10:00
Luke S Thompson
1951b5dbb2 Suspend/Unsuspend now Stop/Start 2023-09-14 15:05:09 +10:00
Luke S Thompson
13fce0651b Update SQL statement formatting (MariaDB) 2023-09-14 13:03:52 +10:00
Luke S Thompson
6e6f2a5e86 Same missing bracket (#40) as with noVNC 2023-09-14 13:01:19 +10:00
Luke S Thompson
5fa8fbe00f Change c'log to point out to SQL.md 2023-09-14 10:29:26 +10:00
Luke S Thompson
0e040aff44 Add SQL.md file for Update Changes 2023-09-14 10:26:16 +10:00
Luke S Thompson
dd2ec07d6b Missing bracket when verifying vnc_secret (#40) 2023-09-14 10:10:24 +10:00
Luke S Thompson
98fa2c32d8 Add issue templates - bug/feature 2023-09-14 08:51:43 +10:00
Luke S Thompson
6a96263dee Test and tweak Debug Mode, resolves #38 2023-09-14 08:37:12 +10:00
Luke S Thompson
88720b5f56 GUI Option for #38 (Debug); Try fix #40 (Error)
Plus more respectful re-arrange of SQL, so we can look to supply update script/function to add missing columns.
2023-09-14 08:27:20 +10:00
Luke S Thompson
aca15eb2d3 1st pass at Debug Mode (#38) 2023-09-14 08:11:47 +10:00
Luke S Thompson
d5ab11b03e Pointless file_put; Prep for debug_mode; etc. 2023-09-14 07:58:56 +10:00
Luke S Thompson
d9ef54e25a Minor tweaks to GUI language 2023-09-13 14:38:44 +10:00
Luke S Thompson
6f969a618e Missing bracket; VLAN ID null default; SERVER_NAME 2023-09-13 14:28:08 +10:00
Luke S Thompson
a016784d20 Slight tweaks to README and C'LOG 2023-09-13 14:14:31 +10:00
Luke S Thompson
4e7cb78aad Set on-boot for CTs in PVE Creation (#34) 2023-09-13 13:27:52 +10:00
Luke S Thompson
0b794ebd96 feat: Ability to assign VLAN ID to Plans (#35) 2023-09-13 13:12:56 +10:00
Luke S Thompson
f017bcd1f0 + Update Checker (#21), more code comments 2023-09-13 12:39:35 +10:00
Luke S Thompson
a220eea9fa Add WHMCS Service config save to README 2023-09-13 09:59:04 +10:00
Luke S Thompson
b8da683746 IP SQL Error (#36), VNC check conf (#27), GUI tune 2023-09-13 08:24:05 +10:00
Luke S Thompson
25ea01effb Module Config/GUI: Text improvements 2023-09-11 15:38:01 +10:00
Luke S Thompson
3ee12c4231 \n 2023-08-22 10:57:31 +10:00
Luke S Thompson
8ef4b8cb4f Clean-up README a little 2023-08-22 10:56:20 +10:00
Luke S Thompson
616ccda1f9 Improve comments in noVNC router 2023-08-07 17:25:37 +10:00
Luke S Thompson
d8d8644775 Minor heading tweaks 2023-07-05 20:41:18 +10:00
Luke S Thompson
0b39af76b8 Headings: Emoji book-ending 2023-07-04 21:54:09 +10:00
Luke S Thompson
7dc3ebce92 Larger headings 2023-07-04 21:52:24 +10:00
Luke S Thompson
484bb1f79c Remove line break 2023-07-04 21:51:41 +10:00
Luke S Thompson
3854fd86fe Overhaul completed 2023-07-04 21:50:48 +10:00
Luke S Thompson
c9d14506c4 Add Installation section 2023-06-28 23:12:40 +10:00
Luke S Thompson
799500bbf0 Add Wiki links; Explanation for vnc cred field 2023-06-21 19:45:27 +10:00
Luke S Thompson
b7ee090b4d Admin Area: Remove noVNC (no HTML) 2023-06-19 18:53:12 +10:00
Luke S Thompson
7f6171efbf Change action return to new; Actions in Admin GUI 2023-06-19 18:51:29 +10:00
10 changed files with 463 additions and 162 deletions

View File

@@ -0,0 +1,37 @@
---
name: "\U0001F41B Bug Report"
about: Create a report to help us improve the module!
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behaviour:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behaviour**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem to us.
**Module > Support/Health tab (remove IP and paste here):**
- Version of module
- Web Server info
- PHP version
- etc.
**WHMCS Information (please complete the following):**
- WHMCS Version (must be supported):
- Using HTTPS: Yes or No
**Confirm that you have MORE THAN 100 services (all statuses) in WHMCS?**
Otherwise you will receive a "value does not look like a valid VM ID" error. Check the error!

View File

@@ -0,0 +1,20 @@
---
name: "\U0001F680 Feature Request"
about: How can we improve Proxmox VE for WHMCS?
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -1,21 +1,42 @@
# Changelog
All notable changes to Proxmox VE for WHMCS will be documented in this file.
## [1.2.2] - 2023-09-15
### 🚀 Feature
- Debugging Mode: Allow admin to turn on/off Module Log feed (#38)*
- VLAN ID: Set the required Virtual LAN ID against VM/CT Plan (#35)*
- Version: Report in-use & latest versions in Health; ver alert (#21)
- Power Actions: Now available in Admin Area as well as Client Area
- (Note: Suspend/Unsuspend/Terminate remain admin-only functions)
### 💅 Polish
- Client Area: Power Action wording amended (Soft Stop, Hard Stop)
- Admin, Module Config: Explain what the VNC Secret field is about
- Admin, Module Config: House-keeping to design, Support/Health tab
### 🐛 Bug Fix
- Admin, Create Service: Fails if Plan/Pool not assigned in WHMCS (#36)
- Client, VNC: Fails early if VNC Secret is not set or adequate (#27)
- On-boot Status: Enabled/Disabled now properly applied for CTs (#34)
(\*): SQL Note: There are new columns in 2 of the module tables, see [SQL.md](https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/blob/master/SQL.md)
## [1.2.1b] - 2023-06-19
### Added
### 🚀 Feature
- Module Config tab, allowing for configuration of the VNC Secret
- Reboot command/action added to Client Area (ie. on/off/hard-off)
- Link from Health tab of Admin GUI to WHMCS Marketplace re: reviews
- Images for all supported Operating Systems & Kernel types (some fixed)
- Ground-work for noVNC overhaul, to support PVE Auth & VNC Tunnel tickets
- noVNC overhauled, to send PVE Cookie (ticket) and VNC Access Ticket also
### Changed
### 💅 Polish
- Stop VM/CT (Client Area) renamed to Hard Stop, compared to Shut Down
- Modify the PHP API2 class, adding getTicket() so we can dual-auth (VNC)
- Move VNC Clients from root-level to vnc-only-level access to Proxmox VE
### Fixed
### 🐛 Bug Fix
- noVNC render method updated to stop out-of-order data flow problem
- noVNC back-end vncproxy and vncwebsocket methods updated re: spec
- Client Area actions (Power Off/On, etc) fixed for LXC (QEMU OK)
@@ -23,7 +44,7 @@ All notable changes to Proxmox VE for WHMCS will be documented in this file.
## [1.2.0b] - 2023-06-18
### Added
### 🚀 Feature
- Link off to GitHub Issues for Support from the Module page in WHMCS
- CHANGELOG.md file added to repository to track in recommended format
- Try-catch around the Creation API Call, routing OK/error into WHMCS
@@ -34,7 +55,7 @@ All notable changes to Proxmox VE for WHMCS will be documented in this file.
- Warning in README.md re: WHMCS Service ID being > 100
- Zero Tolerance Abuse Policy added to README file
### Changed
### 💅 Polish
- Module versioning changed to semver (semantic versioning) 1.2.0
- Change rel. path to ROOTDIR in IPv4 file, in case of other issues
- Use /cluster/resources via API, not /node/, to get stats (ex. swap)
@@ -43,7 +64,7 @@ All notable changes to Proxmox VE for WHMCS will be documented in this file.
- Updated the PVE2 API Class and improved its logging (prefix/exception)
- Method to fire API Calls updated due to reduction in WHMCS param scope
### Fixed
### 🐛 Bug Fix
- Regression in v1.1 with missing semicolon breaking activation (#14)
- Edit Icon not rendering on IP/Pool edit page, missing asset (#13)
- Relative link to PVE2 API Class file broken, use ROOTDIR (#13/15)
@@ -56,19 +77,19 @@ All notable changes to Proxmox VE for WHMCS will be documented in this file.
## [1.1b] - 2023-06-06
### Added
### 🚀 Feature
- Swap space editing for plans; back-end existed but not GUI editing
- Modern-day language to GUI according to changes in the 6 years
- README now links out to all Dependencies and Documentation
### Changed
### 💅 Polish
- Module Name from "PRVE" to "pvewhmcs" (ie. Proxmox VE for WHMCS)
- Default storage/disk type changed from IDE to Virtio (fastest)
- Updated 3 dependencies to latest: PVE2-PHP, noVNC, TigerVNC
- Removed all code segments relating to Software Licensing
- DNS defaults changed from Google DNS to Cloudflare DNS
### Fixed
### 🐛 Bug Fix
- Module can now be installed onto WHMCS 8.x installations
- OpenVZ changed to LXC, to support PVE 4.x installs & up
- Removed I/O Priority setting, to re-do via Throttling
@@ -76,11 +97,11 @@ All notable changes to Proxmox VE for WHMCS will be documented in this file.
## [1.0] - 2017-01-26
### Added
### 🚀 Feature
- Open-sourced the previously commercial plugin
### Changed
### 💅 Polish
- Commented out the licensing code segments
### Fixed
### 🐛 Bug Fix
- Removed old database schema import file

View File

@@ -1,41 +1,57 @@
# Proxmox VE for WHMCS (Module) Provision & Manage
We're overhauling the Module to suit our internal needs at [LEOPARD.host](https://leopard.host).
We're mostly done overhauling the Module to suit our internal needs at [LEOPARD.host](https://leopard.host).
- Automatically Provision VMs & CTs in [Proxmox VE](https://proxmox.com/en/proxmox-ve/features) from [WHMCS](https://www.whmcs.com/tour/)
- Allow clients to view/manage VMs using WHMCS Client Area
- Configure VM/CT plans with custom CPU/RAM/VLAN/On-boot/Bandwidth/etc
- Automatically Provision VMs & CTs in [Proxmox VE](https://proxmox.com/en/proxmox-ve/features) from [WHMCS](https://www.whmcs.com/tour/) easily
- Allow clients to view/manage VMs using the WHMCS Client Area
- Create/Suspend/Unsuspend/Terminate via WHMCS Admin Area
- Statistics/Graphing is available in the Client Area for services :)
The original module was written in 2 months by @cybercoder for sale online in 2016, though didn't sell any copies so they kindly open-sourced it and removed the licensing requirement. _The manual PDF files are due to be updated (these still mention licensing - ignore this)_
https://marketplace.whmcs.com/product/6935-proxmox-ve-for-whmcs
### 🛠️ SYSTEM REQUIREMENTS:
## 🎯 MODULE: SYSTEM REQUIREMENTS 🎯
- (WHMCS) v8.x.x stable (HTTPS)
- (WHMCS) Service ID >100
- (PHP) v8.x.x stable
- (Proxmox) VE v7/8
- (Proxmox) 2 users
- (WHMCS) **Service ID above 100**
- (PHP) v8.x.x (stable version)
- (Proxmox) VE v7/8 (current)
- (Proxmox) 2 users (API/VNC)
**SID >100:** The WHMCS Service ID requirement is critical, as Proxmox reserves VMIDs <100.
**SID >100:** The WHMCS Service ID requirement is CRITICAL, as Proxmox reserves VMIDs <100 (system).
_If you don't have enough services (any status) in WHMCS, create services until you reach SID 101._
_If you don't have enough services (of any status) in WHMCS (DB: tblhosting.id), create enough dummy/test entries to reach Service ID 101+._ **Else you're likely to see an error which explains this:** `HTTP/1.1 400 Parameter verification failed. (invalid format - value does not look like a valid VM ID)`
### 🥽 noVNC CONSOLE TUNNELING:
## ✅ MODULE: INSTALL & CONFIG ✅
Once you have uploaded, activated and made the WHMCS Module available to Administrators, you need to:
1. WHMCS Admin > Addons > Proxmox VE for WHMCS > Module Config > VNC Secret (see below)
2. WHMCS Admin > Addons > Proxmox VE for WHMCS > Add KVM/LXC Plan/s
3. WHMCS Admin > Addons > Proxmox VE for WHMCS > Add an IP Pool
4. WHMCS Admin > Config > Products/Services > New Service (create offering)
5. " " > Newly-added Service > Tab 3 > SAVE (associates Plan/Pool to WHMCS Service type)
For now, please use the Manual PDFs as supplementary information, re: ISO files, LXC templates, etc. This is out-dated though still helpful contextually - please read the note at the top of this README.
## 🥽 noVNC: CONSOLE TUNNELING 🥽
To access VNC via WHMCS Client Area, you need to:
1. Follow the PVE User Requirement below
2. PVE and WHMCS on the same Domain Name*
3. Have valid PTR/rDNS for the PVE Address
2. Public IPv4 for PVE, or proxy to private subnet
3. PVE and WHMCS on the same Domain Name*
4. Have valid PTR/rDNS for the PVE Address
**WIP NOTE:** noVNC has been overhauled. It is not guaranteed, nor the project at all. :-)
\* = You must use different Subdomains on the same Domain Name, for the cookie (anti-CSRF).
\* = If your Domain Name has a 2-part TLD (ie. co.uk) then you will need to amend the code.
\* = If your Domain Name has a 2-part TLD (ie. co.uk) then you will need to fork & amend novnc_router.php - ideally we/someone will optimise this to better cater to all formats.
### 👥 PROXMOX USER REQUIREMENT:
## 👥 PROXMOX: USERS (ROOT & VNC) 👥
You must have a root (etc) account to Create/Access services. Configured via WHMCS Config > Servers.
@@ -48,13 +64,17 @@ For the VNC User in Proxmox you need to:
4. Add permission to access VNC -> Datacenter / Node / VM / Permissions / Add Group Permissions - select Group: "VNC", Role: "VNC"
5. Configure the WHMCS > Modules > Proxmox VE for WHMCS > Module Config > VNC Secret with 'vnc' password.
### 🤬 ABUSE - ZERO TOLERANCE:
## 🤬 ABUSE: ZERO TOLERANCE 🤬
**NOTE:** This module is being overhauled and is in beta. Your support is welcomed.
**NOTE:** This module has been overhauled and remains in functionally-OK beta.
Your support is welcomed per the spirit of FOSS (Free Open-source Software)!
If you cannot accept this, do not download nor use the code. Complaints, nasty reviews, and similar behaviour is against the spirit of FOSS and will not be tolerated. Be grateful & considerate - thank you!
### 🆘 TECHNICAL SUPPORT:
## 🆘 TECHNICAL SUPPORT 🆘
Wiki: https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/wiki
Including logs, details, steps to reproduce, etc, please raise an [Issue](https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/issues).
@@ -70,20 +90,28 @@ Please note that this is FOSS and Support is not guaranteed.
This module is licensed via the GNU General Public License v3.0.
### 🖥️ LIBRARIES & DEPENDENCIES:
## 🔄 UPDATING THE ADDON MODULE 🔄
WHMCS Admin > Addon Modules > Proxmox VE for WHMCS > Support/Health shows updates.
You can download the new version and upload it over the top, then run any SQL ops.
Please consult the [SQL.md](https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/blob/master/SQL.md) file, open your WHMCS DB & run the statements. Then you're done.
## 🖥️ LIBRARIES & DEPENDENCIES 🖥️
- [PHP Client for PVE2 API](https://github.com/CpuID/pve2-api-php-client) (Dec 5th, 2022)
- [TigerVNC VncViewer.jar](https://sourceforge.net/projects/tigervnc/files/stable/) (v1.13.1 in repo)
- [noVNC HTML5 Viewer](https://github.com/novnc/noVNC) (v1.4.0 in repo)
### 📄 DOCUMENTATION & RESOURCES:
## 📄 DOCUMENTATION & RESOURCES 📄
- Proxmox API: https://pve.proxmox.com/pve-docs/api-viewer/
- TigerVNC: https://github.com/TigerVNC/tigervnc/wiki
- noVNC: https://github.com/novnc/noVNC/wiki
- WHMCS: https://developers.whmcs.com/
### 🙌 CONTRIBUTING TO THE MODULE:
## 🎉 CONTRIBUTING TO THE MODULE 🎉
If you'd like to contribute to the Module, please open a [PR](https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/pulls).

8
SQL.md Normal file
View File

@@ -0,0 +1,8 @@
# SQL Statements for Updates (nav to DB first)
### v1.2.1 to v1.2.2
```
ALTER TABLE mod_pvewhmcs ADD COLUMN `debug_mode` tinyint(1) unsigned DEFAULT '0';
ALTER TABLE mod_pvewhmcs_plans ADD COLUMN `vlanid` varchar(10) DEFAULT NULL;
```

View File

@@ -2,9 +2,10 @@ CREATE TABLE IF NOT EXISTS `mod_pvewhmcs` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`config` varchar(255),
`vnc_secret` varchar(255),
`debug_mode` tinyint(1) unsigned DEFAULT '0',
PRIMARY KEY (`id`)
);
INSERT INTO `mod_pvewhmcs` (`id`, `config`) VALUES (1, NULL);
INSERT INTO `mod_pvewhmcs` (`id`, `config`, `vnc_secret`) VALUES (1, NULL, NULL);
CREATE TABLE IF NOT EXISTS `mod_pvewhmcs_ip_addresses` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pool_id` int(11) NOT NULL DEFAULT '0',
@@ -46,6 +47,7 @@ CREATE TABLE IF NOT EXISTS `mod_pvewhmcs_plans` (
`bw` int(6) unsigned DEFAULT '0',
`kvm` tinyint(1) unsigned DEFAULT '0',
`onboot` tinyint(1) unsigned DEFAULT '0',
`vlanid` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE IF NOT EXISTS `mod_pvewhmcs_vms` (

View File

@@ -1,62 +1,90 @@
<?php
use Illuminate\Database\Capsule\Manager as Capsule;
define( 'pvewhmcs_BASEURL', 'addonmodules.php?module=pvewhmcs' );
// Require the PHP API Class to interact with Proxmox VE
require_once('proxmox.php');
// CONFIG: Declare key options to the WHMCS Addon Module framework.
function pvewhmcs_config() {
$configarray = array(
"name" => "Proxmox VE for WHMCS",
"description" => "Proxmox Virtual Environment + WHMCS",
"version" => "1.2.1",
"description" => "Proxmox VE (Virtual Environment) & WHMCS, integrated & open-source! Provisioning & Management of VMs/CTs.".is_pvewhmcs_outdated(),
"version" => "1.2.2",
"author" => "The Network Crew Pty Ltd",
'language' => 'English'
);
return $configarray;
}
// VERSION: also stored in repo/version (for update-available checker)
function pvewhmcs_version(){
return "1.2.1";
return "1.2.2";
}
// WHMCS MODULE: ACTIVATION
function pvewhmcs_activate() {
// Pull in the SQL structure (includes VNC/etc tweaks)
$sql = file_get_contents(ROOTDIR.'/modules/addons/pvewhmcs/db.sql');
if (!$sql) {
return array('status'=>'error','description'=>'The db.sql file not found.');
}
// SQL file is good, let's proceed with pulling it in
$err=false;
$i=0;
$query_array=explode(';',$sql) ;
$query_count=count($query_array) ;
// Iterate through the SQL commands to finalise init.
foreach ( $query_array as $query) {
if ($i<$query_count-1)
if (!Capsule::statement($query.';'))
$err=true;
$i++ ;
}
// Return success or error.
if (!$err)
return array('status'=>'success','description'=>'PVE for WHMCS installed successfuly.');
return array('status'=>'success','description'=>'Proxmox VE for WHMCS was installed successfuly.');
return array('status'=>'error','description'=>'PVE for WHMCS was not activated properly.');
return array('status'=>'error','description'=>'Proxmox VE for WHMCS was not activated properly.');
}
// WHMCS MODULE: DEACTIVATION
function pvewhmcs_deactivate() {
// Drop all module-related tables
Capsule::statement('drop table mod_pvewhmcs_ip_addresses,mod_pvewhmcs_ip_pools,mod_pvewhmcs_plans,mod_pvewhmcs_vms,mod_pvewhmcs');
# Return Result
return array('status'=>'success','description'=>'PVE for WHMCS successfuly deactivated and all related tables deleted.');
return array('status'=>'error','description'=>'If an error occurs you can return an error
message for display here');
return array('status'=>'info','description'=>'If you want to give an info message to a user
you can return it here');
// Return the assumed result (change?)
return array('status'=>'success','description'=>'Proxmox VE for WHMCS successfuly deactivated and all related tables deleted.');
}
function pvewhmcs_output($vars) {
// UPDATE CHECKER: live vs repo
function is_pvewhmcs_outdated(){
if(get_pvewhmcs_latest_version() > pvewhmcs_version()){
return "<br><span style='float:right;'><b>Proxmox VE for WHMCS is outdated: <a style='color:red' href='https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/releases'>Download the new version!</a></span>";
}
}
// UPDATE CHECKER: return latest ver
function get_pvewhmcs_latest_version(){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://raw.githubusercontent.com/The-Network-Crew/Proxmox-VE-for-WHMCS/master/version");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close ($ch);
return str_replace("\n", "", $result);
}
// ADMIN MODULE GUI: output (HTML etc)
function pvewhmcs_output($vars) {
$modulelink = $vars['modulelink'];
// Messages
// Check for update and report if available
if (!empty(is_pvewhmcs_outdated())) {
$_SESSION['pvewhmcs']['infomsg']['title']='Proxmox VE for WHMCS: New version available!' ;
$_SESSION['pvewhmcs']['infomsg']['message']='Please visit the GitHub repository > Releases page. https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/releases' ;
}
// Print Messages to GUI before anything else
if (isset($_SESSION['pvewhmcs']['infomsg'])) {
echo '
<div class="infobox">
@@ -74,8 +102,10 @@ function pvewhmcs_output($vars) {
<ul class="nav nav-tabs admin-tabs">
<li class="'.($_GET['tab']=="vmplans" ? "active" : "").'"><a id="tabLink1" data-toggle="tab" role="tab" href="#plans">VM Plans</a></li>
<li class="'.($_GET['tab']=="ippools" ? "active" : "").'"><a id="tabLink2" data-toggle="tab" role="tab" href="#ippools">IP Pools</a></li>
<li class="'.($_GET['tab']=="health" ? "active" : "").'"><a id="tabLink3" data-toggle="tab" role="tab" href="#health">Support / Health</a></li>
<li class="'.($_GET['tab']=="config" ? "active" : "").'"><a id="tabLink4" data-toggle="tab" role="tab" href="#config">Module Config</a></li>
<li class="'.($_GET['tab']=="nodes" ? "active" : "").'"><a id="tabLink3" data-toggle="tab" role="tab" href="#nodes">Nodes / Cluster</a></li>
<li class="'.($_GET['tab']=="actions" ? "active" : "").'"><a id="tabLink4" data-toggle="tab" role="tab" href="#actions">Actions / Logs</a></li>
<li class="'.($_GET['tab']=="health" ? "active" : "").'"><a id="tabLink5" data-toggle="tab" role="tab" href="#health">Support / Health</a></li>
<li class="'.($_GET['tab']=="config" ? "active" : "").'"><a id="tabLink6" data-toggle="tab" role="tab" href="#config">Module Config</a></li>
</ul>
</div>
<div class="tab-content admin-tabs">
@@ -103,15 +133,15 @@ function pvewhmcs_output($vars) {
echo '
<div id="plans" class="tab-pane '.($_GET['tab']=="vmplans" ? "active" : "").'">
<div class="btn-group btn-group-lg" role="group" aria-label="...">
<div class="btn-group" role="group" aria-label="...">
<a class="btn btn-default" href="'. pvewhmcs_BASEURL .'&amp;tab=vmplans&amp;action=planlist">
<i class="fa fa-list"></i>&nbsp; Plans List
<i class="fa fa-list"></i>&nbsp; List: VM Plans
</a>
<a class="btn btn-default" href="'. pvewhmcs_BASEURL .'&amp;tab=vmplans&amp;action=add_kvm_plan">
<i class="fa fa-plus-square"></i>&nbsp; Add new KVM plan
<i class="fa fa-plus-square"></i>&nbsp; Add: KVM Plan
</a>
<a class="btn btn-default" href="'. pvewhmcs_BASEURL .'&amp;tab=vmplans&amp;action=add_lxc_plan">
<i class="fa fa-plus-square"></i>&nbsp; Add new LXC plan
<i class="fa fa-plus-square"></i>&nbsp; Add: LXC Plan
</a>
</div>
';
@@ -187,6 +217,9 @@ function pvewhmcs_output($vars) {
NIC Model
</th>
<th>
VLAN ID
</th>
<th>
Rate
</th>
<th>
@@ -214,6 +247,7 @@ function pvewhmcs_output($vars) {
echo '<td>'.$vm->netmode . PHP_EOL .'</td>';
echo '<td>'.$vm->bridge.$vm->vmbr . PHP_EOL .'</td>';
echo '<td>'.$vm->netmodel . PHP_EOL .'</td>';
echo '<td>'.$vm->vlanid . PHP_EOL .'</td>';
echo '<td>'.$vm->netrate . PHP_EOL .'</td>';
echo '<td>'.$vm->bw . PHP_EOL .'</td>';
echo '<td>
@@ -237,10 +271,10 @@ function pvewhmcs_output($vars) {
<div id="ippools" class="tab-pane '.($_GET['tab']=="ippools" ? "active" : "").'" >
<div class="btn-group">
<a class="btn btn-default" href="'. pvewhmcs_BASEURL .'&amp;tab=ippools&amp;action=list_ip_pools">
<i class="fa fa-list"></i>&nbsp; List IP Pools
<i class="fa fa-list"></i>&nbsp; List: IP Pools
</a>
<a class="btn btn-default" href="'. pvewhmcs_BASEURL .'&amp;tab=ippools&amp;action=newip">
<i class="fa fa-plus"></i>&nbsp; Add IP to Pool
<i class="fa fa-plus"></i>&nbsp; Add: IP to Pool
</a>
</div>
';
@@ -268,13 +302,33 @@ function pvewhmcs_output($vars) {
echo'
</div>
';
// Health Tab
// NODES / CLUSTER tab in ADMIN GUI
echo '<div id="nodes" class="tab-pane '.($_GET['tab']=="nodes" ? "active" : "").'" >' ;
echo ('<strong><h2>PVE: /cluster/resources</h2></strong>');
echo ('Coming in v1.2.3');
echo ('<strong><h2>PVE: Cluster Action Viewer</h2></strong>');
echo ('Coming in v1.3.x');
echo ('<strong><h2>PVE: Failed Actions (emailed)</h2></strong>');
echo ('Coming in v1.3.x<br><br>');
echo ('<strong><a href=\'https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/milestones\' target=\'_blank\'>View the milestones/versions on GitHub</a></strong>');
echo '</div>';
// ACTIONS / LOGS tab in ADMIN GUI
echo '<div id="actions" class="tab-pane '.($_GET['tab']=="actions" ? "active" : "").'" >' ;
echo ('<strong><h2>Module: Action History</h2></strong>');
echo ('Coming in v1.2.3');
echo ('<strong><h2>Module: Failed Actions</h2></strong>');
echo ('Coming in v1.2.3');
echo ('<strong><h2>WHMCS: Module Logging</h2></strong>');
echo ('<u><a href=\'/admin/index.php?rp=/admin/logs/module-log\'>Click here</a></u> (Module Config > Debug Mode = ON)<br><br>');
echo ('<strong><a href=\'https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/milestones\' target=\'_blank\'>View the milestones/versions on GitHub</a></strong>');
echo '</div>';
// SUPPORT / HEALTH tab in ADMIN GUI
echo '<div id="health" class="tab-pane '.($_GET['tab']=="health" ? "active" : "").'" >' ;
echo ('<h2>System Environment:</h2>Proxmox VE for WHMCS v' . pvewhmcs_version() . ' on PHP v' . phpversion() . ' (' . $_SERVER['SERVER_SOFTWARE'] . ')<br><br>');
echo ('<h2>Technical Support:</h2>Please raise an <a href="https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/issues/new" target="_blank"><u>Issue</u></a> on GitHub - include logs, steps to reproduce, etc.<br><br>');
echo ('<h2>Updates & Codebase:</h2><b>Proxmox for WHMCS is open-source and free to use & improve on!</b><br><a href="https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/" target="_blank">https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/</a><br><br>');
echo ('<h2>Product & Reviewing</h2><b>Your 5-star review on WHMCS Marketplace will help the module grow!</b><br><a href="https://marketplace.whmcs.com/product/6935-proxmox-ve-for-whmcs" target="_blank">https://marketplace.whmcs.com/product/6935-proxmox-ve-for-whmcs</a><br><br>');
echo ('<strong><h2>System Environment</h2></strong><b>Proxmox VE for WHMCS</b> v' . pvewhmcs_version() . ' (GitHub reports latest as <b>v' . get_pvewhmcs_latest_version() . '</b>)' . '<br><b>PHP</b> v' . phpversion() . ' running on <b>' . $_SERVER['SERVER_SOFTWARE'] . '</b> Web Server (' . $_SERVER['SERVER_NAME'] . ')<br><br>');
echo ('<strong><h2>Updates & Codebase</h2></strong><b>Proxmox for WHMCS is open-source and free to use & improve on! ❤️</b><br>Repo: <a href="https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/" target="_blank">https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/</a><br><br>');
echo ('<strong><h2>Product & Reviewing</h2></strong><b style="color:darkgreen;">Your 5-star review on WHMCS Marketplace will help the module grow!</b><br>*****: <a href="https://marketplace.whmcs.com/product/6935-proxmox-ve-for-whmcs" target="_blank">https://marketplace.whmcs.com/product/6935-proxmox-ve-for-whmcs</a><br><br>');
echo ('<strong><h2>Issues: Common Causes</h2></strong>1. <b>WHMCS needs to have >100 Services, else it is an illegal Proxmox VMID.</b><br>2. Save your Package (Plan/Pool)! (configproducts.php?action=edit&id=...#tab=3)<br>3. Where possible, we pass-through the exact error to WHMCS Admin. Check it for info!<br><br>');
echo ('<strong><h2>Module Technical Support</h2></strong>Please raise an <a href="https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/issues/new" target="_blank"><u>Issue</u></a> on GitHub - include logs, steps to reproduce, etc.<br>Help is not guaranteed (FOSS). We will need your assistance. <b>Thank you.</b><br><br>');
echo '</div>';
// Config Tab
@@ -286,7 +340,15 @@ function pvewhmcs_output($vars) {
<tr>
<td class="fieldlabel">VNC Secret</td>
<td class="fieldarea">
<input type="text" size="35" name="vnc_secret" id="vnc_secret" value="'.$config->vnc_secret.'">
<input type="text" size="35" name="vnc_secret" id="vnc_secret" value="'.$config->vnc_secret.'"> Password of "vnc"@"pve" user. Mandatory for VNC proxying. See the <a href="https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/wiki" target="_blank">Wiki</a> for more info.
</td>
</tr>
<tr>
<td class="fieldlabel">Debug Mode</td>
<td class="fieldarea">
<label class="checkbox-inline">
<input type="checkbox" name="debug_mode" value="1" '. ($config->debug_mode=="1" ? "checked" : "").'> Whether or not you want Debug Logging enabled (WHMCS Module Log for Debugging >> /admin/logs/module-log)
</label>
</td>
</tr>
</table>
@@ -306,7 +368,7 @@ function pvewhmcs_output($vars) {
}
}
/* commit module config to DB */
// MODULE CONFIG: Commit changes to the database
function save_config() {
try {
Capsule::connection()->transaction(
@@ -316,6 +378,7 @@ function save_config() {
$connectionManager->table('mod_pvewhmcs')->update(
[
'vnc_secret' => $_POST['vnc_secret'],
'debug_mode' => $_POST['debug_mode'],
]
);
}
@@ -328,7 +391,7 @@ function save_config() {
}
}
/* adding a KVM plan */
// MODULE FORM: Add new KVM Plan
function kvm_plan_add() {
echo '
<form method="post">
@@ -500,7 +563,7 @@ function kvm_plan_add() {
</td>
</tr>
<tr>
<td class="fieldlabel">PVE Storage - Name</td>
<td class="fieldlabel">PVE Store - Name</td>
<td class="fieldarea">
<input type="text" size="8" name="storage" id="storage" value="local" required>
Name of VM/CT Storage on Proxmox VE hypervisor. local/local-lvm/etc.
@@ -563,12 +626,19 @@ function kvm_plan_add() {
</td>
</tr>
<tr>
<td class="fieldlabel">Trunk - VLAN ID</td>
<td class="fieldarea">
<input type="text" size="8" name="vlanid" id="vlanid">
VLAN ID for Plan Services. Default forgoes tagging (VLAN ID), leave blank for untagged.
</td>
</tr>
<tr>
<td class="fieldlabel">
Hardware Virt?
</td>
<td class="fieldarea">
<label class="checkbox-inline">
<input type="checkbox" name="kvm" value="1" checked> Enable KVM hardware virtualisation. (Recommended)
<input type="checkbox" name="kvm" value="1" checked> Enable KVM hardware virtualisation. Requires support/enablement in BIOS. (Recommended)
</label>
</td>
</tr>
@@ -592,7 +662,7 @@ function kvm_plan_add() {
';
}
/* editing a KVM plan */
// MODULE FORM: Edit a KVM Plan
function kvm_plan_edit($id) {
$plan= Capsule::table('mod_pvewhmcs_plans')->where('id', '=', $id)->get()[0];
if (empty($plan)) {
@@ -718,7 +788,7 @@ function kvm_plan_edit($id) {
<td class="fieldlabel">CPU - Weighting</td>
<td class="fieldarea">
<input type="text" size="8" name="cpuunits" id="cpuunits" value="'.$plan->cpuunits.'" required>
Number is relative to weights of all the other running VMs. 8 - 500000 recommended 1024. NOTE: You can disable fair-scheduler configuration by setting this to 0.
Number is relative to weights of all the other running VMs. 8 - 500000 recommended 1024. NOTE: You can disable fair-scheduler by setting this to 0.
</td>
</tr>
<tr>
@@ -772,7 +842,7 @@ function kvm_plan_edit($id) {
</td>
</tr>
<tr>
<td class="fieldlabel">PVE Storage - Name</td>
<td class="fieldlabel">PVE Store - Name</td>
<td class="fieldarea">
<input type="text" size="8" name="storage" id="storage" required value="'.$plan->storage.'">
Name of VM/CT Storage on Proxmox VE hypervisor. local/local-lvm/etc.
@@ -800,14 +870,14 @@ function kvm_plan_edit($id) {
<td class="fieldlabel">Network - Rate</td>
<td class="fieldarea">
<input type="text" size="8" name="netrate" id="netrate" value="'.$plan->netrate.'">
Network Rate Limit in Megabit, Blank means unlimit.
Network Rate Limit in Megabit, Blank means unlimited.
</td>
</tr>
<tr>
<td class="fieldlabel">Network - BW Limit</td>
<td class="fieldarea">
<input type="text" size="8" name="bw" id="bw" value="'.$plan->bw.'">
Monthly Bandwidth Limit in GigaByte, Blank means unlimit.
Monthly Bandwidth Limit in Gigabyte, Blank means unlimited.
</td>
</tr>
<tr>
@@ -835,12 +905,19 @@ function kvm_plan_edit($id) {
</td>
</tr>
<tr>
<td class="fieldlabel">Trunk - VLAN ID</td>
<td class="fieldarea">
<input type="text" size="8" name="vlanid" id="vlanid">
VLAN ID for Plan Services. Default forgoes tagging (VLAN ID), leave blank for untagged.
</td>
</tr>
<tr>
<td class="fieldlabel">
Hardware Virt?
</td>
<td class="fieldarea">
<label class="checkbox-inline">
<input type="checkbox" name="kvm" value="1" '. ($plan->kvm=="1" ? "checked" : "").'> Enable KVM hardware virtualisation. (Recommended)
<input type="checkbox" name="kvm" value="1" '. ($plan->kvm=="1" ? "checked" : "").'> Enable KVM hardware virtualisation. Requires support/enablement in BIOS. (Recommended)
</label>
</td>
</tr>
@@ -864,8 +941,7 @@ function kvm_plan_edit($id) {
';
}
/* adding an LXC plan */
// MODULE FORM: Add an LXC Plan
function lxc_plan_add() {
echo '
<form method="post">
@@ -908,11 +984,11 @@ function lxc_plan_add() {
<td class="fieldlabel">SSD/HDD - Disk</td>
<td class="fieldarea">
<input type="text" size="8" name="disk" id="disk" required>
Disk space in Gigabayte e.g 1024 = 1TB
Disk space in Gigabytes e.g 1024 = 1TB
</td>
</tr>
<tr>
<td class="fieldlabel">PVE Storage - Name</td>
<td class="fieldlabel">PVE Store - Name</td>
<td class="fieldarea">
<input type="text" size="8" name="storage" id="storage" value="local" required>
Name of VM/CT Storage on Proxmox VE hypervisor. local/local-lvm/etc.
@@ -940,6 +1016,13 @@ function lxc_plan_add() {
</td>
</tr>
<tr>
<td class="fieldlabel">Trunk - VLAN ID</td>
<td class="fieldarea">
<input type="text" size="8" name="vlanid" id="vlanid">
VLAN ID for Plan Services. Default forgoes tagging (VLAN ID), leave blank for untagged.
</td>
</tr>
<tr>
<td class="fieldlabel">Network - Rate</td>
<td class="fieldarea">
<input type="text" size="8" name="netrate" id="netrate">
@@ -973,7 +1056,7 @@ function lxc_plan_add() {
';
}
/* editing an LXC plan */
// MODULE FORM: Edit an LXC Plan
function lxc_plan_edit($id) {
$plan= Capsule::table('mod_pvewhmcs_plans')->where('id', '=', $id)->get()[0];
if (empty($plan)) {
@@ -1029,7 +1112,7 @@ function lxc_plan_edit($id) {
</td>
</tr>
<tr>
<td class="fieldlabel">PVE Storage - Name</td>
<td class="fieldlabel">PVE Store - Name</td>
<td class="fieldarea">
<input type="text" size="8" name="storage" id="storage" value="'.$plan->storage.'" required>
Name of VM/CT Storage on Proxmox VE hypervisor. local/local-lvm/etc.
@@ -1057,6 +1140,13 @@ function lxc_plan_edit($id) {
</td>
</tr>
<tr>
<td class="fieldlabel">Trunk - VLAN ID</td>
<td class="fieldarea">
<input type="text" size="8" name="vlanid" id="vlanid">
VLAN ID for Plan Services. Default forgoes tagging (VLAN ID), leave blank for untagged.
</td>
</tr>
<tr>
<td class="fieldlabel">Network - Rate</td>
<td class="fieldarea">
<input type="text" size="8" name="netrate" id="netrate" value="'.$plan->netrate.'">
@@ -1090,6 +1180,7 @@ function lxc_plan_edit($id) {
';
}
// MODULE FORM ACTION: Save KVM Plan
function save_kvm_plan() {
try {
Capsule::connection()->transaction(
@@ -1117,6 +1208,7 @@ function save_kvm_plan() {
'bridge' => $_POST['bridge'],
'vmbr' => $_POST['vmbr'],
'netmodel' => $_POST['netmodel'],
'vlanid' => $_POST['vlanid'],
'netrate' => $_POST['netrate'],
'bw' => $_POST['bw'],
'kvm' => $_POST['kvm'],
@@ -1133,6 +1225,7 @@ function save_kvm_plan() {
}
}
// MODULE FORM ACTION: Update KVM Plan
function update_kvm_plan() {
Capsule::table('mod_pvewhmcs_plans')
->where('id', $_GET['id'])
@@ -1157,6 +1250,7 @@ function update_kvm_plan() {
'bridge' => $_POST['bridge'],
'vmbr' => $_POST['vmbr'],
'netmodel' => $_POST['netmodel'],
'vlanid' => $_POST['vlanid'],
'netrate' => $_POST['netrate'],
'bw' => $_POST['bw'],
'kvm' => $_POST['kvm'],
@@ -1168,13 +1262,15 @@ function update_kvm_plan() {
header("Location: ".pvewhmcs_BASEURL."&tab=vmplans&action=planlist");
}
// MODULE FORM ACTION: Remove Plan
function remove_plan($id) {
Capsule::table('mod_pvewhmcs_plans')->where('id', '=', $id)->delete();
header("Location: ".pvewhmcs_BASEURL."&tab=vmplans&action=planlist");
$_SESSION['pvewhmcs']['infomsg']['title']='Plan Deleted.' ;
$_SESSION['pvewhmcs']['infomsg']['message']='Selected Item deleted successfuly.' ;
}
// MODULE FORM ACTION: Save LXC Plan
function save_lxc_plan() {
try {
Capsule::connection()->transaction(
@@ -1196,6 +1292,7 @@ function save_lxc_plan() {
'bridge' => $_POST['bridge'],
'vmbr' => $_POST['vmbr'],
'netmodel' => $_POST['netmodel'],
'vlanid' => $_POST['vlanid'],
'netrate' => $_POST['netrate'],
'bw' => $_POST['bw'],
'onboot' => $_POST['onboot'],
@@ -1211,6 +1308,7 @@ function save_lxc_plan() {
}
}
// MODULE FORM ACTION: Update LXC Plan
function update_lxc_plan() {
Capsule::table('mod_pvewhmcs_plans')
->where('id', $_GET['id'])
@@ -1229,6 +1327,7 @@ function update_lxc_plan() {
'bridge' => $_POST['bridge'],
'vmbr' => $_POST['vmbr'],
'netmodel' => $_POST['netmodel'],
'vlanid' => $_POST['vlanid'],
'netrate' => $_POST['netrate'],
'bw' => $_POST['bw'],
'onboot' => $_POST['onboot'],
@@ -1239,7 +1338,7 @@ function update_lxc_plan() {
header("Location: ".pvewhmcs_BASEURL."&tab=vmplans&action=planlist");
}
// List IP pools in table
// IP POOLS: List all Pools
function list_ip_pools() {
echo '<a class="btn btn-default" href="'. pvewhmcs_BASEURL .'&amp;tab=ippools&amp;action=new_ip_pool"><i class="fa fa-plus-square"></i>&nbsp; New IP Pool</a>';
echo '<table class="datatable"><tr><th>ID</th><th>Pool</th><th>Gateway</th><th>Action</th></tr>';
@@ -1257,7 +1356,7 @@ function list_ip_pools() {
echo '</table>';
}
//create new IP pool
// IP POOL FORM: Add IP Pool
function add_ip_pool() {
echo '
<form method="post">
@@ -1279,6 +1378,7 @@ function add_ip_pool() {
';
}
// IP POOL FORM ACTION: Save Pool
function save_ip_pool() {
try {
Capsule::connection()->transaction(
@@ -1301,6 +1401,7 @@ function save_ip_pool() {
}
}
// IP POOL FORM ACTION: Remove Pool
function removeIpPool($id) {
Capsule::table('mod_pvewhmcs_ip_addresses')->where('pool_id', '=', $id)->delete();
Capsule::table('mod_pvewhmcs_ip_pools')->where('id', '=', $id)->delete();
@@ -1310,7 +1411,7 @@ function removeIpPool($id) {
$_SESSION['pvewhmcs']['infomsg']['message']='Deleted the IP Pool successfully.' ;
}
// add IP address/subnet to Pool
// IP POOL FORM ACTION: Add IP to Pool
function add_ip_2_pool() {
require_once(ROOTDIR.'/modules/addons/pvewhmcs/Ipv4/Subnet.php');
echo '<form method="post">
@@ -1370,7 +1471,7 @@ function add_ip_2_pool() {
}
}
// List IP addresses in pool
// IP POOL FORM: List IPs in Pool
function list_ips() {
//echo '<script>$(function() {$( "#dialog" ).dialog();});</script>' ;
//echo '<div id="dialog">' ;
@@ -1387,7 +1488,7 @@ function list_ips() {
}
// Remove IP Address
// IP POOL FORM ACTION: Remove IP from Pool
function removeip($id,$pool_id) {
Capsule::table('mod_pvewhmcs_ip_addresses')->where('id', '=', $id)->delete();
header("Location: ".pvewhmcs_BASEURL."&tab=ippools&action=list_ips&id=".$pool_id);

View File

@@ -1,24 +1,33 @@
<?php
// FILE: novnc_router.php
// REPO: https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/
// TASK: Take WHMCS request, add browser cookie, then redirect to noVNC
// NOTE: Anti-CSRF means the Domain for both WHMCS and PVE must be the same, ONLY the Subdomain can differ.
if (isset($_GET['pveticket']) && isset($_GET['host']) && isset($_GET['path']) && isset($_GET['vncticket'])) {
// Take passed-in variables and re-assign for usage
$pveticket = $_GET['pveticket'];
$vncticket = $_GET['vncticket'];
$host = $_GET['host'];
$path = $_GET['path'];
// Get the requesting hostname/domain from request
$whmcsdomain = parse_url($_SERVER['HTTP_HOST']);
$domainonly = preg_replace("/^(.*?)\.(.*)$/","$2",$whmcsdomain['path']);
// Get the requesting hostname/domain from the WHMCS-originated request
$whmcsdomain = parse_url($_SERVER['HTTP_HOST']);
// Now extract just the domain parts we need (FUTURE: capacity/option for multi-part TLDs)
$domainonly = preg_replace("/^(.*?)\.(.*)$/","$2",$whmcsdomain['path']);
// Set the cookie as Proxmox will be expecting it, so it is WHMCS to VNC without further login
setrawcookie('PVEAuthCookie', $pveticket, 0, '/', $domainonly);
// Create the final noVNC URL with the re-encoded vncticket
$hostname = gethostbyaddr($host);
$redirect_url = '/modules/servers/pvewhmcs/novnc/vnc.html?autoconnect=true&encrypt=true&host=' . $hostname . '&port=8006&password=' . urlencode($vncticket) . '&path=' . urlencode($path);
// Redirect the visitor to noVNC & we're done
header('Location: ' . $redirect_url);
exit;
} else {
// Passed in values not present, exit
echo 'Error: Missing required info to route your request. Please try again.';
exit;
}
?>
?>

View File

@@ -1,4 +1,5 @@
<?php
// Require the PHP API Class to interact with Proxmox VE
if (file_exists('../modules/addons/pvewhmcs/proxmox.php'))
require_once('../modules/addons/pvewhmcs/proxmox.php');
else
@@ -8,6 +9,7 @@ use Illuminate\Database\Capsule\Manager as Capsule;
global $guest ;
// WHMCS CONFIG > SERVICES/PRODUCTS > Their Service > Tab #3 (Plan/Pool)
function pvewhmcs_ConfigOptions() {
// Reterive PVE for WHMCS Cluster
$server=Capsule::table('tblservers')->where('type', '=', 'pve-whmcs')->get()[0] ;
@@ -59,7 +61,19 @@ function pvewhmcs_ConfigOptions() {
return $configarray;
}
// PVE API FUNCTION: Create the Service on the Hypervisor
function pvewhmcs_CreateAccount($params) {
// Make sure "WHMCS Admin > Products/Services > Proxmox-based Service -> Plan + Pool" are set. Else, fail early. (Issue #36)
if (!isset($params['configoption1'], $params['configoption2'])) {
throw new Exception("PVEWHMCS Error: Missing Config. Service/Product WHMCS Config not saved (Plan/Pool not assigned to WHMCS Service type). Check Support/Health tab in Module Config for info. Quick and easy fix.");
}
if (empty($params['configoption1'])) {
throw new Exception("PVEWHMCS Error: Missing Config. Service/Product WHMCS Config not saved (Plan/Pool not assigned to WHMCS Service type). Check Support/Health tab in Module Config for info. Quick and easy fix.");
}
if (empty($params['configoption2'])) {
throw new Exception("PVEWHMCS Error: Missing Config. Service/Product WHMCS Config not saved (Plan/Pool not assigned to WHMCS Service type). Check Support/Health tab in Module Config for info. Quick and easy fix.");
}
// Retrieve Plan from table
$plan = Capsule::table('mod_pvewhmcs_plans')->where('id', '=', $params['configoption1'])->get()[0];
@@ -74,7 +88,7 @@ function pvewhmcs_CreateAccount($params) {
// CREATE IF QEMU/KVM
if (!empty($params['customfields']['KVMTemplate'])) {
file_put_contents('d:\log.txt', $params['customfields']['KVMTemplate']);
// file_put_contents('d:\log.txt', $params['customfields']['KVMTemplate']);
$proxmox = new PVE2_API($serverip, $serverusername, "pam", $serverpassword);
if ($proxmox->login()) {
@@ -86,12 +100,14 @@ function pvewhmcs_CreateAccount($params) {
$vm_settings['name'] = "vps" . $params["serviceid"] . "-cus" . $params['clientsdetails']['userid'];
$vm_settings['full'] = true;
// DEBUG - Log the request parameters before it's fired
logModuleCall(
'pvewhmcs',
__FUNCTION__,
'vm_settings_and_v_1',
['vm_settings' => $vm_settings, 'v' => $v]
);
if (Capsule::table('mod_pvewhmcs')->where('id', '1')->value('debug_mode') == 1) {
logModuleCall(
'pvewhmcs',
__FUNCTION__,
'vm_settings_and_v_1',
['vm_settings' => $vm_settings, 'v' => $v]
);
}
$response = $proxmox->post('/nodes/' . $first_node . '/qemu/' . $params['customfields']['KVMTemplate'] . '/clone', $vm_settings);
if ($response) {
Capsule::table('mod_pvewhmcs_vms')->insert(
@@ -128,7 +144,11 @@ function pvewhmcs_CreateAccount($params) {
$vm_settings['rootfs'] = $plan->storage . ':' . $plan->disk;
$vm_settings['bwlimit'] = $plan->diskio;
$vm_settings['net0'] = 'name=eth0,bridge=' . $plan->bridge . $plan->vmbr . ',ip=' . $ip->ipaddress . '/' . mask2cidr($ip->mask) . ',gw=' . $ip->gateway;
if(!empty($plan->vlanid)){
$vm_settings['net0'] .= ',trunk=' . $plan->vlanid;
}
$vm_settings['nameserver'] = '1.1.1.1';
$vm_settings['onboot'] = $plan->onboot;
$vm_settings['password'] = $params['customfields']['Password'];
} else {
$vm_settings['ostype'] = $plan->ostype;
@@ -160,6 +180,9 @@ function pvewhmcs_CreateAccount($params) {
if (!empty($plan->netrate)) {
$vm_settings['net0'] .= ',rate=' . $plan->netrate;
}
if (!empty($plan->vlanid)) {
$vm_settings['net0'] .= ',trunk=' . $plan->vlanid;
}
}
/* end of network settings */
}
@@ -184,12 +207,14 @@ function pvewhmcs_CreateAccount($params) {
}
// DEBUG - Log the request parameters before it's fired
logModuleCall(
'pvewhmcs',
__FUNCTION__,
'vm_settings_and_v_2',
['vm_settings' => $vm_settings, 'v' => $v]
);
if (Capsule::table('mod_pvewhmcs')->where('id', '1')->value('debug_mode') == 1) {
logModuleCall(
'pvewhmcs',
__FUNCTION__,
'vm_settings_and_v_2',
['vm_settings' => $vm_settings, 'v' => $v]
);
}
$response = $proxmox->post('/nodes/' . $first_node . '/' . $v, $vm_settings);
if ($response) {
unset($vm_settings);
@@ -220,21 +245,22 @@ function pvewhmcs_CreateAccount($params) {
}
} catch (PVE2_Exception $e) {
// Record the error in WHMCS's module log.
logModuleCall(
'pvewhmcs',
__FUNCTION__,
$params,
$e->getMessage(),
$e->getTraceAsString()
);
if (Capsule::table('mod_pvewhmcs')->where('id', '1')->value('debug_mode') == 1) {
logModuleCall(
'pvewhmcs',
__FUNCTION__,
$params,
$e->getMessage(),
$e->getTraceAsString()
);
}
return $e->getMessage();
}
unset($vm_settings);
}
}
// PVE API FUNCTION, ADMIN: Test Connection with Proxmox node
function pvewhmcs_TestConnection(array $params) {
try {
// Call the service's connection test function.
@@ -246,14 +272,16 @@ function pvewhmcs_TestConnection(array $params) {
$success = true;
$errorMsg = '';
} catch (Exception $e) {
// Record the error in WHMCS's module log.
logModuleCall(
'provisioningmodule',
__FUNCTION__,
$params,
$e->getMessage(),
$e->getTraceAsString()
);
// Record the error in WHMCS's module log, if debug mode is enabled.
if (Capsule::table('mod_pvewhmcs')->where('id', '1')->value('debug_mode') == 1) {
logModuleCall(
'pvewhmcs',
__FUNCTION__,
$params,
$e->getMessage(),
$e->getTraceAsString()
);
}
$success = false;
$errorMsg = $e->getMessage();
}
@@ -263,42 +291,54 @@ function pvewhmcs_TestConnection(array $params) {
);
}
// PVE API FUNCTION, ADMIN: Suspend a Service on the hypervisor
function pvewhmcs_SuspendAccount(array $params) {
$serverip = $params["serverip"]; $serverusername = $params["serverusername"]; $serverpassword = $params["serverpassword"];
$serverip = $params["serverip"];
$serverusername = $params["serverusername"];
$serverpassword = $params["serverpassword"];
$proxmox=new PVE2_API($serverip, $serverusername, "pam", $serverpassword);
if ($proxmox->login()){
if ($proxmox->login()) {
# Get first node name.
$nodes = $proxmox->get_node_list();
$first_node = $nodes[0];
unset($nodes);
// find virtual machine type
$vm=Capsule::table('mod_pvewhmcs_vms')->where('id', '=', $params['serviceid'])->get()[0];
if ($proxmox->post('/nodes/'.$first_node.'/'.$vm->vtype.'/'.$params['serviceid'].'/status/suspend')) {
return true ;
}
$guest=Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$pve_cmdparam = array();
if ($proxmox->post('/nodes/' . $first_node . '/' . $guest->vtype . '/' . $params['serviceid'] . '/status/stop' , $pve_cmdparam))
return "success" ;
}
return false;
$response_message = json_encode($proxmox['data']['errors']);
return "Error performing action. " . $response_message;
}
// PVE API FUNCTION, ADMIN: Unsuspend a Service on the hypervisor
function pvewhmcs_UnsuspendAccount(array $params) {
$serverip = $params["serverip"]; $serverusername = $params["serverusername"]; $serverpassword = $params["serverpassword"];
$serverip = $params["serverip"];
$serverusername = $params["serverusername"];
$serverpassword = $params["serverpassword"];
$proxmox=new PVE2_API($serverip, $serverusername, "pam", $serverpassword);
if ($proxmox->login()){
if ($proxmox->login()) {
# Get first node name.
$nodes = $proxmox->get_node_list();
$first_node = $nodes[0];
unset($nodes);
// find virtual machine type
$vm=Capsule::table('mod_pvewhmcs_vms')->where('id', '=', $params['serviceid'])->get()[0];
if ($proxmox->post('/nodes/'.$first_node.'/'.$vm->vtype.'/'.$params['serviceid'].'/status/resume')) {
return true ;
}
$guest=Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$pve_cmdparam = array();
if ($proxmox->post('/nodes/' . $first_node . '/' . $guest->vtype . '/' . $params['serviceid'] . '/status/start' , $pve_cmdparam))
return "success" ;
}
return false;
$response_message = json_encode($proxmox['data']['errors']);
return "Error performing action. " . $response_message;
}
// PVE API FUNCTION, ADMIN: Terminate a Service on the hypervisor
function pvewhmcs_TerminateAccount(array $params) {
$serverip = $params["serverip"]; $serverusername = $params["serverusername"]; $serverpassword = $params["serverpassword"];
$serverip = $params["serverip"];
$serverusername = $params["serverusername"];
$serverpassword = $params["serverpassword"];
$proxmox=new PVE2_API($serverip, $serverusername, "pam", $serverpassword);
if ($proxmox->login()){
# Get first node name.
@@ -306,19 +346,21 @@ function pvewhmcs_TerminateAccount(array $params) {
$first_node = $nodes[0];
unset($nodes);
// find virtual machine type
$vm=Capsule::table('mod_pvewhmcs_vms')->where('id', '=', $params['serviceid'])->get()[0];
$proxmox->post('/nodes/'.$first_node.'/'.$vm->vtype.'/'.$params['serviceid'].'/status/stop') ;
sleep(10) ;
if ($proxmox->delete('/nodes/'.$first_node.'/'.$vm->vtype.'/'.$params['serviceid'],array('skiplock'=>1))) {
$guest=Capsule::table('mod_pvewhmcs_vms')->where('id', '=', $params['serviceid'])->get()[0];
// stop the service before terminating
$proxmox->post('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'].'/status/stop') ;
sleep(30) ;
if ($proxmox->delete('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'],array('skiplock'=>1))) {
// delete entry from module table once service terminated in PVE
Capsule::table('mod_pvewhmcs_vms')->where('id', '=', $params['serviceid'])->delete();
return true ;
return "success";
}
}
return false ;
$response_message = json_encode($proxmox['data']['errors']);
return "Error performing action. " . $response_message;
}
// WHMCS Decrypter
// GENERAL CLASS: WHMCS Decrypter
class hash_encryption {
/**
* Hashed value of the user provided encryption key
@@ -508,6 +550,7 @@ class hash_encryption {
}
}
// GENERAL FUNCTION: Server PW from WHMCS DB
function get_server_pass_from_whmcs($enc_pass){
global $cc_encryption_hash;
// Include WHMCS database configuration file
@@ -519,19 +562,32 @@ function get_server_pass_from_whmcs($enc_pass){
return $hasher->decrypt($enc_pass);
}
// MODULE BUTTONS: Admin Interface button regos
function pvewhmcs_AdminCustomButtonArray() {
$buttonarray = array(
"Start" => "vmStart",
"Reboot" => "vmReboot",
"Soft Stop" => "vmShutdown",
"Hard Stop" => "vmStop",
);
return $buttonarray;
}
// MODULE BUTTONS: Client Interface button regos
function pvewhmcs_ClientAreaCustomButtonArray() {
$buttonarray = array(
"<img src='./modules/servers/pvewhmcs/img/novnc.png'/> noVNC (HTML5)" => "noVNC",
"<img src='./modules/servers/pvewhmcs/img/tigervnc.png'/> TigerVNC (Java)" => "javaVNC",
"<i class='fa fa-2x fa-flag-checkered'></i> Start Machine" => "vmStart",
"<i class='fa fa-2x fa-sync'></i> Reboot Now" => "vmReboot",
"<i class='fa fa-2x fa-power-off'></i> Shut Down" => "vmShutdown",
"<i class='fa fa-2x fa-power-off'></i> Power Off" => "vmShutdown",
"<i class='fa fa-2x fa-stop'></i> Hard Stop" => "vmStop",
"<i class='fa fa-2x fa-chart-bar'></i> Statistics" => "vmStat",
);
return $buttonarray;
}
// OUTPUT: Module output to the Client Area
function pvewhmcs_ClientArea($params) {
// Retrieve virtual machine info from table mod_pvewhmcs_vms
$guest=Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
@@ -707,11 +763,18 @@ function pvewhmcs_ClientArea($params) {
);
}
// OUTPUT: VM Statistics/Graphs render to Client Area
function pvewhmcs_vmStat($params) {
return true ;
return true;
}
// VNC: Console access to VM/CT via noVNC
function pvewhmcs_noVNC($params) {
// Check if VNC Secret is configured in Module Config, fail early if not. (#27)
if (strlen(Capsule::table('mod_pvewhmcs')->where('id', '1')->value('vnc_secret'))<15) {
throw new Exception("PVEWHMCS Error: VNC Secret in Module Config either not set or not long enough. Recommend 20+ characters for security.");
}
// Get login credentials then make the Proxmox connection attempt.
$serverip = $params["serverip"];
$serverusername = 'vnc';
$serverpassword = Capsule::table('mod_pvewhmcs')->where('id', '1')->value('vnc_secret');
@@ -729,19 +792,24 @@ function pvewhmcs_noVNC($params) {
$vncticket = $vm_vncproxy['ticket'];
// $path should only contain the actual path without any query parameters
$path = 'api2/json/nodes/' . $first_node . '/' . $guest->vtype . '/' . $params['serviceid'] . '/vncwebsocket?port=' . $vm_vncproxy['port'] . '&vncticket=' . urlencode($vncticket);
// Construct the noVNC Router URL with the path already prepared now
$url = '/modules/servers/pvewhmcs/novnc_router.php?host=' . $serverip . '&pveticket=' . urlencode($pveticket) . '&path=' . urlencode($path) . '&vncticket=' . urlencode($vncticket);
// Build and deliver the noVNC Router hyperlink for access
$vncreply='<center><strong>Console (noVNC) prepared for usage. <a href="'.$url.'" target="_blanK">Click here</a> to open the noVNC window.</strong></center>' ;
return $vncreply;
} else {
$vncreply='Failed to prepare noVNC. Please contact Technical Support.';
return $vncreply;
}
}
// VNC: Console access to VM/CT via TigerVNC
function pvewhmcs_javaVNC($params){
// Check if VNC Secret is configured in Module Config, fail early if not. (#27)
if (strlen(Capsule::table('mod_pvewhmcs')->where('id', '1')->value('vnc_secret'))<15) {
throw new Exception("PVEWHMCS Error: VNC Secret in Module Config either not set or not long enough. Recommend 20+ characters for security.");
}
// Get login credentials then make the Proxmox connection attempt.
$serverip = $params["serverip"];
$serverusername = 'vnc';
$serverpassword = Capsule::table('mod_pvewhmcs')->where('id', '1')->value('vnc_secret');
@@ -774,6 +842,7 @@ function pvewhmcs_javaVNC($params){
}
}
// PVE API FUNCTION, CLIENT/ADMIN: Start the VM/CT
function pvewhmcs_vmStart($params) {
// Gather access credentials for PVE, as these are no longer passed for Client Area
$pveservice=Capsule::table('tblhosting')->find($params['serviceid']) ;
@@ -794,14 +863,14 @@ function pvewhmcs_vmStart($params) {
unset($nodes);
$guest=Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$pve_cmdparam = array();
// $pve_cmdparam['timeout'] = '60';
if ($proxmox->post('/nodes/' . $first_node . '/' . $guest->vtype . '/' . $params['serviceid'] . '/status/start' , $pve_cmdparam))
return true ;
return "success" ;
}
return false;
$response_message = json_encode($proxmox['data']['errors']);
return "Error performing action. " . $response_message;
}
// PVE API FUNCTION, CLIENT/ADMIN: Reboot the VM/CT
function pvewhmcs_vmReboot($params) {
// Gather access credentials for PVE, as these are no longer passed for Client Area
$pveservice=Capsule::table('tblhosting')->find($params['serviceid']) ;
@@ -825,11 +894,13 @@ function pvewhmcs_vmReboot($params) {
// $pve_cmdparam['timeout'] = '60';
if ($proxmox->post('/nodes/' . $first_node . '/' . $guest->vtype . '/' . $params['serviceid'] . '/status/reboot' , $pve_cmdparam))
return true ;
return "success" ;
}
return false;
$response_message = json_encode($proxmox['data']['errors']);
return "Error performing action. " . $response_message;
}
// PVE API FUNCTION, CLIENT/ADMIN: Shutdown the VM/CT
function pvewhmcs_vmShutdown($params) {
// Gather access credentials for PVE, as these are no longer passed for Client Area
$pveservice=Capsule::table('tblhosting')->find($params['serviceid']) ;
@@ -853,11 +924,13 @@ function pvewhmcs_vmShutdown($params) {
// $pve_cmdparam['timeout'] = '60';
if ($proxmox->post('/nodes/' . $first_node . '/' . $guest->vtype . '/' . $params['serviceid'] . '/status/shutdown' , $pve_cmdparam))
return true ;
return "success" ;
}
return false;
$response_message = json_encode($proxmox['data']['errors']);
return "Error performing action. " . $response_message;
}
// PVE API FUNCTION, CLIENT/ADMIN: Stop the VM/CT
function pvewhmcs_vmStop($params) {
// Gather access credentials for PVE, as these are no longer passed for Client Area
$pveservice=Capsule::table('tblhosting')->find($params['serviceid']) ;
@@ -881,12 +954,13 @@ function pvewhmcs_vmStop($params) {
// $pve_cmdparam['timeout'] = '60';
if ($proxmox->post('/nodes/' . $first_node . '/' . $guest->vtype . '/' . $params['serviceid'] . '/status/stop' , $pve_cmdparam))
return true ;
return "success" ;
}
return false;
$response_message = json_encode($proxmox['data']['errors']);
return "Error performing action. " . $response_message;
}
// convert subnet mask to CIDR
// NETWORKING FUNCTION: Convert subnet mask to CIDR
function mask2cidr($mask){
$long = ip2long($mask);
$base = ip2long('255.255.255.255');

1
version Normal file
View File

@@ -0,0 +1 @@
1.2.2