181 lines
		
	
	
	
		
			6.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			181 lines
		
	
	
	
		
			6.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
assert node.has_bundle('redis')
 | 
						|
assert node.has_bundle('postgresql')
 | 
						|
 | 
						|
from mako.template import Template
 | 
						|
from shlex import quote
 | 
						|
from copy import deepcopy
 | 
						|
from itertools import count
 | 
						|
import yaml
 | 
						|
import json
 | 
						|
 | 
						|
svc_systemd['grafana-server'] = {
 | 
						|
    'needs': [
 | 
						|
        'pkg_apt:grafana',
 | 
						|
    ],
 | 
						|
}
 | 
						|
 | 
						|
admin_password = node.metadata.get('grafana/config/security/admin_password')
 | 
						|
port = node.metadata.get('grafana/config/server/http_port')
 | 
						|
actions['reset_grafana_admin_password'] = {
 | 
						|
    'command': f"grafana-cli admin reset-admin-password {quote(admin_password)}",
 | 
						|
    'unless': f"sleep 5 && curl http://admin:{quote(admin_password)}@localhost:{port}/api/org --fail",
 | 
						|
    'needs': [
 | 
						|
        'svc_systemd:grafana-server',
 | 
						|
    ],
 | 
						|
}
 | 
						|
 | 
						|
directories = {
 | 
						|
    '/etc/grafana': {},
 | 
						|
    '/etc/grafana/provisioning': {
 | 
						|
        'owner': 'grafana',
 | 
						|
        'group': 'grafana',
 | 
						|
    },
 | 
						|
    '/etc/grafana/provisioning/datasources': {
 | 
						|
        'purge': True,
 | 
						|
    },
 | 
						|
    '/etc/grafana/provisioning/dashboards': {
 | 
						|
        'purge': True,
 | 
						|
    },
 | 
						|
    '/var/lib/grafana': {
 | 
						|
        'owner': 'grafana',
 | 
						|
        'group': 'grafana',
 | 
						|
    },
 | 
						|
    '/var/lib/grafana/dashboards': {
 | 
						|
        'owner': 'grafana',
 | 
						|
        'group': 'grafana',
 | 
						|
        'purge': True,
 | 
						|
        'triggers': [
 | 
						|
            'svc_systemd:grafana-server:restart',
 | 
						|
        ],
 | 
						|
    },
 | 
						|
}
 | 
						|
 | 
						|
files = {
 | 
						|
    '/etc/grafana/grafana.ini': {
 | 
						|
        'content': repo.libs.ini.dumps(node.metadata.get('grafana/config')),
 | 
						|
        'owner': 'grafana',
 | 
						|
        'group': 'grafana',
 | 
						|
        'triggers': [
 | 
						|
            'svc_systemd:grafana-server:restart',
 | 
						|
        ],
 | 
						|
    },
 | 
						|
    '/etc/grafana/provisioning/datasources/managed.yaml': {
 | 
						|
        'content': yaml.dump({
 | 
						|
            'apiVersion': 1,
 | 
						|
            'datasources': list(node.metadata.get('grafana/datasources').values()),
 | 
						|
        }),
 | 
						|
        'owner': 'grafana',
 | 
						|
        'group': 'grafana',
 | 
						|
        'triggers': [
 | 
						|
            'svc_systemd:grafana-server:restart',
 | 
						|
        ],
 | 
						|
    },
 | 
						|
    '/etc/grafana/provisioning/dashboards/managed.yaml': {
 | 
						|
        'content': yaml.dump({
 | 
						|
            'apiVersion': 1,
 | 
						|
            'providers': [{
 | 
						|
                'name': 'Default',
 | 
						|
                'folder': 'Generated',
 | 
						|
                'type': 'file',
 | 
						|
                'options': {
 | 
						|
                    'path': '/var/lib/grafana/dashboards',
 | 
						|
                },
 | 
						|
            }],
 | 
						|
        }),
 | 
						|
        'owner': 'grafana',
 | 
						|
        'group': 'grafana',
 | 
						|
        'triggers': [
 | 
						|
            'svc_systemd:grafana-server:restart',
 | 
						|
        ],
 | 
						|
    },
 | 
						|
}
 | 
						|
 | 
						|
# DASHBOARDS
 | 
						|
 | 
						|
with open(repo.path.join([f'data/grafana/dashboard.py'])) as file:
 | 
						|
    dashboard_template = eval(file.read())
 | 
						|
with open(repo.path.join([f'data/grafana/panel.py'])) as file:
 | 
						|
    panel_template = eval(file.read())
 | 
						|
with open(repo.path.join([f'data/grafana/flux.mako'])) as file:
 | 
						|
    flux_template = Template(file.read())
 | 
						|
 | 
						|
