Skip to content

Commit

Permalink
TASK SIO-4479 allow reinstalling to application
Browse files Browse the repository at this point in the history
  • Loading branch information
Stanislav Vozhov authored and vss414 committed Sep 6, 2022
1 parent f1ef2e9 commit 52e5d58
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 24 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ The module gives the ability to select a specific operating system while orderin

Create a configurable option named `Operating System`. Add options with the following convention: `osId|osName`. The option will have higher priority over the selected operating system in the Module Settings of a product.

#### Applications

The module gives the ability to select a specific application while ordering a product. You can manage the list of available applications in the Configurable Options.

![Application](./docs/option-app.png)

Create a configurable option named `Application`. Add options with the following convention: `applicationId|applicationName`. The option will have higher priority over the selected application in the Module Settings of a product. If client chooses both `Operating System` and `Application` then the `Operating System` option will be used.

#### Plan parameters

The module gives the ability to select specific plan parameters such as `VCPU`, `Memory`, `Disk Space`, `Total traffic limit monthly` (for KVM and VZ), `VCPU Units`, `VCPU Limit`, `IO Priority`, and `Swap` (for VZ) while ordering a product.
Expand Down
Binary file added docs/option-app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions modules/servers/solusiovps/js/jquery.validate.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions modules/servers/solusiovps/lang/english.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

$_LANG['solusiovps_config_option_plan'] = 'Plan';
$_LANG['solusiovps_config_option_operating_system'] = 'Operating System';
$_LANG['solusvm2vps_config_option_application'] = 'Application';
$_LANG['solusiovps_config_option_default_operating_system'] = 'Default Operating System';
$_LANG['solusiovps_config_option_application'] = 'Application';
$_LANG['solusiovps_config_option_default_location'] = 'Default Location';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class ProductConfigOption
{
const LOCATION = 'Location';
const OPERATING_SYSTEM = 'Operating System';
const APPLICATION = 'Application';
const MEMORY = 'Memory';
const DISK_SPACE = 'Disk Space';
const VCPU = 'VCPU';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public function restart(int $id): array
return $this->processResponse($this->connector->post("servers/{$id}/restart"));
}

public function reinstall(int $serverId, int $osId): array
public function reinstall(int $serverId, int $osId, int $applicationId, array $applicationData = []): array
{
$options = [];

Expand All @@ -71,6 +71,13 @@ public function reinstall(int $serverId, int $osId): array
'os' => $osId,
],
];
} else if ($applicationId > 0) {
$options = [
'json' => [
'application' => $applicationId,
'application_data' => $applicationData,
],
];
}

return $this->processResponse($this->connector->post("servers/{$serverId}/reinstall", $options));
Expand Down
9 changes: 6 additions & 3 deletions modules/servers/solusiovps/pages/reinstall.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@
require dirname(__DIR__, 4) . '/init.php';
require dirname(__DIR__) . '/vendor/autoload.php';

$serviceId = (int) $_GET['serviceId'];
$osId = (int) $_GET['osId'];
$serviceId = (int) $_POST['serviceId'];
$osId = (int) $_POST['osId'];
$applicationId = (int) $_POST['applicationId'];
$applicationData = $_POST['applicationData'];

$ca = new ClientArea();
$hosting = Hosting::getByServiceId($serviceId);

Expand All @@ -28,4 +31,4 @@
$serverParams = Server::getParams($serverId);
$serverResource = new ServerResource(Connector::create($serverParams));

$serverResource->reinstall($server->server_id, $osId);
$serverResource->reinstall($server->server_id, $osId, $applicationId, $applicationData);
25 changes: 24 additions & 1 deletion modules/servers/solusiovps/solusiovps.php
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,25 @@ function solusiovps_ClientArea(array $params): array
$serverResponse = $serverResource->get($server->server_id);
$productId = (int)$params['pid'];
$defaultOsId = (int)Arr::get($params, 'configoption3');
$defaultApplicationId = (int)Arr::get($params, 'configoption4');

$applicationOptions = ProductConfigOption::getProductOptions($productId, ProductConfigOption::APPLICATION);

$applicationResource = new ApplicationResource(Connector::create($params));
$applications = [];
foreach ($applicationResource->list() as $item) {
$id = (int)Arr::get($item, 'id');
if (isset($applicationOptions[$id]) || $id === $defaultApplicationId) {
$schema = json_decode(Arr::get($item, 'json_schema'), true);
foreach ($schema['required'] as $property) {
$schema['properties'][$property]['required'] = true;
}
$applications[$id] = [
'name' => Arr::get($item, 'name'),
'schema' => $schema,
];
}
}

