Add feature to specify a custom endpoint name for a host

- Render Endpoint and Zone with a different name per host
- Add custom variable `_director_custom_endpoint_name` to a host with that name
- Update `command_endpoint` behavior in services to use custom var or hostname
- Includes a feature flag that needs to be enabled
This commit is contained in:
Markus Frosch 2021-10-18 10:32:34 +02:00 committed by Thomas Gelf
parent 3d528dc3af
commit 8237d84cdb
11 changed files with 98 additions and 14 deletions

View File

@ -97,6 +97,17 @@ class IcingaHostForm extends DirectorObjectForm
$this->addHidden('command_endpoint_id', null);
$this->setSentValue('command_endpoint_id', null);
$settings = $this->object->getConnection()->settings();
if ($settings->get('feature_custom_endpoint') === 'y' && ! $this->isTemplate()) {
$this->addElement('text', 'custom_endpoint_name', [
'label' => $this->translate('Custom Endpoint Name'),
'description' => $this->translate(
'Use a different name for the generated endpoint object than the host name'
. ' and add a custom variable to allow services setting the correct command endpoint.'
),
]);
}
} else {
if ($this->isTemplate()) {
$this->addElement('select', 'command_endpoint_id', [
@ -123,6 +134,7 @@ class IcingaHostForm extends DirectorObjectForm
'master_should_connect',
'accept_config',
'command_endpoint_id',
'custom_endpoint_name',
'api_key',
];
$this->addDisplayGroup($elements, 'clustering', [

View File

@ -105,6 +105,18 @@ class SettingsForm extends DirectorForm
));
}
$this->addBoolean('feature_custom_endpoint', [
'label' => $this->translate('Feature: Custom Endpoint Name'),
'description' => $this->translate(
'Enabled the feature for custom endpoint names,'
. ' where you can choose a different name for the generated endpoint object.'
. ' This uses some Icinga config snippets and a special custom variable.'
. ' Please do NOT enable this, unless you really need divergent endpoint names!'
),
'value' => $settings->getStoredValue('feature_custom_endpoint')
]);
$this->addElement('select', 'config_format', array(
'label' => $this->translate('Configuration format'),
'multiOptions' => $this->eventuallyConfiguredEnum(

View File

@ -126,11 +126,6 @@ class AgentWizard
$this->ticket = $ticket;
}
protected function getCertName()
{
return $this->host->getObjectName();
}
protected function loadPowershellModule()
{
return $this->getContribFile('windows-agent-installer/Icinga2Agent.psm1');
@ -142,7 +137,7 @@ class AgentWizard
. "\n\n"
. 'exit Icinga2AgentModule `' . "\n "
. $this->renderPowershellParameters([
'AgentName' => $this->getCertName(),
'AgentName' => $this->host->getEndpointName(),
'Ticket' => $this->getTicket(),
'ParentZone' => $this->getParentZone()->getObjectName(),
'ParentEndpoints' => array_keys($this->getParentEndpoints()),
@ -272,7 +267,7 @@ class AgentWizard
}
return $this->replaceBashTemplate($script, [
'ICINGA2_NODENAME' => $this->getCertName(),
'ICINGA2_NODENAME' => $this->host->getEndpointName(),
'ICINGA2_CA_TICKET' => $this->getTicket(),
'ICINGA2_PARENT_ZONE' => $this->getParentZone()->getObjectName(),
'ICINGA2_PARENT_ENDPOINTS' => $endpoints,

View File

@ -9,6 +9,7 @@ use Icinga\Module\Director\Db;
use Icinga\Module\Director\DirectorObject\Automation\ExportInterface;
use Icinga\Module\Director\Exception\DuplicateKeyException;
use Icinga\Module\Director\IcingaConfig\IcingaConfig;
use Icinga\Module\Director\IcingaConfig\IcingaConfigHelper as c;
use Icinga\Module\Director\IcingaConfig\IcingaLegacyConfigHelper as c1;
use Icinga\Module\Director\Objects\Extension\FlappingSupport;
use InvalidArgumentException;
@ -55,6 +56,7 @@ class IcingaHost extends IcingaObject implements ExportInterface
'has_agent' => null,
'master_should_connect' => null,
'accept_config' => null,
'custom_endpoint_name' => null,
'api_key' => null,
'template_choice_id' => null,
);
@ -215,7 +217,8 @@ class IcingaHost extends IcingaObject implements ExportInterface
return;
}
$name = $this->object_name;
$name = $this->getEndpointName();
if (IcingaEndpoint::exists($name, $this->connection)) {
return;
}
@ -249,6 +252,37 @@ class IcingaHost extends IcingaObject implements ExportInterface
$config->configFile($pre . 'agent_zones')->addObject($zone);
}
protected function renderCustom_endpoint_name()
{
// When feature flag feature_custom_endpoint is enabled, render custom var
if ($this->connection->settings()->get('feature_custom_endpoint') === 'y') {
return c::renderKeyValue(
'vars._director_custom_endpoint_name',
c::renderPhpValue($this->get('custom_endpoint_name'))
);
}
return '';
}
/**
* Returns the hostname or custom endpoint name of the Icinga agent
*
* @return string
*/
public function getEndpointName()
{
$name = $this->getObjectName();
if ($this->connection->settings()->get('feature_custom_endpoint') === 'y') {
if (($customName = $this->get('custom_endpoint_name')) !== null) {
$name = $customName;
}
}
return $name;
}
public function getAgentListenPort()
{
$conn = $this->connection;

View File

@ -571,7 +571,22 @@ class IcingaService extends IcingaObject implements ExportInterface
}
if ($this->get('use_agent') === 'y') {
return $output . c::renderKeyValue('command_endpoint', 'host_name');
// When feature flag feature_custom_endpoint is enabled, render additional code
if ($this->connection->settings()->get('feature_custom_endpoint') === 'y') {
return $output . "
// Set command_endpoint dynamically with Director
if (!host) {
var host = get_host(host_name)
}
if (host.vars._director_custom_endpoint_name) {
command_endpoint = host.vars._director_custom_endpoint_name
} else {
command_endpoint = host_name
}
";
} else {
return $output . c::renderKeyValue('command_endpoint', 'host_name');
}
} elseif ($this->get('use_agent') === 'n') {
return $output . c::renderKeyValue('command_endpoint', c::renderPhpValue(null));
} else {

View File

@ -26,6 +26,7 @@ class Settings
'self-service/resolve_parent_host' => '0',
'self-service/global_zones' => ['director-global'],
'ignore_bug7530' => 'n',
'feature_custom_endpoint' => 'n',
// 'experimental_features' => null, // 'allow'
// 'master_zone' => null,
];

View File

@ -223,10 +223,9 @@ class SelfService
)));
$cc->addTitle('Agent deployment instructions');
$certname = $host->getObjectName();
try {
$ticket = $this->api->getTicket($host->getObjectName());
$ticket = $this->api->getTicket($host->getEndpointName());
$wizard = new AgentWizard($host);
$wizard->setTicket($ticket);
} catch (Exception $e) {
@ -278,7 +277,7 @@ class SelfService
public function handleLegacyAgentDownloads($os)
{
$wizard = new AgentWizard($this->host);
$wizard->setTicket($this->api->getTicket($this->host->getObjectName()));
$wizard->setTicket($this->api->getTicket($this->host->getEndpointName()));
switch ($os) {
case 'windows-kickstart':

View File

@ -0,0 +1,6 @@
ALTER TABLE icinga_host ADD COLUMN custom_endpoint_name VARCHAR(255) DEFAULT NULL AFTER accept_config;
ALTER TABLE branched_icinga_host ADD COLUMN custom_endpoint_name VARCHAR(255) DEFAULT NULL AFTER accept_config;
INSERT INTO director_schema_migration
(schema_version, migration_time)
VALUES ('176', NOW());

View File

@ -555,6 +555,7 @@ CREATE TABLE icinga_host (
has_agent ENUM('y', 'n') DEFAULT NULL,
master_should_connect ENUM('y', 'n') DEFAULT NULL,
accept_config ENUM('y', 'n') DEFAULT NULL,
custom_endpoint_name VARCHAR(255) DEFAULT NULL,
api_key VARCHAR(40) DEFAULT NULL,
template_choice_id INT(10) UNSIGNED DEFAULT NULL,
PRIMARY KEY (id),
@ -1977,6 +1978,7 @@ CREATE TABLE branched_icinga_host (
has_agent ENUM('y', 'n') DEFAULT NULL,
master_should_connect ENUM('y', 'n') DEFAULT NULL,
accept_config ENUM('y', 'n') DEFAULT NULL,
custom_endpoint_name VARCHAR(255) DEFAULT NULL,
api_key VARCHAR(40) DEFAULT NULL,
imports TEXT DEFAULT NULL,
@ -2393,4 +2395,4 @@ CREATE TABLE branched_icinga_dependency (
INSERT INTO director_schema_migration
(schema_version, migration_time)
VALUES (175, NOW());
VALUES (176, NOW());

View File

@ -0,0 +1,6 @@
ALTER TABLE icinga_host ADD COLUMN custom_endpoint_name character varying(255) DEFAULT NULL;
ALTER TABLE branched_icinga_host ADD COLUMN custom_endpoint_name character varying(255) DEFAULT NULL;
INSERT INTO director_schema_migration
(schema_version, migration_time)
VALUES ('176', NOW());

View File

@ -690,6 +690,7 @@ CREATE TABLE icinga_host (
has_agent enum_boolean DEFAULT NULL,
master_should_connect enum_boolean DEFAULT NULL,
accept_config enum_boolean DEFAULT NULL,
custom_endpoint_name character varying(255) DEFAULT NULL,
api_key character varying(40) DEFAULT NULL,
template_choice_id int DEFAULT NULL,
PRIMARY KEY (id),
@ -2298,6 +2299,7 @@ CREATE TABLE branched_icinga_host (
has_agent enum_boolean DEFAULT NULL,
master_should_connect enum_boolean DEFAULT NULL,
accept_config enum_boolean DEFAULT NULL,
custom_endpoint_name character varying(255) DEFAULT NULL,
api_key character varying(40) DEFAULT NULL,
-- template_choice character varying(255) DEFAULT NULL, -- TODO: Forbid them!
@ -2739,4 +2741,4 @@ CREATE INDEX branched_dependency_search_object_name ON branched_icinga_dependenc
INSERT INTO director_schema_migration
(schema_version, migration_time)
VALUES (175, NOW());
VALUES (176, NOW());