bucket = repo.get_node(node.metadata.get('grafana/influxdb_node')).metadata.get('influxdb/bucket')
 | 
						|
 | 
						|
monitored_nodes = [
 | 
						|
    other_node
 | 
						|
        for other_node in repo.nodes
 | 
						|
        if other_node.metadata.get('telegraf/influxdb_node', None) == node.metadata.get('grafana/influxdb_node')
 | 
						|
]
 | 
						|
 | 
						|
for dashboard_id, monitored_node in enumerate(monitored_nodes, start=1):
 | 
						|
    dashboard = deepcopy(dashboard_template)
 | 
						|
    dashboard['id'] = dashboard_id
 | 
						|
    dashboard['title'] = monitored_node.name
 | 
						|
    dashboard['uid'] = monitored_node.metadata.get('id')
 | 
						|
    panel_id = count(start=1)
 | 
						|
 | 
						|
    for row_id, row_name in enumerate(sorted(monitored_node.metadata.get('grafana_rows')), start=1):
 | 
						|
        with open(repo.path.join([f'data/grafana/rows/{row_name}.py'])) as file:
 | 
						|
            row = eval(file.read())
 | 
						|
 | 
						|
        for panel_in_row, (panel_name, panel_config) in enumerate(row.items()):
 | 
						|
            panel = deepcopy(panel_template)
 | 
						|
            panel['id'] = next(panel_id)
 | 
						|
            panel['title'] = f'{row_name} {panel_name}'
 | 
						|
            panel['gridPos']['w'] = 24 // len(row)
 | 
						|
            panel['gridPos']['x'] = (24 // len(row)) * panel_in_row
 | 
						|
            panel['gridPos']['y'] = (row_id - 1) * panel['gridPos']['h']
 | 
						|
 | 
						|
            if 'display_name' in panel_config:
 | 
						|
                panel['fieldConfig']['defaults']['displayName'] = '${'+panel_config['display_name']+'}'
 | 
						|
 | 
						|
            if panel_config.get('stacked'):
 | 
						|
                panel['fieldConfig']['defaults']['custom']['stacking']['mode'] = 'normal'
 | 
						|
 | 
						|
            if 'unit' in panel_config:
 | 
						|
                panel['fieldConfig']['defaults']['unit'] = panel_config['unit']
 | 
						|
 | 
						|
            if 'min' in panel_config:
 | 
						|
                panel['fieldConfig']['defaults']['min'] = panel_config['min']
 | 
						|
            if 'max' in panel_config:
 | 
						|
                panel['fieldConfig']['defaults']['max'] = panel_config['max']
 | 
						|
            if 'soft_max' in panel_config:
 | 
						|
                panel['fieldConfig']['defaults']['custom']['axisSoftMax'] = panel_config['soft_max']
 | 
						|
 | 
						|
            if 'legend' in panel_config:
 | 
						|
                panel['options']['legend'].update(panel_config['legend'])
 | 
						|
 | 
						|
            if 'tooltip' in panel_config:
 | 
						|
                panel['options']['tooltip']['mode'] = panel_config['tooltip']
 | 
						|
                if panel_config['tooltip'] == 'multi':
 | 
						|
                    panel['options']['tooltip']['sort'] = 'desc'
 | 
						|
 | 
						|
            for query_name, query_config in panel_config['queries'].items():
 | 
						|
                panel['targets'].append({
 | 
						|
                    'refId': query_name,
 | 
						|
                    'query': flux_template.render(
 | 
						|
                        bucket=bucket,
 | 
						|
                        host=monitored_node.name,
 | 
						|
                        negative=query_config.get('negative', False),
 | 
						|
                        boolean_to_int=query_config.get('boolean_to_int', False),
 | 
						|
                        minimum=query_config.get('minimum', None),
 | 
						|
                        filters={
 | 
						|
                            'host': monitored_node.name,
 | 
						|
                            **query_config['filters'],
 | 
						|
                        },
 | 
						|
                        exists=query_config.get('exists', []),
 | 
						|
                        function=query_config.get('function', None),
 | 
						|
                    ).strip()
 | 
						|
                })
 | 
						|
 | 
						|
            dashboard['panels'].append(panel)
 | 
						|
 | 
						|
    files[f'/var/lib/grafana/dashboards/{monitored_node.name}.json'] = {
 | 
						|
        'content': json.dumps(dashboard, indent=4),
 | 
						|
        'owner': 'grafana',
 | 
						|
        'group': 'grafana',
 | 
						|
        'triggers': [
 | 
						|
            'svc_systemd:grafana-server:restart',
 | 
						|
        ]
 | 
						|
    }
 | 
						|
 |