This repository has been archived by the owner on May 31, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 305
/
dashboards.yml
161 lines (151 loc) · 5.68 KB
/
dashboards.yml
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
---
- become: false
delegate_to: localhost
run_once: true
block:
- name: Create local grafana dashboard directory
tempfile:
state: directory
register: _tmp_dashboards
changed_when: false
check_mode: false
# Use curl to solve issue #77
- name: download grafana dashboard from grafana.net to local directory
command: >
curl --fail --compressed
https://grafana.com/api/dashboards/{{ item.dashboard_id }}/revisions/{{ item.revision_id }}/download
-o {{ _tmp_dashboards.path }}/{{ item.dashboard_id }}.json
args:
creates: "{{ _tmp_dashboards.path }}/{{ item.dashboard_id }}.json"
warn: false
register: _download_dashboards
until: _download_dashboards is succeeded
retries: 5
delay: 2
with_items: "{{ grafana_dashboards }}"
when: grafana_dashboards | length > 0
changed_when: false
check_mode: false
tags:
- skip_ansible_lint
# As noted in [1] an exported dashboard replaces the exporter's datasource
# name with a representative name, something like 'DS_GRAPHITE'. The name
# is different for each datasource plugin, but always begins with 'DS_'.
# In the rest of the data, the same name is used, but captured in braces,
# for example: '${DS_GRAPHITE}'.
#
# [1] http://docs.grafana.org/reference/export_import/#import-sharing-with-grafana-2-x-or-3-0
#
# The data structure looks (massively abbreviated) something like:
#
# "name": "DS_GRAPHITE",
# "datasource": "${DS_GRAPHITE}",
#
# If we import the downloaded dashboard verbatim, it will not automatically
# be connected to the data source like we want it. The Grafana UI expects
# us to do the final connection by hand, which we do not want to do.
# So, in the below task we ensure that we replace instances of this string
# with the data source name we want.
# To make sure that we're not being too greedy with the regex replacement
# of the data source to use for each dashboard that's uploaded, we make the
# regex match very specific by using the following:
#
# 1. Literal boundaries for " on either side of the match.
# 2. Non-capturing optional group matches for the ${} bits which may, or
# or may not, be there..
# 3. A case-sensitive literal match for DS .
# 4. A one-or-more case-sensitive match for the part that follows the
# underscore, with only A-Z, 0-9 and - or _ allowed.
#
# This regex can be tested and understood better by looking at the
# matches and non-matches in https://regex101.com/r/f4Gkvg/6
- name: Set the correct data source name in the dashboard
replace:
dest: "{{ _tmp_dashboards.path }}/{{ item.dashboard_id }}.json"
regexp: '"(?:\${)?DS_[A-Z0-9_-]+(?:})?"'
replace: '"{{ item.datasource }}"'
changed_when: false
with_items: "{{ grafana_dashboards }}"
when: grafana_dashboards | length > 0
- name: Import grafana dashboards through API
uri:
url: "{{ grafana_api_url }}/api/dashboards/db"
user: "{{ grafana_security.admin_user }}"
password: "{{ grafana_security.admin_password }}"
force_basic_auth: true
method: POST
body_format: json
body: >
{
"dashboard": {{ lookup("file", item) }},
"overwrite": true,
"message": "Updated by ansible"
}
no_log: true
with_fileglob:
- "{{ _tmp_dashboards.path }}/*"
- "{{ grafana_dashboards_dir }}/*.json"
when: not grafana_use_provisioning
# TODO: uncomment this when ansible 2.7 will be min supported version
# - name: import grafana dashboards
# grafana_dashboard:
# grafana_url: "{{ grafana_api_url }}"
# grafana_user: "{{ grafana_security.admin_user }}"
# grafana_password: "{{ grafana_security.admin_password }}"
# path: "/tmp/dashboards/{{ item }}"
# message: Updated by ansible
# state: present
# overwrite: true
# no_log: true
# with_fileglob:
# - "/tmp/dashboards/*"
- when: grafana_use_provisioning
block:
- name: Create/Update dashboards file (provisioning)
become: true
copy:
dest: "/etc/grafana/provisioning/dashboards/ansible.yml"
content: |
apiVersion: 1
providers:
- name: 'default'
orgId: 1
folder: ''
type: file
options:
path: "{{ grafana_data_dir }}/dashboards"
backup: false
owner: root
group: grafana
mode: 0640
notify: restart grafana
- name: Register previously copied dashboards
find:
paths: "{{ grafana_data_dir }}/dashboards"
hidden: true
patterns:
- "*.json"
register: _dashboards_present
when: grafana_provisioning_synced
- name: Import grafana dashboards
become: true
copy:
src: "{{ item }}"
dest: "{{ grafana_data_dir }}/dashboards/{{ item | basename }}"
with_fileglob:
- "{{ _tmp_dashboards.path }}/*"
- "{{ grafana_dashboards_dir }}/*.json"
register: _dashboards_copied
notify: "provisioned dashboards changed"
- name: Get dashboard lists
set_fact:
_dashboards_present_list: "{{ _dashboards_present | json_query('files[*].path') | default([]) }}"
_dashboards_copied_list: "{{ _dashboards_copied | json_query('results[*].dest') | default([]) }}"
when: grafana_provisioning_synced
- name: Remove dashboards not present on deployer machine (synchronize)
become: true
file:
path: "{{ item }}"
state: absent
with_items: "{{ _dashboards_present_list | difference( _dashboards_copied_list ) }}"
when: grafana_provisioning_synced