Handle expressions only for apply objects

Expressions will be handled only if the object is an ApplyRule.
Only properties and custom variables are replaced.

refs #11976
This commit is contained in:
Corentin Ardeois 2016-09-01 17:25:38 -04:00 committed by Thomas Gelf
parent bcef87f4c9
commit ddcfb09f58
11 changed files with 136 additions and 31 deletions

View File

@ -88,12 +88,12 @@ abstract class CustomVariable implements IcingaConfigRenderer
return $this->modified;
}
public function toConfigStringPrefetchable()
public function toConfigStringPrefetchable($renderExpressions = false)
{
if (PrefetchCache::shouldBeUsed()) {
return PrefetchCache::instance()->renderVar($this);
return PrefetchCache::instance()->renderVar($this, $renderExpressions);
} else {
return $this->toConfigString();
return $this->toConfigString($renderExpressions);
}
}

View File

@ -36,8 +36,8 @@ class CustomVariableString extends CustomVariable
return $this;
}
public function toConfigString()
public function toConfigString($renderExpressions = false)
{
return c::renderString($this->getValue());
return c::renderString($this->getValue(), $renderExpressions);
}
}

View File

@ -268,24 +268,24 @@ class CustomVariables implements Iterator, Countable, IcingaConfigRenderer
return $this->storedVars;
}
public function toConfigString()
public function toConfigString($renderExpressions = false)
{
$out = '';
ksort($this->vars);
foreach ($this->vars as $key => $var) {
// TODO: ctype_alnum + underscore?
$out .= $this->renderSingleVar($key, $var);
$out .= $this->renderSingleVar($key, $var, $renderExpressions);
}
return $out;
}
protected function renderSingleVar($key, $var)
protected function renderSingleVar($key, $var, $renderExpressions = false)
{
return c::renderKeyValue(
$this->renderKeyName($key),
$var->toConfigStringPrefetchable()
$var->toConfigStringPrefetchable($renderExpressions)
);
}

View File

