Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
code_quality:
strategy:
matrix:
php_version: [8.1, 8.2, 8.3, 8.4]
php_version: [8.1, 8.2, 8.3, 8.4, 8.5]
runs-on: ubuntu-latest
steps:
- name: Checkout hypernode-deploy
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ Here's a list of Hypernode API features implemented in the client.
- Updating one or multiple Hypernode settings at once.
- Querying/polling the logbook for the status of a job.
- Listing, creating, updating and cancelling Brancher Hypernode instances.
- Ordering a new Hypernode.
- Listing and creating backups.
- Listing, creating and deleting whitelist entries.
- Listing products and retrieving the current product of a Hypernode.
- Listing SLA addons.
- Listing available preinstall configurations.
- Listing available settings (EAV descriptions) and block attack descriptions.
- Listing and creating Insights annotations.

## Related projects

Expand Down
18 changes: 18 additions & 0 deletions src/HypernodeClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,45 @@
use Http\Client\Common\HttpMethodsClientInterface;
use Hypernode\Api\Exception\HypernodeApiClientException;
use Hypernode\Api\Exception\HypernodeApiServerException;
use Hypernode\Api\Service\Addon;
use Hypernode\Api\Service\App;
use Hypernode\Api\Service\Backup;
use Hypernode\Api\Service\BrancherApp;
use Hypernode\Api\Service\Configuration;
use Hypernode\Api\Service\InsightsAnnotation;
use Hypernode\Api\Service\Logbook;
use Hypernode\Api\Service\Product;
use Hypernode\Api\Service\Settings;
use Hypernode\Api\Service\Whitelist;
use Psr\Http\Message\ResponseInterface;

class HypernodeClient
{
public HttpMethodsClientInterface $api;
public Addon $addon;
public App $app;
public Backup $backup;
public BrancherApp $brancherApp;
public Configuration $configuration;
public InsightsAnnotation $insightsAnnotation;
public Product $product;
public Settings $settings;
public Logbook $logbook;
public Whitelist $whitelist;

public function __construct(HttpMethodsClientInterface $apiClient)
{
$this->api = $apiClient;
$this->addon = new Addon($this);
$this->app = new App($this);
$this->backup = new Backup($this);
$this->brancherApp = new BrancherApp($this);
$this->configuration = new Configuration($this);
$this->insightsAnnotation = new InsightsAnnotation($this);
$this->product = new Product($this);
$this->settings = new Settings($this);
$this->logbook = new Logbook($this);
$this->whitelist = new Whitelist($this);
}

public function getJsonFromResponse(ResponseInterface $response)
Expand Down
29 changes: 29 additions & 0 deletions src/Service/Addon.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Hypernode\Api\Service;

use Hypernode\Api\Exception\HypernodeApiClientException;
use Hypernode\Api\Exception\HypernodeApiServerException;

class Addon extends AbstractService
{
public const V2_ADDON_SLA_LIST_URL = "/v2/addon/slas/";

/**
* List all available SLA addons.
*
* @return array List of SLA addons
* @throws HypernodeApiClientException
* @throws HypernodeApiServerException
*/
public function getSlas(): array
{
$response = $this->client->api->get(self::V2_ADDON_SLA_LIST_URL);

$this->client->maybeThrowApiExceptions($response);

return $this->client->getJsonFromResponse($response);
}
}
55 changes: 55 additions & 0 deletions src/Service/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ class App extends AbstractService
public const V2_BRANCHER_APP_URL = "/v2/brancher/app/%s/";
public const V2_BRANCHER_DETAIL_URL = "/v2/brancher/%s/";
public const V1_APP_FLOWS_URL = "/logbook/v1/logbooks/%s/flows/";
public const V2_APP_BLOCK_ATTACK_DESCRIPTIONS_URL = "/v2/app/block_attack_descriptions/";
public const V2_APP_EAV_DESCRIPTIONS_URL = "/v2/app/eav_descriptions/";
public const V2_APP_ORDER_URL = "/v2/app/order/";

/**
* @param array $params
Expand Down Expand Up @@ -44,4 +47,56 @@ public function getList(array $params = []): array

return $apps;
}

/**
* Show the available blocks that can be triggered using the block attack endpoint.
*
* @return array Map of attack names to their descriptions
* @throws \Http\Client\Exception
* @throws \Hypernode\Api\Exception\HypernodeApiClientException
* @throws \Hypernode\Api\Exception\HypernodeApiServerException
*/
public function getBlockAttackDescriptions(): array
{
$response = $this->client->api->get(self::V2_APP_BLOCK_ATTACK_DESCRIPTIONS_URL);

$this->client->maybeThrowApiExceptions($response);

return $this->client->getJsonFromResponse($response);
}

/**
* Show the available EAVs (entity-attribute values) that can be changed
* using the settings service.
*
* @return array Map of setting names to their descriptions
* @throws \Http\Client\Exception
* @throws \Hypernode\Api\Exception\HypernodeApiClientException
* @throws \Hypernode\Api\Exception\HypernodeApiServerException
*/
public function getEavDescriptions(): array
{
$response = $this->client->api->get(self::V2_APP_EAV_DESCRIPTIONS_URL);

$this->client->maybeThrowApiExceptions($response);

return $this->client->getJsonFromResponse($response);
}

/**
* Order a new Hypernode under your account.
*
* @param array $data Order data, requires at least the keys
* `product_code`, `app_name` and `initial_app_configuration`.
* @return void
* @throws \Http\Client\Exception
* @throws \Hypernode\Api\Exception\HypernodeApiClientException
* @throws \Hypernode\Api\Exception\HypernodeApiServerException
*/
public function order(array $data): void
{
$response = $this->client->api->post(self::V2_APP_ORDER_URL, [], json_encode($data));

$this->client->maybeThrowApiExceptions($response);
}
}
67 changes: 67 additions & 0 deletions src/Service/Backup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

