259 lines
7.5 KiB
PHP
259 lines
7.5 KiB
PHP
<?php
|
|
|
|
namespace Paymenter\Extensions\Servers\Virtfusion;
|
|
|
|
use App\Classes\Extension\Server;
|
|
use App\Models\Service;
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
class Virtfusion extends Server
|
|
{
|
|
/**
|
|
* Get all the configuration for the extension
|
|
*
|
|
* @param array $values
|
|
*/
|
|
public function getConfig($values = []): array
|
|
{
|
|
return [
|
|
[
|
|
'name' => 'host',
|
|
'type' => 'text',
|
|
'label' => 'Hostname',
|
|
'required' => true,
|
|
'validation' => 'url',
|
|
],
|
|
[
|
|
'name' => 'apikey',
|
|
'type' => 'text',
|
|
'label' => 'API key',
|
|
'required' => true,
|
|
'encrypted' => true,
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Get product config
|
|
*
|
|
* @param array $values
|
|
*/
|
|
public function getProductConfig($values = []): array
|
|
{
|
|
$apiPackages = $this->request('/packages');
|
|
$packages = [];
|
|
foreach ($apiPackages['data'] as $package) {
|
|
$packages[$package['id']] = $package['name'];
|
|
}
|
|
|
|
// We need to wait for a virtfusion update to get hypervisors
|
|
$apiHypervisors = $this->request('/compute/hypervisors/groups');
|
|
$hypervisors = [];
|
|
foreach ($apiHypervisors['data'] as $hypervisor) {
|
|
$hypervisors[$hypervisor['id']] = $hypervisor['name'];
|
|
}
|
|
|
|
return [
|
|
[
|
|
'name' => 'package',
|
|
'type' => 'select',
|
|
'label' => 'Package',
|
|
'required' => true,
|
|
'options' => $packages,
|
|
],
|
|
[
|
|
'name' => 'hypervisor',
|
|
'type' => 'select',
|
|
'label' => 'Hypervisor Group ID',
|
|
'required' => true,
|
|
'description' => 'The default Hypervisor group ID',
|
|
'options' => $hypervisors,
|
|
],
|
|
[
|
|
'name' => 'ipv4',
|
|
'type' => 'number',
|
|
'label' => 'Default IPv4',
|
|
'description' => 'The default amount of IPv4 addresses to assign to the server',
|
|
'required' => true,
|
|
'validation' => 'integer|min:1',
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Check if currenct configuration is valid
|
|
*/
|
|
public function testConfig(): bool|string
|
|
{
|
|
try {
|
|
$this->request('/connect');
|
|
} catch (\Exception $e) {
|
|
return $e->getMessage();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Do a request to the Virtfusion API
|
|
*
|
|
* @param string $url
|
|
* @param string $method
|
|
* @param array $data
|
|
*/
|
|
public function request($url, $method = 'get', $data = []): array
|
|
{
|
|
// Trim any leading slashes from the base url and add the path URL to it
|
|
$req_url = rtrim($this->config('host'), '/') . '/api/v1' . $url;
|
|
$response = Http::withHeaders([
|
|
'Authorization' => 'Bearer ' . $this->config('apikey'),
|
|
'Accept' => 'application/json',
|
|
])->$method($req_url, $data);
|
|
|
|
if (!$response->successful()) {
|
|
throw new \Exception('An error occurred, got status code ' . $response->status() . ' on ' . $req_url);
|
|
}
|
|
|
|
return $response->json() ?? [];
|
|
}
|
|
|
|
/**
|
|
* Get or create a user on VirtFusion
|
|
*/
|
|
public function getUser(Service $service): string
|
|
{
|
|
try {
|
|
$response = $this->request('/users/' . $service->user->id . '/byExtRelation');
|
|
} catch (\Exception $e) {
|
|
try {
|
|
$response = $this->request('/users', 'post', [
|
|
'email' => $service->user->email,
|
|
'name' => $service->user->name,
|
|
'extRelationId' => $service->user->id,
|
|
]);
|
|
} catch (\Exception $e) {
|
|
throw new \Exception('Failed to create user, this is probably due to a wrong extRelationId');
|
|
}
|
|
}
|
|
|
|
return $response['data']['id'] ?? '';
|
|
}
|
|
|
|
/**
|
|
* Create a server
|
|
*
|
|
* @param array $settings (product settings)
|
|
* @param array $properties (checkout options)
|
|
* @return bool
|
|
*/
|
|
public function createServer(Service $service, $settings, $properties)
|
|
{
|
|
if (isset($properties['server_id'])) {
|
|
throw new \Exception('Server already exists');
|
|
}
|
|
|
|
$data = [
|
|
'packageId' => $settings['package'],
|
|
'userId' => $this->getUser($service),
|
|
'hypervisorId' => $settings['hypervisor'],
|
|
'ipv4' => $settings['ipv4'],
|
|
];
|
|
// Allowed data to be overwritten
|
|
$allowed = ['ipv4', 'packageId', 'hypervisorId', 'storage', 'memory', 'traffic', 'networkSpeedInbound', 'networkSpeedOutbound', 'cpuCores', 'networkProfile', 'storageProfile'];
|
|
$settings = array_merge($settings, $properties);
|
|
$settings = array_intersect_key($settings, array_flip($allowed));
|
|
$data = array_merge($data, $settings);
|
|
|
|
$response = $this->request('/servers', 'post', $data);
|
|
|
|
$service->properties()->updateOrCreate([
|
|
'key' => 'server_id',
|
|
], [
|
|
'name' => 'VirtFusion Server ID',
|
|
'value' => $response['data']['id'],
|
|
]);
|
|
|
|
return $response['data'];
|
|
}
|
|
|
|
/**
|
|
* Suspend a server
|
|
*
|
|
* @param array $settings (product settings)
|
|
* @param array $properties (checkout options)
|
|
* @return bool
|
|
*/
|
|
public function suspendServer(Service $service, $settings, $properties)
|
|
{
|
|
if (!isset($properties['server_id'])) {
|
|
throw new \Exception('Server does not exist');
|
|
}
|
|
|
|
$this->request('/servers/' . $properties['server_id'] . '/suspend', 'post');
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Unsuspend a server
|
|
*
|
|
* @param array $settings (product settings)
|
|
* @param array $properties (checkout options)
|
|
* @return bool
|
|
*/
|
|
public function unsuspendServer(Service $service, $settings, $properties)
|
|
{
|
|
if (!isset($properties['server_id'])) {
|
|
throw new \Exception('Server does not exist');
|
|
}
|
|
|
|
$this->request('/servers/' . $properties['server_id'] . '/unsuspend', 'post');
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Terminate a server
|
|
*
|
|
* @param array $settings (product settings)
|
|
* @param array $properties (checkout options)
|
|
* @return bool
|
|
*/
|
|
public function terminateServer(Service $service, $settings, $properties)
|
|
{
|
|
if (!isset($properties['server_id'])) {
|
|
throw new \Exception('Server does not exist');
|
|
}
|
|
|
|
$this->request('/servers/' . $properties['server_id'], 'delete');
|
|
|
|
return true;
|
|
}
|
|
|
|
public function getActions(Service $service): array
|
|
{
|
|
return [
|
|
[
|
|
'type' => 'button',
|
|
'label' => 'Go to Server',
|
|
'function' => 'ssoLink',
|
|
],
|
|
];
|
|
}
|
|
|
|
public function ssoLink(Service $service): string
|
|
{
|
|
$data = $this->request('/users/' . $service->user->id . '/authenticationTokens', 'post');
|
|
|
|
return rtrim($this->config('host'), '/') . $data['data']['authentication']['endpoint_complete'];
|
|
}
|
|
|
|
public function migrateOption(string $key, ?string $value)
|
|
{
|
|
return match ($key) {
|
|
'ips' => ['key' => 'ipv4', 'value' => $value],
|
|
default => ['key' => $key, 'value' => $value]
|
|
};
|
|
}
|
|
}
|