summaryrefslogtreecommitdiffstats
path: root/application/clicommands/Icinga2Command.php
blob: e0e0ee4e8f29f723f71e5a4ee5e11af6e3d19cb7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
<?php

/* Icinga Web 2 | (c) 2018 Icinga Development Team | GPLv2+ */

namespace Icinga\Module\Graphite\Clicommands;

use Icinga\Cli\Command;
use Icinga\Module\Graphite\Graphing\GraphingTrait;
use Icinga\Module\Graphite\Graphing\Template;
use Icinga\Module\Graphite\Util\MacroTemplate;
use Icinga\Module\Graphite\Web\Widget\Graphs;

class Icinga2Command extends Command
{
    use GraphingTrait;

    /**
     * Generate Icinga 2 host and service config based on the present graph templates
     *
     * The generated (fictive) monitored objects' checks yield random perfdata to be
     * written to Graphite as expected by the present graph templates of this module.
     * The generated Icinga 2 config can be used to simulate graphs generated based
     * on the graph templates.
     *
     * icingacli graphite icinga2 config
     */
    public function configAction()
    {
        $icinga2CfgObjPrefix = 'IW2_graphite_demo';
        $obscuredCheckCommandCustomVar = Graphs::getObscuredCheckCommandCustomVar();

        $result = [
            <<<EOT
object CheckCommand "$icinga2CfgObjPrefix" {
    command = [ "/usr/bin/printf" ]
    arguments = {
        "%s" = {{
            var res = " |"
            for (label => max in macro("\$$icinga2CfgObjPrefix\$")) {
                res += " '" + label + "'=" + (random() % max) + ";" + (max * 0.8) + ";" + (max * 0.9) + ";0;" + max
            }
            res
        }}
    }
}
EOT
            ,
            <<<EOT
object HostGroup "$icinga2CfgObjPrefix" {
    assign where host.vars.$icinga2CfgObjPrefix
}
EOT
            ,
            <<<EOT
object ServiceGroup "$icinga2CfgObjPrefix" {
    assign where service.vars.$icinga2CfgObjPrefix
}
EOT
            ,
            <<<EOT
object Host "{$icinga2CfgObjPrefix}_doesntmatchanycheckcommand" {
    check_command = "$icinga2CfgObjPrefix"
    check_interval = 30s
    vars.$obscuredCheckCommandCustomVar = "doesntmatchanycheckcommand"
    vars.$icinga2CfgObjPrefix = {
        "dummy1" = 100
        "dummy2" = 100
        "dummy3" = 100
        "dummy4" = 100
    }
}
EOT
            ,
            <<<EOT
apply Service "{$icinga2CfgObjPrefix}_doesntmatchanycheckcommand" {
    assign where host.vars.$icinga2CfgObjPrefix
    check_command = "$icinga2CfgObjPrefix"
    check_interval = 30s
    vars.$obscuredCheckCommandCustomVar = "doesntmatchanycheckcommand"
    vars.$icinga2CfgObjPrefix = {
        "dummy1" = 100
        "dummy2" = 100
        "dummy3" = 100
        "dummy4" = 100
    }
}
EOT
        ];

        foreach (static::getAllTemplates()->getAllTemplates() as $checkCommand => $templates) {
            $perfdata = [];

            foreach ($templates as $templateName => $template) {
                /** @var Template $template */

                $urlParams = $template->getUrlParams();

                switch (isset($urlParams['yUnitSystem']) ? $urlParams['yUnitSystem']->resolve([]) : 'none') {
                    case 'si':
                    case 'binary':
                        $max = 42000000;
                        break;

                    case 'sec':
                    case 'msec':
                        $max = 82800;
                        break;

                    default:
                        $max = 100;
                }

                foreach ($template->getCurves() as $curveName => $curve) {
                    /** @var MacroTemplate $metricFilter */
                    $metricFilter = $curve[0];

                    $macros = array_flip($metricFilter->getMacros());
                    $service = isset($macros['service_name_template']);

                    foreach ($macros as & $macro) {
                        $macro = ['dummy1', 'dummy2', 'dummy3', 'dummy4'];
                    }

                    $macros['host_name_template'] = [''];
                    $macros['service_name_template'] = [''];

                    foreach ($this->cartesianProduct($macros) as $macroValues) {
                        if (
                            preg_match(
                                '/\A\.[^.]+\.(.+)\.[^.]+\z/',
                                $metricFilter->resolve($macroValues),
                                $match
                            )
                        ) {
                            $perfdata[$match[1]] = $max;
                        }
                    }
                }
            }

            assert(isset($service), '$service not initialized in the loop');

            $monObj = $service
                ? [
                    "apply Service \"{$icinga2CfgObjPrefix}_{$checkCommand}\" {",
                    "    assign where host.vars.$icinga2CfgObjPrefix"
                ]
                : ["object Host \"{$icinga2CfgObjPrefix}_{$checkCommand}\" {"];

            $monObj[] = "    check_command = \"$icinga2CfgObjPrefix\"";
            $monObj[] = '    check_interval = 30s';
            $monObj[] = "    vars.$obscuredCheckCommandCustomVar = \"$checkCommand\"";
            $monObj[] = "    vars.$icinga2CfgObjPrefix = {";

            foreach ($perfdata as $label => $max) {
                $monObj[] = "        \"$label\" = $max";
            }

            $monObj[] = '    }';
            $monObj[] = '}';

            $result[] = implode("\n", $monObj);
        }

        echo implode("\n\n", $result) . "\n";
    }

    /**
     * Generate the cartesian product of the given array
     *
     * [
     *   'a' => ['b', 'c'],
     *   'd' => ['e', 'f']
     * ]
     *
     * [
     *   ['a' => 'b', 'd' => 'e'],
     *   ['a' => 'b', 'd' => 'f'],
     *   ['a' => 'c', 'd' => 'e'],
     *   ['a' => 'c', 'd' => 'f']
     * ]
     *
     * @param   array[] $input
     *
     * @return  array[]
     */
    protected function cartesianProduct(array &$input)
    {
        $results = [[]];

        foreach ($input as $key => & $values) {
            $nextStep = [];

            foreach ($results as & $result) {
                foreach ($values as $value) {
                    $nextStep[] = array_merge($result, [$key => $value]);
                }
            }
            unset($result);

            $results = & $nextStep;
            unset($nextStep);
        }
        unset($values);

        return $results;
    }
}