diff --git a/Shoko/shoko.svg b/Shoko/shoko.svg index f63e0b22c4..87ac7aa229 100644 --- a/Shoko/shoko.svg +++ b/Shoko/shoko.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/USAS/USAS.php b/USAS/USAS.php new file mode 100644 index 0000000000..9700c35c98 --- /dev/null +++ b/USAS/USAS.php @@ -0,0 +1,96 @@ + "ISO", + "provision" => "Install", + "baseline" => "Baseline", + "site" => "Site", + "keys" => "Keys", + ]; + private const RESULTS = [ + "succeeded" => "OK", + "failed" => "Failed", + "stopped" => "Stopped", + "interrupted" => "Stopped", + ]; + + public function __construct() + { + } + + public function test() + { + $test = parent::appTest($this->url("api/status"), $this->getAttrs()); + echo $test->status; + } + + public function livestats() + { + $status = "inactive"; + $data = [ + "run_title" => "Run", + "run_value" => "-", + "vms" => "-", + "pending" => "-", + ]; + + // GET /api/status (docs/interfaces.md#the-status-api in the USAS repository). execute() returns + // null when the connection fails and never throws for an error status. + $res = parent::execute($this->url("api/status"), $this->getAttrs()); + if ($res === null || $res->getStatusCode() !== 200) { + return parent::getLiveStats($status, $data); + } + $body = json_decode($res->getBody()); + if (!is_object($body) || ($body->schema ?? null) !== 1) { + return parent::getLiveStats($status, $data); + } + + $running = $body->running ?? null; + $playbook = is_object($running) && is_string($running->playbook ?? null) ? $running->playbook : ""; + if (isset(self::PLAYBOOKS[$playbook])) { + // Heimdall asks every 5 seconds while the status is active, every 30 otherwise. + $status = "active"; + $data["run_title"] = "Now"; + $data["run_value"] = self::PLAYBOOKS[$playbook]; + } else { + $last = $body->last_run ?? null; + $result = is_object($last) && is_string($last->status ?? null) ? $last->status : ""; + $data["run_value"] = is_object($last) ? (self::RESULTS[$result] ?? "-") : "None"; + } + + $vms = $body->vms ?? null; + if (is_object($vms) && is_int($vms->running ?? null) && is_int($vms->total ?? null)) { + $data["vms"] = $vms->running . "/" . $vms->total; + } + $servers = $body->servers ?? null; + if (is_object($servers) && is_int($servers->pending ?? null)) { + $data["pending"] = (string) $servers->pending; + } + + return parent::getLiveStats($status, $data); + } + + public function url($endpoint) + { + return parent::normaliseurl($this->config->url) . $endpoint; + } + + private function getAttrs() + { + // The status token, made in USAS on the Account page. It goes only in this header, never in the URL. + return [ + "headers" => [ + "Accept" => "application/json", + "Authorization" => "Bearer " . trim($this->config->password ?? ""), + ], + ]; + } +} diff --git a/USAS/app.json b/USAS/app.json new file mode 100644 index 0000000000..5e3c98b735 --- /dev/null +++ b/USAS/app.json @@ -0,0 +1,10 @@ +{ + "appid": "a30b98c03a1facce720e0838722513881066a95f", + "name": "USAS", + "website": "https://github.com/HoneyBearTech/ubuntu-server-auto-setup", + "license": "MIT License", + "description": "USAS (Ubuntu Server Auto Setup) installs Ubuntu Server on new Proxmox VE VMs with nobody at the keyboard, loads the admin's GitHub SSH keys and applies a hardened baseline, from a web UI. The tile shows whether a run is going, how the last one ended, the cluster's running VMs and the servers still to install.", + "enhanced": true, + "tile_background": "dark", + "icon": "usas.svg" +} diff --git a/USAS/config.blade.php b/USAS/config.blade.php new file mode 100644 index 0000000000..977587e9fd --- /dev/null +++ b/USAS/config.blade.php @@ -0,0 +1,15 @@ +

{{ __('app.apps.config') }} ({{ __('app.optional') }}) @include('items.enable')

+
+
+ + {!! Form::text('config[override_url]', isset($item) ? $item->getconfig()->override_url : null, ['placeholder' => __('app.apps.override'), 'id' => 'override_url', 'class' => 'form-control']) !!} +
+
+ + {!! Form::input('password', 'config[password]', '', ['placeholder' => 'usas_st_...', 'data-config' => 'password', 'class' => 'form-control config-item']) !!} +

Make it in USAS on the Account page, under Status for dashboards. It only reads the status.

+
+
+ +
+
diff --git a/USAS/livestats.blade.php b/USAS/livestats.blade.php new file mode 100644 index 0000000000..208b03ef5f --- /dev/null +++ b/USAS/livestats.blade.php @@ -0,0 +1,14 @@ + diff --git a/USAS/usas.svg b/USAS/usas.svg new file mode 100644 index 0000000000..5275abd758 --- /dev/null +++ b/USAS/usas.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Verdaccio/verdaccio.svg b/Verdaccio/verdaccio.svg index 8a98484a4a..37b7017f1e 100644 --- a/Verdaccio/verdaccio.svg +++ b/Verdaccio/verdaccio.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file