---
# Grafana role: installs Grafana, configures PostgreSQL backend,
# provisions Prometheus datasource, and deploys dashboards.

# -- Database setup (runs on primary) --

- name: Create Grafana PostgreSQL user on primary
  community.postgresql.postgresql_user:
    name: "{{ grafana_db_user }}"
    password: "{{ grafana_db_password }}"
    state: present
  delegate_to: "{{ groups['primary'][0] }}"
  become_user: postgres
  run_once: true
  tags: [grafana, grafana-db]

- name: Create Grafana database on primary
  community.postgresql.postgresql_db:
    name: "{{ grafana_db_name }}"
    owner: "{{ grafana_db_user }}"
    state: present
  delegate_to: "{{ groups['primary'][0] }}"
  become_user: postgres
  run_once: true
  tags: [grafana, grafana-db]

# -- Grafana installation --

- name: Install prerequisite packages
  apt:
    name:
      - apt-transport-https
      - software-properties-common
    state: present
    update_cache: true
    cache_valid_time: 3600
  tags: [grafana]

- name: Add Grafana GPG key
  apt_key:
    url: https://apt.grafana.com/gpg.key
    state: present
  tags: [grafana]

- name: Add Grafana APT repository
  apt_repository:
    repo: "deb https://apt.grafana.com stable main"
    state: present
    filename: grafana
  tags: [grafana]

- name: Install Grafana
  apt:
    name: grafana
    state: present
    update_cache: true
  tags: [grafana]

# -- Configuration --

- name: Deploy grafana.ini
  template:
    src: grafana.ini.j2
    dest: /etc/grafana/grafana.ini
    owner: root
    group: grafana
    mode: "0640"
  notify: restart grafana
  tags: [grafana]

# -- Provisioning --

- name: Deploy Prometheus datasource
  template:
    src: datasource.yml.j2
    dest: /etc/grafana/provisioning/datasources/prometheus.yml
    owner: root
    group: grafana
    mode: "0640"
  notify: restart grafana
  tags: [grafana]

- name: Deploy dashboard provider config
  template:
    src: dashboard-provider.yml.j2
    dest: /etc/grafana/provisioning/dashboards/default.yml
    owner: root
    group: grafana
    mode: "0640"
  notify: restart grafana
  tags: [grafana]

- name: Create dashboard directory
  file:
    path: /var/lib/grafana/dashboards
    state: directory
    owner: grafana
    group: grafana
    mode: "0755"
  tags: [grafana]

- name: Deploy dashboard JSON files
  copy:
    src: "dashboards/{{ item }}"
    dest: "/var/lib/grafana/dashboards/{{ item }}"
    owner: grafana
    group: grafana
    mode: "0644"
  loop:
    - chatmail-eijo-im.json
    - infra-eijo-im.json
  notify: restart grafana
  tags: [grafana]

# -- Service --

- name: Enable and start Grafana
  systemd:
    name: grafana-server
    enabled: true
    state: started
  tags: [grafana]

- name: Wait for Grafana to become ready
  uri:
    url: "http://{{ grafana_http_addr }}:{{ grafana_http_port }}/api/health"
    status_code: 200
  register: _grafana_health
  retries: 30
  delay: 5
  until: _grafana_health.status == 200
  tags: [grafana, verify]

# -- Verification --

- name: Verify Grafana is active
  command: systemctl is-active grafana-server
  changed_when: false
  tags: [verify]

- name: Verify datasource is reachable
  uri:
    url: "http://{{ grafana_http_addr }}:{{ grafana_http_port }}/api/datasources/uid/prometheus/health"
    user: "{{ grafana_admin_user }}"
    password: "{{ grafana_admin_password }}"
    force_basic_auth: true
    status_code: 200
  changed_when: false
  tags: [verify]

- name: Verify dashboards are loaded
  uri:
    url: "http://{{ grafana_http_addr }}:{{ grafana_http_port }}/api/search?type=dash-db"
    user: "{{ grafana_admin_user }}"
    password: "{{ grafana_admin_password }}"
    force_basic_auth: true
    return_content: true
  register: _dashboards
  failed_when: (_dashboards.json | length) < 2
  changed_when: false
  tags: [verify]
