Skip to content

Commit

Permalink
Allow managing dashboards in subfolders
Browse files Browse the repository at this point in the history
Since Grafana 11, it is possible to have dashboards in subfolders.
This enables users to manage dashboards in those.
  • Loading branch information
BenjaminSchubert committed Dec 11, 2024
1 parent f867ad3 commit 400b412
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 5 deletions.
3 changes: 3 additions & 0 deletions changelogs/fragments/411-dashboard-subfolders.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
minor_changes:
- Allow creating dashboards in subfolders for `grafana_dashboard`
34 changes: 29 additions & 5 deletions plugins/modules/grafana_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@
default: General
version_added: "1.0.0"
type: str
parent_uid:
description:
- The parent folder UID.
- Available with subfolder feature of Grafana 11.
- Allows creating dashboards in subfolders
version_added: "2.2.0"
type: str
state:
description:
- State of the dashboard.
Expand Down Expand Up @@ -112,6 +119,15 @@
folder: public
dashboard_url: https://grafana.com/api/dashboards/6098/revisions/1/download
- name: Import Grafana dashboard zabbix in a subfolder
community.grafana.grafana_dashboard:
grafana_url: http://grafana.company.com
grafana_api_key: "{{ grafana_api_key }}"
# Can be retrieved from `community.grafana.grafana_folder` as `folder.uid`
parent_uid: "{{ parent_uid }}"
folder: myteam
dashboard_url: https://grafana.com/api/dashboards/6098/revisions/1/download
- name: Export dashboard
community.grafana.grafana_dashboard:
grafana_url: http://grafana.company.com
Expand Down Expand Up @@ -226,15 +242,17 @@ def get_grafana_version(module, grafana_url, headers):
return int(grafana_version)


def grafana_folder_exists(module, grafana_url, folder_name, headers):
def grafana_folder_exists(module, grafana_url, folder_name, parent_uid, headers):
# the 'General' folder is a special case, it's ID is always '0'
if folder_name == "General":
return True, 0

try:
r, info = fetch_url(
module, "%s/api/folders" % grafana_url, headers=headers, method="GET"
)
url = "%s/api/folders" % grafana_url
if parent_uid:
url = "%s?parentUid=%s" % (url, parent_uid)

r, info = fetch_url(module, url, headers=headers, method="GET")

if info["status"] != 200:
raise GrafanaAPIException(
Expand Down Expand Up @@ -382,9 +400,14 @@ def grafana_create_dashboard(module, data):

# test if the folder exists
folder_exists = False
if data["parent_uid"] and grafana_version < 11:
module.fail_json(

Check warning on line 404 in plugins/modules/grafana_dashboard.py

View check run for this annotation

Codecov / codecov/patch

plugins/modules/grafana_dashboard.py#L404

Added line #L404 was not covered by tests
failed=True, msg="Subfolder API is available starting Grafana v11"
)

if grafana_version >= 5:
folder_exists, folder_id = grafana_folder_exists(
module, data["url"], data["folder"], headers
module, data["url"], data["folder"], data["parent_uid"], headers
)
if folder_exists is False:
raise GrafanaAPIException(
Expand Down Expand Up @@ -612,6 +635,7 @@ def main():
org_id=dict(default=1, type="int"),
org_name=dict(type="str"),
folder=dict(type="str", default="General"),
parent_uid=dict(type="str"),
uid=dict(type="str"),
slug=dict(type="str"),
path=dict(aliases=["dashboard_url"], type="str"),
Expand Down
1 change: 1 addition & 0 deletions roles/grafana/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ Configure Grafana organizations, dashboards, folders, datasources, teams and use
| org_id | no |
| org_name | no |
| overwrite | no |
| parent_uid | no |
| path | no |
| slug | no |
| state | no |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,69 @@
- dfff_result2.failed == true
- dfff_result2.changed == false
- "dfff_result2.msg == 'error : Dashboard folder \\'inexistent\\' does not exist.'"

- name: Create a dashboard in a folder
block:
- name: Create the original folder
community.grafana.grafana_folder:
title: parent_folder
state: present
url: "{{ grafana_url }}"
url_username: "{{ grafana_username }}"
url_password: "{{ grafana_password }}"
register: parent_folder

- name: Create the dashboard in the folder
community.grafana.grafana_dashboard:
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: present
commit_message: Updated by ansible
path: /tmp/dashboard.json
overwrite: true
folder: parent_folder
check_mode: false
register: diff_result3
ignore_errors: true
- ansible.builtin.assert:
that:
- diff_result3.failed == false
- diff_result3.changed == true

- name: Create a dashboard in a subfolder
block:
- name: Create the subfolder
community.grafana.grafana_folder:
title: sub_folder
parent_uid: "{{ parent_folder.folder.uid }}"
state: present
url: "{{ grafana_url }}"
url_username: "{{ grafana_username }}"
url_password: "{{ grafana_password }}"
register: sub_folder

- name: Create the dashboard in the subfolder
community.grafana.grafana_dashboard:
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: present
commit_message: Updated by ansible
path: /tmp/dashboard.json
overwrite: true
folder: sub_folder
parent_uid: "{{ parent_folder.folder.uid }}"
check_mode: false
register: diff_result4
ignore_errors: true
- ansible.builtin.assert:
that:
- diff_result4.failed == false
- diff_result4.changed == true
rescue:
- name: Skip if we are running an older version of Grafana
ansible.builtin.assert:
that:
- sub_folder.msg | default ('') == 'Subfolder API is available starting Grafana v11'
fail_msg: "Failed to create dashboard in subfolder, for a separate reason than using an older Grafana. See above."

0 comments on commit 400b412

Please sign in to comment.