mirror of
https://github.com/Icinga/icingadb-web.git
synced 2026-06-09 00:32:05 -04:00
RedisConfigForm: Store pem files on disk, not in config
This commit is contained in:
parent
0e1771a3c2
commit
bbef9fd363
2 changed files with 74 additions and 44 deletions
|
|
@ -6,6 +6,10 @@ namespace Icinga\Module\Icingadb\Forms;
|
|||
|
||||
use Exception;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Exception\NotWritableError;
|
||||
use Icinga\File\Storage\LocalFileStorage;
|
||||
use Icinga\File\Storage\TemporaryLocalFileStorage;
|
||||
use Icinga\Forms\ConfigForm;
|
||||
use Icinga\Module\Icingadb\Common\IcingaRedis;
|
||||
use Icinga\Web\Form;
|
||||
|
|
@ -261,6 +265,64 @@ class RedisConfigForm extends ConfigForm
|
|||
return true;
|
||||
}
|
||||
|
||||
public function onRequest()
|
||||
{
|
||||
$errors = [];
|
||||
|
||||
$redisConfig = $this->config->getSection('redis');
|
||||
if ($redisConfig->get('tls', false)) {
|
||||
foreach (['ca', 'cert', 'key'] as $name) {
|
||||
$path = $redisConfig->get($name);
|
||||
if (file_exists($path)) {
|
||||
try {
|
||||
$redisConfig[$name] = file_get_contents($path);
|
||||
} catch (Exception $e) {
|
||||
unset($redisConfig[$name]);
|
||||
$errors['redis_' . $name] = sprintf(
|
||||
t('Failed to read file "%s": %s'),
|
||||
$path,
|
||||
$e->getMessage()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
unset($redisConfig[$name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
parent::onRequest();
|
||||
|
||||
foreach ($errors as $elementName => $message) {
|
||||
$this->getElement($elementName)->addError($message);
|
||||
}
|
||||
}
|
||||
|
||||
public function onSuccess()
|
||||
{
|
||||
if ($this->getElement('redis_tls')->isChecked()) {
|
||||
$storage = new LocalFileStorage(Icinga::app()->getStorageDir(
|
||||
join(DIRECTORY_SEPARATOR, ['modules', 'icingadb', 'redis'])
|
||||
));
|
||||
|
||||
foreach (['redis_ca', 'redis_cert', 'redis_key'] as $name) {
|
||||
$pem = $this->getValue($name);
|
||||
$pemFile = md5($pem) . '-' . $name . '.pem';
|
||||
if (! $storage->has($pemFile)) {
|
||||
try {
|
||||
$storage->create($pemFile, $pem);
|
||||
} catch (NotWritableError $e) {
|
||||
$this->getElement($name)->addError($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$this->getElement($name)->setValue($storage->resolvePath($pemFile));
|
||||
}
|
||||
}
|
||||
|
||||
return parent::onSuccess();
|
||||
}
|
||||
|
||||
public function addSubmitButton()
|
||||
{
|
||||
parent::addSubmitButton()
|
||||
|
|
@ -296,9 +358,15 @@ class RedisConfigForm extends ConfigForm
|
|||
$sections = [];
|
||||
$config = new Config();
|
||||
|
||||
$storage = new TemporaryLocalFileStorage();
|
||||
foreach (ConfigForm::transformEmptyValuesToNull($form->getValues()) as $sectionAndPropertyName => $value) {
|
||||
if ($value !== null) {
|
||||
list($section, $property) = explode('_', $sectionAndPropertyName, 2);
|
||||
if (in_array($property, ['ca', 'cert', 'key'])) {
|
||||
$storage->create("$property.pem", $value);
|
||||
$value = $storage->resolvePath("$property.pem");
|
||||
}
|
||||
|
||||
$sections[$section][$property] = $value;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,6 @@ namespace Icinga\Module\Icingadb\Common;
|
|||
|
||||
use Exception;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Exception\NotFoundError;
|
||||
use Icinga\File\Storage\CommonFileStorage;
|
||||
use Icinga\File\Storage\TemporaryLocalFileStorage;
|
||||
use Predis\Client as Redis;
|
||||
|
||||
trait IcingaRedis
|
||||
|
|
@ -95,11 +92,8 @@ trait IcingaRedis
|
|||
|
||||
private function getPrimaryRedis(Config $config = null)
|
||||
{
|
||||
$pkiIsTemporary = true;
|
||||
|
||||
if ($config === null) {
|
||||
$config = Config::module('icingadb');
|
||||
$pkiIsTemporary = false;
|
||||
}
|
||||
|
||||
$section = $config->getSection('redis1');
|
||||
|
|
@ -108,7 +102,7 @@ trait IcingaRedis
|
|||
'host' => $section->get('host', 'localhost'),
|
||||
'port' => $section->get('port', 6380),
|
||||
'timeout' => 0.5
|
||||
] + $this->getTlsParams($config, $pkiIsTemporary));
|
||||
] + $this->getTlsParams($config));
|
||||
|
||||
$redis->ping();
|
||||
|
||||
|
|
@ -117,11 +111,8 @@ trait IcingaRedis
|
|||
|
||||
private function getSecondaryRedis(Config $config = null)
|
||||
{
|
||||
$pkiIsTemporary = true;
|
||||
|
||||
if ($config === null) {
|
||||
$config = Config::module('icingadb');
|
||||
$pkiIsTemporary = false;
|
||||
}
|
||||
|
||||
$section = $config->getSection('redis2');
|
||||
|
|
@ -135,14 +126,14 @@ trait IcingaRedis
|
|||
'host' => $host,
|
||||
'port' => $section->get('port', 6380),
|
||||
'timeout' => 0.5
|
||||
] + $this->getTlsParams($config, $pkiIsTemporary));
|
||||
] + $this->getTlsParams($config));
|
||||
|
||||
$redis->ping();
|
||||
|
||||
return $redis;
|
||||
}
|
||||
|
||||
private function getTlsParams(Config $config, $pkiIsTemporary)
|
||||
private function getTlsParams(Config $config)
|
||||
{
|
||||
$config = $config->getSection('redis');
|
||||
|
||||
|
|
@ -159,7 +150,7 @@ trait IcingaRedis
|
|||
$ca = $config->get('ca');
|
||||
|
||||
if ($ca !== null) {
|
||||
$ssl['cafile'] = $this->ensurePemOnDisk($ca, 'ca', $pkiIsTemporary);
|
||||
$ssl['cafile'] = $ca;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -167,39 +158,10 @@ trait IcingaRedis
|
|||
$key = $config->get('key');
|
||||
|
||||
if ($cert !== null && $key !== null) {
|
||||
$ssl['local_cert'] = $this->ensurePemOnDisk($cert, 'cert', $pkiIsTemporary);
|
||||
$ssl['local_pk'] = $this->ensurePemOnDisk($key, 'key', $pkiIsTemporary);
|
||||
$ssl['local_cert'] = $cert;
|
||||
$ssl['local_pk'] = $key;
|
||||
}
|
||||
|
||||
return ['scheme' => 'tls', 'ssl' => $ssl];
|
||||
}
|
||||
|
||||
private function ensurePemOnDisk($pem, $subject, $temporary)
|
||||
{
|
||||
if ($temporary) {
|
||||
$storage = new TemporaryLocalFileStorage();
|
||||
$keepAlive = (object) ['storage' => $storage];
|
||||
|
||||
$storage->create("$subject.pem", $pem);
|
||||
|
||||
// Keep a reference to $storage until shutdown
|
||||
register_shutdown_function(function () use ($keepAlive) {
|
||||
$keepAlive->storage = null;
|
||||
});
|
||||
} else {
|
||||
$storage = CommonFileStorage::module('redis');
|
||||
|
||||
try {
|
||||
$create = $storage->read("$subject.pem") !== $pem;
|
||||
} catch (NotFoundError $_) {
|
||||
$create = true;
|
||||
}
|
||||
|
||||
if ($create) {
|
||||
$storage->create("$subject.pem", $pem);
|
||||
}
|
||||
}
|
||||
|
||||
return $storage->resolvePath("$subject.pem");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue