Merge pull request #1809 from Icinga/feature/command-flat

IcingaCommand: Allow command to be rendered as string
This commit is contained in:
Markus Frosch 2019-03-26 12:37:13 +01:00 committed by GitHub
commit eee3372430
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 85 additions and 24 deletions

View File

@ -73,6 +73,22 @@ class IcingaCommandForm extends DirectorObjectForm
. ' specific unit (e.g. 1m or also 3m 30s).' . ' specific unit (e.g. 1m or also 3m 30s).'
) )
)); ));
$descIsString = [
$this->translate('Render the command as a plain string instead of an array.'),
$this->translate('If enabled you can not define arguments.'),
$this->translate('Disabled by default, and should only be used in rare cases.'),
$this->translate('WARNING, this can allow shell script injection via custom variables used in command.'),
];
$this->addBoolean(
'is_string',
array(
'label' => $this->translate('Render as string'),
'description' => join(' ', $descIsString),
)
);
$this->addDisabledElement(); $this->addDisabledElement();
$this->addZoneSection(); $this->addZoneSection();
$this->setButtons(); $this->setButtons();

View File

@ -19,14 +19,19 @@ class IcingaCommand extends IcingaObject implements ObjectWithArguments, ExportI
protected $type = 'CheckCommand'; protected $type = 'CheckCommand';
protected $defaultProperties = [ protected $defaultProperties = [
'id' => null, 'id' => null,
'object_name' => null, 'object_name' => null,
'object_type' => null, 'object_type' => null,
'disabled' => 'n', 'disabled' => 'n',
'methods_execute' => null, 'methods_execute' => null,
'command' => null, 'command' => null,
'timeout' => null, 'timeout' => null,
'zone_id' => null, 'zone_id' => null,
'is_string' => null,
];
protected $booleans = [
'is_string' => 'is_string',
]; ];
protected $supportsCustomVars = true; protected $supportsCustomVars = true;
@ -288,16 +293,33 @@ class IcingaCommand extends IcingaObject implements ObjectWithArguments, ExportI
$command = $this->get('command'); $command = $this->get('command');
$prefix = ''; $prefix = '';
if (preg_match('~^([A-Z][A-Za-z0-9_]+\s\+\s)(.+?)$~', $command, $m)) { if (preg_match('~^([A-Z][A-Za-z0-9_]+\s\+\s)(.+?)$~', $command, $m)) {
$prefix = $m[1]; $prefix = $m[1];
$command = $m[2]; $command = $m[2];
} elseif (! $this->isAbsolutePath($command)) { } elseif (! $this->isAbsolutePath($command)) {
$prefix = 'PluginDir + '; $prefix = 'PluginDir + ';
$command = '/' . $command; $command = '/' . $command;
} }
$parts = preg_split('/\s+/', $command, -1, PREG_SPLIT_NO_EMPTY);
array_unshift($parts, c::alreadyRendered($prefix . c::renderString(array_shift($parts))));
return c::renderKeyValue('command', c::renderArray($parts)); $inherited = $this->getInheritedProperties();
if ($this->get('is_string') === 'y' || ($this->get('is_string') === null
&& property_exists($inherited, 'is_string') && $inherited->is_string === 'y')) {
return c::renderKeyValue('command', $prefix . c::renderString($command));
} else {
$parts = preg_split('/\s+/', $command, -1, PREG_SPLIT_NO_EMPTY);
array_unshift($parts, c::alreadyRendered($prefix . c::renderString(array_shift($parts))));
return c::renderKeyValue('command', c::renderArray($parts));
}
}
/**
* @codingStandardsIgnoreStart
*/
protected function renderIs_string()
{
// @codingStandardsIgnoreEnd
return '';
} }
protected function isAbsolutePath($path) protected function isAbsolutePath($path)

View File

@ -99,17 +99,23 @@ class ObjectPreview
$classes[] = 'logfile'; $classes[] = 'logfile';
} }
$type = $object->getShortTableName();
$plain = Html::wantHtml($file->getContent())->render(); $plain = Html::wantHtml($file->getContent())->render();
$plain = preg_replace_callback( $plain = preg_replace_callback(
'/^(\s+import\s+\&quot\;)(.+)(\&quot\;)/m', '/^(\s+import\s+\&quot\;)(.+)(\&quot\;)/m',
[$this, 'linkImport'], [$this, 'linkImport'],
$plain $plain
); );
$plain = preg_replace_callback(
'/^(\s+(?:check_|event_)?command\s+=\s+\&quot\;)(.+)(\&quot\;)/m', if ($type !== 'command') {
[$this, 'linkCommand'], $plain = preg_replace_callback(
$plain '/^(\s+(?:check_|event_)?command\s+=\s+\&quot\;)(.+)(\&quot\;)/m',
); [$this, 'linkCommand'],
$plain
);
}
$plain = preg_replace_callback( $plain = preg_replace_callback(
'/^(\s+host_name\s+=\s+\&quot\;)(.+)(\&quot\;)/m', '/^(\s+host_name\s+=\s+\&quot\;)(.+)(\&quot\;)/m',
[$this, 'linkHost'], [$this, 'linkHost'],

View File

@ -57,18 +57,21 @@ class IcingaObjectInspection extends BaseHtmlElement
{ {
$this->add(Html::tag('h2', null, $this->translate('Last Check Result'))); $this->add(Html::tag('h2', null, $this->translate('Last Check Result')));
$this->renderCheckResultDetails($result); $this->renderCheckResultDetails($result);
if (property_exists($result, 'command') && is_array($result->command)) { if (property_exists($result, 'command')) {
$this->renderExecutedCommand($result->command); $this->renderExecutedCommand($result->command);
} }
} }
/** /**
* @param array $command * @param array|string $command
*
* @throws \Icinga\Exception\IcingaException * @throws \Icinga\Exception\IcingaException
*/ */
protected function renderExecutedCommand(array $command) protected function renderExecutedCommand($command)
{ {
$command = implode(' ', array_map('escapeshellarg', $command)); if (is_array($command)) {
$command = implode(' ', array_map('escapeshellarg', $command));
}
$this->add([ $this->add([
Html::tag('h3', null, 'Executed Command'), Html::tag('h3', null, 'Executed Command'),
$this->formatConsole($command) $this->formatConsole($command)

View File

@ -0,0 +1,6 @@
ALTER TABLE icinga_command
ADD COLUMN is_string enum ('y', 'n') NULL;
INSERT INTO director_schema_migration
(schema_version, migration_time)
VALUES (160, NOW());

View File

@ -320,6 +320,7 @@ CREATE TABLE icinga_command (
disabled ENUM('y', 'n') NOT NULL DEFAULT 'n', disabled ENUM('y', 'n') NOT NULL DEFAULT 'n',
methods_execute VARCHAR(64) DEFAULT NULL, methods_execute VARCHAR(64) DEFAULT NULL,
command TEXT DEFAULT NULL, command TEXT DEFAULT NULL,
is_string ENUM('y', 'n') NULL,
-- env text DEFAULT NULL, -- env text DEFAULT NULL,
-- vars text DEFAULT NULL, -- vars text DEFAULT NULL,
timeout SMALLINT UNSIGNED DEFAULT NULL, timeout SMALLINT UNSIGNED DEFAULT NULL,
@ -1787,4 +1788,4 @@ CREATE TABLE icinga_timeperiod_exclude (
INSERT INTO director_schema_migration INSERT INTO director_schema_migration
(schema_version, migration_time) (schema_version, migration_time)
VALUES (159, NOW()); VALUES (160, NOW());

View File

@ -0,0 +1,6 @@
ALTER TABLE icinga_command
ADD COLUMN is_string enum_boolean NULL;
INSERT INTO director_schema_migration
(schema_version, migration_time)
VALUES (160, NOW());

View File

@ -415,6 +415,7 @@ CREATE TABLE icinga_command (
disabled enum_boolean NOT NULL DEFAULT 'n', disabled enum_boolean NOT NULL DEFAULT 'n',
methods_execute character varying(64) DEFAULT NULL, methods_execute character varying(64) DEFAULT NULL,
command text DEFAULT NULL, command text DEFAULT NULL,
is_string enum_boolean NULL,
-- env text DEFAULT NULL, -- env text DEFAULT NULL,
timeout smallint DEFAULT NULL, timeout smallint DEFAULT NULL,
zone_id integer DEFAULT NULL, zone_id integer DEFAULT NULL,
@ -2086,4 +2087,4 @@ CREATE TABLE icinga_timeperiod_exclude (
INSERT INTO director_schema_migration INSERT INTO director_schema_migration
(schema_version, migration_time) (schema_version, migration_time)
VALUES (158, NOW()); VALUES (160, NOW());