Skip to content

Commit

Permalink
Add endpoint to run health self-test
Browse files Browse the repository at this point in the history
  • Loading branch information
ganiuszka committed May 12, 2024
1 parent ad0ec09 commit 5a043b4
Show file tree
Hide file tree
Showing 5 changed files with 527 additions and 0 deletions.
354 changes: 354 additions & 0 deletions API/Modules/SelfTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,354 @@
<?php
/*
* Bacularis - Bacula web interface
*
* Copyright (C) 2021-2024 Marcin Haba
*
* The main author of Bacularis is Marcin Haba, with contributors, whose
* full list can be found in the AUTHORS file.
*
* You may use this file and others of this release according to the
* license defined in the LICENSE file, which includes the Affero General
* Public License, v3.0 ("AGPLv3") and some additional permissions and
* terms pursuant to its AGPLv3 Section 7.
*/

namespace Bacularis\API\Modules;

use Bacularis\API\Modules\SelfTestResult;

/**
* Tools to perform health check self-test.
*
* @author Marcin Haba <[email protected]>
* @category Module
*/
class SelfTest extends APIModule
{
private function configModuleTest(): array
{
$result = [];
$misc = $this->getModule('misc');
$api_config = $this->getModule('api_config');
$json_tools = $this->getModule('json_tools');
$components = $misc->getComponents();
$section = 'Bacula configuration';

// check if Bacula config function is enabled
$test = new SelfTestResult();
$name = 'Bacula configuration feature is enabled.';
$test->setName($name);
$test->setSection($section);
$test->setType('boolean');
$function_enabled = $api_config->isJSONToolsEnabled();
$test->setResult($function_enabled);
$state = !$function_enabled ? SelfTestResult::TEST_RESULT_STATE_DISABLED : SelfTestResult::TEST_RESULT_STATE_INFO;
$test->setState($state);
$description = SelfTestResult::TEST_RESULT_DESC_OK;
if (!$function_enabled) {
$description = sprintf(
'%s. If you plan to configure Bacula using the Bacularis web interface, Bacula configuration function needs to be enabled in the API.',
SelfTestResult::TEST_RESULT_DESC_DISABLED
);
}
$test->setDescription($description);
$result[] = $test->toArray();

for ($i = 0; $i < count($components); $i++) {
$comp = $misc->getComponentFullName($components[$i]);

// check if component config is configured
$test = new SelfTestResult();
$name = sprintf('%s configuration function is configured.', $comp);
$test->setName($name);
$test->setSection($section);
$test->setType('boolean');
$result_configured = $api_config->isJSONToolConfigured($components[$i]);
$test->setResult($result_configured);
$state_configured = !$function_enabled || !$result_configured ? SelfTestResult::TEST_RESULT_STATE_DISABLED : SelfTestResult::TEST_RESULT_STATE_INFO;
$test->setState($state_configured);
$description = SelfTestResult::TEST_RESULT_DESC_OK;
if (!$function_enabled || !$result_configured) {
$description = sprintf(
'%s. If you plan to configure Bacula %s using the Bacularis web interface, Bacula %s configuration function needs to be configured in the API.',
SelfTestResult::TEST_RESULT_DESC_DISABLED,
$comp,
$comp
);
}
$test->setDescription($description);
$result[] = $test->toArray();

// check if config is readable
$test = new SelfTestResult();
$name = sprintf('%s configuration is readable.', $comp);
$test->setName($name);
$test->setSection($section);
$test->setType('boolean');
$state_read = '';
$description = '';
if ($function_enabled && $result_configured) {
$ret = $json_tools->execCommand(
$components[$i]
);
$result_read = ($ret['exitcode'] === 0);
$test->setResult($result_read);
$state_read = SelfTestResult::TEST_RESULT_STATE_INFO;
$description = SelfTestResult::TEST_RESULT_DESC_OK;
if (!$result_read) {
$state_read = SelfTestResult::TEST_RESULT_STATE_ERROR;
$description = sprintf(
'%s. Bacula %s configuration is not possible to read.',
SelfTestResult::TEST_RESULT_DESC_ERROR,
$comp
);
}
} else {
$test->setResult(true);
$state_read = SelfTestResult::TEST_RESULT_STATE_DISABLED;
$description = sprintf(
'%s. Test skipped.',
SelfTestResult::TEST_RESULT_DESC_DISABLED
);
}
$test->setState($state_read);
$test->setDescription($description);
$result[] = $test->toArray();

// check if config is writeable
$test = new SelfTestResult();
$name = sprintf('%s configuration is writeable.', $comp);
$test->setName($name);
$test->setSection($section);
$test->setType('boolean');
$state_write = '';
$description = '';
if ($function_enabled && $result_configured) {
$ret = $api_config->getJSONToolConfig(
$components[$i]
);
$result_write = is_writeable($ret['cfg']);
$test->setResult($result_write);
$state_write = SelfTestResult::TEST_RESULT_STATE_INFO;
$description = SelfTestResult::TEST_RESULT_DESC_OK;
if (!$result_write) {
$state_write = SelfTestResult::TEST_RESULT_STATE_ERROR;
$description = sprintf(
'%s. Bacula %s configuration is not possible to write.',
SelfTestResult::TEST_RESULT_DESC_ERROR,
$comp
);
}
} else {
$test->setResult(true);
$state_write = SelfTestResult::TEST_RESULT_STATE_DISABLED;
$description = sprintf(
'%s. Test skipped.',
SelfTestResult::TEST_RESULT_DESC_DISABLED
);
}
$test->setState($state_write);
$test->setDescription($description);
$result[] = $test->toArray();

}
return $result;
}

private function bconsoleTest(): array
{
$result = [];
$bconsole = $this->getModule('bconsole');
$api_config = $this->getModule('api_config');
$config = $api_config->getConfig('bconsole');
$section = 'Bconsole';

// check if Bacula console is enabled
$test = new SelfTestResult();
$name = 'Bconsole feature is enabled.';
$test->setName($name);
$test->setSection($section);
$test->setType('boolean');
$result_enabled = $config['enabled'] === '1';
$test->setResult($result_enabled);
$state_enabled = $result_enabled ? SelfTestResult::TEST_RESULT_STATE_INFO : SelfTestResult::TEST_RESULT_STATE_DISABLED;
$test->setState($state_enabled);
$description = SelfTestResult::TEST_RESULT_DESC_OK;
if (!$result_enabled) {
$description = SelfTestResult::TEST_RESULT_DESC_DISABLED;
}
$test->setDescription($description);
$result[] = $test->toArray();

// check if Bacula console is accessible
$test = new SelfTestResult();
$name = 'Bconsole is accessible.';
$test->setName($name);
$test->setSection($section);
$test->setType('boolean');
$sudo = [
'use_sudo' => $config['use_sudo'],
'user' => $config['sudo_user'] ?? '',
'group' => $config['sudo_group'] ?? ''
];
$ret = $bconsole->testBconsoleCommand(['version'], $config['bin_path'], $config['cfg_path'], $sudo);
$result_accessible = ($ret->exitcode === 0);
$test->setResult($result_accessible);
if ($result_enabled) {
if ($result_accessible) {
$state_accessible = SelfTestResult::TEST_RESULT_STATE_INFO;
$description = SelfTestResult::TEST_RESULT_DESC_OK;
} else {
$state_accessible = SelfTestResult::TEST_RESULT_STATE_ERROR;
$description = sprintf(
'%s. Bconsole is enabled but not accessible.',
SelfTestResult::TEST_RESULT_DESC_ERROR
);
}
} else {
$state_accessible = SelfTestResult::TEST_RESULT_STATE_DISABLED;
$description = sprintf(
'%s. Test skipped.',
SelfTestResult::TEST_RESULT_DESC_DISABLED
);
}
$test->setState($state_accessible);
$test->setDescription($description);
$result[] = $test->toArray();

return $result;
}

private function catalogTest(): array
{
$result = [];
$db = $this->getModule('db');
$api_config = $this->getModule('api_config');
$config = $api_config->getConfig('db');
$section = 'Catalog';

// check if Catalog is enabled
$test = new SelfTestResult();
$name = 'Catalog feature is enabled.';
$test->setName($name);
$test->setSection($section);
$test->setType('boolean');
$result_enabled = $config['enabled'] === '1';
$test->setResult($result_enabled);
$state_enabled = SelfTestResult::TEST_RESULT_STATE_INFO;
$test->setState($state_enabled);
if ($result_enabled) {
$description = SelfTestResult::TEST_RESULT_DESC_OK;
} else {
$description = SelfTestResult::TEST_RESULT_DESC_DISABLED;
}
$test->setDescription($description);
$result[] = $test->toArray();

// check if Catalog is accessible
$test = new SelfTestResult();
$name = 'Catalog feature is accessible.';
$test->setName($name);
$test->setSection($section);
$test->setType('boolean');
$result_accessible = false;
$state_accessible = $description = '';
if ($result_enabled) {
try {
$result_accessible = $db->testCatalog();
} catch (BCatalogException $e) {
$result_accessible = false;
}
if ($result_accessible) {
$state_accessible = SelfTestResult::TEST_RESULT_STATE_INFO;
$description = SelfTestResult::TEST_RESULT_DESC_OK;
} else {
$state_accessible = SelfTestResult::TEST_RESULT_STATE_ERROR;
$description = sprintf(
'%s. Catalog database is not accessible',
SelfTestResult::TEST_RESULT_DESC_ERROR
);
}
} else {
$state_accessible = SelfTestResult::TEST_RESULT_STATE_DISABLED;
$description = sprintf(
'%s. Test skipped',
SelfTestResult::TEST_RESULT_DESC_DISABLED
);
}
$test->setResult($result_accessible);
$test->setState($state_accessible);
$test->setDescription($description);
$result[] = $test->toArray();

return $result;
}

private function actionsTest(): array
{
$result = [];
$bconsole = $this->getModule('bconsole');
$api_config = $this->getModule('api_config');
$section = 'Actions';

// Check if actions are enabled
$test = new SelfTestResult();
$name = 'Actions feature is enabled.';
$test->setName($name);
$test->setSection($section);
$test->setType('boolean');
$result_enabled = $api_config->isActionsEnabled();
$test->setResult($result_enabled);
if ($result_enabled) {
$state_enabled = SelfTestResult::TEST_RESULT_STATE_INFO;
$description = SelfTestResult::TEST_RESULT_DESC_OK;
} else {
$state_enabled = SelfTestResult::TEST_RESULT_STATE_DISABLED;
$description = SelfTestResult::TEST_RESULT_DESC_DISABLED;
}
$test->setState($state_enabled);
$test->setDescription($description);
$result[] = $test->toArray();

return $result;
}

private function softwareManagementTest(): array
{
$result = [];
$bconsole = $this->getModule('bconsole');
$api_config = $this->getModule('api_config');
$section = 'Software management';

// Check if software management is enabled
$test = new SelfTestResult();
$name = 'Software management feature is enabled.';
$test->setName($name);
$test->setSection($section);
$test->setType('boolean');
$result_enabled = $api_config->isSoftwareManagementEnabled();
$test->setResult($result_enabled);
if ($result_enabled) {
$state_enabled = SelfTestResult::TEST_RESULT_STATE_INFO;
$description = SelfTestResult::TEST_RESULT_DESC_OK;
} else {
$state_enabled = SelfTestResult::TEST_RESULT_STATE_DISABLED;
$description = SelfTestResult::TEST_RESULT_DESC_DISABLED;
}
$test->setState($state_enabled);
$test->setDescription($description);
$result[] = $test->toArray();

return $result;
}

public function getTestResults(): array
{
$db = $this->catalogTest();
$config = $this->configModuleTest();
$bconsole = $this->bconsoleTest();
$actions = $this->actionsTest();
$software_mgmt = $this->softwareManagementTest();
return array_merge($db, $bconsole, $config, $actions, $software_mgmt);
}
}
Loading

0 comments on commit 5a043b4

Please sign in to comment.