4 Commits
0.0.6 ... 0.0.9

Author SHA1 Message Date
e5570785db Updated README.md 2023-09-10 19:52:19 -04:00
b25535ba5f Cleaned up code to make it OOP. 2023-09-10 19:48:18 -04:00
00ccd2c902 Migrated to below heading 2023-09-10 18:53:17 -04:00
33f466af04 Updated badge 2023-09-10 18:43:48 -04:00
4 changed files with 129 additions and 170 deletions

View File

@@ -1,10 +1,10 @@
[![GitHub Super-Linter](https://github.com/EZSCALE/virtfusion-whmcs-module/actions/workflows/linter/badge.svg)](https://github.com/marketplace/actions/super-linter) # VirtFusion Direct Provisioning Module for WHMCS
[![GitHub Super-Linter](https://github.com/EZSCALE/virtfusion-whmcs-module/actions/workflows/publish-release.yml/badge.svg)](https://github.com/EZSCALE/virtfusion-whmcs-module/actions)
![GitHub](https://img.shields.io/github/license/EZSCALE/virtfusion-whmcs-module) ![GitHub](https://img.shields.io/github/license/EZSCALE/virtfusion-whmcs-module)
![GitHub issues](https://img.shields.io/github/issues/EZSCALE/virtfusion-whmcs-module) ![GitHub issues](https://img.shields.io/github/issues/EZSCALE/virtfusion-whmcs-module)
![GitHub pull requests](https://img.shields.io/github/issues-pr/EZSCALE/virtfusion-whmcs-module) ![GitHub pull requests](https://img.shields.io/github/issues-pr/EZSCALE/virtfusion-whmcs-module)
# VirtFusion Direct Provisioning Module for WHMCS
This module requires VirtFusion v1.7.3 or higher as this is what it's based on. Please refer to the official [documenataion](https://docs.virtfusion.com/integrations/whmcs). This module requires VirtFusion v1.7.3 or higher as this is what it's based on. Please refer to the official [documenataion](https://docs.virtfusion.com/integrations/whmcs).
## Installation ## Installation
@@ -12,22 +12,13 @@ This module requires VirtFusion v1.7.3 or higher as this is what it's based on.
1. Download the latest release from the [releases](https://github.com/EZSCALE/virtfusion-whmcs-module/releases) page. 1. Download the latest release from the [releases](https://github.com/EZSCALE/virtfusion-whmcs-module/releases) page.
2. Extract the contents of the archive and upload the modules folder to your WHMCS installation directory. 2. Extract the contents of the archive and upload the modules folder to your WHMCS installation directory.
## Configuration
You'll need to configure the following constraints in your `configuration.php` file.
This is only temporary and will be replaced with pulling the token from the database in the future.
```php
// VirtFusion API URL
const VIRTFUSION_API_URL = "https://your-virtfusion-url.com/api/v1";
// VirtFusion API Token
const VIRT_TOKEN = "your-virtfusion-token";
```
## What does this module change? ## What does this module change?
This module changes the following things: This module changes the following things:
- Adds configurable options to the product configuration page to allow the user to select the operating system and add - Adds configurable options to the product configuration page to allow the user to select the operating system and add
a ssh key to the initial deployment. a ssh key to the initial deployment.
## TODO
- [ ] Add post checkout checks to ensure the user has selected an operating system and added a ssh key.

View File

@@ -1,162 +1,12 @@
<?php <?php
use WHMCS\Module\Server\VirtFusionDirect\ConfigureService;
use WHMCS\User\User; use WHMCS\User\User;
if (!defined("WHMCS")) { if (!defined("WHMCS")) {
die("This file cannot be accessed directly"); die("This file cannot be accessed directly");
} }
/**
* You'll need to configure the following constrants in your configuration.php file.
* This is only temporary and will be replaced with pulling the token from the database in the future.
*
* const VIRTFUSION_API_URL = "https://your-virtfusion-url.com/api/v1";
*
* You can create a token in the VirtFusion control panel under System > API.
*
* const VIRT_TOKEN = "your-virtfusion-token";
*/
/**
* If the constants are not defined, return null to prevent errors.
*/
if (!defined("VIRTFUSION_API_URL") || !defined("VIRT_TOKEN")) {
return null;
}
if (!function_exists('fetchPackageId')) {
/**
* @param string $packageName
* @return int|null
* @throws JsonException
*/
function fetchPackageId(string $packageName): ?int
{
$url = sprintf("%s/packages", VIRTFUSION_API_URL);
$packages = makeRequest($url);
foreach ($packages['data'] as $package) {
if ($package['name'] === $packageName && $package['enabled'] === true) {
return $package['id'];
}
}
return null;
}
}
if (!function_exists('fetchTemplates')) {
/**
* @param int $serverPackageId
* @return array|null
* @throws JsonException
*/
function fetchTemplates(int $serverPackageId): ?array
{
$url = sprintf("%s/media/templates/fromServerPackageSpec/%d", VIRTFUSION_API_URL, $serverPackageId);
return makeRequest($url);
}
}
if (!function_exists('custom_os_templates_hook')) {
/**
* @param array $vars
* @return array|null[]
*/
function custom_os_templates_hook(array $vars): array
{
try {
$serverPackageId = fetchPackageId($vars['productinfo']['name']); // Replace with the appropriate server package ID
if ($serverPackageId === null) {
return [
'templates' => null,
];
}
$templates = fetchTemplates($serverPackageId);
// Assign the generated dropdown menu to a Smarty template variable
return [
'templates' => $templates,
];
} catch (JsonException $e) {
return [
'templates' => null,
];
}
}
}
if (!function_exists('get_vf_user_details')) {
/**
* @param int $id
* @return array
* @throws JsonException
*/
function get_vf_user_details(int $id): ?array {
$url = sprintf("%s/users/%s/byExtRelation", VIRTFUSION_API_URL, $id);
$response = makeRequest($url);
if (isset($response['msg']) && $response['msg'] === "ext_relation_id not found") {
return null;
}
return $response['data'];
}
}
if (!function_exists('makeRequest')) {
/**
* @param string $url
* @return mixed
* @throws JsonException
* @throws Exception
*/
function makeRequest(string $url): array
{
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array(
sprintf("Authorization: Bearer %s", VIRT_TOKEN)
)
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
throw new Exception("cURL Error: " . $err);
}
return json_decode($response, true, 512, JSON_THROW_ON_ERROR);
}
}
if (!function_exists('get_users_ssh_keys')) {
/**
* @throws JsonException
*/
function get_users_ssh_keys(?User $user): ?array {
if (is_null($user)) {
return null;
}
$vfUser = get_vf_user_details($user['id']);
$url = sprintf("%s/ssh_keys/user/%s", VIRTFUSION_API_URL, $vfUser['id']);
$response = makeRequest($url);
return $response;
}
}
if (!function_exists('add_hook_os_templates')) { if (!function_exists('add_hook_os_templates')) {
/** /**
* @param array $vars * @param array $vars
@@ -169,13 +19,18 @@ if (!function_exists('add_hook_os_templates')) {
return null; return null;
} }
$templates_data = custom_os_templates_hook($vars)['templates']; $cs = new ConfigureService();
$templates_data = $cs->fetchTemplates(
$cs->fetchPackageId($vars['productinfo']['name'])
);
if (empty($templates_data)) { if (empty($templates_data)) {
return null; return null;
} }
$dropdownOptions = []; $dropdownOptions = [];
foreach ($templates_data['data'] as $osCategory) { foreach ($templates_data['data'] as $osCategory) {
foreach ($osCategory['templates'] as $template) { foreach ($osCategory['templates'] as $template) {
$optionValue = $template['id']; $optionValue = $template['id'];
@@ -197,7 +52,7 @@ if (!function_exists('add_hook_os_templates')) {
'selectedvalue' => '' 'selectedvalue' => ''
]; ];
$sshKeys = get_users_ssh_keys($vars['loggedinuser']); $sshKeys = $cs->getUserSshKeys($vars['loggedinuser']);
$sshKeysOptions = [ $sshKeysOptions = [
'id' => 'ssh_key', 'id' => 'ssh_key',
@@ -217,6 +72,7 @@ if (!function_exists('add_hook_os_templates')) {
]; ];
$configurableoptions = $vars['configurableoptions']; $configurableoptions = $vars['configurableoptions'];
array_push( array_push(
$configurableoptions, $configurableoptions,
$osTemplates, $osTemplates,

View File

@@ -0,0 +1,99 @@
<?php
namespace WHMCS\Module\Server\VirtFusionDirect;
use JsonException;
use WHMCS\Database\Capsule as DB;
use WHMCS\User\User;
class ConfigureService extends Module
{
/**
* @var array|false $cp
*/
private array|bool $cp;
public function __construct()
{
parent::__construct();
$this->cp = $this->getCP(false, true);
}
/**
* @param string $packageName
* @return int|null
* @throws JsonException
*/
public function fetchPackageId(string $packageName): ?int
{
$request = $this->initCurl($this->cp['token']);
$response = $request->get(
sprintf("%s/packages", $this->cp['url'])
);
$packages = $this->decodeResponseFromJson($response);
foreach ($packages['data'] as $package) {
if ($package['name'] === $packageName && $package['enabled'] === true) {
return $package['id'];
}
}
return null;
}
/**
* @param int $serverPackageId
* @return array|null
* @throws JsonException
*/
public function fetchTemplates(int $serverPackageId): ?array
{
$request = $this->initCurl($this->cp['token']);
$response = $request->get(
sprintf("%s/media/templates/fromServerPackageSpec/%d", $this->cp['url'], $serverPackageId)
);
return $this->decodeResponseFromJson($response);
}
/**
* @param User|null $user
* @return array|null
* @throws JsonException
*/
public function getUserSshKeys(?User $user): ?array
{
if (is_null($user)) {
return null;
}
$request = $this->initCurl($this->cp['token']);
$vfUser = $this->getVFUserDetails($user['id']);
$response = $request->get(
sprintf("%s/ssh_keys/user/%d", $this->cp['url'], $vfUser['id'])
);
return $this->decodeResponseFromJson($response);
}
/**
* @param int $id
* @return array|null
* @throws JsonException
*/
public function getVFUserDetails(int $id): ?array
{
$request = $this->initCurl($this->cp['token']);
$response = $this->decodeResponseFromJson($request->get(
sprintf("%s/users/%d/byExtRelation", $this->cp['url'], $id)
));
return isset($response['msg']) && $response['msg'] === "ext_relation_id not found" ? null : $response['data'];
}
}

View File

@@ -232,4 +232,17 @@ class Module
return $curl; return $curl;
} }
/**
* Decodes a response from JSON into an associative array.
*
* @param string $response
*
* @return array
* @throws \JsonException
*/
public function decodeResponseFromJson(string $response): array
{
return json_decode($response, true, 512, JSON_THROW_ON_ERROR);
}
} }