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',
 | |
|         ]
 | |
|     }
 | |
| 
 |