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 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)
# 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).
## 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.
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?
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
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
use WHMCS\Module\Server\VirtFusionDirect\ConfigureService;
use WHMCS\User\User;
if (!defined("WHMCS")) {
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')) {
/**
* @param array $vars
@@ -169,13 +19,18 @@ if (!function_exists('add_hook_os_templates')) {
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)) {
return null;
}
$dropdownOptions = [];
foreach ($templates_data['data'] as $osCategory) {
foreach ($osCategory['templates'] as $template) {
$optionValue = $template['id'];
@@ -197,7 +52,7 @@ if (!function_exists('add_hook_os_templates')) {
'selectedvalue' => ''
];
$sshKeys = get_users_ssh_keys($vars['loggedinuser']);
$sshKeys = $cs->getUserSshKeys($vars['loggedinuser']);
$sshKeysOptions = [
'id' => 'ssh_key',
@@ -217,6 +72,7 @@ if (!function_exists('add_hook_os_templates')) {
];
$configurableoptions = $vars['configurableoptions'];
array_push(
$configurableoptions,
$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;
}
/**
* 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);
}
}