$totalTraffic = Unit::convert(
Arr::get($serverResponse, 'data.usage.network.incoming.value') +
Expand All @@ -436,8 +455,12 @@ function solusiovps_ClientArea(array $params): array
'data' => [
'ip' => Arr::get($serverResponse, 'data.ip_addresses.ipv4.0.ip'),
'status' => Arr::get($serverResponse, 'data.status'),
'operating_systems' => json_encode(ProductConfigOption::getProductOptions($productId, ProductConfigOption::OPERATING_SYSTEM)),
'operating_systems' => json_encode(
ProductConfigOption::getProductOptions($productId, ProductConfigOption::OPERATING_SYSTEM)
),
'default_os_id' => $defaultOsId,
'applications' => json_encode($applications),
'default_application_id' => $defaultApplicationId,
'domain' => $params['domain'],
'boot_mode' => Arr::get($serverResponse, 'data.boot_mode'),
'traffic_current' => $totalTraffic,
Expand Down
110 changes: 92 additions & 18 deletions modules/servers/solusiovps/templates/overview.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,36 @@
</style>

<script src="modules/servers/solusiovps/node_modules/chart.js/dist/Chart.js"></script>
<script type="text/javascript" src="modules/servers/solusiovps/node_modules/jsonform/deps/underscore.js"></script>
<script type="text/javascript" src="modules/servers/solusiovps/node_modules/jsonform/deps/opt/jsv.js"></script>
<script type="text/javascript" src="modules/servers/solusiovps/node_modules/jsonform/lib/jsonform.js"></script>
<script type="text/javascript" src="modules/servers/solusiovps/js/jquery.validate.min.js"></script>

<div id="dlg-os-selector" class="modal">
<div id="dlg-reinstall-selector" class="modal">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-body">
<p>
{$LANG.solusiovps_config_option_operating_system}:
</p>
<p>
<select id="fld-os-id" class="form-control">
<option value="0">.lauris.space</option>
</select>
</p>
<div id="os-id-block">
<p>
{$LANG.solusiovps_config_option_operating_system}:
</p>
<p>
<select id="fld-os-id" class="form-control" onchange="onChangeOs();">
<option value="0"></option>
</select>
</p>
</div>
<div id="application-id-block">
<p>
{$LANG.solusiovps_config_option_application}:
</p>
<p>
<select id="fld-application-id" class="form-control" onchange="onChangeApplication(this.value);">
<option value="0"></option>
</select>
</p>
<form id="reinstall-form"></form>
</div>
<p style="text-align: right;">
<button class="btn btn-danger" onclick="reinstallServerConfirm();">
{$LANG.solusiovps_button_reinstall}
Expand Down Expand Up @@ -243,7 +260,7 @@
<td>{$nextduedate}</td>
</tr>
<tr style="border-bottom: 1px solid #dddddd">
<td>{$LANG.solusvm2vps_traffic}</td>
<td>{$LANG.solusiovps_traffic}</td>
<td>
{$data['traffic_current']} {$data['traffic_unit']}
{if $data['traffic_limit']}
Expand Down Expand Up @@ -294,6 +311,8 @@
<script>
const operatingSystems = {$data['operating_systems']};
const defaultOsId = {$data['default_os_id']};
const applications = {$data['applications']};
const defaultApplicationId = {$data['default_application_id']};
let domain = '{$data['domain']}';
let bootMode = '{$data['boot_mode']}';
Expand Down Expand Up @@ -351,11 +370,34 @@ const restartServer = () => {
});
}
const onChangeOs = () => {
let $select = $('#fld-application-id');
$select.val(0);
$('#reinstall-form').html("")
}
const onChangeApplication = (value) => {
let $select = $('#fld-os-id');
$select.val(0);
if (applications[value] !== undefined) {
$('#reinstall-form').html("").jsonForm({
schema: applications[value]['schema'],
form: ["*"],
});
}
}
const reinstallServer = () => {
if (!window.confirm('{$LANG.solusiovps_confirm_reinstall}')) {
return;
}
if (Object.keys(operatingSystems).length === 0 && Object.keys(applications).length === 0) {
reinstallServerContinue(defaultOsId, 0);
return;
}
if (Object.keys(operatingSystems).length > 0) {
let $select = $('#fld-os-id');
Expand All @@ -369,33 +411,65 @@ const reinstallServer = () => {
}
$select.val(defaultOsId);
} else {
$('#os-id-block').hide()
}
if (Object.keys(applications).length > 0) {
let $select = $('#fld-application-id');
$select.empty();
$('#dlg-os-selector').modal('show');
for (const [id, application] of Object.entries(applications)) {
$select.append($('<option>', {
value: id,
text: application['name']
}));
}
if (Object.keys(operatingSystems).length === 0 || defaultOsId === 0) {
$select.val(defaultApplicationId);
if (defaultApplicationId > 0) {
onChangeApplication(defaultApplicationId);
}
} else {
$select.val(0);
}
} else {
reinstallServerContinue(defaultOsId);
$('#application-id-block').hide()
}
$('#dlg-reinstall-selector').modal('show');
}
const reinstallServerContinue = osId => {
$.get({
const reinstallServerContinue = (osId, applicationId = 0, applicationData = {}) => {
$.post({
url: 'modules/servers/solusiovps/pages/reinstall.php',
data: {
serviceId: {$serviceid},
osId: osId
osId: osId,
applicationId: applicationId,
applicationData: applicationData,
}
});
}
const reinstallServerConfirm = () => {
const osId = $('#fld-os-id').val();
const applicationId = $('#fld-application-id').val();
const form = $('#reinstall-form');
let applicationData = new Object();
reinstallServerContinue(osId);
if(applicationId > 0 && $(form).valid()) {
form.serializeArray().map(field => applicationData[field.name] = field.value);
}
$('#dlg-os-selector').modal('hide');
reinstallServerContinue(osId, applicationId, applicationData);
$('#dlg-reinstall-selector').modal('hide');
}
const reinstallServerCancel = () => {
$('#dlg-os-selector').modal('hide');
$('#dlg-reinstall-selector').modal('hide');
}
const openVncDialog = () => {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
},
"dependencies": {
"@novnc/novnc": "^1.2.0",
"chart.js": "^2.9.4"
"chart.js": "^2.9.4",
"jsonform": "^2.2.5"
},
"require-dev": {
"phpunit/phpunit": "^9.5.9"
Expand Down
54 changes: 54 additions & 0 deletions tests/ClientAreaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@
use WHMCS\Module\Server\SolusIoVps\SolusAPI\Connector;
use WHMCS\Module\Server\SolusIoVps\SolusAPI\Resources\ServerResource;
use WHMCS\Module\Server\SolusIoVps\WhmcsAPI\Language;
use WHMCS\Module\Server\SolusVm2Vps\SolusAPI\Resources\ApplicationResource;

class ClientAreaTest extends AbstractModuleTest
{
private int $serverId = 1;
private array $params;
private Mockery\MockInterface $serverResource;
private Mockery\MockInterface $solusServer;
private Mockery\MockInterface $applicationResource;
private Mockery\MockInterface $productConfigOption;

protected function setUp(): void
Expand All @@ -31,11 +33,14 @@ protected function setUp(): void
'status' => 'Pending',
// default operating system id
'configoption3' => '1',
// default application id
'configoption4' => '2',
];

Mockery::getConfiguration()->setConstantsMap([
'WHMCS\Module\Server\SolusIoVps\Database\Models\ProductConfigOption' => [
'OPERATING_SYSTEM' => 'Operating System',
'APPLICATION' => 'Application',
],
]);

Expand All @@ -45,6 +50,7 @@ protected function setUp(): void
$this->productConfigOption = Mockery::mock('overload:' . ProductConfigOption::class);
$this->solusServer = Mockery::mock('overload:' . SolusServer::class);
$this->solusServer->shouldReceive('getByServiceId')->once()->andReturn(true);
$this->applicationResource = Mockery::mock('overload:' . ApplicationResource::class);
}

public function loadServerPageNegativeDataProvider(): array
Expand Down Expand Up @@ -135,6 +141,40 @@ public function testLoadServerPageServer(bool $isEnabledTrafficLimit, ?int $expe
$this->productConfigOption->shouldReceive('getProductOptions')
->with($this->params['pid'], 'Operating System')
->andReturn([ 'product' => [ 'option1', 'option2' ] ]);
$this->productConfigOption->shouldReceive('getProductOptions')
->with($this->params['pid'], 'Application')
->andReturn([[
'id' => 2,
'name' => 'Application 2',
]]);
$this->applicationResource->shouldReceive('list')->andReturn([
[
'id' => 1,
'name' => 'Application 1',
'json_schema' => json_encode([
'foo1' => 'bar1',
'required' => ['foo1'],
'properties' => [
'foo1' => [
'type' => 'string',
],
],
]),
],
[
'id' => 2,
'name' => 'Application 2',
'json_schema' => json_encode([
'foo2' => 'bar2',
'required' => ['foo2'],
'properties' => [
'foo2' => [
'type' => 'string',
],
],
]),
],
]);

$result = call_user_func(self::getModuleFunction('ClientArea'), $this->params);

Expand All @@ -145,7 +185,21 @@ public function testLoadServerPageServer(bool $isEnabledTrafficLimit, ?int $expe
'ip' => '192.168.0.1',
'status' => 'running',
'operating_systems' => json_encode([ 'product' => [ 'option1', 'option2' ] ]),
'applications' => json_encode([2 => [
'name' => 'Application 2',
'schema' => [
'foo2' => 'bar2',
'required' => ['foo2'],
'properties' => [
'foo2' => [
'type' => 'string',
'required' => true,
],
],
],
]]),
'default_os_id' => 1,
'default_application_id' => 2,
'domain' => 'test.domain.ltd',
'boot_mode' => 'resque',
'traffic_current' => 0.99,
Expand Down

0 comments on commit 52e5d58

Please sign in to comment.