Add Director Self-Service setup wizard integration

This commit is contained in:
Lord Hepipud 2019-11-02 17:42:39 +01:00
parent 0a9f24f663
commit 8a3c8c4102
7 changed files with 332 additions and 12 deletions

View file

@ -15,7 +15,7 @@ function Get-IcingaDirectorSelfServiceConfig()
$ProgressPreference = "SilentlyContinue"; $ProgressPreference = "SilentlyContinue";
$EndpointUrl = [string]::Format('{0}/self-service/powershell-parameters?key={1}', $DirectorUrl, $ApiKey); $EndpointUrl = Join-WebPath -Path $DirectorUrl -ChildPath ([string]::Format('/self-service/powershell-parameters?key={0}', $ApiKey));
$response = Invoke-WebRequest -Uri $EndpointUrl -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST'; $response = Invoke-WebRequest -Uri $EndpointUrl -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST';

View file

@ -0,0 +1,29 @@
function Get-IcingaDirectorSelfServiceTicket()
{
param(
$DirectorUrl,
$ApiKey = $null
);
if ([string]::IsNullOrEmpty($DirectorUrl)) {
Write-Host 'Unable to fetch host ticket. No Director url has been specified';
return;
}
if ([string]::IsNullOrEmpty($ApiKey)) {
Write-Host 'Unable to fetch host ticket. No API key has been specified';
return;
}
[string]$url = Join-WebPath -Path $DirectorUrl -ChildPath ([string]::Format('/self-service/ticket?key={0}', $ApiKey));
$response = Invoke-WebRequest -Uri $url -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST';
if ($response.StatusCode -ne 200) {
throw $response.Content;
}
$JsonContent = ConvertFrom-Json -InputObject $response.Content;
return $JsonContent;
}

View file

@ -20,7 +20,7 @@ function Register-IcingaDirectorSelfServiceHost()
$ProgressPreference = "SilentlyContinue"; $ProgressPreference = "SilentlyContinue";
$EndpointUrl = [string]::Format('{0}/self-service/register-host?name={1}&key={2}', $DirectorUrl, $Hostname, $ApiKey); $EndpointUrl = Join-WebPath -Path $DirectorUrl -ChildPath ([string]::Format('/self-service/register-host?name={0}&key={1}', $Hostname, $ApiKey));
$response = Invoke-WebRequest -Uri $EndpointUrl -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST'; $response = Invoke-WebRequest -Uri $EndpointUrl -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST';
@ -31,8 +31,14 @@ function Register-IcingaDirectorSelfServiceHost()
$JsonContent = ConvertFrom-Json -InputObject $response.Content; $JsonContent = ConvertFrom-Json -InputObject $response.Content;
if (Test-PSCustomObjectMember -PSObject $JsonContent -Name 'error') { if (Test-PSCustomObjectMember -PSObject $JsonContent -Name 'error') {
if ($JsonContent.error -like '*already been registered*') {
return $null;
}
throw 'Icinga Director Self-Service has thrown an error: ' + $JsonContent.error; throw 'Icinga Director Self-Service has thrown an error: ' + $JsonContent.error;
} }
Set-IcingaPowerShellConfig -Path 'IcingaDirector.SelfService.ApiKey' -Value $JsonContent;
return $JsonContent; return $JsonContent;
} }

View file

@ -6,6 +6,11 @@ function Install-IcingaFrameworkService()
[SecureString]$Password [SecureString]$Password
); );
if ([string]::IsNullOrEmpty($Path)) {
Write-Host 'No path specified for Framework service. Service will not be installed';
return;
}
if ((Test-Path $Path) -eq $FALSE) { if ((Test-Path $Path) -eq $FALSE) {
throw 'Please specify the path directly to the service binary'; throw 'Please specify the path directly to the service binary';
} }

View file

