summaryrefslogtreecommitdiffstats
path: root/library/Graphite/Graphing/Templates.php
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 12:44:18 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 12:44:18 +0000
commit23be945fd2810ee82e3a23cbcd2352c9bda43d4f (patch)
treedd511b321f308264952cffb005a4288ea4e478e6 /library/Graphite/Graphing/Templates.php
parentInitial commit. (diff)
downloadicingaweb2-module-graphite-23be945fd2810ee82e3a23cbcd2352c9bda43d4f.tar.xz
icingaweb2-module-graphite-23be945fd2810ee82e3a23cbcd2352c9bda43d4f.zip
Adding upstream version 1.2.2.upstream/1.2.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/Graphite/Graphing/Templates.php')
-rw-r--r--library/Graphite/Graphing/Templates.php321
1 files changed, 321 insertions, 0 deletions
diff --git a/library/Graphite/Graphing/Templates.php b/library/Graphite/Graphing/Templates.php
new file mode 100644
index 0000000..0765e46
--- /dev/null
+++ b/library/Graphite/Graphing/Templates.php
@@ -0,0 +1,321 @@
+<?php
+
+namespace Icinga\Module\Graphite\Graphing;
+
+use Icinga\Application\Config;
+use Icinga\Data\ConfigObject;
+use Icinga\Exception\ConfigurationError;
+use Icinga\Module\Graphite\Util\MacroTemplate;
+use Icinga\Web\UrlParams;
+use InvalidArgumentException;
+use RecursiveDirectoryIterator;
+use RecursiveIteratorIterator;
+use SplFileInfo;
+
+/**
+ * Templates collection
+ */
+class Templates
+{
+ /**
+ * All templates by their check command and name
+ *
+ * @var Template[][]
+ */
+ protected $templates = [];
+
+ /**
+ * All default templates by their name
+ *
+ * @var Template[]
+ */
+ protected $defaultTemplates = [];
+
+ /**
+ * Default URL params for all templates
+ *
+ * @var string[]
+ */
+ protected $defaultUrlParams = [];
+
+ /**
+ * Constructor
+ */
+ public function __construct()
+ {
+ $config = Config::module('graphite');
+
+ foreach ($config->getSection('default_url_params') as $param => $value) {
+ try {
+ $this->defaultUrlParams[$param] = new MacroTemplate($value);
+ } catch (InvalidArgumentException $e) {
+ throw new ConfigurationError(
+ 'Invalid URL parameter "%s" ("%s") in file "%s"',
+ $param,
+ $value,
+ $config->getConfigFile(),
+ $e
+ );
+ }
+ }
+ }
+
+ /**
+ * Load templates as configured inside the given directory
+ *
+ * @param string $path
+ *
+ * @return $this
+ *
+ * @throws ConfigurationError If the configuration is invalid
+ */
+ public function loadDir($path)
+ {
+ foreach (
+ new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator(
+ $path,
+ RecursiveDirectoryIterator::KEY_AS_PATHNAME | RecursiveDirectoryIterator::CURRENT_AS_FILEINFO
+ | RecursiveDirectoryIterator::SKIP_DOTS | RecursiveDirectoryIterator::FOLLOW_SYMLINKS
+ ),
+ RecursiveIteratorIterator::LEAVES_ONLY
+ ) as $filepath => $fileinfo
+ ) {
+ /** @var SplFileInfo $fileinfo */
+
+ if ($fileinfo->isFile() && preg_match('/\A[^.].*\.ini\z/si', $fileinfo->getFilename())) {
+ $this->loadIni($filepath);
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Load templates as configured in the given INI file
+ *
+ * @param string $path
+ *
+ * @return $this
+ *
+ * @throws ConfigurationError If the configuration is invalid
+ */
+ public function loadIni($path)
+ {
+ /** @var string[][][] $templates */
+ $templates = [];
+
+ foreach (Config::fromIni($path) as $section => $options) {
+ /** @var ConfigObject $options */
+
+ $matches = [];
+ if (! preg_match('/\A(.+)\.(graph|metrics_filters|urlparams|functions)\z/', $section, $matches)) {
+ throw new ConfigurationError('Bad section name "%s" in file "%s"', $section, $path);
+ }
+
+ $templates[$matches[1]][$matches[2]] = $options->toArray();
+ }
+
+ $checkCommands = [];
+
+ foreach ($templates as $templateName => $template) {
+ $checkCommands[$templateName] = isset($template['graph']['check_command'])
+ ? array_unique(preg_split('/\s*,\s*/', $template['graph']['check_command'], -1, PREG_SPLIT_NO_EMPTY))
+ : [];
+ unset($template['graph']['check_command']);
+
+ if (isset($template['graph'])) {
+ switch (count($template['graph'])) {
+ case 0:
+ break;
+
+ case 1:
+ throw new ConfigurationError(
+ 'Bad option for template "%s" in file "%s": "graph.%s"',
+ $templateName,
+ $path,
+ array_keys($template['graph'])[0]
+ );
+
+ default:
+ $standalone = array_keys($template['graph']);
+ sort($standalone);
+
+ throw new ConfigurationError(
+ 'Bad options for template "%s" in file "%s": %s',
+ $templateName,
+ $path,
+ implode(', ', array_map(
+ function ($option) {
+ return "\"graph.$option\"";
+ },
+ $standalone
+ ))
+ );
+ }
+ }
+
+ /** @var MacroTemplate[][] $curves */
+ $curves = [];
+
+ if (isset($template['metrics_filters'])) {
+ foreach ($template['metrics_filters'] as $curve => $metricsFilter) {
+ try {
+ $curves[$curve][0] = new MacroTemplate($metricsFilter);
+ } catch (InvalidArgumentException $e) {
+ throw new ConfigurationError(
+ 'Bad metrics filter "%s" for curve "%s" of template "%s" in file "%s": %s',
+ $metricsFilter,
+ $curve,
+ $templateName,
+ $path,
+ $e->getMessage()
+ );
+ }
+
+ if (
+ count(array_intersect(
+ $curves[$curve][0]->getMacros(),
+ ['host_name_template', 'service_name_template']
+ )) !== 1
+ ) {
+ throw new ConfigurationError(
+ 'Bad metrics filter "%s" for curve "%s" of template "%s" in file "%s": must include'
+ . ' either the macro $host_name_template$ or $service_name_template$, but not both',
+ $metricsFilter,
+ $curve,
+ $templateName,
+ $path
+ );
+ }
+
+ if (isset($template['functions'][$curve])) {
+ try {
+ $curves[$curve][1] = new MacroTemplate($template['functions'][$curve]);
+ } catch (InvalidArgumentException $e) {
+ throw new ConfigurationError(
+ 'Bad function "%s" for curve "%s" of template "%s" in file "%s": %s',
+ $template['functions'][$curve],
+ $curve,
+ $templateName,
+ $path,
+ $e->getMessage()
+ );
+ }
+
+ unset($template['functions'][$curve]);
+ } else {
+ $curves[$curve][1] = new MacroTemplate('$metric$');
+ }
+ }
+ }
+
+ if (isset($template['functions'])) {
+ switch (count($template['functions'])) {
+ case 0:
+ break;
+
+ case 1:
+ throw new ConfigurationError(
+ 'Metrics filter for curve "%s" of template "%s" in file "%s" missing',
+ array_keys($template['functions'])[0],
+ $templateName,
+ $path
+ );
+
+ default:
+ $standalone = array_keys($template['functions']);
+ sort($standalone);
+
+ throw new ConfigurationError(
+ 'Metrics filter for curves of template "%s" in file "%s" missing: "%s"',
+ $templateName,
+ $path,
+ implode('", "', $standalone)
+ );
+ }
+ }
+
+ $urlParams = $this->defaultUrlParams;
+
+ if (isset($template['urlparams'])) {
+ foreach ($template['urlparams'] as $key => $value) {
+ try {
+ $urlParams[$key] = new MacroTemplate($value);
+ } catch (InvalidArgumentException $e) {
+ throw new ConfigurationError(
+ 'Invalid URL parameter "%s" ("%s") for template "%s" in file "%s": %s',
+ $key,
+ $value,
+ $templateName,
+ $path,
+ $e->getMessage()
+ );
+ }
+ }
+ }
+
+ $templates[$templateName] = empty($curves) ? null : (new Template())
+ ->setCurves($curves)
+ ->setUrlParams($urlParams);
+ }
+
+ foreach ($templates as $templateName => $template) {
+ if ($template === null) {
+ if (empty($checkCommands[$templateName])) {
+ unset($this->defaultTemplates[$templateName]);
+ } else {
+ foreach ($checkCommands[$templateName] as $checkCommand) {
+ unset($this->templates[$checkCommand][$templateName]);
+
+ if (empty($this->templates[$checkCommand])) {
+ unset($this->templates[$checkCommand]);
+ }
+ }
+ }
+ } else {
+ if (empty($checkCommands[$templateName])) {
+ $this->defaultTemplates[$templateName] = $template;
+ } else {
+ foreach ($checkCommands[$templateName] as $checkCommand) {
+ $this->templates[$checkCommand][$templateName] = $template;
+ }
+ }
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get all loaded templates for the given check command by their names
+ *
+ * @param string $checkCommand
+ *
+ * @return Template[]
+ */
+ public function getTemplates($checkCommand)
+ {
+ return isset($this->templates[$checkCommand]) ? $this->templates[$checkCommand] : [];
+ }
+
+ /**
+ * Get all loaded templates for all check commands
+ *
+ * @return Template[][]
+ */
+ public function getAllTemplates()
+ {
+ return $this->templates;
+ }
+
+ /**
+ * Get all loaded default templates by their names
+ *
+ * @return Template[]
+ */
+ public function getDefaultTemplates()
+ {
+ return $this->defaultTemplates;
+ }
+}