- Requirements
- Versioning
- Security
- Installing and upgrading
- Initial configuration
- Creating more products
- Renaming configurable options
- Configuration
- Template and asset overrides
- Notes
- Going further
- Development
- PHP >= 8.1
- WHMCS >= 8.0
- A Katapult account with access to managed organizations
- A Katapult organization API key
This module follows semantic versioning.
If you discover any security related issues, please email contact@krystal.uk instead of using the issue tracker.
Download the latest katapult.zip and extract it to /whmcs/modules/servers/katapult
. The resulting file structure should look similar to this:
├── /whmcs/modules/servers/katapult
│ ├── assets
│ ├── helpers.php
│ ├── hooks.php
│ ├── katapult.php
│ ├── lib
│ ├── overrides
│ ├── README.md
│ ├── vendor
│ └── views
The Katapult module will then be available for you to use inside WHMCS.
Due to a limitation in WHMCS (#18), a server is required to use the SSO functionality of this module, which is used to open a console session on a VM.
Create a server in WHMCS and assign it to the Katapult module. You can use any values in the fields (hostname, password etc) as they're not used anywhere.
It's a good idea to split the Katapult products into a new product group, you should do this before creating a new product.
Note: Katapult products do not need to be separated from your other products if you don't want them to be.
Before you can sell a Katapult service, you need to create a new WHMCS product. Create a product as normal and set the module to Katapult
. It is important that at this stage you click Save Changes before proceeding.
You can now click the 'Other' tab on the product's configuration, and you will be presented with a GUI to enter your Katapult API key and parent organization (if using a user key). Fill those in and click Save Changes. Please note, this GUI will not show up unless the product is assigned to the Katapult module and then saved, before viewing the 'Other' tab.
When you save your API key, WHMCS will connect to Katapult and sync available datacenters and disk templates for virtual machines and assign them to configurable options for the Katapult products.
Once the API key and parent organization have been saved, you can go back to the 'Module Settings' tab, and select the VM package you wish to assign to this product, and then Save Changes.
You are now ready to sell this product as you would any other WHMCS product.
When creating a new product, the most important things to confirm are the Katapult module is selected, and the configurable option group Katapult Virtual Machines
is assigned to it.
The Katapult module keeps its own record of the configurable options it creates to allow it to automatically sync them with Katapult. You can change the name of configurable options and the groups as you need.
Dropdown options such as disk template and data center use friendly display names - you can change everything after the first |
(pipe) symbol in their names if desired.
If you wish to manually sync options from Katapult, you can do so by ticking the 'Re-sync' checkbox on the 'Other' tab of a Katapult product.
⚙️ Note: Data centers and disk templates are automatically synced from Katapult daily, and new ones are hidden by default, you must un-hide them as required. This is to give you the control of selling into new regions and with new disk templates as you see fit.
You can set the Katapult API key and other options in a products settings under the 'Other' tab for any Katapult product. The settings will be used for all products.
The module comes with whitelabel defaults for the client area. You can however override the template, JS and CSS files with your own. The defaults are neither pre-compiled nor minified for ease of editing, they also contain comments to explain what's going on.
To override a default file, simply copy the default into overrides
and then apply your changes to that file:
cp views/client/virtual_machines/overview.tpl overrides/views/client/virtual_machines/overview.tpl
Your override file will then be used instead of the default. Overrides can be used for any files in assets
or views
. An example directory structure is provided by default but is not required.
Operations on a VM are logged against the service via the client's activity log. This is the case for both admins and clients, for complete traceability.
For debugging purposes, all HTTP requests to the Katapult API can also be logged in detail by enabling the WHMCS module debug log.
The module's client area actions are protected by a no replay token, which is automatically appended to action URLs. This prevents the end user from bookmarking the shutdown URL and shutting their VM down everytime they view it in their client area via their bookmark.
WHMCS does not protect module actions by default, so be aware that a page can't be refreshed to re-run an action on a VM, which may be possible with other modules. For more information see this issue.
Virtual machines are built asynchronously on Katapult. This means when a service is created in WHMCS, it will call to Katapult and ask it to build a VM. At this point, there is no VM, but the service is considered active. There is a task which runs on the WHMCS cron (which should be called as often as possible, usually every 5 minutes) which will call back to Katapult to check if the VM is built. When the VM is built, the initial root password, hostname, IP addresses and VM ID will be persisted to the WHMCS database.
The issue raised with this, is WHMCS considers the service active when the build has been requested. It will then send the services welcome email (if configured). That's not useful if you want to include the VM's IP address or hostname, as WHMCS doesn't know it at that point. This problem can be solved by using a hook to send the services welcome email and disabling the default welcome email in WHMCS on the products settings.
This module exposes some hooks for you to interact with at key lifecycle events of objects.
Fires when a VM build has been created with Katapult.
use \WHMCS\Module\Server\Katapult\WHMCS\Service\VirtualMachine;
\add_hook('KatapultVirtualMachineBuildRequested', 0, function(VirtualMachine $service) {
\sendMessage('Katapult Server Building Email', $service->id);
});
Fires when a VM has finished building and has been persisted to the WHMCS database.
use \WHMCS\Module\Server\Katapult\WHMCS\Service\VirtualMachine;
\add_hook('KatapultVirtualMachineBuilt', 0, function(VirtualMachine $service) {
\sendMessage('Katapult Server Built Email', $service->id);
});
Fires when a VM build has timed out. The module will continue to check for the build, but this hook will only be fired once. The timeout is set to 15 minutes.
use \WHMCS\Module\Server\Katapult\WHMCS\Service\VirtualMachine;
\add_hook('KatapultVirtualMachineBuildTimedOut', 0, function(VirtualMachine $service) {
// Send a notification to an admin or open a ticket
});
The \WHMCS\Module\Server\Katapult\WHMCS\Service\VirtualMachine
class ultimately extends from the WHMCS service model, WHMCS\Service\Service
, which is a Laravel model, which references tblhosting
in the WHMCS database.
This module uses the Salmon datastore to persist data to WHMCS, outside the default tables, using mod_salmon_data_store_items
. Data such as VM ID, build ID, organization ID and the encrypted API key are stored in this table.
Because of its parentage, you can instantiate a Katapult service like this:
use \WHMCS\Module\Server\Katapult\WHMCS\Service\VirtualMachine as VirtualMachineService;
use Krystal\Katapult\API\RestfulKatapultApiV1\Resources\Organization\VirtualMachine as KatapultVirtualMachine;
/** @var VirtualMachineService $katapultService */
$katapultService = VirtualMachineService::findOrFail(1337); // 1337 being the ID of the service in tblhosting
// You can then access various details about the service and even the virtual machine itself
$katapultService->vm_build_id; // string|null - The build ID Katapult created for the VM
$katapultService->vm_build_started_at; // \Carbon\Carbon|null - When WHMCS requested the VM build
$katapultService->vm_id; // string|null - The VM ID. This is only available once the VM has been built.
$katapultService->vm; // KatapultVirtualMachine|null - the live VM instance from Katapult. It is cached per request lifecycle.
$katapultService->vm_state; // string - note, this will be 'unknown' if the VM does not exist
/** @var KatapultVirtualMachine|null $virtualMachine */
$virtualMachine = $katapultService->vm;
// Assuming we have a VM, we can perform actions against it
$virtualMachine->start();
$virtualMachine->stop();
$virtualMachine->shutdown();
$virtualMachine->reset();
$virtualMachine->createConsoleSession();
More details about interacting with the Katapult VM instance can be found in the Katault PHP library.
You can clone this repository directly into your development WHMCS installation, for example using this Vagrant box:
# Assuming you're WHMCS installation is at `/var/www/html/whmcs`
# This would normally be run on your host machine, not in the Vagrant VM
cd /var/www/html/whmcs/modules/servers
git clone git@github.com:krystal/katapult-whmcs.git katapult
cd katapult
composer install
When changes have been made to the module, and a new release is being published, a new ZIP file will need to be created to attach to the release. These ZIP files are used to distribute and install the module into WHMCS.
The module has a few require-dev dependencies which aren't required for use within WHMCS. Guzzle being one which has been known to cause conflicts with WHMCS, and is required by krystal/katapult-php. Because WHMCS has Guzzle installed, we don't need to include it the distribution of this module.
Things to consider when packaging the module up:
- Installing the required Composer dependencies
- Removing development and untracked files
- Adding special files such as
.htaccess
in/vendor
(WHMCS restriction with it being in the docroot) - Zipping it up consistently between versions.
To build the module automatically:
$ ./bin/katapult build:server-module
This will result in a katapult.zip
file in your build
directory, the full path will be outputted by the command.