36 Commits

Author SHA1 Message Date
Luke S Thompson
7c6e5df65c v1.2.4 into C'LOG (date) 2024-05-19 14:42:54 +10:00
Luke S Thompson
b98fc9f3d1 (v1.2.4) version bump core file 2024-05-19 14:36:53 +10:00
Luke S Thompson
0ab97dcf1c Fork IPv6 to separate vNIC (#33) untested 2024-05-19 14:06:49 +10:00
Luke S Thompson
02c2bb7b75 Tidy-up wording (VNC) 2024-05-19 13:19:27 +10:00
Luke S Thompson
0cb3e59904 Improve PVE VNC perms wording (#70) 2024-05-19 13:15:23 +10:00
Luke S Thompson
422f6241f2 Improve tabbing & comments 2024-05-19 12:40:13 +10:00
Luke S Thompson
ecbe3e09d7 TestConnection = debug log always (if fail)
Ignore module setting for this, to help first-steps diagnostics
2024-05-19 10:58:41 +10:00
Luke S Thompson
bbe0f8455a TestConnection OK (#70) 2024-05-19 10:11:27 +10:00
Luke S Thompson
2142ff71d7 TestConnection (C'LOG into v1.2.4) 2024-05-19 09:42:16 +10:00
Luke S Thompson
12d3150f38 Improve TestConnection (re: #70) 2024-05-19 09:40:47 +10:00
Luke S Thompson
0cf0b54354 Add #32 CT post-clone re-spec (C'LOG) 2024-05-02 12:34:28 +10:00
Luke S Thompson
43171ca782 Minor tidy-up 2024-05-02 12:15:22 +10:00
Luke S Thompson
a1901aaedd Improve spacing, mostly around PVE2_API 2024-05-02 12:09:12 +10:00
Luke S Thompson
ad5da6c31f Clarify on current v6 support 2024-05-02 11:52:23 +10:00
Luke S Thompson
e854971f10 v1.2.4 update: IPv6 SQL Columns 2024-05-02 11:50:09 +10:00
Luke S Thompson
ddbc25b1f5 Pass in 2 params for post-clone tweaks #32 2024-05-02 11:45:31 +10:00
Luke S Thompson
55232a8354 v6: off/DHCP/SLAAC options 2024-05-02 11:40:34 +10:00
Luke S Thompson
f0c2d3e7a4 v6 configurability into C'LOG 2024-05-02 11:39:11 +10:00
Luke S Thompson
2f7c769260 GUI tab name VM > VM/CT Plans 2024-05-02 11:34:45 +10:00
Luke S Thompson
f32483320b IPv6 option config into GUI (partial) #33 2024-05-02 10:46:00 +10:00
Luke S Thompson
5411250bb1 IPv6 config-based exec/actions #33 2024-05-02 10:32:42 +10:00
Luke S Thompson
d7f6bf2b88 Plan/IPv6 Y/N & Service/v6 Prefix (SQL Storage) #33 2024-05-02 10:15:57 +10:00
Luke S Thompson
ea3956a177 SLAAC IPv6 (#33 partial) into C'LOG 2024-05-01 17:04:13 +10:00
Luke S Thompson
419e5114d7 Mention IPv6 SLAAC 2024-05-01 17:00:52 +10:00
Luke S Thompson
a63bfd6a12 IPv6 via SLAAC; tidy-up comments 2024-05-01 16:59:16 +10:00
Luke S Thompson
84d6afa4e3 Strip of []() links per WHMCS Marketplace restrictions 2024-04-30 09:52:38 +10:00
Luke S Thompson
96bbd91808 Corporate domain updates 2024-04-01 09:00:32 +10:00
Luke S Thompson
a85da71327 Add TBC v1.2.4 to C'LOG 2024-02-02 18:42:59 +10:00
Luke S Thompson
2d04e30b79 2nd attempt for Issue #67 2024-02-02 07:09:54 +10:00
Luke S Thompson
6ac82ea0d4 db.sql > ./db.sql (try fix Issue #67) 2024-02-01 17:33:51 +10:00
Luke S Thompson
b898d4a809 Merge branch 'master' of https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS 2024-01-01 11:00:48 +10:00
Luke S Thompson
82fe49ee01 Improve reliability of db.sql import on-activation 2024-01-01 11:00:45 +10:00
Luke S Thompson
5e5ccee2b4 Bring in 2nd line for 1 sub-cat 2024-01-01 10:39:39 +10:00
Luke S Thompson
12037a1f1b Emphasis in all sub-cats of VM/CT conf 2024-01-01 10:38:42 +10:00
Luke S Thompson
e39d64a3d5 Explicit hyperlinks for all URLs 2024-01-01 10:31:30 +10:00
Luke S Thompson
d5965759a4 Try direct link to #reviews (Marketplace) 2024-01-01 10:25:32 +10:00
6 changed files with 418 additions and 241 deletions

View File

@@ -1,6 +1,19 @@
# Changelog
All notable changes to Proxmox VE for WHMCS will be documented in this file.
## [1.2.4] - 2024-05-19 - _"Fine tuning"_
### 🚀 Feature
- IPv6: By default, new instances will be created with SLAAC configured. (#33)
- IPv6: Ability to configure off/DHCP/SLAAC via VM/CT Plan setting. (#33)
### 💅 Polish
- CT Specs: Now amended post-clone, to ensure they match the Plan. (#32)
### 🐛 Bug Fix
- db.sql: Improve logic with SQL import to pull from relative dir. (#67)
- Connection Test (WHMCS Server): Refine fallback/normal logic (re: #70)
## [1.2.3] - 2023-12-31 - _"NY Tidy-up 123"_
### 🚀 Feature

View File

@@ -5,20 +5,23 @@
<img alt="Logo for the Proxmox VE for WHMCS module" src="zLOGO.png">
- 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-virtual-environment/features) from [WHMCS](https://www.whmcs.com/tour/) easily
- Automatically Provision VMs & CTs in **Proxmox VE** from **WHMCS** 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 :)
- Leverage the power of QEMU & LXC with PVE's convenience
Repo: https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/
## ❤️ RTFM: Read the Manual & Review the Module!
**Please read the entire README.md file before getting started with Proxmox VE for WHMCS.** Thanks!
We're pretty much done overhauling the Module to suit our needs at [The Network Crew Pty Ltd (TNC)](https://thenetworkcrew.com.au).
We're pretty much done overhauling the Module to suit our needs at The Network Crew Pty Ltd & Merlot Digital.
> **Please review the module!** https://marketplace.whmcs.com/product/6935-proxmox-ve-for-whmcs
> **Please review the module!** https://marketplace.whmcs.com/product/6935-proxmox-ve-for-whmcs#reviews
>
> If you want it to remain free and fabulous, it could use a moment of your time in reviewing it. Thanks!
> _If you want it to remain free and fabulous, it could use a moment of your time in reviewing it._ **Thanks!**
## 🎯 MODULE: System Requirements (PVE/WHMCS)
@@ -52,7 +55,7 @@ Once you've done all of that, in order to get the module working properly, you n
## 🥽 noVNC: Console Tunnel (Client Area)
After forking the module, we considered how to improve security of Console Tunneling via WHMCS. We decided to implement a routing method which uses a secondary user in Proxmox VE with very restrictive permissions. This requires more work to make it function, however improves security.
After forking the module, we considered how to improve security of Console Tunneling via WHMCS. We decided to implement a routing method which uses a secondary user in Proxmox VE with very restrictive permissions. This is due to be re-built again to further enhance security.
### To offer VNC via WHMCS Client Area
@@ -75,13 +78,15 @@ Additionally, to improve security, for VNC you must also have a Restricted User.
### Creating the VNC user within PVE
1. Create User Group "VNC" via PVE > Datacenter / Permissions / Group
2. Create new User "vnc" > Datacenter / Permissions / Users - select Group: "VNC", Realm: pve
3. Create new Role -> Datacenter / Permissions / Roles - select Name: "VNC", Privileges: VM.Console (only)
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.
1. Create User Group "VNC" via PVE > ` Datacenter / Permissions / Group`
2. Create new User "vnc" > `Datacenter / Permissions / Users` - Group: "VNC", Realm: pve
3. Create new Role -> `Datacenter / Permissions / Roles` - Name: "VNC", Privileges: VM.Console (only)
4. Permit VNC Access -> `Datacenter / Permissions / Add Group Permissions` - Group: "VNC", Role: "VNC"
5. WHMCS > Modules > Proxmox VE for WHMCS > Module Config > VNC Secret = 'vnc' password (PVE) you set
> Do NOT set less restrictive permissions. The above is designed for hypervisor security.
>
> However, if you wish for proper security, wait for VNC to be further improved.
## ⚙️ VM/CT PLANS: Setting everything up
@@ -103,15 +108,14 @@ Use that ID in the Custom Field `KVMTemplate`, as in `ID|Name`.
Firstly, create the Plan in WHMCS Module. Then, WHMCS Config > Services.
Under the Service, you need to add a Custom Field `ISO` with the full location.
> Under the Service, you need to add a Custom Field `ISO` with the full location.
### CT Option: LXC, using PVE Template File
Firstly, store the Template in PVE. You need its unique File Name.
Use that full file name in the Custom Field `Template`, as in:
`ubuntu-99.99-standard_amd64.tar.gz|Ubuntu 99`
> Use that full file name in the Custom Field `Template`, as in:<br>
> `ubuntu-99.99-standard_amd64.tar.gz|Ubuntu 99`
Then make a 2nd Custom Field `Password` for the CT's root user.
@@ -121,13 +125,15 @@ Please make sure you create an IP Pool with sufficient scope/size to be able to
**Private IPs for PVE Hosts:** Note that VNC may be problematic without work due to the strict requirements introduced in Proxmox v8.0 (strict same-site attribute).
### IPv6: Not yet functional! 😐
### IPv6: SLAAC default, same vNIC
Per The-Network-Crew/Proxmox-VE-for-WHMCS#33 there is not yet functional IPv6 in this module.
Per The-Network-Crew/Proxmox-VE-for-WHMCS#33 there is off/DHCP/SLAAC available (dual-stack vNIC) as of May 2024.
You can of course add this via PVE/`pvesh` manually, however it isn't module-supported as of late 2023.
You can of course add different config via PVE/`pvesh` manually, if you need to specify a prefix.
## 💅 FEATURES: PVE v8.0/8.1 bling
We're exploring the expansion of IPv6 support through the Issue Tracker. (**ie. fork to eth1.**)
## 💅 FEATURES: PVE v8.x bling
There are new features deployed into Proxmox VE upstream in the v8 branch which are exciting and should be added to this module.
@@ -143,7 +149,14 @@ There are new features deployed into Proxmox VE upstream in the v8 branch which
3. New flexible notification system (SMTP & Gotify).
4. MAC Organizationally Unique Identifier (OUI) BC:24:11: prefix!
Reference: https://pve.proxmox.com/wiki/Roadmap
### Proxmox 8.2
1. Import Wizard for Guests.
2. Unattended PVE Install (answer file).
3. Backup Fleecing (local disk as data block buffer).
4. Firewall Preview (based on nftables).
PVE Roadmap: https://pve.proxmox.com/wiki/Roadmap
## 🤬 ABUSE: Zero Tolerance (ZT)
@@ -157,16 +170,16 @@ If you cannot accept this, do not download nor use the code. Complaints, nasty r
## 🆘 HELP: Best-effort Support
**Before raising a [GitHub Issue](https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/issues), please check:**
**Before raising a GitHub Issue, please check:**
1. The [Wiki](https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/wiki)
2. The [README.md](https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/tree/master)
3. Open [GitHub Issues](https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/issues)
1. The Wiki.
2. The README.md.
3. Open GitHub Issues on the repo.
4. HTTP, PHP, WHMCS & debug logs (see below).
5. PVE logs; best practices; network; etc.
6. Read the errors. Do they explain it?
> Help: Including logs, details, steps to reproduce, etc, please raise a [GitHub Issue](https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/issues).
> Help: Including logs, details, steps to reproduce, etc, please raise a **GitHub Issue**.
>
> Logs: We work to ensure that Proxmox VE for WHMCS passes through error details to you.
@@ -189,11 +202,11 @@ If you cannot accept this, do not download nor use the code. Complaints, nasty r
The more info/context you provide up-front, the quicker & easier it will be!
\* Debug: Make sure you enable Debug Logging in the Module Settings, as needed.
\* Debug: Also enable Debug Logging in Proxmox VE for WHMCS > Settings, as needed.
**Please note that this is FOSS and Support is not guaranteed at all.**
**If you don't read, listen or actively try, no help given.**
**If you don't read, listen or actively try, no help is given.**
## 🔄 UPDATING: Patching the Module
@@ -201,15 +214,15 @@ WHMCS Admin > Addon Modules > Proxmox VE for WHMCS > Support/Health shows update
You can download the new version and upload it over the top, then run any needed SQL ops.
Please consult the [UPDATE-SQL.md](https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/blob/master/UPDATE-SQL.md) file, open your WHMCS DB & run the statements. Then you're done.
Please consult the **UPDATE-SQL.md** file, open your WHMCS DB & run the statements. Then you're done.
## 🖥️ INC: Libraries & Dependencies
- (MIT) [PHP Client for PVE2 API](https://github.com/CpuID/pve2-api-php-client) (Dec 5th, 2022)
- (GPLv2) [TigerVNC VncViewer.jar](https://sourceforge.net/projects/tigervnc/files/stable/) (v1.13.1 in repo)
- (MPLv2) [noVNC HTML5 Viewer](https://github.com/novnc/noVNC) (v1.4.0 in repo)
- (GPLv3) [SPICE HTML5 Viewer](https://gitlab.freedesktop.org/spice/spice-html5) (v0.3 in repo)
- (MIT) [IPv4/SN Validation](https://github.com/tapmodo/php-ipv4/) (August 2012)
- (MIT) PHP Client for PVE2 API (Dec 5th, 2022) https://github.com/CpuID/pve2-api-php-client
- (GPLv2) TigerVNC VncViewer.jar (v1.13.1 in repo) https://sourceforge.net/projects/tigervnc/files/stable/
- (MPLv2) noVNC HTML5 Viewer (v1.4.0 in repo) https://github.com/novnc/noVNC
- (GPLv3) SPICE HTML5 Viewer (v0.3 in repo) https://gitlab.freedesktop.org/spice/spice-html5
- (MIT) IPv4/SN Validation (August 2012) https://github.com/tapmodo/php-ipv4/
## 📄 DIY: Documentation & Resources
@@ -217,17 +230,17 @@ Please consult the [UPDATE-SQL.md](https://github.com/The-Network-Crew/Proxmox-V
- TigerVNC: https://github.com/TigerVNC/tigervnc/wiki
- noVNC: https://github.com/novnc/noVNC/wiki
- WHMCS: https://developers.whmcs.com/
- x86-64-ABI: [latest PDF download](https://gitlab.com/x86-psABIs/x86-64-ABI/-/jobs/artifacts/master/raw/x86-64-ABI/abi.pdf?job=build)
- x86-64-ABI: https://gitlab.com/x86-psABIs/x86-64-ABI/-/jobs/artifacts/master/raw/x86-64-ABI/abi.pdf?job=build
## 🎉 FOSS: Contributions & Open-source
If you'd like to contribute to the Module, please open a [PR](https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/pulls).
If you'd like to contribute to the Module, please open a Pull on GitHub >> The-Network-Crew/Proxmox-VE-for-WHMCS
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.
We would like to thank [@cybercoder](https://github.com/cybercoder/) and [@WaldperlachFabi](https://github.com/WaldperlachFabi) for their original contributions and troubleshooting assistance respectively.
We would like to thank @cybercoder and @WaldperlachFabi for their original contributions and troubleshooting assistance respectively.
Thank you to [psyborg®](https://www.psyborg.com.au/graphic-design-services-newcastle/logo-design/) for the module's logo design! We love it.
Thank you to psyborg® for the module's logo design! We love it.
FOSS is only possible thanks to dedicated individuals!
@@ -237,10 +250,12 @@ _**This module is licensed under the GNU General Public License (GPL) v3.0.**_
GPLv3: https://www.gnu.org/licenses/gpl-3.0.txt (by the Free Software Foundation)
**[The Network Crew Pty Ltd](https://thenetworkcrew.com.au)**
### Corporate Sites: TNC & Merlot Digital
**[LEOPARD.host](https://leopard.host)**
**The Network Crew Pty Ltd** :: https://tnc.works
**Merlot Digital** :: https://merlot.digital
### Support: Best-effort via GitHub Issues
Browse issues, raise a new one: **[GitHub Issues](https://github.com/The-Network-Crew/Proxmox-VE-for-WHMCS/issues)**
Browse issues, raise a new one: **GitHub Issues**

View File

@@ -1,8 +1,15 @@
# SQL Statements for Updates (nav to DB first)
### v1.2.3 to v1.2.4
```
ALTER TABLE mod_pvewhmcs_vms ADD COLUMN `v6prefix` varchar(128) DEFAULT NULL;
ALTER TABLE mod_pvewhmcs_plans ADD COLUMN `ipv6` varchar(10) DEFAULT 'auto';
```
### 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

@@ -48,6 +48,7 @@ CREATE TABLE IF NOT EXISTS `mod_pvewhmcs_plans` (
`kvm` tinyint(1) unsigned DEFAULT '0',
`onboot` tinyint(1) unsigned DEFAULT '0',
`vlanid` varchar(10) DEFAULT NULL,
`ipv6` varchar(10) unsigned DEFAULT 'auto',
PRIMARY KEY (`id`)
);
CREATE TABLE IF NOT EXISTS `mod_pvewhmcs_vms` (
@@ -58,5 +59,6 @@ CREATE TABLE IF NOT EXISTS `mod_pvewhmcs_vms` (
`subnetmask` varchar(255) NOT NULL,
`gateway` varchar(255) NOT NULL,
`created` datetime DEFAULT NULL,
`v6prefix` varchar(128) DEFAULT NULL,
PRIMARY KEY (`id`)
);
);

View File

@@ -35,7 +35,7 @@ function pvewhmcs_config() {
$configarray = array(
"name" => "Proxmox VE for WHMCS",
"description" => "Proxmox VE (Virtual Environment) & WHMCS, integrated & open-source! Provisioning & Management of VMs/CTs.".is_pvewhmcs_outdated(),
"version" => "1.2.3",
"version" => "1.2.4",
"author" => "The Network Crew Pty Ltd",
'language' => 'English'
);
@@ -44,16 +44,16 @@ function pvewhmcs_config() {
// VERSION: also stored in repo/version (for update-available checker)
function pvewhmcs_version(){
return "1.2.3";
return "1.2.4";
}
// WHMCS MODULE: ACTIVATION of the ADDON MODULE
// This consists of importing the SQL structure, and then crudely returning yay or nay (needs improving)
function pvewhmcs_activate() {
// Pull in the SQL structure (includes VNC/etc tweaks)
$sql = file_get_contents(ROOTDIR.'/modules/addons/pvewhmcs/db.sql');
$sql = file_get_contents(__DIR__ . '/db.sql');
if (!$sql) {
return array('status'=>'error','description'=>'The db.sql file not found.');
return array('status'=>'error','description'=>'The db.sql file was not found.');
}
// SQL file is good, let's proceed with pulling it in
$err=false;
@@ -69,7 +69,7 @@ function pvewhmcs_activate() {
}
// Return success or error.
if (!$err)
return array('status'=>'success','description'=>'Proxmox VE for WHMCS was installed successfully.');
return array('status'=>'success','description'=>'Proxmox VE for WHMCS was installed successfully!');
return array('status'=>'error','description'=>'Proxmox VE for WHMCS was not activated properly.');
@@ -127,7 +127,7 @@ function pvewhmcs_output($vars) {
echo '
<div id="clienttabs">
<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']=="vmplans" ? "active" : "").'"><a id="tabLink1" data-toggle="tab" role="tab" href="#plans">VM/CT 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']=="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>
@@ -252,6 +252,9 @@ function pvewhmcs_output($vars) {
<th>
BW
</th>
<th>
IPv6
</th>
<th>
Actions
</th>
@@ -277,6 +280,7 @@ function pvewhmcs_output($vars) {
echo '<td>'.$vm->vlanid . PHP_EOL .'</td>';
echo '<td>'.$vm->netrate . PHP_EOL .'</td>';
echo '<td>'.$vm->bw . PHP_EOL .'</td>';
echo '<td>'.$vm->ipv6 . PHP_EOL .'</td>';
echo '<td>
<a href="'.pvewhmcs_BASEURL.'&amp;tab=vmplans&amp;action=editplan&amp;id='.$vm->id.'&amp;vmtype='.$vm->vmtype.'"><img height="16" width="16" border="0" alt="Edit" src="images/edit.gif"></a>
<a href="'.pvewhmcs_BASEURL.'&amp;tab=vmplans&amp;action=removeplan&amp;id='.$vm->id.'" onclick="return confirm(\'Plan will be deleted, continue?\')"><img height="16" width="16" border="0" alt="Edit" src="images/delete.gif"></a>
@@ -534,21 +538,21 @@ function kvm_plan_add() {
<td class="fieldlabel">CPU - Sockets</td>
<td class="fieldarea">
<input type="text" size="8" name="cpus" id="cpus" value="1" required>
The number of CPU sockets. 1 - 4.
The number of CPU Sockets. 1 - 4.
</td>
</tr>
<tr>
<td class="fieldlabel">CPU - Cores</td>
<td class="fieldarea">
<input type="text" size="8" name="cores" id="cores" value="1" required>
The number of CPU cores per socket. 1 - 32.
The number of CPU Cores per socket. 1 - 32.
</td>
</tr>
<tr>
<td class="fieldlabel">CPU - Limit</td>
<td class="fieldarea">
<input type="text" size="8" name="cpulimit" id="cpulimit" value="0" required>
Limit of CPU usage. Note if the Server has 2 CPUs, it has total of "2" CPU time. Value "0" indicates no CPU limit.
Limit of CPU Usage. Note if the Server has 2 CPUs, it has total of "2" CPU time. Value "0" indicates no CPU limit.
</td>
</tr>
<tr>
@@ -647,6 +651,17 @@ function kvm_plan_add() {
Monthly Bandwidth Limit in Gigabytes, Blank means unlimited.
</td>
</tr>
<tr>
<td class="fieldlabel">Network - IPv6 Conf.</td>
<td class="fieldarea">
<select class="form-control select-inline" name="ipv6">
<option value="0">Off</option>
<option value="auto">SLAAC</option>
<option value="dhcp">DHCPv6</option>
<option value="prefix">Prefix</option>
</select>
</td>
</tr>
<tr>
<td class="fieldlabel">Network - Mode</td>
<td class="fieldarea">
@@ -945,6 +960,17 @@ function kvm_plan_edit($id) {
Monthly Bandwidth Limit in Gigabyte, Blank means unlimited.
</td>
</tr>
<tr>
<td class="fieldlabel">Network - IPv6 Conf.</td>
<td class="fieldarea">
<select class="form-control select-inline" name="ipv6">
<option value="0" '. ($plan->ipv6=="0" ? "selected" : "").'>Off</option>
<option value="auto" '. ($plan->ipv6=="auto" ? "selected" : "").'>SLAAC</option>
<option value="dhcp" '. ($plan->ipv6=="dhcp" ? "selected" : "").'>DHCPv6</option>
<option value="prefix" '. ($plan->ipv6=="prefix" ? "selected" : "").'>Prefix</option>
</select>
</td>
</tr>
<tr>
<td class="fieldlabel">Network - Mode</td>
<td class="fieldarea">
@@ -1101,6 +1127,17 @@ function lxc_plan_add() {
Monthly Bandwidth Limit in Gigabytes, blank means unlimited.
</td>
</tr>
<tr>
<td class="fieldlabel">Network - IPv6 Conf.</td>
<td class="fieldarea">
<select class="form-control select-inline" name="ipv6">
<option value="0">Off</option>
<option value="auto">SLAAC</option>
<option value="dhcp">DHCPv6</option>
<option value="prefix">Prefix</option>
</select>
</td>
</tr>
<tr>
<td class="fieldlabel">
On-boot CT?
@@ -1225,6 +1262,17 @@ function lxc_plan_edit($id) {
Monthly Bandwidth Limit in Gigabytes, blank means unlimited.
</td>
</tr>
<tr>
<td class="fieldlabel">Network - IPv6 Conf.</td>
<td class="fieldarea">
<select class="form-control select-inline" name="ipv6">
<option value="0" '. ($plan->ipv6=="0" ? "selected" : "").'>Off</option>
<option value="auto" '. ($plan->ipv6=="auto" ? "selected" : "").'>SLAAC</option>
<option value="dhcp" '. ($plan->ipv6=="dhcp" ? "selected" : "").'>DHCPv6</option>
<option value="prefix" '. ($plan->ipv6=="prefix" ? "selected" : "").'>Prefix</option>
</select>
</td>
</tr>
<tr>
<td class="fieldlabel">
On-boot CT?
@@ -1276,6 +1324,7 @@ function save_kvm_plan() {
'vlanid' => $_POST['vlanid'],
'netrate' => $_POST['netrate'],
'bw' => $_POST['bw'],
'ipv6' => $_POST['ipv6'],
'kvm' => $_POST['kvm'],
'onboot' => $_POST['onboot'],
]
@@ -1318,6 +1367,7 @@ function update_kvm_plan() {
'vlanid' => $_POST['vlanid'],
'netrate' => $_POST['netrate'],
'bw' => $_POST['bw'],
'ipv6' => $_POST['ipv6'],
'kvm' => $_POST['kvm'],
'onboot' => $_POST['onboot'],
]
@@ -1360,6 +1410,7 @@ function save_lxc_plan() {
'vlanid' => $_POST['vlanid'],
'netrate' => $_POST['netrate'],
'bw' => $_POST['bw'],
'ipv6' => $_POST['ipv6'],
'onboot' => $_POST['onboot'],
]
);
@@ -1395,6 +1446,7 @@ function update_lxc_plan() {
'vlanid' => $_POST['vlanid'],
'netrate' => $_POST['netrate'],
'bw' => $_POST['bw'],
'ipv6' => $_POST['ipv6'],
'onboot' => $_POST['onboot'],
]
);

View File

@@ -27,9 +27,11 @@ if (file_exists('../modules/addons/pvewhmcs/proxmox.php'))
else
require_once(ROOTDIR.'/modules/addons/pvewhmcs/proxmox.php');
// Import SQL Connectivity (WHMCS)
use Illuminate\Database\Capsule\Manager as Capsule;
global $guest ;
// Prepare to source Guest type
global $guest;
// WHMCS CONFIG > SERVICES/PRODUCTS > Their Service > Tab #3 (Plan/Pool)
function pvewhmcs_ConfigOptions() {
@@ -45,15 +47,16 @@ function pvewhmcs_ConfigOptions() {
foreach (Capsule::table('mod_pvewhmcs_ip_pools')->get() as $ippool) {
$ippools[$ippool->id]=$ippool->title ;
}
/*
$proxmox=new PVE2_API($server->ipaddress, $server->username, "pam", get_server_pass_from_whmcs($server->password));
$proxmox = new PVE2_API($server->ipaddress, $server->username, "pam", get_server_pass_from_whmcs($server->password));
if ($proxmox->login()) {
# Get first node name.
$nodes = $proxmox->get_node_list();
$first_node = $nodes[0];
unset($nodes);
$storage_contents=$proxmox->get('/nodes/'.$first_node.'/storage/local/content') ;
$storage_contents = $proxmox->get('/nodes/'.$first_node.'/storage/local/content') ;
foreach ($storage_contents as $storage_content) {
if ($storage_content['content']=='vztmpl') {
@@ -62,6 +65,7 @@ function pvewhmcs_ConfigOptions() {
}
}
*/
// OPTIONS FOR THE QEMU/LXC PACKAGE; ties WHMCS PRODUCT to MODULE PLAN/POOL
// Ref: https://developers.whmcs.com/provisioning-modules/config-options/
// SQL/Param: configoption1 configoption2
@@ -76,10 +80,11 @@ function pvewhmcs_ConfigOptions() {
"FriendlyName" => "IP Pool",
"Type" => "dropdown",
'Options'=> $ippools,
"Description" => "Pool to assign VM IP from."
"Description" => "IPv4 : Allocation Pool"
),
);
// Deliver the options back into WHMCS
return $configarray;
}
@@ -90,31 +95,35 @@ function pvewhmcs_CreateAccount($params) {
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.");
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.");
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
// Retrieve Plan from table
$plan = Capsule::table('mod_pvewhmcs_plans')->where('id', '=', $params['configoption1'])->get()[0];
// PVE Host - Connection Info
$serverip = $params["serverip"];
$serverusername = $params["serverusername"];
$serverpassword = $params["serverpassword"];
// Prepare the service config array
$vm_settings = array();
// Select an IP address from pool
// Select an IP Address from Pool
$ip = Capsule::select('select ipaddress,mask,gateway from mod_pvewhmcs_ip_addresses i INNER JOIN mod_pvewhmcs_ip_pools p on (i.pool_id=p.id and p.id=' . $params['configoption2'] . ') where i.ipaddress not in(select ipaddress from mod_pvewhmcs_vms) limit 1')[0];
// CREATE IF QEMU/KVM
////////////////////////
// CREATE IF QEMU/KVM //
////////////////////////
if (!empty($params['customfields']['KVMTemplate'])) {
// file_put_contents('d:\log.txt', $params['customfields']['KVMTemplate']);
$proxmox = new PVE2_API($serverip, $serverusername, "pam", $serverpassword);
if ($proxmox->login()) {
// Get first node name.
// Get first node name.
$nodes = $proxmox->get_node_list();
$first_node = $nodes[0];
unset($nodes);
@@ -143,6 +152,7 @@ function pvewhmcs_CreateAccount($params) {
'subnetmask' => $ip->mask,
'gateway' => $ip->gateway,
'created' => date("Y-m-d H:i:s"),
'v6prefix' => $plan->ipv6,
]
);
// ISSUE #32 relates - amend post-clone to ensure excludes-disk amendments are all done, too.
@@ -153,7 +163,7 @@ function pvewhmcs_CreateAccount($params) {
$cloned_tweaks['cpu'] = $plan->cpuemu;
$cloned_tweaks['kvm'] = $plan->kvm;
$cloned_tweaks['onboot'] = $plan->onboot;
$amendment = $proxmox->post('/nodes/' . $first_node . '/qemu/' . $vm_settings['newid'] . '/config'. $cloned_tweaks);
$amendment = $proxmox->post('/nodes/' . $first_node . '/qemu/' . $vm_settings['newid'] . '/config', $cloned_tweaks);
return true;
} else {
if (is_array($response) && isset($response['data']['errors'])) {
@@ -168,28 +178,81 @@ function pvewhmcs_CreateAccount($params) {
} else {
throw new Exception("Proxmox Error: PVE API login failed. Please check your credentials.");
}
// PREPARE SETTINGS FOR QEMU/LXC EVENTUALITIES
// PREPARE SETTINGS FOR QEMU/LXC EVENTUALITIES
} else {
$vm_settings['vmid'] = $params["serviceid"];
if ($plan->vmtype == 'lxc') {
/////////////////////////////
// Process LXC preparation //
/////////////////////////////
$vm_settings['ostemplate'] = $plan->storage . ':vztmpl/' . $params['customfields']['Template'];
$vm_settings['swap'] = $plan->swap;
$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->ipv6) && $plan->ipv6 != '0') {
// Standard prep for the 2nd int.
$vm_settings['net1'] = 'name=eth1,bridge=' . $plan->bridge . $plan->vmbr;
// Handling different IPv6 configs
switch ($plan->ipv6) {
case 'auto':
// Passes 'auto' directly, triggering SLAAC
$vm_settings['net1'] .= ',ip6=auto';
break;
case 'dhcp':
// Passes 'dhcp' directly
$vm_settings['net1'] .= ',ip6=dhcp';
break;
case 'prefix':
// Placeholder for future development - currently does nothing
// TODO: Handle 'prefix' case once prefix allocation logic is developed
break;
default:
// Handle any unexpected IPv6 settings - logging, etc
break;
}
// VLAN tag, only for v6
if(!empty($plan->vlanid)){
$vm_settings['net1'] .= ',trunk=' . $plan->vlanid;
}
}
// VLAN tag, only for v4
if(!empty($plan->vlanid)){
$vm_settings['net0'] .= ',trunk=' . $plan->vlanid;
}
$vm_settings['nameserver'] = '1.1.1.1';
$vm_settings['nameserver'] = '76.76.2.0 76.76.10.0';
$vm_settings['onboot'] = $plan->onboot;
$vm_settings['password'] = $params['customfields']['Password'];
} else {
//////////////////////////////
// Process QEMU preparation //
//////////////////////////////
$vm_settings['ostype'] = $plan->ostype;
$vm_settings['sockets'] = $plan->cpus;
$vm_settings['cores'] = $plan->cores;
$vm_settings['cpu'] = $plan->cpuemu;
$vm_settings['ipconfig0'] = 'ip=' . $ip->ipaddress . '/' . mask2cidr($ip->mask) . ',gw=' . $ip->gateway;
$vm_settings['nameserver'] = '1.1.1.1';
if (!empty($plan->ipv6) && $plan->ipv6 != '0') {
// Handling different IPv6 configs
switch ($plan->ipv6) {
case 'auto':
// Passes 'auto' directly, triggering SLAAC
$vm_settings['ipconfig1'] = 'ip6=auto';
break;
case 'dhcp':
// Passes 'dhcp' directly
$vm_settings['ipconfig1'] = 'ip6=dhcp';
break;
case 'prefix':
// Placeholder for future development - currently does nothing
// TODO: Handle 'prefix' case once prefix allocation logic is developed
break;
default:
// Handle any unexpected IPv6 settings - logging, etc
break;
}
}
$vm_settings['nameserver'] = '76.76.2.0 76.76.10.0';
$vm_settings['kvm'] = $plan->kvm;
$vm_settings['onboot'] = $plan->onboot;
@@ -198,13 +261,14 @@ function pvewhmcs_CreateAccount($params) {
$vm_settings[$plan->disktype . '0'] .= ',cache=' . $plan->diskcache;
}
// Assign ISO File
// Assign ISO File
if (isset($params['customfields']['ISO'])) {
$vm_settings['ide2'] = 'local:iso/' . $params['customfields']['ISO'] . ',media=cdrom';
}
/* Network settings */
/* Network Specifics - Bridge, Rate & Trunk/VLAN */
if ($plan->netmode != 'none') {
// Perform the additions for IPv4 (net0/ipconfig0)
$vm_settings['net0'] = $plan->netmodel;
if ($plan->netmode == 'bridge') {
$vm_settings['net0'] .= ',bridge=' . $plan->bridge . $plan->vmbr;
@@ -216,6 +280,20 @@ function pvewhmcs_CreateAccount($params) {
if (!empty($plan->vlanid)) {
$vm_settings['net0'] .= ',trunk=' . $plan->vlanid;
}
// Check if ipconfig1 exists, and then do the same for net1 if so
if (isset($vm_settings['ipconfig1'])) {
$vm_settings['net1'] = $plan->netmodel;
if ($plan->netmode == 'bridge') {
$vm_settings['net1'] .= ',bridge=' . $plan->bridge . $plan->vmbr;
}
$vm_settings['net1'] .= ',firewall=' . $plan->firewall;
if (!empty($plan->netrate)) {
$vm_settings['net1'] .= ',rate=' . $plan->netrate;
}
if (!empty($plan->vlanid)) {
$vm_settings['net1'] .= ',trunk=' . $plan->vlanid;
}
}
}
/* end of network settings */
}
@@ -224,12 +302,14 @@ function pvewhmcs_CreateAccount($params) {
$vm_settings['cpulimit'] = $plan->cpulimit;
$vm_settings['memory'] = $plan->memory;
// CREATION: Attempt to create the QEMU/LXC instance on Proxmox VE via API
////////////////////////////////////////////////////
// CREATION: Attempt to Create Guest via PVE2 API //
////////////////////////////////////////////////////
try {
$proxmox = new PVE2_API($serverip, $serverusername, "pam", $serverpassword);
if ($proxmox->login()) {
// Get first node name.
// Get first node name.
$nodes = $proxmox->get_node_list();
$first_node = $nodes[0];
unset($nodes);
@@ -263,6 +343,7 @@ function pvewhmcs_CreateAccount($params) {
'subnetmask' => $ip->mask,
'gateway' => $ip->gateway,
'created' => date("Y-m-d H:i:s"),
'v6prefix' => $plan->ipv6,
]
);
return true;
@@ -280,8 +361,8 @@ function pvewhmcs_CreateAccount($params) {
throw new Exception("Proxmox Error: PVE API login failed. Please check your credentials.");
}
} catch (PVE2_Exception $e) {
// Record the error in WHMCS's module log.
if (Capsule::table('mod_pvewhmcs')->where('id', '1')->value('debug_mode') == 1) {
// Record the error in WHMCS's module log.
if (Capsule::table('mod_pvewhmcs')->where('id', '1')->value('debug_mode') == 1) {
logModuleCall(
'pvewhmcs',
__FUNCTION__,
@@ -297,32 +378,36 @@ function pvewhmcs_CreateAccount($params) {
// PVE API FUNCTION, ADMIN: Test Connection with Proxmox node
function pvewhmcs_TestConnection(array $params) {
$success = true; // Assume success by default
try {
// Call the service's connection test function.
$serverip = $params["serverip"];
$serverusername = $params["serverusername"];
$serverpassword = $params["serverpassword"];
$proxmox = new PVE2_API($serverip, $serverusername, "pam", $serverpassword);
try {
// Call the service's connection test function.
$serverip = $params["serverip"];
$serverusername = $params["serverusername"];
$serverpassword = $params["serverpassword"];
$proxmox = new PVE2_API($serverip, $serverusername, "pam", $serverpassword);
if (!$proxmox->login()) {
$success = false; // Set success to false if login fails
}
} catch (Exception $e) {
// 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 = $e->getMessage(); // Set the error message as the success value
}
return array('success' => $success); // Return either true or the error
// Set success if login succeeded
if ($proxmox->login()) {
$success = true;
$errorMsg = '';
}
} catch (Exception $e) {
// Record the error in WHMCS's module log
logModuleCall(
'pvewhmcs',
__FUNCTION__,
$params,
$e->getMessage(),
$e->getTraceAsString()
);
// Set the error message as a failure
$success = false;
$errorMsg = $e->getMessage();
}
// Return success or error, and info
return array(
'success' => $success,
'error' => $errorMsg,
);
}
// PVE API FUNCTION, ADMIN: Suspend a Service on the hypervisor
@@ -331,7 +416,7 @@ function pvewhmcs_SuspendAccount(array $params) {
$serverusername = $params["serverusername"];
$serverpassword = $params["serverpassword"];
$proxmox=new PVE2_API($serverip, $serverusername, "pam", $serverpassword);
$proxmox = new PVE2_API($serverip, $serverusername, "pam", $serverpassword);
if ($proxmox->login()) {
# Get first node name.
$nodes = $proxmox->get_node_list();
@@ -353,11 +438,11 @@ function pvewhmcs_SuspendAccount(array $params) {
}
// Return success only if no errors returned by PVE
if (isset($response) && !isset($response['errors'])) {
return "success";
return "success";
} else {
// Handle the case where there are errors
$response_message = isset($response['errors']) ? json_encode($response['errors']) : "Unknown Error, consider using Debug Mode.";
return "Error performing action. " . $response_message;
// Handle the case where there are errors
$response_message = isset($response['errors']) ? json_encode($response['errors']) : "Unknown Error, consider using Debug Mode.";
return "Error performing action. " . $response_message;
}
}
@@ -367,7 +452,7 @@ function pvewhmcs_UnsuspendAccount(array $params) {
$serverusername = $params["serverusername"];
$serverpassword = $params["serverpassword"];
$proxmox=new PVE2_API($serverip, $serverusername, "pam", $serverpassword);
$proxmox = new PVE2_API($serverip, $serverusername, "pam", $serverpassword);
if ($proxmox->login()) {
# Get first node name.
$nodes = $proxmox->get_node_list();
@@ -389,11 +474,11 @@ function pvewhmcs_UnsuspendAccount(array $params) {
}
// Return success only if no errors returned by PVE
if (isset($response) && !isset($response['errors'])) {
return "success";
return "success";
} else {
// Handle the case where there are errors
$response_message = isset($response['errors']) ? json_encode($response['errors']) : "Unknown Error, consider using Debug Mode.";
return "Error performing action. " . $response_message;
// Handle the case where there are errors
$response_message = isset($response['errors']) ? json_encode($response['errors']) : "Unknown Error, consider using Debug Mode.";
return "Error performing action. " . $response_message;
}
}
@@ -403,7 +488,7 @@ function pvewhmcs_TerminateAccount(array $params) {
$serverusername = $params["serverusername"];
$serverpassword = $params["serverpassword"];
$proxmox=new PVE2_API($serverip, $serverusername, "pam", $serverpassword);
$proxmox = new PVE2_API($serverip, $serverusername, "pam", $serverpassword);
if ($proxmox->login()){
# Get first node name.
$nodes = $proxmox->get_node_list();
@@ -431,23 +516,25 @@ class hash_encryption {
* @var string
**/
var $hash_key;
/**
* String length of hashed values using the current algorithm
* @var int
**/
var $hash_lenth;
/**
* Switch base64 enconding on / off
* @var bool true = use base64, false = binary output / input
**/
var $base64;
/**
* Secret value added to randomize output and protect the user provided key
* @var string Change this value to add more randomness to your encryption
**/
var $salt = 'Change this to any secret value you like. "d41d8cd98f00b204e9800998ecf8427e" might be a good example.';
/**
* Constructor method
*
@@ -617,7 +704,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
// Include WHMCS database configuration file
include_once(dirname(dirname(dirname(dirname(__FILE__)))).'/configuration.php');
$key1 = md5 (md5 ($cc_encryption_hash));
$key2 = md5 ($cc_encryption_hash);
@@ -664,11 +751,11 @@ function pvewhmcs_ClientArea($params) {
$serverusername = $pveserver->username;
$api_data = array(
'password2' => $pveserver->password,
'password2' => $pveserver->password,
);
$serverpassword = localAPI('DecryptPassword', $api_data);
$proxmox=new PVE2_API($serverip, $serverusername, "pam", $serverpassword['password']);
$proxmox = new PVE2_API($serverip, $serverusername, "pam", $serverpassword['password']);
if ($proxmox->login()) {
//$proxmox->setCookie();
# Get first node name.
@@ -677,7 +764,7 @@ function pvewhmcs_ClientArea($params) {
unset($nodes);
# Get and set VM variables
$vm_config=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/config') ;
$vm_config = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/config') ;
$cluster_resources = $proxmox->get('/cluster/resources');
$vm_status = null;
@@ -710,131 +797,132 @@ function pvewhmcs_ClientArea($params) {
$vm_status['memusepercent'] = intval($vm_status['mem'] * 100 / $vm_status['maxmem']);
if ($guest->vtype == 'lxc') {
$ct_specific=$proxmox->get('/nodes/'.$first_node.'/lxc/'.$params['serviceid'] .'/status/current') ;
$ct_specific = $proxmox->get('/nodes/'.$first_node.'/lxc/'.$params['serviceid'] .'/status/current') ;
$vm_status['swapusepercent'] = intval($ct_specific['swap'] * 100 / $ct_specific['maxswap']);
}
} else {
// Handle the VM not found in the cluster resources (Optional)
// Handle the VM not found in the cluster resources (Optional)
echo "VM/CT not found in Cluster Resources.";
}
// Max CPU usage Yearly
$rrd_params = '?timeframe=year&ds=cpu&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] . '/rrd' . $rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['cpu']['year']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] . '/rrd' . $rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['cpu']['year'] = base64_encode($vm_rrd['image']);
// Max CPU usage monthly
$rrd_params = '?timeframe=month&ds=cpu&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['cpu']['month']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['cpu']['month'] = base64_encode($vm_rrd['image']);
// Max CPU usage weekly
$rrd_params = '?timeframe=week&ds=cpu&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['cpu']['week']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['cpu']['week'] = base64_encode($vm_rrd['image']);
// Max CPU usage daily
$rrd_params = '?timeframe=day&ds=cpu&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['cpu']['day']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['cpu']['day'] = base64_encode($vm_rrd['image']);
// Max memory Yearly
$rrd_params = '?timeframe=year&ds=maxmem&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['maxmem']['year']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['maxmem']['year'] = base64_encode($vm_rrd['image']);
// Max memory monthly
$rrd_params = '?timeframe=month&ds=maxmem&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['maxmem']['month']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['maxmem']['month'] = base64_encode($vm_rrd['image']);
// Max memory weekly
$rrd_params = '?timeframe=week&ds=maxmem&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['maxmem']['week']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['maxmem']['week'] = base64_encode($vm_rrd['image']);
// Max memory daily
$rrd_params = '?timeframe=day&ds=maxmem&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['maxmem']['day']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['maxmem']['day'] = base64_encode($vm_rrd['image']);
// Network rate Yearly
$rrd_params = '?timeframe=year&ds=netin,netout&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['netinout']['year']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['netinout']['year'] = base64_encode($vm_rrd['image']);
// Network rate monthly
$rrd_params = '?timeframe=month&ds=netin,netout&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['netinout']['month']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['netinout']['month'] = base64_encode($vm_rrd['image']);
// Network rate weekly
$rrd_params = '?timeframe=week&ds=netin,netout&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['netinout']['week']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['netinout']['week'] = base64_encode($vm_rrd['image']);
// Network rate daily
$rrd_params = '?timeframe=day&ds=netin,netout&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['netinout']['day']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['netinout']['day'] = base64_encode($vm_rrd['image']);
// Max IO Yearly
$rrd_params = '?timeframe=year&ds=diskread,diskwrite&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['diskrw']['year']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['diskrw']['year'] = base64_encode($vm_rrd['image']);
// Max IO monthly
$rrd_params = '?timeframe=month&ds=diskread,diskwrite&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['diskrw']['month']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['diskrw']['month'] = base64_encode($vm_rrd['image']);
// Max IO weekly
$rrd_params = '?timeframe=week&ds=diskread,diskwrite&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['diskrw']['week']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['diskrw']['week'] = base64_encode($vm_rrd['image']);
// Max IO daily
$rrd_params = '?timeframe=day&ds=diskread,diskwrite&cf=AVERAGE';
$vm_rrd=$proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image']=utf8_decode($vm_rrd['image']) ;
$vm_statistics['diskrw']['day']=base64_encode($vm_rrd['image']);
$vm_rrd = $proxmox->get('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/rrd'.$rrd_params) ;
$vm_rrd['image'] = utf8_decode($vm_rrd['image']) ;
$vm_statistics['diskrw']['day'] = base64_encode($vm_rrd['image']);
unset($vm_rrd) ;
$vm_config['vtype']=$guest->vtype ;
$vm_config['ipv4']=$guest->ipaddress ;
$vm_config['netmask4']=$guest->subnetmask ;
$vm_config['gateway4']=$guest->gateway ;
$vm_config['created']=$guest->created ;
$vm_config['vtype'] = $guest->vtype ;
$vm_config['ipv4'] = $guest->ipaddress ;
$vm_config['netmask4'] = $guest->subnetmask ;
$vm_config['gateway4'] = $guest->gateway ;
$vm_config['created'] = $guest->created ;
$vm_config['v6prefix'] = $guest->v6prefix ;
}
else {
echo '<center><strong>Unable to contact Hypervisor - aborting!<br>Please contact Tech Support.</strong></center>';
die;
exit;
}
return array(
'templatefile' => 'clientarea',
'vars' => array(
'params' => $params,
'vm_config'=>$vm_config,
'vm_status'=>$vm_status,
'vm_statistics'=>$vm_statistics,
'vm_vncproxy'=>$vm_vncproxy,
'vm_config' => $vm_config,
'vm_status' => $vm_status,
'vm_statistics' => $vm_statistics,
'vm_vncproxy' => $vm_vncproxy,
),
);
}
@@ -850,19 +938,21 @@ function pvewhmcs_noVNC($params) {
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');
$proxmox=new PVE2_API($serverip, $serverusername, "pve", $serverpassword);
$proxmox = new PVE2_API($serverip, $serverusername, "pve", $serverpassword);
if ($proxmox->login()) {
# Get first node name.
// Get first node name
$nodes = $proxmox->get_node_list();
$first_node = $nodes[0];
unset($nodes);
$guest=Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$vm_vncproxy=$proxmox->post('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/vncproxy', array( 'websocket' => '1' )) ;
// Early prep work
$guest = Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$vm_vncproxy = $proxmox->post('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/vncproxy', array( 'websocket' => '1' )) ;
// Get both tickets prepared
$pveticket = $proxmox->getTicket();
$vncticket = $vm_vncproxy['ticket'];
@@ -871,10 +961,10 @@ function pvewhmcs_noVNC($params) {
// 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>' ;
$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.';
$vncreply = 'Failed to prepare noVNC. Please contact Technical Support.';
return $vncreply;
}
}
@@ -885,19 +975,21 @@ function pvewhmcs_SPICE($params) {
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');
$proxmox=new PVE2_API($serverip, $serverusername, "pve", $serverpassword);
$proxmox = new PVE2_API($serverip, $serverusername, "pve", $serverpassword);
if ($proxmox->login()) {
# Get first node name.
// Get first node name
$nodes = $proxmox->get_node_list();
$first_node = $nodes[0];
unset($nodes);
$guest=Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$vm_vncproxy=$proxmox->post('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/vncproxy', array( 'websocket' => '1' )) ;
// Early prep work
$guest = Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$vm_vncproxy = $proxmox->post('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/vncproxy', array( 'websocket' => '1' )) ;
// Get both tickets prepared
$pveticket = $proxmox->getTicket();
$vncticket = $vm_vncproxy['ticket'];
@@ -906,10 +998,10 @@ function pvewhmcs_SPICE($params) {
// Construct the SPICE Router URL with the path already prepared now
$url = '/modules/servers/pvewhmcs/spice_router.php?host=' . $serverip . '&pveticket=' . urlencode($pveticket) . '&path=' . urlencode($path) . '&vncticket=' . urlencode($vncticket);
// Build and deliver the SPICE Router hyperlink for access
$vncreply='<center><strong>Console (SPICE) prepared for usage. <a href="'.$url.'" target="_blanK">Click here</a> to open the noVNC window.</strong></center>' ;
$vncreply = '<center><strong>Console (SPICE) 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 SPICE. Please contact Technical Support.';
$vncreply = 'Failed to prepare SPICE. Please contact Technical Support.';
return $vncreply;
}
}
@@ -924,31 +1016,30 @@ function pvewhmcs_javaVNC($params){
$serverip = $params["serverip"];
$serverusername = 'vnc';
$serverpassword = Capsule::table('mod_pvewhmcs')->where('id', '1')->value('vnc_secret');
$proxmox=new PVE2_API($serverip, $serverusername, "pve", $serverpassword);
$proxmox = new PVE2_API($serverip, $serverusername, "pve", $serverpassword);
if ($proxmox->login()) {
# Get first node name.
// Get first node name
$nodes = $proxmox->get_node_list();
$first_node = $nodes[0];
unset($nodes);
$guest=Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
// Early prep work
$guest = Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$vncparams = array();
$vm_vncproxy=$proxmox->post('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/vncproxy', $vncparams) ;
$javaVNCparams=array() ;
$javaVNCparams[0]=$serverip ;
$javaVNCparams[1]=str_replace("\n","|",$vm_vncproxy['cert']) ;
$javaVNCparams[2]=$vm_vncproxy['port'] ;
$javaVNCparams[3]=$vm_vncproxy['user'] ;
$javaVNCparams[4]=$vm_vncproxy['ticket'] ;
$url='./modules/servers/pvewhmcs/tigervnc.php?'.http_build_query($javaVNCparams).'' ;
$vncreply='<center><strong>Console (TigerVNC) prepared for usage. <a href="'.$url.'" target="_blanK">Click here</a> to open the TigerVNC window.</strong></center>' ;
$vm_vncproxy = $proxmox->post('/nodes/'.$first_node.'/'.$guest->vtype.'/'.$params['serviceid'] .'/vncproxy', $vncparams) ;
// Java-specific params
$javaVNCparams = array() ;
$javaVNCparams[0] = $serverip ;
$javaVNCparams[1] = str_replace("\n","|",$vm_vncproxy['cert']) ;
$javaVNCparams[2] = $vm_vncproxy['port'] ;
$javaVNCparams[3] = $vm_vncproxy['user'] ;
$javaVNCparams[4] = $vm_vncproxy['ticket'] ;
// URL preparation to deliver in hyperlink message
$url = './modules/servers/pvewhmcs/tigervnc.php?'.http_build_query($javaVNCparams).'' ;
$vncreply = '<center><strong>Console (TigerVNC) prepared for usage. <a href="'.$url.'" target="_blanK">Click here</a> to open the TigerVNC window.</strong></center>' ;
// echo '<script>window.open("modules/servers/pvewhmcs/tigervnc.php?'.http_build_query($javaVNCparams).'","VNC","location=0,toolbar=0,menubar=0,scrollbars=1,resizable=1,width=802,height=624")</script>';
return $vncreply;
} else {
$vncreply='Failed to prepare TigerVNC. Please contact Technical Support.';
$vncreply = 'Failed to prepare TigerVNC. Please contact Technical Support.';
return $vncreply;
}
}
@@ -956,23 +1047,22 @@ 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']) ;
$pveserver=Capsule::table('tblservers')->where('id','=',$pveservice->server)->get()[0] ;
$pveservice = Capsule::table('tblhosting')->find($params['serviceid']) ;
$pveserver = Capsule::table('tblservers')->where('id','=',$pveservice->server)->get()[0] ;
$serverip = $pveserver->ipaddress;
$serverusername = $pveserver->username;
$api_data = array(
'password2' => $pveserver->password,
'password2' => $pveserver->password,
);
$serverpassword = localAPI('DecryptPassword', $api_data);
$proxmox=new PVE2_API($serverip, $serverusername, "pam", $serverpassword['password']);
$proxmox = new PVE2_API($serverip, $serverusername, "pam", $serverpassword['password']);
if ($proxmox->login()) {
# Get first node name.
$nodes = $proxmox->get_node_list();
$first_node = $nodes[0];
unset($nodes);
$guest=Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$guest = Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$pve_cmdparam = array();
$logrequest = '/nodes/' . $first_node . '/' . $guest->vtype . '/' . $params['serviceid'] . '/status/start';
$response = $proxmox->post('/nodes/' . $first_node . '/' . $guest->vtype . '/' . $params['serviceid'] . '/status/start' , $pve_cmdparam);
@@ -988,34 +1078,33 @@ function pvewhmcs_vmStart($params) {
}
// Return success only if no errors returned by PVE
if (isset($response) && !isset($response['errors'])) {
return "success";
return "success";
} else {
// Handle the case where there are errors
$response_message = isset($response['errors']) ? json_encode($response['errors']) : "Unknown Error, consider using Debug Mode.";
return "Error performing action. " . $response_message;
// Handle the case where there are errors
$response_message = isset($response['errors']) ? json_encode($response['errors']) : "Unknown Error, consider using Debug Mode.";
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']) ;
$pveserver=Capsule::table('tblservers')->where('id','=',$pveservice->server)->get()[0] ;
$pveservice = Capsule::table('tblhosting')->find($params['serviceid']) ;
$pveserver = Capsule::table('tblservers')->where('id','=',$pveservice->server)->get()[0] ;
$serverip = $pveserver->ipaddress;
$serverusername = $pveserver->username;
$api_data = array(
'password2' => $pveserver->password,
'password2' => $pveserver->password,
);
$serverpassword = localAPI('DecryptPassword', $api_data);
$proxmox=new PVE2_API($serverip, $serverusername, "pam", $serverpassword['password']);
$proxmox = new PVE2_API($serverip, $serverusername, "pam", $serverpassword['password']);
if ($proxmox->login()) {
# Get first node name.
$nodes = $proxmox->get_node_list();
$first_node = $nodes[0];
unset($nodes);
$guest=Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$guest = Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$pve_cmdparam = array();
// $pve_cmdparam['timeout'] = '60';
$logrequest = '/nodes/' . $first_node . '/' . $guest->vtype . '/' . $params['serviceid'] . '/status/reboot';
@@ -1032,34 +1121,34 @@ function pvewhmcs_vmReboot($params) {
}
// Return success only if no errors returned by PVE
if (isset($response) && !isset($response['errors'])) {
return "success";
return "success";
} else {
// Handle the case where there are errors
$response_message = isset($response['errors']) ? json_encode($response['errors']) : "Unknown Error, consider using Debug Mode.";
return "Error performing action. " . $response_message;
// Handle the case where there are errors
$response_message = isset($response['errors']) ? json_encode($response['errors']) : "Unknown Error, consider using Debug Mode.";
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']) ;
$pveserver=Capsule::table('tblservers')->where('id','=',$pveservice->server)->get()[0] ;
$pveservice = Capsule::table('tblhosting')->find($params['serviceid']) ;
$pveserver = Capsule::table('tblservers')->where('id','=',$pveservice->server)->get()[0] ;
$serverip = $pveserver->ipaddress;
$serverusername = $pveserver->username;
$api_data = array(
'password2' => $pveserver->password,
'password2' => $pveserver->password,
);
$serverpassword = localAPI('DecryptPassword', $api_data);
$proxmox=new PVE2_API($serverip, $serverusername, "pam", $serverpassword['password']);
$proxmox = new PVE2_API($serverip, $serverusername, "pam", $serverpassword['password']);
if ($proxmox->login()) {
# Get first node name.
$nodes = $proxmox->get_node_list();
$first_node = $nodes[0];
unset($nodes);
$guest=Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$guest = Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$pve_cmdparam = array();
// $pve_cmdparam['timeout'] = '60';
$logrequest = '/nodes/' . $first_node . '/' . $guest->vtype . '/' . $params['serviceid'] . '/status/shutdown';
@@ -1076,34 +1165,33 @@ function pvewhmcs_vmShutdown($params) {
}
// Return success only if no errors returned by PVE
if (isset($response) && !isset($response['errors'])) {
return "success";
return "success";
} else {
// Handle the case where there are errors
$response_message = isset($response['errors']) ? json_encode($response['errors']) : "Unknown Error, consider using Debug Mode.";
return "Error performing action. " . $response_message;
// Handle the case where there are errors
$response_message = isset($response['errors']) ? json_encode($response['errors']) : "Unknown Error, consider using Debug Mode.";
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']) ;
$pveserver=Capsule::table('tblservers')->where('id','=',$pveservice->server)->get()[0] ;
$pveservice = Capsule::table('tblhosting')->find($params['serviceid']) ;
$pveserver = Capsule::table('tblservers')->where('id','=',$pveservice->server)->get()[0] ;
$serverip = $pveserver->ipaddress;
$serverusername = $pveserver->username;
$api_data = array(
'password2' => $pveserver->password,
'password2' => $pveserver->password,
);
$serverpassword = localAPI('DecryptPassword', $api_data);
$proxmox=new PVE2_API($serverip, $serverusername, "pam", $serverpassword['password']);
$proxmox = new PVE2_API($serverip, $serverusername, "pam", $serverpassword['password']);
if ($proxmox->login()) {
# Get first node name.
$nodes = $proxmox->get_node_list();
$first_node = $nodes[0];
unset($nodes);
$guest=Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$guest = Capsule::table('mod_pvewhmcs_vms')->where('id','=',$params['serviceid'])->get()[0] ;
$pve_cmdparam = array();
// $pve_cmdparam['timeout'] = '60';
$logrequest = '/nodes/' . $first_node . '/' . $guest->vtype . '/' . $params['serviceid'] . '/status/stop';
@@ -1120,11 +1208,11 @@ function pvewhmcs_vmStop($params) {
}
// Return success only if no errors returned by PVE
if (isset($response) && !isset($response['errors'])) {
return "success";
return "success";
} else {
// Handle the case where there are errors
$response_message = isset($response['errors']) ? json_encode($response['errors']) : "Unknown Error, consider using Debug Mode.";
return "Error performing action. " . $response_message;
// Handle the case where there are errors
$response_message = isset($response['errors']) ? json_encode($response['errors']) : "Unknown Error, consider using Debug Mode.";
return "Error performing action. " . $response_message;
}
}