mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-07-28 16:24:04 +02:00
commit
118055c07d
182
library/Icinga/Util/GlobFilter.php
Normal file
182
library/Icinga/Util/GlobFilter.php
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
<?php
|
||||||
|
/* Icinga Web 2 | (c) 2016 Icinga Development Team | GPLv2+ */
|
||||||
|
|
||||||
|
namespace Icinga\Util;
|
||||||
|
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GLOB-like filter for simple data structures
|
||||||
|
*
|
||||||
|
* e.g. this filters:
|
||||||
|
*
|
||||||
|
* foo.bar.baz
|
||||||
|
* foo.b*r.baz
|
||||||
|
* **.baz
|
||||||
|
*
|
||||||
|
* match this one:
|
||||||
|
*
|
||||||
|
* array(
|
||||||
|
* 'foo' => array(
|
||||||
|
* 'bar' => array(
|
||||||
|
* 'baz' => 'deadbeef' // <---
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
class GlobFilter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The prepared filters
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $filters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new filter from a comma-separated list of GLOB-like filters or an array of such lists.
|
||||||
|
*
|
||||||
|
* @param string|\Traversable $filters
|
||||||
|
*/
|
||||||
|
public function __construct($filters)
|
||||||
|
{
|
||||||
|
$patterns = array(array(''));
|
||||||
|
$lastIndex1 = $lastIndex2 = 0;
|
||||||
|
|
||||||
|
foreach ((is_string($filters) ? array($filters) : $filters) as $rawPatterns) {
|
||||||
|
$escape = false;
|
||||||
|
|
||||||
|
foreach (str_split($rawPatterns) as $c) {
|
||||||
|
if ($escape) {
|
||||||
|
$escape = false;
|
||||||
|
$patterns[$lastIndex1][$lastIndex2] .= preg_quote($c, '/');
|
||||||
|
} else {
|
||||||
|
switch ($c) {
|
||||||
|
case '\\':
|
||||||
|
$escape = true;
|
||||||
|
break;
|
||||||
|
case ',':
|
||||||
|
$patterns[] = array('');
|
||||||
|
++$lastIndex1;
|
||||||
|
$lastIndex2 = 0;
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
$patterns[$lastIndex1][] = '';
|
||||||
|
++$lastIndex2;
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
$patterns[$lastIndex1][$lastIndex2] .= '.*';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$patterns[$lastIndex1][$lastIndex2] .= preg_quote($c, '/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($escape) {
|
||||||
|
$patterns[$lastIndex1][$lastIndex2] .= '\\\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->filters = array();
|
||||||
|
|
||||||
|
foreach ($patterns as $pattern) {
|
||||||
|
foreach ($pattern as $i => $subPattern) {
|
||||||
|
if ($subPattern === '') {
|
||||||
|
unset($pattern[$i]);
|
||||||
|
} elseif ($subPattern === '.*.*') {
|
||||||
|
$pattern[$i] = '**';
|
||||||
|
} elseif ($subPattern === '.*') {
|
||||||
|
$pattern[$i] = '/^' . $subPattern . '$/';
|
||||||
|
} else {
|
||||||
|
$pattern[$i] = '/^' . trim($subPattern) . '$/i';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! empty($pattern)) {
|
||||||
|
$found = false;
|
||||||
|
foreach ($pattern as $i => $v) {
|
||||||
|
if ($found) {
|
||||||
|
if ($v === '**') {
|
||||||
|
unset($pattern[$i]);
|
||||||
|
} else {
|
||||||
|
$found = false;
|
||||||
|
}
|
||||||
|
} elseif ($v === '**') {
|
||||||
|
$found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end($pattern) === '**') {
|
||||||
|
$pattern[] = '/^.*$/';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->filters[] = array_values($pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all keys/attributes matching any of $this->filters from $dataStructure
|
||||||
|
*
|
||||||
|
* @param stdClass|array $dataStructure
|
||||||
|
*
|
||||||
|
* @return stdClass|array The modified copy of $dataStructure
|
||||||
|
*/
|
||||||
|
public function removeMatching($dataStructure)
|
||||||
|
{
|
||||||
|
foreach ($this->filters as $filter) {
|
||||||
|
$dataStructure = static::removeMatchingRecursive($dataStructure, $filter);
|
||||||
|
}
|
||||||
|
return $dataStructure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method for removeMatching()
|
||||||
|
*
|
||||||
|
* @param stdClass|array $dataStructure
|
||||||
|
* @param array $filter
|
||||||
|
*
|
||||||
|
* @return stdClass|array
|
||||||
|
*/
|
||||||
|
protected static function removeMatchingRecursive($dataStructure, $filter)
|
||||||
|
{
|
||||||
|
$multiLevelPattern = $filter[0] === '**';
|
||||||
|
if ($multiLevelPattern) {
|
||||||
|
$dataStructure = static::removeMatchingRecursive($dataStructure, array_slice($filter, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
$isObject = $dataStructure instanceof stdClass;
|
||||||
|
if ($isObject || is_array($dataStructure)) {
|
||||||
|
if ($isObject) {
|
||||||
|
$dataStructure = (array) $dataStructure;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($multiLevelPattern) {
|
||||||
|
foreach ($dataStructure as $k => & $v) {
|
||||||
|
$v = static::removeMatchingRecursive($v, $filter);
|
||||||
|
unset($v);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$currentLevel = $filter[0];
|
||||||
|
$nextLevels = count($filter) === 1 ? null : array_slice($filter, 1);
|
||||||
|
foreach ($dataStructure as $k => & $v) {
|
||||||
|
if (preg_match($currentLevel, (string) $k)) {
|
||||||
|
if ($nextLevels === null) {
|
||||||
|
unset($dataStructure[$k]);
|
||||||
|
} else {
|
||||||
|
$v = static::removeMatchingRecursive($v, $nextLevels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($isObject) {
|
||||||
|
$dataStructure = (object) $dataStructure;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $dataStructure;
|
||||||
|
}
|
||||||
|
}
|
@ -84,6 +84,10 @@ $this->provideRestriction(
|
|||||||
'monitoring/filter/objects',
|
'monitoring/filter/objects',
|
||||||
$this->translate('Restrict views to the Icinga objects that match the filter')
|
$this->translate('Restrict views to the Icinga objects that match the filter')
|
||||||
);
|
);
|
||||||
|
$this->provideRestriction(
|
||||||
|
'monitoring/blacklist/properties',
|
||||||
|
$this->translate('Hide the properties of monitored objects that match the filter')
|
||||||
|
);
|
||||||
|
|
||||||
$this->provideConfigTab('backends', array(
|
$this->provideConfigTab('backends', array(
|
||||||
'title' => $this->translate('Configure how to retrieve monitoring information'),
|
'title' => $this->translate('Configure how to retrieve monitoring information'),
|
||||||
|
77
modules/monitoring/doc/restrict-custom-variables.md
Normal file
77
modules/monitoring/doc/restrict-custom-variables.md
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
# Restrict Access to Custom Variables (WIP)
|
||||||
|
|
||||||
|
* Restriction name: monitoring/blacklist/properties
|
||||||
|
* Restriction value: Comma separated list of GLOB like filters
|
||||||
|
|
||||||
|
Imagine the following host custom variable structure.
|
||||||
|
|
||||||
|
```
|
||||||
|
host.vars.
|
||||||
|
|-- cmdb_name
|
||||||
|
|-- cmdb_id
|
||||||
|
|-- cmdb_location
|
||||||
|
|-- wiki_id
|
||||||
|
|-- passwords.
|
||||||
|
| |-- mysql_password
|
||||||
|
| |-- ldap_password
|
||||||
|
| `-- mongodb_password
|
||||||
|
|-- legacy.
|
||||||
|
| |-- cmdb_name
|
||||||
|
| |-- mysql_password
|
||||||
|
| `-- wiki_id
|
||||||
|
`-- backup.
|
||||||
|
`-- passwords.
|
||||||
|
|-- mysql_password
|
||||||
|
`-- ldap_password
|
||||||
|
```
|
||||||
|
|
||||||
|
`host.vars.cmdb_name`
|
||||||
|
|
||||||
|
Blacklists cmdb_name in the first level of the custom variable structure only.
|
||||||
|
`host.vars.legacy.cmdb_name` is not blacklisted.
|
||||||
|
|
||||||
|
|
||||||
|
`host.vars.cmdb_*`
|
||||||
|
|
||||||
|
All custom variables in the first level of the structure which begin with `cmdb_` become blacklisted.
|
||||||
|
Deeper custom variables are ignored. `host.vars.legacy.cmdb_name` is not blacklisted.
|
||||||
|
|
||||||
|
`host.vars.*id`
|
||||||
|
|
||||||
|
All custom variables in the first level of the structure which end with `id` become blacklisted.
|
||||||
|
Deeper custom variables are ignored. `host.vars.legacy.wiki_id` is not blacklisted.
|
||||||
|
|
||||||
|
`host.vars.*.mysql_password`
|
||||||
|
|
||||||
|
Matches all custom variables on the second level which are equal to `mysql_password`.
|
||||||
|
|
||||||
|
`host.vars.*.*password`
|
||||||
|
|
||||||
|
Matches all custom variables on the second level which end with `password`.
|
||||||
|
|
||||||
|
`host.vars.*.mysql_password,host.vars.*.ldap_password`
|
||||||
|
|
||||||
|
Matches all custorm variables on the second level which equal `mysql_password` or `ldap_password`.
|
||||||
|
|
||||||
|
`host.vars.**.*password`
|
||||||
|
|
||||||
|
Matches all custom variables on all levels which end with `password`.
|
||||||
|
|
||||||
|
Please note the two asterisks, `**`, here for crossing level boundaries. This syntax is used for matching the complete
|
||||||
|
custom variable structure.
|
||||||
|
|
||||||
|
If you want to restrict all custom variables that end with password for both hosts and services, you have to define
|
||||||
|
the following restriction.
|
||||||
|
|
||||||
|
`host.vars.**.*password,service.vars.**.*password`
|
||||||
|
|
||||||
|
## Escape Meta Characters
|
||||||
|
|
||||||
|
Use backslash to escape the meta characters
|
||||||
|
|
||||||
|
* *
|
||||||
|
* ,
|
||||||
|
|
||||||
|
`host.vars.\*fall`
|
||||||
|
|
||||||
|
Matches all custom variables in the first level which equal `*fall`.
|
@ -5,12 +5,14 @@ namespace Icinga\Module\Monitoring\Object;
|
|||||||
|
|
||||||
use stdClass;
|
use stdClass;
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
|
use Icinga\Authentication\Auth;
|
||||||
use Icinga\Application\Config;
|
use Icinga\Application\Config;
|
||||||
use Icinga\Data\Filter\Filter;
|
use Icinga\Data\Filter\Filter;
|
||||||
use Icinga\Data\Filterable;
|
use Icinga\Data\Filterable;
|
||||||
use Icinga\Exception\InvalidPropertyException;
|
use Icinga\Exception\InvalidPropertyException;
|
||||||
use Icinga\Exception\ProgrammingError;
|
use Icinga\Exception\ProgrammingError;
|
||||||
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
||||||
|
use Icinga\Util\GlobFilter;
|
||||||
use Icinga\Web\UrlParams;
|
use Icinga\Web\UrlParams;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,6 +149,13 @@ abstract class MonitoredObject implements Filterable
|
|||||||
*/
|
*/
|
||||||
protected $stats;
|
protected $stats;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The properties to hide from the user
|
||||||
|
*
|
||||||
|
* @var GlobFilter
|
||||||
|
*/
|
||||||
|
protected $blacklistedProperties = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a monitored object, i.e. host or service
|
* Create a monitored object, i.e. host or service
|
||||||
*
|
*
|
||||||
@ -457,7 +466,9 @@ abstract class MonitoredObject implements Filterable
|
|||||||
$customvars = $this->hostVariables;
|
$customvars = $this->hostVariables;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->customvars = $this->obfuscateCustomVars($customvars, $blacklistPattern);
|
$this->customvars = $customvars;
|
||||||
|
$this->hideBlacklistedProperties();
|
||||||
|
$this->customvars = $this->obfuscateCustomVars($this->customvars, $blacklistPattern);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -485,6 +496,25 @@ abstract class MonitoredObject implements Filterable
|
|||||||
return $customvars instanceof stdClass ? (object) $obfuscatedCustomVars : $obfuscatedCustomVars;
|
return $customvars instanceof stdClass ? (object) $obfuscatedCustomVars : $obfuscatedCustomVars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide all blacklisted properties from the user as restricted by monitoring/blacklist/properties
|
||||||
|
*
|
||||||
|
* Currently this only affects the custom variables
|
||||||
|
*/
|
||||||
|
protected function hideBlacklistedProperties()
|
||||||
|
{
|
||||||
|
if ($this->blacklistedProperties === null) {
|
||||||
|
$this->blacklistedProperties = new GlobFilter(
|
||||||
|
Auth::getInstance()->getRestrictions('monitoring/blacklist/properties')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$allProperties = $this->blacklistedProperties->removeMatching(
|
||||||
|
array($this->type => array('vars' => $this->customvars))
|
||||||
|
);
|
||||||
|
$this->customvars = isset($allProperties[$this->type]['vars']) ? $allProperties[$this->type]['vars'] : array();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the host custom variables related to this object
|
* Fetch the host custom variables related to this object
|
||||||
*
|
*
|
||||||
|
325
test/php/library/Icinga/Util/GlobFilterTest.php
Normal file
325
test/php/library/Icinga/Util/GlobFilterTest.php
Normal file
@ -0,0 +1,325 @@
|
|||||||
|
<?php
|
||||||
|
/* Icinga Web 2 | (c) 2016 Icinga Development Team | GPLv2+ */
|
||||||
|
|
||||||
|
namespace Tests\Icinga\Util;
|
||||||
|
|
||||||
|
use Icinga\Util\GlobFilter;
|
||||||
|
use Icinga\Test\BaseTestCase;
|
||||||
|
|
||||||
|
class GlobFilterTest extends BaseTestCase
|
||||||
|
{
|
||||||
|
protected function assertGlobFilterRemovesMatching($filterPattern, $unfiltered, $filtered)
|
||||||
|
{
|
||||||
|
$filter = new GlobFilter($filterPattern);
|
||||||
|
$this->assertTrue(
|
||||||
|
$filter->removeMatching($unfiltered) === $filtered,
|
||||||
|
'Filter `' . $filterPattern . '\' doesn\'t work as intended'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPatternWithoutAnyWildcards()
|
||||||
|
{
|
||||||
|
$this->assertGlobFilterRemovesMatching(
|
||||||
|
'host.vars.cmdb_name',
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'cmdb_name' => '',
|
||||||
|
'cmdb_id' => '',
|
||||||
|
'legacy' => array(
|
||||||
|
'cmdb_name' => ''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'cmdb_id' => '',
|
||||||
|
'legacy' => array(
|
||||||
|
'cmdb_name' => ''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPatternWithAnAsteriskAtTheEndOfAComponent()
|
||||||
|
{
|
||||||
|
$this->assertGlobFilterRemovesMatching(
|
||||||
|
'host.vars.cmdb_*',
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'cmdb_name' => '',
|
||||||
|
'cmdb_id' => '',
|
||||||
|
'cmdb_location' => '',
|
||||||
|
'wiki_id' => '',
|
||||||
|
'legacy' => array(
|
||||||
|
'cmdb_name' => ''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'wiki_id' => '',
|
||||||
|
'legacy' => array(
|
||||||
|
'cmdb_name' => ''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPatternWithAnAsteriskAtTheBeginningOfAComponent()
|
||||||
|
{
|
||||||
|
$this->assertGlobFilterRemovesMatching(
|
||||||
|
'host.vars.*id',
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'cmdb_name' => '',
|
||||||
|
'cmdb_id' => '',
|
||||||
|
'wiki_id' => '',
|
||||||
|
'legacy' => array(
|
||||||
|
'wiki_id' => ''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'cmdb_name' => '',
|
||||||
|
'legacy' => array(
|
||||||
|
'wiki_id' => ''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPatternWithAComponentBeingTheAsteriskOnly()
|
||||||
|
{
|
||||||
|
$this->assertGlobFilterRemovesMatching(
|
||||||
|
'host.vars.*.mysql_password',
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'cmdb_name' => '',
|
||||||
|
'passwords' => array(
|
||||||
|
'mysql_password' => '',
|
||||||
|
'ldap_password' => ''
|
||||||
|
),
|
||||||
|
'legacy' => array(
|
||||||
|
'mysql_password' => ''
|
||||||
|
),
|
||||||
|
'backup' => array(
|
||||||
|
'passwords' => array(
|
||||||
|
'mysql_password' => ''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'cmdb_name' => '',
|
||||||
|
'passwords' => array(
|
||||||
|
'ldap_password' => ''
|
||||||
|
),
|
||||||
|
'legacy' => array(),
|
||||||
|
'backup' => array(
|
||||||
|
'passwords' => array(
|
||||||
|
'mysql_password' => ''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPatternWithTwoComponentsContainingAsterisks()
|
||||||
|
{
|
||||||
|
$this->assertGlobFilterRemovesMatching(
|
||||||
|
'host.vars.*.*password',
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'cmdb_name' => '',
|
||||||
|
'passwords' => array(
|
||||||
|
'mysql_password' => '',
|
||||||
|
'ldap_password' => '',
|
||||||
|
'mongodb_password' => ''
|
||||||
|
),
|
||||||
|
'legacy' => array(
|
||||||
|
'cmdb_name' => '',
|
||||||
|
'mysql_password' => ''
|
||||||
|
),
|
||||||
|
'backup' => array(
|
||||||
|
'passwords' => array(
|
||||||
|
'mysql_password' => '',
|
||||||
|
'ldap_password' => ''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'cmdb_name' => '',
|
||||||
|
'passwords' => array(),
|
||||||
|
'legacy' => array(
|
||||||
|
'cmdb_name' => ''
|
||||||
|
),
|
||||||
|
'backup' => array(
|
||||||
|
'passwords' => array(
|
||||||
|
'mysql_password' => '',
|
||||||
|
'ldap_password' => ''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testTwoCommaSeparatedPatternsEachWithAnAsterisk()
|
||||||
|
{
|
||||||
|
$this->assertGlobFilterRemovesMatching(
|
||||||
|
'host.vars.*.mysql_password,host.vars.*.ldap_password',
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'cmdb_name' => '',
|
||||||
|
'passwords' => array(
|
||||||
|
'mysql_password' => '',
|
||||||
|
'ldap_password' => '',
|
||||||
|
'mongodb_password' => ''
|
||||||
|
),
|
||||||
|
'legacy' => array(
|
||||||
|
'mysql_password' => ''
|
||||||
|
),
|
||||||
|
'backup' => array(
|
||||||
|
'passwords' => array(
|
||||||
|
'mysql_password' => '',
|
||||||
|
'ldap_password' => ''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'cmdb_name' => '',
|
||||||
|
'passwords' => array(
|
||||||
|
'mongodb_password' => ''
|
||||||
|
),
|
||||||
|
'legacy' => array(),
|
||||||
|
'backup' => array(
|
||||||
|
'passwords' => array(
|
||||||
|
'mysql_password' => '',
|
||||||
|
'ldap_password' => ''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPatternWithAComponentBeingTheMultiLevelWildcard()
|
||||||
|
{
|
||||||
|
$this->assertGlobFilterRemovesMatching(
|
||||||
|
'host.vars.**.*password',
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'cmdb_location' => '',
|
||||||
|
'passwords' => array(
|
||||||
|
'mysql_password' => '',
|
||||||
|
'ldap_password' => '',
|
||||||
|
'mongodb_password' => ''
|
||||||
|
),
|
||||||
|
'legacy' => array(
|
||||||
|
'mysql_password' => '',
|
||||||
|
),
|
||||||
|
'backup' => array(
|
||||||
|
'passwords' => array(
|
||||||
|
'mysql_password' => '',
|
||||||
|
'ldap_password' => ''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'cmdb_location' => '',
|
||||||
|
'passwords' => array(),
|
||||||
|
'legacy' => array(),
|
||||||
|
'backup' => array(
|
||||||
|
'passwords' => array()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPatternWithAnEscapedAsterisk()
|
||||||
|
{
|
||||||
|
$this->assertGlobFilterRemovesMatching(
|
||||||
|
'host.vars.**.\*password',
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'wiki_id' => '',
|
||||||
|
'passwords' => array(
|
||||||
|
'mongodb_password' => '',
|
||||||
|
'*password' => ''
|
||||||
|
),
|
||||||
|
'legacy' => array(
|
||||||
|
'mysql_password' => '',
|
||||||
|
'*password' => ''
|
||||||
|
),
|
||||||
|
'backup' => array(
|
||||||
|
'passwords' => array(
|
||||||
|
'*password' => '',
|
||||||
|
'ldap_password' => ''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'host' => array(
|
||||||
|
'vars' => array(
|
||||||
|
'wiki_id' => '',
|
||||||
|
'passwords' => array(
|
||||||
|
'mongodb_password' => ''
|
||||||
|
),
|
||||||
|
'legacy' => array(
|
||||||
|
'mysql_password' => ''
|
||||||
|
),
|
||||||
|
'backup' => array(
|
||||||
|
'passwords' => array(
|
||||||
|
'ldap_password' => ''
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user