install_grafana.yaml 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. ---
  2. - name: Ensure that Grafana has nodes to run on
  3. import_role:
  4. name: openshift_control_plane
  5. tasks_from: ensure_nodes_matching_selector.yml
  6. vars:
  7. openshift_master_ensure_nodes_selector: "{{ grafana_node_selector | map_to_pairs }}"
  8. openshift_master_ensure_nodes_service: Grafana
  9. - name: Create grafana namespace
  10. oc_project:
  11. state: present
  12. name: "{{ grafana_namespace }}"
  13. node_selector: "{{ grafana_node_selector | lib_utils_oo_selector_to_string_list() }}"
  14. description: Grafana
  15. - name: create grafana_serviceaccount_name serviceaccount
  16. oc_serviceaccount:
  17. state: present
  18. name: "{{ grafana_serviceaccount_name }}"
  19. namespace: "{{ grafana_namespace }}"
  20. changed_when: no
  21. # TODO remove this when annotations are supported by oc_serviceaccount
  22. - name: annotate serviceaccount
  23. command: >
  24. {{ openshift_client_binary }} --config={{ openshift.common.config_base }}/master/admin.kubeconfig
  25. annotate --overwrite -n {{ grafana_namespace }}
  26. serviceaccount {{ grafana_serviceaccount_name }} {{ item }}
  27. with_items:
  28. "{{ grafana_serviceaccount_annotations }}"
  29. # create clusterrolebinding for prometheus serviceaccount
  30. - name: Set cluster-reader permissions for grafana
  31. oc_adm_policy_user:
  32. state: present
  33. namespace: "{{ grafana_namespace }}"
  34. resource_kind: cluster-role
  35. resource_name: cluster-reader
  36. user: "{{ openshift_grafana_serviceaccount_name }}"
  37. - name: create grafana routes
  38. oc_route:
  39. state: present
  40. name: "{{ item.name }}"
  41. host: "{{ item.host }}"
  42. namespace: "{{ grafana_namespace }}"
  43. service_name: "{{ item.name }}"
  44. tls_termination: reencrypt
  45. with_items:
  46. - name: grafana
  47. host: "{{ grafana_hostname }}"
  48. - name: create services for grafana
  49. oc_service:
  50. name: "{{ grafana_service_name }}"
  51. namespace: "{{ grafana_namespace }}"
  52. labels:
  53. name: grafana
  54. annotations:
  55. prometheus.io/scrape: "true"
  56. prometheus.io/scheme: https
  57. prometheus.io/port: "{{ grafana_service_targetport | int }}"
  58. service.alpha.openshift.io/serving-cert-secret-name: grafana-tls
  59. ports:
  60. - name: grafana
  61. port: "{{ grafana_service_port }}"
  62. targetPort: "{{ grafana_service_targetport }}"
  63. protocol: TCP
  64. selector:
  65. app: grafana
  66. - name: Set grafana secrets
  67. oc_secret:
  68. state: present
  69. name: "{{ item }}-proxy"
  70. namespace: "{{ grafana_namespace }}"
  71. contents:
  72. - path: session_secret
  73. data: "{{ 43 | lib_utils_oo_random_word }}="
  74. with_items:
  75. - grafana
  76. # Storage
  77. - name: create grafana pvc
  78. oc_pvc:
  79. namespace: "{{ grafana_namespace }}"
  80. name: "{{ grafana_pvc_name }}"
  81. access_modes: "{{ grafana_pvc_access_modes }}"
  82. volume_capacity: "{{ grafana_pvc_size }}"
  83. selector: "{{ grafana_pvc_pv_selector }}"
  84. storage_class_name: "{{ grafana_sc_name }}"
  85. when: grafana_storage_type == 'pvc'
  86. - name: template grafana components
  87. template:
  88. src: "{{ item }}.j2"
  89. dest: "{{ mktemp.stdout }}/{{ item }}"
  90. changed_when: no
  91. with_items:
  92. - "grafana.yml"
  93. - "grafana-config.yml"
  94. - name: Set grafana configmap
  95. oc_configmap:
  96. state: present
  97. name: "grafana-config"
  98. namespace: "{{ grafana_namespace }}"
  99. from_file:
  100. defaults.ini: "{{ mktemp.stdout }}/grafana-config.yml"
  101. - name: Set grafana deployment
  102. oc_obj:
  103. state: present
  104. name: "grafana"
  105. namespace: "{{ grafana_namespace }}"
  106. kind: deployment
  107. files:
  108. - "{{ mktemp.stdout }}/grafana.yml"
  109. - name: Copy Grafana files
  110. copy:
  111. src: "dashboards/{{ item }}"
  112. dest: "{{ mktemp.stdout }}/{{ item }}"
  113. with_items:
  114. - "{{ grafana_dashboards }}"
  115. - name: Wait for grafana pod
  116. oc_obj:
  117. namespace: "{{ grafana_namespace }}"
  118. kind: pod
  119. state: list
  120. selector: "app=grafana"
  121. register: grafana_pod
  122. until:
  123. - "grafana_pod.results.results[0]['items'] | count > 0"
  124. # Pod's 'Ready' status must be True
  125. - "grafana_pod.results.results[0]['items'] | lib_utils_oo_collect(attribute='status.conditions') | lib_utils_oo_collect(attribute='status', filters={'type': 'Ready'}) | map('bool') | select | list | count == 1"
  126. delay: 10
  127. retries: "{{ (grafana_timeout | int / 10) | int }}"
  128. - name: Get the prometheus SA token
  129. shell: oc sa get-token {{ grafana_prometheus_serviceaccount }} -n {{ grafana_prometheus_namespace }}
  130. register: prometheus_sa_token
  131. - name: Get the grafana SA token
  132. shell: oc sa get-token {{ grafana_serviceaccount_name }} -n {{ grafana_namespace }}
  133. register: grafana_sa_token
  134. - name: Get prometheus route
  135. oc_route:
  136. state: list
  137. name: "{{ grafana_prometheus_route }}"
  138. namespace: "{{ grafana_prometheus_namespace }}"
  139. register: prometheus_route
  140. - name: Get grafana route
  141. oc_route:
  142. state: list
  143. name: grafana
  144. namespace: "{{ grafana_namespace }}"
  145. register: grafana_route
  146. - name: set facts
  147. set_fact:
  148. payload_data: "{{ grafana_datasource_json | regex_replace('grafana_name', grafana_datasource_name ) | regex_replace('prometheus_url', prometheus_route.results[0].spec.host ) | regex_replace('Bearer', 'Bearer ' + prometheus_sa_token.stdout) }}"
  149. grafana_route: "https://{{ grafana_route.results[0].spec.host }}"
  150. - name: Add new datasource to grafana
  151. uri:
  152. url: "{{ grafana_route }}/api/datasources"
  153. user: "{{ grafana_sa_token.stdout }}"
  154. validate_certs: false
  155. method: POST
  156. body: '{{ payload_data }}'
  157. body_format: json
  158. status_code:
  159. - 200
  160. - 409
  161. headers:
  162. Content-Type: "Content-Type: application/json"
  163. register: add_ds
  164. - block:
  165. - name: Retrieve current grafana datasource
  166. uri:
  167. url: "{{ grafana_route }}/api/datasources/name/{{ grafana_datasource_name }}"
  168. user: "{{ grafana_sa_token.stdout }}"
  169. validate_certs: false
  170. method: GET
  171. status_code:
  172. - 200
  173. register: grafana_ds
  174. - name: Update grafana datasource
  175. uri:
  176. url: "{{ grafana_route }}/api/datasources/{{ grafana_ds.json['id'] }}"
  177. user: "{{ grafana_sa_token.stdout }}"
  178. validate_certs: false
  179. method: PUT
  180. body: '{{ payload_data }}'
  181. body_format: json
  182. headers:
  183. Content-Type: "Content-Type: application/json"
  184. status_code:
  185. - 200
  186. register: update_ds
  187. when: add_ds.status == 409
  188. - name: Regex set data source name for openshift dashboard
  189. replace:
  190. path: "{{ mktemp.stdout }}/openshift-cluster-monitoring.json"
  191. regexp: '{{ item.regexp }}'
  192. replace: '{{ item.replace }}'
  193. backup: yes
  194. with_items:
  195. - regexp: '##DS_PR##'
  196. replace: '{{ grafana_datasource_name }}'
  197. - regexp: 'Xs'
  198. replace: '{{ grafana_graph_granularity }}'
  199. - name: Regex set data source name for node exporter
  200. replace:
  201. path: "{{ mktemp.stdout }}/node-exporter-full-dashboard.json"
  202. regexp: '{{ item.regexp }}'
  203. replace: '{{ item.replace }}'
  204. backup: yes
  205. with_items:
  206. - regexp: '##DS_PR##'
  207. replace: '{{ grafana_datasource_name }}'
  208. - regexp: 'Xs'
  209. replace: '{{ grafana_graph_granularity }}'
  210. when: grafana_node_exporter | default(false) | bool == true
  211. - set_fact:
  212. cluster_monitoring_dashboard: "{{ mktemp.stdout }}/openshift-cluster-monitoring.json"
  213. node_exporter_dashboard: "{{ mktemp.stdout }}/node-exporter-full-dashboard.json"
  214. - name: Slurp dashboard file
  215. slurp:
  216. src: "{{ cluster_monitoring_dashboard }}"
  217. register: slurpfile
  218. - set_fact:
  219. dashboard_data: '{{ slurpfile["content"] | b64decode | from_json | combine({ "dashboard": { "overwrite": true } }, recursive=True) | to_json }}'
  220. - name: Add openshift dashboard
  221. uri:
  222. url: "{{ grafana_route }}/api/dashboards/db"
  223. user: "{{ grafana_sa_token.stdout }}"
  224. validate_certs: false
  225. method: POST
  226. body: '{{ dashboard_data }}'
  227. body_format: json
  228. status_code:
  229. - 200
  230. - 412
  231. headers:
  232. Content-Type: "Content-Type: application/json"
  233. register: add_ds
  234. - name: Slurp dashboard file
  235. slurp:
  236. src: "{{ node_exporter_dashboard }}"
  237. register: slurpfile
  238. - set_fact:
  239. dashboard_data: '{{ slurpfile["content"] | b64decode | from_json | combine({ "dashboard": { "overwrite": true } }, recursive=True) | to_json }}'
  240. - name: Add node exporter dashboard
  241. uri:
  242. url: "{{ grafana_route }}/api/dashboards/db"
  243. user: "{{ grafana_sa_token.stdout }}"
  244. validate_certs: false
  245. method: POST
  246. body: '{{ dashboard_data }}'
  247. body_format: json
  248. status_code:
  249. - 200
  250. - 412
  251. headers:
  252. Content-Type: "Content-Type: application/json"
  253. register: add_ds
  254. when: grafana_node_exporter | default(false) | bool == true