@ -0,0 +1,64 @@
function Convert-IcingaDirectorSelfServiceArguments()
{
param(
$JsonInput
);
if ($null -eq $JsonInput) {
return @{};
}
[hashtable]$DirectorArguments = @{
PackageSource = $JsonInput.download_url;
AgentVersion = $JsonInput.agent_version;
CAPort = $JsonInput.agent_listen_port;
AllowVersionChanges = $JsonInput.allow_updates;
GlobalZones = $JsonInput.global_zones;
ParentZone = $JsonInput.parent_zone;
CAEndpoint = $JsonInput.ca_server;
Endpoints = $JsonInput.parent_endpoints;
AddFirewallRule = $JsonInput.agent_add_firewall_rule;
AcceptConnections = $JsonInput.agent_add_firewall_rule;
#ServiceUser = $JsonInput.service_user; # This is yet missing within the Icinga Director API
ServiceUser = 'NT Authority\NetworkService';
UpdateAgent = $TRUE;
AddDirectorGlobal = $FALSE;
AddGlobalTemplates = $FALSE;
RunInstaller = $TRUE;
};
if ($JsonInput.transform_hostname -eq 1) {
$DirectorArguments.Add(
'LowerCase', $TRUE
);
}
if ($JsonInput.transform_hostname -eq 2) {
$DirectorArguments.Add(
'UpperCase', $TRUE
);
}
if ($JsonInput.fetch_agent_fqdn) {
$DirectorArguments.Add(
'AutoUseFQDN', $TRUE
);
} elseif ($JsonInput.fetch_agent_name) {
$DirectorArguments.Add(
'AutoUseHostname', $TRUE
);
}
$NetworkDefault = '';
foreach ($Endpoint in $JsonInput.parent_endpoints) {
$NetworkDefault += [string]::Format('[{0}]:{1},', $Endpoint, $JsonInput.agent_listen_port);
}
if ([string]::IsNullOrEmpty($NetworkDefault) -eq $FALSE) {
$NetworkDefault = $NetworkDefault.Substring(0, $NetworkDefault.Length - 1);
$DirectorArguments.Add(
'EndpointConnections', $NetworkDefault
);
}
return $DirectorArguments;
}

View file

