Vagrant icinga / grafana
This commit is contained in:
parent
561c3ed9da
commit
b1611e2f78
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
*/__pycache__/
|
||||
check_patroni.egg-info
|
||||
test/*.state_file
|
||||
test/vagrant/.vagrant
|
||||
.*.swp
|
||||
|
|
29
test/vagrant/LICENSE
Normal file
29
test/vagrant/LICENSE
Normal file
|
@ -0,0 +1,29 @@
|
|||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2019, Jehan-Guillaume (ioguix) de Rorthais
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
22
test/vagrant/Makefile
Normal file
22
test/vagrant/Makefile
Normal file
|
@ -0,0 +1,22 @@
|
|||
export VAGRANT_BOX_UPDATE_CHECK_DISABLE=1
|
||||
export VAGRANT_CHECKPOINT_DISABLE=1
|
||||
|
||||
.PHONY: all prov validate
|
||||
|
||||
all: prov
|
||||
|
||||
prov:
|
||||
vagrant up --provision
|
||||
|
||||
clean:
|
||||
vagrant destroy -f
|
||||
|
||||
validate:
|
||||
@vagrant validate
|
||||
@if which shellcheck >/dev/null ;\
|
||||
then shellcheck provision/* ;\
|
||||
else echo "WARNING: shellcheck is not in PATH, not checking bash syntax" ;\
|
||||
fi
|
||||
|
||||
|
||||
|
127
test/vagrant/README.md
Normal file
127
test/vagrant/README.md
Normal file
|
@ -0,0 +1,127 @@
|
|||
# Icinga
|
||||
|
||||
## Install
|
||||
|
||||
Create the VM:
|
||||
|
||||
```
|
||||
make
|
||||
```
|
||||
|
||||
## IcingaWeb
|
||||
|
||||
Configure Icingaweb :
|
||||
|
||||
```
|
||||
http://$IP/icingaweb2/setup
|
||||
```
|
||||
|
||||
* Screen 1: Welcome
|
||||
|
||||
Use the icinga token given a the end of the `icinga2-setup` provision, or:
|
||||
|
||||
```
|
||||
sudo icingacli setup token show
|
||||
```
|
||||
|
||||
Next
|
||||
|
||||
* Screen 2: Modules
|
||||
|
||||
Activate Monitor (already set)
|
||||
|
||||
Next
|
||||
|
||||
* Screen 3: Icinga Web 2
|
||||
|
||||
Next
|
||||
|
||||
* Screen 4: Authentication
|
||||
|
||||
Next
|
||||
|
||||
* Screen 5: Database Resource
|
||||
|
||||
Database Name: icingaweb_db
|
||||
Username: supervisor
|
||||
Password: th3Pass
|
||||
Charset: UTF8
|
||||
|
||||
Validate
|
||||
Next
|
||||
|
||||
* Screen 6: Authentication Backend
|
||||
|
||||
Next
|
||||
|
||||
* Screen 7: Administration
|
||||
|
||||
Fill the blanks
|
||||
Next
|
||||
|
||||
* Screen 8: Application Configuration
|
||||
|
||||
Next
|
||||
|
||||
* Screen 9: Summary
|
||||
|
||||
Next
|
||||
|
||||
* Screen 10: Welcome ... again
|
||||
|
||||
Next
|
||||
|
||||
* Screen 11: Monitoring IDO Resource
|
||||
|
||||
Database Name: icinga2
|
||||
Username: supervisor
|
||||
Password: th3Pass
|
||||
Charset: UTF8
|
||||
|
||||
Validate
|
||||
Next
|
||||
|
||||
* Screen 12: Command Transport
|
||||
|
||||
Transaport name: icinga2
|
||||
Transport Type: API
|
||||
Host: 127.0.0.1
|
||||
Port: 5665
|
||||
User: icinga_api
|
||||
Password: th3Pass
|
||||
|
||||
Next
|
||||
|
||||
* Screen 13: Monitoring Security
|
||||
|
||||
Next
|
||||
|
||||
* Screen 14: Summary
|
||||
|
||||
Finish
|
||||
|
||||
* Screen 15: Hopefuly success
|
||||
|
||||
Login
|
||||
|
||||
## Add servers to icinga
|
||||
|
||||
```
|
||||
# Connect to the vm
|
||||
vagrant ssh s1
|
||||
|
||||
# Create /etc/icinga2/conf.d/check_patroni.conf
|
||||
sudo /vagrant/provision/director.bash init cluster1 p1=10.20.89.54 p2=10.20.89.55
|
||||
|
||||
# Check and load conf
|
||||
sudo icinga2 daemon -C
|
||||
sudo systemctl restart icinga2.service
|
||||
```
|
||||
|
||||
# Grafana
|
||||
|
||||
Connect to: http://10.20.89.52:3000/login
|
||||
User / pass: admin/admin
|
||||
|
||||
Import the dashboards for the grafana directory. They are created for cluster1,
|
||||
and servers p1, p2.
|
62
test/vagrant/Vagrantfile
vendored
Normal file
62
test/vagrant/Vagrantfile
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
require 'ipaddr'
|
||||
#require 'yaml'
|
||||
|
||||
ENV["LC_ALL"] = 'en_US.utf8'
|
||||
|
||||
myBox = 'debian/buster64'
|
||||
myProvider = 'libvirt'
|
||||
|
||||
pgver = 11
|
||||
start_ip = '10.20.89.51'
|
||||
etcd_nodes = []
|
||||
patroni_nodes = []
|
||||
sup_nodes = ['s1']
|
||||
|
||||
Vagrant.configure(2) do |config|
|
||||
config.vm.provider myProvider
|
||||
|
||||
next_ip = IPAddr.new(start_ip).succ
|
||||
host_ip = (IPAddr.new(start_ip) & "255.255.255.0").succ.to_s
|
||||
nodes_ips = {}
|
||||
|
||||
( patroni_nodes + etcd_nodes + sup_nodes ).each do |node|
|
||||
nodes_ips[node] = next_ip.to_s
|
||||
next_ip = next_ip.succ
|
||||
end
|
||||
|
||||
# don't mind about insecure ssh key
|
||||
config.ssh.insert_key = false
|
||||
|
||||
# https://vagrantcloud.com/search.
|
||||
config.vm.box = myBox
|
||||
|
||||
# hardware and host settings
|
||||
config.vm.provider 'libvirt' do |lv|
|
||||
lv.cpus = 1
|
||||
lv.memory = 512
|
||||
lv.watchdog model: 'i6300esb'
|
||||
lv.default_prefix = 'patroni_'
|
||||
lv.qemu_use_session = false
|
||||
end
|
||||
|
||||
# disable default share (NFS is not working directly in DEBIAN 10)
|
||||
config.vm.synced_folder ".", "/vagrant", type: "rsync"
|
||||
config.vm.synced_folder "/home/benoit/git/dalibo/check_patroni", "/check_patroni", type: "rsync"
|
||||
|
||||
## allow root@vm to ssh to ssh_login@network_1
|
||||
#config.vm.synced_folder 'ssh', '/root/.ssh', type: 'rsync',
|
||||
# owner: 'root', group: 'root',
|
||||
# rsync__args: [ "--verbose", "--archive", "--delete", "--copy-links", "--no-perms" ]
|
||||
|
||||
# system setup for sup nodes
|
||||
(sup_nodes).each do |node|
|
||||
config.vm.define node do |conf|
|
||||
conf.vm.network 'private_network', ip: nodes_ips[node]
|
||||
conf.vm.provision 'icinga2-setup', type: 'shell', path: 'provision/icinga2.bash',
|
||||
args: [ node ],
|
||||
preserve_order: true
|
||||
conf.vm.provision 'check_patroni', type: 'shell', path: 'provision/check_patroni.bash',
|
||||
preserve_order: true
|
||||
end
|
||||
end
|
||||
end
|
793
test/vagrant/grafana/cluster_status_cluster1.json
Normal file
793
test/vagrant/grafana/cluster_status_cluster1.json
Normal file
|
@ -0,0 +1,793 @@
|
|||
{
|
||||
"__inputs": [
|
||||
{
|
||||
"name": "DS_OPM",
|
||||
"label": "opm",
|
||||
"description": "",
|
||||
"type": "datasource",
|
||||
"pluginId": "postgres",
|
||||
"pluginName": "PostgreSQL"
|
||||
},
|
||||
{
|
||||
"name": "VAR_CLUSTER_NAME",
|
||||
"type": "constant",
|
||||
"label": "cluster_name",
|
||||
"value": "cluster1",
|
||||
"description": ""
|
||||
}
|
||||
],
|
||||
"__elements": [],
|
||||
"__requires": [
|
||||
{
|
||||
"type": "grafana",
|
||||
"id": "grafana",
|
||||
"name": "Grafana",
|
||||
"version": "8.3.3"
|
||||
},
|
||||
{
|
||||
"type": "datasource",
|
||||
"id": "postgres",
|
||||
"name": "PostgreSQL",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"type": "panel",
|
||||
"id": "stat",
|
||||
"name": "Stat",
|
||||
"version": ""
|
||||
},
|
||||
{
|
||||
"type": "panel",
|
||||
"id": "timeseries",
|
||||
"name": "Time series",
|
||||
"version": ""
|
||||
}
|
||||
],
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": "-- Grafana --",
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"target": {
|
||||
"limit": 100,
|
||||
"matchAny": false,
|
||||
"tags": [],
|
||||
"type": "dashboard"
|
||||
},
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"id": null,
|
||||
"iteration": 1640960519458,
|
||||
"links": [],
|
||||
"liveNow": false,
|
||||
"panels": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 10,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "never",
|
||||
"spanNulls": true,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 6,
|
||||
"w": 20,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 14,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
"placement": "bottom"
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "8.3.3",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM wh_nagios.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id FROM wh_nagios.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$cluster_name' AND s.service = 'check_patroni_cluster_has_replica'\n ) \n AND m.label ilike '%lag%' \nGROUP BY time, m.label ORDER BY time",
|
||||
"refId": "A",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"title": "Cluster replica lag",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 2,
|
||||
"w": 4,
|
||||
"x": 20,
|
||||
"y": 0
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"colorMode": "value",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "auto"
|
||||
},
|
||||
"pluginVersion": "8.3.3",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM wh_nagios.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id FROM wh_nagios.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$cluster_name' AND s.service = 'check_patroni_cluster_has_leader'\n ) GROUP BY time, m.label ORDER BY time",
|
||||
"refId": "A",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"title": "Cluster has primary",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 2,
|
||||
"w": 4,
|
||||
"x": 20,
|
||||
"y": 2
|
||||
},
|
||||
"id": 10,
|
||||
"options": {
|
||||
"colorMode": "value",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "auto"
|
||||
},
|
||||
"pluginVersion": "8.3.3",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM wh_nagios.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id FROM wh_nagios.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$cluster_name' AND s.service = 'check_patroni_cluster_config_has_changed'\n ) GROUP BY time, m.label ORDER BY time",
|
||||
"refId": "A",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"title": "Cluster config has changed",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 2,
|
||||
"w": 4,
|
||||
"x": 20,
|
||||
"y": 4
|
||||
},
|
||||
"id": 8,
|
||||
"options": {
|
||||
"colorMode": "value",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "auto"
|
||||
},
|
||||
"pluginVersion": "8.3.3",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM wh_nagios.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id FROM wh_nagios.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$cluster_name' AND s.service = 'check_patroni_cluster_is_in_maintenance'\n ) GROUP BY time, m.label ORDER BY time",
|
||||
"refId": "A",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"title": "Cluster is in maintenance",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "role_leader"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "displayName",
|
||||
"value": "leader"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "role_replica"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "displayName",
|
||||
"value": "replicas"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "state_running"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "displayName",
|
||||
"value": "running"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 5,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 6
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"colorMode": "value",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "center",
|
||||
"orientation": "vertical",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "auto"
|
||||
},
|
||||
"pluginVersion": "8.3.3",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM public.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id \n FROM public.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$cluster_name' AND s.service = 'check_patroni_cluster_node_count'\n ) GROUP BY time, m.label ORDER BY time",
|
||||
"refId": "A",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"title": "Cluster node count",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic"
|
||||
},
|
||||
"custom": {
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 10,
|
||||
"gradientMode": "none",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"lineInterpolation": "linear",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "never",
|
||||
"spanNulls": true,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "short"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "healthy_replica"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "displayName",
|
||||
"value": "healthy"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "unhealthy_replica"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "displayName",
|
||||
"value": "unhealthy"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 5,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 6
|
||||
},
|
||||
"id": 6,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [],
|
||||
"displayMode": "list",
|
||||
"placement": "bottom"
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "single"
|
||||
}
|
||||
},
|
||||
"pluginVersion": "8.3.3",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM public.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id \n FROM public.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$cluster_name' AND s.service = 'check_patroni_cluster_has_replica'\n )\n AND m.label IN('healthy_replica','unhealthy_replica') \n GROUP BY time, m.label ORDER BY time",
|
||||
"refId": "A",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"title": "Cluster has replica",
|
||||
"type": "timeseries"
|
||||
}
|
||||
],
|
||||
"refresh": "",
|
||||
"schemaVersion": 34,
|
||||
"style": "dark",
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"hide": 2,
|
||||
"name": "cluster_name",
|
||||
"query": "${VAR_CLUSTER_NAME}",
|
||||
"skipUrlSync": false,
|
||||
"type": "constant",
|
||||
"current": {
|
||||
"value": "${VAR_CLUSTER_NAME}",
|
||||
"text": "${VAR_CLUSTER_NAME}",
|
||||
"selected": false
|
||||
},
|
||||
"options": [
|
||||
{
|
||||
"value": "${VAR_CLUSTER_NAME}",
|
||||
"text": "${VAR_CLUSTER_NAME}",
|
||||
"selected": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"auto": false,
|
||||
"auto_count": 30,
|
||||
"auto_min": "10s",
|
||||
"current": {
|
||||
"selected": true,
|
||||
"text": "1m",
|
||||
"value": "1m"
|
||||
},
|
||||
"hide": 0,
|
||||
"name": "interval",
|
||||
"options": [
|
||||
{
|
||||
"selected": true,
|
||||
"text": "1m",
|
||||
"value": "1m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "10m",
|
||||
"value": "10m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "30m",
|
||||
"value": "30m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "1h",
|
||||
"value": "1h"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "6h",
|
||||
"value": "6h"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "12h",
|
||||
"value": "12h"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "1d",
|
||||
"value": "1d"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "7d",
|
||||
"value": "7d"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "14d",
|
||||
"value": "14d"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "30d",
|
||||
"value": "30d"
|
||||
}
|
||||
],
|
||||
"query": "1m,10m,30m,1h,6h,12h,1d,7d,14d,30d",
|
||||
"queryValue": "",
|
||||
"refresh": 2,
|
||||
"skipUrlSync": false,
|
||||
"type": "interval"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "Cluster status: cluster1",
|
||||
"uid": "4BullO0nk",
|
||||
"version": 10,
|
||||
"weekStart": ""
|
||||
}
|
496
test/vagrant/grafana/node_status_p1.json
Normal file
496
test/vagrant/grafana/node_status_p1.json
Normal file
|
@ -0,0 +1,496 @@
|
|||
{
|
||||
"__inputs": [
|
||||
{
|
||||
"name": "DS_OPM",
|
||||
"label": "opm",
|
||||
"description": "",
|
||||
"type": "datasource",
|
||||
"pluginId": "postgres",
|
||||
"pluginName": "PostgreSQL"
|
||||
},
|
||||
{
|
||||
"name": "VAR_NODE_NAME",
|
||||
"type": "constant",
|
||||
"label": "node_name",
|
||||
"value": "p1",
|
||||
"description": ""
|
||||
}
|
||||
],
|
||||
"__elements": [],
|
||||
"__requires": [
|
||||
{
|
||||
"type": "grafana",
|
||||
"id": "grafana",
|
||||
"name": "Grafana",
|
||||
"version": "8.3.3"
|
||||
},
|
||||
{
|
||||
"type": "datasource",
|
||||
"id": "postgres",
|
||||
"name": "PostgreSQL",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"type": "panel",
|
||||
"id": "stat",
|
||||
"name": "Stat",
|
||||
"version": ""
|
||||
}
|
||||
],
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": "-- Grafana --",
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"target": {
|
||||
"limit": 100,
|
||||
"matchAny": false,
|
||||
"tags": [],
|
||||
"type": "dashboard"
|
||||
},
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"id": null,
|
||||
"iteration": 1640961009033,
|
||||
"links": [],
|
||||
"liveNow": false,
|
||||
"panels": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "is_primary"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "displayName",
|
||||
"value": "Primaire"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "is_replica"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "displayName",
|
||||
"value": "Secondaire"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"colorMode": "value",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "auto"
|
||||
},
|
||||
"pluginVersion": "8.3.3",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM wh_nagios.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id FROM wh_nagios.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$node_name' AND s.service = 'check_patroni_node_is_primary'\n ) GROUP BY time, m.label ORDER BY time",
|
||||
"refId": "A",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"hide": false,
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM wh_nagios.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id FROM wh_nagios.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$node_name' AND s.service = 'check_patroni_node_is_replica'\n ) GROUP BY time, m.label ORDER BY time",
|
||||
"refId": "B",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"title": "Node type",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "is_alive"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "displayName",
|
||||
"value": "Node is alive"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "is_pending_restart"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "displayName",
|
||||
"value": "Node is pending restart"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "timeline"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "displayName",
|
||||
"value": "Current timeline"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"colorMode": "value",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "horizontal",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "auto"
|
||||
},
|
||||
"pluginVersion": "8.3.3",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM wh_nagios.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id FROM wh_nagios.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$node_name' AND s.service = 'check_patroni_node_is_alive'\n ) GROUP BY time, m.label ORDER BY time",
|
||||
"refId": "A",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"hide": false,
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM wh_nagios.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id FROM wh_nagios.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$node_name' AND s.service = 'check_patroni_node_tl_has_changed'\n )\nAND m.label = 'timeline'\nGROUP BY time, m.label ORDER BY time",
|
||||
"refId": "B",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"hide": false,
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM wh_nagios.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id FROM wh_nagios.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$node_name' AND s.service = 'check_patroni_node_is_pending_restart'\n ) GROUP BY time, m.label ORDER BY time",
|
||||
"refId": "D",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"title": "Health stats",
|
||||
"type": "stat"
|
||||
}
|
||||
],
|
||||
"schemaVersion": 34,
|
||||
"style": "dark",
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"hide": 2,
|
||||
"name": "node_name",
|
||||
"query": "${VAR_NODE_NAME}",
|
||||
"skipUrlSync": false,
|
||||
"type": "constant",
|
||||
"current": {
|
||||
"value": "${VAR_NODE_NAME}",
|
||||
"text": "${VAR_NODE_NAME}",
|
||||
"selected": false
|
||||
},
|
||||
"options": [
|
||||
{
|
||||
"value": "${VAR_NODE_NAME}",
|
||||
"text": "${VAR_NODE_NAME}",
|
||||
"selected": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"auto": false,
|
||||
"auto_count": 30,
|
||||
"auto_min": "10s",
|
||||
"current": {
|
||||
"selected": false,
|
||||
"text": "1m",
|
||||
"value": "1m"
|
||||
},
|
||||
"hide": 0,
|
||||
"name": "interval",
|
||||
"options": [
|
||||
{
|
||||
"selected": true,
|
||||
"text": "1m",
|
||||
"value": "1m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "10m",
|
||||
"value": "10m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "30m",
|
||||
"value": "30m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "1h",
|
||||
"value": "1h"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "6h",
|
||||
"value": "6h"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "12h",
|
||||
"value": "12h"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "1d",
|
||||
"value": "1d"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "7d",
|
||||
"value": "7d"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "14d",
|
||||
"value": "14d"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "30d",
|
||||
"value": "30d"
|
||||
}
|
||||
],
|
||||
"query": "1m,10m,30m,1h,6h,12h,1d,7d,14d,30d",
|
||||
"queryValue": "",
|
||||
"refresh": 2,
|
||||
"skipUrlSync": false,
|
||||
"type": "interval"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "Node status: p1",
|
||||
"uid": "2LfUnFAnk",
|
||||
"version": 1,
|
||||
"weekStart": ""
|
||||
}
|
496
test/vagrant/grafana/node_status_p2.json
Normal file
496
test/vagrant/grafana/node_status_p2.json
Normal file
|
@ -0,0 +1,496 @@
|
|||
{
|
||||
"__inputs": [
|
||||
{
|
||||
"name": "DS_OPM",
|
||||
"label": "opm",
|
||||
"description": "",
|
||||
"type": "datasource",
|
||||
"pluginId": "postgres",
|
||||
"pluginName": "PostgreSQL"
|
||||
},
|
||||
{
|
||||
"name": "VAR_NODE_NAME",
|
||||
"type": "constant",
|
||||
"label": "node_name",
|
||||
"value": "p2",
|
||||
"description": ""
|
||||
}
|
||||
],
|
||||
"__elements": [],
|
||||
"__requires": [
|
||||
{
|
||||
"type": "grafana",
|
||||
"id": "grafana",
|
||||
"name": "Grafana",
|
||||
"version": "8.3.3"
|
||||
},
|
||||
{
|
||||
"type": "datasource",
|
||||
"id": "postgres",
|
||||
"name": "PostgreSQL",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"type": "panel",
|
||||
"id": "stat",
|
||||
"name": "Stat",
|
||||
"version": ""
|
||||
}
|
||||
],
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": "-- Grafana --",
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"target": {
|
||||
"limit": 100,
|
||||
"matchAny": false,
|
||||
"tags": [],
|
||||
"type": "dashboard"
|
||||
},
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"id": null,
|
||||
"iteration": 1640960994907,
|
||||
"links": [],
|
||||
"liveNow": false,
|
||||
"panels": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "is_primary"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "displayName",
|
||||
"value": "Primaire"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "is_replica"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "displayName",
|
||||
"value": "Secondaire"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
"colorMode": "value",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "auto"
|
||||
},
|
||||
"pluginVersion": "8.3.3",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM wh_nagios.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id FROM wh_nagios.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$node_name' AND s.service = 'check_patroni_node_is_primary'\n ) GROUP BY time, m.label ORDER BY time",
|
||||
"refId": "A",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"hide": false,
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM wh_nagios.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id FROM wh_nagios.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$node_name' AND s.service = 'check_patroni_node_is_replica'\n ) GROUP BY time, m.label ORDER BY time",
|
||||
"refId": "B",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"title": "Node type",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "is_alive"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "displayName",
|
||||
"value": "Node is alive"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "is_pending_restart"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "displayName",
|
||||
"value": "Node is pending restart"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "timeline"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "displayName",
|
||||
"value": "Current timeline"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
"colorMode": "value",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "horizontal",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"lastNotNull"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "auto"
|
||||
},
|
||||
"pluginVersion": "8.3.3",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM wh_nagios.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id FROM wh_nagios.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$node_name' AND s.service = 'check_patroni_node_is_alive'\n ) GROUP BY time, m.label ORDER BY time",
|
||||
"refId": "A",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"hide": false,
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM wh_nagios.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id FROM wh_nagios.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$node_name' AND s.service = 'check_patroni_node_tl_has_changed'\n )\nAND m.label = 'timeline'\nGROUP BY time, m.label ORDER BY time",
|
||||
"refId": "B",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "postgres",
|
||||
"uid": "${DS_OPM}"
|
||||
},
|
||||
"format": "time_series",
|
||||
"group": [],
|
||||
"hide": false,
|
||||
"metricColumn": "none",
|
||||
"rawQuery": true,
|
||||
"rawSql": " SELECT $__timeGroup(timet, $interval) AS time, MAX(d.value), m.label AS metric\n FROM wh_nagios.metrics m,\nLATERAL wh_nagios.get_metric_data(m.id, $__timeFrom(), $__timeTo()) d\n WHERE m.id_service = (\n SELECT s.id FROM wh_nagios.services s \n JOIN public.servers h ON h.id=s.id_server\n WHERE h.hostname = '$node_name' AND s.service = 'check_patroni_node_is_pending_restart'\n ) GROUP BY time, m.label ORDER BY time",
|
||||
"refId": "D",
|
||||
"select": [
|
||||
[
|
||||
{
|
||||
"params": [
|
||||
"value"
|
||||
],
|
||||
"type": "column"
|
||||
}
|
||||
]
|
||||
],
|
||||
"timeColumn": "time",
|
||||
"where": [
|
||||
{
|
||||
"name": "$__timeFilter",
|
||||
"params": [],
|
||||
"type": "macro"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"title": "Health stats",
|
||||
"type": "stat"
|
||||
}
|
||||
],
|
||||
"schemaVersion": 34,
|
||||
"style": "dark",
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"hide": 2,
|
||||
"name": "node_name",
|
||||
"query": "${VAR_NODE_NAME}",
|
||||
"skipUrlSync": false,
|
||||
"type": "constant",
|
||||
"current": {
|
||||
"value": "${VAR_NODE_NAME}",
|
||||
"text": "${VAR_NODE_NAME}",
|
||||
"selected": false
|
||||
},
|
||||
"options": [
|
||||
{
|
||||
"value": "${VAR_NODE_NAME}",
|
||||
"text": "${VAR_NODE_NAME}",
|
||||
"selected": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"auto": false,
|
||||
"auto_count": 30,
|
||||
"auto_min": "10s",
|
||||
"current": {
|
||||
"selected": false,
|
||||
"text": "1m",
|
||||
"value": "1m"
|
||||
},
|
||||
"hide": 0,
|
||||
"name": "interval",
|
||||
"options": [
|
||||
{
|
||||
"selected": true,
|
||||
"text": "1m",
|
||||
"value": "1m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "10m",
|
||||
"value": "10m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "30m",
|
||||
"value": "30m"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "1h",
|
||||
"value": "1h"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "6h",
|
||||
"value": "6h"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "12h",
|
||||
"value": "12h"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "1d",
|
||||
"value": "1d"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "7d",
|
||||
"value": "7d"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "14d",
|
||||
"value": "14d"
|
||||
},
|
||||
{
|
||||
"selected": false,
|
||||
"text": "30d",
|
||||
"value": "30d"
|
||||
}
|
||||
],
|
||||
"query": "1m,10m,30m,1h,6h,12h,1d,7d,14d,30d",
|
||||
"queryValue": "",
|
||||
"refresh": 2,
|
||||
"skipUrlSync": false,
|
||||
"type": "interval"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "Node status: p2",
|
||||
"uid": "2LfUnFAnkr",
|
||||
"version": 1,
|
||||
"weekStart": ""
|
||||
}
|
22
test/vagrant/provision/check_patroni.bash
Executable file
22
test/vagrant/provision/check_patroni.bash
Executable file
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
info (){
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
info "#============================================================================="
|
||||
info "# check_patroni"
|
||||
info "#============================================================================="
|
||||
|
||||
DEBIAN_FRONTEND=noninteractive apt install -q -y git python3-pip
|
||||
pip3 install --upgrade pip
|
||||
|
||||
cd /check_patroni
|
||||
pip3 install .
|
||||
ln -s /usr/local/bin/check_patroni /usr/lib/nagios/plugins/check_patroni
|
||||
|
||||
check_patroni --version
|
392
test/vagrant/provision/director.bash
Executable file
392
test/vagrant/provision/director.bash
Executable file
|
@ -0,0 +1,392 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
info(){
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
usage(){
|
||||
echo "$0 ACTION CLUSTER_NAME [NODE..]"
|
||||
echo ""
|
||||
echo " ACTION: init | add"
|
||||
echo " CLUSTER: cluster name"
|
||||
echo " NODE: HOST=IP"
|
||||
echo " HOST: any name for icinga"
|
||||
echo " IP: the IP"
|
||||
}
|
||||
|
||||
if [ "$#" -le "3" ]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ACTION="$1"
|
||||
shift
|
||||
CLUSTER="$1"
|
||||
shift
|
||||
NODES=( "$@" )
|
||||
|
||||
TARGET="/etc/icinga2/conf.d/check_patroni.conf"
|
||||
|
||||
#set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
init(){
|
||||
cat << '__EOF__' > "$TARGET"
|
||||
# ===================================================================
|
||||
# Check Commands
|
||||
# ===================================================================
|
||||
template CheckCommand "check_patroni" {
|
||||
command = [ PluginDir + "/check_patroni" ]
|
||||
|
||||
arguments = {
|
||||
"--endpoints" = {
|
||||
value = "$endpoints$"
|
||||
order = -2
|
||||
repeat_key = true
|
||||
}
|
||||
"--timeout" = {
|
||||
value = "$timeout$"
|
||||
order = -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object CheckCommand "check_patroni_node_is_alive" {
|
||||
import "check_patroni"
|
||||
|
||||
arguments += {
|
||||
"node_is_alive" = {
|
||||
order = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object CheckCommand "check_patroni_node_is_primary" {
|
||||
import "check_patroni"
|
||||
|
||||
arguments += {
|
||||
"node_is_primary" = {
|
||||
order = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object CheckCommand "check_patroni_node_is_replica" {
|
||||
import "check_patroni"
|
||||
|
||||
arguments += {
|
||||
"node_is_replica" = {
|
||||
order = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object CheckCommand "check_patroni_node_is_pending_restart" {
|
||||
import "check_patroni"
|
||||
|
||||
arguments += {
|
||||
"node_is_pending_restart" = {
|
||||
order = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object CheckCommand "check_patroni_node_patroni_version" {
|
||||
import "check_patroni"
|
||||
|
||||
arguments += {
|
||||
"node_patroni_version" = {
|
||||
order = 1
|
||||
}
|
||||
"--patroni-version" = {
|
||||
value = "$patroni_version$"
|
||||
order = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object CheckCommand "check_patroni_node_tl_has_changed" {
|
||||
import "check_patroni"
|
||||
|
||||
arguments += {
|
||||
"node_tl_has_changed" = {
|
||||
order = 1
|
||||
}
|
||||
"--state-file" = {
|
||||
value = "/tmp/$state_file$" # a quick and dirty way for this poc
|
||||
order = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
object CheckCommand "check_patroni_cluster_has_leader" {
|
||||
import "check_patroni"
|
||||
|
||||
arguments += {
|
||||
"cluster_has_leader" = {
|
||||
order = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object CheckCommand "check_patroni_cluster_has_replica" {
|
||||
import "check_patroni"
|
||||
|
||||
arguments += {
|
||||
"cluster_has_replica" = {
|
||||
order = 1
|
||||
}
|
||||
"--warning" = {
|
||||
value = "$has_replica_warning$"
|
||||
order = 2
|
||||
}
|
||||
"--critical" = {
|
||||
value = "$has_replica_critical$"
|
||||
order = 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object CheckCommand "check_patroni_cluster_config_has_changed" {
|
||||
import "check_patroni"
|
||||
|
||||
arguments += {
|
||||
"cluster_config_has_changed" = {
|
||||
order = 1
|
||||
}
|
||||
"--state-file" = {
|
||||
value = "/tmp/$state_file$" # a quick and dirty way for this poc
|
||||
order = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object CheckCommand "check_patroni_cluster_is_in_maintenance" {
|
||||
import "check_patroni"
|
||||
|
||||
arguments += {
|
||||
"cluster_is_in_maintenance" = {
|
||||
order = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object CheckCommand "check_patroni_cluster_node_count" {
|
||||
import "check_patroni"
|
||||
|
||||
arguments += {
|
||||
"cluster_node_count" = {
|
||||
order = 1
|
||||
}
|
||||
"--warning" = {
|
||||
value = "$node_count_warning$"
|
||||
order = 2
|
||||
}
|
||||
"--critical" = {
|
||||
value = "$node_count_critical$"
|
||||
order = 3
|
||||
}
|
||||
"--running-warning" = {
|
||||
value = "$node_count_running_warning$"
|
||||
order = 4
|
||||
}
|
||||
"--running-critical" = {
|
||||
value = "$node_count_running_critical$"
|
||||
order = 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ===================================================================
|
||||
# Services
|
||||
# ===================================================================
|
||||
template Service "check_patroni" {
|
||||
max_check_attempts = 3
|
||||
check_interval = 1m # we spam a little for the sake of testing
|
||||
retry_interval = 15 # we spam a little for the sake of testing
|
||||
enable_perfdata = true
|
||||
vars.timeout = 10
|
||||
}
|
||||
|
||||
apply Service "check_patroni_node_is_alive" {
|
||||
import "check_patroni"
|
||||
check_command = "check_patroni_node_is_alive"
|
||||
|
||||
assign where "patroni_servers" in host.groups
|
||||
}
|
||||
|
||||
apply Service "check_patroni_node_is_primary" {
|
||||
import "check_patroni"
|
||||
check_command = "check_patroni_node_is_primary"
|
||||
|
||||
assign where "patroni_servers" in host.groups
|
||||
}
|
||||
|
||||
apply Service "check_patroni_node_is_replica" {
|
||||
import "check_patroni"
|
||||
check_command = "check_patroni_node_is_replica"
|
||||
|
||||
assign where "patroni_servers" in host.groups
|
||||
}
|
||||
|
||||
apply Service "check_patroni_node_is_pending_restart" {
|
||||
import "check_patroni"
|
||||
check_command = "check_patroni_node_is_pending_restart"
|
||||
|
||||
assign where "patroni_servers" in host.groups
|
||||
}
|
||||
|
||||
apply Service "check_patroni_node_patroni_version" {
|
||||
import "check_patroni"
|
||||
check_command = "check_patroni_node_patroni_version"
|
||||
|
||||
assign where "patroni_servers" in host.groups
|
||||
}
|
||||
|
||||
apply Service "check_patroni_node_tl_has_changed" {
|
||||
import "check_patroni"
|
||||
vars.state_file = host.name + ".state"
|
||||
check_command = "check_patroni_node_tl_has_changed"
|
||||
|
||||
assign where "patroni_servers" in host.groups
|
||||
}
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
apply Service "check_patroni_cluster_has_leader" {
|
||||
import "check_patroni"
|
||||
check_command = "check_patroni_cluster_has_leader"
|
||||
|
||||
assign where "patroni_clusters" in host.groups
|
||||
}
|
||||
|
||||
apply Service "check_patroni_cluster_has_replica" {
|
||||
import "check_patroni"
|
||||
check_command = "check_patroni_cluster_has_replica"
|
||||
|
||||
assign where "patroni_clusters" in host.groups
|
||||
}
|
||||
|
||||
apply Service "check_patroni_cluster_config_has_changed" {
|
||||
import "check_patroni"
|
||||
vars.state_file = host.name + ".state"
|
||||
check_command = "check_patroni_cluster_config_has_changed"
|
||||
|
||||
assign where "patroni_clusters" in host.groups
|
||||
}
|
||||
|
||||
apply Service "check_patroni_cluster_is_in_maintenance" {
|
||||
import "check_patroni"
|
||||
check_command = "check_patroni_cluster_is_in_maintenance"
|
||||
|
||||
assign where "patroni_clusters" in host.groups
|
||||
}
|
||||
|
||||
apply Service "check_patroni_cluster_node_count" {
|
||||
import "check_patroni"
|
||||
check_command = "check_patroni_cluster_node_count"
|
||||
|
||||
assign where "patroni_clusters" in host.groups
|
||||
}
|
||||
|
||||
# ===================================================================
|
||||
# Hosts meta
|
||||
# ===================================================================
|
||||
object HostGroup "patroni_servers" {
|
||||
display_name = "patroni servers"
|
||||
}
|
||||
|
||||
template Host "patroni_servers" {
|
||||
groups = [ "patroni_servers" ]
|
||||
check_command = "hostalive"
|
||||
|
||||
vars.patroni_version = "2.1.2"
|
||||
}
|
||||
|
||||
# -------------------------------------------------------------------
|
||||
|
||||
object HostGroup "patroni_clusters" {
|
||||
display_name = "patroni clusters"
|
||||
}
|
||||
|
||||
template Host "patroni_clusters" {
|
||||
groups = [ "patroni_clusters" ]
|
||||
check_command = "dummy"
|
||||
}
|
||||
|
||||
# ===================================================================
|
||||
# Hosts meta
|
||||
# ===================================================================
|
||||
__EOF__
|
||||
}
|
||||
|
||||
add_hosts(){
|
||||
NODES=$@
|
||||
for N in "${NODES[@]}"; do
|
||||
IP="${N##*=}"
|
||||
HOST="${N%=*}"
|
||||
|
||||
cat << __EOF__ >> "$TARGET"
|
||||
|
||||
object Host "$HOST" {
|
||||
import "patroni_servers"
|
||||
|
||||
display_name = "Server patroni $HOST"
|
||||
address = "$IP"
|
||||
|
||||
vars.endpoints = [ "http://" + address + ":8008" ]
|
||||
}
|
||||
__EOF__
|
||||
done
|
||||
}
|
||||
|
||||
add_cluster(){
|
||||
CLUSTER=$1
|
||||
NODES=$2
|
||||
|
||||
NAME=""
|
||||
IPS=" "
|
||||
for N in "${NODES[@]}"; do
|
||||
IP="${N##*=}"
|
||||
HOST="${N%=*}"
|
||||
|
||||
NAME="$NAME $HOST"
|
||||
IPS="$IPS\"http://${IP}:8008\", "
|
||||
done
|
||||
|
||||
cat << __EOF__ >> "$TARGET"
|
||||
|
||||
object Host "$CLUSTER" {
|
||||
import "patroni_clusters"
|
||||
|
||||
display_name = "Cluster: $CLUSTER ($NAME )"
|
||||
|
||||
vars.endpoints = [$IPS ]
|
||||
vars.has_replica_warning = "1:"
|
||||
vars.has_replica_critical = "1:"
|
||||
vars.node_count_warning = "2:"
|
||||
vars.node_count_critical = "1:"
|
||||
vars.node_count_running_warning = "2:"
|
||||
vars.node_count_running_critical = "1:"
|
||||
}
|
||||
__EOF__
|
||||
}
|
||||
|
||||
case "$ACTION" in
|
||||
"init")
|
||||
init
|
||||
add_hosts "$NODES"
|
||||
add_cluster "$CLUSTER" "$NODES"
|
||||
;;
|
||||
"add")
|
||||
add_hosts "$NODES"
|
||||
add_cluster "$CLUSTER" "$NODES"
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
echo "error: invalid action"
|
||||
exit 1
|
||||
esac
|
347
test/vagrant/provision/icinga2.bash
Executable file
347
test/vagrant/provision/icinga2.bash
Executable file
|
@ -0,0 +1,347 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
info (){
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
#set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
NODENAME="$1"
|
||||
shift
|
||||
|
||||
PG_ICINGA_USER_NAME="supervisor"
|
||||
PG_ICINGA_USER_PWD="th3Pass"
|
||||
PG_ICINGAWEB_USER_NAME="supervisor"
|
||||
PG_ICINGAWEB_USER_PWD="th3Pass"
|
||||
PG_DIRECTOR_USER_NAME="supervisor"
|
||||
PG_DIRECTOR_USER_PWD="th3Pass"
|
||||
PG_OPM_USER_NAME="opm"
|
||||
PG_OPM_USER_PWD="th3Pass"
|
||||
PG_GRAFANA_USER_NAME="supervisor"
|
||||
PG_GRAFANA_USER_PWD="th3Pass"
|
||||
|
||||
set_hostname(){
|
||||
info "#============================================================================="
|
||||
info "# hostname and /etc/hosts setup"
|
||||
info "#============================================================================="
|
||||
hostnamectl set-hostname "${NODENAME}"
|
||||
sed --in-place -e "s/\(127\.0\.0\.1\s*localhost$\)/\1 ${NODENAME}/" /etc/hosts
|
||||
}
|
||||
|
||||
packages(){
|
||||
info "#============================================================================="
|
||||
info "# install required repos and packages"
|
||||
info "#============================================================================="
|
||||
apt-get update || true
|
||||
apt-get -y install apt-transport-https wget gnupg software-properties-common
|
||||
|
||||
DIST=$(awk -F"[)(]+" '/VERSION=/ {print $2}' /etc/os-release)
|
||||
echo "deb https://packages.icinga.com/debian icinga-${DIST} main" > "/etc/apt/sources.list.d/${DIST}-icinga.list"
|
||||
echo "deb-src https://packages.icinga.com/debian icinga-${DIST} main" >> "/etc/apt/sources.list.d/${DIST}-icinga.list"
|
||||
echo "deb https://packages.grafana.com/oss/deb stable main" > /etc/apt/sources.list.d/grafana.list
|
||||
echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list
|
||||
|
||||
wget -q -O - https://packages.icinga.com/icinga.key | apt-key add -
|
||||
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
|
||||
wget -q -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
|
||||
|
||||
apt-get update || true
|
||||
|
||||
PACKAGES=(
|
||||
grafana
|
||||
icinga2 icinga2-ido-pgsql icingaweb2 icingaweb2-module-monitoring icingacli
|
||||
postgresql-client postgresql-14
|
||||
php7.3-pgsql php7.3-imagick php7.3-intl
|
||||
nagios-plugins
|
||||
)
|
||||
DEBIAN_FRONTEND=noninteractive apt install -q -y "${PACKAGES[@]}"
|
||||
|
||||
systemctl --quiet --now enable postgresql@14
|
||||
}
|
||||
|
||||
icinga_setup(){
|
||||
info "#============================================================================="
|
||||
info "# Icinga setup"
|
||||
info "#============================================================================="
|
||||
|
||||
## this part is already done by the standart icinga install with the user icinga2
|
||||
## and a random password, here we dont really care
|
||||
|
||||
cat << __EOF__ | sudo -u postgres psql
|
||||
DROP ROLE IF EXISTS supervisor;
|
||||
DROP DATABASE IF EXISTS icinga2;
|
||||
CREATE ROLE ${PG_ICINGA_USER_NAME} WITH LOGIN SUPERUSER PASSWORD '${PG_ICINGA_USER_PWD}';
|
||||
CREATE DATABASE icinga2;
|
||||
__EOF__
|
||||
echo "*:*:*:${PG_ICINGA_USER_NAME}:${PG_ICINGA_USER_PWD}" > ~postgres/.pgpass
|
||||
chown postgres:postgres ~postgres/.pgpass
|
||||
chmod 600 ~postgres/.pgpass
|
||||
PGPASSFILE=~postgres/.pgpass psql -U $PG_ICINGA_USER_NAME -h 127.0.0.1 -d icinga2 -f /usr/share/icinga2-ido-pgsql/schema/pgsql.sql
|
||||
|
||||
icingacli setup config directory --group icingaweb2
|
||||
icingacli setup token create
|
||||
|
||||
## this part is already done by the standart icinga install with the user icinga2
|
||||
cat << __EOF__ > /etc/icinga2/features-available/ido-pgsql.conf
|
||||
/**
|
||||
* The db_ido_pgsql library implements IDO functionality
|
||||
* for PostgreSQL.
|
||||
*/
|
||||
|
||||
library "db_ido_pgsql"
|
||||
|
||||
object IdoPgsqlConnection "ido-pgsql" {
|
||||
user = "${PG_ICINGA_USER_NAME}",
|
||||
password = "${PG_ICINGA_USER_PWD}",
|
||||
host = "localhost",
|
||||
database = "icinga2"
|
||||
}
|
||||
__EOF__
|
||||
icinga2 feature enable ido-pgsql
|
||||
icinga2 feature enable command
|
||||
icinga2 feature enable perfdata
|
||||
|
||||
#icinga2 node wizard
|
||||
icinga2 node setup --master --cn s1 --zone master
|
||||
|
||||
systemctl restart icinga2.service
|
||||
}
|
||||
|
||||
icinga_API(){
|
||||
info "#============================================================================="
|
||||
info "# Icinga API"
|
||||
info "#============================================================================="
|
||||
icinga2 api setup
|
||||
|
||||
cat <<__EOF__ >> /etc/icinga2/conf.d/api-users.conf
|
||||
object ApiUser "icingaapi" {
|
||||
password = "th3Pass"
|
||||
permissions = [ "*" ]
|
||||
}
|
||||
__EOF__
|
||||
systemctl restart icinga2.service
|
||||
}
|
||||
|
||||
icinga_web(){
|
||||
info "#============================================================================="
|
||||
info "# Icinga2 Web"
|
||||
info "#============================================================================="
|
||||
if [ "$PG_ICINGA_USER_NAME" != "$PG_ICINGAWEB_USER_NAME" ]; then
|
||||
sudo -u postgres psql -c "CREATE ROLE ${PG_ICINGAWEB_USER_NAME} WITH LOGIN PASSWORD '${PG_ICINGAWEB_USER_PWD}';"
|
||||
fi
|
||||
sudo -u postgres psql -c "CREATE DATABASE icingaweb_db OWNER ${PG_ICINGAWEB_USER_NAME};"
|
||||
|
||||
sed --in-place -e "s/;date\.timezone =/date.timezone = europe\/paris/" /etc/php/7.3/apache2/php.ini
|
||||
a2enconf icingaweb2
|
||||
a2enmod rewrite
|
||||
a2dismod mpm_event
|
||||
a2enmod php7.3
|
||||
|
||||
systemctl restart apache2
|
||||
}
|
||||
|
||||
director(){
|
||||
info "#============================================================================="
|
||||
info "# Icinga director"
|
||||
info "#============================================================================="
|
||||
# Create the database
|
||||
if [ "$PG_ICINGA_USER_NAME" != "$PG_DIRECTOR_USER_NAME" ]; then
|
||||
sudo -u postgres psql -c "CREATE ROLE ${PG_DIRECTOR_USER_NAME} WITH LOGIN PASSWORD '${PG_DIRECTOR_USER_PWD}';"
|
||||
fi
|
||||
sudo -u postgres psql -c "CREATE DATABASE director_db OWNER ${PG_DIRECTOR_USER_NAME};"
|
||||
sudo -iu postgres psql -d director_db -c "CREATE EXTENSION pgcrypto;"
|
||||
|
||||
## Prereq
|
||||
MODULE_NAME=incubator
|
||||
MODULE_VERSION=v0.11.0
|
||||
MODULES_PATH="/usr/share/icingaweb2/modules"
|
||||
MODULE_PATH="${MODULES_PATH}/${MODULE_NAME}"
|
||||
RELEASES="https://github.com/Icinga/icingaweb2-module-${MODULE_NAME}/archive"
|
||||
mkdir "$MODULE_PATH" \
|
||||
&& wget -q $RELEASES/${MODULE_VERSION}.tar.gz -O - \
|
||||
| tar xfz - -C "$MODULE_PATH" --strip-components 1
|
||||
icingacli module enable "${MODULE_NAME}"
|
||||
|
||||
## Director
|
||||
MODULE_VERSION="1.8.1"
|
||||
ICINGAWEB_MODULEPATH="/usr/share/icingaweb2/modules"
|
||||
REPO_URL="https://github.com/icinga/icingaweb2-module-director"
|
||||
TARGET_DIR="${ICINGAWEB_MODULEPATH}/director"
|
||||
URL="${REPO_URL}/archive/v${MODULE_VERSION}.tar.gz"
|
||||
|
||||
useradd -r -g icingaweb2 -d /var/lib/icingadirector -s /bin/false icingadirector
|
||||
install -d -o icingadirector -g icingaweb2 -m 0750 /var/lib/icingadirector
|
||||
install -d -m 0755 "${TARGET_DIR}"
|
||||
wget -q -O - "$URL" | tar xfz - -C "${TARGET_DIR}" --strip-components 1
|
||||
cp "${TARGET_DIR}/contrib/systemd/icinga-director.service" /etc/systemd/system/
|
||||
|
||||
icingacli module enable director
|
||||
systemctl daemon-reload
|
||||
systemctl enable icinga-director.service
|
||||
systemctl start icinga-director.service
|
||||
|
||||
# The permission have to be like this to let icingaweb activate modules
|
||||
chown -R www-data:icingaweb2 /etc/icingaweb2
|
||||
}
|
||||
|
||||
grafana(){
|
||||
info "#============================================================================="
|
||||
info "# Grafana"
|
||||
info "#============================================================================="
|
||||
if [ "$PG_ICINGA_USER_NAME" != "$PG_GRAFANA_USER_NAME" ]; then
|
||||
sudo -u postgres psql -c "CREATE ROLE ${PG_GRAFANA_USER_NAME} WITH LOGIN PASSWORD '${PG_GRAFANA_USER_PWD}';"
|
||||
fi
|
||||
sudo -u postgres psql -c "CREATE DATABASE grafana OWNER ${PG_GRAFANA_USER_NAME};"
|
||||
|
||||
cat << __EOF__ > /etc/grafana/grafana.ini
|
||||
[database]
|
||||
# You can configure the database connection by specifying type, host, name, user and password
|
||||
# as seperate properties or as on string using the url propertie.
|
||||
|
||||
# Either "mysql", "postgres" or "sqlite3", it's your choice
|
||||
type = postgres
|
||||
host = 127.0.0.1:5432
|
||||
name = grafana
|
||||
user = $PG_GRAFANA_USER_NAME
|
||||
password = $PG_GRAFANA_USER_PWD
|
||||
__EOF__
|
||||
systemctl --quiet --now enable grafana-server.service
|
||||
}
|
||||
|
||||
opm(){
|
||||
info "#============================================================================="
|
||||
info "# OPM"
|
||||
info "#============================================================================="
|
||||
|
||||
## OPM Install
|
||||
|
||||
DEBIAN_FRONTEND=noninteractive apt install -q -y postgresql-server-dev-10 libdbd-pg-perl git build-essential
|
||||
|
||||
cd /usr/local/src || exit 1
|
||||
git clone https://github.com/OPMDG/opm-core.git
|
||||
git clone https://github.com/OPMDG/opm-wh_nagios.git
|
||||
cd /usr/local/src/opm-wh_nagios/pg/ || exit 1
|
||||
make install
|
||||
cd /usr/local/src/opm-core/pg/ || exit 1
|
||||
make install
|
||||
|
||||
## OPM db setup
|
||||
|
||||
cat << __EOF__ | sudo -iu postgres psql
|
||||
CREATE ROLE ${PG_OPM_USER_NAME} WITH LOGIN PASSWORD '${PG_OPM_USER_PWD}';
|
||||
CREATE DATABASE opm OWNER ${PG_OPM_USER_NAME};
|
||||
__EOF__
|
||||
cat << __EOF__ | sudo -iu postgres psql -d opm
|
||||
CREATE EXTENSION opm_core;
|
||||
CREATE EXTENSION wh_nagios CASCADE;
|
||||
SELECT * FROM grant_dispatcher('wh_nagios', 'opm');
|
||||
__EOF__
|
||||
|
||||
## OPM dispatcher
|
||||
|
||||
cat <<EOF > /etc/opm_dispatcher.conf
|
||||
daemon=0
|
||||
directory=/var/spool/icinga2/perfdata
|
||||
frequency=5
|
||||
db_connection_string=dbi:Pg:dbname=opm host=localhost
|
||||
db_user=${PG_OPM_USER_NAME}
|
||||
db_password=${PG_OPM_USER_PWD}
|
||||
debug=0
|
||||
syslog=1
|
||||
hostname_filter = /^$/ # Empty hostname. Never happens
|
||||
service_filter = /^$/ # Empty service
|
||||
label_filter = /^$/ # Empty label
|
||||
EOF
|
||||
|
||||
cat <<'EOF' > /etc/systemd/system/opm_dispatcher.service
|
||||
[Unit]
|
||||
Description=dispatcher nagios, import perf files from icinga to opm
|
||||
|
||||
[Service]
|
||||
User=nagios
|
||||
Group=nagios
|
||||
ExecStart=/usr/local/src/opm-wh_nagios/bin/nagios_dispatcher.pl -c /etc/opm_dispatcher.conf
|
||||
|
||||
# start right after boot
|
||||
Type=simple
|
||||
# restart on crash
|
||||
Restart=always
|
||||
# after 10s
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
## OPM planned task
|
||||
|
||||
cat <<'EOF' > /etc/systemd/system/opm_dispatch_record.service
|
||||
[Unit]
|
||||
Description=Run wh_nagios.dispatch_record() on OPM database
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=postgres
|
||||
Group=postgres
|
||||
SyslogIdentifier=opm_dispatch_record
|
||||
ExecStart=/usr/bin/psql -U postgres -d opm -c "SELECT * FROM wh_nagios.dispatch_record()"
|
||||
EOF
|
||||
|
||||
cat <<'EOF' > /etc/systemd/system/opm_dispatch_record.timer
|
||||
[Unit]
|
||||
Description=Timer to run wh_nagios.dispatch_record() on OPM
|
||||
|
||||
[Timer]
|
||||
OnBootSec=60s
|
||||
OnUnitInactiveSec=1min
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable opm_dispatcher
|
||||
systemctl start opm_dispatcher
|
||||
systemctl enable opm_dispatch_record.timer
|
||||
systemctl start opm_dispatch_record.timer
|
||||
|
||||
## To check once everything is setup (icingaweb is setup)
|
||||
# sudo journalctl -fu opm_dispatcher
|
||||
# sudo ournalctl -ft opm_dispatch_record
|
||||
|
||||
## Grants for graphana
|
||||
|
||||
sudo -iu postgres psql -c "CREATE ROLE grafana WITH LOGIN PASSWORD 'th3Pass'"
|
||||
cat <<EOQ | sudo -iu postgres psql -d opm
|
||||
GRANT CONNECT ON DATABASE opm TO ${PG_GRAPHANA_USER_NAME};
|
||||
GRANT SELECT ON ALL TABLES IN SCHEMA public,wh_nagios TO ${PG_GRAPHANA_USER_NAME};
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA public, wh_nagios GRANT SELECT ON TABLES TO ${PG_GRAPHANA_USER_NAME};
|
||||
GRANT USAGE ON SCHEMA public,wh_nagios TO ${PG_GRAPHANA_USER_NAME};
|
||||
GRANT EXECUTE ON FUNCTION wh_nagios.get_metric_data(bigint, timestamptz, timestamptz) TO ${PG_GRAPHANA_USER_NAME};
|
||||
GRANT USAGE ON SCHEMA pr_dalibo TO ${PG_GRAPHANA_USER_NAME};
|
||||
GRANT EXECUTE ON FUNCTION pr_dalibo.variation_taille_service(p_hostname text, p_service text,
|
||||
p_label text, p_tstamp_debut timestamp with time zone, p_duree interval,
|
||||
OUT v_compteur_debut numeric, OUT v_compteur_fin numeric,
|
||||
OUT v_compteur_delta numeric, OUT v_type_corr text, OUT v_corr double precision,
|
||||
OUT v_taille_un_mois numeric) TO ${PG_GRAPHANA_USER_NAME};
|
||||
GRANT EXECUTE ON FUNCTION pr_dalibo.pg_taille_jolie(p_valeur bigint, OUT v_jolie text) TO ${PG_GRAPHANA_USER_NAME};
|
||||
EOQ
|
||||
}
|
||||
|
||||
set_hostname
|
||||
packages
|
||||
icinga_setup
|
||||
icinga_API
|
||||
icinga_web
|
||||
#director ## Not needed anymore, kept for reference
|
||||
grafana
|
||||
opm
|
||||
|
||||
# "icingacli setup" doesnt work when the icinga2 web setup is finished
|
||||
info "#============================================================================="
|
||||
info "# Icinga Web -- $(icingacli setup token show)"
|
||||
info "#============================================================================="
|
||||
|
||||
exit 0
|
Loading…
Reference in a new issue