@ -84,14 +84,14 @@ class PrefetchCache
}
*/
public function renderVar(CustomVariable $var)
public function renderVar(CustomVariable $var, $renderExpressions = false)
{
$checksum = $var->getChecksum();
if (null === $checksum) {
return $var->toConfigString();
return $var->toConfigString($renderExpressions);
} else {
if (! array_key_exists($checksum, $this->renderedVars)) {
$this->renderedVars[$checksum] = $var->toConfigString();
$this->renderedVars[$checksum] = $var->toConfigString($renderExpressions);
}
return $this->renderedVars[$checksum];

View File

@ -74,7 +74,7 @@ class IcingaConfigHelper
// TODO: Find out how to allow multiline {{{...}}} strings.
// Parameter? Dedicated method? Always if \n is found?
public static function renderString($string)
public static function renderString($string, $renderExpressions = false)
{
$special = array(
'/\\\/',
@ -100,7 +100,11 @@ class IcingaConfigHelper
$string = preg_replace($special, $replace, $string);
return '"' . self::renderVariablesAsExpression($string) . '"';
if ($renderExpressions) {
return self::renderStringWithVariables($string);
} else {
return '"' . $string . '"';
}
}
public static function renderDictionaryKey($key)
@ -258,7 +262,15 @@ class IcingaConfigHelper
return $seconds . 's';
}
private static function renderVariablesAsExpression($string) {
return preg_replace('/\$\$([\w\.]+)\$\$/', '" + ${1} + "', $string);
private static function renderStringWithVariables($string) {
$string = preg_replace('/\$\$([\w\.]+)\$\$/', '" + ${1} + "', $string);
$string = '"' . $string . '"';
if (substr($string, 0, 5) === '"" + ') {
$string = substr($string, 5);
}
if (substr($string, -5) === ' + ""') {
$string = substr($string, 0, -5);
}
return $string;
}
}

View File

@ -1631,11 +1631,8 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
protected function renderLegacyProperties()
{
$out = '';
$blacklist = array_merge(array(
'id',
'object_name',
'object_type',
), array() /* $this->prioritizedProperties */);
$blacklist = array_merge($this->propertiesNotForRendering,
array() /* $this->prioritizedProperties */);
foreach ($this->properties as $key => $value) {
if (in_array($key, $blacklist)) {
@ -1706,7 +1703,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
return $this->renderRelationProperty($relKey, $value);
}
return c::renderKeyValue($key, c::renderString($value));
return c::renderKeyValue($key, c::renderString($value, $this->isApplyRule()));
}
protected function renderLegacyObjectProperty($key, $value)
@ -1783,7 +1780,7 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
protected function renderCustomVars()
{
if ($this->supportsCustomVars()) {
return $this->vars()->toConfigString();
return $this->vars()->toConfigString($this->isApplyRule());
} else {
return '';
}

View File

@ -44,6 +44,21 @@ class CustomVariablesTest extends BaseTestCase
);
}
public function testVariablesToExpression()
{
$vars = $this->newVars();
$vars->bla = 'da';
$vars->abc = '$$val$$';
$expected = $this->indentVarsList(array(
'vars.abc = val',
'vars.bla = "da"'
));
$this->assertEquals(
$vars->toConfigString(true),
$expected
);
}
protected function indentVarsList($vars)
{
return $this->indent . implode(

View File

@ -83,16 +83,19 @@ class IcingaConfigHelperTest extends BaseTestCase
public function testRenderStringWithVariables()
{
$this->assertEquals(c::renderString('Before $$var$$', true), '"Before " + var');
$this->assertEquals(c::renderString('$$var$$ After', true), 'var + " After"');
$this->assertEquals(c::renderString('$$var$$', true), 'var');
$this->assertEquals(
c::renderString('Before $$name$$ $$name$$ After'),
c::renderString('Before $$name$$ $$name$$ After', true),
'"Before " + name + " " + name + " After"');
$this->assertEquals(
c::renderString('Before $$var1$$ $$var2$$ After'),
c::renderString('Before $$var1$$ $$var2$$ After', true),
'"Before " + var1 + " " + var2 + " After"');
$this->assertEquals(c::renderString('$$host.vars.custom$$'), '"" + host.vars.custom + ""');
$this->assertEquals(c::renderString('$$var"$$'), '"$$var\"$$"');
$this->assertEquals(c::renderString('$$host.vars.custom$$', true), 'host.vars.custom');
$this->assertEquals(c::renderString('$$var"$$', true), '"$$var\"$$"');
$this->assertEquals(
c::renderString('\tI am\rrendering\nproperly\fand I $$support$$ "multiple" $$variables$$\$'),
c::renderString('\tI am\rrendering\nproperly\fand I $$support$$ "multiple" $$variables$$\$', true),
'"\\\\tI am\\\\rrendering\\\\nproperly\\\\fand I " + support + " \"multiple\" " + variables + "\\\\$"');
}
}

View File

@ -12,6 +12,7 @@ class IcingaServiceTest extends BaseTestCase
protected $testHostName = '___TEST___host';
protected $testServiceName = '___TEST___service';
protected $createdServices = [];
public function testUnstoredHostCanBeLazySet()
{
@ -233,6 +234,51 @@ class IcingaServiceTest extends BaseTestCase
);
}
public function testVariablesInPropertiesAndCustomVariables()
{
if ($this->skipForMissingDb()) {
return;
}
$db = $this->getDb();
$service = $this->service('___TEST___service_$$not_replaced$$');
$service->object_type = 'apply';
$service->display_name = 'Service: $$replaced$$';
$service->assignments = array(
'host.address="127.*"',
);
$service->{'vars.custom_var'} = '$$replaced$$';
$service->store($db);
$service = IcingaService::loadWithAutoIncId($service->id, $db);
$this->assertEquals(
$this->loadRendered('service3'),
(string) $service
);
}
public function testVariablesAreNotReplacedForNonApplyObjects()
{
if ($this->skipForMissingDb()) {
return;
}
$db = $this->getDb();
$service = $this->service('___TEST___service_$$not_replaced$$');
$service->object_type = 'object';
$service->display_name = 'Service: $$not_replaced$$';
$service->{'vars.custom_var'} = '$$not_replaced$$';
$service->store($db);
$service = IcingaService::loadWithAutoIncId($service->id, $db);
$this->assertEquals(
$this->loadRendered('service4'),
(string) $service
);
}
protected function host()
{
return IcingaHost::create(array(
@ -242,10 +288,14 @@ class IcingaServiceTest extends BaseTestCase
));
}
protected function service()
protected function service($objectName = null)
{
if ($objectName === null) {
$objectName = $this->testServiceName;
}
$this->createdServices[] = $objectName;
return IcingaService::create(array(
'object_name' => $this->testServiceName,
'object_name' => $objectName,
'object_type' => 'object',
'display_name' => 'Whatever service',
'vars' => array(
@ -279,7 +329,7 @@ class IcingaServiceTest extends BaseTestCase
}
}
$kill = array($this->testServiceName);
$kill = $this->createdServices;
foreach ($kill as $name) {
if (IcingaService::exists(array($name), $db)) {
IcingaService::load($name, $db)->delete();

View File

@ -0,0 +1,16 @@
apply Service "___TEST___service_$$not_replaced$$" {
display_name = "Service: " + replaced
vars.custom_var = replaced
vars.test1 = "string"
vars.test2 = 17
vars.test3 = false
vars.test4 = {
a = [ "dict", "ionary" ]
@this = "is"
}
assign where match("127.*", host.address)
import "host var overrides (Director)"
}

View File

@ -0,0 +1,12 @@
object Service "___TEST___service_$$not_replaced$$" {
display_name = "Service: $$not_replaced$$"
vars.custom_var = "$$not_replaced$$"
vars.test1 = "string"
vars.test2 = 17
vars.test3 = false
vars.test4 = {
a = [ "dict", "ionary" ]
@this = "is"
}
}