@ -0,0 +1,127 @@
function Start-IcingaAgentDirectorWizard()
{
param(
[string]$DirectorUrl,
[string]$SelfServiceAPIKey,
$OverrideDirectorVars = $null,
$InstallFrameworkService = $null,
$ServiceDirectory = $null,
$ServiceBin = $null,
[bool]$RunInstaller = $FALSE
);
if ([string]::IsNullOrEmpty($DirectorUrl)) {
$DirectorUrl = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the Url pointing to your Icinga Director' -Default 'v').answer;
}
[bool]$HostKnown = $FALSE;
[string]$TemplateKey = $SelfServiceAPIKey;
if ($null -eq $OverrideDirectorVars) {
if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to manually override arguments provided by the Director API?' -Default 'n').result -eq 0) {
$OverrideDirectorVars = $TRUE;
} else{
$OverrideDirectorVars = $FALSE;
}
}
$SelfServiceAPIKey = Get-IcingaPowerShellConfig -Path 'IcingaDirector.SelfService.ApiKey';
if ([string]::IsNullOrEmpty($SelfServiceAPIKey)) {
$LegacyTokenPath = Join-Path -Path Get-IcingaAgentConfigDirectory -ChildPath 'icingadirector.token';
if (Test-Path $LegacyTokenPath) {
$SelfServiceAPIKey = Get-Content -Path $LegacyTokenPath;
Set-IcingaPowerShellConfig -Path 'IcingaDirector.SelfService.ApiKey' -Value $SelfServiceAPIKey;
}
}
if ([string]::IsNullOrEmpty($SelfServiceAPIKey)) {
$SelfServiceAPIKey = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter your Self-Service API key' -Default 'v').answer;
} else {
$HostKnown = $TRUE;
}
$Arguments = Get-IcingaDirectorSelfServiceConfig -DirectorUrl $DirectorUrl -ApiKey $SelfServiceAPIKey;
$Arguments = Convert-IcingaDirectorSelfServiceArguments -JsonInput $Arguments;
if ($OverrideDirectorVars -eq $TRUE) {
$NewArguments = Start-IcingaDirectorAPIArgumentOverride -Arguments $Arguments;
$Arguments = $NewArguments;
}
if ($HostKnown -eq $FALSE) {
Write-Host $SelfServiceAPIKey;
Write-Host (Get-IcingaHostname @Arguments);
Write-Host $DirectorUrl;
$SelfServiceAPIKey = Register-IcingaDirectorSelfServiceHost -DirectorUrl $DirectorUrl -ApiKey $SelfServiceAPIKey -Hostname (Get-IcingaHostname @Arguments);
# Host is already registered
if ($null -eq $SelfServiceAPIKey) {
Write-Host 'The wizard is unable to complete as this host is already registered but the local API key is not stored within the config'
return;
}
$Arguments = Get-IcingaDirectorSelfServiceConfig -DirectorUrl $DirectorUrl -ApiKey $SelfServiceAPIKey;
$Arguments = Convert-IcingaDirectorSelfServiceArguments -JsonInput $Arguments;
if ($OverrideDirectorVars -eq $TRUE) {
$NewArguments = Start-IcingaDirectorAPIArgumentOverride -Arguments $Arguments;
$Arguments = $NewArguments;
}
}
$Arguments.Add(
'UseDirectorSelfService', $TRUE
);
$Arguments.Add(
'OverrideDirectorVars', $FALSE
);
$Arguments.Add(
'DirectorUrl', $DirectorUrl
);
$Arguments.Add(
'SelfServiceAPIKey', $TemplateKey
);
$Arguments.Add(
'SkipDirectorQuestion', $TRUE
);
$Arguments.Add(
'InstallFrameworkService', $InstallFrameworkService
);
$Arguments.Add(
'ServiceDirectory', $ServiceDirectory
);
$Arguments.Add(
'ServiceBin', $ServiceBin
);
$Arguments.Add(
'ProvidedArgs', $Arguments
);
if ($RunInstaller) {
Start-IcingaAgentInstallWizard @Arguments;
return;
}
if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'The Director wizard is complete. Do you want to start the installation now?' -Default 'y').result -eq 1) {
Start-IcingaAgentInstallWizard @Arguments;
}
}
function Start-IcingaDirectorAPIArgumentOverride()
{
param(
$Arguments
);
$NewArguments = @{};
Write-Host 'Please follow the wizard and manually override all entries you intend to';
Write-Host '====';
foreach ($entry in $Arguments.Keys) {
$value = (Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Please enter the new value for the argument "{0}"', $entry)) -Default 'v' -DefaultInput $Arguments[$entry]).answer;
$NewArguments.Add($entry, $value);
}
return $NewArguments;
}
Export-ModuleMember -Function @( 'Start-IcingaAgentDirectorWizard' );

View file

@ -28,12 +28,41 @@ function Start-IcingaAgentInstallWizard()
$InstallFrameworkService = $null, $InstallFrameworkService = $null,
$FrameworkServiceUrl = $null, $FrameworkServiceUrl = $null,
$ServiceDirectory = $null, $ServiceDirectory = $null,
$ServiceBin = $null $ServiceBin = $null,
$UseDirectorSelfService = $null,
[bool]$SkipDirectorQuestion = $FALSE,
[string]$DirectorUrl,
[string]$SelfServiceAPIKey,
$OverrideDirectorVars = $null,
[hashtable]$ProvidedArgs = @{}
); );
[array]$InstallerArguments = @(); [array]$InstallerArguments = @();
[array]$GlobalZoneConfig = @(); [array]$GlobalZoneConfig = @();
if ($SkipDirectorQuestion -eq $FALSE) {
if ($null -eq $UseDirectorSelfService) {
if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to use the Icinga Director Self-Service API?' -Default 'y').result -eq 1) {
$UseDirectorSelfService = $TRUE;
} else {
$UseDirectorSelfService = $FALSE;
$InstallerArguments += '-UseDirectorSelfService 0';
}
}
if ($UseDirectorSelfService) {
$InstallerArguments += '-UseDirectorSelfService 1';
Start-IcingaAgentDirectorWizard `
-DirectorUrl $DirectorUrl `
-SelfServiceAPIKey $SelfServiceAPIKey `
-OverrideDirectorVars $OverrideDirectorVars `
-InstallFrameworkService $InstallFrameworkService `
-ServiceDirectory $ServiceDirectory `
-ServiceBin $ServiceBin `
-RunInstaller $RunInstaller;
return;
}
}
if ([string]::IsNullOrEmpty($Hostname) -And $AutoUseFQDN -eq $FALSE -And $AutoUseHostname -eq $FALSE) { if ([string]::IsNullOrEmpty($Hostname) -And $AutoUseFQDN -eq $FALSE -And $AutoUseHostname -eq $FALSE) {
if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to manually specify a hostname?' -Default 'n').result -eq 1) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to manually specify a hostname?' -Default 'n').result -eq 1) {
if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to automatically fetch the hostname with its FQDN?' -Default 'y').result -eq 1) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to automatically fetch the hostname with its FQDN?' -Default 'y').result -eq 1) {
@ -261,27 +290,87 @@ function Start-IcingaAgentInstallWizard()
$InstallerArguments += [string]::Format("-ServiceDirectory '{0}'", $result.ServiceDirectory); $InstallerArguments += [string]::Format("-ServiceDirectory '{0}'", $result.ServiceDirectory);
$InstallerArguments += [string]::Format("-ServiceBin '{0}'", $result.ServiceBin); $InstallerArguments += [string]::Format("-ServiceBin '{0}'", $result.ServiceBin);
$ServiceBin = $result.ServiceBin; $ServiceBin = $result.ServiceBin;
} else {
$InstallerArguments += "-InstallFrameworkService 0";
} }
} elseif ($InstallFrameworkService -eq $TRUE) { } elseif ($InstallFrameworkService -eq $TRUE) {
$result = Get-IcingaFrameworkServiceBinary -FrameworkServiceUrl $FrameworkServiceUrl -ServiceDirectory $ServiceDirectory; $result = Get-IcingaFrameworkServiceBinary -FrameworkServiceUrl $FrameworkServiceUrl -ServiceDirectory $ServiceDirectory;
$ServiceBin = $result.ServiceBin; $ServiceBin = $result.ServiceBin;
} else {
$InstallerArguments += "-InstallFrameworkService 0";
} }
if ($InstallerArguments.Count -ne 0) { if ($InstallerArguments.Count -ne 0) {
$InstallerArguments += "-RunInstaller"; $InstallerArguments += "-RunInstaller";
Write-Host 'The wizard is complete. These are the configured settings:'; Write-Host 'The wizard is complete. These are the configured settings:';
foreach ($entry in $ProvidedArgs.Keys) {
if ($entry -eq 'ProvidedArgs' -Or $entry -eq 'SkipDirectorQuestion') {
continue;
}
[bool]$SkipArgument = $FALSE;
if ($OverrideDirectorVars -eq $FALSE) {
switch ($entry) {
'InstallFrameworkService' { break; };
'FrameworkServiceUrl' { break; };
'ServiceDirectory' { break; };
'ServiceBin' { break; };
'UseDirectorSelfService' { break; };
'DirectorUrl' { break; };
'SelfServiceAPIKey' { break; };
'OverrideDirectorVars' { break; };
Default {
$SkipArgument = $TRUE;
break;
}
}
if ($SkipArgument) {
continue;
}
}
[bool]$KnownArgument = $FALSE;
foreach ($item in $InstallerArguments) {
if ($item -like "-$entry *" -Or $item -eq "-$entry") {
$KnownArgument = $TRUE;
break;
}
}
if ($KnownArgument) {
continue;
}
$Value = $ProvidedArgs[$entry];
if ($Value -is [System.Object]) {
$Value = [string]::Join(',', $Value);
}
if ($OverrideDirectorVars -eq $FALSE) {
#$ClearedArguments += [string]::Format("-{0} '{1}'", $entry, $Value);
#continue;
}
$InstallerArguments += [string]::Format("-{0} '{1}'", $entry, $Value);
}
Write-Host ($InstallerArguments | Out-String); Write-Host ($InstallerArguments | Out-String);
if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Is this configuration correct?' -Default 'y').result -eq 1) { if (-Not $RunInstaller) {
if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to run the installer now? (Otherwise only the configration command will be printed)' -Default 'y').result -eq 1) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Is this configuration correct?' -Default 'y').result -eq 1) {
Write-Host 'To execute your Icinga Agent installation based on your answers again on this or another machine, simply run this command:' if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to run the installer now? (Otherwise only the configration command will be printed)' -Default 'y').result -eq 1) {
Write-Host 'To execute your Icinga Agent installation based on your answers again on this or another machine, simply run this command:'
$RunInstaller = $TRUE; $RunInstaller = $TRUE;
} else {
Write-Host 'To execute your Icinga Agent installation based on your answers, simply run this command:'
}
} else { } else {
Write-Host 'To execute your Icinga Agent installation based on your answers, simply run this command:' Write-Host 'Please run the wizard again to modify your answers or modify the command below:'
} }
} else {
Write-Host 'Please run the wizard again to modify your answers or modify the command below:'
} }
Get-IcingaAgentInstallCommand -InstallerArguments $InstallerArguments -PrintConsole; Get-IcingaAgentInstallCommand -InstallerArguments $InstallerArguments -PrintConsole;
} }
@ -289,8 +378,8 @@ function Start-IcingaAgentInstallWizard()
if ($RunInstaller) { if ($RunInstaller) {
if ((Install-IcingaAgent -Version $AgentVersion -Source $PackageSource -AllowUpdates $AllowVersionChanges) -Or $Reconfigure) { if ((Install-IcingaAgent -Version $AgentVersion -Source $PackageSource -AllowUpdates $AllowVersionChanges) -Or $Reconfigure) {
Move-IcingaAgentDefaultConfig; Move-IcingaAgentDefaultConfig;
Set-IcingaAgentServiceUser -User $ServiceUser -Password $ServicePass; Set-IcingaAgentServiceUser -User $ServiceUser -Password $ServicePass | Out-Null;
Set-IcingaAgentServicePermission; Set-IcingaAgentServicePermission | Out-Null;
Set-IcingaAcl "$Env:ProgramData\icinga2\etc"; Set-IcingaAcl "$Env:ProgramData\icinga2\etc";
Set-IcingaAcl "$Env:ProgramData\icinga2\var"; Set-IcingaAcl "$Env:ProgramData\icinga2\var";
Set-IcingaAcl (Get-IcingaCacheDir); Set-IcingaAcl (Get-IcingaCacheDir);