declare(strict_types=1);

namespace Hypernode\Api\Service;

use Hypernode\Api\Exception\HypernodeApiClientException;
use Hypernode\Api\Exception\HypernodeApiServerException;

class Backup extends AbstractService
{
public const V2_APP_BACKUP_URL = "/v2/app/%s/backup/";

/**
* Show all backups that are currently available for the given Hypernode.
*
* @param string $app Name of the Hypernode
* @param array $params Query parameters, e.g. limit and offset
* @return array List of backups
* @throws HypernodeApiClientException
* @throws HypernodeApiServerException
*/
public function getList(string $app, array $params = []): array
{
$backups = [];

$requestUrl = sprintf(self::V2_APP_BACKUP_URL, $app);
if ($params) {
$requestUrl .= '?' . http_build_query($params);
}

while ($requestUrl) {
$response = $this->client->api->get($requestUrl);

$this->client->maybeThrowApiExceptions($response);
$data = $this->client->getJsonFromResponse($response);

foreach ($data['results'] as $item) {
$backups[] = $item;
}

$requestUrl = $data['next'];
}

return $backups;
}

/**
* Create a new snapshot backup. This requires sla-standard to be enabled
* on the Hypernode.
*
* @param string $app Name of the Hypernode
* @return string Response message
* @throws HypernodeApiClientException
* @throws HypernodeApiServerException
*/
public function create(string $app): string
{
$url = sprintf(self::V2_APP_BACKUP_URL, $app);

$response = $this->client->api->post($url);

$this->client->maybeThrowApiExceptions($response);

return $this->client->getJsonFromResponse($response);
}
}
46 changes: 46 additions & 0 deletions src/Service/Configuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Hypernode\Api\Service;

use Hypernode\Api\Exception\HypernodeApiClientException;
use Hypernode\Api\Exception\HypernodeApiServerException;

class Configuration extends AbstractService
{
public const V2_CONFIGURATION_URL = "/v2/configuration/";

/**
* List all available configurations for preinstalls.
*
* @param array $params Query parameters, e.g. allow_preinstall, limit and offset
* @return array List of app configurations
* @throws HypernodeApiClientException
* @throws HypernodeApiServerException
*/
public function getList(array $params = []): array
{
$configurations = [];

$requestUrl = self::V2_CONFIGURATION_URL;
if ($params) {
$requestUrl .= '?' . http_build_query($params);
}

while ($requestUrl) {
$response = $this->client->api->get($requestUrl);

$this->client->maybeThrowApiExceptions($response);
$data = $this->client->getJsonFromResponse($response);

foreach ($data['results'] as $item) {
$configurations[] = $item;
}

$requestUrl = $data['next'];
}

return $configurations;
}
}
75 changes: 75 additions & 0 deletions src/Service/InsightsAnnotation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

declare(strict_types=1);

namespace Hypernode\Api\Service;

use Hypernode\Api\Exception\HypernodeApiClientException;
use Hypernode\Api\Exception\HypernodeApiServerException;

class InsightsAnnotation extends AbstractService
{
public const V2_INSIGHTS_ANNOTATION_LIST_URL = "/v2/insights-annotation/";
public const V2_INSIGHTS_ANNOTATION_CREATE_URL = "/v2/insights-annotation/create/";

/**
* List all custom Insights annotations for the Hypernodes you have access
* to. Only annotations created through the API are listed; system
* annotations generated from platform events are not included.
*
* @param array $params Query parameters, e.g. limit and offset
* @return array List of Insights annotations
* @throws HypernodeApiClientException
* @throws HypernodeApiServerException
*/
public function getList(array $params = []): array
{
$annotations = [];

$requestUrl = self::V2_INSIGHTS_ANNOTATION_LIST_URL;
if ($params) {
$requestUrl .= '?' . http_build_query($params);
}

while ($requestUrl) {
$response = $this->client->api->get($requestUrl);

$this->client->maybeThrowApiExceptions($response);
$data = $this->client->getJsonFromResponse($response);

foreach ($data['results'] as $item) {
$annotations[] = $item;
}

$requestUrl = $data['next'];
}

return $annotations;
}

/**
* Create a custom Insights annotation for a Hypernode. The annotation is
* shown in the Insights graphs at the point in time given by `x_axis` (a
* unix timestamp in seconds). Optionally restrict the annotation to
* specific graphs with `metrics`, a comma-separated list of metric names;
* when omitted, the annotation applies to all metrics.
*
* @param array $data Annotation data, requires at least the keys
* `name`, `x_axis` and `app`.
* @return array The created annotation
* @throws HypernodeApiClientException
* @throws HypernodeApiServerException
*/
public function create(array $data): array
{
$response = $this->client->api->post(
self::V2_INSIGHTS_ANNOTATION_CREATE_URL,
[],
json_encode($data)
);

$this->client->maybeThrowApiExceptions($response);

return $this->client->getJsonFromResponse($response);
}
}
Loading
Loading