2017-07-06 15:11:57 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Icinga\Module\Director\Controllers;
|
|
|
|
|
2017-07-06 17:11:15 +02:00
|
|
|
use Exception;
|
|
|
|
use Icinga\Exception\NotFoundError;
|
|
|
|
use Icinga\Exception\ProgrammingError;
|
2017-07-06 15:11:57 +02:00
|
|
|
use Icinga\Module\Director\Forms\IcingaHostSelfServiceForm;
|
2017-07-06 17:11:15 +02:00
|
|
|
use Icinga\Module\Director\Objects\IcingaHost;
|
|
|
|
use Icinga\Module\Director\Objects\IcingaZone;
|
|
|
|
use Icinga\Module\Director\Settings;
|
2017-07-06 15:11:57 +02:00
|
|
|
use Icinga\Module\Director\Web\Controller\ActionController;
|
|
|
|
use ipl\Html\Html;
|
|
|
|
|
|
|
|
class SelfServiceController extends ActionController
|
|
|
|
{
|
|
|
|
protected $isApified = true;
|
|
|
|
|
|
|
|
protected $requiresAuthentication = false;
|
|
|
|
|
|
|
|
protected function assertApiPermission()
|
|
|
|
{
|
|
|
|
// no permission required, we'll check the API key
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function checkDirectorPermissions()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-07-06 17:55:17 +02:00
|
|
|
public function apiVersionAction()
|
|
|
|
{
|
|
|
|
$this->sendPowerShellResponse('1.4.0');
|
|
|
|
}
|
|
|
|
|
2017-07-06 15:11:57 +02:00
|
|
|
public function registerHostAction()
|
|
|
|
{
|
2017-07-06 17:11:15 +02:00
|
|
|
$request = $this->getRequest();
|
2017-07-06 15:11:57 +02:00
|
|
|
$form = IcingaHostSelfServiceForm::create($this->db());
|
2017-07-06 17:11:15 +02:00
|
|
|
$form->setApiRequest($request->isApiRequest());
|
|
|
|
try {
|
|
|
|
if ($key = $this->params->get('key')) {
|
|
|
|
$form->loadTemplateWithApiKey($key);
|
|
|
|
}
|
|
|
|
} catch (Exception $e) {
|
|
|
|
$this->sendPowerShellError($e->getMessage(), 404);
|
|
|
|
return;
|
2017-07-06 15:11:57 +02:00
|
|
|
}
|
|
|
|
if ($name = $this->params->get('name')) {
|
|
|
|
$form->setHostName($name);
|
|
|
|
}
|
|
|
|
|
2017-07-06 17:11:15 +02:00
|
|
|
if ($request->isApiRequest()) {
|
|
|
|
$data = json_decode($request->getRawBody());
|
|
|
|
$request->setPost((array) $data);
|
|
|
|
$form->handleRequest();
|
2017-07-06 15:11:57 +02:00
|
|
|
if ($newKey = $form->getHostApiKey()) {
|
2017-07-06 17:11:15 +02:00
|
|
|
$this->sendPowerShellResponse($newKey);
|
2017-07-06 15:11:57 +02:00
|
|
|
} else {
|
|
|
|
$error = implode('; ', $form->getErrorMessages());
|
|
|
|
if ($error === '') {
|
|
|
|
foreach ($form->getErrors() as $elName => $errors) {
|
|
|
|
if (in_array('isEmpty', $errors)) {
|
2017-07-06 17:11:15 +02:00
|
|
|
$this->sendPowerShellError(
|
|
|
|
sprintf("%s is required", $elName),
|
|
|
|
400
|
2017-07-06 15:11:57 +02:00
|
|
|
);
|
|
|
|
return;
|
|
|
|
} else {
|
2017-07-06 17:11:15 +02:00
|
|
|
$this->sendPowerShellError('An unknown error ocurred', 500);
|
2017-07-06 15:11:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2017-07-06 17:11:15 +02:00
|
|
|
$this->sendPowerShellError($error, 400);
|
2017-07-06 15:11:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-07-06 17:11:15 +02:00
|
|
|
$form->handleRequest();
|
2017-07-06 15:11:57 +02:00
|
|
|
$this->addSingleTab($this->translate('Self Service'))
|
|
|
|
->addTitle($this->translate('Self Service - Host Registration'))
|
|
|
|
->content()->add(Html::p($this->translate(
|
|
|
|
'In case an Icinga Admin provided you with a self service API'
|
|
|
|
. ' token, this is where you can register new hosts'
|
|
|
|
)))
|
|
|
|
->add($form);
|
|
|
|
}
|
2017-07-06 17:11:15 +02:00
|
|
|
|
|
|
|
protected function sendPowerShellResponse($response)
|
|
|
|
{
|
|
|
|
if ($this->getRequest()->getHeader('X-Director-Accept') === 'text/plain') {
|
|
|
|
if (is_array($response)) {
|
|
|
|
echo $this->makePlainTextPowerShellArray($response);
|
|
|
|
} else {
|
|
|
|
echo $response;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$this->sendJson($this->getResponse(), $response);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function sendPowerShellError($error, $code)
|
|
|
|
{
|
|
|
|
$this->getResponse()->setHttpResponseCode($code);
|
|
|
|
if ($this->getRequest()->getHeader('X-Director-Accept') === 'text/plain') {
|
|
|
|
echo "ERROR: $error";
|
|
|
|
} else {
|
|
|
|
$this->sendJsonError($this->getResponse(), $error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function makePowerShellBoolean($value)
|
|
|
|
{
|
|
|
|
if ($value === 'y' || $value === true) {
|
|
|
|
return 'true';
|
|
|
|
} elseif ($value === 'n' || $value === false) {
|
|
|
|
return 'false';
|
|
|
|
} else {
|
|
|
|
throw new ProgrammingError(
|
|
|
|
'Expected boolean value, got %s',
|
|
|
|
var_export($value, 1)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function makePlainTextPowerShellArray(array $params)
|
|
|
|
{
|
|
|
|
$plain = '';
|
|
|
|
|
|
|
|
foreach ($params as $key => $value) {
|
|
|
|
if (is_bool($value)) {
|
|
|
|
$value = $this->makePowerShellBoolean($value);
|
|
|
|
}
|
|
|
|
$plain .= "$key: $value\r\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
return $plain;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function powershellParametersAction()
|
|
|
|
{
|
|
|
|
if (!$this->getRequest()->isApiRequest()) {
|
|
|
|
throw new NotFoundError('Not found');
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
$this->shipPowershellParams();
|
|
|
|
} catch (Exception $e) {
|
|
|
|
if ($e instanceof NotFoundError) {
|
|
|
|
$this->sendPowerShellError($e->getMessage(), 404);
|
|
|
|
} else {
|
|
|
|
$this->sendPowerShellError($e->getMessage(), 500);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function shipPowershellParams()
|
|
|
|
{
|
|
|
|
$db = $this->db();
|
|
|
|
$key = $this->params->getRequired('key');
|
|
|
|
$host = IcingaHost::loadWithApiKey($key, $db);
|
|
|
|
if ($host->isTemplate()) {
|
|
|
|
throw new NotFoundError('Got invalid API key "%s"', $key);
|
|
|
|
}
|
|
|
|
$name = $host->getObjectName();
|
|
|
|
|
|
|
|
if ($host->getSingleResolvedProperty('has_agent') !== 'y') {
|
|
|
|
$this->sendPowerShellError(sprintf(
|
|
|
|
'%s is not configured for Icinga Agent usage',
|
|
|
|
$name
|
|
|
|
), 403);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$zoneName = $host->getRenderingZone();
|
|
|
|
if ($zoneName === IcingaHost::RESOLVE_ERROR) {
|
|
|
|
$this->sendPowerShellError(sprintf(
|
|
|
|
'Could not resolve target Zone for %s',
|
|
|
|
$name
|
|
|
|
), 404);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$zone = IcingaZone::load($zoneName, $db);
|
|
|
|
$master = $db->getDeploymentEndpoint();
|
|
|
|
$settings = new Settings($db);
|
|
|
|
$params = [
|
|
|
|
'fetch_agent_name' => $settings->get('self-service/agent_name') === 'host',
|
|
|
|
'fetch_agent_fqdn' => $settings->get('self-service/agent_name') === 'fqdn',
|
|
|
|
'transform_hostname' => $settings->get('self-service/transform_hostname'),
|
|
|
|
'parent_zone' => $zoneName,
|
|
|
|
'ca_server' => $master->getObjectName(),
|
|
|
|
'parent_endpoints' => implode(',', $zone->listEndpoints()),
|
|
|
|
'flush_api_directory' => $settings->get('self-service/flush_api_dir') === 'y'
|
|
|
|
];
|
|
|
|
|
|
|
|
if ($settings->get('self-service/download_type')) {
|
|
|
|
$params['download_url'] = $settings->get('self-service/download_url');
|
|
|
|
$params['agent_version'] = $settings->get('self-service/agent_version');
|
|
|
|
$params['allow_updates'] = $settings->get('self-service/allow_updates') === 'y';
|
|
|
|
$params['accept_config'] = $host->getSingleResolvedProperty('accept_config')=== 'y';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($this->getRequest()->getHeader('X-Director-Accept') === 'text/plain') {
|
|
|
|
echo $this->makePlainTextPowerShellArray($params);
|
|
|
|
} else {
|
|
|
|
$this->sendJson($this->getResponse(), $params);
|
|
|
|
}
|
|
|
|
}
|
2017-07-06 15:11:57 +02:00
|
|
|
}
|