summaryrefslogtreecommitdiffstats
path: root/ansible_collections/community/grafana
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/community/grafana')
-rw-r--r--ansible_collections/community/grafana/.all-contributorsrc23
-rw-r--r--ansible_collections/community/grafana/.config/ansible-lint.yml5
-rw-r--r--ansible_collections/community/grafana/.config/yamllint/config2
-rw-r--r--ansible_collections/community/grafana/.github/CODEOWNERS6
-rw-r--r--ansible_collections/community/grafana/.github/workflows/ansible-test.yml48
-rw-r--r--ansible_collections/community/grafana/.github/workflows/lint.yml36
-rw-r--r--ansible_collections/community/grafana/.gitignore1
-rw-r--r--ansible_collections/community/grafana/CHANGELOG.rst65
-rw-r--r--ansible_collections/community/grafana/FILES.json678
-rw-r--r--ansible_collections/community/grafana/MANIFEST.json4
-rw-r--r--ansible_collections/community/grafana/README.md57
-rw-r--r--ansible_collections/community/grafana/changelogs/changelog.yaml72
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/238_checkmode.yml2
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/242_add_grafana_organization_user_module.yml2
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/285_fix_doc.yml6
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/294-bump-grafana-version.yml5
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/300_datasource_prometheus_time_interval.yml2
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/308_datasource_quickwit.yml2
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/311_dashboard_check_mode.yml5
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/318-org_users_by_org_name.yml7
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/321-action-groups-org-users.yml4
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/324_formatting.yml2
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/325_linting.yml2
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/325_true_false.yml2
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/331-dashboard-by-org-name.yml8
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/332-datasource-by-org-name.yml4
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/335-add-datasource-type-tempo.yml2
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/339-lint-black.yml3
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/341-lint-ruff.yml3
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/342-ruff-findings.yml2
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/343-telekom-mms-role.yml2
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/345-datasource-compare-diff-orgid.yml3
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/347-folder-for-orgs.yml7
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/349-role-notification-channel.yml4
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/350-python3.12.yml3
-rw-r--r--ansible_collections/community/grafana/changelogs/fragments/fix-316.yml2
-rw-r--r--ansible_collections/community/grafana/codecov.yml2
-rw-r--r--ansible_collections/community/grafana/hacking/find_grafana_versions.py7
-rw-r--r--ansible_collections/community/grafana/hacking/requirements.txt2
-rw-r--r--ansible_collections/community/grafana/meta/runtime.yml19
-rw-r--r--ansible_collections/community/grafana/molecule/default/converge.yml48
-rw-r--r--ansible_collections/community/grafana/molecule/default/molecule.yml21
-rw-r--r--ansible_collections/community/grafana/molecule/default/test_dashboard.json126
-rw-r--r--ansible_collections/community/grafana/plugins/callback/grafana_annotations.py123
-rw-r--r--ansible_collections/community/grafana/plugins/doc_fragments/api_key.py7
-rw-r--r--ansible_collections/community/grafana/plugins/doc_fragments/basic_auth.py17
-rw-r--r--ansible_collections/community/grafana/plugins/lookup/grafana_dashboard.py106
-rw-r--r--ansible_collections/community/grafana/plugins/module_utils/base.py24
-rw-r--r--ansible_collections/community/grafana/plugins/modules/grafana_dashboard.py585
-rw-r--r--ansible_collections/community/grafana/plugins/modules/grafana_datasource.py596
-rw-r--r--ansible_collections/community/grafana/plugins/modules/grafana_folder.py141
-rw-r--r--ansible_collections/community/grafana/plugins/modules/grafana_notification_channel.py660
-rw-r--r--ansible_collections/community/grafana/plugins/modules/grafana_organization.py70
-rw-r--r--ansible_collections/community/grafana/plugins/modules/grafana_organization_user.py294
-rw-r--r--ansible_collections/community/grafana/plugins/modules/grafana_plugin.py203
-rw-r--r--ansible_collections/community/grafana/plugins/modules/grafana_team.py93
-rw-r--r--ansible_collections/community/grafana/plugins/modules/grafana_user.py89
-rw-r--r--ansible_collections/community/grafana/roles/grafana/README.md190
-rw-r--r--ansible_collections/community/grafana/roles/grafana/defaults/main.yml9
-rw-r--r--ansible_collections/community/grafana/roles/grafana/meta/main.yml14
-rw-r--r--ansible_collections/community/grafana/roles/grafana/tasks/main.yml203
-rw-r--r--ansible_collections/community/grafana/ruff.toml1
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/defaults/main.yml9
-rwxr-xr-xansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/runme.sh5
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/site.yml6
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-by-org-name.yml84
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-export.yml100
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-folder-destination.yml65
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-file-export.yml90
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-file.yml44
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-id.yml80
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-url.yml79
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/delete-dashboard.yml62
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/main.yml27
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/defaults/main.yml8
-rwxr-xr-xansible_collections/community/grafana/tests/integration/targets/grafana_datasource/runme.sh5
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/site.yml6
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/azure.yml117
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/cloudwatch.yml111
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/elastic.yml378
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/errors.yml12
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/influx.yml71
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/issues.yml59
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/loki.yml73
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/main.yml36
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/postgres.yml65
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/quickwit.yml137
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/redis.yml85
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/tempo.yml79
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/thruk.yml69
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/uid.yml255
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/zabbix.yml107
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_folder/defaults/main.yml8
-rwxr-xr-xansible_collections/community/grafana/tests/integration/targets/grafana_folder/runme.sh6
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_folder/site.yml6
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_folder/tasks/create-delete.yml58
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_folder/tasks/main.yml57
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_folder/tasks/org.yml7
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/defaults/main.yml8
-rwxr-xr-xansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/runme.sh5
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/site.yml6
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/dingding.yml32
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/discord.yml32
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/email.yml42
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/googlechat.yml40
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/hipchat.yml40
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/kafka.yml40
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/line.yml40
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/main.yml50
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/opsgenie.yml42
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/pagerduty.yml40
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/prometheus.yml40
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/pushover.yml40
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/sensu.yml40
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/slack-and-beyond.yml60
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/teams.yml40
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/telegram.yml40
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/threema.yml40
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/victorops.yml40
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/webhook.yml40
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_organization/defaults/main.yml6
-rwxr-xr-xansible_collections/community/grafana/tests/integration/targets/grafana_organization/runme.sh6
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_organization/site.yml6
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_organization/tasks/main.yml45
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/defaults/main.yml4
-rwxr-xr-xansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/runme.sh6
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/site.yml6
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/tasks/main.yml172
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_team/defaults/main.yml8
-rwxr-xr-xansible_collections/community/grafana/tests/integration/targets/grafana_team/runme.sh5
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_team/site.yml6
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_team/tasks/create_user.yml25
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_team/tasks/main.yml273
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_user/defaults/main.yml6
-rwxr-xr-xansible_collections/community/grafana/tests/integration/targets/grafana_user/runme.sh6
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_user/site.yml6
-rw-r--r--ansible_collections/community/grafana/tests/integration/targets/grafana_user/tasks/main.yml186
-rw-r--r--ansible_collections/community/grafana/tests/requirements.yml3
-rw-r--r--ansible_collections/community/grafana/tests/sanity/ignore-2.16.txt4
-rw-r--r--ansible_collections/community/grafana/tests/sanity/ignore-2.17.txt4
-rw-r--r--ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_datasource/test_grafana_datasource.py283
-rw-r--r--ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py35
-rw-r--r--ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_team/test_grafana_team.py572
-rw-r--r--ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_user/test_grafana_user.py239
144 files changed, 6607 insertions, 3299 deletions
diff --git a/ansible_collections/community/grafana/.all-contributorsrc b/ansible_collections/community/grafana/.all-contributorsrc
index 878f911bf..f1a1cb6dc 100644
--- a/ansible_collections/community/grafana/.all-contributorsrc
+++ b/ansible_collections/community/grafana/.all-contributorsrc
@@ -177,6 +177,26 @@
"contributions": [
"bug"
]
+ },
+ {
+ "login": "amenzhinsky",
+ "name": "Aliaksandr Mianzhynski",
+ "avatar_url": "https://avatars.githubusercontent.com/u/1308953?v=4",
+ "profile": "https://github.com/amenzhinsky",
+ "contributions": [
+ "code",
+ "test"
+ ]
+ },
+ {
+ "login": "Nemental",
+ "name": "Moritz",
+ "avatar_url": "https://avatars.githubusercontent.com/u/15136847?v=4",
+ "profile": "https://nemental.de",
+ "contributions": [
+ "bug",
+ "code"
+ ]
}
],
"contributorsPerLine": 7,
@@ -185,5 +205,6 @@
"repoType": "github",
"repoHost": "https://github.com",
"skipCi": true,
- "commitConvention": "angular"
+ "commitConvention": "angular",
+ "commitType": "docs"
}
diff --git a/ansible_collections/community/grafana/.config/ansible-lint.yml b/ansible_collections/community/grafana/.config/ansible-lint.yml
new file mode 100644
index 000000000..81424ef79
--- /dev/null
+++ b/ansible_collections/community/grafana/.config/ansible-lint.yml
@@ -0,0 +1,5 @@
+---
+exclude_paths:
+ - .github/
+ - tests/
+ - changelogs/
diff --git a/ansible_collections/community/grafana/.config/yamllint/config b/ansible_collections/community/grafana/.config/yamllint/config
new file mode 100644
index 000000000..e907140bf
--- /dev/null
+++ b/ansible_collections/community/grafana/.config/yamllint/config
@@ -0,0 +1,2 @@
+---
+extends: default
diff --git a/ansible_collections/community/grafana/.github/CODEOWNERS b/ansible_collections/community/grafana/.github/CODEOWNERS
index 3035cfbbd..2cc403628 100644
--- a/ansible_collections/community/grafana/.github/CODEOWNERS
+++ b/ansible_collections/community/grafana/.github/CODEOWNERS
@@ -1,13 +1,9 @@
.github
# Repo maintainers, and goverance team (like Anisble's @ansible-commit-external)
-* @rrey @seuf @gundalow-collections/community-goverance-team
+* @rrey @seuf
# or possibly, we may want to define teams at the org level.
-# * @gundalow-collections/grafana-maintainers
# Example of maintainer of just a single plugin
#grafana/plugins/modules/grafana_plugin.py @someone-else
-
-
-.github/ @gundalow
diff --git a/ansible_collections/community/grafana/.github/workflows/ansible-test.yml b/ansible_collections/community/grafana/.github/workflows/ansible-test.yml
index e8f2cd6b3..a5717781f 100644
--- a/ansible_collections/community/grafana/.github/workflows/ansible-test.yml
+++ b/ansible_collections/community/grafana/.github/workflows/ansible-test.yml
@@ -12,8 +12,8 @@ jobs:
timeout-minutes: 30
strategy:
matrix:
- python_version: ["3.9"]
- ansible_version: ["stable-2.13", "stable-2.14", "devel"]
+ python_version: ["3.10"]
+ ansible_version: ["stable-2.15", "stable-2.16", "devel"]
steps:
- name: Perform testing
uses: ansible-community/ansible-test-gh-action@release/v1
@@ -29,8 +29,8 @@ jobs:
timeout-minutes: 30
strategy:
matrix:
- python_version: ["3.9"]
- ansible_version: ["stable-2.13", "stable-2.14", "devel"]
+ python_version: ["3.10"]
+ ansible_version: ["stable-2.15", "stable-2.16", "devel"]
steps:
- name: Perform testing
uses: ansible-community/ansible-test-gh-action@release/v1
@@ -45,9 +45,9 @@ jobs:
strategy:
fail-fast: false
matrix:
- grafana_version: ["9.2.6", "8.5.15", "7.5.16"]
- ansible_version: ["stable-2.13", "stable-2.14", "devel"]
- python_version: ["3.9"]
+ grafana_version: ["9.5.14", "8.5.27", "10.2.2"]
+ ansible_version: ["stable-2.15", "stable-2.16", "devel"]
+ python_version: ["3.10"]
services:
grafana:
image: grafana/grafana:${{ matrix.grafana_version }}
@@ -58,3 +58,37 @@ jobs:
ansible-core-version: ${{ matrix.ansible_version }}
target-python-version: ${{ matrix.python_version }}
testing-type: integration
+
+ molecule:
+ runs-on: ubuntu-latest
+ env:
+ PY_COLORS: 1
+ ANSIBLE_FORCE_COLOR: 1
+ strategy:
+ fail-fast: false
+ matrix:
+ grafana_version: ["9.5.14", "8.5.27", "10.2.2"]
+ ansible_version: ["stable-2.15", "stable-2.16", "devel"]
+ python_version: ["3.10"]
+ services:
+ grafana:
+ image: grafana/grafana:${{ matrix.grafana_version }}
+ ports: ["3000:3000"]
+ steps:
+ - name: Checkout repo
+ uses: actions/checkout@v4
+
+ - name: Set up Python
+ uses: actions/setup-python@v5
+ with:
+ python-version: ${{ matrix.python_version }}
+
+ - name: Install dependencies
+ run: |
+ python -m pip install --no-cache-dir --upgrade pip
+ pip install "git+https://github.com/ansible/ansible@${{ matrix.ansible_version }}" molecule molecule-docker
+
+ - name: Test with molecule
+ run: |
+ molecule --version
+ molecule test
diff --git a/ansible_collections/community/grafana/.github/workflows/lint.yml b/ansible_collections/community/grafana/.github/workflows/lint.yml
new file mode 100644
index 000000000..26216d89b
--- /dev/null
+++ b/ansible_collections/community/grafana/.github/workflows/lint.yml
@@ -0,0 +1,36 @@
+name: Lint
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+
+jobs:
+ python:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Get changed files
+ id: changed-files
+ uses: tj-actions/changed-files@v41
+ with:
+ files: "**/*.py"
+
+ - if: ${{ steps.changed-files.outputs.all_changed_files != '' }}
+ uses: psf/black@stable
+ with:
+ src: ${{ steps.changed-files.outputs.all_changed_files }}
+
+ - if: ${{ steps.changed-files.outputs.all_changed_files != '' }}
+ uses: chartboost/ruff-action@v1
+ with:
+ src: ${{ steps.changed-files.outputs.all_changed_files }}
+ ansible:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Run ansible-lint
+ uses: ansible/ansible-lint@main
diff --git a/ansible_collections/community/grafana/.gitignore b/ansible_collections/community/grafana/.gitignore
index 9f11b755a..2483976dc 100644
--- a/ansible_collections/community/grafana/.gitignore
+++ b/ansible_collections/community/grafana/.gitignore
@@ -1 +1,2 @@
.idea/
+__pycache__/
diff --git a/ansible_collections/community/grafana/CHANGELOG.rst b/ansible_collections/community/grafana/CHANGELOG.rst
index 426f3cdf5..8a40ac18f 100644
--- a/ansible_collections/community/grafana/CHANGELOG.rst
+++ b/ansible_collections/community/grafana/CHANGELOG.rst
@@ -5,6 +5,71 @@ Grafana Collection Release Notes
.. contents:: Topics
+v1.8.0
+======
+
+Minor Changes
+-------------
+
+- Manage `grafana_folder` for organizations
+- Merged ansible role telekom-mms/ansible-role-grafana into ansible-collections/community.grafana
+- added `community.grafana.notification_channel` to role
+- grafana_dashboard - add check_mode support
+
+Bugfixes
+--------
+
+- test: replace deprecated `TestCase.assertEquals` to support Python 3.12
+
+v1.7.0
+======
+
+Minor Changes
+-------------
+
+- Add Quickwit search engine datasource (https://quickwit.io).
+- Add parameter `org_name` to `grafana_dashboard`
+- Add parameter `org_name` to `grafana_datasource`
+- Add parameter `org_name` to `grafana_organization_user`
+- Add support for Grafana Tempo datasource type (https://grafana.com/docs/grafana/latest/datasources/tempo/)
+- default to true/false in docs and code
+
+Bugfixes
+--------
+
+- Add `grafana_organiazion_user` to `action_groups.grafana`
+- Fixed orgId handling in diff comparison for `grafana_datasource` if using org_name
+
+v1.6.1
+======
+
+Minor Changes
+-------------
+
+- Bump version of Python used in tests to 3.10
+- Enable datasource option `time_interval` for prometheus
+- Fix documentation url for Ansible doc website
+- Now testing against Grafana 9.5.13, 8.5.27, 10.2.0
+
+Bugfixes
+--------
+
+- Fix error with datasources configured without basicAuth
+- grafana_folder, fix an issue during delete (starting Grafana 9.3)
+
+v1.6.0
+======
+
+Minor Changes
+-------------
+
+- Add `grafana_organization_user` module
+
+New Modules
+-----------
+
+- community.grafana.grafana_organization_user - Manage Grafana Organization Users.
+
v1.5.4
======
diff --git a/ansible_collections/community/grafana/FILES.json b/ansible_collections/community/grafana/FILES.json
index 4dc1e3d44..be95fa2bc 100644
--- a/ansible_collections/community/grafana/FILES.json
+++ b/ansible_collections/community/grafana/FILES.json
@@ -8,6 +8,34 @@
"format": 1
},
{
+ "name": ".config",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": ".config/yamllint",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": ".config/yamllint/config",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b5910022dcb8c8295c99271d1c55ad728bb9ea20ae873c18aa2df97b8befae92",
+ "format": 1
+ },
+ {
+ "name": ".config/ansible-lint.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "dbf92afa23eaa6ef3d4461829dc8a7d3f8f14caab53e5a74d4070720c721b8af",
+ "format": 1
+ },
+ {
"name": ".github",
"ftype": "dir",
"chksum_type": null,
@@ -25,7 +53,7 @@
"name": ".github/workflows/ansible-test.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "105c6c1fb8b82644fddd6c6eaa59b21ab581662ff4a673483ee05f16cf44a48a",
+ "chksum_sha256": "e3e774ec33a3dc2a5ea1da40931ab5e6b96d3b67e57454fc867f9009cbc9797f",
"format": 1
},
{
@@ -43,6 +71,13 @@
"format": 1
},
{
+ "name": ".github/workflows/lint.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "405ea441af55f0770ae8d90ed355e34e31cef75a3b70dddd558a013df24e3b5d",
+ "format": 1
+ },
+ {
"name": ".github/workflows/rebase.yml",
"ftype": "file",
"chksum_type": "sha256",
@@ -53,7 +88,7 @@
"name": ".github/CODEOWNERS",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "27ba6e53b61251034d894049f866e4e15f9946b605b91756597e2a4727beef98",
+ "chksum_sha256": "81b8c5a2958345d497da521973b94f9c50210535765d8a4cb713d51468e5fb58",
"format": 1
},
{
@@ -225,6 +260,13 @@
"format": 1
},
{
+ "name": "changelogs/fragments/238_checkmode.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "7111820e7939b5645f6ebd20cdc03b166f0e8df983808c964334f4449d2fe73c",
+ "format": 1
+ },
+ {
"name": "changelogs/fragments/239_keyerror_grafana_url.yml",
"ftype": "file",
"chksum_type": "sha256",
@@ -232,6 +274,13 @@
"format": 1
},
{
+ "name": "changelogs/fragments/242_add_grafana_organization_user_module.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "8c86a0c996a356a2884ab70ef4fadfa58c7e504a26f055bc0926f8065de1f556",
+ "format": 1
+ },
+ {
"name": "changelogs/fragments/248_ds_update_error_grafana_9.yml",
"ftype": "file",
"chksum_type": "sha256",
@@ -267,6 +316,13 @@
"format": 1
},
{
+ "name": "changelogs/fragments/285_fix_doc.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "eed5d4709bb9447344c7ca0d8fe47ca3ecb3641697b1e18de865e7ee6b0ec9eb",
+ "format": 1
+ },
+ {
"name": "changelogs/fragments/288_get_actual_org_encode.yml",
"ftype": "file",
"chksum_type": "sha256",
@@ -274,6 +330,146 @@
"format": 1
},
{
+ "name": "changelogs/fragments/294-bump-grafana-version.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "91f1f5dd43943a5955f18df300a3497c0d89c9fd54ee8ddb8fbbd881262aa10f",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/300_datasource_prometheus_time_interval.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f8b238f88f025de74c456235a2a04283d22233da36e33d4c8887bdca56d0fcd0",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/308_datasource_quickwit.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "da003c09e654cf46ca2de33f32782fdd30f19f5d3196d7d8b3258ff6804565d7",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/311_dashboard_check_mode.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "0601ccd2ae0421c355e6183110c64df7243f93e1376f07cf593be5ff4a9f4470",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/318-org_users_by_org_name.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "23c95e1b4d10f2a89dfb8a2857af543b08361ac54e831919c46f30a03f749301",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/321-action-groups-org-users.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f559e5db8e8b85da1b937996024f5f0c23324d40ea6ee5d7fc5c419aa71ebb95",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/324_formatting.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "25665f818c24b36058bcaa706604440967276be1296a2bdc6037271519505e04",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/325_linting.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "af5aec2049dfeae982e2d47daa44e6e84a5f800092b4b818fa8d2a569afbe511",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/325_true_false.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "14a107d144554667832aec72c86f83c5a0fecb31c8645daec3c6933906633459",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/331-dashboard-by-org-name.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "57095fa0bcf6aea3b7f2b79565d3d4f71d01c9d3735ee7044041217c518c4439",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/332-datasource-by-org-name.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "31ad79d93624848dc7b4a30c79938200b94a809ae84df411e7afb993b32529bc",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/335-add-datasource-type-tempo.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "da3c13510502e83b46b7ddc8fffe7d007ec76b4586f311d59c9e7dc33e424754",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/339-lint-black.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "60ede1111ab7b74ab1f933bfe06df23bbcc2fed7fe1cd60270095d6ab315572f",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/341-lint-ruff.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "c1549e022f201f9e5dc7d984a84a38a10bce720f12b046abfcaeab24ddfd27b8",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/342-ruff-findings.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ce61f53984c913b4c8f7bbc099938fce8aed19d566422e530b427d7685b797fa",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/343-telekom-mms-role.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "bfe2053658fe18ffcefbb8b3d7f739281ae24693c16d36b13189229994d3e07c",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/345-datasource-compare-diff-orgid.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "4698e5052edfce0dc51171d390bb7070e8a70bd3181475e6d8f1f90abe7695db",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/347-folder-for-orgs.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "55a59bceab13dfa96e7a63a0a9b0912ecf9248ae8a9037ffff49ecc78a716ad9",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/349-role-notification-channel.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e46d6a7d7175a33ba08ce335b4fc839164afd9d49ea788bc71777e4aee3ec4fb",
+ "format": 1
+ },
+ {
+ "name": "changelogs/fragments/350-python3.12.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "38410fc78c051c85a770d57487c0e44afcfb7788cc23dc675b47018c31ca2be0",
+ "format": 1
+ },
+ {
"name": "changelogs/fragments/add-units-datasource.yml",
"ftype": "file",
"chksum_type": "sha256",
@@ -302,6 +498,13 @@
"format": 1
},
{
+ "name": "changelogs/fragments/fix-316.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "599f961644d8b43f3f8d1c291b4ff1db8c09834d8c493560b91e030f7f2dfb7d",
+ "format": 1
+ },
+ {
"name": "changelogs/fragments/fix_slashes_in_datasources.yml",
"ftype": "file",
"chksum_type": "sha256",
@@ -340,7 +543,7 @@
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "672317831941badc24b8b2b99f256386289e6774791ad54e107bd1a20cab4e0b",
+ "chksum_sha256": "641de48bd2e1d3ab8daeace7b522413299bd4d2521204d1f707e8c23bb445480",
"format": 1
},
{
@@ -375,14 +578,14 @@
"name": "hacking/find_grafana_versions.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f208e226d9f51971c45afd07149e2f9b6a6b583b35abde56c75bacba9961e84d",
+ "chksum_sha256": "39acc81ec9733183bbb4eeae0c10c3aeecdeedd1ffc2dabcc675b84e16565f3e",
"format": 1
},
{
"name": "hacking/requirements.txt",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f68f48b3014372d3e3859aac2030508871fb7f8cd29a5e5b51be92674a192570",
+ "chksum_sha256": "1d277ef3981a3e49b02912a0f03fe1ab563539d7e4e1b5c1e6404a57b19d883f",
"format": 1
},
{
@@ -396,7 +599,42 @@
"name": "meta/runtime.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ad30b0b10736f60b92a231e7f825472184755320479821a6486acbc6b502b4f0",
+ "chksum_sha256": "6872a5ea5042e0a7a43f2b60fe6c02a24e3e76b25deb50a46567df781345e41b",
+ "format": 1
+ },
+ {
+ "name": "molecule",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "molecule/default",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "molecule/default/converge.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "c1e0e02c807ceafdf7bd707e0def1e9d2118e6389af9af44dc832dfc0483dab9",
+ "format": 1
+ },
+ {
+ "name": "molecule/default/molecule.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "93fdbc0ddeba791f7c430b0838ef87de49feb9b0662b8b2f1502b5a949e1c301",
+ "format": 1
+ },
+ {
+ "name": "molecule/default/test_dashboard.json",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ce0f583b94ead7ef7e0ae7e696dc87fefb2ba70106b2fda6cf072f17f8d1a136",
"format": 1
},
{
@@ -424,7 +662,7 @@
"name": "plugins/callback/grafana_annotations.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fac40baac9edab0ff30d12f63ee7d13f29f1dd4777d65f3a3a80d04cffb5a2e2",
+ "chksum_sha256": "2f0a1b0cdb40b90e44dd5c23bba4f65773a163cc92ca26263ca20de5a702e8e0",
"format": 1
},
{
@@ -445,14 +683,14 @@
"name": "plugins/doc_fragments/api_key.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "bb4e6492b954294664aa87ac44bd12ffa42e59ddfcedd693e5a486b42c352dc1",
+ "chksum_sha256": "624cdc3b10d6a2bbdf9cd7d58fa47281658aa8b1377e702a8ecc6ca1f43bf630",
"format": 1
},
{
"name": "plugins/doc_fragments/basic_auth.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fff91970e34eca089abc8275b82957c07acd78889db684281be97252a5b6d27b",
+ "chksum_sha256": "4e16ce6e91408d53d9b482bfdfc1fd5919801aeaa00830e2703bae467fcc3a3d",
"format": 1
},
{
@@ -473,7 +711,7 @@
"name": "plugins/lookup/grafana_dashboard.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a2329d0c45e452ae9c63ed39a921de5aa7b073be4b405eccfde4abdae6603055",
+ "chksum_sha256": "7483dabbd84c95d3cd603e2d9d905b51f00e9f6ab4974164f31387c3ee63535d",
"format": 1
},
{
@@ -487,7 +725,7 @@
"name": "plugins/module_utils/base.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f3a2355da8ff10f76b0a5886d5915556efd87942a640d9f31fb84fe09b4e35c5",
+ "chksum_sha256": "edc463e8bea58732fd5a43b11c31c86b06ca5f5f5af1c81e4c0e1cc8a00ee59c",
"format": 1
},
{
@@ -508,56 +746,126 @@
"name": "plugins/modules/grafana_dashboard.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a941cd951e30bc40d8e50b5f94b6fce724e52c427043a45da3490c7d19b69710",
+ "chksum_sha256": "4f0fa0bd616646667b30cc6373a3983b802704396d0cba184173244b13820b7e",
"format": 1
},
{
"name": "plugins/modules/grafana_datasource.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7da547912f54e294da3ba2bd529a1541e7837e6d59f9657b32af1c842cb13eee",
+ "chksum_sha256": "23081add13f2aba994b4cddb264972d219bee823ac1e4f454931d5a6a374bd94",
"format": 1
},
{
"name": "plugins/modules/grafana_folder.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "3f8b5ff973317b96b2df44d557b4541e3f8878f31c3ac9524e670900a4d94c23",
+ "chksum_sha256": "0690d114c97f3cfabc115b17b1e90c9304737d6681085473f7321365797be9b8",
"format": 1
},
{
"name": "plugins/modules/grafana_notification_channel.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f33607a8e2ab8b641f23e37c13c191d4b536d7f17a0e53167491341f0953ba36",
+ "chksum_sha256": "abfa2ecf38dfa35cfcf4ee3256a0f2f21fb33134669041c613c64522c27511a4",
"format": 1
},
{
"name": "plugins/modules/grafana_organization.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0770da78a9c0c20ecd893ffff6c949757b3d56e69512c074c097af210de62a95",
+ "chksum_sha256": "e3007e6f1b18309adf4c2d591cdf8fe7ff7095e16cb8f712d6118e353e74c4fb",
+ "format": 1
+ },
+ {
+ "name": "plugins/modules/grafana_organization_user.py",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "805358f94bc8d54afb5ceeba18f1539ace43f713c02175441d195837aa96da2e",
"format": 1
},
{
"name": "plugins/modules/grafana_plugin.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d655afaca63400ea116ea4a2f0629b3c9a614e363a3bc587bdfe40404b13865f",
+ "chksum_sha256": "fb0ee164a2936bc35381cf79026b6725c7a1df139e71d58989f8912432043c00",
"format": 1
},
{
"name": "plugins/modules/grafana_team.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "59d95c0432cdc854f7d9176e37c9c0ee0676c27678bbac5a467b762f4985a50e",
+ "chksum_sha256": "1f455f7615dcc33a7612b2dd6e881dbc90d37fadc02bcd1c9b8edcf3c80cc1f5",
"format": 1
},
{
"name": "plugins/modules/grafana_user.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "74081babe6e887d9701f85ad6cfba434d534480b84d8eca89c47c587b7f4400b",
+ "chksum_sha256": "0b1c4c363f47bcdda8f909005816a7f9a87c691050d5123e0b2f3ad2da7cbaed",
+ "format": 1
+ },
+ {
+ "name": "roles",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "roles/grafana",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "roles/grafana/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "roles/grafana/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ee6026b2dd62777a731f2214949124f45d73309102123cad31ad55489a90ca45",
+ "format": 1
+ },
+ {
+ "name": "roles/grafana/meta",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "roles/grafana/meta/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "192ef2ac687cd5594febffbc0ab6f3d184cceed34dc66c11ff217db19f4ccfc2",
+ "format": 1
+ },
+ {
+ "name": "roles/grafana/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "roles/grafana/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "0de2cd11feb7e45f3427d063c3123024f94401bc5c1b48eaecea9716efcc03d5",
+ "format": 1
+ },
+ {
+ "name": "roles/grafana/README.md",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ab4f69856777b7b0c208c3c3d06a9771c98f81a729618dc94df80ea981b1b6ab",
"format": 1
},
{
@@ -599,7 +907,7 @@
"name": "tests/integration/targets/grafana_dashboard/defaults/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1abe5b960f170fe88ae3643d49bb82030dec115a22324db1664f6b52dfc874a8",
+ "chksum_sha256": "3080ff0153745941649566c421bdd85715c4174dc651656a241aef27be424ae7",
"format": 1
},
{
@@ -624,52 +932,59 @@
"format": 1
},
{
+ "name": "tests/integration/targets/grafana_dashboard/tasks/dashboard-by-org-name.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "a43bbb6de9a723b95b69c7c51663f1b4601a58353ca226b63a1df474b800590a",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/grafana_dashboard/tasks/dashboard-export.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5f6af8316c89f6a61b424540b5779682e9a411052b63c94d3d411a926a38cc1a",
+ "chksum_sha256": "6a1fc18ba64dd7e8f1aa7ca2633608e2932e34147acbf2974e8d882ac0087189",
"format": 1
},
{
"name": "tests/integration/targets/grafana_dashboard/tasks/dashboard-folder-destination.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "621fd78f70b4381fc4a346b59f8c71886a74283d439debe973e6a90677322ae1",
+ "chksum_sha256": "23e068c4c5a4d2e77166bc442aa40d61678a09f5923e392bc9ed45be961cd238",
"format": 1
},
{
- "name": "tests/integration/targets/grafana_dashboard/tasks/dashboard-from-file.yml",
+ "name": "tests/integration/targets/grafana_dashboard/tasks/dashboard-from-file-export.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4987b17b353b126c059e60e83ea081eacd83b149d6aeed0ab9d34c013322d574",
+ "chksum_sha256": "3d80e67a2a60f491578a45be9cce19178a9fb675c2fd04932c353d984db9591d",
"format": 1
},
{
"name": "tests/integration/targets/grafana_dashboard/tasks/dashboard-from-id.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "f679381b8db000fb5bf0e1166fd78196a63efc8c0bba4a8917ae02f85e54c295",
+ "chksum_sha256": "d2b528f99db43d1a36c10aedcfca5cf98dd3c34c0087a3d5a0c12ac43871efd1",
"format": 1
},
{
"name": "tests/integration/targets/grafana_dashboard/tasks/dashboard-from-url.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "468c55bbc58254f1e956f8b6eaf318b863e88270f9741a05fd63643d18ced748",
+ "chksum_sha256": "d1bb246bb41e3b47171953bb4194988ae57015b462208287b5e678e157197776",
"format": 1
},
{
"name": "tests/integration/targets/grafana_dashboard/tasks/delete-dashboard.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "abaf3c4b643d2f893fd05849de8ee8f15ed14ae74a24cb9b252db54c64415478",
+ "chksum_sha256": "7544b7ea2374965a6b14ef47c517058ecc614ed2ce388ed96c7301670b4d2a3e",
"format": 1
},
{
"name": "tests/integration/targets/grafana_dashboard/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "83298bca7c6ae5f5467168e5c75dbf34497d458f81258935c1b929126b984916",
+ "chksum_sha256": "9ac539607fab1744739465d19d35eb69337d367f4834f5b260a9f83ccb34a225",
"format": 1
},
{
@@ -680,6 +995,20 @@
"format": 1
},
{
+ "name": "tests/integration/targets/grafana_dashboard/runme.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b9aa6c8dadef0b4ce9cb08a05d0cf6c40f882d04f9e698bff795b26896e8853c",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_dashboard/site.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f30cb92dff7bcfa3c7b92ea0fb4d0cd62d2704f282f9a74bd68a5ba3ac34b142",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/grafana_datasource",
"ftype": "dir",
"chksum_type": null,
@@ -697,7 +1026,7 @@
"name": "tests/integration/targets/grafana_datasource/defaults/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1abe5b960f170fe88ae3643d49bb82030dec115a22324db1664f6b52dfc874a8",
+ "chksum_sha256": "d7d3a06f224d1576e39fcc2083e33261f30e3ceac18506f17772d8bcb72315c2",
"format": 1
},
{
@@ -711,91 +1040,105 @@
"name": "tests/integration/targets/grafana_datasource/tasks/azure.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "19ee9ae9eb2a07401743f0cbe9618c10765b9fe008070344676e9c49aa385a14",
+ "chksum_sha256": "e7ebd714ea8613e5bdfb5ed632526f6435978dfe164e2358cb4d9fa000f7cf65",
"format": 1
},
{
"name": "tests/integration/targets/grafana_datasource/tasks/cloudwatch.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "464c12422283a217c8075285d2ea2c05b005b864ea4437c551701925ff44d7b7",
+ "chksum_sha256": "d3acce4b415027eebf9cef909e2b351fdcf6fadc8fc441da205db041a595010b",
"format": 1
},
{
"name": "tests/integration/targets/grafana_datasource/tasks/elastic.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1635d2de6380a9ee458af3ca590f5640b22381bb12417f6bf4dfbdeebc2f4757",
+ "chksum_sha256": "69fba433ef869f3bb1916f2036a43985af48d21118f08e969f6020532a963d43",
"format": 1
},
{
"name": "tests/integration/targets/grafana_datasource/tasks/errors.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a0d109a1c3408a51bde3d5cf753990c46176d8372164b7e4a2f681dae3920352",
+ "chksum_sha256": "10fac33e0d5bb44d834579e719c498e4e0eb91535625881bb8cb027dc778c39a",
"format": 1
},
{
"name": "tests/integration/targets/grafana_datasource/tasks/influx.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2ce76fc18d2405a0ac4964cac4b6aa2a6685788c98bc42a1b2de3ac8e907e02b",
+ "chksum_sha256": "7852e7f6e7cb6bd5359a29766fa1810faead04e5760536dc5812fafdf32c7e67",
"format": 1
},
{
"name": "tests/integration/targets/grafana_datasource/tasks/issues.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "432147d3f437fb0438de8e13581d6c878ef9f74c4fdf8c2c343be2772003608d",
+ "chksum_sha256": "4ea6ef2c0ff7ab17d4f454b0aca0429dba3bed373b9e7e9f45679354bbb197b6",
"format": 1
},
{
"name": "tests/integration/targets/grafana_datasource/tasks/loki.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9a4b7278d0b86f6a140f618fae5ca135078c4e2c6f45c5c9ce1d392e5bc51e00",
+ "chksum_sha256": "7f6a14c7eb76ee8c8846955ff98bd71c082b741dc1d67b5c7e0f2dd188eea8de",
"format": 1
},
{
"name": "tests/integration/targets/grafana_datasource/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "721d230780309d65c7e436717d0c5097886a4d8952c51b4a3b60ee6191f37a8f",
+ "chksum_sha256": "713a162941560a20ecadd97bd185b09e8a0073451286554ead9c7a8deb71b08f",
"format": 1
},
{
"name": "tests/integration/targets/grafana_datasource/tasks/postgres.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "705a43192be5211f28a87f6b4123859b98fe8b286ba340a3baf0cc6331afcd99",
+ "chksum_sha256": "4ed316aab332c0dfcc005213ef28087ea49ed011c0a73bdd0e5f8481e9403de4",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_datasource/tasks/quickwit.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "3a2adf0e3207fe51808c044312d537f11321cf0b685eb4f1e01f1dfdafad54e9",
"format": 1
},
{
"name": "tests/integration/targets/grafana_datasource/tasks/redis.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "95b32572dabe963cc378c6256b442febb157a41aac8a88b7dfe8aee9010a4bb2",
+ "chksum_sha256": "18869fb58bfbd29d666c02c18a25050fdd87fb6efe6f3945c7d472ab00addc22",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_datasource/tasks/tempo.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "d9626fb7988f6c16a407d15d0397a4a2fee1b4a25ec1e8c256441afcdcfdbfa4",
"format": 1
},
{
"name": "tests/integration/targets/grafana_datasource/tasks/thruk.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "305abe7c14283b27645b7cf40e6e72f37d7c981cf4ec8802624534cbd566bee6",
+ "chksum_sha256": "40964d1ada4844b2896d15e8d6291fcc3cce2de461e23d6a484271ecbe01bea4",
"format": 1
},
{
"name": "tests/integration/targets/grafana_datasource/tasks/uid.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "08990e1b6427c88c54e19eb5bb1ecf7982e82225398dc99df095a8a8d757290b",
+ "chksum_sha256": "3cd162f42bd87ed70b42a7f1eec4465f46470f959e1995d4da16ba7c985cbab5",
"format": 1
},
{
"name": "tests/integration/targets/grafana_datasource/tasks/zabbix.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c6a9c292a023c3da296ac2bd326b90c376b2302e07ce94808172313891421f36",
+ "chksum_sha256": "c2871a04f46eea697114ace8a8ed977e35db18617b6d7d605895d8dc42231d70",
"format": 1
},
{
@@ -806,6 +1149,20 @@
"format": 1
},
{
+ "name": "tests/integration/targets/grafana_datasource/runme.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b9aa6c8dadef0b4ce9cb08a05d0cf6c40f882d04f9e698bff795b26896e8853c",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_datasource/site.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "16d7e16475eb96288139560e75d3f538a276ce843d42c922b73bcbdb3061129e",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/grafana_folder",
"ftype": "dir",
"chksum_type": null,
@@ -823,7 +1180,7 @@
"name": "tests/integration/targets/grafana_folder/defaults/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1abe5b960f170fe88ae3643d49bb82030dec115a22324db1664f6b52dfc874a8",
+ "chksum_sha256": "d7d3a06f224d1576e39fcc2083e33261f30e3ceac18506f17772d8bcb72315c2",
"format": 1
},
{
@@ -834,10 +1191,38 @@
"format": 1
},
{
+ "name": "tests/integration/targets/grafana_folder/tasks/create-delete.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "122f5e9db2674a05c1ee476e946dae3a04e3cd321665c7db71b2cba315097d20",
+ "format": 1
+ },
+ {
"name": "tests/integration/targets/grafana_folder/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "47bc05ebcddd2fe27fa914c732be64a7c2c6378578d5c8cb6429d73f25d355f5",
+ "chksum_sha256": "ff5d04e49ad1db4a7020371f3aac554a0f92221b317cd8dba41aade14495a32d",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_folder/tasks/org.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f334b190c923087495214249c3d63199bfdbd9c16b92f3402ab0bbdd4baceee7",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_folder/runme.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f93043b637d08213e98b76e867cf233123d527d183441230d495fd192ebb0ebe",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_folder/site.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "826699299c1afe13404ece8b0ba37677617244fa6d31479b94ef8fceb86ba40a",
"format": 1
},
{
@@ -858,7 +1243,7 @@
"name": "tests/integration/targets/grafana_notification_channel/defaults/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1abe5b960f170fe88ae3643d49bb82030dec115a22324db1664f6b52dfc874a8",
+ "chksum_sha256": "d7d3a06f224d1576e39fcc2083e33261f30e3ceac18506f17772d8bcb72315c2",
"format": 1
},
{
@@ -872,133 +1257,147 @@
"name": "tests/integration/targets/grafana_notification_channel/tasks/dingding.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "20be703a675310b8986c39720a30cbca5697519aeee1036d735af61608a66cc8",
+ "chksum_sha256": "71fe4171eff7055caae552fd9baf97bf09ddbab7ea9f4d30ad0329fd0ee57ba5",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/discord.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a24f0816c122f278575acf3269028c027d7056350213d5bf79d7e32a87cabb92",
+ "chksum_sha256": "783aedab3656a22446c4d7d66cb73b9098a0a417501618314e8ee016c7f823e7",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/email.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "70de3340f20f09e20f1a9f6bcb9cdc71133e9d3ca5299a56e29ded8941402c4e",
+ "chksum_sha256": "bae730db1d3ae0f9c48b620910e22e084fbb2cd78435cded44d08aab03c49017",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/googlechat.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a8fc0c11896c5831c6295818e9a2142b51906a1d3b32ca2865f8323be48d8dfe",
+ "chksum_sha256": "ed076cea03274dc08b91cfe11440f7d9ed56991192ec8e4ce5fc6aead9932d50",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/hipchat.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "fbe650e907a7327d069f72b0077cd563cb7016cbf6d51703bf5f463c7e22488b",
+ "chksum_sha256": "974a0df2c6fbc614f3cb0110a72437744b528d057fcd07065754e1f0d075f572",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/kafka.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "eb784a102669f4f2d087ae644c63f7f2e09e60363b47acea59ccce9299b3ed78",
+ "chksum_sha256": "d911f680a1dab3c7c6ca24062b07daa650c14cf95d41bb4b3b5f1a03f82bea8e",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/line.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a997b83ad729061f48299a94c609db3eab3f315f4febc86d3e97bc06c0263fec",
+ "chksum_sha256": "0793dcafac5c6baadd8f807f5738b0f43c1043fcaf5461548608a3f788144900",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "603d4be7ff5a3e2685e3e0c2bc51a526222d29c20f63a4b7d301110566a4f765",
+ "chksum_sha256": "3928211b941d3ec67d73d44122519b76364772a9ab79c731a8b5e5f22e46078b",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/opsgenie.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0a3eb750d61a5a3d26434f25b09681a5ac3b27f94bb6d72eb2879e4a5157194d",
+ "chksum_sha256": "10a080ac4ab19d1c2ab7e2c1e1558acb7e11a3e75ae3c7ed3f90f56ef9425fef",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/pagerduty.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d781b916d195e780653185c46aae0cf5007dbc9c92920cd380203164c7512d4e",
+ "chksum_sha256": "5988e630d581c1c2d715e5f617104c8e8ecabb8ecc2c85d18491b3ba16e7ff8c",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/prometheus.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "d893bb8c7f3cddacce404325ce903c5f91d1760ebf17b123a9e2ec58b9d262c6",
+ "chksum_sha256": "abf6e31f7f4485b1b1821e178cd90063572726958c26e724ccc2f0417d8b5999",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/pushover.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1f7313a53d5d3e38de3f79fe1c89be297eac4ffe366cb88872b989354f3beb6a",
+ "chksum_sha256": "afaf52cddb757eb1a5ad988e5ac07638269d9e8669136db07f6d909d7b9f74f9",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/sensu.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "542998ba92afda7d9e84204f4792be3f094059fe3b3aa85ec4f8cd8ca8e1f7f5",
+ "chksum_sha256": "cfa23b2fdd7f2aa998f568177dc029a92c10b00492a6dcb9c575d8aaf06af9a4",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/slack-and-beyond.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5e07153d379c3ed98207b7a9cab4e291962ecf2b493c78e430bb187ad77b3553",
+ "chksum_sha256": "8666a93b31846da1f4eef2e632a1e9c1d62dc765691733647b828229dd16f2f4",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/teams.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9cf484e386db1b5f0b39a97e419127c0c23ef016a8cdf307a46f1a43b6d13b50",
+ "chksum_sha256": "b95ee61e08caf11be5917c421e82feab4e108c5bd05d7eca2804e0bf3dfa69dd",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/telegram.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "881e193e76bc7c63213ccc4d29e9e91831618760edfa33b4d80381799d5684b4",
+ "chksum_sha256": "5ef4e24ceb5a814dde62620e98f3d47cd748fa0800ff5db398aa4a8726ee3b4f",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/threema.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ab5586f7f1be5494b306bc7db62bd147f76f8d9c2269d3109b4d20ea7ca27e5b",
+ "chksum_sha256": "dc35cc7b06bd8f2c4194ccad905bb3aa66053c8f30b2fa6c67626a798710b096",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/victorops.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "6676ea8941ac8758a8b7b68c0d620a02fba4aa46a3208a6143dac3c23a4359c0",
+ "chksum_sha256": "2da1bc74d6e1dc2ecfbf2625c9228a13e72015a37a646baa65343fe0dd4f57b1",
"format": 1
},
{
"name": "tests/integration/targets/grafana_notification_channel/tasks/webhook.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "7c9625e9e31301fc7ffa49c384b211f2d68fba895f8358eafd403403de023acc",
+ "chksum_sha256": "ab506c8c1fc656f62b8bfa34d5ac877086ce6918b7282e22f5d2c0d88cd97475",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_notification_channel/runme.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b9aa6c8dadef0b4ce9cb08a05d0cf6c40f882d04f9e698bff795b26896e8853c",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_notification_channel/site.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "6b38ec20b7346f0bd7ad39edb98487a6c123d3e0c5a86671ab5f81bc6f77d30c",
"format": 1
},
{
@@ -1019,7 +1418,7 @@
"name": "tests/integration/targets/grafana_organization/defaults/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5a300746bed6ecd05371181b97507a46472e5379002f23590c6d3a38b576be68",
+ "chksum_sha256": "3080ff0153745941649566c421bdd85715c4174dc651656a241aef27be424ae7",
"format": 1
},
{
@@ -1033,7 +1432,70 @@
"name": "tests/integration/targets/grafana_organization/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "49205778d4eacf15c53b6b0e69f3f78c02cb758d235a64636523c82fec9a26e0",
+ "chksum_sha256": "5fe8af2ef9401defb8f328e0a24b4184bf1e3309aa8be51c983b34edaa85f234",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_organization/runme.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f93043b637d08213e98b76e867cf233123d527d183441230d495fd192ebb0ebe",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_organization/site.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b29bfe7832b74990a2f2a34f268d16946dca7a1fce852b4ef6c29106ffdc510f",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_organization_user",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_organization_user/defaults",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_organization_user/defaults/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "3080ff0153745941649566c421bdd85715c4174dc651656a241aef27be424ae7",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_organization_user/tasks",
+ "ftype": "dir",
+ "chksum_type": null,
+ "chksum_sha256": null,
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_organization_user/tasks/main.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "4886c04060faeb0617ab4637269d4ba52279e36169cc508e6231ea63773a38b9",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_organization_user/runme.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f93043b637d08213e98b76e867cf233123d527d183441230d495fd192ebb0ebe",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_organization_user/site.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "ff14af15f86f7b705bbc2505639b15edbd8124af4653a8ae12681ea05ac766fd",
"format": 1
},
{
@@ -1054,7 +1516,7 @@
"name": "tests/integration/targets/grafana_team/defaults/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1abe5b960f170fe88ae3643d49bb82030dec115a22324db1664f6b52dfc874a8",
+ "chksum_sha256": "d7d3a06f224d1576e39fcc2083e33261f30e3ceac18506f17772d8bcb72315c2",
"format": 1
},
{
@@ -1068,14 +1530,28 @@
"name": "tests/integration/targets/grafana_team/tasks/create_user.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "1c95f96aaaf709c403a815f6bee8ffe0e1a0acf4bf860b04b84fdeb1e2640d70",
+ "chksum_sha256": "4d64425f6cc9da06d28a9ca5332b1056b01d65396a5a59f8f0d7c592f6f028b3",
"format": 1
},
{
"name": "tests/integration/targets/grafana_team/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "849f63851576fe7d459f0e69380fbf6915606bbdebf3836d36301d594ddde9e7",
+ "chksum_sha256": "3a251b9f1794ca36ff3d9025145ad0f639082d3185772115fdac6eeda2fab8b2",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_team/runme.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "b9aa6c8dadef0b4ce9cb08a05d0cf6c40f882d04f9e698bff795b26896e8853c",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_team/site.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e729b0be1c515ad93b175d7f024bae9232365faaa68a4506b47967447dfa7e65",
"format": 1
},
{
@@ -1096,7 +1572,7 @@
"name": "tests/integration/targets/grafana_user/defaults/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5a300746bed6ecd05371181b97507a46472e5379002f23590c6d3a38b576be68",
+ "chksum_sha256": "3080ff0153745941649566c421bdd85715c4174dc651656a241aef27be424ae7",
"format": 1
},
{
@@ -1110,7 +1586,21 @@
"name": "tests/integration/targets/grafana_user/tasks/main.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "dee06bc10461e6607b56babd7767b70336a3469ba2fcbc687a3f430b4b89e42c",
+ "chksum_sha256": "b87f7be9298d38992197ddba80c4a9049a314604867772780040e53f6a1a2368",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_user/runme.sh",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "f93043b637d08213e98b76e867cf233123d527d183441230d495fd192ebb0ebe",
+ "format": 1
+ },
+ {
+ "name": "tests/integration/targets/grafana_user/site.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e19f63916db02291f7340bcfbaadde68e2063c98ebd570151e51b2590ba55006",
"format": 1
},
{
@@ -1163,6 +1653,20 @@
"format": 1
},
{
+ "name": "tests/sanity/ignore-2.16.txt",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "0908af1f4e86722688b3f158cfa9cc81c931ef40c0a166c398f47a4af69a93f9",
+ "format": 1
+ },
+ {
+ "name": "tests/sanity/ignore-2.17.txt",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "0908af1f4e86722688b3f158cfa9cc81c931ef40c0a166c398f47a4af69a93f9",
+ "format": 1
+ },
+ {
"name": "tests/sanity/ignore-2.9.txt",
"ftype": "file",
"chksum_type": "sha256",
@@ -1201,7 +1705,7 @@
"name": "tests/unit/modules/grafana/grafana_datasource/test_grafana_datasource.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "a2e07e9ebe4ff689cf3a7a6f17fe7a15bb498787d3f34b2b04e8c6a60faec054",
+ "chksum_sha256": "f7163648b75242c0acbfe2b3cd911ae3119107bfe9578019443fe887b0f6dbf9",
"format": 1
},
{
@@ -1215,7 +1719,7 @@
"name": "tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "c7b7015b793f75de5c19cd95772a8aaa170eca6e508a305755f61ae11495e4f1",
+ "chksum_sha256": "ada20cb8aef9852aee7b79afddd78f144f813c9df55baf3b8adc1b3863a8e9db",
"format": 1
},
{
@@ -1229,7 +1733,7 @@
"name": "tests/unit/modules/grafana/grafana_team/test_grafana_team.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "96116b92002f89708a978cf54ba9209234bc65622b82ea37f67b942a8d19b849",
+ "chksum_sha256": "53ca8d47d277ebe320b112ccc59a91e6cd0eae6194eecc1991b8e08977fa2c96",
"format": 1
},
{
@@ -1243,7 +1747,7 @@
"name": "tests/unit/modules/grafana/grafana_user/test_grafana_user.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "ebe4eca4179be5a9780ef606dbd01da1e8512df914b9d576a256a9f0b72c66bb",
+ "chksum_sha256": "02409b123e54c08c9c5e3ce8bdd0213464c00659490873e07cbfbfdc2cec7c7c",
"format": 1
},
{
@@ -1254,24 +1758,31 @@
"format": 1
},
{
+ "name": "tests/requirements.yml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "697e4332a08c9c12c77188df7cf1e687151c9d77e61a3b08f879a825d869f6b4",
+ "format": 1
+ },
+ {
"name": ".all-contributorsrc",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2ef91cc790e39c200094615d52b2d5a7efcddf6ec2f95d1324a5664b8ed5f35b",
+ "chksum_sha256": "00fabf54b7d76fb7d88baea1a20fcfb7e5f3b3a11532d9b8bc474a063bc98a8c",
"format": 1
},
{
"name": ".gitignore",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "0a44bd2b8e7c35cfad385b8f440c3ec6ebcf8bd10248cf5925d2ceacc92f8078",
+ "chksum_sha256": "b42461ab9570bb951c6614a223aab90b258464234d72e53bfb3853ec69006c5e",
"format": 1
},
{
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4840bdb66ca2d031a29df53e3a2e7f9bf3da209fb1fb6ef9a4c6284e6791c56b",
+ "chksum_sha256": "e20df0ad2408ce9c311cf3bf18c99b2362c6eee388db48286b13be28ecedd8db",
"format": 1
},
{
@@ -1285,14 +1796,21 @@
"name": "README.md",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "5b3523fbf8ffe4c3f7f503f6e63c294c33d0d074588d9e1f278b035676c34336",
+ "chksum_sha256": "8e93c6a3ce656865252643666a94835e98d904107d7a678f0a74774445f91125",
"format": 1
},
{
"name": "codecov.yml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "4b37d1d2f2d4ddf5ad85e350ea6e0b6c18b1d09de82807847a230883a19abde4",
+ "chksum_sha256": "187229d57b799f65a9da46cafe34a880c14240022bdbb9b8d447a85de31aa02c",
+ "format": 1
+ },
+ {
+ "name": "ruff.toml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "9b50c21301c083a2c248259c891bed4403e917cc268ffc236f652e73e2869c15",
"format": 1
}
],
diff --git a/ansible_collections/community/grafana/MANIFEST.json b/ansible_collections/community/grafana/MANIFEST.json
index e1c676340..71f9afdc1 100644
--- a/ansible_collections/community/grafana/MANIFEST.json
+++ b/ansible_collections/community/grafana/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "community",
"name": "grafana",
- "version": "1.5.4",
+ "version": "1.8.0",
"authors": [
"R\u00e9mi REY (@rrey)",
"Thierry Sall\u00e9 (@seuf)"
@@ -25,7 +25,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "035021ce8ce32b6ab7857a4f7acf48a7911b14c718c7f9625ead4d097e51788d",
+ "chksum_sha256": "98a10c2378e1ad46d7031d895c557d33af10809314832b9e3af5c2e607099e0b",
"format": 1
},
"format": 1
diff --git a/ansible_collections/community/grafana/README.md b/ansible_collections/community/grafana/README.md
index bf416426d..6d23f1b96 100644
--- a/ansible_collections/community/grafana/README.md
+++ b/ansible_collections/community/grafana/README.md
@@ -3,7 +3,7 @@
![](https://github.com/ansible-collections/grafana/workflows/CI/badge.svg?branch=master)
[![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/community.grafana)](https://codecov.io/gh/ansible-collections/community.grafana)
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
-[![All Contributors](https://img.shields.io/badge/all_contributors-18-orange.svg?style=flat-square)](#contributors-)
+[![All Contributors](https://img.shields.io/badge/all_contributors-20-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->
This repo hosts the `community.grafana` Ansible Collection.
@@ -27,6 +27,7 @@ Click on the name of a plugin or module to view that content's documentation:
- [grafana_folder](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_folder_module.html)
- [grafana_notification_channel](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_notification_channel_module.html)
- [grafana_organization](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_organization_module.html)
+ - [grafana_organization_user](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_organization_user_module.html)
- [grafana_plugin](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_plugin_module.html)
- [grafana_team](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_team_module.html)
- [grafana_user](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_user_module.html)
@@ -36,7 +37,7 @@ Click on the name of a plugin or module to view that content's documentation:
We aim at keeping the last 3 Major versions of Grafana tested.
This collection is currently testing the modules against following versions of Grafana:
```
-grafana_version: ["9.2.6", "8.5.15", "7.5.16"]
+grafana_version: ["9.5.14", "8.5.27", "10.2.2"]
```
## Installation and Usage
@@ -66,12 +67,9 @@ You can either call modules by their Fully Qualified Collection Namespace (FQCN)
gather_facts: false
connection: local
- collections:
- - community.grafana
-
tasks:
- name: Ensure Influxdb datasource exists.
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: "datasource-influxdb"
grafana_url: "https://grafana.company.com"
grafana_user: "admin"
@@ -92,13 +90,11 @@ In your playbooks, you can set [module defaults](https://github.com/ansible/ansi
```yaml
+---
- hosts: localhost
gather_facts: false
connection: local
- collections:
- - community.grafana
-
module_defaults:
group/community.grafana.grafana:
grafana_url: "https://grafana.company.com"
@@ -107,7 +103,7 @@ In your playbooks, you can set [module defaults](https://github.com/ansible/ansi
tasks:
- name: Ensure Influxdb datasource exists.
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: "datasource-influxdb"
org_id: "1"
ds_type: "influxdb"
@@ -117,7 +113,7 @@ In your playbooks, you can set [module defaults](https://github.com/ansible/ansi
tls_ca_cert: "/etc/ssl/certs/ca.pem"
- name: Create or update a Grafana user
- grafana_user:
+ community.grafana.grafana_user:
name: "Bruce Wayne"
email: "batman@gotham.city"
login: "batman"
@@ -184,6 +180,7 @@ Any contribution is welcome and we only ask contributors to:
* Provide *at least* integration tests for any contribution.
* The Pull Request *MUST* contain a changelog fragment. See [Ansible documentation](https://docs.ansible.com/ansible/latest/community/development_process.html#creating-a-changelog-fragment) about fragments.
* Create an issue for any significant contribution that would change a large portion of the code base.
+* Use [ruff](https://github.com/astral-sh/ruff) to lint and [black](https://github.com/psf/black) to format your changes on python code.
## Contributors ✨
@@ -195,28 +192,30 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<table>
<tbody>
<tr>
- <td align="center"><a href="https://github.com/gundalow"><img src="https://avatars1.githubusercontent.com/u/940557?v=4?s=100" width="100px;" alt="John R Barker"/><br /><sub><b>John R Barker</b></sub></a><br /><a href="#infra-gundalow" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=gundalow" title="Tests">⚠️</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=gundalow" title="Code">💻</a></td>
- <td align="center"><a href="https://github.com/rrey"><img src="https://avatars1.githubusercontent.com/u/2752379?v=4?s=100" width="100px;" alt="Rémi REY"/><br /><sub><b>Rémi REY</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=rrey" title="Tests">⚠️</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=rrey" title="Documentation">📖</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=rrey" title="Code">💻</a></td>
- <td align="center"><a href="https://aperogeek.fr"><img src="https://avatars1.githubusercontent.com/u/1336359?v=4?s=100" width="100px;" alt="Thierry Sallé"/><br /><sub><b>Thierry Sallé</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=seuf" title="Code">💻</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=seuf" title="Tests">⚠️</a></td>
- <td align="center"><a href="http://antoine.tanzil.li"><img src="https://avatars0.githubusercontent.com/u/1068018?v=4?s=100" width="100px;" alt="Antoine"/><br /><sub><b>Antoine</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=Tailzip" title="Code">💻</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=Tailzip" title="Tests">⚠️</a></td>
- <td align="center"><a href="https://github.com/pomverte"><img src="https://avatars0.githubusercontent.com/u/695230?v=4?s=100" width="100px;" alt="hvle"/><br /><sub><b>hvle</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=pomverte" title="Code">💻</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=pomverte" title="Tests">⚠️</a></td>
- <td align="center"><a href="https://github.com/jual"><img src="https://avatars2.githubusercontent.com/u/4416541?v=4?s=100" width="100px;" alt="jual"/><br /><sub><b>jual</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=jual" title="Code">💻</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=jual" title="Tests">⚠️</a></td>
- <td align="center"><a href="https://github.com/MCyprien"><img src="https://avatars2.githubusercontent.com/u/11160859?v=4?s=100" width="100px;" alt="MCyprien"/><br /><sub><b>MCyprien</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=MCyprien" title="Code">💻</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=MCyprien" title="Tests">⚠️</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/gundalow"><img src="https://avatars1.githubusercontent.com/u/940557?v=4?s=100" width="100px;" alt="John R Barker"/><br /><sub><b>John R Barker</b></sub></a><br /><a href="#infra-gundalow" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=gundalow" title="Tests">⚠️</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=gundalow" title="Code">💻</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/rrey"><img src="https://avatars1.githubusercontent.com/u/2752379?v=4?s=100" width="100px;" alt="Rémi REY"/><br /><sub><b>Rémi REY</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=rrey" title="Tests">⚠️</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=rrey" title="Documentation">📖</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=rrey" title="Code">💻</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://aperogeek.fr"><img src="https://avatars1.githubusercontent.com/u/1336359?v=4?s=100" width="100px;" alt="Thierry Sallé"/><br /><sub><b>Thierry Sallé</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=seuf" title="Code">💻</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=seuf" title="Tests">⚠️</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="http://antoine.tanzil.li"><img src="https://avatars0.githubusercontent.com/u/1068018?v=4?s=100" width="100px;" alt="Antoine"/><br /><sub><b>Antoine</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=Tailzip" title="Code">💻</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=Tailzip" title="Tests">⚠️</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/pomverte"><img src="https://avatars0.githubusercontent.com/u/695230?v=4?s=100" width="100px;" alt="hvle"/><br /><sub><b>hvle</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=pomverte" title="Code">💻</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=pomverte" title="Tests">⚠️</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/jual"><img src="https://avatars2.githubusercontent.com/u/4416541?v=4?s=100" width="100px;" alt="jual"/><br /><sub><b>jual</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=jual" title="Code">💻</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=jual" title="Tests">⚠️</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/MCyprien"><img src="https://avatars2.githubusercontent.com/u/11160859?v=4?s=100" width="100px;" alt="MCyprien"/><br /><sub><b>MCyprien</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=MCyprien" title="Code">💻</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=MCyprien" title="Tests">⚠️</a></td>
</tr>
<tr>
- <td align="center"><a href="https://twitter.com/RealRockaut"><img src="https://avatars0.githubusercontent.com/u/453368?v=4?s=100" width="100px;" alt="Markus Fischbacher"/><br /><sub><b>Markus Fischbacher</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=rockaut" title="Code">💻</a></td>
- <td align="center"><a href="https://github.com/rverchere"><img src="https://avatars3.githubusercontent.com/u/232433?v=4?s=100" width="100px;" alt="Remi Verchere"/><br /><sub><b>Remi Verchere</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=rverchere" title="Code">💻</a></td>
- <td align="center"><a href="http://akasurde.github.io"><img src="https://avatars1.githubusercontent.com/u/633765?v=4?s=100" width="100px;" alt="Abhijeet Kasurde"/><br /><sub><b>Abhijeet Kasurde</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=Akasurde" title="Documentation">📖</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=Akasurde" title="Tests">⚠️</a></td>
- <td align="center"><a href="https://github.com/martinwangjian"><img src="https://avatars2.githubusercontent.com/u/1770277?v=4?s=100" width="100px;" alt="martinwangjian"/><br /><sub><b>martinwangjian</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=martinwangjian" title="Code">💻</a></td>
- <td align="center"><a href="https://github.com/CWollinger"><img src="https://avatars2.githubusercontent.com/u/11299733?v=4?s=100" width="100px;" alt="cwollinger"/><br /><sub><b>cwollinger</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=cwollinger" title="Code">💻</a></td>
- <td align="center"><a href="https://github.com/Andersson007"><img src="https://avatars3.githubusercontent.com/u/34477873?v=4?s=100" width="100px;" alt="Andrew Klychkov"/><br /><sub><b>Andrew Klychkov</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=Andersson007" title="Code">💻</a></td>
- <td align="center"><a href="https://github.com/vnea"><img src="https://avatars.githubusercontent.com/u/10775422?v=4?s=100" width="100px;" alt="Victor"/><br /><sub><b>Victor</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=vnea" title="Code">💻</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://twitter.com/RealRockaut"><img src="https://avatars0.githubusercontent.com/u/453368?v=4?s=100" width="100px;" alt="Markus Fischbacher"/><br /><sub><b>Markus Fischbacher</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=rockaut" title="Code">💻</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/rverchere"><img src="https://avatars3.githubusercontent.com/u/232433?v=4?s=100" width="100px;" alt="Remi Verchere"/><br /><sub><b>Remi Verchere</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=rverchere" title="Code">💻</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="http://akasurde.github.io"><img src="https://avatars1.githubusercontent.com/u/633765?v=4?s=100" width="100px;" alt="Abhijeet Kasurde"/><br /><sub><b>Abhijeet Kasurde</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=Akasurde" title="Documentation">📖</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=Akasurde" title="Tests">⚠️</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/martinwangjian"><img src="https://avatars2.githubusercontent.com/u/1770277?v=4?s=100" width="100px;" alt="martinwangjian"/><br /><sub><b>martinwangjian</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=martinwangjian" title="Code">💻</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/CWollinger"><img src="https://avatars2.githubusercontent.com/u/11299733?v=4?s=100" width="100px;" alt="cwollinger"/><br /><sub><b>cwollinger</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=cwollinger" title="Code">💻</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/Andersson007"><img src="https://avatars3.githubusercontent.com/u/34477873?v=4?s=100" width="100px;" alt="Andrew Klychkov"/><br /><sub><b>Andrew Klychkov</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=Andersson007" title="Code">💻</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/vnea"><img src="https://avatars.githubusercontent.com/u/10775422?v=4?s=100" width="100px;" alt="Victor"/><br /><sub><b>Victor</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=vnea" title="Code">💻</a></td>
</tr>
<tr>
- <td align="center"><a href="https://github.com/paytroff"><img src="https://avatars.githubusercontent.com/u/93038288?v=4?s=100" width="100px;" alt="paytroff"/><br /><sub><b>paytroff</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=paytroff" title="Code">💻</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=paytroff" title="Tests">⚠️</a></td>
- <td align="center"><a href="https://github.com/jseiser"><img src="https://avatars.githubusercontent.com/u/4855527?v=4?s=100" width="100px;" alt="Justin Seiser"/><br /><sub><b>Justin Seiser</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=jseiser" title="Code">💻</a></td>
- <td align="center"><a href="https://github.com/prndrbr"><img src="https://avatars.githubusercontent.com/u/96344856?v=4?s=100" width="100px;" alt="Pierre"/><br /><sub><b>Pierre</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/issues?q=author%3Aprndrbr" title="Bug reports">🐛</a></td>
- <td align="center"><a href="https://github.com/miksonx"><img src="https://avatars.githubusercontent.com/u/5308184?v=4?s=100" width="100px;" alt="MiksonX"/><br /><sub><b>MiksonX</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/issues?q=author%3Amiksonx" title="Bug reports">🐛</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/paytroff"><img src="https://avatars.githubusercontent.com/u/93038288?v=4?s=100" width="100px;" alt="paytroff"/><br /><sub><b>paytroff</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=paytroff" title="Code">💻</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=paytroff" title="Tests">⚠️</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/jseiser"><img src="https://avatars.githubusercontent.com/u/4855527?v=4?s=100" width="100px;" alt="Justin Seiser"/><br /><sub><b>Justin Seiser</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=jseiser" title="Code">💻</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/prndrbr"><img src="https://avatars.githubusercontent.com/u/96344856?v=4?s=100" width="100px;" alt="Pierre"/><br /><sub><b>Pierre</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/issues?q=author%3Aprndrbr" title="Bug reports">🐛</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/miksonx"><img src="https://avatars.githubusercontent.com/u/5308184?v=4?s=100" width="100px;" alt="MiksonX"/><br /><sub><b>MiksonX</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/issues?q=author%3Amiksonx" title="Bug reports">🐛</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/amenzhinsky"><img src="https://avatars.githubusercontent.com/u/1308953?v=4?s=100" width="100px;" alt="Aliaksandr Mianzhynski"/><br /><sub><b>Aliaksandr Mianzhynski</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/commits?author=amenzhinsky" title="Code">💻</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=amenzhinsky" title="Tests">⚠️</a></td>
+ <td align="center" valign="top" width="14.28%"><a href="https://nemental.de"><img src="https://avatars.githubusercontent.com/u/15136847?v=4?s=100" width="100px;" alt="Moritz"/><br /><sub><b>Moritz</b></sub></a><br /><a href="https://github.com/ansible-collections/community.grafana/issues?q=author%3ANemental" title="Bug reports">🐛</a> <a href="https://github.com/ansible-collections/community.grafana/commits?author=Nemental" title="Code">💻</a></td>
</tr>
</tbody>
</table>
diff --git a/ansible_collections/community/grafana/changelogs/changelog.yaml b/ansible_collections/community/grafana/changelogs/changelog.yaml
index 6166fe7a3..465b42bc3 100644
--- a/ansible_collections/community/grafana/changelogs/changelog.yaml
+++ b/ansible_collections/community/grafana/changelogs/changelog.yaml
@@ -207,3 +207,75 @@ releases:
- 277-gha-ansible-test-versions.yml
- 288_get_actual_org_encode.yml
release_date: '2023-02-07'
+ 1.6.0:
+ changes:
+ minor_changes:
+ - Add `grafana_organization_user` module
+ fragments:
+ - 242_add_grafana_organization_user_module.yml
+ modules:
+ - description: Manage Grafana Organization Users.
+ name: grafana_organization_user
+ namespace: ''
+ release_date: '2023-02-19'
+ 1.6.1:
+ changes:
+ bugfixes:
+ - Fix error with datasources configured without basicAuth
+ - grafana_folder, fix an issue during delete (starting Grafana 9.3)
+ minor_changes:
+ - Bump version of Python used in tests to 3.10
+ - Enable datasource option `time_interval` for prometheus
+ - Fix documentation url for Ansible doc website
+ - Now testing against Grafana 9.5.13, 8.5.27, 10.2.0
+ fragments:
+ - 285_fix_doc.yml
+ - 294-bump-grafana-version.yml
+ - 300_datasource_prometheus_time_interval.yml
+ - fix-316.yml
+ release_date: '2023-11-05'
+ 1.7.0:
+ changes:
+ bugfixes:
+ - Add `grafana_organiazion_user` to `action_groups.grafana`
+ - Fixed orgId handling in diff comparison for `grafana_datasource` if using
+ org_name
+ minor_changes:
+ - Add Quickwit search engine datasource (https://quickwit.io).
+ - Add parameter `org_name` to `grafana_dashboard`
+ - Add parameter `org_name` to `grafana_datasource`
+ - Add parameter `org_name` to `grafana_organization_user`
+ - Add support for Grafana Tempo datasource type (https://grafana.com/docs/grafana/latest/datasources/tempo/)
+ - default to true/false in docs and code
+ fragments:
+ - 238_checkmode.yml
+ - 308_datasource_quickwit.yml
+ - 318-org_users_by_org_name.yml
+ - 321-action-groups-org-users.yml
+ - 324_formatting.yml
+ - 325_linting.yml
+ - 325_true_false.yml
+ - 331-dashboard-by-org-name.yml
+ - 332-datasource-by-org-name.yml
+ - 335-add-datasource-type-tempo.yml
+ - 339-lint-black.yml
+ - 341-lint-ruff.yml
+ - 342-ruff-findings.yml
+ - 345-datasource-compare-diff-orgid.yml
+ release_date: '2024-01-17'
+ 1.8.0:
+ changes:
+ bugfixes:
+ - 'test: replace deprecated `TestCase.assertEquals` to support Python 3.12'
+ minor_changes:
+ - Manage `grafana_folder` for organizations
+ - Merged ansible role telekom-mms/ansible-role-grafana into ansible-collections/community.grafana
+ - added `community.grafana.notification_channel` to role
+ - grafana_dashboard - add check_mode support
+ fragments:
+ - 311_dashboard_check_mode.yml
+ - 343-telekom-mms-role.yml
+ - 347-folder-for-orgs.yml
+ - 349-role-notification-channel.yml
+ - 350-python3.12.yml
+ release_date: '2024-02-21'
diff --git a/ansible_collections/community/grafana/changelogs/fragments/238_checkmode.yml b/ansible_collections/community/grafana/changelogs/fragments/238_checkmode.yml
new file mode 100644
index 000000000..81785b52d
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/238_checkmode.yml
@@ -0,0 +1,2 @@
+trivial:
+ - run integration tests in check-mode.
diff --git a/ansible_collections/community/grafana/changelogs/fragments/242_add_grafana_organization_user_module.yml b/ansible_collections/community/grafana/changelogs/fragments/242_add_grafana_organization_user_module.yml
new file mode 100644
index 000000000..2296df462
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/242_add_grafana_organization_user_module.yml
@@ -0,0 +1,2 @@
+minor_changes:
+ - Add `grafana_organization_user` module
diff --git a/ansible_collections/community/grafana/changelogs/fragments/285_fix_doc.yml b/ansible_collections/community/grafana/changelogs/fragments/285_fix_doc.yml
new file mode 100644
index 000000000..74db5e2c7
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/285_fix_doc.yml
@@ -0,0 +1,6 @@
+---
+
+minor_changes:
+ - Fix documentation url for Ansible doc website
+
+...
diff --git a/ansible_collections/community/grafana/changelogs/fragments/294-bump-grafana-version.yml b/ansible_collections/community/grafana/changelogs/fragments/294-bump-grafana-version.yml
new file mode 100644
index 000000000..7149cfe0f
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/294-bump-grafana-version.yml
@@ -0,0 +1,5 @@
+minor_changes:
+ - Bump version of Python used in tests to 3.10
+ - Now testing against Grafana 9.5.13, 8.5.27, 10.2.0
+bugfixes:
+ - grafana_folder, fix an issue during delete (starting Grafana 9.3)
diff --git a/ansible_collections/community/grafana/changelogs/fragments/300_datasource_prometheus_time_interval.yml b/ansible_collections/community/grafana/changelogs/fragments/300_datasource_prometheus_time_interval.yml
new file mode 100644
index 000000000..970797f76
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/300_datasource_prometheus_time_interval.yml
@@ -0,0 +1,2 @@
+minor_changes:
+ - Enable datasource option `time_interval` for prometheus
diff --git a/ansible_collections/community/grafana/changelogs/fragments/308_datasource_quickwit.yml b/ansible_collections/community/grafana/changelogs/fragments/308_datasource_quickwit.yml
new file mode 100644
index 000000000..d91a13082
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/308_datasource_quickwit.yml
@@ -0,0 +1,2 @@
+minor_changes:
+ - Add Quickwit search engine datasource (https://quickwit.io).
diff --git a/ansible_collections/community/grafana/changelogs/fragments/311_dashboard_check_mode.yml b/ansible_collections/community/grafana/changelogs/fragments/311_dashboard_check_mode.yml
new file mode 100644
index 000000000..394edad9b
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/311_dashboard_check_mode.yml
@@ -0,0 +1,5 @@
+minor_changes:
+ - grafana_dashboard - add check_mode support
+
+trivial:
+ - Refactor tests for `grafana_dashboard`
diff --git a/ansible_collections/community/grafana/changelogs/fragments/318-org_users_by_org_name.yml b/ansible_collections/community/grafana/changelogs/fragments/318-org_users_by_org_name.yml
new file mode 100644
index 000000000..ef8d4959e
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/318-org_users_by_org_name.yml
@@ -0,0 +1,7 @@
+---
+
+minor_changes:
+ - Add parameter `org_name` to `grafana_organization_user`
+
+trivial:
+ - Add tests for new `grafana_organization_user`-parameter `org_name`
diff --git a/ansible_collections/community/grafana/changelogs/fragments/321-action-groups-org-users.yml b/ansible_collections/community/grafana/changelogs/fragments/321-action-groups-org-users.yml
new file mode 100644
index 000000000..d62f076bf
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/321-action-groups-org-users.yml
@@ -0,0 +1,4 @@
+---
+
+bugfixes:
+ - Add `grafana_organiazion_user` to `action_groups.grafana`
diff --git a/ansible_collections/community/grafana/changelogs/fragments/324_formatting.yml b/ansible_collections/community/grafana/changelogs/fragments/324_formatting.yml
new file mode 100644
index 000000000..db7b9609d
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/324_formatting.yml
@@ -0,0 +1,2 @@
+trivial:
+ - Format with black, remove unused variables
diff --git a/ansible_collections/community/grafana/changelogs/fragments/325_linting.yml b/ansible_collections/community/grafana/changelogs/fragments/325_linting.yml
new file mode 100644
index 000000000..cfeff8a52
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/325_linting.yml
@@ -0,0 +1,2 @@
+trivial:
+ - fix linting with ansible-lint write.
diff --git a/ansible_collections/community/grafana/changelogs/fragments/325_true_false.yml b/ansible_collections/community/grafana/changelogs/fragments/325_true_false.yml
new file mode 100644
index 000000000..c192d086f
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/325_true_false.yml
@@ -0,0 +1,2 @@
+minor_changes:
+- default to true/false in docs and code
diff --git a/ansible_collections/community/grafana/changelogs/fragments/331-dashboard-by-org-name.yml b/ansible_collections/community/grafana/changelogs/fragments/331-dashboard-by-org-name.yml
new file mode 100644
index 000000000..576c8c143
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/331-dashboard-by-org-name.yml
@@ -0,0 +1,8 @@
+---
+
+minor_changes:
+ - Add parameter `org_name` to `grafana_dashboard`
+
+trivial:
+ - Add tests for new `grafana_dashboard`-parameter `org_name`
+ - Refactor tests for `grafana_dashboard`
diff --git a/ansible_collections/community/grafana/changelogs/fragments/332-datasource-by-org-name.yml b/ansible_collections/community/grafana/changelogs/fragments/332-datasource-by-org-name.yml
new file mode 100644
index 000000000..0c8e265df
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/332-datasource-by-org-name.yml
@@ -0,0 +1,4 @@
+---
+
+minor_changes:
+ - Add parameter `org_name` to `grafana_datasource`
diff --git a/ansible_collections/community/grafana/changelogs/fragments/335-add-datasource-type-tempo.yml b/ansible_collections/community/grafana/changelogs/fragments/335-add-datasource-type-tempo.yml
new file mode 100644
index 000000000..18d34a0aa
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/335-add-datasource-type-tempo.yml
@@ -0,0 +1,2 @@
+minor_changes:
+ - Add support for Grafana Tempo datasource type (https://grafana.com/docs/grafana/latest/datasources/tempo/) \ No newline at end of file
diff --git a/ansible_collections/community/grafana/changelogs/fragments/339-lint-black.yml b/ansible_collections/community/grafana/changelogs/fragments/339-lint-black.yml
new file mode 100644
index 000000000..2a37ca851
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/339-lint-black.yml
@@ -0,0 +1,3 @@
+---
+trivial:
+ - added python black linting action
diff --git a/ansible_collections/community/grafana/changelogs/fragments/341-lint-ruff.yml b/ansible_collections/community/grafana/changelogs/fragments/341-lint-ruff.yml
new file mode 100644
index 000000000..e5cfd5b49
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/341-lint-ruff.yml
@@ -0,0 +1,3 @@
+---
+trivial:
+ - added python ruff linting action
diff --git a/ansible_collections/community/grafana/changelogs/fragments/342-ruff-findings.yml b/ansible_collections/community/grafana/changelogs/fragments/342-ruff-findings.yml
new file mode 100644
index 000000000..79c7ab220
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/342-ruff-findings.yml
@@ -0,0 +1,2 @@
+trivial:
+ - fixed ruff python formatter findings
diff --git a/ansible_collections/community/grafana/changelogs/fragments/343-telekom-mms-role.yml b/ansible_collections/community/grafana/changelogs/fragments/343-telekom-mms-role.yml
new file mode 100644
index 000000000..07da942ca
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/343-telekom-mms-role.yml
@@ -0,0 +1,2 @@
+minor_changes:
+ - Merged ansible role telekom-mms/ansible-role-grafana into ansible-collections/community.grafana
diff --git a/ansible_collections/community/grafana/changelogs/fragments/345-datasource-compare-diff-orgid.yml b/ansible_collections/community/grafana/changelogs/fragments/345-datasource-compare-diff-orgid.yml
new file mode 100644
index 000000000..11c211417
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/345-datasource-compare-diff-orgid.yml
@@ -0,0 +1,3 @@
+---
+bugfixes:
+ - Fixed orgId handling in diff comparison for `grafana_datasource` if using org_name
diff --git a/ansible_collections/community/grafana/changelogs/fragments/347-folder-for-orgs.yml b/ansible_collections/community/grafana/changelogs/fragments/347-folder-for-orgs.yml
new file mode 100644
index 000000000..c37990eb4
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/347-folder-for-orgs.yml
@@ -0,0 +1,7 @@
+---
+
+minor_changes:
+ - Manage `grafana_folder` for organizations
+
+trivial:
+ - Fixed syntax for code in some docs
diff --git a/ansible_collections/community/grafana/changelogs/fragments/349-role-notification-channel.yml b/ansible_collections/community/grafana/changelogs/fragments/349-role-notification-channel.yml
new file mode 100644
index 000000000..f2428c3a6
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/349-role-notification-channel.yml
@@ -0,0 +1,4 @@
+---
+
+minor_changes:
+ - added `community.grafana.notification_channel` to role
diff --git a/ansible_collections/community/grafana/changelogs/fragments/350-python3.12.yml b/ansible_collections/community/grafana/changelogs/fragments/350-python3.12.yml
new file mode 100644
index 000000000..21b7cc760
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/350-python3.12.yml
@@ -0,0 +1,3 @@
+---
+bugfixes:
+ - "test: replace deprecated `TestCase.assertEquals` to support Python 3.12"
diff --git a/ansible_collections/community/grafana/changelogs/fragments/fix-316.yml b/ansible_collections/community/grafana/changelogs/fragments/fix-316.yml
new file mode 100644
index 000000000..4569d4456
--- /dev/null
+++ b/ansible_collections/community/grafana/changelogs/fragments/fix-316.yml
@@ -0,0 +1,2 @@
+bugfixes:
+ - Fix error with datasources configured without basicAuth \ No newline at end of file
diff --git a/ansible_collections/community/grafana/codecov.yml b/ansible_collections/community/grafana/codecov.yml
index c01a21d4a..d376ab571 100644
--- a/ansible_collections/community/grafana/codecov.yml
+++ b/ansible_collections/community/grafana/codecov.yml
@@ -3,4 +3,4 @@ coverage:
round: down
range: "70...100"
fixes:
- - "/ansible_collections/community/grafana/::"
+ - "/ansible_collections/community/grafana/::"
diff --git a/ansible_collections/community/grafana/hacking/find_grafana_versions.py b/ansible_collections/community/grafana/hacking/find_grafana_versions.py
index 06625a2d5..b31fc530a 100644
--- a/ansible_collections/community/grafana/hacking/find_grafana_versions.py
+++ b/ansible_collections/community/grafana/hacking/find_grafana_versions.py
@@ -7,11 +7,14 @@ import requests
def get_by_major(version):
if version.startswith("v"):
version = version[1:]
- return (version[0], version, int(version.replace('.', '')))
+ return (version[0], version, int(version.replace(".", "")))
def get_grafana_releases():
- r = requests.get('https://api.github.com/repos/grafana/grafana/releases?per_page=50', headers={"Accept": "application/vnd.github.v3+json"})
+ r = requests.get(
+ "https://api.github.com/repos/grafana/grafana/releases?per_page=50",
+ headers={"Accept": "application/vnd.github.v3+json"},
+ )
if r.status_code != 200:
raise Exception("Failed to get releases from GitHub")
return r.json()
diff --git a/ansible_collections/community/grafana/hacking/requirements.txt b/ansible_collections/community/grafana/hacking/requirements.txt
index ced51d094..2c24336eb 100644
--- a/ansible_collections/community/grafana/hacking/requirements.txt
+++ b/ansible_collections/community/grafana/hacking/requirements.txt
@@ -1 +1 @@
-requests==2.28.0
+requests==2.31.0
diff --git a/ansible_collections/community/grafana/meta/runtime.yml b/ansible_collections/community/grafana/meta/runtime.yml
index 8d9b13a42..15f5554fc 100644
--- a/ansible_collections/community/grafana/meta/runtime.yml
+++ b/ansible_collections/community/grafana/meta/runtime.yml
@@ -1,12 +1,13 @@
---
-requires_ansible: '>=2.9.0'
+requires_ansible: ">=2.14.0"
action_groups:
grafana:
- - grafana_dashboard
- - grafana_datasource
- - grafana_folder
- - grafana_notification_channel
- - grafana_organization
- - grafana_plugin
- - grafana_team
- - grafana_user
+ - grafana_dashboard
+ - grafana_datasource
+ - grafana_folder
+ - grafana_notification_channel
+ - grafana_organization
+ - grafana_organization_user
+ - grafana_plugin
+ - grafana_team
+ - grafana_user
diff --git a/ansible_collections/community/grafana/molecule/default/converge.yml b/ansible_collections/community/grafana/molecule/default/converge.yml
new file mode 100644
index 000000000..b1e1cf20b
--- /dev/null
+++ b/ansible_collections/community/grafana/molecule/default/converge.yml
@@ -0,0 +1,48 @@
+---
+- name: Converge
+ hosts: localhost
+ environment:
+ http_proxy: "{{ lookup('env', 'HTTP_PROXY') | default(omit) }}"
+ https_proxy: "{{ lookup('env', 'HTTPS_PROXY') | default(omit) }}"
+ no_proxy: "{{ lookup('env', 'NO_PROXY') | default(omit) }}"
+
+ vars:
+ grafana_url: http://localhost:3000
+ grafana_username: admin
+ grafana_password: admin
+
+ grafana_organizations:
+ - name: my_org
+
+ grafana_datasources:
+ - name: Loki
+ ds_type: loki
+ ds_url: http://127.0.0.1:3100
+ tls_skip_verify: true
+
+ grafana_folders:
+ - name: my_service
+ - name: other_service
+
+ grafana_teams:
+ - name: my_team
+ email: myteam@example.de
+
+ grafana_users:
+ - name: Test User
+ login: testuser
+ password: supersecure!123
+ email: testuser@example.de
+
+ grafana_organization_users:
+ - login: testuser
+ org_id: 1
+ - login: testuser
+ org_name: my_org
+
+ grafana_dashboards:
+ - folder: my_service
+ path: test_dashboard.json
+ overwrite: true
+
+ roles: [{role: community.grafana.grafana}]
diff --git a/ansible_collections/community/grafana/molecule/default/molecule.yml b/ansible_collections/community/grafana/molecule/default/molecule.yml
new file mode 100644
index 000000000..ab4613bcb
--- /dev/null
+++ b/ansible_collections/community/grafana/molecule/default/molecule.yml
@@ -0,0 +1,21 @@
+---
+dependency:
+ name: galaxy
+driver:
+ name: docker
+platforms:
+ - name: instance
+ image: rndmh3ro/docker-debian12-ansible:latest
+ command: ${MOLECULE_DOCKER_COMMAND:-/lib/systemd/systemd}
+ env:
+ container: docker
+ pre_build_image: true
+ platform: amd64
+provisioner:
+ name: ansible
+ config_options:
+ defaults:
+ interpreter_python: auto_silent
+ callback_whitelist: profile_tasks, timer, yaml
+verifier:
+ name: ansible
diff --git a/ansible_collections/community/grafana/molecule/default/test_dashboard.json b/ansible_collections/community/grafana/molecule/default/test_dashboard.json
new file mode 100644
index 000000000..b95184512
--- /dev/null
+++ b/ansible_collections/community/grafana/molecule/default/test_dashboard.json
@@ -0,0 +1,126 @@
+{
+ "annotations": {
+ "list": [
+ {
+ "builtIn": 1,
+ "datasource": "-- Grafana --",
+ "enable": true,
+ "hide": true,
+ "iconColor": "rgba(0, 211, 255, 1)",
+ "name": "Annotations & Alerts",
+ "target": {
+ "limit": 100,
+ "matchAny": false,
+ "tags": [],
+ "type": "dashboard"
+ },
+ "type": "dashboard"
+ }
+ ]
+ },
+ "editable": true,
+ "fiscalYearStartMonth": 0,
+ "graphTooltip": 0,
+ "id": 3,
+ "links": [],
+ "liveNow": false,
+ "panels": [
+ {
+ "datasource": {
+ "type": "loki"
+ },
+ "fieldConfig": {
+ "defaults": {
+ "color": {
+ "mode": "palette-classic"
+ },
+ "custom": {
+ "axisLabel": "",
+ "axisPlacement": "auto",
+ "barAlignment": 0,
+ "drawStyle": "line",
+ "fillOpacity": 0,
+ "gradientMode": "none",
+ "hideFrom": {
+ "legend": false,
+ "tooltip": false,
+ "viz": false
+ },
+ "lineInterpolation": "linear",
+ "lineWidth": 1,
+ "pointSize": 5,
+ "scaleDistribution": {
+ "type": "linear"
+ },
+ "showPoints": "auto",
+ "spanNulls": false,
+ "stacking": {
+ "group": "A",
+ "mode": "none"
+ },
+ "thresholdsStyle": {
+ "mode": "off"
+ }
+ },
+ "mappings": [],
+ "thresholds": {
+ "mode": "absolute",
+ "steps": [
+ {
+ "color": "green"
+ },
+ {
+ "color": "red",
+ "value": 80
+ }
+ ]
+ }
+ },
+ "overrides": []
+ },
+ "gridPos": {
+ "h": 8,
+ "w": 12,
+ "x": 0,
+ "y": 0
+ },
+ "options": {
+ "legend": {
+ "calcs": [],
+ "displayMode": "list",
+ "placement": "bottom"
+ },
+ "tooltip": {
+ "mode": "single"
+ }
+ },
+ "targets": [
+ {
+ "datasource": {
+ "type": "loki"
+ },
+ "refId": "A"
+ }
+ ],
+ "title": "Panel Title",
+ "type": "timeseries"
+ }
+ ],
+ "refresh": "",
+ "schemaVersion": 33,
+ "style": "dark",
+ "tags": [],
+ "templating": {
+ "list": []
+ },
+ "time": {
+ "from": "now-6h",
+ "to": "now"
+ },
+ "timepicker": {},
+ "timezone": "",
+ "title": "New dashboard",
+ "uid": "ES5apb27k",
+ "version": 1,
+ "weekStart": ""
+}
diff --git a/ansible_collections/community/grafana/plugins/callback/grafana_annotations.py b/ansible_collections/community/grafana/plugins/callback/grafana_annotations.py
index 04555eae0..6030b0c8b 100644
--- a/ansible_collections/community/grafana/plugins/callback/grafana_annotations.py
+++ b/ansible_collections/community/grafana/plugins/callback/grafana_annotations.py
@@ -14,10 +14,11 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
-DOCUMENTATION = '''
+DOCUMENTATION = """
name: grafana_annotations
type: notification
short_description: send ansible events as annotations on charts to grafana over http api.
@@ -29,7 +30,7 @@ DOCUMENTATION = '''
options:
grafana_url:
description: Grafana annotations api URL
- required: True
+ required: true
env:
- name: GRAFANA_URL
ini:
@@ -45,7 +46,7 @@ DOCUMENTATION = '''
key: validate_grafana_certs
- section: callback_grafana_annotations
key: validate_certs
- default: True
+ default: true
type: bool
aliases: [ validate_grafana_certs ]
http_agent:
@@ -104,7 +105,7 @@ DOCUMENTATION = '''
default: []
type: list
elements: integer
-'''
+"""
import json
import socket
@@ -148,7 +149,7 @@ Result:
def to_millis(dt):
- return int(dt.strftime('%s')) * 1000
+ return int(dt.strftime("%s")) * 1000
class CallbackModule(CallbackBase):
@@ -161,15 +162,14 @@ class CallbackModule(CallbackBase):
"""
CALLBACK_VERSION = 2.0
- CALLBACK_TYPE = 'aggregate'
- CALLBACK_NAME = 'community.grafana.grafana_annotations'
+ CALLBACK_TYPE = "aggregate"
+ CALLBACK_NAME = "community.grafana.grafana_annotations"
CALLBACK_NEEDS_WHITELIST = True
def __init__(self, display=None):
-
super(CallbackModule, self).__init__(display=display)
- self.headers = {'Content-Type': 'application/json'}
+ self.headers = {"Content-Type": "application/json"}
self.force_basic_auth = False
self.hostname = socket.gethostname()
self.username = getpass.getuser()
@@ -177,38 +177,42 @@ class CallbackModule(CallbackBase):
self.errors = 0
def set_options(self, task_keys=None, var_options=None, direct=None):
-
- super(CallbackModule, self).set_options(task_keys=task_keys, var_options=var_options, direct=direct)
-
- self.grafana_api_key = self.get_option('grafana_api_key')
- self.grafana_url = self.get_option('grafana_url')
- self.validate_grafana_certs = self.get_option('validate_certs')
- self.http_agent = self.get_option('http_agent')
- self.grafana_user = self.get_option('grafana_user')
- self.grafana_password = self.get_option('grafana_password')
- self.dashboard_id = self.get_option('grafana_dashboard_id')
- self.panel_ids = self.get_option('grafana_panel_ids')
+ super(CallbackModule, self).set_options(
+ task_keys=task_keys, var_options=var_options, direct=direct
+ )
+
+ self.grafana_api_key = self.get_option("grafana_api_key")
+ self.grafana_url = self.get_option("grafana_url")
+ self.validate_grafana_certs = self.get_option("validate_certs")
+ self.http_agent = self.get_option("http_agent")
+ self.grafana_user = self.get_option("grafana_user")
+ self.grafana_password = self.get_option("grafana_password")
+ self.dashboard_id = self.get_option("grafana_dashboard_id")
+ self.panel_ids = self.get_option("grafana_panel_ids")
if self.grafana_api_key:
- self.headers['Authorization'] = "Bearer %s" % self.grafana_api_key
+ self.headers["Authorization"] = "Bearer %s" % self.grafana_api_key
else:
self.force_basic_auth = True
if self.grafana_url is None:
self.disabled = True
- self._display.warning('Grafana URL was not provided. The '
- 'Grafana URL can be provided using '
- 'the `GRAFANA_URL` environment variable.')
- self._display.debug('Grafana URL: %s' % self.grafana_url)
+ self._display.warning(
+ "Grafana URL was not provided. The "
+ "Grafana URL can be provided using "
+ "the `GRAFANA_URL` environment variable."
+ )
+ self._display.debug("Grafana URL: %s" % self.grafana_url)
def v2_playbook_on_start(self, playbook):
self.playbook = playbook._file_name
- text = PLAYBOOK_START_TXT.format(playbook=self.playbook, hostname=self.hostname,
- username=self.username)
+ text = PLAYBOOK_START_TXT.format(
+ playbook=self.playbook, hostname=self.hostname, username=self.username
+ )
data = {
- 'time': to_millis(self.start_time),
- 'text': text,
- 'tags': ['ansible', 'ansible_event_start', self.playbook, self.hostname]
+ "time": to_millis(self.start_time),
+ "text": text,
+ "tags": ["ansible", "ansible_event_start", self.playbook, self.hostname],
}
self._send_annotation(data)
@@ -223,30 +227,39 @@ class CallbackModule(CallbackBase):
if self.errors == 0:
status = "OK"
- text = PLAYBOOK_STATS_TXT.format(playbook=self.playbook, hostname=self.hostname,
- duration=duration.total_seconds(),
- status=status, username=self.username,
- summary=json.dumps(summarize_stat))
+ text = PLAYBOOK_STATS_TXT.format(
+ playbook=self.playbook,
+ hostname=self.hostname,
+ duration=duration.total_seconds(),
+ status=status,
+ username=self.username,
+ summary=json.dumps(summarize_stat),
+ )
data = {
- 'time': to_millis(self.start_time),
- 'timeEnd': to_millis(end_time),
- 'isRegion': True,
- 'text': text,
- 'tags': ['ansible', 'ansible_report', self.playbook, self.hostname]
+ "time": to_millis(self.start_time),
+ "timeEnd": to_millis(end_time),
+ "isRegion": True,
+ "text": text,
+ "tags": ["ansible", "ansible_report", self.playbook, self.hostname],
}
self._send_annotations(data)
def v2_runner_on_failed(self, result, ignore_errors=False, **kwargs):
- text = PLAYBOOK_ERROR_TXT.format(playbook=self.playbook, hostname=self.hostname,
- username=self.username, task=result._task,
- host=result._host.name, result=self._dump_results(result._result))
+ text = PLAYBOOK_ERROR_TXT.format(
+ playbook=self.playbook,
+ hostname=self.hostname,
+ username=self.username,
+ task=result._task,
+ host=result._host.name,
+ result=self._dump_results(result._result),
+ )
if ignore_errors:
return
data = {
- 'time': to_millis(datetime.now()),
- 'text': text,
- 'tags': ['ansible', 'ansible_event_failure', self.playbook, self.hostname]
+ "time": to_millis(datetime.now()),
+ "text": text,
+ "tags": ["ansible", "ansible_event_failure", self.playbook, self.hostname],
}
self.errors += 1
self._send_annotations(data)
@@ -263,10 +276,16 @@ class CallbackModule(CallbackBase):
def _send_annotation(self, annotation):
try:
- open_url(self.grafana_url, data=json.dumps(annotation), headers=self.headers,
- method="POST",
- validate_certs=self.validate_grafana_certs,
- url_username=self.grafana_user, url_password=self.grafana_password,
- http_agent=self.http_agent, force_basic_auth=self.force_basic_auth)
+ open_url(
+ self.grafana_url,
+ data=json.dumps(annotation),
+ headers=self.headers,
+ method="POST",
+ validate_certs=self.validate_grafana_certs,
+ url_username=self.grafana_user,
+ url_password=self.grafana_password,
+ http_agent=self.http_agent,
+ force_basic_auth=self.force_basic_auth,
+ )
except Exception as e:
- self._display.error(u'Could not submit message to Grafana: %s' % to_text(e))
+ self._display.error("Could not submit message to Grafana: %s" % to_text(e))
diff --git a/ansible_collections/community/grafana/plugins/doc_fragments/api_key.py b/ansible_collections/community/grafana/plugins/doc_fragments/api_key.py
index ffea714e5..94fdb57a2 100644
--- a/ansible_collections/community/grafana/plugins/doc_fragments/api_key.py
+++ b/ansible_collections/community/grafana/plugins/doc_fragments/api_key.py
@@ -2,17 +2,16 @@
# Copyright: (c) 2019, Rémi REY (@rrey)
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
__metaclass__ = type
class ModuleDocFragment(object):
-
- DOCUMENTATION = r'''options:
+ DOCUMENTATION = r"""options:
grafana_api_key:
description:
- The Grafana API key.
- If set, C(url_username) and C(url_password) will be ignored.
type: str
- '''
+ """
diff --git a/ansible_collections/community/grafana/plugins/doc_fragments/basic_auth.py b/ansible_collections/community/grafana/plugins/doc_fragments/basic_auth.py
index 8c41acdbe..5a8aec541 100644
--- a/ansible_collections/community/grafana/plugins/doc_fragments/basic_auth.py
+++ b/ansible_collections/community/grafana/plugins/doc_fragments/basic_auth.py
@@ -2,14 +2,13 @@
# Copyright: (c) 2019, Rémi REY (@rrey)
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
__metaclass__ = type
class ModuleDocFragment(object):
-
- DOCUMENTATION = r'''options:
+ DOCUMENTATION = r"""options:
url:
description:
- The Grafana URL.
@@ -30,9 +29,9 @@ class ModuleDocFragment(object):
aliases: [ grafana_password ]
use_proxy:
description:
- - If C(no), it will not use a proxy, even if one is defined in an environment variable on the target hosts.
+ - If C(false), it will not use a proxy, even if one is defined in an environment variable on the target hosts.
type: bool
- default: yes
+ default: true
client_cert:
description:
- PEM formatted certificate chain file to be used for SSL client authentication.
@@ -45,8 +44,8 @@ class ModuleDocFragment(object):
type: path
validate_certs:
description:
- - If C(no), SSL certificates will not be validated.
- - This should only set to C(no) used on personally controlled sites using self-signed certificates.
+ - If C(false), SSL certificates will not be validated.
+ - This should only set to C(false) used on personally controlled sites using self-signed certificates.
type: bool
- default: yes
- '''
+ default: true
+ """
diff --git a/ansible_collections/community/grafana/plugins/lookup/grafana_dashboard.py b/ansible_collections/community/grafana/plugins/lookup/grafana_dashboard.py
index ff288a1f3..c7fa31574 100644
--- a/ansible_collections/community/grafana/plugins/lookup/grafana_dashboard.py
+++ b/ansible_collections/community/grafana/plugins/lookup/grafana_dashboard.py
@@ -1,9 +1,10 @@
# (c) 2018 Ansible Project
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
-DOCUMENTATION = '''
+DOCUMENTATION = """
name: grafana_dashboard
author: Thierry Salle (@seuf)
short_description: list or search grafana dashboards
@@ -40,7 +41,7 @@ options:
description: optional filter for dashboard search.
env:
- name: GRAFANA_DASHBOARD_SEARCH
-'''
+"""
EXAMPLES = """
- name: get project foo grafana dashboards
@@ -64,30 +65,30 @@ from ansible.utils.display import Display
display = Display()
-ANSIBLE_GRAFANA_URL = 'http://127.0.0.1:3000'
+ANSIBLE_GRAFANA_URL = "http://127.0.0.1:3000"
ANSIBLE_GRAFANA_API_KEY = None
-ANSIBLE_GRAFANA_USER = 'admin'
-ANSIBLE_GRAFANA_PASSWORD = 'admin'
+ANSIBLE_GRAFANA_USER = "admin"
+ANSIBLE_GRAFANA_PASSWORD = "admin"
ANSIBLE_GRAFANA_ORG_ID = 1
ANSIBLE_GRAFANA_DASHBOARD_SEARCH = None
-if os.getenv('GRAFANA_URL') is not None:
- ANSIBLE_GRAFANA_URL = os.environ['GRAFANA_URL']
+if os.getenv("GRAFANA_URL") is not None:
+ ANSIBLE_GRAFANA_URL = os.environ["GRAFANA_URL"]
-if os.getenv('GRAFANA_API_KEY') is not None:
- ANSIBLE_GRAFANA_API_KEY = os.environ['GRAFANA_API_KEY']
+if os.getenv("GRAFANA_API_KEY") is not None:
+ ANSIBLE_GRAFANA_API_KEY = os.environ["GRAFANA_API_KEY"]
-if os.getenv('GRAFANA_USER') is not None:
- ANSIBLE_GRAFANA_USER = os.environ['GRAFANA_USER']
+if os.getenv("GRAFANA_USER") is not None:
+ ANSIBLE_GRAFANA_USER = os.environ["GRAFANA_USER"]
-if os.getenv('GRAFANA_PASSWORD') is not None:
- ANSIBLE_GRAFANA_PASSWORD = os.environ['GRAFANA_PASSWORD']
+if os.getenv("GRAFANA_PASSWORD") is not None:
+ ANSIBLE_GRAFANA_PASSWORD = os.environ["GRAFANA_PASSWORD"]
-if os.getenv('GRAFANA_ORG_ID') is not None:
- ANSIBLE_GRAFANA_ORG_ID = os.environ['GRAFANA_ORG_ID']
+if os.getenv("GRAFANA_ORG_ID") is not None:
+ ANSIBLE_GRAFANA_ORG_ID = os.environ["GRAFANA_ORG_ID"]
-if os.getenv('GRAFANA_DASHBOARD_SEARCH') is not None:
- ANSIBLE_GRAFANA_DASHBOARD_SEARCH = os.environ['GRAFANA_DASHBOARD_SEARCH']
+if os.getenv("GRAFANA_DASHBOARD_SEARCH") is not None:
+ ANSIBLE_GRAFANA_DASHBOARD_SEARCH = os.environ["GRAFANA_DASHBOARD_SEARCH"]
class GrafanaAPIException(Exception):
@@ -96,35 +97,47 @@ class GrafanaAPIException(Exception):
class GrafanaAPI:
def __init__(self, **kwargs):
- self.grafana_url = kwargs.get('grafana_url', ANSIBLE_GRAFANA_URL)
- self.grafana_api_key = kwargs.get('grafana_api_key', ANSIBLE_GRAFANA_API_KEY)
- self.grafana_user = kwargs.get('grafana_user', ANSIBLE_GRAFANA_USER)
- self.grafana_password = kwargs.get('grafana_password', ANSIBLE_GRAFANA_PASSWORD)
- self.grafana_org_id = kwargs.get('grafana_org_id', ANSIBLE_GRAFANA_ORG_ID)
- self.search = kwargs.get('search', ANSIBLE_GRAFANA_DASHBOARD_SEARCH)
+ self.grafana_url = kwargs.get("grafana_url", ANSIBLE_GRAFANA_URL)
+ self.grafana_api_key = kwargs.get("grafana_api_key", ANSIBLE_GRAFANA_API_KEY)
+ self.grafana_user = kwargs.get("grafana_user", ANSIBLE_GRAFANA_USER)
+ self.grafana_password = kwargs.get("grafana_password", ANSIBLE_GRAFANA_PASSWORD)
+ self.grafana_org_id = kwargs.get("grafana_org_id", ANSIBLE_GRAFANA_ORG_ID)
+ self.search = kwargs.get("search", ANSIBLE_GRAFANA_DASHBOARD_SEARCH)
def grafana_switch_organisation(self, headers):
try:
- r = open_url('%s/api/user/using/%s' % (self.grafana_url, self.grafana_org_id), headers=headers, method='POST')
+ r = open_url(
+ "%s/api/user/using/%s" % (self.grafana_url, self.grafana_org_id),
+ headers=headers,
+ method="POST",
+ )
except HTTPError as e:
- raise GrafanaAPIException('Unable to switch to organization %s : %s' % (self.grafana_org_id, to_native(e)))
+ raise GrafanaAPIException(
+ "Unable to switch to organization %s : %s"
+ % (self.grafana_org_id, to_native(e))
+ )
if r.getcode() != 200:
- raise GrafanaAPIException('Unable to switch to organization %s : %s' % (self.grafana_org_id, str(r.getcode())))
+ raise GrafanaAPIException(
+ "Unable to switch to organization %s : %s"
+ % (self.grafana_org_id, str(r.getcode()))
+ )
def grafana_headers(self):
- headers = {'content-type': 'application/json; charset=utf8'}
+ headers = {"content-type": "application/json; charset=utf8"}
if self.grafana_api_key:
api_key = self.grafana_api_key
if len(api_key) % 4 == 2:
display.deprecated(
"Passing a mangled version of the API key to the grafana_dashboard lookup is no longer necessary and should not be done.",
"2.0.0",
- collection_name='community.grafana',
+ collection_name="community.grafana",
)
- api_key += '=='
- headers['Authorization'] = "Bearer %s" % api_key
+ api_key += "=="
+ headers["Authorization"] = "Bearer %s" % api_key
else:
- headers['Authorization'] = basic_auth_header(self.grafana_user, self.grafana_password)
+ headers["Authorization"] = basic_auth_header(
+ self.grafana_user, self.grafana_password
+ )
self.grafana_switch_organisation(headers)
return headers
@@ -136,35 +149,44 @@ class GrafanaAPI:
dashboard_list = []
try:
if self.search:
- r = open_url('%s/api/search?query=%s' % (self.grafana_url, self.search), headers=headers, method='GET')
+ r = open_url(
+ "%s/api/search?query=%s" % (self.grafana_url, self.search),
+ headers=headers,
+ method="GET",
+ )
else:
- r = open_url('%s/api/search/' % self.grafana_url, headers=headers, method='GET')
+ r = open_url(
+ "%s/api/search/" % self.grafana_url, headers=headers, method="GET"
+ )
except HTTPError as e:
- raise GrafanaAPIException('Unable to search dashboards : %s' % to_native(e))
+ raise GrafanaAPIException("Unable to search dashboards : %s" % to_native(e))
if r.getcode() == 200:
try:
dashboard_list = json.loads(r.read())
except Exception as e:
- raise GrafanaAPIException('Unable to parse json list %s' % to_native(e))
+ raise GrafanaAPIException("Unable to parse json list %s" % to_native(e))
else:
- raise GrafanaAPIException('Unable to list grafana dashboards : %s' % str(r.getcode()))
+ raise GrafanaAPIException(
+ "Unable to list grafana dashboards : %s" % str(r.getcode())
+ )
return dashboard_list
class LookupModule(LookupBase):
-
def run(self, terms, variables=None, **kwargs):
-
- grafana_args = terms[0].split(' ')
+ grafana_args = terms[0].split(" ")
grafana_dict = {}
ret = []
for param in grafana_args:
try:
- key, value = param.split('=', 1)
+ key, value = param.split("=", 1)
except ValueError:
- raise AnsibleError("grafana_dashboard lookup plugin needs key=value pairs, but received %s" % terms)
+ raise AnsibleError(
+ "grafana_dashboard lookup plugin needs key=value pairs, but received %s"
+ % terms
+ )
grafana_dict[key] = value
grafana = GrafanaAPI(**grafana_dict)
diff --git a/ansible_collections/community/grafana/plugins/module_utils/base.py b/ansible_collections/community/grafana/plugins/module_utils/base.py
index 3a0174bbd..7d51601d8 100644
--- a/ansible_collections/community/grafana/plugins/module_utils/base.py
+++ b/ansible_collections/community/grafana/plugins/module_utils/base.py
@@ -16,7 +16,7 @@
#
# Copyright: (c) 2019, Rémi REY (@rrey)
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
from ansible.module_utils.urls import url_argument_spec
__metaclass__ = type
@@ -29,26 +29,26 @@ def clean_url(url):
def grafana_argument_spec():
argument_spec = url_argument_spec()
- del argument_spec['force']
- del argument_spec['force_basic_auth']
- del argument_spec['http_agent']
+ del argument_spec["force"]
+ del argument_spec["force_basic_auth"]
+ del argument_spec["http_agent"]
# Avoid sanity error with devel
if "use_gssapi" in argument_spec:
- del argument_spec['use_gssapi']
+ del argument_spec["use_gssapi"]
argument_spec.update(
- state=dict(choices=['present', 'absent'], default='present'),
- url=dict(aliases=['grafana_url'], type='str', required=True),
- grafana_api_key=dict(type='str', no_log=True),
- url_username=dict(aliases=['grafana_user'], default='admin'),
- url_password=dict(aliases=['grafana_password'], default='admin', no_log=True),
+ state=dict(choices=["present", "absent"], default="present"),
+ url=dict(aliases=["grafana_url"], type="str", required=True),
+ grafana_api_key=dict(type="str", no_log=True),
+ url_username=dict(aliases=["grafana_user"], default="admin"),
+ url_password=dict(aliases=["grafana_password"], default="admin", no_log=True),
)
return argument_spec
def grafana_required_together():
- return [['url_username', 'url_password']]
+ return [["url_username", "url_password"]]
def grafana_mutually_exclusive():
- return [['url_username', 'grafana_api_key']]
+ return [["url_username", "grafana_api_key"]]
diff --git a/ansible_collections/community/grafana/plugins/modules/grafana_dashboard.py b/ansible_collections/community/grafana/plugins/modules/grafana_dashboard.py
index 99801d494..77a5a7565 100644
--- a/ansible_collections/community/grafana/plugins/modules/grafana_dashboard.py
+++ b/ansible_collections/community/grafana/plugins/modules/grafana_dashboard.py
@@ -6,7 +6,7 @@
from __future__ import absolute_import, division, print_function
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
module: grafana_dashboard
author:
@@ -18,10 +18,17 @@ description:
options:
org_id:
description:
- - The Grafana Organisation ID where the dashboard will be imported / exported.
- - Not used when I(grafana_api_key) is set, because the grafana_api_key only belongs to one organisation..
+ - The Grafana organization ID where the dashboard will be imported / exported / deleted.
+ - Not used when I(grafana_api_key) is set, because the grafana_api_key only belongs to one organization.
+ - Mutually exclusive with C(org_name).
default: 1
type: int
+ org_name:
+ description:
+ - The Grafana organization name where the dashboard will be imported / exported / deleted.
+ - Not used when I(grafana_api_key) is set, because the grafana_api_key only belongs to one organization.
+ - Mutually exclusive with C(org_id).
+ type: str
folder:
description:
- The Grafana folder where this dashboard will be imported to.
@@ -58,7 +65,7 @@ options:
description:
- Override existing dashboard when state is present.
type: bool
- default: 'no'
+ default: false
dashboard_id:
description:
- Public Grafana.com dashboard id to import
@@ -80,55 +87,52 @@ options:
extends_documentation_fragment:
- community.grafana.basic_auth
- community.grafana.api_key
-'''
-
-EXAMPLES = '''
-- hosts: localhost
- connection: local
- tasks:
- - name: Import Grafana dashboard foo
- community.grafana.grafana_dashboard:
- grafana_url: http://grafana.company.com
- grafana_api_key: "{{ grafana_api_key }}"
- state: present
- commit_message: Updated by ansible
- overwrite: yes
- path: /path/to/dashboards/foo.json
-
- - name: Import Grafana dashboard Zabbix
- community.grafana.grafana_dashboard:
- grafana_url: http://grafana.company.com
- grafana_api_key: "{{ grafana_api_key }}"
- folder: zabbix
- dashboard_id: 6098
- dashbord_revision: 1
-
- - name: Import Grafana dashboard zabbix
- community.grafana.grafana_dashboard:
- grafana_url: http://grafana.company.com
- grafana_api_key: "{{ grafana_api_key }}"
- folder: public
- dashboard_url: https://grafana.com/api/dashboards/6098/revisions/1/download
-
- - name: Export dashboard
- community.grafana.grafana_dashboard:
- grafana_url: http://grafana.company.com
- grafana_user: "admin"
- grafana_password: "{{ grafana_password }}"
- org_id: 1
- state: export
- uid: "000000653"
- path: "/path/to/dashboards/000000653.json"
-'''
-
-RETURN = '''
+"""
+
+EXAMPLES = """
+- name: Import Grafana dashboard foo
+ community.grafana.grafana_dashboard:
+ grafana_url: http://grafana.company.com
+ grafana_api_key: "{{ grafana_api_key }}"
+ state: present
+ commit_message: Updated by ansible
+ overwrite: true
+ path: /path/to/dashboards/foo.json
+
+- name: Import Grafana dashboard Zabbix
+ community.grafana.grafana_dashboard:
+ grafana_url: http://grafana.company.com
+ grafana_api_key: "{{ grafana_api_key }}"
+ folder: zabbix
+ dashboard_id: 6098
+ dashboard_revision: 1
+
+- name: Import Grafana dashboard zabbix
+ community.grafana.grafana_dashboard:
+ grafana_url: http://grafana.company.com
+ grafana_api_key: "{{ grafana_api_key }}"
+ folder: public
+ dashboard_url: https://grafana.com/api/dashboards/6098/revisions/1/download
+
+- name: Export dashboard
+ community.grafana.grafana_dashboard:
+ grafana_url: http://grafana.company.com
+ grafana_user: "admin"
+ grafana_password: "{{ grafana_password }}"
+ org_id: 1
+ state: export
+ uid: "000000653"
+ path: "/path/to/dashboards/000000653.json"
+"""
+
+RETURN = """
---
uid:
description: uid or slug of the created / deleted / exported dashboard.
returned: success
type: str
sample: 000000063
-'''
+"""
import json
from ansible.module_utils.basic import AnsibleModule
@@ -136,7 +140,10 @@ from ansible.module_utils.urls import fetch_url
from ansible.module_utils.six.moves.urllib.parse import urlencode
from ansible.module_utils._text import to_native
from ansible.module_utils._text import to_text
-from ansible_collections.community.grafana.plugins.module_utils.base import grafana_argument_spec, clean_url
+from ansible_collections.community.grafana.plugins.module_utils.base import (
+ grafana_argument_spec,
+ clean_url,
+)
__metaclass__ = type
@@ -157,56 +164,91 @@ class GrafanaDeleteException(Exception):
pass
-def grafana_switch_organisation(module, grafana_url, org_id, headers):
- r, info = fetch_url(module, '%s/api/user/using/%s' % (grafana_url, org_id), headers=headers, method='POST')
- if info['status'] != 200:
- raise GrafanaAPIException('Unable to switch to organization %s : %s' % (org_id, info))
+def grafana_organization_id_by_name(module, grafana_url, org_name, headers):
+ r, info = fetch_url(
+ module, "%s/api/user/orgs" % grafana_url, headers=headers, method="GET"
+ )
+ if info["status"] != 200:
+ raise GrafanaAPIException("Unable to retrieve users organizations: %s" % info)
+ organizations = json.loads(to_text(r.read()))
+ for org in organizations:
+ if org["name"] == org_name:
+ return org["orgId"]
+
+ raise GrafanaAPIException(
+ "Current user isn't member of organization: %s" % org_name
+ )
+
+
+def grafana_switch_organization(module, grafana_url, org_id, headers):
+ r, info = fetch_url(
+ module,
+ "%s/api/user/using/%s" % (grafana_url, org_id),
+ headers=headers,
+ method="POST",
+ )
+ if info["status"] != 200:
+ raise GrafanaAPIException(
+ "Unable to switch to organization %s : %s" % (org_id, info)
+ )
def grafana_headers(module, data):
- headers = {'content-type': 'application/json; charset=utf8'}
- if 'grafana_api_key' in data and data['grafana_api_key']:
- headers['Authorization'] = "Bearer %s" % data['grafana_api_key']
+ headers = {"content-type": "application/json; charset=utf8"}
+ if "grafana_api_key" in data and data["grafana_api_key"]:
+ headers["Authorization"] = "Bearer %s" % data["grafana_api_key"]
else:
- module.params['force_basic_auth'] = True
- grafana_switch_organisation(module, data['url'], data['org_id'], headers)
+ module.params["force_basic_auth"] = True
+ if module.params["org_name"]:
+ org_name = module.params["org_name"]
+ data["org_id"] = grafana_organization_id_by_name(
+ module, data["url"], org_name, headers
+ )
+ grafana_switch_organization(module, data["url"], data["org_id"], headers)
return headers
def get_grafana_version(module, grafana_url, headers):
grafana_version = None
- r, info = fetch_url(module, '%s/api/frontend/settings' % grafana_url, headers=headers, method='GET')
- if info['status'] == 200:
+ r, info = fetch_url(
+ module, "%s/api/frontend/settings" % grafana_url, headers=headers, method="GET"
+ )
+ if info["status"] == 200:
try:
settings = json.loads(to_text(r.read()))
- grafana_version = settings['buildInfo']['version'].split('.')[0]
- except UnicodeError as e:
- raise GrafanaAPIException('Unable to decode version string to Unicode')
+ grafana_version = settings["buildInfo"]["version"].split(".")[0]
+ except UnicodeError:
+ raise GrafanaAPIException("Unable to decode version string to Unicode")
except Exception as e:
raise GrafanaAPIException(e)
else:
- raise GrafanaAPIException('Unable to get grafana version : %s' % info)
+ raise GrafanaAPIException("Unable to get grafana version: %s" % info)
return int(grafana_version)
def grafana_folder_exists(module, grafana_url, folder_name, headers):
# the 'General' folder is a special case, it's ID is always '0'
- if folder_name == 'General':
+ if folder_name == "General":
return True, 0
try:
- r, info = fetch_url(module, '%s/api/folders' % grafana_url, headers=headers, method='GET')
+ r, info = fetch_url(
+ module, "%s/api/folders" % grafana_url, headers=headers, method="GET"
+ )
- if info['status'] != 200:
- raise GrafanaAPIException("Unable to query Grafana API for folders (name: %s): %d" % (folder_name, info['status']))
+ if info["status"] != 200:
+ raise GrafanaAPIException(
+ "Unable to query Grafana API for folders (name: %s): %d"
+ % (folder_name, info["status"])
+ )
folders = json.loads(r.read())
for folder in folders:
- if folder['title'] == folder_name:
- return True, folder['id']
+ if folder["title"] == folder_name:
+ return True, folder["id"]
except Exception as e:
raise GrafanaAPIException(e)
@@ -219,73 +261,73 @@ def grafana_dashboard_exists(module, grafana_url, uid, headers):
grafana_version = get_grafana_version(module, grafana_url, headers)
if grafana_version >= 5:
- uri = '%s/api/dashboards/uid/%s' % (grafana_url, uid)
+ uri = "%s/api/dashboards/uid/%s" % (grafana_url, uid)
else:
- uri = '%s/api/dashboards/db/%s' % (grafana_url, uid)
+ uri = "%s/api/dashboards/db/%s" % (grafana_url, uid)
- r, info = fetch_url(module, uri, headers=headers, method='GET')
+ r, info = fetch_url(module, uri, headers=headers, method="GET")
- if info['status'] == 200:
+ if info["status"] == 200:
dashboard_exists = True
try:
dashboard = json.loads(r.read())
except Exception as e:
raise GrafanaAPIException(e)
- elif info['status'] == 404:
+ elif info["status"] == 404:
dashboard_exists = False
else:
- raise GrafanaAPIException('Unable to get dashboard %s : %s' % (uid, info))
+ raise GrafanaAPIException("Unable to get dashboard %s : %s" % (uid, info))
return dashboard_exists, dashboard
def grafana_dashboard_search(module, grafana_url, folder_id, title, headers):
-
# search by title
- uri = '%s/api/search?%s' % (grafana_url, urlencode({
- 'folderIds': folder_id,
- 'query': title,
- 'type': 'dash-db'
- }))
- r, info = fetch_url(module, uri, headers=headers, method='GET')
-
- if info['status'] == 200:
+ uri = "%s/api/search?%s" % (
+ grafana_url,
+ urlencode({"folderIds": folder_id, "query": title, "type": "dash-db"}),
+ )
+ r, info = fetch_url(module, uri, headers=headers, method="GET")
+
+ if info["status"] == 200:
try:
dashboards = json.loads(r.read())
for d in dashboards:
- if d['title'] == title:
- return grafana_dashboard_exists(module, grafana_url, d['uid'], headers)
+ if d["title"] == title:
+ return grafana_dashboard_exists(
+ module, grafana_url, d["uid"], headers
+ )
except Exception as e:
raise GrafanaAPIException(e)
else:
- raise GrafanaAPIException('Unable to search dashboard %s : %s' % (title, info))
+ raise GrafanaAPIException("Unable to search dashboard %s : %s" % (title, info))
return False, None
# for comparison, we sometimes need to ignore a few keys
-def grafana_dashboard_changed(payload, dashboard):
+def is_grafana_dashboard_changed(payload, dashboard):
# you don't need to set the version, but '0' is incremented to '1' by Grafana's API
- if 'version' in payload['dashboard']:
- del payload['dashboard']['version']
- if 'version' in dashboard['dashboard']:
- del dashboard['dashboard']['version']
+ if "version" in payload["dashboard"]:
+ del payload["dashboard"]["version"]
+ if "version" in dashboard["dashboard"]:
+ del dashboard["dashboard"]["version"]
# remove meta key if exists for compare
- if 'meta' in dashboard:
- del dashboard['meta']
- if 'meta' in payload:
- del payload['meta']
+ if "meta" in dashboard:
+ del dashboard["meta"]
+ if "meta" in payload:
+ del payload["meta"]
# if folderId is not provided in dashboard, set default folderId
- if 'folderId' not in dashboard:
- dashboard['folderId'] = 0
+ if "folderId" not in dashboard:
+ dashboard["folderId"] = 0
# Ignore dashboard ids since real identifier is uuid
- if 'id' in dashboard['dashboard']:
- del dashboard['dashboard']['id']
- if 'id' in payload['dashboard']:
- del payload['dashboard']['id']
+ if "id" in dashboard["dashboard"]:
+ del dashboard["dashboard"]["id"]
+ if "id" in payload["dashboard"]:
+ del payload["dashboard"]["id"]
if payload == dashboard:
return False
@@ -293,43 +335,48 @@ def grafana_dashboard_changed(payload, dashboard):
def grafana_create_dashboard(module, data):
-
# define data payload for grafana API
payload = {}
- if data.get('dashboard_id'):
- data['path'] = "https://grafana.com/api/dashboards/%s/revisions/%s/download" % (data['dashboard_id'], data['dashboard_revision'])
- if data['path'].startswith('http'):
- r, info = fetch_url(module, data['path'])
- if info['status'] != 200:
- raise GrafanaAPIException('Unable to download grafana dashboard from url %s : %s' % (data['path'], info))
+ if data.get("dashboard_id"):
+ data["path"] = "https://grafana.com/api/dashboards/%s/revisions/%s/download" % (
+ data["dashboard_id"],
+ data["dashboard_revision"],
+ )
+ if data["path"].startswith("http"):
+ r, info = fetch_url(module, data["path"])
+ if info["status"] != 200:
+ raise GrafanaAPIException(
+ "Unable to download grafana dashboard from url %s : %s"
+ % (data["path"], info)
+ )
payload = json.loads(r.read())
else:
try:
- with open(data['path'], 'r', encoding="utf-8") as json_file:
+ with open(data["path"], "r", encoding="utf-8") as json_file:
payload = json.load(json_file)
except Exception as e:
raise GrafanaAPIException("Can't load json file %s" % to_native(e))
# Check that the dashboard JSON is nested under the 'dashboard' key
- if 'dashboard' not in payload:
- payload = {'dashboard': payload}
+ if "dashboard" not in payload:
+ payload = {"dashboard": payload}
# define http header
headers = grafana_headers(module, data)
- grafana_version = get_grafana_version(module, data['url'], headers)
+ grafana_version = get_grafana_version(module, data["url"], headers)
if grafana_version < 5:
- if data.get('slug'):
- uid = data['slug']
- elif 'meta' in payload and 'slug' in payload['meta']:
- uid = payload['meta']['slug']
+ if data.get("slug"):
+ uid = data["slug"]
+ elif "meta" in payload and "slug" in payload["meta"]:
+ uid = payload["meta"]["slug"]
else:
- raise GrafanaMalformedJson('No slug found in json. Needed with grafana < 5')
+ raise GrafanaMalformedJson("No slug found in json. Needed with grafana < 5")
else:
- if data.get('uid'):
- uid = data['uid']
- elif 'uid' in payload['dashboard']:
- uid = payload['dashboard']['uid']
+ if data.get("uid"):
+ uid = data["uid"]
+ elif "uid" in payload["dashboard"]:
+ uid = payload["dashboard"]["uid"]
else:
uid = None
@@ -338,148 +385,223 @@ def grafana_create_dashboard(module, data):
# test if the folder exists
folder_exists = False
if grafana_version >= 5:
- folder_exists, folder_id = grafana_folder_exists(module, data['url'], data['folder'], headers)
+ folder_exists, folder_id = grafana_folder_exists(
+ module, data["url"], data["folder"], headers
+ )
if folder_exists is False:
- raise GrafanaAPIException("Dashboard folder '%s' does not exist." % data['folder'])
+ raise GrafanaAPIException(
+ "Dashboard folder '%s' does not exist." % data["folder"]
+ )
- payload['folderId'] = folder_id
+ payload["folderId"] = folder_id
# test if dashboard already exists
if uid:
dashboard_exists, dashboard = grafana_dashboard_exists(
- module, data['url'], uid, headers=headers)
+ module, data["url"], uid, headers=headers
+ )
else:
dashboard_exists, dashboard = grafana_dashboard_search(
- module, data['url'], folder_id, payload['dashboard']['title'], headers=headers)
+ module,
+ data["url"],
+ folder_id,
+ payload["dashboard"]["title"],
+ headers=headers,
+ )
if dashboard_exists is True:
- if grafana_dashboard_changed(payload, dashboard):
+ grafana_dashboard_changed = is_grafana_dashboard_changed(payload, dashboard)
+
+ if grafana_dashboard_changed:
+ if module.check_mode:
+ module.exit_json(
+ uid=uid,
+ failed=False,
+ changed=True,
+ msg="Dashboard %s will be updated" % payload["dashboard"]["title"],
+ )
# update
- if 'overwrite' in data and data['overwrite']:
- payload['overwrite'] = True
- if 'commit_message' in data and data['commit_message']:
- payload['message'] = data['commit_message']
-
- r, info = fetch_url(module, '%s/api/dashboards/db' % data['url'],
- data=json.dumps(payload), headers=headers, method='POST')
- if info['status'] == 200:
+ if "overwrite" in data and data["overwrite"]:
+ payload["overwrite"] = True
+ if "commit_message" in data and data["commit_message"]:
+ payload["message"] = data["commit_message"]
+
+ r, info = fetch_url(
+ module,
+ "%s/api/dashboards/db" % data["url"],
+ data=json.dumps(payload),
+ headers=headers,
+ method="POST",
+ )
+ if info["status"] == 200:
if grafana_version >= 5:
try:
dashboard = json.loads(r.read())
- uid = dashboard['uid']
+ uid = dashboard["uid"]
except Exception as e:
raise GrafanaAPIException(e)
- result['uid'] = uid
- result['msg'] = "Dashboard %s updated" % payload['dashboard']['title']
- result['changed'] = True
+ result["uid"] = uid
+ result["msg"] = "Dashboard %s updated" % payload["dashboard"]["title"]
+ result["changed"] = True
else:
- body = json.loads(info['body'])
- raise GrafanaAPIException('Unable to update the dashboard %s : %s (HTTP: %d)' %
- (uid, body['message'], info['status']))
+ body = json.loads(info["body"])
+ raise GrafanaAPIException(
+ "Unable to update the dashboard %s : %s (HTTP: %d)"
+ % (uid, body["message"], info["status"])
+ )
else:
# unchanged
- result['uid'] = uid
- result['msg'] = "Dashboard %s unchanged." % payload['dashboard']['title']
- result['changed'] = False
+ result["uid"] = uid
+ result["msg"] = "Dashboard %s unchanged." % payload["dashboard"]["title"]
+ result["changed"] = False
else:
+ if module.check_mode:
+ module.exit_json(
+ failed=False,
+ changed=True,
+ msg="Dashboard %s will be created" % payload["dashboard"]["title"],
+ )
+
# Ensure there is no id in payload
- if 'id' in payload['dashboard']:
- del payload['dashboard']['id']
-
- r, info = fetch_url(module, '%s/api/dashboards/db' % data['url'],
- data=json.dumps(payload), headers=headers, method='POST')
- if info['status'] == 200:
- result['msg'] = "Dashboard %s created" % payload['dashboard']['title']
- result['changed'] = True
+ if "id" in payload["dashboard"]:
+ del payload["dashboard"]["id"]
+
+ r, info = fetch_url(
+ module,
+ "%s/api/dashboards/db" % data["url"],
+ data=json.dumps(payload),
+ headers=headers,
+ method="POST",
+ )
+ if info["status"] == 200:
+ result["msg"] = "Dashboard %s created" % payload["dashboard"]["title"]
+ result["changed"] = True
if grafana_version >= 5:
try:
dashboard = json.loads(r.read())
- uid = dashboard['uid']
+ uid = dashboard["uid"]
except Exception as e:
raise GrafanaAPIException(e)
- result['uid'] = uid
+ result["uid"] = uid
else:
- raise GrafanaAPIException('Unable to create the new dashboard %s : %s - %s. (headers : %s)' %
- (payload['dashboard']['title'], info['status'], info, headers))
+ raise GrafanaAPIException(
+ "Unable to create the new dashboard %s : %s - %s. (headers : %s)"
+ % (payload["dashboard"]["title"], info["status"], info, headers)
+ )
return result
def grafana_delete_dashboard(module, data):
-
# define http headers
headers = grafana_headers(module, data)
- grafana_version = get_grafana_version(module, data['url'], headers)
+ grafana_version = get_grafana_version(module, data["url"], headers)
if grafana_version < 5:
- if data.get('slug'):
- uid = data['slug']
+ if data.get("slug"):
+ uid = data["slug"]
else:
- raise GrafanaMalformedJson('No slug parameter. Needed with grafana < 5')
+ raise GrafanaMalformedJson("No slug parameter. Needed with grafana < 5")
else:
- if data.get('uid'):
- uid = data['uid']
+ if data.get("uid"):
+ uid = data["uid"]
else:
- raise GrafanaDeleteException('No uid specified %s')
+ raise GrafanaDeleteException("No uid specified %s")
# test if dashboard already exists
- dashboard_exists, dashboard = grafana_dashboard_exists(module, data['url'], uid, headers=headers)
+ dashboard_exists, dashboard = grafana_dashboard_exists(
+ module, data["url"], uid, headers=headers
+ )
result = {}
if dashboard_exists is True:
+ if module.check_mode:
+ module.exit_json(
+ uid=uid,
+ failed=False,
+ changed=True,
+ msg="Dashboard %s will be deleted" % uid,
+ )
+
# delete
if grafana_version < 5:
- r, info = fetch_url(module, '%s/api/dashboards/db/%s' % (data['url'], uid), headers=headers, method='DELETE')
+ r, info = fetch_url(
+ module,
+ "%s/api/dashboards/db/%s" % (data["url"], uid),
+ headers=headers,
+ method="DELETE",
+ )
else:
- r, info = fetch_url(module, '%s/api/dashboards/uid/%s' % (data['url'], uid), headers=headers, method='DELETE')
- if info['status'] == 200:
- result['msg'] = "Dashboard %s deleted" % uid
- result['changed'] = True
- result['uid'] = uid
+ r, info = fetch_url(
+ module,
+ "%s/api/dashboards/uid/%s" % (data["url"], uid),
+ headers=headers,
+ method="DELETE",
+ )
+ if info["status"] == 200:
+ result["msg"] = "Dashboard %s deleted" % uid
+ result["changed"] = True
+ result["uid"] = uid
else:
- raise GrafanaAPIException('Unable to update the dashboard %s : %s' % (uid, info))
+ raise GrafanaAPIException(
+ "Unable to update the dashboard %s : %s" % (uid, info)
+ )
else:
# dashboard does not exist, do nothing
- result = {'msg': "Dashboard %s does not exist." % uid,
- 'changed': False,
- 'uid': uid}
+ result = {
+ "msg": "Dashboard %s does not exist." % uid,
+ "changed": False,
+ "uid": uid,
+ }
return result
def grafana_export_dashboard(module, data):
-
# define http headers
headers = grafana_headers(module, data)
- grafana_version = get_grafana_version(module, data['url'], headers)
+ grafana_version = get_grafana_version(module, data["url"], headers)
if grafana_version < 5:
- if data.get('slug'):
- uid = data['slug']
+ if data.get("slug"):
+ uid = data["slug"]
else:
- raise GrafanaMalformedJson('No slug parameter. Needed with grafana < 5')
+ raise GrafanaMalformedJson("No slug parameter. Needed with grafana < 5")
else:
- if data.get('uid'):
- uid = data['uid']
+ if data.get("uid"):
+ uid = data["uid"]
else:
- raise GrafanaExportException('No uid specified')
+ raise GrafanaExportException("No uid specified")
# test if dashboard already exists
- dashboard_exists, dashboard = grafana_dashboard_exists(module, data['url'], uid, headers=headers)
+ dashboard_exists, dashboard = grafana_dashboard_exists(
+ module, data["url"], uid, headers=headers
+ )
if dashboard_exists is True:
+ if module.check_mode:
+ module.exit_json(
+ uid=uid,
+ failed=False,
+ changed=True,
+ msg="Dashboard %s will be exported to %s" % (uid, data["path"]),
+ )
try:
- with open(data['path'], 'w', encoding="utf-8") as f:
+ with open(data["path"], "w", encoding="utf-8") as f:
f.write(json.dumps(dashboard, indent=2))
except Exception as e:
raise GrafanaExportException("Can't write json file : %s" % to_native(e))
- result = {'msg': "Dashboard %s exported to %s" % (uid, data['path']),
- 'uid': uid,
- 'changed': True}
+ result = {
+ "msg": "Dashboard %s exported to %s" % (uid, data["path"]),
+ "uid": uid,
+ "changed": True,
+ }
else:
- result = {'msg': "Dashboard %s does not exist." % uid,
- 'uid': uid,
- 'changed': False}
+ result = {
+ "msg": "Dashboard %s does not exist." % uid,
+ "uid": uid,
+ "changed": False,
+ }
return result
@@ -488,72 +610,75 @@ def main():
# use the predefined argument spec for url
argument_spec = grafana_argument_spec()
argument_spec.update(
- state=dict(choices=['present', 'absent', 'export'], default='present'),
- org_id=dict(default=1, type='int'),
- folder=dict(type='str', default='General'),
- uid=dict(type='str'),
- slug=dict(type='str'),
- path=dict(aliases=['dashboard_url'], type='str'),
- dashboard_id=dict(type='str'),
- dashboard_revision=dict(type='str', default='1'),
- overwrite=dict(type='bool', default=False),
- commit_message=dict(type='str', aliases=['message'],
- deprecated_aliases=[dict(name='message',
- version='2.0.0', collection_name="community.grafana")]),
+ state=dict(choices=["present", "absent", "export"], default="present"),
+ org_id=dict(default=1, type="int"),
+ org_name=dict(type="str"),
+ folder=dict(type="str", default="General"),
+ uid=dict(type="str"),
+ slug=dict(type="str"),
+ path=dict(aliases=["dashboard_url"], type="str"),
+ dashboard_id=dict(type="str"),
+ dashboard_revision=dict(type="str", default="1"),
+ overwrite=dict(type="bool", default=False),
+ commit_message=dict(
+ type="str",
+ aliases=["message"],
+ deprecated_aliases=[
+ dict(
+ name="message", version="2.0.0", collection_name="community.grafana"
+ )
+ ],
+ ),
)
module = AnsibleModule(
argument_spec=argument_spec,
- supports_check_mode=False,
+ supports_check_mode=True,
required_if=[
- ['state', 'export', ['path']],
+ ["state", "export", ["path"]],
+ ],
+ required_together=[["url_username", "url_password", "org_id"]],
+ mutually_exclusive=[
+ ["url_username", "grafana_api_key"],
+ ["uid", "slug"],
+ ["path", "dashboard_id"],
+ ["org_id", "org_name"],
],
- required_together=[['url_username', 'url_password', 'org_id']],
- mutually_exclusive=[['url_username', 'grafana_api_key'], ['uid', 'slug'], ['path', 'dashboard_id']],
)
module.params["url"] = clean_url(module.params["url"])
- if 'message' in module.params:
- module.fail_json(msg="'message' is reserved keyword, please change this parameter to 'commit_message'")
+ if "message" in module.params:
+ module.fail_json(
+ msg="'message' is reserved keyword, please change this parameter to 'commit_message'"
+ )
try:
- if module.params['state'] == 'present':
+ if module.params["state"] == "present":
result = grafana_create_dashboard(module, module.params)
- elif module.params['state'] == 'absent':
+ elif module.params["state"] == "absent":
result = grafana_delete_dashboard(module, module.params)
else:
result = grafana_export_dashboard(module, module.params)
except GrafanaAPIException as e:
- module.fail_json(
- failed=True,
- msg="error : %s" % to_native(e)
- )
+ module.fail_json(failed=True, msg="error : %s" % to_native(e))
return
except GrafanaMalformedJson as e:
- module.fail_json(
- failed=True,
- msg="error : %s" % to_native(e)
- )
+ module.fail_json(failed=True, msg="error : %s" % to_native(e))
return
except GrafanaDeleteException as e:
module.fail_json(
- failed=True,
- msg="error : Can't delete dashboard : %s" % to_native(e)
+ failed=True, msg="error : Can't delete dashboard : %s" % to_native(e)
)
return
except GrafanaExportException as e:
module.fail_json(
- failed=True,
- msg="error : Can't export dashboard : %s" % to_native(e)
+ failed=True, msg="error : Can't export dashboard : %s" % to_native(e)
)
return
- module.exit_json(
- failed=False,
- **result
- )
+ module.exit_json(failed=False, **result)
return
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/grafana/plugins/modules/grafana_datasource.py b/ansible_collections/community/grafana/plugins/modules/grafana_datasource.py
index 6346038f4..29cdbea7c 100644
--- a/ansible_collections/community/grafana/plugins/modules/grafana_datasource.py
+++ b/ansible_collections/community/grafana/plugins/modules/grafana_datasource.py
@@ -5,9 +5,10 @@
# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
-DOCUMENTATION = '''
+DOCUMENTATION = """
module: grafana_datasource
author:
- Thierry Sallé (@seuf)
@@ -46,6 +47,8 @@ options:
- camptocamp-prometheus-alertmanager-datasource
- loki
- redis-datasource
+ - tempo
+ - quickwit-quickwit-datasource
type: str
ds_url:
description:
@@ -67,15 +70,18 @@ options:
(index name), C(mysql) or C(postgres).
required: false
type: str
+ default: ''
user:
description:
- The datasource login user for influxdb datasources.
type: str
+ default: ''
password:
description:
- The datasource password.
- Stored as secure data, see C(enforce_secure_data) and notes!
type: str
+ default: ''
basic_auth_user:
description:
- The datasource basic auth user.
@@ -83,7 +89,7 @@ options:
type: str
basic_auth_password:
description:
- - The datasource basic auth password, when C(basic auth) is C(yes).
+ - The datasource basic auth password, when C(basic auth) is C(true).
- Stored as secure data, see C(enforce_secure_data) and notes!
type: str
with_credentials:
@@ -91,7 +97,7 @@ options:
- Whether credentials such as cookies or auth headers should be sent with cross-site
requests.
type: bool
- default: 'no'
+ default: false
tls_client_cert:
description:
- The client TLS certificate.
@@ -120,14 +126,22 @@ options:
description:
- Make this datasource the default one.
type: bool
- default: 'no'
+ default: false
org_id:
description:
- - Grafana Organisation ID in which the datasource should be created.
+ - Grafana organization ID in which the datasource should be created.
- Not used when C(grafana_api_key) is set, because the C(grafana_api_key) only
- belong to one organisation.
+ belongs to one organization.
+ - Mutually exclusive with C(org_name).
default: 1
type: int
+ org_name:
+ description:
+ - Grafana organization name in which the datasource should be created.
+ - Not used when C(grafana_api_key) is set, because the C(grafana_api_key) only
+ belongs to one organization.
+ - Mutually exclusive with C(org_id).
+ type: str
state:
description:
- Status of the datasource
@@ -166,7 +180,7 @@ options:
default: '@timestamp'
time_interval:
description:
- - Minimum group by interval for C(influxdb) or C(elasticsearch) datasources.
+ - Minimum group by interval for C(influxdb), C(elasticsearch) or C(prometheus) datasources.
- for example C(>10s).
type: str
interval:
@@ -180,6 +194,7 @@ options:
- Monthly
- Yearly
type: str
+ default: ''
tsdb_version:
description:
- The opentsdb version.
@@ -213,7 +228,7 @@ options:
description:
- Use trends or not for zabbix datasource type.
type: bool
- default: False
+ default: false
aws_auth_type:
description:
- Type for AWS authentication for CloudWatch datasource type (authType of grafana
@@ -280,7 +295,6 @@ options:
aws_custom_metrics_namespaces:
description:
- Namespaces of Custom Metrics for CloudWatch datasource type
- default: ''
required: false
type: str
azure_cloud:
@@ -350,9 +364,9 @@ notes:
data will not be updated after initial creation! To force the secure data update you have to set I(enforce_secure_data=True).
- Hint, with the C(enforce_secure_data) always reporting changed=True, you might just do one Task updating the datasource without
any secure data and make a separate playbook/task also changing the secure data. This way it will not break any workflow.
-'''
+"""
-EXAMPLES = '''
+EXAMPLES = """
---
- name: Create elasticsearch datasource
community.grafana.grafana_datasource:
@@ -460,9 +474,9 @@ EXAMPLES = '''
additional_secure_json_data:
httpHeaderValue1: "Bearer ihavenogroot"
enforce_secure_data: true
-'''
+"""
-RETURN = '''
+RETURN = """
---
datasource:
description: datasource created/updated by module
@@ -488,13 +502,13 @@ datasource:
"user": "",
"password": "",
"withCredentials": false }
-'''
+"""
import json
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six.moves.urllib.parse import quote
-from ansible.module_utils.urls import fetch_url, url_argument_spec, basic_auth_header
+from ansible.module_utils.urls import fetch_url, basic_auth_header
from ansible_collections.community.grafana.plugins.module_utils import base
@@ -506,175 +520,191 @@ ES_VERSION_MAPPING = {
def compare_datasources(new, current, compareSecureData=True):
- if new['uid'] is None:
- del current['uid']
- del new['uid']
- del current['typeLogoUrl']
- del current['id']
- if 'version' in current:
- del current['version']
- if 'readOnly' in current:
- del current['readOnly']
- if current['basicAuth'] is False:
- del current['basicAuthUser']
- if 'password' in current:
- del current['password']
- if 'basicAuthPassword' in current:
- del current['basicAuthPassword']
+ if new["uid"] is None:
+ del current["uid"]
+ del new["uid"]
+ del current["typeLogoUrl"]
+ del current["id"]
+ if "version" in current:
+ del current["version"]
+ if "readOnly" in current:
+ del current["readOnly"]
+ if current["basicAuth"] is False:
+ if "basicAuthUser" in current:
+ del current["basicAuthUser"]
+ if "password" in current:
+ del current["password"]
+ if "basicAuthPassword" in current:
+ del current["basicAuthPassword"]
# check if secureJsonData should be compared
if not compareSecureData:
# if we should ignore it just drop alltogether
- new.pop('secureJsonData', None)
- new.pop('secureJsonFields', None)
- current.pop('secureJsonData', None)
- current.pop('secureJsonFields', None)
+ new.pop("secureJsonData", None)
+ new.pop("secureJsonFields", None)
+ current.pop("secureJsonData", None)
+ current.pop("secureJsonFields", None)
else:
# handle secureJsonData/secureJsonFields, some current facts:
# - secureJsonFields is reporting each field set as true
# - secureJsonFields once set cant be removed (DS has to be deleted)
- if not new.get('secureJsonData'):
+ if not new.get("secureJsonData"):
# secureJsonData is not provided so just remove both for comparision
- new.pop('secureJsonData', None)
- current.pop('secureJsonFields', None)
+ new.pop("secureJsonData", None)
+ current.pop("secureJsonFields", None)
else:
# we have some secure data so just "rename" secureJsonFields for comparison as it will change anyhow everytime
- current['secureJsonData'] = current.pop('secureJsonFields')
+ current["secureJsonData"] = current.pop("secureJsonFields")
return dict(before=current, after=new)
-def get_datasource_payload(data):
+def get_datasource_payload(data, org_id=None):
payload = {
- 'orgId': data['org_id'],
- 'name': data['name'],
- 'uid': data['uid'],
- 'type': data['ds_type'],
- 'access': data['access'],
- 'url': data['ds_url'],
- 'database': data['database'],
- 'withCredentials': data['with_credentials'],
- 'isDefault': data['is_default'],
- 'user': data['user'],
- 'jsonData': data['additional_json_data'],
- 'secureJsonData': data['additional_secure_json_data']
+ "orgId": data["org_id"] if org_id is None else org_id,
+ "name": data["name"],
+ "uid": data["uid"],
+ "type": data["ds_type"],
+ "access": data["access"],
+ "url": data["ds_url"],
+ "database": data["database"],
+ "withCredentials": data["with_credentials"],
+ "isDefault": data["is_default"],
+ "user": data["user"],
+ "jsonData": data["additional_json_data"],
+ "secureJsonData": data["additional_secure_json_data"],
}
- json_data = payload['jsonData']
- secure_json_data = payload['secureJsonData']
+ json_data = payload["jsonData"]
+ secure_json_data = payload["secureJsonData"]
# define password
- if data.get('password'):
- secure_json_data['password'] = data['password']
+ if data.get("password"):
+ secure_json_data["password"] = data["password"]
# define basic auth
- if 'basic_auth_user' in data and data['basic_auth_user'] and 'basic_auth_password' in data and data['basic_auth_password']:
- payload['basicAuth'] = True
- payload['basicAuthUser'] = data['basic_auth_user']
- secure_json_data['basicAuthPassword'] = data['basic_auth_password']
+ if (
+ "basic_auth_user" in data
+ and data["basic_auth_user"]
+ and "basic_auth_password" in data
+ and data["basic_auth_password"]
+ ):
+ payload["basicAuth"] = True
+ payload["basicAuthUser"] = data["basic_auth_user"]
+ secure_json_data["basicAuthPassword"] = data["basic_auth_password"]
else:
- payload['basicAuth'] = False
+ payload["basicAuth"] = False
# define tls auth
- if data.get('tls_client_cert') and data.get('tls_client_key'):
- json_data['tlsAuth'] = True
- if data.get('tls_ca_cert'):
- secure_json_data['tlsCACert'] = data['tls_ca_cert']
- secure_json_data['tlsClientCert'] = data['tls_client_cert']
- secure_json_data['tlsClientKey'] = data['tls_client_key']
- json_data['tlsAuthWithCACert'] = True
+ if data.get("tls_client_cert") and data.get("tls_client_key"):
+ json_data["tlsAuth"] = True
+ if data.get("tls_ca_cert"):
+ secure_json_data["tlsCACert"] = data["tls_ca_cert"]
+ secure_json_data["tlsClientCert"] = data["tls_client_cert"]
+ secure_json_data["tlsClientKey"] = data["tls_client_key"]
+ json_data["tlsAuthWithCACert"] = True
else:
- secure_json_data['tlsClientCert'] = data['tls_client_cert']
- secure_json_data['tlsClientKey'] = data['tls_client_key']
+ secure_json_data["tlsClientCert"] = data["tls_client_cert"]
+ secure_json_data["tlsClientKey"] = data["tls_client_key"]
else:
- json_data['tlsAuth'] = False
- json_data['tlsAuthWithCACert'] = False
- if data.get('tls_ca_cert'):
- json_data['tlsAuthWithCACert'] = True
- secure_json_data['tlsCACert'] = data['tls_ca_cert']
+ json_data["tlsAuth"] = False
+ json_data["tlsAuthWithCACert"] = False
+ if data.get("tls_ca_cert"):
+ json_data["tlsAuthWithCACert"] = True
+ secure_json_data["tlsCACert"] = data["tls_ca_cert"]
- if data.get('tls_skip_verify'):
- json_data['tlsSkipVerify'] = True
+ if data.get("tls_skip_verify"):
+ json_data["tlsSkipVerify"] = True
# datasource type related parameters
- if data['ds_type'] == 'elasticsearch':
-
- json_data['maxConcurrentShardRequests'] = data['max_concurrent_shard_requests']
- json_data['timeField'] = data['time_field']
- if data.get('interval'):
- json_data['interval'] = data['interval']
+ if data["ds_type"] == "elasticsearch":
+ json_data["maxConcurrentShardRequests"] = data["max_concurrent_shard_requests"]
+ json_data["timeField"] = data["time_field"]
+ if data.get("interval"):
+ json_data["interval"] = data["interval"]
# Handle changes in es_version format in Grafana < 8.x which used to
# be integers and is now semver format
try:
- es_version = int(data['es_version'])
+ es_version = int(data["es_version"])
if es_version < 56:
- json_data.pop('maxConcurrentShardRequests')
+ json_data.pop("maxConcurrentShardRequests")
except ValueError:
# Retrieve the Semver format expected by API
- es_version = ES_VERSION_MAPPING.get(data['es_version'])
- json_data['esVersion'] = es_version
+ es_version = ES_VERSION_MAPPING.get(data["es_version"])
+ json_data["esVersion"] = es_version
- if data['ds_type'] == 'elasticsearch' or data['ds_type'] == 'influxdb':
- if data.get('time_interval'):
- json_data['timeInterval'] = data['time_interval']
+ if data["ds_type"] in ["elasticsearch", "influxdb", "prometheus"]:
+ if data.get("time_interval"):
+ json_data["timeInterval"] = data["time_interval"]
- if data['ds_type'] == 'opentsdb':
- json_data['tsdbVersion'] = data['tsdb_version']
- if data['tsdb_resolution'] == 'second':
- json_data['tsdbResolution'] = 1
+ if data["ds_type"] == "opentsdb":
+ json_data["tsdbVersion"] = data["tsdb_version"]
+ if data["tsdb_resolution"] == "second":
+ json_data["tsdbResolution"] = 1
else:
- json_data['tsdbResolution'] = 2
-
- if data['ds_type'] == 'postgres':
- json_data['sslmode'] = data['sslmode']
-
- if data['ds_type'] == 'alexanderzobnin-zabbix-datasource':
- if data.get('trends'):
- json_data['trends'] = True
- json_data['username'] = data['zabbix_user']
- json_data['password'] = data['zabbix_password']
-
- if data['ds_type'] == 'grafana-azure-monitor-datasource':
- json_data['tenantId'] = data['azure_tenant']
- json_data['clientId'] = data['azure_client']
- json_data['cloudName'] = data['azure_cloud']
- json_data['clientsecret'] = 'clientsecret'
- if data.get('azure_secret'):
- secure_json_data['clientSecret'] = data['azure_secret']
-
- if data['ds_type'] == 'cloudwatch':
- if data.get('aws_credentials_profile'):
- payload['database'] = data.get('aws_credentials_profile')
-
- json_data['authType'] = data['aws_auth_type']
- json_data['defaultRegion'] = data['aws_default_region']
-
- if data.get('aws_custom_metrics_namespaces'):
- json_data['customMetricsNamespaces'] = data.get('aws_custom_metrics_namespaces')
- if data.get('aws_assume_role_arn'):
- json_data['assumeRoleArn'] = data.get('aws_assume_role_arn')
- if data.get('aws_access_key') and data.get('aws_secret_key'):
- secure_json_data['accessKey'] = data.get('aws_access_key')
- secure_json_data['secretKey'] = data.get('aws_secret_key')
-
- payload['jsonData'] = json_data
- payload['secureJsonData'] = secure_json_data
+ json_data["tsdbResolution"] = 2
+
+ if data["ds_type"] == "postgres":
+ json_data["sslmode"] = data["sslmode"]
+
+ if data["ds_type"] == "alexanderzobnin-zabbix-datasource":
+ if data.get("trends"):
+ json_data["trends"] = True
+ json_data["username"] = data["zabbix_user"]
+ json_data["password"] = data["zabbix_password"]
+
+ if data["ds_type"] == "grafana-azure-monitor-datasource":
+ json_data["tenantId"] = data["azure_tenant"]
+ json_data["clientId"] = data["azure_client"]
+ json_data["cloudName"] = data["azure_cloud"]
+ json_data["clientsecret"] = "clientsecret"
+ if data.get("azure_secret"):
+ secure_json_data["clientSecret"] = data["azure_secret"]
+
+ if data["ds_type"] == "cloudwatch":
+ if data.get("aws_credentials_profile"):
+ payload["database"] = data.get("aws_credentials_profile")
+
+ json_data["authType"] = data["aws_auth_type"]
+ json_data["defaultRegion"] = data["aws_default_region"]
+
+ if data.get("aws_custom_metrics_namespaces"):
+ json_data["customMetricsNamespaces"] = data.get(
+ "aws_custom_metrics_namespaces"
+ )
+ if data.get("aws_assume_role_arn"):
+ json_data["assumeRoleArn"] = data.get("aws_assume_role_arn")
+ if data.get("aws_access_key") and data.get("aws_secret_key"):
+ secure_json_data["accessKey"] = data.get("aws_access_key")
+ secure_json_data["secretKey"] = data.get("aws_secret_key")
+
+ payload["jsonData"] = json_data
+ payload["secureJsonData"] = secure_json_data
return payload
class GrafanaInterface(object):
-
def __init__(self, module):
self._module = module
self.grafana_url = base.clean_url(module.params.get("url"))
+ self.org_id = None
# {{{ Authentication header
self.headers = {"Content-Type": "application/json"}
- if module.params.get('grafana_api_key', None):
- self.headers["Authorization"] = "Bearer %s" % module.params['grafana_api_key']
+ if module.params.get("grafana_api_key", None):
+ self.headers["Authorization"] = (
+ "Bearer %s" % module.params["grafana_api_key"]
+ )
else:
- self.headers["Authorization"] = basic_auth_header(module.params['url_username'], module.params['url_password'])
- self.switch_organisation(module.params['org_id'])
+ self.headers["Authorization"] = basic_auth_header(
+ module.params["url_username"], module.params["url_password"]
+ )
+ self.org_id = (
+ self.organization_by_name(module.params["org_name"])
+ if module.params["org_name"]
+ else module.params["org_id"]
+ )
+ self.switch_organization(self.org_id)
# }}}
def _send_request(self, url, data=None, headers=None, method="GET"):
@@ -684,125 +714,200 @@ class GrafanaInterface(object):
headers = []
full_url = "{grafana_url}{path}".format(grafana_url=self.grafana_url, path=url)
- resp, info = fetch_url(self._module, full_url, data=data, headers=headers, method=method)
+ resp, info = fetch_url(
+ self._module, full_url, data=data, headers=headers, method=method
+ )
status_code = info["status"]
if status_code == 404:
return None
elif status_code == 401:
- self._module.fail_json(failed=True, msg="Unauthorized to perform action '%s' on '%s'" % (method, full_url))
+ self._module.fail_json(
+ failed=True,
+ msg="Unauthorized to perform action '%s' on '%s'" % (method, full_url),
+ )
elif status_code == 403:
self._module.fail_json(failed=True, msg="Permission Denied")
elif status_code == 200:
return self._module.from_json(resp.read())
- self._module.fail_json(failed=True, msg="Grafana API answered with HTTP %d for url %s and data %s" % (status_code, url, data))
+ self._module.fail_json(
+ failed=True,
+ msg="Grafana API answered with HTTP %d for url %s and data %s"
+ % (status_code, url, data),
+ )
- def switch_organisation(self, org_id):
+ def switch_organization(self, org_id):
url = "/api/user/using/%d" % org_id
- response = self._send_request(url, headers=self.headers, method='POST')
+ self._send_request(url, headers=self.headers, method="POST")
+
+ def organization_by_name(self, org_name):
+ url = "/api/user/orgs"
+ organizations = self._send_request(url, headers=self.headers, method="GET")
+ orga = next((org for org in organizations if org["name"] == org_name))
+ if orga:
+ return orga["orgId"]
+
+ return self._module.fail_json(
+ failed=True, msg="Current user isn't member of organization: %s" % org_name
+ )
def datasource_by_name(self, name):
- datasource_exists = False
- ds = {}
- url = "/api/datasources/name/%s" % quote(name, safe='')
- return self._send_request(url, headers=self.headers, method='GET')
+ url = "/api/datasources/name/%s" % quote(name, safe="")
+ return self._send_request(url, headers=self.headers, method="GET")
def delete_datasource(self, name):
- url = "/api/datasources/name/%s" % quote(name, safe='')
- self._send_request(url, headers=self.headers, method='DELETE')
+ url = "/api/datasources/name/%s" % quote(name, safe="")
+ self._send_request(url, headers=self.headers, method="DELETE")
def update_datasource(self, ds_id, data):
url = "/api/datasources/%d" % ds_id
- self._send_request(url, data=data, headers=self.headers, method='PUT')
+ self._send_request(url, data=data, headers=self.headers, method="PUT")
def create_datasource(self, data):
url = "/api/datasources"
- self._send_request(url, data=data, headers=self.headers, method='POST')
+ self._send_request(url, data=data, headers=self.headers, method="POST")
def setup_module_object():
argument_spec = base.grafana_argument_spec()
argument_spec.update(
- name=dict(required=True, type='str'),
- uid=dict(type='str'),
- ds_type=dict(choices=['graphite',
- 'prometheus',
- 'elasticsearch',
- 'influxdb',
- 'opentsdb',
- 'mysql',
- 'postgres',
- 'cloudwatch',
- 'alexanderzobnin-zabbix-datasource',
- 'grafana-azure-monitor-datasource',
- 'camptocamp-prometheus-alertmanager-datasource',
- 'sni-thruk-datasource',
- 'redis-datasource',
- 'loki']),
- ds_url=dict(type='str'),
- access=dict(default='proxy', choices=['proxy', 'direct']),
- database=dict(type='str', default=""),
- user=dict(default='', type='str'),
- password=dict(default='', no_log=True, type='str'),
- basic_auth_user=dict(type='str'),
- basic_auth_password=dict(type='str', no_log=True),
- with_credentials=dict(default=False, type='bool'),
- tls_client_cert=dict(type='str', no_log=True),
- tls_client_key=dict(type='str', no_log=True),
- tls_ca_cert=dict(type='str', no_log=True),
- tls_skip_verify=dict(type='bool', default=False),
- is_default=dict(default=False, type='bool'),
- org_id=dict(default=1, type='int'),
- es_version=dict(type='str', default="7.10+", choices=["2", "5", "56", "60",
- "70", "7.7+", "7.10+",
- "8.0+"]),
- max_concurrent_shard_requests=dict(type='int', default=256),
- time_field=dict(default='@timestamp', type='str'),
- time_interval=dict(type='str'),
- interval=dict(type='str', choices=['', 'Hourly', 'Daily', 'Weekly', 'Monthly', 'Yearly'], default=''),
- tsdb_version=dict(type='int', default=1, choices=[1, 2, 3]),
- tsdb_resolution=dict(type='str', default='second', choices=['second', 'millisecond']),
- sslmode=dict(default='disable', choices=['disable', 'require', 'verify-ca', 'verify-full']),
- trends=dict(default=False, type='bool'),
- aws_auth_type=dict(default='keys', choices=['keys', 'credentials', 'arn', 'default']),
- aws_default_region=dict(default='us-east-1', choices=['ap-northeast-1', 'ap-northeast-2', 'ap-southeast-1', 'ap-southeast-2', 'ap-south-1',
- 'ca-central-1',
- 'cn-north-1', 'cn-northwest-1',
- 'eu-central-1', 'eu-west-1', 'eu-west-2', 'eu-west-3',
- 'sa-east-1',
- 'us-east-1', 'us-east-2', 'us-gov-west-1', 'us-west-1', 'us-west-2']),
- aws_access_key=dict(default='', no_log=True, type='str'),
- aws_secret_key=dict(default='', no_log=True, type='str'),
- aws_credentials_profile=dict(default='', type='str'),
- aws_assume_role_arn=dict(default='', type='str'),
- aws_custom_metrics_namespaces=dict(type='str'),
- azure_cloud=dict(type='str', default='azuremonitor', choices=['azuremonitor', 'chinaazuremonitor', 'govazuremonitor', 'germanyazuremonitor']),
- azure_tenant=dict(type='str'),
- azure_client=dict(type='str'),
- azure_secret=dict(type='str', no_log=True),
- zabbix_user=dict(type='str'),
- zabbix_password=dict(type='str', no_log=True),
- additional_json_data=dict(type='dict', default={}, required=False),
- additional_secure_json_data=dict(type='dict', default={}, required=False),
- enforce_secure_data=dict(type='bool', default=False, required=False)
+ name=dict(required=True, type="str"),
+ uid=dict(type="str"),
+ ds_type=dict(
+ choices=[
+ "graphite",
+ "prometheus",
+ "elasticsearch",
+ "influxdb",
+ "opentsdb",
+ "mysql",
+ "postgres",
+ "cloudwatch",
+ "alexanderzobnin-zabbix-datasource",
+ "grafana-azure-monitor-datasource",
+ "camptocamp-prometheus-alertmanager-datasource",
+ "sni-thruk-datasource",
+ "redis-datasource",
+ "loki",
+ "tempo",
+ "quickwit-quickwit-datasource",
+ ]
+ ),
+ ds_url=dict(type="str"),
+ access=dict(default="proxy", choices=["proxy", "direct"]),
+ database=dict(type="str", default=""),
+ user=dict(default="", type="str"),
+ password=dict(default="", no_log=True, type="str"),
+ basic_auth_user=dict(type="str"),
+ basic_auth_password=dict(type="str", no_log=True),
+ with_credentials=dict(default=False, type="bool"),
+ tls_client_cert=dict(type="str", no_log=True),
+ tls_client_key=dict(type="str", no_log=True),
+ tls_ca_cert=dict(type="str", no_log=True),
+ tls_skip_verify=dict(type="bool", default=False),
+ is_default=dict(default=False, type="bool"),
+ org_id=dict(default=1, type="int"),
+ org_name=dict(type="str"),
+ es_version=dict(
+ type="str",
+ default="7.10+",
+ choices=["2", "5", "56", "60", "70", "7.7+", "7.10+", "8.0+"],
+ ),
+ max_concurrent_shard_requests=dict(type="int", default=256),
+ time_field=dict(default="@timestamp", type="str"),
+ time_interval=dict(type="str"),
+ interval=dict(
+ type="str",
+ choices=["", "Hourly", "Daily", "Weekly", "Monthly", "Yearly"],
+ default="",
+ ),
+ tsdb_version=dict(type="int", default=1, choices=[1, 2, 3]),
+ tsdb_resolution=dict(
+ type="str", default="second", choices=["second", "millisecond"]
+ ),
+ sslmode=dict(
+ default="disable",
+ choices=["disable", "require", "verify-ca", "verify-full"],
+ ),
+ trends=dict(default=False, type="bool"),
+ aws_auth_type=dict(
+ default="keys", choices=["keys", "credentials", "arn", "default"]
+ ),
+ aws_default_region=dict(
+ default="us-east-1",
+ choices=[
+ "ap-northeast-1",
+ "ap-northeast-2",
+ "ap-southeast-1",
+ "ap-southeast-2",
+ "ap-south-1",
+ "ca-central-1",
+ "cn-north-1",
+ "cn-northwest-1",
+ "eu-central-1",
+ "eu-west-1",
+ "eu-west-2",
+ "eu-west-3",
+ "sa-east-1",
+ "us-east-1",
+ "us-east-2",
+ "us-gov-west-1",
+ "us-west-1",
+ "us-west-2",
+ ],
+ ),
+ aws_access_key=dict(default="", no_log=True, type="str"),
+ aws_secret_key=dict(default="", no_log=True, type="str"),
+ aws_credentials_profile=dict(default="", type="str"),
+ aws_assume_role_arn=dict(default="", type="str"),
+ aws_custom_metrics_namespaces=dict(type="str"),
+ azure_cloud=dict(
+ type="str",
+ default="azuremonitor",
+ choices=[
+ "azuremonitor",
+ "chinaazuremonitor",
+ "govazuremonitor",
+ "germanyazuremonitor",
+ ],
+ ),
+ azure_tenant=dict(type="str"),
+ azure_client=dict(type="str"),
+ azure_secret=dict(type="str", no_log=True),
+ zabbix_user=dict(type="str"),
+ zabbix_password=dict(type="str", no_log=True),
+ additional_json_data=dict(type="dict", default={}, required=False),
+ additional_secure_json_data=dict(type="dict", default={}, required=False),
+ enforce_secure_data=dict(type="bool", default=False, required=False),
)
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=False,
- required_together=[['url_username', 'url_password', 'org_id'], ['tls_client_cert', 'tls_client_key']],
- mutually_exclusive=[['url_username', 'grafana_api_key'], ['tls_ca_cert', 'tls_skip_verify']],
+ required_together=[
+ ["url_username", "url_password", "org_id"],
+ ["tls_client_cert", "tls_client_key"],
+ ],
+ mutually_exclusive=[
+ ["url_username", "grafana_api_key"],
+ ["tls_ca_cert", "tls_skip_verify"],
+ ["org_id", "org_name"],
+ ],
required_if=[
- ['state', 'present', ['ds_type', 'ds_url']],
- ['ds_type', 'opentsdb', ['tsdb_version', 'tsdb_resolution']],
- ['ds_type', 'influxdb', ['database']],
- ['ds_type', 'elasticsearch', ['database', 'es_version', 'time_field', 'interval']],
- ['ds_type', 'mysql', ['database']],
- ['ds_type', 'postgres', ['database', 'sslmode']],
- ['ds_type', 'cloudwatch', ['aws_auth_type', 'aws_default_region']],
- ['es_version', "56", ['max_concurrent_shard_requests']],
- ['es_version', "60", ['max_concurrent_shard_requests']],
- ['es_version', "70", ['max_concurrent_shard_requests']]
+ ["state", "present", ["ds_type", "ds_url"]],
+ ["ds_type", "opentsdb", ["tsdb_version", "tsdb_resolution"]],
+ ["ds_type", "influxdb", ["database"]],
+ [
+ "ds_type",
+ "elasticsearch",
+ ["database", "es_version", "time_field", "interval"],
+ ],
+ ["ds_type", "mysql", ["database"]],
+ ["ds_type", "postgres", ["database", "sslmode"]],
+ ["ds_type", "cloudwatch", ["aws_auth_type", "aws_default_region"]],
+ ["es_version", "56", ["max_concurrent_shard_requests"]],
+ ["es_version", "60", ["max_concurrent_shard_requests"]],
+ ["es_version", "70", ["max_concurrent_shard_requests"]],
],
)
return module
@@ -811,35 +916,52 @@ def setup_module_object():
def main():
module = setup_module_object()
- state = module.params['state']
- name = module.params['name']
- enforce_secure_data = module.params['enforce_secure_data']
+ state = module.params["state"]
+ name = module.params["name"]
+ enforce_secure_data = module.params["enforce_secure_data"]
grafana_iface = GrafanaInterface(module)
ds = grafana_iface.datasource_by_name(name)
- if state == 'present':
- payload = get_datasource_payload(module.params)
+ if state == "present":
+ payload = get_datasource_payload(module.params, grafana_iface.org_id)
if ds is None:
grafana_iface.create_datasource(payload)
ds = grafana_iface.datasource_by_name(name)
- module.exit_json(changed=True, datasource=ds, msg='Datasource %s created' % name)
+ module.exit_json(
+ changed=True, datasource=ds, msg="Datasource %s created" % name
+ )
else:
diff = compare_datasources(payload.copy(), ds.copy(), enforce_secure_data)
- if diff.get('before') == diff.get('after'):
- module.exit_json(changed=False, datasource=ds, msg='Datasource %s unchanged' % name)
- grafana_iface.update_datasource(ds.get('id'), payload)
+ if diff.get("before") == diff.get("after"):
+ module.exit_json(
+ changed=False, datasource=ds, msg="Datasource %s unchanged" % name
+ )
+ grafana_iface.update_datasource(ds.get("id"), payload)
ds = grafana_iface.datasource_by_name(name)
- if diff.get('before') == diff.get('after'):
- module.exit_json(changed=False, datasource=ds, msg='Datasource %s unchanged' % name)
-
- module.exit_json(changed=True, diff=diff, datasource=ds, msg='Datasource %s updated' % name)
+ if diff.get("before") == diff.get("after"):
+ module.exit_json(
+ changed=False, datasource=ds, msg="Datasource %s unchanged" % name
+ )
+
+ module.exit_json(
+ changed=True,
+ diff=diff,
+ datasource=ds,
+ msg="Datasource %s updated" % name,
+ )
else:
if ds is None:
- module.exit_json(changed=False, datasource=None, msg='Datasource %s does not exist.' % name)
+ module.exit_json(
+ changed=False,
+ datasource=None,
+ msg="Datasource %s does not exist." % name,
+ )
grafana_iface.delete_datasource(name)
- module.exit_json(changed=True, datasource=None, msg='Datasource %s deleted.' % name)
+ module.exit_json(
+ changed=True, datasource=None, msg="Datasource %s deleted." % name
+ )
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/grafana/plugins/modules/grafana_folder.py b/ansible_collections/community/grafana/plugins/modules/grafana_folder.py
index d39e56e41..73c437dbb 100644
--- a/ansible_collections/community/grafana/plugins/modules/grafana_folder.py
+++ b/ansible_collections/community/grafana/plugins/modules/grafana_folder.py
@@ -19,7 +19,7 @@
from __future__ import absolute_import, division, print_function
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
module: grafana_folder
author:
@@ -44,20 +44,35 @@ options:
default: present
type: str
choices: ["present", "absent"]
+ org_id:
+ description:
+ - Grafana organization ID in which the datasource should be created.
+ - Not used when C(grafana_api_key) is set, because the C(grafana_api_key) only
+ belongs to one organization.
+ - Mutually exclusive with C(org_name).
+ default: 1
+ type: int
+ org_name:
+ description:
+ - Grafana organization name in which the datasource should be created.
+ - Not used when C(grafana_api_key) is set, because the C(grafana_api_key) only
+ belongs to one organization.
+ - Mutually exclusive with C(org_id).
+ type: str
skip_version_check:
description:
- Skip Grafana version check and try to reach api endpoint anyway.
- - This parameter can be useful if you enabled `hide_version` in grafana.ini
+ - This parameter can be useful if you enabled C(hide_version) in grafana.ini
required: False
type: bool
- default: False
+ default: false
version_added: "1.2.0"
extends_documentation_fragment:
- community.grafana.basic_auth
- community.grafana.api_key
-'''
+"""
-EXAMPLES = '''
+EXAMPLES = """
---
- name: Create a folder
community.grafana.grafana_folder:
@@ -72,9 +87,9 @@ EXAMPLES = '''
grafana_api_key: "{{ some_api_token_value }}"
title: "grafana_working_group"
state: absent
-'''
+"""
-RETURN = '''
+RETURN = """
---
folder:
description: Information about the Folder
@@ -159,7 +174,7 @@ folder:
type: int
sample:
- 1
-'''
+"""
import json
@@ -177,24 +192,36 @@ class GrafanaError(Exception):
class GrafanaFolderInterface(object):
-
def __init__(self, module):
self._module = module
+ self.grafana_url = base.clean_url(module.params.get("url"))
+ self.org_id = None
# {{{ Authentication header
self.headers = {"Content-Type": "application/json"}
- if module.params.get('grafana_api_key', None):
- self.headers["Authorization"] = "Bearer %s" % module.params['grafana_api_key']
+ if module.params.get("grafana_api_key", None):
+ self.headers["Authorization"] = (
+ "Bearer %s" % module.params["grafana_api_key"]
+ )
else:
- self.headers["Authorization"] = basic_auth_header(module.params['url_username'], module.params['url_password'])
+ self.headers["Authorization"] = basic_auth_header(
+ module.params["url_username"], module.params["url_password"]
+ )
+ self.org_id = (
+ self.organization_by_name(module.params["org_name"])
+ if module.params["org_name"]
+ else module.params["org_id"]
+ )
+ self.switch_organization(self.org_id)
# }}}
- self.grafana_url = base.clean_url(module.params.get("url"))
if module.params.get("skip_version_check") is False:
try:
grafana_version = self.get_version()
except GrafanaError as e:
self._module.fail_json(failed=True, msg=to_text(e))
if grafana_version["major"] < 5:
- self._module.fail_json(failed=True, msg="Folders API is available starting Grafana v5")
+ self._module.fail_json(
+ failed=True, msg="Folders API is available starting Grafana v5"
+ )
def _send_request(self, url, data=None, headers=None, method="GET"):
if data is not None:
@@ -203,24 +230,51 @@ class GrafanaFolderInterface(object):
headers = []
full_url = "{grafana_url}{path}".format(grafana_url=self.grafana_url, path=url)
- resp, info = fetch_url(self._module, full_url, data=data, headers=headers, method=method)
+ resp, info = fetch_url(
+ self._module, full_url, data=data, headers=headers, method=method
+ )
status_code = info["status"]
if status_code == 404:
return None
elif status_code == 401:
- self._module.fail_json(failed=True, msg="Unauthorized to perform action '%s' on '%s'" % (method, full_url))
+ self._module.fail_json(
+ failed=True,
+ msg="Unauthorized to perform action '%s' on '%s'" % (method, full_url),
+ )
elif status_code == 403:
self._module.fail_json(failed=True, msg="Permission Denied")
elif status_code == 412:
- error_msg = resp.read()['message']
+ error_msg = resp.read()["message"]
self._module.fail_json(failed=True, msg=error_msg)
elif status_code == 200:
- return self._module.from_json(resp.read())
- self._module.fail_json(failed=True, msg="Grafana Folders API answered with HTTP %d" % status_code)
+ # XXX: Grafana folders endpoint stopped sending back json in response for delete operations
+ # see https://github.com/grafana/grafana/issues/77673
+ response = resp.read() or "{}"
+ return self._module.from_json(response)
+ self._module.fail_json(
+ failed=True, msg="Grafana Folders API answered with HTTP %d" % status_code
+ )
+
+ def switch_organization(self, org_id):
+ url = "/api/user/using/%d" % org_id
+ self._send_request(url, headers=self.headers, method="POST")
+
+ def organization_by_name(self, org_name):
+ url = "/api/user/orgs"
+ organizations = self._send_request(url, headers=self.headers, method="GET")
+ orga = next((org for org in organizations if org["name"] == org_name))
+ if orga:
+ return orga["orgId"]
+
+ self._module.fail_json(
+ failed=True, msg="Current user isn't member of organization: %s" % org_name
+ )
def get_version(self):
url = "/api/health"
- response = self._send_request(url, data=None, headers=self.headers, method="GET")
+ response = self._send_request(
+ url, data=None, headers=self.headers, method="GET"
+ )
version = response.get("version")
if version is not None:
major, minor, rev = version.split(".")
@@ -230,7 +284,9 @@ class GrafanaFolderInterface(object):
def create_folder(self, title):
url = "/api/folders"
folder = dict(title=title)
- response = self._send_request(url, data=folder, headers=self.headers, method="POST")
+ response = self._send_request(
+ url, data=folder, headers=self.headers, method="POST"
+ )
return response
def get_folder(self, title):
@@ -247,34 +303,33 @@ class GrafanaFolderInterface(object):
return response
-def setup_module_object():
+def main():
+ argument_spec = base.grafana_argument_spec()
+ argument_spec.update(
+ name=dict(type="str", aliases=["title"], required=True),
+ state=dict(type="str", default="present", choices=["present", "absent"]),
+ skip_version_check=dict(type="bool", default=False),
+ org_id=dict(default=1, type="int"),
+ org_name=dict(type="str"),
+ )
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=False,
- required_together=base.grafana_required_together(),
- mutually_exclusive=base.grafana_mutually_exclusive(),
+ required_together=base.grafana_required_together()
+ + [["url_username", "url_password", "org_id"]],
+ mutually_exclusive=base.grafana_mutually_exclusive()
+ + [
+ ["org_id", "org_name"],
+ ],
)
- return module
-
-
-argument_spec = base.grafana_argument_spec()
-argument_spec.update(
- name=dict(type='str', aliases=['title'], required=True),
- state=dict(type='str', default='present', choices=['present', 'absent']),
- skip_version_check=dict(type='bool', default=False),
-)
-
-
-def main():
-
- module = setup_module_object()
- state = module.params['state']
- title = module.params['name']
+ state = module.params["state"]
+ title = module.params["name"]
+ module.params["url"] = base.clean_url(module.params["url"])
grafana_iface = GrafanaFolderInterface(module)
changed = False
- if state == 'present':
+ if state == "present":
folder = grafana_iface.get_folder(title)
if folder is None:
grafana_iface.create_folder(title)
@@ -282,7 +337,7 @@ def main():
changed = True
folder = grafana_iface.get_folder(title)
module.exit_json(changed=changed, folder=folder)
- elif state == 'absent':
+ elif state == "absent":
folder = grafana_iface.get_folder(title)
if folder is None:
module.exit_json(changed=False, message="No folder found")
@@ -290,5 +345,5 @@ def main():
module.exit_json(changed=True, message=result)
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/grafana/plugins/modules/grafana_notification_channel.py b/ansible_collections/community/grafana/plugins/modules/grafana_notification_channel.py
index eb808fa1b..30b5b1124 100644
--- a/ansible_collections/community/grafana/plugins/modules/grafana_notification_channel.py
+++ b/ansible_collections/community/grafana/plugins/modules/grafana_notification_channel.py
@@ -16,9 +16,10 @@
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
module: grafana_notification_channel
notes:
@@ -82,17 +83,17 @@ options:
- Required when I(state) is C(present).
is_default:
type: bool
- default: 'no'
+ default: false
description:
- Use this channel for all alerts.
include_image:
type: bool
- default: 'no'
+ default: false
description:
- Capture a visualization image and attach it to notifications.
disable_resolve_message:
type: bool
- default: 'no'
+ default: false
description:
- Disable the resolve message.
reminder_frequency:
@@ -368,10 +369,10 @@ options:
extends_documentation_fragment:
- community.grafana.basic_auth
- community.grafana.api_key
-'''
+"""
-EXAMPLES = '''
+EXAMPLES = """
- name: Create slack notification channel
register: result
grafana_notification_channel:
@@ -391,9 +392,9 @@ EXAMPLES = '''
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password}}"
-'''
+"""
-RETURN = '''
+RETURN = """
notification_channel:
description: Notification channel created or updated by the module.
returned: changed
@@ -416,14 +417,17 @@ notification_channel:
"uid": "slack-oops",
"updated": "2020-11-10T21:10:19.675308112+03:00"
}
-'''
+"""
import json
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.urls import fetch_url
from ansible.module_utils._text import to_text
-from ansible_collections.community.grafana.plugins.module_utils.base import grafana_argument_spec, clean_url
+from ansible_collections.community.grafana.plugins.module_utils.base import (
+ grafana_argument_spec,
+ clean_url,
+)
from ansible.module_utils.urls import basic_auth_header
@@ -432,412 +436,448 @@ class GrafanaAPIException(Exception):
def dingding_channel_payload(data, payload):
- payload['settings']['url'] = data['dingding_url']
- if data.get('dingding_message_type'):
- payload['settings']['msgType'] = {
- 'link': 'link',
- 'action_card': 'actionCard',
- }[data['dingding_message_type']]
+ payload["settings"]["url"] = data["dingding_url"]
+ if data.get("dingding_message_type"):
+ payload["settings"]["msgType"] = {
+ "link": "link",
+ "action_card": "actionCard",
+ }[data["dingding_message_type"]]
def discord_channel_payload(data, payload):
- payload['settings']['url'] = data['discord_url']
- if data.get('discord_message_content'):
- payload['settings']['content'] = data['discord_message_content']
+ payload["settings"]["url"] = data["discord_url"]
+ if data.get("discord_message_content"):
+ payload["settings"]["content"] = data["discord_message_content"]
def email_channel_payload(data, payload):
- payload['settings']['addresses'] = ';'.join(data['email_addresses'])
- if data.get('email_single'):
- payload['settings']['singleEmail'] = data['email_single']
+ payload["settings"]["addresses"] = ";".join(data["email_addresses"])
+ if data.get("email_single"):
+ payload["settings"]["singleEmail"] = data["email_single"]
def hipchat_channel_payload(data, payload):
- payload['settings']['url'] = data['hipchat_url']
- if data.get('hipchat_api_key'):
- payload['settings']['apiKey'] = data['hipchat_api_key']
- if data.get('hipchat_room_id'):
- payload['settings']['roomid'] = data['hipchat_room_id']
+ payload["settings"]["url"] = data["hipchat_url"]
+ if data.get("hipchat_api_key"):
+ payload["settings"]["apiKey"] = data["hipchat_api_key"]
+ if data.get("hipchat_room_id"):
+ payload["settings"]["roomid"] = data["hipchat_room_id"]
def pagerduty_channel_payload(data, payload):
- payload['settings']['integrationKey'] = data['pagerduty_integration_key']
- if data.get('pagerduty_severity'):
- payload['settings']['severity'] = data['pagerduty_severity']
- if data.get('pagerduty_auto_resolve'):
- payload['settings']['autoResolve'] = data['pagerduty_auto_resolve']
- if data.get('pagerduty_message_in_details'):
- payload['settings']['messageInDetails'] = data['pagerduty_message_in_details']
+ payload["settings"]["integrationKey"] = data["pagerduty_integration_key"]
+ if data.get("pagerduty_severity"):
+ payload["settings"]["severity"] = data["pagerduty_severity"]
+ if data.get("pagerduty_auto_resolve"):
+ payload["settings"]["autoResolve"] = data["pagerduty_auto_resolve"]
+ if data.get("pagerduty_message_in_details"):
+ payload["settings"]["messageInDetails"] = data["pagerduty_message_in_details"]
def prometheus_channel_payload(data, payload):
- payload['type'] = 'prometheus-alertmanager'
- payload['settings']['url'] = data['prometheus_url']
- if data.get('prometheus_username'):
- payload['settings']['basicAuthUser'] = data['prometheus_username']
- if data.get('prometheus_password'):
- payload['settings']['basicAuthPassword'] = data['prometheus_password']
+ payload["type"] = "prometheus-alertmanager"
+ payload["settings"]["url"] = data["prometheus_url"]
+ if data.get("prometheus_username"):
+ payload["settings"]["basicAuthUser"] = data["prometheus_username"]
+ if data.get("prometheus_password"):
+ payload["settings"]["basicAuthPassword"] = data["prometheus_password"]
def pushover_channel_payload(data, payload):
- payload['settings']['apiToken'] = data['pushover_api_token']
- payload['settings']['userKey'] = data['pushover_user_key']
- if data.get('pushover_devices'):
- payload['settings']['device'] = ';'.join(data['pushover_devices'])
- if data.get('pushover_priority'):
- payload['settings']['priority'] = {
- 'emergency': '2',
- 'high': '1',
- 'normal': '0',
- 'low': '-1',
- 'lowest': '-2'
- }[data['pushover_priority']]
- if data.get('pushover_retry'):
- payload['settings']['retry'] = str(data['pushover_retry'])
- if data.get('pushover_expire'):
- payload['settings']['expire'] = str(data['pushover_expire'])
- if data.get('pushover_alert_sound'):
- payload['settings']['sound'] = data['pushover_alert_sound']
- if data.get('pushover_ok_sound'):
- payload['settings']['okSound'] = data['pushover_ok_sound']
+ payload["settings"]["apiToken"] = data["pushover_api_token"]
+ payload["settings"]["userKey"] = data["pushover_user_key"]
+ if data.get("pushover_devices"):
+ payload["settings"]["device"] = ";".join(data["pushover_devices"])
+ if data.get("pushover_priority"):
+ payload["settings"]["priority"] = {
+ "emergency": "2",
+ "high": "1",
+ "normal": "0",
+ "low": "-1",
+ "lowest": "-2",
+ }[data["pushover_priority"]]
+ if data.get("pushover_retry"):
+ payload["settings"]["retry"] = str(data["pushover_retry"])
+ if data.get("pushover_expire"):
+ payload["settings"]["expire"] = str(data["pushover_expire"])
+ if data.get("pushover_alert_sound"):
+ payload["settings"]["sound"] = data["pushover_alert_sound"]
+ if data.get("pushover_ok_sound"):
+ payload["settings"]["okSound"] = data["pushover_ok_sound"]
def sensu_channel_payload(data, payload):
- payload['settings']['url'] = data['sensu_url']
- if data.get('sensu_source'):
- payload['settings']['source'] = data['sensu_source']
- if data.get('sensu_handler'):
- payload['settings']['handler'] = data['sensu_handler']
- if data.get('sensu_username'):
- payload['settings']['username'] = data['sensu_username']
- if data.get('sensu_password'):
- payload['settings']['password'] = data['sensu_password']
+ payload["settings"]["url"] = data["sensu_url"]
+ if data.get("sensu_source"):
+ payload["settings"]["source"] = data["sensu_source"]
+ if data.get("sensu_handler"):
+ payload["settings"]["handler"] = data["sensu_handler"]
+ if data.get("sensu_username"):
+ payload["settings"]["username"] = data["sensu_username"]
+ if data.get("sensu_password"):
+ payload["settings"]["password"] = data["sensu_password"]
def slack_channel_payload(data, payload):
- payload['settings']['url'] = data['slack_url']
- if data.get('slack_recipient'):
- payload['settings']['recipient'] = data['slack_recipient']
- if data.get('slack_username'):
- payload['settings']['username'] = data['slack_username']
- if data.get('slack_icon_emoji'):
- payload['settings']['iconEmoji'] = data['slack_icon_emoji']
- if data.get('slack_icon_url'):
- payload['settings']['iconUrl'] = data['slack_icon_url']
- if data.get('slack_mention_users'):
- payload['settings']['mentionUsers'] = ','.join(data['slack_mention_users'])
- if data.get('slack_mention_groups'):
- payload['settings']['mentionGroups'] = ','.join(data['slack_mention_groups'])
- if data.get('slack_mention_channel'):
- payload['settings']['mentionChannel'] = data['slack_mention_channel']
- if data.get('slack_token'):
- payload['settings']['token'] = data['slack_token']
+ payload["settings"]["url"] = data["slack_url"]
+ if data.get("slack_recipient"):
+ payload["settings"]["recipient"] = data["slack_recipient"]
+ if data.get("slack_username"):
+ payload["settings"]["username"] = data["slack_username"]
+ if data.get("slack_icon_emoji"):
+ payload["settings"]["iconEmoji"] = data["slack_icon_emoji"]
+ if data.get("slack_icon_url"):
+ payload["settings"]["iconUrl"] = data["slack_icon_url"]
+ if data.get("slack_mention_users"):
+ payload["settings"]["mentionUsers"] = ",".join(data["slack_mention_users"])
+ if data.get("slack_mention_groups"):
+ payload["settings"]["mentionGroups"] = ",".join(data["slack_mention_groups"])
+ if data.get("slack_mention_channel"):
+ payload["settings"]["mentionChannel"] = data["slack_mention_channel"]
+ if data.get("slack_token"):
+ payload["settings"]["token"] = data["slack_token"]
def webhook_channel_payload(data, payload):
- payload['settings']['url'] = data['webhook_url']
- if data.get('webhook_http_method'):
- payload['settings']['httpMethod'] = data['webhook_http_method']
- if data.get('webhook_username'):
- payload['settings']['username'] = data['webhook_username']
- if data.get('webhook_password'):
- payload['settings']['password'] = data['webhook_password']
+ payload["settings"]["url"] = data["webhook_url"]
+ if data.get("webhook_http_method"):
+ payload["settings"]["httpMethod"] = data["webhook_http_method"]
+ if data.get("webhook_username"):
+ payload["settings"]["username"] = data["webhook_username"]
+ if data.get("webhook_password"):
+ payload["settings"]["password"] = data["webhook_password"]
def grafana_notification_channel_payload(data):
payload = {
- 'uid': data['uid'],
- 'name': data['name'],
- 'type': data['type'],
- 'isDefault': data['is_default'],
- 'disableResolveMessage': data['disable_resolve_message'],
- 'settings': {
- 'uploadImage': data['include_image']
- }
+ "uid": data["uid"],
+ "name": data["name"],
+ "type": data["type"],
+ "isDefault": data["is_default"],
+ "disableResolveMessage": data["disable_resolve_message"],
+ "settings": {"uploadImage": data["include_image"]},
}
- if data.get('reminder_frequency'):
- payload['sendReminder'] = True
- payload['frequency'] = data['reminder_frequency']
+ if data.get("reminder_frequency"):
+ payload["sendReminder"] = True
+ payload["frequency"] = data["reminder_frequency"]
- if data['type'] == 'dingding':
+ if data["type"] == "dingding":
dingding_channel_payload(data, payload)
- elif data['type'] == 'discord':
+ elif data["type"] == "discord":
discord_channel_payload(data, payload)
- elif data['type'] == 'email':
+ elif data["type"] == "email":
email_channel_payload(data, payload)
- elif data['type'] == 'googlechat':
- payload['settings']['url'] = data['googlechat_url']
- elif data['type'] == 'hipchat':
+ elif data["type"] == "googlechat":
+ payload["settings"]["url"] = data["googlechat_url"]
+ elif data["type"] == "hipchat":
hipchat_channel_payload(data, payload)
- elif data['type'] == 'kafka':
- payload['settings']['kafkaRestProxy'] = data['kafka_url']
- payload['settings']['kafkaTopic'] = data['kafka_topic']
- elif data['type'] == 'line':
- payload['settings']['token'] = data['line_token']
- elif data['type'] == 'teams':
- payload['settings']['url'] = data['teams_url']
- elif data['type'] == 'opsgenie':
- payload['settings']['apiUrl'] = data['opsgenie_url']
- payload['settings']['apiKey'] = data['opsgenie_api_key']
- elif data['type'] == 'pagerduty':
+ elif data["type"] == "kafka":
+ payload["settings"]["kafkaRestProxy"] = data["kafka_url"]
+ payload["settings"]["kafkaTopic"] = data["kafka_topic"]
+ elif data["type"] == "line":
+ payload["settings"]["token"] = data["line_token"]
+ elif data["type"] == "teams":
+ payload["settings"]["url"] = data["teams_url"]
+ elif data["type"] == "opsgenie":
+ payload["settings"]["apiUrl"] = data["opsgenie_url"]
+ payload["settings"]["apiKey"] = data["opsgenie_api_key"]
+ elif data["type"] == "pagerduty":
pagerduty_channel_payload(data, payload)
- elif data['type'] == 'prometheus':
+ elif data["type"] == "prometheus":
prometheus_channel_payload(data, payload)
- elif data['type'] == 'pushover':
+ elif data["type"] == "pushover":
pushover_channel_payload(data, payload)
- elif data['type'] == 'sensu':
+ elif data["type"] == "sensu":
sensu_channel_payload(data, payload)
- elif data['type'] == 'slack':
+ elif data["type"] == "slack":
slack_channel_payload(data, payload)
- elif data['type'] == 'telegram':
- payload['settings']['bottoken'] = data['telegram_bot_token']
- payload['settings']['chatid'] = data['telegram_chat_id']
- elif data['type'] == 'threema':
- payload['settings']['gateway_id'] = data['threema_gateway_id']
- payload['settings']['recipient_id'] = data['threema_recipient_id']
- payload['settings']['api_secret'] = data['threema_api_secret']
- elif data['type'] == 'victorops':
- payload['settings']['url'] = data['victorops_url']
- if data.get('victorops_auto_resolve'):
- payload['settings']['autoResolve'] = data['victorops_auto_resolve']
- elif data['type'] == 'webhook':
+ elif data["type"] == "telegram":
+ payload["settings"]["bottoken"] = data["telegram_bot_token"]
+ payload["settings"]["chatid"] = data["telegram_chat_id"]
+ elif data["type"] == "threema":
+ payload["settings"]["gateway_id"] = data["threema_gateway_id"]
+ payload["settings"]["recipient_id"] = data["threema_recipient_id"]
+ payload["settings"]["api_secret"] = data["threema_api_secret"]
+ elif data["type"] == "victorops":
+ payload["settings"]["url"] = data["victorops_url"]
+ if data.get("victorops_auto_resolve"):
+ payload["settings"]["autoResolve"] = data["victorops_auto_resolve"]
+ elif data["type"] == "webhook":
webhook_channel_payload(data, payload)
return payload
class GrafanaNotificationChannelInterface(object):
-
def __init__(self, module):
self._module = module
# {{{ Authentication header
self.headers = {"Content-Type": "application/json"}
- if module.params.get('grafana_api_key', None):
- self.headers["Authorization"] = "Bearer %s" % module.params['grafana_api_key']
+ if module.params.get("grafana_api_key", None):
+ self.headers["Authorization"] = (
+ "Bearer %s" % module.params["grafana_api_key"]
+ )
else:
- self.headers["Authorization"] = basic_auth_header(module.params['url_username'], module.params['url_password'])
+ self.headers["Authorization"] = basic_auth_header(
+ module.params["url_username"], module.params["url_password"]
+ )
# }}}
self.grafana_url = clean_url(module.params.get("url"))
def grafana_switch_organisation(self, grafana_url, org_id):
- r, info = fetch_url(self._module, '%s/api/user/using/%s' % (grafana_url, org_id),
- headers=self.headers, method='POST')
- if info['status'] != 200:
- raise GrafanaAPIException('Unable to switch to organization %s : %s' %
- (org_id, info))
+ r, info = fetch_url(
+ self._module,
+ "%s/api/user/using/%s" % (grafana_url, org_id),
+ headers=self.headers,
+ method="POST",
+ )
+ if info["status"] != 200:
+ raise GrafanaAPIException(
+ "Unable to switch to organization %s : %s" % (org_id, info)
+ )
def grafana_create_notification_channel(self, data, payload):
- r, info = fetch_url(self._module, '%s/api/alert-notifications' % data['url'],
- data=json.dumps(payload), headers=self.headers, method='POST')
- if info['status'] == 200:
+ r, info = fetch_url(
+ self._module,
+ "%s/api/alert-notifications" % data["url"],
+ data=json.dumps(payload),
+ headers=self.headers,
+ method="POST",
+ )
+ if info["status"] == 200:
return {
- 'state': 'present',
- 'changed': True,
- 'channel': json.loads(to_text(r.read())),
+ "state": "present",
+ "changed": True,
+ "channel": json.loads(to_text(r.read())),
}
else:
- raise GrafanaAPIException("Unable to create notification channel: %s" % info)
+ raise GrafanaAPIException(
+ "Unable to create notification channel: %s" % info
+ )
def grafana_update_notification_channel(self, data, payload, before):
- r, info = fetch_url(self._module, '%s/api/alert-notifications/uid/%s' %
- (data['url'], data['uid']),
- data=json.dumps(payload), headers=self.headers, method='PUT')
- if info['status'] == 200:
- del before['created']
- del before['updated']
+ r, info = fetch_url(
+ self._module,
+ "%s/api/alert-notifications/uid/%s" % (data["url"], data["uid"]),
+ data=json.dumps(payload),
+ headers=self.headers,
+ method="PUT",
+ )
+ if info["status"] == 200:
+ del before["created"]
+ del before["updated"]
channel = json.loads(to_text(r.read()))
after = channel.copy()
- del after['created']
- del after['updated']
+ del after["created"]
+ del after["updated"]
if before == after:
return {
- 'changed': False,
- 'channel': channel,
+ "changed": False,
+ "channel": channel,
}
else:
return {
- 'changed': True,
- 'diff': {
- 'before': before,
- 'after': after,
+ "changed": True,
+ "diff": {
+ "before": before,
+ "after": after,
},
- 'channel': channel,
+ "channel": channel,
}
else:
- raise GrafanaAPIException("Unable to update notification channel %s : %s" %
- (data['uid'], info))
+ raise GrafanaAPIException(
+ "Unable to update notification channel %s : %s" % (data["uid"], info)
+ )
def grafana_create_or_update_notification_channel(self, data):
payload = grafana_notification_channel_payload(data)
- r, info = fetch_url(self._module, '%s/api/alert-notifications/uid/%s' %
- (data['url'], data['uid']), headers=self.headers)
- if info['status'] == 200:
+ r, info = fetch_url(
+ self._module,
+ "%s/api/alert-notifications/uid/%s" % (data["url"], data["uid"]),
+ headers=self.headers,
+ )
+ if info["status"] == 200:
before = json.loads(to_text(r.read()))
return self.grafana_update_notification_channel(data, payload, before)
- elif info['status'] == 404:
+ elif info["status"] == 404:
return self.grafana_create_notification_channel(data, payload)
else:
- raise GrafanaAPIException("Unable to get notification channel %s : %s" %
- (data['uid'], info))
+ raise GrafanaAPIException(
+ "Unable to get notification channel %s : %s" % (data["uid"], info)
+ )
def grafana_delete_notification_channel(self, data):
- r, info = fetch_url(self._module, '%s/api/alert-notifications/uid/%s' %
- (data['url'], data['uid']),
- headers=self.headers, method='DELETE')
- if info['status'] == 200:
- return {
- 'state': 'absent',
- 'changed': True
- }
- elif info['status'] == 404:
- return {
- 'changed': False
- }
+ r, info = fetch_url(
+ self._module,
+ "%s/api/alert-notifications/uid/%s" % (data["url"], data["uid"]),
+ headers=self.headers,
+ method="DELETE",
+ )
+ if info["status"] == 200:
+ return {"state": "absent", "changed": True}
+ elif info["status"] == 404:
+ return {"changed": False}
else:
- raise GrafanaAPIException("Unable to delete notification channel %s : %s" %
- (data['uid'], info))
+ raise GrafanaAPIException(
+ "Unable to delete notification channel %s : %s" % (data["uid"], info)
+ )
def main():
argument_spec = grafana_argument_spec()
argument_spec.update(
- org_id=dict(type='int', default=1),
- uid=dict(type='str'),
- name=dict(type='str'),
- type=dict(type='str',
- choices=['dingding', 'discord', 'email', 'googlechat', 'hipchat',
- 'kafka', 'line', 'teams', 'opsgenie', 'pagerduty',
- 'prometheus', 'pushover', 'sensu', 'slack', 'telegram',
- 'threema', 'victorops', 'webhook']),
- is_default=dict(type='bool', default=False),
- include_image=dict(type='bool', default=False),
- disable_resolve_message=dict(type='bool', default=False),
- reminder_frequency=dict(type='str'),
-
- dingding_url=dict(type='str'),
- dingding_message_type=dict(type='list', elements='str',
- choices=['link', 'action_card']),
-
- discord_url=dict(type='str'),
- discord_message_content=dict(type='str'),
-
- email_addresses=dict(type='list', elements='str'),
- email_single=dict(type='bool'),
-
- googlechat_url=dict(type='str'),
-
- hipchat_url=dict(type='str'),
- hipchat_api_key=dict(type='str', no_log=True),
- hipchat_room_id=dict(type='str'),
-
- kafka_url=dict(type='str'),
- kafka_topic=dict(type='str'),
-
- line_token=dict(type='str', no_log=True),
-
- teams_url=dict(type='str'),
-
- opsgenie_url=dict(type='str'),
- opsgenie_api_key=dict(type='str', no_log=True),
- opsgenie_auto_close=dict(type='bool'),
- opsgenie_override_priority=dict(type='bool'),
-
- pagerduty_integration_key=dict(type='str', no_log=True),
- pagerduty_severity=dict(type='list', elements='str',
- choices=['critical', 'error', 'warning', 'info']),
- pagerduty_auto_resolve=dict(type='bool'),
- pagerduty_message_in_details=dict(type='bool'),
-
- prometheus_url=dict(type='str'),
- prometheus_username=dict(type='str'),
- prometheus_password=dict(type='str', no_log=True),
-
- pushover_api_token=dict(type='str', no_log=True),
- pushover_user_key=dict(type='str', no_log=True),
- pushover_devices=dict(type='list', elements='str'),
- pushover_priority=dict(type='list', elements='str',
- choices=['emergency', 'high', 'normal', 'low', 'lowest']),
- pushover_retry=dict(type='int'), # TODO: only when priority==emergency
- pushover_expire=dict(type='int'), # TODO: only when priority==emergency
- pushover_alert_sound=dict(type='str'), # TODO: add sound choices
- pushover_ok_sound=dict(type='str'), # TODO: add sound choices
-
- sensu_url=dict(type='str'),
- sensu_source=dict(type='str'),
- sensu_handler=dict(type='str'),
- sensu_username=dict(type='str'),
- sensu_password=dict(type='str', no_log=True),
-
- slack_url=dict(type='str', no_log=True),
- slack_recipient=dict(type='str'),
- slack_username=dict(type='str'),
- slack_icon_emoji=dict(type='str'),
- slack_icon_url=dict(type='str'),
- slack_mention_users=dict(type='list', elements='str'),
- slack_mention_groups=dict(type='list', elements='str'),
- slack_mention_channel=dict(type='list', elements='str',
- choices=['here', 'channel']),
- slack_token=dict(type='str', no_log=True),
-
- telegram_bot_token=dict(type='str', no_log=True),
- telegram_chat_id=dict(type='str'),
-
- threema_gateway_id=dict(type='str'),
- threema_recipient_id=dict(type='str'),
- threema_api_secret=dict(type='str', no_log=True),
-
- victorops_url=dict(type='str'),
- victorops_auto_resolve=dict(type='bool'),
-
- webhook_url=dict(type='str'),
- webhook_username=dict(type='str'),
- webhook_password=dict(type='str', no_log=True),
- webhook_http_method=dict(type='list', elements='str', choices=['POST', 'PUT'])
+ org_id=dict(type="int", default=1),
+ uid=dict(type="str"),
+ name=dict(type="str"),
+ type=dict(
+ type="str",
+ choices=[
+ "dingding",
+ "discord",
+ "email",
+ "googlechat",
+ "hipchat",
+ "kafka",
+ "line",
+ "teams",
+ "opsgenie",
+ "pagerduty",
+ "prometheus",
+ "pushover",
+ "sensu",
+ "slack",
+ "telegram",
+ "threema",
+ "victorops",
+ "webhook",
+ ],
+ ),
+ is_default=dict(type="bool", default=False),
+ include_image=dict(type="bool", default=False),
+ disable_resolve_message=dict(type="bool", default=False),
+ reminder_frequency=dict(type="str"),
+ dingding_url=dict(type="str"),
+ dingding_message_type=dict(
+ type="list", elements="str", choices=["link", "action_card"]
+ ),
+ discord_url=dict(type="str"),
+ discord_message_content=dict(type="str"),
+ email_addresses=dict(type="list", elements="str"),
+ email_single=dict(type="bool"),
+ googlechat_url=dict(type="str"),
+ hipchat_url=dict(type="str"),
+ hipchat_api_key=dict(type="str", no_log=True),
+ hipchat_room_id=dict(type="str"),
+ kafka_url=dict(type="str"),
+ kafka_topic=dict(type="str"),
+ line_token=dict(type="str", no_log=True),
+ teams_url=dict(type="str"),
+ opsgenie_url=dict(type="str"),
+ opsgenie_api_key=dict(type="str", no_log=True),
+ opsgenie_auto_close=dict(type="bool"),
+ opsgenie_override_priority=dict(type="bool"),
+ pagerduty_integration_key=dict(type="str", no_log=True),
+ pagerduty_severity=dict(
+ type="list",
+ elements="str",
+ choices=["critical", "error", "warning", "info"],
+ ),
+ pagerduty_auto_resolve=dict(type="bool"),
+ pagerduty_message_in_details=dict(type="bool"),
+ prometheus_url=dict(type="str"),
+ prometheus_username=dict(type="str"),
+ prometheus_password=dict(type="str", no_log=True),
+ pushover_api_token=dict(type="str", no_log=True),
+ pushover_user_key=dict(type="str", no_log=True),
+ pushover_devices=dict(type="list", elements="str"),
+ pushover_priority=dict(
+ type="list",
+ elements="str",
+ choices=["emergency", "high", "normal", "low", "lowest"],
+ ),
+ pushover_retry=dict(type="int"), # TODO: only when priority==emergency
+ pushover_expire=dict(type="int"), # TODO: only when priority==emergency
+ pushover_alert_sound=dict(type="str"), # TODO: add sound choices
+ pushover_ok_sound=dict(type="str"), # TODO: add sound choices
+ sensu_url=dict(type="str"),
+ sensu_source=dict(type="str"),
+ sensu_handler=dict(type="str"),
+ sensu_username=dict(type="str"),
+ sensu_password=dict(type="str", no_log=True),
+ slack_url=dict(type="str", no_log=True),
+ slack_recipient=dict(type="str"),
+ slack_username=dict(type="str"),
+ slack_icon_emoji=dict(type="str"),
+ slack_icon_url=dict(type="str"),
+ slack_mention_users=dict(type="list", elements="str"),
+ slack_mention_groups=dict(type="list", elements="str"),
+ slack_mention_channel=dict(
+ type="list", elements="str", choices=["here", "channel"]
+ ),
+ slack_token=dict(type="str", no_log=True),
+ telegram_bot_token=dict(type="str", no_log=True),
+ telegram_chat_id=dict(type="str"),
+ threema_gateway_id=dict(type="str"),
+ threema_recipient_id=dict(type="str"),
+ threema_api_secret=dict(type="str", no_log=True),
+ victorops_url=dict(type="str"),
+ victorops_auto_resolve=dict(type="bool"),
+ webhook_url=dict(type="str"),
+ webhook_username=dict(type="str"),
+ webhook_password=dict(type="str", no_log=True),
+ webhook_http_method=dict(type="list", elements="str", choices=["POST", "PUT"]),
)
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=False,
- required_together=[['url_username', 'url_password', 'org_id'],
- ['prometheus_username', 'prometheus_password'],
- ['sensu_username', 'sensu_password']],
- mutually_exclusive=[['url_username', 'grafana_api_key']],
+ required_together=[
+ ["url_username", "url_password", "org_id"],
+ ["prometheus_username", "prometheus_password"],
+ ["sensu_username", "sensu_password"],
+ ],
+ mutually_exclusive=[["url_username", "grafana_api_key"]],
required_if=[
- ['state', 'present', ['name', 'type']],
- ['type', 'dingding', ['dingding_url']],
- ['type', 'discord', ['discord_url']],
- ['type', 'email', ['email_addresses']],
- ['type', 'googlechat', ['googlechat_url']],
- ['type', 'hipchat', ['hipchat_url']],
- ['type', 'kafka', ['kafka_url', 'kafka_topic']],
- ['type', 'line', ['line_token']],
- ['type', 'teams', ['teams_url']],
- ['type', 'opsgenie', ['opsgenie_url', 'opsgenie_api_key']],
- ['type', 'pagerduty', ['pagerduty_integration_key']],
- ['type', 'prometheus', ['prometheus_url']],
- ['type', 'pushover', ['pushover_api_token', 'pushover_user_key']],
- ['type', 'sensu', ['sensu_url']],
- ['type', 'slack', ['slack_url']],
- ['type', 'telegram', ['telegram_bot_token', 'telegram_chat_id']],
- ['type', 'threema', ['threema_gateway_id', 'threema_recipient_id',
- 'threema_api_secret']],
- ['type', 'victorops', ['victorops_url']],
- ['type', 'webhook', ['webhook_url']]
- ]
+ ["state", "present", ["name", "type"]],
+ ["type", "dingding", ["dingding_url"]],
+ ["type", "discord", ["discord_url"]],
+ ["type", "email", ["email_addresses"]],
+ ["type", "googlechat", ["googlechat_url"]],
+ ["type", "hipchat", ["hipchat_url"]],
+ ["type", "kafka", ["kafka_url", "kafka_topic"]],
+ ["type", "line", ["line_token"]],
+ ["type", "teams", ["teams_url"]],
+ ["type", "opsgenie", ["opsgenie_url", "opsgenie_api_key"]],
+ ["type", "pagerduty", ["pagerduty_integration_key"]],
+ ["type", "prometheus", ["prometheus_url"]],
+ ["type", "pushover", ["pushover_api_token", "pushover_user_key"]],
+ ["type", "sensu", ["sensu_url"]],
+ ["type", "slack", ["slack_url"]],
+ ["type", "telegram", ["telegram_bot_token", "telegram_chat_id"]],
+ [
+ "type",
+ "threema",
+ ["threema_gateway_id", "threema_recipient_id", "threema_api_secret"],
+ ],
+ ["type", "victorops", ["victorops_url"]],
+ ["type", "webhook", ["webhook_url"]],
+ ],
)
module.params["url"] = clean_url(module.params["url"])
alert_channel_iface = GrafanaNotificationChannelInterface(module)
- if module.params['state'] == 'present':
- result = alert_channel_iface.grafana_create_or_update_notification_channel(module.params)
+ if module.params["state"] == "present":
+ result = alert_channel_iface.grafana_create_or_update_notification_channel(
+ module.params
+ )
module.exit_json(failed=False, **result)
else:
result = alert_channel_iface.grafana_delete_notification_channel(module.params)
module.exit_json(failed=False, **result)
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/grafana/plugins/modules/grafana_organization.py b/ansible_collections/community/grafana/plugins/modules/grafana_organization.py
index 7fad4c876..7bddcb3f4 100644
--- a/ansible_collections/community/grafana/plugins/modules/grafana_organization.py
+++ b/ansible_collections/community/grafana/plugins/modules/grafana_organization.py
@@ -19,7 +19,7 @@
from __future__ import absolute_import, division, print_function
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
module: grafana_organization
author:
@@ -43,9 +43,9 @@ options:
choices: ["present", "absent"]
extends_documentation_fragment:
- community.grafana.basic_auth
-'''
+"""
-EXAMPLES = '''
+EXAMPLES = """
---
- name: Create a Grafana organization
community.grafana.grafana_organization:
@@ -62,9 +62,9 @@ EXAMPLES = '''
url_password: changeme
name: orgtest
state: absent
-'''
+"""
-RETURN = '''
+RETURN = """
---
org:
description: Information about the organization
@@ -94,7 +94,7 @@ org:
country: ""
state: ""
zipCode: ""
-'''
+"""
import json
@@ -107,12 +107,13 @@ __metaclass__ = type
class GrafanaOrgInterface(object):
-
def __init__(self, module):
self._module = module
# {{{ Authentication header
self.headers = {"Content-Type": "application/json"}
- self.headers["Authorization"] = basic_auth_header(module.params['url_username'], module.params['url_password'])
+ self.headers["Authorization"] = basic_auth_header(
+ module.params["url_username"], module.params["url_password"]
+ )
# }}}
self.grafana_url = base.clean_url(module.params.get("url"))
@@ -123,20 +124,35 @@ class GrafanaOrgInterface(object):
headers = []
full_url = "{grafana_url}{path}".format(grafana_url=self.grafana_url, path=url)
- resp, info = fetch_url(self._module, full_url, data=data, headers=headers, method=method)
+ resp, info = fetch_url(
+ self._module, full_url, data=data, headers=headers, method=method
+ )
status_code = info["status"]
if status_code == 404:
return None
elif status_code == 401:
- self._module.fail_json(failed=True, msg="Unauthorized to perform action '%s' on '%s' header: %s" % (method, full_url, self.headers))
+ self._module.fail_json(
+ failed=True,
+ msg="Unauthorized to perform action '%s' on '%s' header: %s"
+ % (method, full_url, self.headers),
+ )
elif status_code == 403:
self._module.fail_json(failed=True, msg="Permission Denied")
elif status_code == 200:
return self._module.from_json(resp.read())
if resp is None:
- self._module.fail_json(failed=True, msg="Cannot connect to API Grafana %s" % info['msg'], status=status_code, url=info['url'])
+ self._module.fail_json(
+ failed=True,
+ msg="Cannot connect to API Grafana %s" % info["msg"],
+ status=status_code,
+ url=info["url"],
+ )
else:
- self._module.fail_json(failed=True, msg="Grafana Org API answered with HTTP %d" % status_code, body=self._module.from_json(resp.read()))
+ self._module.fail_json(
+ failed=True,
+ msg="Grafana Org API answered with HTTP %d" % status_code,
+ body=self._module.from_json(resp.read()),
+ )
def get_actual_org(self, name):
# https://grafana.com/docs/grafana/latest/http_api/org/#get-organization-by-name
@@ -160,40 +176,48 @@ def setup_module_object():
module = AnsibleModule(
argument_spec=argument_spec,
supports_check_mode=False,
- required_together=base.grafana_required_together()
+ required_together=base.grafana_required_together(),
)
return module
argument_spec = base.grafana_argument_spec()
argument_spec.update(
- state=dict(choices=['present', 'absent'], default='present'),
- name=dict(type='str', required=True),
+ state=dict(choices=["present", "absent"], default="present"),
+ name=dict(type="str", required=True),
)
-argument_spec.pop('grafana_api_key')
+argument_spec.pop("grafana_api_key")
def main():
module = setup_module_object()
- state = module.params['state']
- name = module.params['name']
+ state = module.params["state"]
+ name = module.params["name"]
grafana_iface = GrafanaOrgInterface(module)
# search org by name
actual_org = grafana_iface.get_actual_org(name)
- if state == 'present':
+ if state == "present":
has_changed = False
if actual_org is None:
# create new org
actual_org = grafana_iface.create_org(name)
has_changed = True
- module.exit_json(changed=has_changed, msg='Organization %s created.' % name, org=actual_org)
+ module.exit_json(
+ changed=has_changed,
+ msg="Organization %s created." % name,
+ org=actual_org,
+ )
else:
- module.exit_json(changed=has_changed, msg='Organization %s already created.' % name, org=actual_org)
+ module.exit_json(
+ changed=has_changed,
+ msg="Organization %s already created." % name,
+ org=actual_org,
+ )
- elif state == 'absent':
+ elif state == "absent":
if actual_org is None:
module.exit_json(msg="No org found, nothing to do")
# delete org
@@ -201,5 +225,5 @@ def main():
module.exit_json(changed=True, msg=result.get("message"))
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/grafana/plugins/modules/grafana_organization_user.py b/ansible_collections/community/grafana/plugins/modules/grafana_organization_user.py
new file mode 100644
index 000000000..11171f38f
--- /dev/null
+++ b/ansible_collections/community/grafana/plugins/modules/grafana_organization_user.py
@@ -0,0 +1,294 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+#
+# Copyright: (c) 2021
+
+from __future__ import absolute_import, division, print_function
+
+DOCUMENTATION = """
+---
+module: grafana_organization_user
+author:
+ - Aliaksandr Mianzhynski (@amenzhinsky)
+version_added: "1.6.0"
+short_description: Manage Grafana Organization Users.
+description:
+ - Add or remove users or change their roles in Grafana organizations through org API.
+ - The user has to exist before using this module. See U(https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_user_module.html).
+options:
+ login:
+ type: str
+ required: True
+ description:
+ - Username or email.
+ role:
+ type: str
+ choices:
+ - viewer
+ - editor
+ - admin
+ default: viewer
+ description:
+ - User's role in the organization.
+ state:
+ type: str
+ default: present
+ choices:
+ - present
+ - absent
+ description:
+ - Status of a user's organization membership.
+ org_id:
+ type: int
+ default: 1
+ description:
+ - Organization ID.
+ - Mutually exclusive with C(org_name).
+ org_name:
+ type: str
+ description:
+ - Organization name.
+ - Mutually exclusive with C(org_id).
+
+extends_documentation_fragment:
+ - community.grafana.basic_auth
+"""
+
+EXAMPLES = """
+---
+- name: Add user to organization
+ community.grafana.grafana_organization_user:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ login: john
+ role: admin
+
+- name: Remove user from organization
+ community.grafana.grafana_organization_user:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ login: john
+ state: absent
+"""
+
+RETURN = """
+---
+user:
+ description: Information about the organization user
+ returned: when state present
+ type: complex
+ contains:
+ email:
+ description: The User email address
+ returned: always
+ type: str
+ sample:
+ - "foo.bar@example.com"
+ login:
+ description: The User login
+ returned: always
+ type: str
+ sample:
+ - "batman"
+ name:
+ description: The User name (same as login)
+ returned: always
+ type: str
+ sample:
+ - "batman"
+ orgId:
+ description: The organization id that the team is part of.
+ returned: always
+ type: int
+ sample:
+ - 1
+ role:
+ description: The user role in the organization
+ returned: always
+ type: str
+ choices:
+ - Viewer
+ - Editor
+ - Admin
+ sample:
+ - Viewer
+"""
+
+
+import json
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.urls import fetch_url
+from ansible.module_utils._text import to_text
+from ansible_collections.community.grafana.plugins.module_utils.base import (
+ grafana_argument_spec,
+ clean_url,
+)
+from ansible.module_utils.urls import basic_auth_header
+
+__metaclass__ = type
+
+
+class GrafanaAPIException(Exception):
+ pass
+
+
+class GrafanaOrganizationUserInterface(object):
+ def __init__(self, module):
+ self._module = module
+ # {{{ Authentication header
+ self.headers = {"Content-Type": "application/json"}
+ self.headers["Authorization"] = basic_auth_header(
+ module.params["url_username"], module.params["url_password"]
+ )
+ # }}}
+ self.grafana_url = clean_url(module.params.get("url"))
+
+ def _api_call(self, method, path, payload):
+ data = None
+ if payload:
+ data = json.dumps(payload)
+ return fetch_url(
+ self._module,
+ self.grafana_url + "/api/" + path,
+ headers=self.headers,
+ method=method,
+ data=data,
+ )
+
+ def _organization_by_name(self, org_name):
+ r, info = self._api_call("GET", "orgs/name/%s" % org_name, None)
+ if info["status"] != 200:
+ raise GrafanaAPIException("Unable to retrieve organization: %s" % info)
+ return json.loads(to_text(r.read()))
+
+ def _organization_users(self, org_id):
+ r, info = self._api_call("GET", "orgs/%d/users" % org_id, None)
+ if info["status"] != 200:
+ raise GrafanaAPIException(
+ "Unable to retrieve organization users: %s" % info
+ )
+ return json.loads(to_text(r.read()))
+
+ def _create_organization_user(self, org_id, login, role):
+ return self._api_call(
+ "POST",
+ "orgs/%d/users" % org_id,
+ {
+ "loginOrEmail": login,
+ "role": role,
+ },
+ )
+
+ def _update_organization_user_role(self, org_id, user_id, role):
+ return self._api_call(
+ "PATCH",
+ "orgs/%d/users/%s" % (org_id, user_id),
+ {
+ "role": role,
+ },
+ )
+
+ def _remove_organization_user(self, org_id, user_id):
+ return self._api_call("DELETE", "orgs/%d/users/%s" % (org_id, user_id), None)
+
+ def _organization_user_by_login(self, org_id, login):
+ for user in self._organization_users(org_id):
+ if login in (user["login"], user["email"]):
+ return user
+
+ def create_or_update_user(self, org_id, login, role):
+ r, info = self._create_organization_user(org_id, login, role)
+ if info["status"] == 200:
+ return {
+ "state": "present",
+ "changed": True,
+ "user": self._organization_user_by_login(org_id, login),
+ }
+ if info["status"] == 409: # already member
+ user = self._organization_user_by_login(org_id, login)
+ if not user:
+ raise Exception("[BUG] User not found in organization")
+
+ if user["role"] == role:
+ return {"changed": False}
+
+ r, info = self._update_organization_user_role(org_id, user["userId"], role)
+ if info["status"] == 200:
+ return {
+ "changed": True,
+ "user": self._organization_user_by_login(org_id, login),
+ }
+ else:
+ raise GrafanaAPIException(
+ "Unable to update organization user: %s" % info
+ )
+ else:
+ raise GrafanaAPIException("Unable to add user to organization: %s" % info)
+
+ def remove_user(self, org_id, login):
+ user = self._organization_user_by_login(org_id, login)
+ if not user:
+ return {"changed": False}
+
+ r, info = self._remove_organization_user(org_id, user["userId"])
+ if info["status"] == 200:
+ return {"state": "absent", "changed": True}
+ else:
+ raise GrafanaAPIException("Unable to delete organization user: %s" % info)
+
+
+def main():
+ argument_spec = grafana_argument_spec()
+ argument_spec.pop("grafana_api_key")
+ argument_spec.update(
+ org_id=dict(type="int", default=1),
+ org_name=dict(type="str"),
+ login=dict(type="str", required=True),
+ role=dict(type="str", choices=["viewer", "editor", "admin"], default="viewer"),
+ )
+ module = AnsibleModule(
+ argument_spec=argument_spec,
+ supports_check_mode=False,
+ mutually_exclusive=[
+ ("org_id", "org_name"),
+ ],
+ required_if=[
+ ["state", "present", ["role"]],
+ ],
+ )
+
+ org_id = module.params["org_id"]
+ login = module.params["login"]
+ iface = GrafanaOrganizationUserInterface(module)
+ if module.params["org_name"]:
+ org_name = module.params["org_name"]
+ organization = iface._organization_by_name(org_name)
+ org_id = organization["id"]
+ if module.params["state"] == "present":
+ role = module.params["role"].capitalize()
+ result = iface.create_or_update_user(org_id, login, role)
+ module.exit_json(failed=False, **result)
+ else:
+ result = iface.remove_user(org_id, login)
+ module.exit_json(failed=False, **result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/ansible_collections/community/grafana/plugins/modules/grafana_plugin.py b/ansible_collections/community/grafana/plugins/modules/grafana_plugin.py
index 7fd418760..c510f02ba 100644
--- a/ansible_collections/community/grafana/plugins/modules/grafana_plugin.py
+++ b/ansible_collections/community/grafana/plugins/modules/grafana_plugin.py
@@ -6,7 +6,7 @@
from __future__ import absolute_import, division, print_function
-DOCUMENTATION = '''module: grafana_plugin
+DOCUMENTATION = """module: grafana_plugin
author:
- Thierry Sallé (@seuf)
short_description: Manage Grafana plugins via grafana-cli
@@ -50,26 +50,26 @@ options:
validate_certs:
description:
- Boolean variable to include --insecure while installing pluging
- default: False
+ default: false
type: bool
-'''
+"""
-EXAMPLES = '''
+EXAMPLES = """
---
- name: Install/update Grafana piechart panel plugin
community.grafana.grafana_plugin:
name: grafana-piechart-panel
version: latest
state: present
-'''
+"""
-RETURN = '''
+RETURN = """
---
version:
description: version of the installed/removed/updated plugin.
type: str
returned: always
-'''
+"""
import os
from ansible.module_utils.basic import AnsibleModule
@@ -82,18 +82,18 @@ class GrafanaCliException(Exception):
def parse_version(string):
- name, version = string.split('@')
+ name, version = string.split("@")
return name.strip(), version.strip()
def grafana_cli_bin(params):
- '''
+ """
Get the grafana-cli binary path with global options.
Raise a GrafanaCliException if the grafana-cli is not present or not in PATH
:param params: ansible module params. Used to fill grafana-cli global params.
- '''
- program = 'grafana-cli'
+ """
+ program = "grafana-cli"
grafana_cli = None
def is_exe(fpath):
@@ -112,50 +112,57 @@ def grafana_cli_bin(params):
break
if grafana_cli is None:
- raise GrafanaCliException('grafana-cli binary is not present or not in PATH')
+ raise GrafanaCliException("grafana-cli binary is not present or not in PATH")
else:
- if 'grafana_plugin_url' in params and params['grafana_plugin_url']:
- grafana_cli = '{0} {1} {2}'.format(grafana_cli, '--pluginUrl', params['grafana_plugin_url'])
- if 'grafana_plugins_dir' in params and params['grafana_plugins_dir']:
- grafana_cli = '{0} {1} {2}'.format(grafana_cli, '--pluginsDir', params['grafana_plugins_dir'])
- if 'grafana_repo' in params and params['grafana_repo']:
- grafana_cli = '{0} {1} {2}'.format(grafana_cli, '--repo', params['grafana_repo'])
- if 'validate_certs' in params and params['validate_certs'] is False:
- grafana_cli = '{0} {1}'.format(grafana_cli, '--insecure')
-
- return '{0} {1}'.format(grafana_cli, 'plugins')
+ if "grafana_plugin_url" in params and params["grafana_plugin_url"]:
+ grafana_cli = "{0} {1} {2}".format(
+ grafana_cli, "--pluginUrl", params["grafana_plugin_url"]
+ )
+ if "grafana_plugins_dir" in params and params["grafana_plugins_dir"]:
+ grafana_cli = "{0} {1} {2}".format(
+ grafana_cli, "--pluginsDir", params["grafana_plugins_dir"]
+ )
+ if "grafana_repo" in params and params["grafana_repo"]:
+ grafana_cli = "{0} {1} {2}".format(
+ grafana_cli, "--repo", params["grafana_repo"]
+ )
+ if "validate_certs" in params and params["validate_certs"] is False:
+ grafana_cli = "{0} {1}".format(grafana_cli, "--insecure")
+
+ return "{0} {1}".format(grafana_cli, "plugins")
def get_grafana_plugin_version(module, params):
- '''
+ """
Fetch grafana installed plugin version. Return None if plugin is not installed.
:param module: ansible module object. used to run system commands.
:param params: ansible module params.
- '''
+ """
grafana_cli = grafana_cli_bin(params)
- rc, stdout, stderr = module.run_command('{0} ls'.format(grafana_cli))
+ rc, stdout, stderr = module.run_command("{0} ls".format(grafana_cli))
stdout_lines = stdout.split("\n")
for line in stdout_lines:
- if line.find(' @ ') != -1:
+ if line.find(" @ ") != -1:
line = line.rstrip()
plugin_name, plugin_version = parse_version(line)
- if plugin_name == params['name']:
+ if plugin_name == params["name"]:
return plugin_version
return None
def get_grafana_plugin_version_latest(module, params):
- '''
+ """
Fetch the latest version available from grafana-cli.
Return the newest version number or None not found.
:param module: ansible module object. used to run system commands.
:param params: ansible module params.
- '''
+ """
grafana_cli = grafana_cli_bin(params)
- rc, stdout, stderr = module.run_command('{0} list-versions {1}'.format(grafana_cli,
- params['name']))
+ rc, stdout, stderr = module.run_command(
+ "{0} list-versions {1}".format(grafana_cli, params["name"])
+ )
stdout_lines = stdout.split("\n")
if stdout_lines[0]:
return stdout_lines[0].rstrip()
@@ -163,108 +170,126 @@ def get_grafana_plugin_version_latest(module, params):
def grafana_plugin(module, params):
- '''
+ """
Install update or remove grafana plugin
:param module: ansible module object. used to run system commands.
:param params: ansible module params.
- '''
+ """
grafana_cli = grafana_cli_bin(params)
- if params['state'] == 'present':
+ if params["state"] == "present":
grafana_plugin_version = get_grafana_plugin_version(module, params)
if grafana_plugin_version is not None:
- if 'version' in params and params['version']:
- if params['version'] == grafana_plugin_version:
- return {'msg': 'Grafana plugin already installed',
- 'changed': False,
- 'version': grafana_plugin_version}
+ if "version" in params and params["version"]:
+ if params["version"] == grafana_plugin_version:
+ return {
+ "msg": "Grafana plugin already installed",
+ "changed": False,
+ "version": grafana_plugin_version,
+ }
else:
- if params['version'] == 'latest' or params['version'] is None:
- latest_version = get_grafana_plugin_version_latest(module, params)
+ if params["version"] == "latest" or params["version"] is None:
+ latest_version = get_grafana_plugin_version_latest(
+ module, params
+ )
if latest_version == grafana_plugin_version:
- return {'msg': 'Grafana plugin already installed',
- 'changed': False,
- 'version': grafana_plugin_version}
- cmd = '{0} update {1}'.format(grafana_cli, params['name'])
+ return {
+ "msg": "Grafana plugin already installed",
+ "changed": False,
+ "version": grafana_plugin_version,
+ }
+ cmd = "{0} update {1}".format(grafana_cli, params["name"])
else:
- cmd = '{0} install {1} {2}'.format(grafana_cli, params['name'], params['version'])
+ cmd = "{0} install {1} {2}".format(
+ grafana_cli, params["name"], params["version"]
+ )
else:
- return {'msg': 'Grafana plugin already installed',
- 'changed': False,
- 'version': grafana_plugin_version}
+ return {
+ "msg": "Grafana plugin already installed",
+ "changed": False,
+ "version": grafana_plugin_version,
+ }
else:
- if 'version' in params:
- if params['version'] == 'latest' or params['version'] is None:
- cmd = '{0} install {1}'.format(grafana_cli, params['name'])
+ if "version" in params:
+ if params["version"] == "latest" or params["version"] is None:
+ cmd = "{0} install {1}".format(grafana_cli, params["name"])
else:
- cmd = '{0} install {1} {2}'.format(grafana_cli, params['name'], params['version'])
+ cmd = "{0} install {1} {2}".format(
+ grafana_cli, params["name"], params["version"]
+ )
else:
- cmd = '{0} install {1}'.format(grafana_cli, params['name'])
+ cmd = "{0} install {1}".format(grafana_cli, params["name"])
else:
- cmd = '{0} uninstall {1}'.format(grafana_cli, params['name'])
+ cmd = "{0} uninstall {1}".format(grafana_cli, params["name"])
rc, stdout, stderr = module.run_command(cmd)
if rc == 0:
stdout_lines = stdout.split("\n")
for line in stdout_lines:
- if line.find(params['name']):
- if line.find(' @ ') != -1:
+ if line.find(params["name"]):
+ if line.find(" @ ") != -1:
line = line.rstrip()
plugin_name, plugin_version = parse_version(line)
else:
plugin_version = None
- if params['state'] == 'present':
- return {'msg': 'Grafana plugin {0} installed : {1}'.format(params['name'], cmd),
- 'changed': True,
- 'version': plugin_version}
+ if params["state"] == "present":
+ return {
+ "msg": "Grafana plugin {0} installed : {1}".format(
+ params["name"], cmd
+ ),
+ "changed": True,
+ "version": plugin_version,
+ }
else:
- return {'msg': 'Grafana plugin {0} uninstalled : {1}'.format(params['name'], cmd),
- 'changed': True}
+ return {
+ "msg": "Grafana plugin {0} uninstalled : {1}".format(
+ params["name"], cmd
+ ),
+ "changed": True,
+ }
else:
- if params['state'] == 'absent' and stdout.find("plugin does not exist"):
- return {'msg': 'Grafana plugin {0} already uninstalled : {1}'.format(params['name'], cmd), 'changed': False}
- raise GrafanaCliException("'{0}' execution returned an error : [{1}] {2} {3}".format(cmd, rc, stdout, stderr))
+ if params["state"] == "absent" and stdout.find("plugin does not exist"):
+ return {
+ "msg": "Grafana plugin {0} already uninstalled : {1}".format(
+ params["name"], cmd
+ ),
+ "changed": False,
+ }
+ raise GrafanaCliException(
+ "'{0}' execution returned an error : [{1}] {2} {3}".format(
+ cmd, rc, stdout, stderr
+ )
+ )
def main():
module = AnsibleModule(
argument_spec=dict(
- name=dict(required=True,
- type='str'),
- version=dict(type='str'),
- grafana_plugins_dir=dict(type='str'),
- grafana_repo=dict(type='str'),
- grafana_plugin_url=dict(type='str'),
- validate_certs=dict(type='bool', default=False),
- state=dict(choices=['present', 'absent'],
- default='present')
+ name=dict(required=True, type="str"),
+ version=dict(type="str"),
+ grafana_plugins_dir=dict(type="str"),
+ grafana_repo=dict(type="str"),
+ grafana_plugin_url=dict(type="str"),
+ validate_certs=dict(type="bool", default=False),
+ state=dict(choices=["present", "absent"], default="present"),
),
- supports_check_mode=False
+ supports_check_mode=False,
)
try:
result = grafana_plugin(module, module.params)
except GrafanaCliException as e:
- module.fail_json(
- failed=True,
- msg="{0}".format(e)
- )
+ module.fail_json(failed=True, msg="{0}".format(e))
return
except Exception as e:
- module.fail_json(
- failed=True,
- msg="{0} : {1} ".format(type(e), e)
- )
+ module.fail_json(failed=True, msg="{0} : {1} ".format(type(e), e))
return
- module.exit_json(
- failed=False,
- **result
- )
+ module.exit_json(failed=False, **result)
return
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/grafana/plugins/modules/grafana_team.py b/ansible_collections/community/grafana/plugins/modules/grafana_team.py
index 7f8de8457..76dc70a62 100644
--- a/ansible_collections/community/grafana/plugins/modules/grafana_team.py
+++ b/ansible_collections/community/grafana/plugins/modules/grafana_team.py
@@ -19,7 +19,7 @@
from __future__ import absolute_import, division, print_function
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
module: grafana_team
author:
@@ -59,22 +59,22 @@ options:
description:
- Delete the members not found in the C(members) parameters from the
- list of members found on the Team.
- default: False
+ default: false
type: bool
skip_version_check:
description:
- Skip Grafana version check and try to reach api endpoint anyway.
- - This parameter can be useful if you enabled `hide_version` in grafana.ini
+ - This parameter can be useful if you enabled C(hide_version) in grafana.ini
required: False
type: bool
- default: False
+ default: false
version_added: "1.2.0"
extends_documentation_fragment:
- community.grafana.basic_auth
- community.grafana.api_key
-'''
+"""
-EXAMPLES = '''
+EXAMPLES = """
---
- name: Create a team
community.grafana.grafana_team:
@@ -104,7 +104,7 @@ EXAMPLES = '''
members:
- john.doe@example.com
- jane.doe@example.com
- enforce_members: yes
+ enforce_members: true
state: present
- name: Delete a team
@@ -114,9 +114,9 @@ EXAMPLES = '''
name: "grafana_working_group"
email: "foo.bar@example.com"
state: absent
-'''
+"""
-RETURN = '''
+RETURN = """
---
team:
description: Information about the Team
@@ -165,7 +165,7 @@ team:
type: int
sample:
- 1
-'''
+"""
import json
@@ -183,15 +183,18 @@ class GrafanaError(Exception):
class GrafanaTeamInterface(object):
-
def __init__(self, module):
self._module = module
# {{{ Authentication header
self.headers = {"Content-Type": "application/json"}
- if module.params.get('grafana_api_key', None):
- self.headers["Authorization"] = "Bearer %s" % module.params['grafana_api_key']
+ if module.params.get("grafana_api_key", None):
+ self.headers["Authorization"] = (
+ "Bearer %s" % module.params["grafana_api_key"]
+ )
else:
- self.headers["Authorization"] = basic_auth_header(module.params['url_username'], module.params['url_password'])
+ self.headers["Authorization"] = basic_auth_header(
+ module.params["url_username"], module.params["url_password"]
+ )
# }}}
self.grafana_url = base.clean_url(module.params.get("url"))
if module.params.get("skip_version_check") is False:
@@ -200,7 +203,9 @@ class GrafanaTeamInterface(object):
except GrafanaError as e:
self._module.fail_json(failed=True, msg=to_text(e))
if grafana_version["major"] < 5:
- self._module.fail_json(failed=True, msg="Teams API is available starting Grafana v5")
+ self._module.fail_json(
+ failed=True, msg="Teams API is available starting Grafana v5"
+ )
def _send_request(self, url, data=None, headers=None, method="GET"):
if data is not None:
@@ -209,23 +214,32 @@ class GrafanaTeamInterface(object):
headers = []
full_url = "{grafana_url}{path}".format(grafana_url=self.grafana_url, path=url)
- resp, info = fetch_url(self._module, full_url, data=data, headers=headers, method=method)
+ resp, info = fetch_url(
+ self._module, full_url, data=data, headers=headers, method=method
+ )
status_code = info["status"]
if status_code == 404:
return None
elif status_code == 401:
- self._module.fail_json(failed=True, msg="Unauthorized to perform action '%s' on '%s'" % (method, full_url))
+ self._module.fail_json(
+ failed=True,
+ msg="Unauthorized to perform action '%s' on '%s'" % (method, full_url),
+ )
elif status_code == 403:
self._module.fail_json(failed=True, msg="Permission Denied")
elif status_code == 409:
self._module.fail_json(failed=True, msg="Team name is taken")
elif status_code == 200:
return self._module.from_json(resp.read())
- self._module.fail_json(failed=True, msg="Grafana Teams API answered with HTTP %d" % status_code)
+ self._module.fail_json(
+ failed=True, msg="Grafana Teams API answered with HTTP %d" % status_code
+ )
def get_version(self):
url = "/api/health"
- response = self._send_request(url, data=None, headers=self.headers, method="GET")
+ response = self._send_request(
+ url, data=None, headers=self.headers, method="GET"
+ )
version = response.get("version")
if version is not None:
major, minor, rev = version.split(".")
@@ -235,7 +249,9 @@ class GrafanaTeamInterface(object):
def create_team(self, name, email):
url = "/api/teams"
team = dict(email=email, name=name)
- response = self._send_request(url, data=team, headers=self.headers, method="POST")
+ response = self._send_request(
+ url, data=team, headers=self.headers, method="POST"
+ )
return response
def get_team(self, name):
@@ -251,7 +267,9 @@ class GrafanaTeamInterface(object):
def update_team(self, team_id, name, email):
url = "/api/teams/{team_id}".format(team_id=team_id)
team = dict(email=email, name=name)
- response = self._send_request(url, data=team, headers=self.headers, method="PUT")
+ response = self._send_request(
+ url, data=team, headers=self.headers, method="PUT"
+ )
return response
def delete_team(self, team_id):
@@ -272,7 +290,9 @@ class GrafanaTeamInterface(object):
def delete_team_member(self, team_id, email):
user_id = self.get_user_id_from_mail(email)
- url = "/api/teams/{team_id}/members/{user_id}".format(team_id=team_id, user_id=user_id)
+ url = "/api/teams/{team_id}/members/{user_id}".format(
+ team_id=team_id, user_id=user_id
+ )
self._send_request(url, headers=self.headers, method="DELETE")
def get_user_id_from_mail(self, email):
@@ -295,27 +315,26 @@ def setup_module_object():
argument_spec = base.grafana_argument_spec()
argument_spec.update(
- name=dict(type='str', required=True),
- email=dict(type='str', required=True),
- members=dict(type='list', elements='str', required=False),
- enforce_members=dict(type='bool', default=False),
- skip_version_check=dict(type='bool', default=False),
+ name=dict(type="str", required=True),
+ email=dict(type="str", required=True),
+ members=dict(type="list", elements="str", required=False),
+ enforce_members=dict(type="bool", default=False),
+ skip_version_check=dict(type="bool", default=False),
)
def main():
-
module = setup_module_object()
- state = module.params['state']
- name = module.params['name']
- email = module.params['email']
- members = module.params['members']
- enforce_members = module.params['enforce_members']
+ state = module.params["state"]
+ name = module.params["name"]
+ email = module.params["email"]
+ members = module.params["members"]
+ enforce_members = module.params["enforce_members"]
grafana_iface = GrafanaTeamInterface(module)
changed = False
- if state == 'present':
+ if state == "present":
team = grafana_iface.get_team(name)
if team is None:
grafana_iface.create_team(name, email)
@@ -332,9 +351,9 @@ def main():
grafana_iface.delete_team_member(team.get("id"), member)
changed = True
team = grafana_iface.get_team(name)
- team['members'] = grafana_iface.get_team_members(team.get("id"))
+ team["members"] = grafana_iface.get_team_members(team.get("id"))
module.exit_json(failed=False, changed=changed, team=team)
- elif state == 'absent':
+ elif state == "absent":
team = grafana_iface.get_team(name)
if team is None:
module.exit_json(failed=False, changed=False, message="No team found")
@@ -353,5 +372,5 @@ def diff_members(target, current):
return diff
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/grafana/plugins/modules/grafana_user.py b/ansible_collections/community/grafana/plugins/modules/grafana_user.py
index 3247b534a..6e99718ac 100644
--- a/ansible_collections/community/grafana/plugins/modules/grafana_user.py
+++ b/ansible_collections/community/grafana/plugins/modules/grafana_user.py
@@ -19,7 +19,7 @@
from __future__ import absolute_import, division, print_function
-DOCUMENTATION = '''
+DOCUMENTATION = """
---
module: grafana_user
author:
@@ -68,13 +68,13 @@ options:
type: str
choices: ["present", "absent"]
notes:
-- Unlike other modules from the collection, this module does not support `grafana_api_key` authentication type. The Grafana API endpoint for users management
+- Unlike other modules from the collection, this module does not support C(grafana_api_key) authentication type. The Grafana API endpoint for users management
requires basic auth and admin privileges.
extends_documentation_fragment:
- community.grafana.basic_auth
-'''
+"""
-EXAMPLES = '''
+EXAMPLES = """
---
- name: Create or update a Grafana user
community.grafana.grafana_user:
@@ -95,9 +95,9 @@ EXAMPLES = '''
url_password: changeme
login: batman
state: absent
-'''
+"""
-RETURN = '''
+RETURN = """
---
user:
description: Information about the User
@@ -152,7 +152,7 @@ user:
type: bool
sample:
- false
-'''
+"""
import json
@@ -165,12 +165,13 @@ __metaclass__ = type
class GrafanaUserInterface(object):
-
def __init__(self, module):
self._module = module
# {{{ Authentication header
self.headers = {"Content-Type": "application/json"}
- self.headers["Authorization"] = basic_auth_header(module.params['url_username'], module.params['url_password'])
+ self.headers["Authorization"] = basic_auth_header(
+ module.params["url_username"], module.params["url_password"]
+ )
# }}}
self.grafana_url = base.clean_url(module.params.get("url"))
@@ -181,22 +182,34 @@ class GrafanaUserInterface(object):
headers = []
full_url = "{grafana_url}{path}".format(grafana_url=self.grafana_url, path=url)
- resp, info = fetch_url(self._module, full_url, data=data, headers=headers, method=method)
+ resp, info = fetch_url(
+ self._module, full_url, data=data, headers=headers, method=method
+ )
status_code = info["status"]
if status_code == 404:
return None
elif status_code == 401:
- self._module.fail_json(failed=True, msg="Unauthorized to perform action '%s' on '%s' header: %s" % (method, full_url, self.headers))
+ self._module.fail_json(
+ failed=True,
+ msg="Unauthorized to perform action '%s' on '%s' header: %s"
+ % (method, full_url, self.headers),
+ )
elif status_code == 403:
self._module.fail_json(failed=True, msg="Permission Denied")
elif status_code == 200:
return self._module.from_json(resp.read())
- self._module.fail_json(failed=True, msg="Grafana Users API answered with HTTP %d" % status_code, body=self._module.from_json(resp.read()))
+ self._module.fail_json(
+ failed=True,
+ msg="Grafana Users API answered with HTTP %d" % status_code,
+ body=self._module.from_json(resp.read()),
+ )
def create_user(self, name, email, login, password):
# https://grafana.com/docs/http_api/admin/#global-users
if not password:
- self._module.fail_json(failed=True, msg="missing required arguments: password")
+ self._module.fail_json(
+ failed=True, msg="missing required arguments: password"
+ )
url = "/api/admin/users"
user = dict(name=name, email=email, login=login, password=password)
self._send_request(url, data=user, headers=self.headers, method="POST")
@@ -218,7 +231,9 @@ class GrafanaUserInterface(object):
# https://grafana.com/docs/http_api/admin/#permissions
url = "/api/admin/users/{user_id}/permissions".format(user_id=user_id)
permissions = dict(isGrafanaAdmin=is_admin)
- return self._send_request(url, data=permissions, headers=self.headers, method="PUT")
+ return self._send_request(
+ url, data=permissions, headers=self.headers, method="PUT"
+ )
def delete_user(self, user_id):
# https://grafana.com/docs/http_api/admin/#delete-global-user
@@ -232,7 +247,7 @@ def is_user_update_required(target_user, email, name, login, is_admin):
email=target_user.get("email"),
name=target_user.get("name"),
login=target_user.get("login"),
- is_admin=target_user.get("isGrafanaAdmin")
+ is_admin=target_user.get("isGrafanaAdmin"),
)
param_dict = dict(email=email, name=name, login=login, is_admin=is_admin)
return target_user_dict != param_dict
@@ -243,44 +258,46 @@ def setup_module_object():
argument_spec=argument_spec,
supports_check_mode=False,
required_if=[
- ['state', 'present', ['name', 'email']],
+ ["state", "present", ["name", "email"]],
],
- required_together=base.grafana_required_together()
+ required_together=base.grafana_required_together(),
)
return module
argument_spec = base.grafana_argument_spec()
argument_spec.update(
- state=dict(choices=['present', 'absent'], default='present'),
- name=dict(type='str', required=False),
- email=dict(type='str', required=False),
- login=dict(type='str', required=True),
- password=dict(type='str', required=False, no_log=True),
- is_admin=dict(type='bool', default=False),
+ state=dict(choices=["present", "absent"], default="present"),
+ name=dict(type="str", required=False),
+ email=dict(type="str", required=False),
+ login=dict(type="str", required=True),
+ password=dict(type="str", required=False, no_log=True),
+ is_admin=dict(type="bool", default=False),
)
-argument_spec.pop('grafana_api_key')
+argument_spec.pop("grafana_api_key")
def main():
module = setup_module_object()
- state = module.params['state']
- name = module.params['name']
- email = module.params['email']
- login = module.params['login']
- password = module.params['password']
- is_admin = module.params['is_admin']
+ state = module.params["state"]
+ name = module.params["name"]
+ email = module.params["email"]
+ login = module.params["login"]
+ password = module.params["password"]
+ is_admin = module.params["is_admin"]
grafana_iface = GrafanaUserInterface(module)
# search user by login
actual_grafana_user = grafana_iface.get_user_from_login(login)
- if state == 'present':
+ if state == "present":
has_changed = False
if actual_grafana_user is None:
# create new user
- actual_grafana_user = grafana_iface.create_user(name, email, login, password)
+ actual_grafana_user = grafana_iface.create_user(
+ name, email, login, password
+ )
has_changed = True
if is_user_update_required(actual_grafana_user, email, name, login, is_admin):
@@ -288,17 +305,19 @@ def main():
actual_grafana_user_id = actual_grafana_user.get("id")
if is_admin != actual_grafana_user.get("isGrafanaAdmin"):
grafana_iface.update_user_permissions(actual_grafana_user_id, is_admin)
- actual_grafana_user = grafana_iface.update_user(actual_grafana_user_id, email, name, login)
+ actual_grafana_user = grafana_iface.update_user(
+ actual_grafana_user_id, email, name, login
+ )
has_changed = True
module.exit_json(changed=has_changed, user=actual_grafana_user)
- elif state == 'absent':
+ elif state == "absent":
if actual_grafana_user is None:
module.exit_json(message="No user found, nothing to do")
result = grafana_iface.delete_user(actual_grafana_user.get("id"))
module.exit_json(changed=True, message=result.get("message"))
-if __name__ == '__main__':
+if __name__ == "__main__":
main()
diff --git a/ansible_collections/community/grafana/roles/grafana/README.md b/ansible_collections/community/grafana/roles/grafana/README.md
new file mode 100644
index 000000000..f46434edf
--- /dev/null
+++ b/ansible_collections/community/grafana/roles/grafana/README.md
@@ -0,0 +1,190 @@
+# Grafana Role for Ansible Collection Community.Grafana
+
+Configure Grafana organizations, dashboards, folders, datasources, teams and users.
+
+## Role Variables
+
+| Variable | Required | Default |
+| ---------------- | -------- | ------- |
+| grafana_url | yes |
+| grafana_username | yes |
+| grafana_password | yes |
+| [**grafana_users**](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_user_module.html) |
+| email | no |
+| is_admin | no |
+| login | yes |
+| name | yes |
+| password | no |
+| state | no |
+| [**grafana_organizations**](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_organization_module.html) |
+| name | yes |
+| state | no |
+| [**grafana_teams**](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_team_module.html) |
+| email | yes |
+| enforce_members | no |
+| members | no |
+| name | yes |
+| skip_version_check | no |
+| state | no |
+| [**grafana_datasources**](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_datasource_module.html) |
+| access | no |
+| additional_json_data | no |
+| additional_secure_json_data | no |
+| aws_access_key | no |
+| aws_assume_role_arn | no |
+| aws_auth_type | no |
+| aws_credentials_profile | no |
+| aws_custom_metrics_namespaces | no |
+| aws_default_region | no |
+| aws_secret_key | no |
+| azure_client | no |
+| azure_cloud | no |
+| azure_secret | no |
+| azure_tenant | no |
+| basic_auth_password | no |
+| basic_auth_user | no |
+| database | no |
+| ds_type | no |
+| ds_url | no |
+| enforce_secure_data | no |
+| es_version | no |
+| interval | no |
+| is_default | no |
+| max_concurrent_shard_requests | no |
+| name | yes |
+| org_id | no |
+| org_name | no |
+| password | no |
+| sslmode | no |
+| state | no |
+| time_field | no |
+| time_interval | no |
+| tls_ca_cert | no |
+| tls_client_cert | no |
+| tls_client_key | no |
+| tls_skip_verify | no |
+| trends | no |
+| tsdb_resolution | no |
+| tsdb_version | no |
+| uid | no |
+| user | no |
+| with_credentials | no |
+| zabbix_password | no |
+| zabbix_user | no |
+| [**grafana_folders**](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_folder_module.html) |
+| name | yes |
+| skip_version_check | no |
+| state | no |
+| org_id | no |
+| org_name | no |
+| [**grafana_dashboards**](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_dashboard_module.html) |
+| commit_message | no |
+| dashboard_id | no |
+| dashboard_revision | no |
+| folder | no |
+| org_id | no |
+| org_name | no |
+| overwrite | no |
+| path | no |
+| slug | no |
+| state | no |
+| uid | no |
+| [**grafana_organization_users**](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_organization_user_module.html) |
+| login | yes |
+| org_id | no |
+| org_name | no |
+| role | no |
+| state | no |
+| [**grafana_notification_channel**](https://docs.ansible.com/ansible/latest/collections/community/grafana/grafana_notification_channel_module.html) |
+| dingding_message_type | no |
+| dingding_url | no |
+| disable_resolve_message | no |
+| discord_message_content | no |
+| discord_url | no |
+| email_addresses | no |
+| email_single | no |
+| googlechat_url | no |
+| hipchat_api_key | no |
+| hipchat_room_id | no |
+| hipchat_url | no |
+| include_image | no |
+| is_default | no |
+| kafka_topic | no |
+| kafka_url | no |
+| line_token | no |
+| name | yes |
+| opsgenie_api_key | no |
+| opsgenie_auto_close | no |
+| opsgenie_override_priority | no |
+| opsgenie_url | no |
+| org_id | no |
+| pagerduty_auto_resolve | no |
+| pagerduty_integration_key | no |
+| pagerduty_message_in_details | no |
+| pagerduty_severity | no |
+| prometheus_password | no |
+| prometheus_url | no |
+| prometheus_username | no |
+| pushover_alert_sound | no |
+| pushover_api_token | no |
+| pushover_devices | no |
+| pushover_expire | no |
+| pushover_ok_sound | no |
+| pushover_priority | no |
+| pushover_retry | no |
+| pushover_user_key | no |
+| reminder_frequency | no |
+| sensu_handler | no |
+| sensu_password | no |
+| sensu_source | no |
+| sensu_url | no |
+| sensu_username | no |
+| slack_icon_emoji | no |
+| slack_icon_url | no |
+| slack_mention_channel | no |
+| slack_mention_groups | no |
+| slack_mention_users | no |
+| slack_recipient | no |
+| slack_token | no |
+| slack_url | no |
+| slack_username | no |
+| state | no |
+| teams_url | no |
+| telegram_bot_token | no |
+| telegram_chat_id | no |
+| threema_api_secret | no |
+| threema_gateway_id | no |
+| threema_recipient_id | no |
+| type | yes |
+| uid | no |
+| victorops_auto_resolve | no |
+| victorops_url | no |
+| webhook_http_method | no |
+| webhook_password | no |
+| webhook_url | no |
+| webhook_username | no |
+
+## Example Playbook
+
+```yaml
+---
+- hosts: localhost
+ gather_facts: false
+
+ vars:
+ grafana_url: "https://monitoring.example.com"
+ grafana_username: "api-user"
+ grafana_password: "******"
+
+ grafana_datasources:
+ - name: "Loki"
+ ds_type: "loki"
+ ds_url: "http://127.0.0.1:3100"
+ tls_skip_verify: yes
+ grafana_folders:
+ - name: my_service
+ - name: other_service
+
+ roles:
+ - role: community.grafana.grafana
+```
diff --git a/ansible_collections/community/grafana/roles/grafana/defaults/main.yml b/ansible_collections/community/grafana/roles/grafana/defaults/main.yml
new file mode 100644
index 000000000..6a84370d3
--- /dev/null
+++ b/ansible_collections/community/grafana/roles/grafana/defaults/main.yml
@@ -0,0 +1,9 @@
+---
+grafana_organizations: []
+grafana_organization_users: []
+grafana_users: []
+grafana_teams: []
+grafana_datasources: []
+grafana_folders: []
+grafana_dashboards: []
+grafana_notification_channels: []
diff --git a/ansible_collections/community/grafana/roles/grafana/meta/main.yml b/ansible_collections/community/grafana/roles/grafana/meta/main.yml
new file mode 100644
index 000000000..47d4af5b7
--- /dev/null
+++ b/ansible_collections/community/grafana/roles/grafana/meta/main.yml
@@ -0,0 +1,14 @@
+---
+galaxy_info:
+ role_name: grafana
+ author: community
+ description: Configure Grafana organizations, dashboards, folders, datasources, teams and users
+ license: GPLv3
+ min_ansible_version: "2.14"
+ galaxy_tags: [grafana, monitoring]
+ platforms:
+ - {name: EL, versions: [all]}
+ - {name: Fedora, versions: [all]}
+ - {name: Amazon, versions: [all]}
+ - {name: Debian, versions: [all]}
+ - {name: Ubuntu, versions: [all]}
diff --git a/ansible_collections/community/grafana/roles/grafana/tasks/main.yml b/ansible_collections/community/grafana/roles/grafana/tasks/main.yml
new file mode 100644
index 000000000..82bbc633d
--- /dev/null
+++ b/ansible_collections/community/grafana/roles/grafana/tasks/main.yml
@@ -0,0 +1,203 @@
+---
+- name: Group tasks for authentication parameters
+ module_defaults:
+ group/community.grafana.grafana:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ use_proxy: "{{ grafana_use_proxy | default(omit) }}"
+ validate_certs: "{{ grafana_validate_certs | default(omit) }}"
+ block:
+ - name: Manage organization # noqa: args[module]
+ community.grafana.grafana_organization:
+ name: "{{ organization.name }}"
+ state: "{{ organization.state | default(omit) }}"
+ loop: "{{ grafana_organizations }}"
+ loop_control: {loop_var: organization}
+ tags: organization
+
+ - name: Manage notification channel
+ community.grafana.grafana_notification_channel:
+ dingding_message_type: "{{ notification_channel.dingding_message_type | default(omit) }}"
+ dingding_url: "{{ notification_channel.dingding_url | default(omit) }}"
+ disable_resolve_message: "{{ notification_channel.disable_resolve_message | default(omit) }}"
+ discord_message_content: "{{ notification_channel.discord_message_content | default(omit) }}"
+ discord_url: "{{ notification_channel.discord_url | default(omit) }}"
+ email_addresses: "{{ notification_channel.email_addresses | default(omit) }}"
+ email_single: "{{ notification_channel.email_single | default(omit) }}"
+ googlechat_url: "{{ notification_channel.googlechat_url | default(omit) }}"
+ hipchat_api_key: "{{ notification_channel.hipchat_api_key | default(omit) }}"
+ hipchat_room_id: "{{ notification_channel.hipchat_room_id | default(omit) }}"
+ hipchat_url: "{{ notification_channel.hipchat_url | default(omit) }}"
+ include_image: "{{ notification_channel.include_image | default(omit) }}"
+ is_default: "{{ notification_channel.is_default | default(omit) }}"
+ kafka_topic: "{{ notification_channel.kafka_topic | default(omit) }}"
+ kafka_url: "{{ notification_channel.kafka_url | default(omit) }}"
+ line_token: "{{ notification_channel.line_token | default(omit) }}"
+ name: "{{ notification_channel.name }}"
+ opsgenie_api_key: "{{ notification_channel.opsgenie_api_key | default(omit) }}"
+ opsgenie_auto_close: "{{ notification_channel.opsgenie_auto_close | default(omit) }}"
+ opsgenie_override_priority: "{{ notification_channel.opsgenie_override_priority | default(omit) }}"
+ opsgenie_url: "{{ notification_channel.opsgenie_url | default(omit) }}"
+ org_id: "{{ notification_channel.org_id | default(omit) }}"
+ pagerduty_auto_resolve: "{{ notification_channel.pagerduty_auto_resolve | default(omit) }}"
+ pagerduty_integration_key: "{{ notification_channel.pagerduty_integration_key | default(omit) }}"
+ pagerduty_message_in_details: "{{ notification_channel.pagerduty_message_in_details | default(omit) }}"
+ pagerduty_severity: "{{ notification_channel.pagerduty_severity | default(omit) }}"
+ prometheus_password: "{{ notification_channel.prometheus_password | default(omit) }}"
+ prometheus_url: "{{ notification_channel.prometheus_url | default(omit) }}"
+ prometheus_username: "{{ notification_channel.prometheus_username | default(omit) }}"
+ pushover_alert_sound: "{{ notification_channel.pushover_alert_sound | default(omit) }}"
+ pushover_api_token: "{{ notification_channel.pushover_api_token | default(omit) }}"
+ pushover_devices: "{{ notification_channel.pushover_devices | default(omit) }}"
+ pushover_expire: "{{ notification_channel.pushover_expire | default(omit) }}"
+ pushover_ok_sound: "{{ notification_channel.pushover_ok_sound | default(omit) }}"
+ pushover_priority: "{{ notification_channel.pushover_priority | default(omit) }}"
+ pushover_retry: "{{ notification_channel.pushover_retry | default(omit) }}"
+ pushover_user_key: "{{ notification_channel.pushover_user_key | default(omit) }}"
+ reminder_frequency: "{{ notification_channel.reminder_frequency | default(omit) }}"
+ sensu_handler: "{{ notification_channel.sensu_handler | default(omit) }}"
+ sensu_password: "{{ notification_channel.sensu_password | default(omit) }}"
+ sensu_source: "{{ notification_channel.sensu_source | default(omit) }}"
+ sensu_url: "{{ notification_channel.sensu_url | default(omit) }}"
+ sensu_username: "{{ notification_channel.sensu_username | default(omit) }}"
+ slack_icon_emoji: "{{ notification_channel.slack_icon_emoji | default(omit) }}"
+ slack_icon_url: "{{ notification_channel.slack_icon_url | default(omit) }}"
+ slack_mention_channel: "{{ notification_channel.slack_mention_channel | default(omit) }}"
+ slack_mention_groups: "{{ notification_channel.slack_mention_groups | default(omit) }}"
+ slack_mention_users: "{{ notification_channel.slack_mention_users | default(omit) }}"
+ slack_recipient: "{{ notification_channel.slack_recipient | default(omit) }}"
+ slack_token: "{{ notification_channel.slack_token | default(omit) }}"
+ slack_url: "{{ notification_channel.slack_url | default(omit) }}"
+ slack_username: "{{ notification_channel.slack_username | default(omit) }}"
+ state: "{{ notification_channel.state | default(omit) }}"
+ teams_url: "{{ notification_channel.teams_url | default(omit) }}"
+ telegram_bot_token: "{{ notification_channel.telegram_bot_token | default(omit) }}"
+ telegram_chat_id: "{{ notification_channel.telegram_chat_id | default(omit) }}"
+ threema_api_secret: "{{ notification_channel.threema_api_secret | default(omit) }}"
+ threema_gateway_id: "{{ notification_channel.threema_gateway_id | default(omit) }}"
+ threema_recipient_id: "{{ notification_channel.threema_recipient_id | default(omit) }}"
+ type: "{{ notification_channel.type }}"
+ uid: "{{ notification_channel.uid | default(omit) }}"
+ victorops_auto_resolve: "{{ notification_channel.victorops_auto_resolve | default(omit) }}"
+ victorops_url: "{{ notification_channel.victorops_url | default(omit) }}"
+ webhook_http_method: "{{ notification_channel.webhook_http_method | default(omit) }}"
+ webhook_password: "{{ notification_channel.webhook_password | default(omit) }}"
+ webhook_url: "{{ notification_channel.webhook_url | default(omit) }}"
+ webhook_username: "{{ notification_channel.webhook_username | default(omit) }}"
+ loop: "{{ grafana_notification_channels }}"
+ loop_control: {loop_var: notification_channel}
+ tags: notification_channel
+
+ - name: Manage datasource
+ community.grafana.grafana_datasource:
+ access: "{{ datasource.access | default(omit) }}"
+ additional_json_data: "{{ datasource.additional_json_data | default(omit) }}"
+ additional_secure_json_data: "{{ datasource.additional_secure_json_data | default(omit) }}"
+ aws_access_key: "{{ datasource.aws_access_key | default(omit) }}"
+ aws_assume_role_arn: "{{ datasource.aws_assume_role_arn | default(omit) }}"
+ aws_auth_type: "{{ datasource.aws_auth_type | default(omit) }}"
+ aws_credentials_profile: "{{ datasource.aws_credentials_profile | default(omit) }}"
+ aws_custom_metrics_namespaces: "{{ datasource.aws_custom_metrics_namespaces | default(omit) }}"
+ aws_default_region: "{{ datasource.aws_default_region | default(omit) }}"
+ aws_secret_key: "{{ datasource.aws_secret_key | default(omit) }}"
+ azure_client: "{{ datasource.azure_client | default(omit) }}"
+ azure_cloud: "{{ datasource.azure_cloud | default(omit) }}"
+ azure_secret: "{{ datasource.azure_secret | default(omit) }}"
+ azure_tenant: "{{ datasource.azure_tenant | default(omit) }}"
+ basic_auth_password: "{{ datasource.basic_auth_password | default(omit) }}"
+ basic_auth_user: "{{ datasource.basic_auth_user | default(omit) }}"
+ database: "{{ datasource.database | default(omit) }}"
+ ds_type: "{{ datasource.ds_type | default(omit) }}"
+ ds_url: "{{ datasource.ds_url | default(omit) }}"
+ enforce_secure_data: "{{ datasource.enforce_secure_data | default(omit) }}"
+ es_version: "{{ datasource.es_version | default(omit) }}"
+ interval: "{{ datasource.interval | default(omit) }}"
+ is_default: "{{ datasource.is_default | default(omit) }}"
+ max_concurrent_shard_requests: "{{ datasource.max_concurrent_shard_requests | default(omit) }}"
+ name: "{{ datasource.name }}"
+ org_id: "{{ datasource.org_id | default(omit) }}"
+ org_name: "{{ datasource.org_name | default(omit) }}"
+ password: "{{ datasource.password | default(omit) }}"
+ sslmode: "{{ datasource.sslmode | default(omit) }}"
+ state: "{{ datasource.state | default(omit) }}"
+ time_field: "{{ datasource.time_field | default(omit) }}"
+ time_interval: "{{ datasource.time_interval | default(omit) }}"
+ tls_ca_cert: "{{ datasource.tls_ca_cert | default(omit) }}"
+ tls_client_cert: "{{ datasource.tls_client_cert | default(omit) }}"
+ tls_client_key: "{{ datasource.tls_client_key | default(omit) }}"
+ tls_skip_verify: "{{ datasource.tls_skip_verify | default(omit) }}"
+ trends: "{{ datasource.trends | default(omit) }}"
+ tsdb_resolution: "{{ datasource.tsdb_resolution | default(omit) }}"
+ tsdb_version: "{{ datasource.tsdb_version | default(omit) }}"
+ uid: "{{ datasource.uid | default(omit) }}"
+ user: "{{ datasource.user | default(omit) }}"
+ with_credentials: "{{ datasource.with_credentials | default(omit) }}"
+ zabbix_password: "{{ datasource.zabbix_password | default(omit) }}"
+ zabbix_user: "{{ datasource.zabbix_user | default(omit) }}"
+ loop: "{{ grafana_datasources }}"
+ loop_control: {loop_var: datasource}
+ tags: datasource
+
+ - name: Manage folder # noqa: args[module]
+ community.grafana.grafana_folder:
+ name: "{{ folder.name }}"
+ skip_version_check: "{{ folder.skip_version_check | default(omit) }}"
+ state: "{{ folder.state | default(omit) }}"
+ org_id: "{{ folder.org_id | default(omit) }}"
+ org_name: "{{ folder.org_name | default(omit) }}"
+ loop: "{{ grafana_folders }}"
+ loop_control: {loop_var: folder}
+ tags: folder
+
+ - name: Manage team # noqa: args[module]
+ community.grafana.grafana_team:
+ email: "{{ team.email }}"
+ enforce_members: "{{ team.enforce_members | default(omit) }}"
+ members: "{{ team.members | default(omit) }}"
+ name: "{{ team.name }}"
+ skip_version_check: "{{ team.skip_version_check | default(omit) }}"
+ state: "{{ team.state | default(omit) }}"
+ loop: "{{ grafana_teams }}"
+ loop_control: {loop_var: team}
+ tags: team
+
+ - name: Manage user # noqa: args[module]
+ community.grafana.grafana_user:
+ email: "{{ user.email | default(omit) }}"
+ is_admin: "{{ user.is_admin | default(omit) }}"
+ login: "{{ user.login }}"
+ name: "{{ user.name }}"
+ password: "{{ user.password | default(omit) }}"
+ state: "{{ user.state | default(omit) }}"
+ loop: "{{ grafana_users }}"
+ loop_control: {loop_var: user}
+ tags: user
+
+ - name: Manage organization users
+ community.grafana.grafana_organization_user:
+ login: "{{ organization_user.login }}"
+ org_id: "{{ organization_user.org_id | default(omit) }}"
+ org_name: "{{ organization_user.org_name | default(omit) }}"
+ role: "{{ organization_user.role | default(omit) }}"
+ state: "{{ organization_user.state | default(omit) }}"
+ loop: "{{ grafana_organization_users }}"
+ loop_control: {loop_var: organization_user}
+ tags: organization_user
+
+ - name: Manage dashboard
+ community.grafana.grafana_dashboard:
+ commit_message: "{{ dashboard.commit_message | default(omit) }}"
+ dashboard_id: "{{ dashboard.dashboard_id | default(omit) }}"
+ dashboard_revision: "{{ dashboard.dashboard_revision | default(omit) }}"
+ folder: "{{ dashboard.folder | default(omit) }}"
+ org_id: "{{ dashboard.org_id | default(omit) }}"
+ org_name: "{{ dashboard.org_name | default(omit) }}"
+ overwrite: "{{ dashboard.overwrite | default(omit) }}"
+ path: "{{ dashboard.path | default(omit) }}"
+ slug: "{{ dashboard.slug | default(omit) }}"
+ state: "{{ dashboard.state | default(omit) }}"
+ uid: "{{ dashboard.uid | default(omit) }}"
+ loop: "{{ grafana_dashboards }}"
+ loop_control: {loop_var: dashboard}
+ tags: [dashboard, molecule-idempotence-notest]
diff --git a/ansible_collections/community/grafana/ruff.toml b/ansible_collections/community/grafana/ruff.toml
new file mode 100644
index 000000000..ef486c58f
--- /dev/null
+++ b/ansible_collections/community/grafana/ruff.toml
@@ -0,0 +1 @@
+ignore = ["E402"]
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/defaults/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/defaults/main.yml
index 8b9c9348a..3edac8598 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/defaults/main.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/defaults/main.yml
@@ -1,7 +1,4 @@
---
-
-grafana_url: "http://grafana:3000/"
-grafana_username: "admin"
-grafana_password: "admin"
-
-...
+grafana_url: http://grafana:3000/
+grafana_username: admin
+grafana_password: admin
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/runme.sh b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/runme.sh
new file mode 100755
index 000000000..867afb0d3
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/runme.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+set -eux
+
+ansible-playbook site.yml
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/site.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/site.yml
new file mode 100644
index 000000000..c32364ef0
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/site.yml
@@ -0,0 +1,6 @@
+---
+- name: Run tests for grafana_dashboard
+ hosts: localhost
+ tasks:
+ - ansible.builtin.include_role:
+ name: ../../grafana_dashboard
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-by-org-name.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-by-org-name.yml
new file mode 100644
index 000000000..a493eb0f8
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-by-org-name.yml
@@ -0,0 +1,84 @@
+---
+- module_defaults:
+ community.grafana.grafana_dashboard:
+ org_name: Main Org.
+ block:
+ - name: Create Dashboard from file by org_name | check mode | dashboard does not exist
+ 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
+ check_mode: true
+ register: dbo_result1
+ - ansible.builtin.assert:
+ that:
+ - dbo_result1.failed == false
+ - dbo_result1.changed == true
+ - dbo_result1.uid is not defined
+ - dbo_result1.msg == 'Dashboard test will be created'
+
+ - name: Create Dashboard from file by org_name | run mode | dashboard does not exist
+ 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
+ check_mode: false
+ register: dbo_result2
+ - ansible.builtin.assert:
+ that:
+ - dbo_result2.failed == false
+ - dbo_result2.changed == true
+ - dbo_result2.uid is defined
+ - dbo_result2.uid | type_debug == "AnsibleUnsafeText"
+ - dbo_result2.msg == 'Dashboard test created'
+
+ - name: Create Dashboard from file by org_name | check mode | dashboard exists
+ 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
+ check_mode: true
+ register: dbo_result3
+ - ansible.builtin.assert:
+ that:
+ - dbo_result3.failed == false
+ - dbo_result3.changed == false
+ - dbo_result3.uid is defined
+ - dbo_result3.uid | type_debug == "AnsibleUnsafeText"
+ - dbo_result3.msg == 'Dashboard test unchanged.'
+
+ - name: Create Dashboard from file by org_name | run mode | dashboard exists
+ 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
+ check_mode: false
+ register: dbo_result4
+ - ansible.builtin.assert:
+ that:
+ - dbo_result4.failed == false
+ - dbo_result4.changed == false
+ - dbo_result4.uid is defined
+ - dbo_result4.uid | type_debug == "AnsibleUnsafeText"
+ - dbo_result4.msg == 'Dashboard test unchanged.'
+
+ - ansible.builtin.include_tasks:
+ file: delete-dashboard.yml
+ vars:
+ uid_to_delete: '{{ dbo_result4.uid }}'
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-export.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-export.yml
index 04b17f727..bb4f30e10 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-export.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-export.yml
@@ -1,33 +1,93 @@
---
-- set_fact:
- dashboard_uid: "{{ result.uid }}"
+- name: Export Dashboard | check mode | uid does not exist
+ community.grafana.grafana_dashboard:
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: export
+ path: /tmp/dashboard_export.json
+ overwrite: true
+ uid: "090909090"
+ check_mode: true
+ ignore_errors: true
+ register: de_result1
+- ansible.builtin.assert:
+ that:
+ - de_result1.failed == false
+ - de_result1.changed == false
+ - de_result1.uid is defined
+ - de_result1.uid | type_debug == "AnsibleUnsafeText"
+ - de_result1.uid == "090909090"
+ - de_result1.msg == 'Dashboard ' ~ de_result1.uid ~ ' does not exist.'
-- name: Check export grafana dashboard to file
- grafana_dashboard:
+- name: Export Dashboard | run mode | uid does not exist
+ community.grafana.grafana_dashboard:
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: export
- path: /tmp/dashboard.json
+ path: /tmp/dashboard_export.json
overwrite: true
- uid: "{{ dashboard_uid }}"
- register: result
+ uid: "090909090"
+ check_mode: false
+ ignore_errors: true
+ register: de_result2
+- ansible.builtin.assert:
+ that:
+ - de_result2.failed == false
+ - de_result2.changed == false
+ - de_result2.uid is defined
+ - de_result2.uid | type_debug == "AnsibleUnsafeText"
+ - de_result2.uid == "090909090"
+ - de_result2.msg == 'Dashboard ' ~ de_result2.uid ~ ' does not exist.'
-- debug:
- var: result
+- name: Export Dashboard | check mode | uid exists
+ community.grafana.grafana_dashboard:
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: export
+ path: /tmp/dashboard_export.json
+ overwrite: true
+ uid: "{{ uid_to_export }}"
+ check_mode: true
+ register: de_result3
+- ansible.builtin.assert:
+ that:
+ - de_result3.failed == false
+ - de_result3.changed == true
+ - de_result3.uid is defined
+ - de_result3.uid | type_debug == "AnsibleUnsafeText"
+ - de_result3.uid == uid_to_export
+ - de_result3.msg == 'Dashboard ' ~ de_result3.uid ~ ' will be exported to /tmp/dashboard_export.json'
-- assert:
+- name: Export Dashboard | run mode | uid exists
+ community.grafana.grafana_dashboard:
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: export
+ path: /tmp/dashboard_export.json
+ overwrite: true
+ uid: "{{ uid_to_export }}"
+ check_mode: false
+ register: de_result4
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.msg == 'Dashboard {{ dashboard_uid }} exported to /tmp/dashboard.json'"
+ - de_result4.failed == false
+ - de_result4.changed == true
+ - de_result4.uid is defined
+ - de_result4.uid | type_debug == "AnsibleUnsafeText"
+ - de_result4.uid == uid_to_export
+ - de_result4.msg == 'Dashboard ' ~ de_result4.uid ~ ' exported to /tmp/dashboard_export.json'
-- name: Load /tmp/dashboard.json or fail if missing
- set_fact:
- exported_dashboard_lines: "{{ lookup('file', '/tmp/dashboard.json').splitlines() }}"
+- name: Export Dashboard | Load /tmp/dashboard_export.json or fail if missing
+ ansible.builtin.set_fact:
+ exported_dashboard_lines: "{{ lookup('file', '/tmp/dashboard_export.json').splitlines() }}"
-- name: Assert that exported dashboard contains formatted JSON
- assert:
+- name: Export Dashboard | Assert that exported dashboard contains formatted JSON
+ ansible.builtin.assert:
that:
- - "exported_dashboard_lines | length >= 2"
- - "exported_dashboard_lines[0] == '{'"
- - "exported_dashboard_lines[-1] == '}'"
+ - exported_dashboard_lines | length >= 2
+ - exported_dashboard_lines[0] == '{'
+ - exported_dashboard_lines[-1] == '}'
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-folder-destination.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-folder-destination.yml
index f4f3d9f4d..4704002f5 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-folder-destination.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-folder-destination.yml
@@ -1,33 +1,38 @@
---
-- name: copy dashboard file
- copy:
- src: "files/dashboard.json"
- dest: "/tmp/dashboard.json"
-
-- block:
- - name: Check import grafana dashboard from file to unknown folder fails
- 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: inexistent
- register: result
- ignore_errors: true
-
-- debug:
- var: result
-
-- set_fact:
- # XXX: Too many quotes of different types to do inline.
- # I did not manage to find a good way of having it inline.
- expected_error: "error : Dashboard folder 'inexistent' does not exist."
+- name: Create Dashboard from file | check mode | folder does not exist
+ 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: inexistent
+ check_mode: true
+ register: dfff_result1
+ ignore_errors: true
+- ansible.builtin.assert:
+ that:
+ - dfff_result1.failed == true
+ - dfff_result1.changed == false
+ - "dfff_result1.msg == 'error : Dashboard folder \\'inexistent\\' does not exist.'"
-- assert:
+- name: Create Dashboard from file | run mode | folder does not exist
+ 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: inexistent
+ check_mode: false
+ register: dfff_result2
+ ignore_errors: true
+- ansible.builtin.assert:
that:
- - "result.changed == false"
- - "result.failed == true"
- - "result.msg == expected_error"
+ - dfff_result2.failed == true
+ - dfff_result2.changed == false
+ - "dfff_result2.msg == 'error : Dashboard folder \\'inexistent\\' does not exist.'"
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-file-export.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-file-export.yml
new file mode 100644
index 000000000..3d0019c5d
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-file-export.yml
@@ -0,0 +1,90 @@
+---
+- name: Create Dashboard from file | Copy dashboard file
+ ansible.builtin.copy:
+ src: files/dashboard.json
+ dest: /tmp/dashboard.json
+
+- name: Create Dashboard from file | check mode | dashboard does not exist
+ 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
+ check_mode: true
+ register: dff_result1
+- ansible.builtin.assert:
+ that:
+ - dff_result1.failed == false
+ - dff_result1.changed == true
+ - dff_result1.uid is not defined
+ - dff_result1.msg == 'Dashboard test will be created'
+
+- name: Create Dashboard from file | run mode | dashboard does not exist
+ 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
+ check_mode: false
+ register: dff_result2
+- ansible.builtin.assert:
+ that:
+ - dff_result2.failed == false
+ - dff_result2.changed == true
+ - dff_result2.uid is defined
+ - dff_result2.uid | type_debug == "AnsibleUnsafeText"
+ - dff_result2.msg == 'Dashboard test created'
+
+- name: Create Dashboard from file | check mode | dashboard exists
+ 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
+ check_mode: true
+ register: dff_result3
+- ansible.builtin.assert:
+ that:
+ - dff_result3.failed == false
+ - dff_result3.changed == false
+ - dff_result3.uid is defined
+ - dff_result3.uid | type_debug == "AnsibleUnsafeText"
+ - dff_result3.msg == 'Dashboard test unchanged.'
+
+- name: Create Dashboard from file | run mode | dashboard exists
+ 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
+ check_mode: false
+ register: dff_result4
+- ansible.builtin.assert:
+ that:
+ - dff_result4.failed == false
+ - dff_result4.changed == false
+ - dff_result4.uid is defined
+ - dff_result4.uid | type_debug == "AnsibleUnsafeText"
+ - dff_result4.msg == 'Dashboard test unchanged.'
+
+- ansible.builtin.include_tasks:
+ file: dashboard-export.yml
+ vars:
+ uid_to_export: '{{ dff_result4.uid }}'
+
+- ansible.builtin.include_tasks:
+ file: delete-dashboard.yml
+ vars:
+ uid_to_delete: '{{ dff_result4.uid }}'
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-file.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-file.yml
deleted file mode 100644
index 93df1666a..000000000
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-file.yml
+++ /dev/null
@@ -1,44 +0,0 @@
----
-- name: copy dashboard file
- copy:
- src: "files/dashboard.json"
- dest: "/tmp/dashboard.json"
-
-
-- name: Check import grafana dashboard from file
- 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
- register: result
-
-- debug:
- var: result
-
-- assert:
- that:
- - "result.changed == true"
- - "result.msg == 'Dashboard test created'"
-
-- name: Check import grafana dashboard from file idempotency
- 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
- register: result
-
-- debug:
- var: result
-
-- assert:
- that:
- - "result.changed == false"
- - "result.msg == 'Dashboard test unchanged.'"
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-id.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-id.yml
index 3b81ebf71..4de7b4675 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-id.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-id.yml
@@ -1,6 +1,6 @@
---
-- name: Check import grafana dashboard from id
- grafana_dashboard:
+- name: Create Dashboard from ID | check mode | dashboard does not exist
+ community.grafana.grafana_dashboard:
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
@@ -9,18 +9,17 @@
dashboard_id: "6098"
dashboard_revision: "1"
overwrite: true
- register: result
-
-- debug:
- var: result
-
-- assert:
+ check_mode: true
+ register: dfi_result1
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.msg == 'Dashboard Zabbix Host Status created'"
+ - dfi_result1.failed == false
+ - dfi_result1.changed == true
+ - dfi_result1.uid is not defined
+ - dfi_result1.msg == 'Dashboard Zabbix Host Status will be created'
-- name: Check import grafana dashboard from id idempotency
- grafana_dashboard:
+- name: Create Dashboard from ID | run mode | dashboard does not exist
+ community.grafana.grafana_dashboard:
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
@@ -29,12 +28,57 @@
dashboard_id: "6098"
dashboard_revision: "1"
overwrite: true
- register: result
+ check_mode: false
+ register: dfi_result2
+- ansible.builtin.assert:
+ that:
+ - dfi_result2.failed == false
+ - dfi_result2.changed == true
+ - dfi_result2.uid is defined
+ - dfi_result2.uid | type_debug == "AnsibleUnsafeText"
+ - dfi_result2.msg == 'Dashboard Zabbix Host Status created'
-- debug:
- var: result
+- name: Create Dashboard from ID | check mode | dashboard exists
+ community.grafana.grafana_dashboard:
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: present
+ commit_message: Updated by ansible
+ dashboard_id: "6098"
+ dashboard_revision: "1"
+ overwrite: true
+ check_mode: true
+ register: dfi_result3
+- ansible.builtin.assert:
+ that:
+ - dfi_result3.failed == false
+ - dfi_result3.changed == false
+ - dfi_result3.uid is defined
+ - dfi_result3.uid | type_debug == "AnsibleUnsafeText"
+ - dfi_result3.msg == 'Dashboard Zabbix Host Status unchanged.'
-- assert:
+- name: Create Dashboard from ID | run mode | dashboard exists
+ community.grafana.grafana_dashboard:
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: present
+ commit_message: Updated by ansible
+ dashboard_id: "6098"
+ dashboard_revision: "1"
+ overwrite: true
+ check_mode: false
+ register: dfi_result4
+- ansible.builtin.assert:
that:
- - "result.changed == false"
- - "result.msg == 'Dashboard Zabbix Host Status unchanged.'"
+ - dfi_result4.failed == false
+ - dfi_result4.changed == false
+ - dfi_result4.uid is defined
+ - dfi_result4.uid | type_debug == "AnsibleUnsafeText"
+ - dfi_result4.msg == 'Dashboard Zabbix Host Status unchanged.'
+
+- ansible.builtin.include_tasks:
+ file: delete-dashboard.yml
+ vars:
+ uid_to_delete: '{{ dfi_result4.uid }}'
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-url.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-url.yml
index 5146fc9a0..abdeacfd0 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-url.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-url.yml
@@ -1,7 +1,6 @@
---
-
-- name: Check import grafana dashboard from url
- grafana_dashboard:
+- name: Create Dashboard from URL | check mode | dashboard does not exist
+ community.grafana.grafana_dashboard:
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
@@ -9,18 +8,17 @@
commit_message: Updated by ansible
dashboard_url: https://grafana.com/api/dashboards/6098/revisions/1/download
overwrite: true
- register: result
-
-- debug:
- var: result
-
-- assert:
+ check_mode: true
+ register: dfu_result1
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.msg == 'Dashboard Zabbix Host Status created'"
+ - dfu_result1.failed == false
+ - dfu_result1.changed == true
+ - dfu_result1.uid is not defined
+ - dfu_result1.msg == 'Dashboard Zabbix Host Status will be created'
-- name: Check import grafana dashboard from url idempotency
- grafana_dashboard:
+- name: Create Dashboard from URL | run mode | dashboard does not exist
+ community.grafana.grafana_dashboard:
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
@@ -28,12 +26,55 @@
commit_message: Updated by ansible
dashboard_url: https://grafana.com/api/dashboards/6098/revisions/1/download
overwrite: true
- register: result
+ check_mode: false
+ register: dfu_result2
+- ansible.builtin.assert:
+ that:
+ - dfu_result2.failed == false
+ - dfu_result2.changed == true
+ - dfu_result2.uid is defined
+ - dfu_result2.uid | type_debug == "AnsibleUnsafeText"
+ - dfu_result2.msg == 'Dashboard Zabbix Host Status created'
-- debug:
- var: result
+- name: Create Dashboard from URL | check mode | dashboard exists
+ community.grafana.grafana_dashboard:
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: present
+ commit_message: Updated by ansible
+ dashboard_url: https://grafana.com/api/dashboards/6098/revisions/1/download
+ overwrite: true
+ check_mode: true
+ register: dfu_result3
+- ansible.builtin.assert:
+ that:
+ - dfu_result3.failed == false
+ - dfu_result3.changed == false
+ - dfu_result3.uid is defined
+ - dfu_result3.uid | type_debug == "AnsibleUnsafeText"
+ - dfu_result3.msg == 'Dashboard Zabbix Host Status unchanged.'
-- assert:
+- name: Create Dashboard from URL | run mode | dashboard exists
+ community.grafana.grafana_dashboard:
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: present
+ commit_message: Updated by ansible
+ dashboard_url: https://grafana.com/api/dashboards/6098/revisions/1/download
+ overwrite: true
+ check_mode: false
+ register: dfu_result4
+- ansible.builtin.assert:
that:
- - "result.changed == false"
- - "result.msg == 'Dashboard Zabbix Host Status unchanged.'"
+ - dfu_result4.failed == false
+ - dfu_result4.changed == false
+ - dfu_result4.uid is defined
+ - dfu_result4.uid | type_debug == "AnsibleUnsafeText"
+ - dfu_result4.msg == 'Dashboard Zabbix Host Status unchanged.'
+
+- ansible.builtin.include_tasks:
+ file: delete-dashboard.yml
+ vars:
+ uid_to_delete: '{{ dfu_result4.uid }}' \ No newline at end of file
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/delete-dashboard.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/delete-dashboard.yml
index 2013324fb..b2d27fdc8 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/delete-dashboard.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/delete-dashboard.yml
@@ -1,16 +1,60 @@
-- name: Check delete dashboard is working
- grafana_dashboard:
+---
+- name: Delete dashboard | check mode | dashboard exists
+ community.grafana.grafana_dashboard:
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: absent
- uid: "{{ result.uid }}"
- register: result
+ uid: "{{ uid_to_delete }}"
+ check_mode: true
+ register: dd_result1
+- ansible.builtin.assert:
+ that:
+ - dd_result1.failed == false
+ - dd_result1.changed == true
+ - dd_result1.msg == 'Dashboard ' ~ dd_result1.uid ~ ' will be deleted'
+
+- name: Delete dashboard | run mode | dashboard exists
+ community.grafana.grafana_dashboard:
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: absent
+ uid: "{{ uid_to_delete }}"
+ check_mode: false
+ register: dd_result2
+- ansible.builtin.assert:
+ that:
+ - dd_result2.failed == false
+ - dd_result2.changed == true
+ - dd_result2.msg == 'Dashboard ' ~ dd_result2.uid ~ ' deleted'
-- debug:
- var: result
+- name: Delete dashboard | check mode | dashboard does not exist
+ community.grafana.grafana_dashboard:
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: absent
+ uid: "{{ uid_to_delete }}"
+ check_mode: true
+ register: dd_result1
+- ansible.builtin.assert:
+ that:
+ - dd_result1.failed == false
+ - dd_result1.changed == false
+ - dd_result1.msg == 'Dashboard ' ~ dd_result1.uid ~ ' does not exist.'
-- assert:
+- name: Delete dashboard | run mode | dashboard does not exist
+ community.grafana.grafana_dashboard:
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: absent
+ uid: "{{ uid_to_delete }}"
+ check_mode: false
+ register: dd_result2
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.msg == 'Dashboard {{ result.uid }} deleted'"
+ - dd_result2.failed == false
+ - dd_result2.changed == false
+ - dd_result2.msg == 'Dashboard ' ~ dd_result2.uid ~ ' does not exist.' \ No newline at end of file
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/main.yml
index 4d9138fcf..86e756e95 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/main.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/main.yml
@@ -1,7 +1,20 @@
-- block:
- - include: dashboard-from-url.yml
- - include: delete-dashboard.yml
- - include: dashboard-from-id.yml
- - include: dashboard-from-file.yml
- - include: dashboard-export.yml
- - include: dashboard-folder-destination.yml
+---
+- name: Create dashboard from url
+ ansible.builtin.include_tasks:
+ file: dashboard-from-url.yml
+
+- name: Create dashboard from id
+ ansible.builtin.include_tasks:
+ file: dashboard-from-id.yml
+
+- name: Create dashboard from file and export
+ ansible.builtin.include_tasks:
+ file: dashboard-from-file-export.yml
+
+- name: Create dashboard from file by org_name
+ ansible.builtin.include_tasks:
+ file: dashboard-by-org-name.yml
+
+- name: Create dashboard from file in non existing folder
+ ansible.builtin.include_tasks:
+ file: dashboard-folder-destination.yml
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/defaults/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/defaults/main.yml
index 8b9c9348a..4abf9bb43 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/defaults/main.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/defaults/main.yml
@@ -1,7 +1,5 @@
---
-grafana_url: "http://grafana:3000/"
-grafana_username: "admin"
-grafana_password: "admin"
-
-...
+grafana_url: http://grafana:3000/
+grafana_username: admin
+grafana_password: admin
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/runme.sh b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/runme.sh
new file mode 100755
index 000000000..867afb0d3
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/runme.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+set -eux
+
+ansible-playbook site.yml
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/site.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/site.yml
new file mode 100644
index 000000000..c8374dcdd
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/site.yml
@@ -0,0 +1,6 @@
+---
+- name: Run tests for grafana_datasource
+ hosts: localhost
+ tasks:
+ - ansible.builtin.include_role:
+ name: ../../grafana_datasource
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/azure.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/azure.yml
index a96691893..0dbd94963 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/azure.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/azure.yml
@@ -1,11 +1,12 @@
+---
- name: Create azure datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-azure
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
- org_id: '1'
+ grafana_password: "{{ grafana_password }}"
+ org_id: "1"
ds_type: grafana-azure-monitor-datasource
ds_url: http://example.com
azure_client: client1
@@ -13,38 +14,38 @@
azure_secret: secret1
azure_cloud: azuremonitor
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - "result.msg == 'Datasource datasource-azure created'"
- - result.datasource.access == 'proxy'
- - result.datasource.basicAuth == false
- - result.datasource.database == ''
- - result.datasource.isDefault == false
- - result.datasource.jsonData.clientId == 'client1'
- - result.datasource.jsonData.cloudName == 'azuremonitor'
- - result.datasource.jsonData.tenantId == 'tenant1'
- - result.datasource.jsonData.tlsAuth == false
- - result.datasource.jsonData.tlsAuthWithCACert == false
- - result.datasource.name == 'datasource-azure'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'grafana-azure-monitor-datasource'
- - result.datasource.url == 'http://example.com'
- - result.datasource.user == ''
- - result.datasource.withCredentials == false
+ - result.changed
+ - result.msg == 'Datasource datasource-azure created'
+ - result.datasource.access == 'proxy'
+ - result.datasource.basicAuth == false
+ - result.datasource.database == ''
+ - result.datasource.isDefault == false
+ - result.datasource.jsonData.clientId == 'client1'
+ - result.datasource.jsonData.cloudName == 'azuremonitor'
+ - result.datasource.jsonData.tenantId == 'tenant1'
+ - result.datasource.jsonData.tlsAuth == false
+ - result.datasource.jsonData.tlsAuthWithCACert == false
+ - result.datasource.name == 'datasource-azure'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'grafana-azure-monitor-datasource'
+ - result.datasource.url == 'http://example.com'
+ - result.datasource.user == ''
+ - result.datasource.withCredentials == false
- name: Check azure datasource creation idempotency
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-azure
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
- org_id: '1'
+ grafana_password: "{{ grafana_password }}"
+ org_id: "1"
ds_type: grafana-azure-monitor-datasource
ds_url: http://example.com
azure_client: client1
@@ -52,37 +53,37 @@
azure_secret: secret1
azure_cloud: azuremonitor
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
- - result.datasource.access == 'proxy'
- - result.datasource.basicAuth == false
- - result.datasource.database == ''
- - result.datasource.isDefault == false
- - result.datasource.jsonData.clientId == 'client1'
- - result.datasource.jsonData.cloudName == 'azuremonitor'
- - result.datasource.jsonData.tenantId == 'tenant1'
- - result.datasource.jsonData.tlsAuth == false
- - result.datasource.jsonData.tlsAuthWithCACert == false
- - result.datasource.name == 'datasource-azure'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'grafana-azure-monitor-datasource'
- - result.datasource.url == 'http://example.com'
- - result.datasource.user == ''
- - result.datasource.withCredentials == false
+ - not result.changed
+ - result.datasource.access == 'proxy'
+ - result.datasource.basicAuth == false
+ - result.datasource.database == ''
+ - result.datasource.isDefault == false
+ - result.datasource.jsonData.clientId == 'client1'
+ - result.datasource.jsonData.cloudName == 'azuremonitor'
+ - result.datasource.jsonData.tenantId == 'tenant1'
+ - result.datasource.jsonData.tlsAuth == false
+ - result.datasource.jsonData.tlsAuthWithCACert == false
+ - result.datasource.name == 'datasource-azure'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'grafana-azure-monitor-datasource'
+ - result.datasource.url == 'http://example.com'
+ - result.datasource.user == ''
+ - result.datasource.withCredentials == false
- name: Delete azure datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-azure
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
- org_id: '1'
+ grafana_password: "{{ grafana_password }}"
+ org_id: "1"
ds_type: grafana-azure-monitor-datasource
ds_url: http://example.com
azure_client: client1
@@ -91,22 +92,22 @@
azure_cloud: azuremonitor
state: absent
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - "result.msg == 'Datasource datasource-azure deleted.'"
+ - result.changed
+ - result.msg == 'Datasource datasource-azure deleted.'
- name: Delete azure datasource (idempotency)
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-azure
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
- org_id: '1'
+ grafana_password: "{{ grafana_password }}"
+ org_id: "1"
ds_type: grafana-azure-monitor-datasource
ds_url: http://example.com
azure_client: client1
@@ -115,9 +116,9 @@
azure_cloud: azuremonitor
state: absent
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
+ - not result.changed
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/cloudwatch.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/cloudwatch.yml
index 50268ea8f..79408b68b 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/cloudwatch.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/cloudwatch.yml
@@ -1,11 +1,12 @@
+---
- name: Create cloudwatch datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-cloudwatch
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
- org_id: '1'
+ grafana_password: "{{ grafana_password }}"
+ org_id: "1"
ds_type: cloudwatch
ds_url: http://monitoring.us-west-1.amazonaws.com
aws_auth_type: keys
@@ -14,38 +15,38 @@
aws_secret_key: mel10n
aws_custom_metrics_namespaces: n1,n2
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - "result.msg == 'Datasource datasource-cloudwatch created'"
- - result.datasource.access == 'proxy'
- - result.datasource.basicAuth == false
- - result.datasource.database == ''
- - result.datasource.isDefault == false
- - result.datasource.jsonData.authType == 'keys'
- - result.datasource.jsonData.customMetricsNamespaces == 'n1,n2'
- - result.datasource.jsonData.defaultRegion == 'us-west-1'
- - result.datasource.jsonData.tlsAuth == false
- - result.datasource.jsonData.tlsAuthWithCACert == false
- - result.datasource.name == 'datasource-cloudwatch'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'cloudwatch'
- - result.datasource.url == 'http://monitoring.us-west-1.amazonaws.com'
- - result.datasource.user == ''
- - result.datasource.withCredentials == false
+ - result.changed
+ - result.msg == 'Datasource datasource-cloudwatch created'
+ - result.datasource.access == 'proxy'
+ - result.datasource.basicAuth == false
+ - result.datasource.database == ''
+ - result.datasource.isDefault == false
+ - result.datasource.jsonData.authType == 'keys'
+ - result.datasource.jsonData.customMetricsNamespaces == 'n1,n2'
+ - result.datasource.jsonData.defaultRegion == 'us-west-1'
+ - result.datasource.jsonData.tlsAuth == false
+ - result.datasource.jsonData.tlsAuthWithCACert == false
+ - result.datasource.name == 'datasource-cloudwatch'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'cloudwatch'
+ - result.datasource.url == 'http://monitoring.us-west-1.amazonaws.com'
+ - result.datasource.user == ''
+ - result.datasource.withCredentials == false
- name: Check cloudwatch datasource creation idempotency
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-cloudwatch
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: cloudwatch
ds_url: http://monitoring.us-west-1.amazonaws.com
aws_auth_type: keys
@@ -54,58 +55,58 @@
aws_secret_key: mel10n
aws_custom_metrics_namespaces: n1,n2
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
- - result.datasource.access == 'proxy'
- - result.datasource.basicAuth == false
- - result.datasource.database == ''
- - result.datasource.isDefault == false
- - result.datasource.jsonData.authType == 'keys'
- - result.datasource.jsonData.customMetricsNamespaces == 'n1,n2'
- - result.datasource.jsonData.defaultRegion == 'us-west-1'
- - result.datasource.jsonData.tlsAuth == false
- - result.datasource.jsonData.tlsAuthWithCACert == false
- - result.datasource.name == 'datasource-cloudwatch'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'cloudwatch'
- - result.datasource.url == 'http://monitoring.us-west-1.amazonaws.com'
- - result.datasource.user == ''
- - result.datasource.withCredentials == false
+ - not result.changed
+ - result.datasource.access == 'proxy'
+ - result.datasource.basicAuth == false
+ - result.datasource.database == ''
+ - result.datasource.isDefault == false
+ - result.datasource.jsonData.authType == 'keys'
+ - result.datasource.jsonData.customMetricsNamespaces == 'n1,n2'
+ - result.datasource.jsonData.defaultRegion == 'us-west-1'
+ - result.datasource.jsonData.tlsAuth == false
+ - result.datasource.jsonData.tlsAuthWithCACert == false
+ - result.datasource.name == 'datasource-cloudwatch'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'cloudwatch'
+ - result.datasource.url == 'http://monitoring.us-west-1.amazonaws.com'
+ - result.datasource.user == ''
+ - result.datasource.withCredentials == false
- name: Delete cloudwatch datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-cloudwatch
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
state: absent
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - "result.msg == 'Datasource datasource-cloudwatch deleted.'"
+ - result.changed
+ - result.msg == 'Datasource datasource-cloudwatch deleted.'
- name: Delete cloudwatch datasource (idempotency)
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-cloudwatch
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
state: absent
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
+ - not result.changed
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/elastic.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/elastic.yml
index 73b258426..ff05b93f5 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/elastic.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/elastic.yml
@@ -1,313 +1,313 @@
---
- name: Create elasticsearch datasource with legacy elasticsearch format
register: result
- grafana_datasource:
- name: "datasource/elasticLegacy"
- uid: "myuid"
+ community.grafana.grafana_datasource:
+ name: datasource/elasticLegacy
+ uid: myuid
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: elasticsearch
ds_url: https://elastic.company.com:9200
- database: '[logstash_]YYYY.MM.DD'
+ database: "[logstash_]YYYY.MM.DD"
basic_auth_user: grafana
- basic_auth_password: '******'
- time_field: '@timestamp'
+ basic_auth_password: "******"
+ time_field: "@timestamp"
time_interval: 1m
interval: Daily
es_version: 56
max_concurrent_shard_requests: 42
tls_ca_cert: /etc/ssl/certs/ca.pem
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - result.datasource.basicAuth
- - result.datasource.basicAuthUser == 'grafana'
- - result.datasource.access == 'proxy'
- - result.datasource.database == '[logstash_]YYYY.MM.DD'
- - not result.datasource.isDefault
- - result.datasource.jsonData.esVersion == 56
- - result.datasource.jsonData.interval == 'Daily'
- - result.datasource.jsonData.maxConcurrentShardRequests == 42
- - result.datasource.jsonData.timeField == '@timestamp'
- - not result.datasource.jsonData.tlsAuth
- - result.datasource.jsonData.tlsAuthWithCACert
- - result.datasource.name == 'datasource/elasticLegacy'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'elasticsearch'
- - result.datasource.url == 'https://elastic.company.com:9200'
- - result.datasource.user == ''
- - not result.datasource.withCredentials
- - "result.msg == 'Datasource datasource/elasticLegacy created'"
+ - result.changed
+ - result.datasource.basicAuth
+ - result.datasource.basicAuthUser == 'grafana'
+ - result.datasource.access == 'proxy'
+ - result.datasource.database == '[logstash_]YYYY.MM.DD'
+ - not result.datasource.isDefault
+ - result.datasource.jsonData.esVersion == 56
+ - result.datasource.jsonData.interval == 'Daily'
+ - result.datasource.jsonData.maxConcurrentShardRequests == 42
+ - result.datasource.jsonData.timeField == '@timestamp'
+ - not result.datasource.jsonData.tlsAuth
+ - result.datasource.jsonData.tlsAuthWithCACert
+ - result.datasource.name == 'datasource/elasticLegacy'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'elasticsearch'
+ - result.datasource.url == 'https://elastic.company.com:9200'
+ - result.datasource.user == ''
+ - not result.datasource.withCredentials
+ - result.msg == 'Datasource datasource/elasticLegacy created'
- name: Create elasticsearch datasource with new elsaticsearch version format
register: result
- grafana_datasource:
- name: "datasource/elastic"
+ community.grafana.grafana_datasource:
+ name: datasource/elastic
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: elasticsearch
ds_url: https://elastic.company.com:9200
- database: '[logstash_]YYYY.MM.DD'
+ database: "[logstash_]YYYY.MM.DD"
basic_auth_user: grafana
- basic_auth_password: '******'
- time_field: '@timestamp'
+ basic_auth_password: "******"
+ time_field: "@timestamp"
time_interval: 1m
interval: Daily
- es_version: "7.10+"
+ es_version: 7.10+
max_concurrent_shard_requests: 42
tls_ca_cert: /etc/ssl/certs/ca.pem
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - result.datasource.basicAuth
- - result.datasource.basicAuthUser == 'grafana'
- - result.datasource.access == 'proxy'
- - result.datasource.database == '[logstash_]YYYY.MM.DD'
- - not result.datasource.isDefault
- - result.datasource.jsonData.esVersion == "7.10.0"
- - result.datasource.jsonData.interval == 'Daily'
- - result.datasource.jsonData.maxConcurrentShardRequests == 42
- - result.datasource.jsonData.timeField == '@timestamp'
- - not result.datasource.jsonData.tlsAuth
- - result.datasource.jsonData.tlsAuthWithCACert
- - result.datasource.name == 'datasource/elastic'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'elasticsearch'
- - result.datasource.url == 'https://elastic.company.com:9200'
- - result.datasource.user == ''
- - not result.datasource.withCredentials
- - "result.msg == 'Datasource datasource/elastic created'"
+ - result.changed
+ - result.datasource.basicAuth
+ - result.datasource.basicAuthUser == 'grafana'
+ - result.datasource.access == 'proxy'
+ - result.datasource.database == '[logstash_]YYYY.MM.DD'
+ - not result.datasource.isDefault
+ - result.datasource.jsonData.esVersion == "7.10.0"
+ - result.datasource.jsonData.interval == 'Daily'
+ - result.datasource.jsonData.maxConcurrentShardRequests == 42
+ - result.datasource.jsonData.timeField == '@timestamp'
+ - not result.datasource.jsonData.tlsAuth
+ - result.datasource.jsonData.tlsAuthWithCACert
+ - result.datasource.name == 'datasource/elastic'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'elasticsearch'
+ - result.datasource.url == 'https://elastic.company.com:9200'
+ - result.datasource.user == ''
+ - not result.datasource.withCredentials
+ - result.msg == 'Datasource datasource/elastic created'
- name: Check elasticsearch datasource creation idempotency
register: result
- grafana_datasource:
- name: "datasource/elastic"
+ community.grafana.grafana_datasource:
+ name: datasource/elastic
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: elasticsearch
ds_url: https://elastic.company.com:9200
- database: '[logstash_]YYYY.MM.DD'
+ database: "[logstash_]YYYY.MM.DD"
basic_auth_user: grafana
- basic_auth_password: '******'
- time_field: '@timestamp'
+ basic_auth_password: "******"
+ time_field: "@timestamp"
time_interval: 1m
interval: Daily
- es_version: "7.10+"
+ es_version: 7.10+
max_concurrent_shard_requests: 42
tls_ca_cert: /etc/ssl/certs/ca.pem
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
- - result.datasource.basicAuth
- - result.datasource.basicAuthUser == 'grafana'
- - result.datasource.access == 'proxy'
- - result.datasource.database == '[logstash_]YYYY.MM.DD'
- - not result.datasource.isDefault
- - result.datasource.jsonData.esVersion == '7.10.0'
- - result.datasource.jsonData.interval == 'Daily'
- - result.datasource.jsonData.maxConcurrentShardRequests == 42
- - result.datasource.jsonData.timeField == '@timestamp'
- - not result.datasource.jsonData.tlsAuth
- - result.datasource.jsonData.tlsAuthWithCACert
- - result.datasource.name == 'datasource/elastic'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'elasticsearch'
- - result.datasource.url == 'https://elastic.company.com:9200'
- - result.datasource.user == ''
- - not result.datasource.withCredentials
+ - not result.changed
+ - result.datasource.basicAuth
+ - result.datasource.basicAuthUser == 'grafana'
+ - result.datasource.access == 'proxy'
+ - result.datasource.database == '[logstash_]YYYY.MM.DD'
+ - not result.datasource.isDefault
+ - result.datasource.jsonData.esVersion == '7.10.0'
+ - result.datasource.jsonData.interval == 'Daily'
+ - result.datasource.jsonData.maxConcurrentShardRequests == 42
+ - result.datasource.jsonData.timeField == '@timestamp'
+ - not result.datasource.jsonData.tlsAuth
+ - result.datasource.jsonData.tlsAuthWithCACert
+ - result.datasource.name == 'datasource/elastic'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'elasticsearch'
+ - result.datasource.url == 'https://elastic.company.com:9200'
+ - result.datasource.user == ''
+ - not result.datasource.withCredentials
-- name: update elasticsearch datasource creation
+- name: Update elasticsearch datasource creation
register: result
- grafana_datasource:
- name: "datasource/elastic"
+ community.grafana.grafana_datasource:
+ name: datasource/elastic
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: elasticsearch
ds_url: https://elastic.example.com:9200
- database: '[logstash_]YYYY.MM.DD'
+ database: "[logstash_]YYYY.MM.DD"
basic_auth_user: grafana
- basic_auth_password: '******'
- time_field: '@timestamp'
+ basic_auth_password: "******"
+ time_field: "@timestamp"
time_interval: 1m
interval: Daily
- es_version: "7.10+"
+ es_version: 7.10+
max_concurrent_shard_requests: 42
tls_ca_cert: /etc/ssl/certs/ca.pem
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - result.datasource.basicAuth
- - result.datasource.basicAuthUser == 'grafana'
- - result.datasource.access == 'proxy'
- - result.datasource.database == '[logstash_]YYYY.MM.DD'
- - not result.datasource.isDefault
- - result.datasource.jsonData.esVersion == '7.10.0'
- - result.datasource.jsonData.interval == 'Daily'
- - result.datasource.jsonData.maxConcurrentShardRequests == 42
- - result.datasource.jsonData.timeField == '@timestamp'
- - not result.datasource.jsonData.tlsAuth
- - result.datasource.jsonData.tlsAuthWithCACert
- - result.datasource.name == 'datasource/elastic'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'elasticsearch'
- - result.datasource.url == 'https://elastic.example.com:9200'
- - result.datasource.user == ''
- - not result.datasource.withCredentials
+ - result.changed
+ - result.datasource.basicAuth
+ - result.datasource.basicAuthUser == 'grafana'
+ - result.datasource.access == 'proxy'
+ - result.datasource.database == '[logstash_]YYYY.MM.DD'
+ - not result.datasource.isDefault
+ - result.datasource.jsonData.esVersion == '7.10.0'
+ - result.datasource.jsonData.interval == 'Daily'
+ - result.datasource.jsonData.maxConcurrentShardRequests == 42
+ - result.datasource.jsonData.timeField == '@timestamp'
+ - not result.datasource.jsonData.tlsAuth
+ - result.datasource.jsonData.tlsAuthWithCACert
+ - result.datasource.name == 'datasource/elastic'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'elasticsearch'
+ - result.datasource.url == 'https://elastic.example.com:9200'
+ - result.datasource.user == ''
+ - not result.datasource.withCredentials
-- name: update elasticsearch datasource (ignoring secureJsonData)
+- name: Update elasticsearch datasource (ignoring secureJsonData)
register: result
- grafana_datasource:
- name: "datasource/elastic"
+ community.grafana.grafana_datasource:
+ name: datasource/elastic
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: elasticsearch
ds_url: https://elastic.example.com:9200
- database: '[logstash_]YYYY.MM.DD'
+ database: "[logstash_]YYYY.MM.DD"
basic_auth_user: grafana
- basic_auth_password: '******'
- time_field: '@timestamp'
+ basic_auth_password: "******"
+ time_field: "@timestamp"
time_interval: 1m
interval: Daily
- es_version: "7.10+"
+ es_version: 7.10+
max_concurrent_shard_requests: 42
tls_ca_cert: /etc/ssl/certs/ca.pem
enforce_secure_data: false
additional_json_data:
- nonSecureTest: "nonsecure"
+ nonSecureTest: nonsecure
additional_secure_json_data:
- secureTest: "secure"
+ secureTest: secure
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - result.datasource.basicAuth
- - result.datasource.basicAuthUser == 'grafana'
- - result.datasource.access == 'proxy'
- - result.datasource.database == '[logstash_]YYYY.MM.DD'
- - not result.datasource.isDefault
- - result.datasource.jsonData.esVersion == '7.10.0'
- - result.datasource.jsonData.interval == 'Daily'
- - result.datasource.jsonData.maxConcurrentShardRequests == 42
- - result.datasource.jsonData.timeField == '@timestamp'
- - not result.datasource.jsonData.tlsAuth
- - result.datasource.jsonData.tlsAuthWithCACert
- - result.datasource.name == 'datasource/elastic'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'elasticsearch'
- - result.datasource.url == 'https://elastic.example.com:9200'
- - result.datasource.user == ''
- - not result.datasource.withCredentials
- - result.datasource.jsonData.nonSecureTest == 'nonsecure'
+ - result.changed
+ - result.datasource.basicAuth
+ - result.datasource.basicAuthUser == 'grafana'
+ - result.datasource.access == 'proxy'
+ - result.datasource.database == '[logstash_]YYYY.MM.DD'
+ - not result.datasource.isDefault
+ - result.datasource.jsonData.esVersion == '7.10.0'
+ - result.datasource.jsonData.interval == 'Daily'
+ - result.datasource.jsonData.maxConcurrentShardRequests == 42
+ - result.datasource.jsonData.timeField == '@timestamp'
+ - not result.datasource.jsonData.tlsAuth
+ - result.datasource.jsonData.tlsAuthWithCACert
+ - result.datasource.name == 'datasource/elastic'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'elasticsearch'
+ - result.datasource.url == 'https://elastic.example.com:9200'
+ - result.datasource.user == ''
+ - not result.datasource.withCredentials
+ - result.datasource.jsonData.nonSecureTest == 'nonsecure'
-- name: update elasticsearch datasource (including secureJsonData)
+- name: Update elasticsearch datasource (including secureJsonData)
register: result
- grafana_datasource:
- name: "datasource/elastic"
+ community.grafana.grafana_datasource:
+ name: datasource/elastic
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: elasticsearch
ds_url: https://elastic.example.com:9200
- database: '[logstash_]YYYY.MM.DD'
+ database: "[logstash_]YYYY.MM.DD"
basic_auth_user: grafana
- basic_auth_password: '******'
- time_field: '@timestamp'
+ basic_auth_password: "******"
+ time_field: "@timestamp"
time_interval: 1m
interval: Daily
- es_version: "7.10+"
+ es_version: 7.10+
max_concurrent_shard_requests: 42
tls_ca_cert: /etc/ssl/certs/ca.pem
enforce_secure_data: true
additional_json_data:
- nonSecureTest: "nonsecure"
+ nonSecureTest: nonsecure
additional_secure_json_data:
- secureTest: "secure"
+ secureTest: secure
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - result.datasource.basicAuth
- - result.datasource.basicAuthUser == 'grafana'
- - result.datasource.access == 'proxy'
- - result.datasource.database == '[logstash_]YYYY.MM.DD'
- - not result.datasource.isDefault
- - result.datasource.jsonData.esVersion == '7.10.0'
- - result.datasource.jsonData.interval == 'Daily'
- - result.datasource.jsonData.maxConcurrentShardRequests == 42
- - result.datasource.jsonData.timeField == '@timestamp'
- - not result.datasource.jsonData.tlsAuth
- - result.datasource.jsonData.tlsAuthWithCACert
- - result.datasource.name == 'datasource/elastic'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'elasticsearch'
- - result.datasource.url == 'https://elastic.example.com:9200'
- - result.datasource.user == ''
- - not result.datasource.withCredentials
- - result.datasource.jsonData.nonSecureTest == 'nonsecure'
- - result.datasource.secureJsonFields.secureTest == true
- - result.diff.after.secureJsonData is defined
+ - result.changed
+ - result.datasource.basicAuth
+ - result.datasource.basicAuthUser == 'grafana'
+ - result.datasource.access == 'proxy'
+ - result.datasource.database == '[logstash_]YYYY.MM.DD'
+ - not result.datasource.isDefault
+ - result.datasource.jsonData.esVersion == '7.10.0'
+ - result.datasource.jsonData.interval == 'Daily'
+ - result.datasource.jsonData.maxConcurrentShardRequests == 42
+ - result.datasource.jsonData.timeField == '@timestamp'
+ - not result.datasource.jsonData.tlsAuth
+ - result.datasource.jsonData.tlsAuthWithCACert
+ - result.datasource.name == 'datasource/elastic'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'elasticsearch'
+ - result.datasource.url == 'https://elastic.example.com:9200'
+ - result.datasource.user == ''
+ - not result.datasource.withCredentials
+ - result.datasource.jsonData.nonSecureTest == 'nonsecure'
+ - result.datasource.secureJsonFields.secureTest == true
+ - result.diff.after.secureJsonData is defined
- name: Delete elasticsearch datasource
register: result
- grafana_datasource:
- name: "datasource/elastic"
+ community.grafana.grafana_datasource:
+ name: datasource/elastic
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: absent
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
+ - result.changed
- name: Delete elasticsearch datasource (idempotency)
register: result
- grafana_datasource:
- name: "datasource/elastic"
+ community.grafana.grafana_datasource:
+ name: datasource/elastic
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: absent
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
+ - not result.changed
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/errors.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/errors.yml
index 731a19d8f..779b4724d 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/errors.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/errors.yml
@@ -1,18 +1,18 @@
---
- name: Create datasource without `ds_type` and `ds_url` (expect failure)
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-postgres
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
ignore_errors: true
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
- - result.failed
- - "result.msg == 'state is present but all of the following are missing: ds_type, ds_url'"
+ - not result.changed
+ - result.failed
+ - "result.msg == 'state is present but all of the following are missing: ds_type, ds_url'"
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/influx.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/influx.yml
index da61833f6..7952bec6b 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/influx.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/influx.yml
@@ -1,88 +1,89 @@
+---
- name: Create influxdb datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-influxdb
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: influxdb
ds_url: https://influx.company.com:8086
database: telegraf
- time_interval: '>10s'
+ time_interval: ">10s"
tls_ca_cert: /etc/ssl/certs/ca.pem
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - "result.msg == 'Datasource datasource-influxdb created'"
+ - result.changed
+ - result.msg == 'Datasource datasource-influxdb created'
- name: Check influxdb datasource creation idempotency
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-influxdb
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: influxdb
ds_url: https://influx.company.com:8086
database: telegraf
- time_interval: '>10s'
+ time_interval: ">10s"
tls_ca_cert: /etc/ssl/certs/ca.pem
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
- - result.datasource.basicAuth == false
- - result.datasource.access == 'proxy'
- - result.datasource.database == 'telegraf'
- - result.datasource.isDefault == false
- - result.datasource.jsonData.timeInterval == '>10s'
- - result.datasource.jsonData.tlsAuth == false
- - result.datasource.jsonData.tlsAuthWithCACert
- - result.datasource.name == 'datasource-influxdb'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'influxdb'
- - result.datasource.url == 'https://influx.company.com:8086'
- - result.datasource.user == ''
- - result.datasource.withCredentials == false
+ - not result.changed
+ - result.datasource.basicAuth == false
+ - result.datasource.access == 'proxy'
+ - result.datasource.database == 'telegraf'
+ - result.datasource.isDefault == false
+ - result.datasource.jsonData.timeInterval == '>10s'
+ - result.datasource.jsonData.tlsAuth == false
+ - result.datasource.jsonData.tlsAuthWithCACert
+ - result.datasource.name == 'datasource-influxdb'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'influxdb'
+ - result.datasource.url == 'https://influx.company.com:8086'
+ - result.datasource.user == ''
+ - result.datasource.withCredentials == false
- name: Delete influxdb datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-influxdb
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: absent
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
+ - result.changed
- name: Delete influxdb datasource (idempotency)
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-influxdb
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: absent
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
+ - not result.changed
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/issues.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/issues.yml
index f80677d8d..3b4df5a71 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/issues.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/issues.yml
@@ -1,46 +1,43 @@
---
-
-- name: test datasource name with slash
+- name: Test datasource name with slash
register: result
- grafana_datasource:
- name: "datasource/elastic"
+ community.grafana.grafana_datasource:
+ name: datasource/elastic
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: elasticsearch
ds_url: https://elastic.company.com:9200
- database: '[logstash_]YYYY.MM.DD'
+ database: "[logstash_]YYYY.MM.DD"
basic_auth_user: grafana
- basic_auth_password: '******'
- time_field: '@timestamp'
+ basic_auth_password: "******"
+ time_field: "@timestamp"
time_interval: 1m
interval: Daily
es_version: 56
max_concurrent_shard_requests: 42
tls_ca_cert: /etc/ssl/certs/ca.pem
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - result.datasource.basicAuth
- - result.datasource.basicAuthUser == 'grafana'
- - result.datasource.access == 'proxy'
- - result.datasource.database == '[logstash_]YYYY.MM.DD'
- - not result.datasource.isDefault
- - result.datasource.jsonData.esVersion == 56
- - result.datasource.jsonData.interval == 'Daily'
- - result.datasource.jsonData.maxConcurrentShardRequests == 42
- - result.datasource.jsonData.timeField == '@timestamp'
- - not result.datasource.jsonData.tlsAuth
- - not result.datasource.jsonData.tlsAuthWithCACert
- - result.datasource.name == 'datasource/elastic'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'elasticsearch'
- - result.datasource.url == 'https://elastic.company.com:9200'
- - result.datasource.user == ''
- - not result.datasource.withCredentials
- - "result.msg == 'Datasource datasource/elastic created'"
-
-...
+ - result.changed
+ - result.datasource.basicAuth
+ - result.datasource.basicAuthUser == 'grafana'
+ - result.datasource.access == 'proxy'
+ - result.datasource.database == '[logstash_]YYYY.MM.DD'
+ - not result.datasource.isDefault
+ - result.datasource.jsonData.esVersion == 56
+ - result.datasource.jsonData.interval == 'Daily'
+ - result.datasource.jsonData.maxConcurrentShardRequests == 42
+ - result.datasource.jsonData.timeField == '@timestamp'
+ - not result.datasource.jsonData.tlsAuth
+ - not result.datasource.jsonData.tlsAuthWithCACert
+ - result.datasource.name == 'datasource/elastic'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'elasticsearch'
+ - result.datasource.url == 'https://elastic.company.com:9200'
+ - result.datasource.user == ''
+ - not result.datasource.withCredentials
+ - result.msg == 'Datasource datasource/elastic created'
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/loki.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/loki.yml
index 68eca9802..a501b99d2 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/loki.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/loki.yml
@@ -1,82 +1,83 @@
+---
- name: Create loki datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-loki
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
- org_id: '1'
+ grafana_password: "{{ grafana_password }}"
+ org_id: "1"
ds_type: loki
ds_url: https://loki.company.com:3100
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - "result.msg == 'Datasource datasource-loki created'"
+ - result.changed
+ - result.msg == 'Datasource datasource-loki created'
- name: Check loki datasource creation idempotency
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-loki
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: loki
ds_url: https://loki.company.com:3100
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
- - result.datasource.basicAuth == false
- - result.datasource.access == 'proxy'
- - result.datasource.database == ''
- - result.datasource.isDefault == false
- - result.datasource.jsonData.tlsAuth == false
- - result.datasource.jsonData.tlsAuthWithCACert == false
- - result.datasource.name == 'datasource-loki'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'loki'
- - result.datasource.url == 'https://loki.company.com:3100'
- - result.datasource.user == ''
- - result.datasource.withCredentials == false
+ - not result.changed
+ - result.datasource.basicAuth == false
+ - result.datasource.access == 'proxy'
+ - result.datasource.database == ''
+ - result.datasource.isDefault == false
+ - result.datasource.jsonData.tlsAuth == false
+ - result.datasource.jsonData.tlsAuthWithCACert == false
+ - result.datasource.name == 'datasource-loki'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'loki'
+ - result.datasource.url == 'https://loki.company.com:3100'
+ - result.datasource.user == ''
+ - result.datasource.withCredentials == false
- name: Delete loki datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-loki
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
state: absent
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - "result.msg == 'Datasource datasource-loki deleted.'"
+ - result.changed
+ - result.msg == 'Datasource datasource-loki deleted.'
- name: Delete loki datasource (idempotency)
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-loki
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
state: absent
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
+ - not result.changed
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/main.yml
index b5798e9a8..0b3ea4cd6 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/main.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/main.yml
@@ -1,16 +1,24 @@
---
-
- block:
- - include: errors.yml
- - include: elastic.yml
- - include: influx.yml
- - include: postgres.yml
- - include: cloudwatch.yml
- - include: thruk.yml
- - include: loki.yml
- - include: zabbix.yml
- - include: redis.yml
- - include: azure.yml
- - include: uid.yml
-
-...
+ - ansible.builtin.include_tasks:
+ file: errors.yml
+ - ansible.builtin.include_tasks:
+ file: elastic.yml
+ - ansible.builtin.include_tasks:
+ file: influx.yml
+ - ansible.builtin.include_tasks:
+ file: postgres.yml
+ - ansible.builtin.include_tasks:
+ file: cloudwatch.yml
+ - ansible.builtin.include_tasks:
+ file: thruk.yml
+ - ansible.builtin.include_tasks:
+ file: loki.yml
+ - ansible.builtin.include_tasks:
+ file: zabbix.yml
+ - ansible.builtin.include_tasks:
+ file: redis.yml
+ - ansible.builtin.include_tasks:
+ file: azure.yml
+ - ansible.builtin.include_tasks:
+ file: uid.yml
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/postgres.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/postgres.yml
index 80221f012..b07bc752b 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/postgres.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/postgres.yml
@@ -1,11 +1,12 @@
+---
- name: Create postgres datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-postgres
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: postgres
ds_url: postgres.company.com:5432
database: db
@@ -15,22 +16,22 @@
additional_json_data:
timescaledb: true
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - "result.msg == 'Datasource datasource-postgres created'"
+ - result.changed
+ - result.msg == 'Datasource datasource-postgres created'
- name: Check postgres datasource creation idempotency
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-postgres
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: postgres
ds_url: postgres.company.com:5432
database: db
@@ -40,54 +41,54 @@
additional_json_data:
timescaledb: true
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
- - result.datasource.basicAuth == false
- - result.datasource.database == 'db'
- - result.datasource.isDefault == false
- - result.datasource.jsonData.sslmode == 'verify-full'
- - result.datasource.jsonData.tlsAuth == false
- - result.datasource.jsonData.tlsAuthWithCACert == false
- - result.datasource.jsonData.timescaledb == true
- - result.datasource.name == 'datasource-postgres'
- - result.datasource.orgId == 1
- - result.datasource.type == 'postgres'
- - result.datasource.url == 'postgres.company.com:5432'
- - result.datasource.user == 'postgres'
- - result.datasource.withCredentials == false
+ - not result.changed
+ - result.datasource.basicAuth == false
+ - result.datasource.database == 'db'
+ - result.datasource.isDefault == false
+ - result.datasource.jsonData.sslmode == 'verify-full'
+ - result.datasource.jsonData.tlsAuth == false
+ - result.datasource.jsonData.tlsAuthWithCACert == false
+ - result.datasource.jsonData.timescaledb == true
+ - result.datasource.name == 'datasource-postgres'
+ - result.datasource.orgId == 1
+ - result.datasource.type == 'postgres'
+ - result.datasource.url == 'postgres.company.com:5432'
+ - result.datasource.user == 'postgres'
+ - result.datasource.withCredentials == false
- name: Delete postgres datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-postgres
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: absent
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
+ - result.changed
- name: Delete postgres datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-postgres
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: absent
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
+ - not result.changed
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/quickwit.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/quickwit.yml
new file mode 100644
index 000000000..8221dcb42
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/quickwit.yml
@@ -0,0 +1,137 @@
+---
+- name: Create Quickwit datasource
+ register: result
+ community.grafana.grafana_datasource:
+ name: Quickwit
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ org_id: "1"
+ ds_type: quickwit-quickwit-datasource
+ ds_url: http://localhost:7280/api/v1
+ additional_json_data:
+ index: hdfs-logs
+ timeField: timestamp
+ timeOutputFormat: unix_timestamp_secs
+ logMessageField: body
+ logLevelField: severity_text
+
+- ansible.builtin.debug:
+ var: result
+
+- ansible.builtin.assert:
+ that:
+ - result.changed
+ - result.datasource.access == 'proxy'
+ - not result.datasource.isDefault
+ - result.datasource.database == ''
+ - result.datasource.name == 'Quickwit'
+ - result.datasource.orgId == 1
+ - result.datasource.type == 'quickwit-quickwit-datasource'
+ - result.datasource.url == 'http://localhost:7280/api/v1'
+ - result.msg == 'Datasource Quickwit created'
+ - result.datasource.jsonData.index == 'hdfs-logs'
+ - result.datasource.jsonData.timeField == 'timestamp'
+ - result.datasource.jsonData.timeOutputFormat == 'unix_timestamp_secs'
+ - result.datasource.jsonData.logMessageField == 'body'
+ - result.datasource.jsonData.logLevelField == 'severity_text'
+
+- name: Check Quickwit datasource creation (idempotency)
+ register: result
+ community.grafana.grafana_datasource:
+ name: Quickwit
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ org_id: "1"
+ ds_type: quickwit-quickwit-datasource
+ ds_url: http://localhost:7280/api/v1
+ additional_json_data:
+ index: hdfs-logs
+ timeField: timestamp
+ timeOutputFormat: unix_timestamp_secs
+ logMessageField: body
+ logLevelField: severity_text
+
+- ansible.builtin.debug:
+ var: result
+
+- ansible.builtin.assert:
+ that:
+ - not result.changed
+ - result.datasource.access == 'proxy'
+ - not result.datasource.isDefault
+ - result.datasource.database == ''
+ - result.datasource.name == 'Quickwit'
+ - result.datasource.orgId == 1
+ - result.datasource.type == 'quickwit-quickwit-datasource'
+ - result.datasource.url == 'http://localhost:7280/api/v1'
+ - result.msg == 'Datasource Quickwit created'
+ - result.datasource.jsonData.index == 'hdfs-logs'
+ - result.datasource.jsonData.timeField == 'timestamp'
+ - result.datasource.jsonData.timeOutputFormat == 'unix_timestamp_secs'
+ - result.datasource.jsonData.logMessageField == 'body'
+ - result.datasource.jsonData.logLevelField == 'severity_text'
+
+- name: Update Quickwit datasource
+ register: result
+ community.grafana.grafana_datasource:
+ name: Quickwit
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ org_id: "1"
+ ds_type: quickwit-quickwit-datasource
+ ds_url: http://quickwit-url:7280/api/v1
+ additional_json_data:
+ index: hdfs-logs
+ timeField: timestamp
+ timeOutputFormat: unix_timestamp_millis
+ logMessageField: body
+ logLevelField: severity_text
+
+- ansible.builtin.debug:
+ var: result
+
+- ansible.builtin.assert:
+ that:
+ - result.changed
+ - result.datasource.access == 'proxy'
+ - not result.datasource.isDefault
+ - result.datasource.database == ''
+ - result.datasource.name == 'Quickwit'
+ - result.datasource.orgId == 1
+ - result.datasource.type == 'quickwit-quickwit-datasource'
+ - result.datasource.url == 'http://quickwit-url:7280/api/v1'
+ - result.msg == 'Datasource Quickwit created'
+ - result.datasource.jsonData.index == 'hdfs-logs'
+ - result.datasource.jsonData.timeField == 'timestamp'
+ - result.datasource.jsonData.timeOutputFormat == 'unix_timestamp_millis'
+ - result.datasource.jsonData.logMessageField == 'body'
+ - result.datasource.jsonData.logLevelField == 'severity_text'
+
+- name: Delete Quickwit datasource
+ register: result
+ community.grafana.grafana_datasource:
+ name: Quickwit
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - result.changed
+
+- name: Delete Quickwit datasource (idempotency)
+ register: result
+ community.grafana.grafana_datasource:
+ name: Quickwit
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: absent
+
+- ansible.builtin.assert:
+ that:
+ - not result.changed
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/redis.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/redis.yml
index 933695354..dc39be64e 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/redis.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/redis.yml
@@ -1,101 +1,102 @@
+---
- name: Create redis datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-redis
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: redis-datasource
ds_url: https://redis.company.com:6379
time_interval: 1m
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - result.datasource.access == 'proxy'
- - not result.datasource.isDefault
- - result.datasource.name == 'datasource-redis'
- - result.datasource.orgId == 1
- - result.datasource.type == 'redis-datasource'
- - result.datasource.url == 'https://redis.company.com:6379'
- - "result.msg == 'Datasource datasource-redis created'"
+ - result.changed
+ - result.datasource.access == 'proxy'
+ - not result.datasource.isDefault
+ - result.datasource.name == 'datasource-redis'
+ - result.datasource.orgId == 1
+ - result.datasource.type == 'redis-datasource'
+ - result.datasource.url == 'https://redis.company.com:6379'
+ - result.msg == 'Datasource datasource-redis created'
- name: Check redis-datasource datasource creation idempotency
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-redis
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: redis-datasource
ds_url: https://redis.company.com:6379
time_interval: 1m
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
- - result.datasource.access == 'proxy'
- - not result.datasource.isDefault
- - result.datasource.name == 'datasource-redis'
- - result.datasource.orgId == 1
- - result.datasource.type == 'redis-datasource'
- - result.datasource.url == 'https://redis.company.com:6379'
+ - not result.changed
+ - result.datasource.access == 'proxy'
+ - not result.datasource.isDefault
+ - result.datasource.name == 'datasource-redis'
+ - result.datasource.orgId == 1
+ - result.datasource.type == 'redis-datasource'
+ - result.datasource.url == 'https://redis.company.com:6379'
-- name: update redis-datasource datasource creation
+- name: Update redis-datasource datasource creation
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-redis
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: redis-datasource
ds_url: https://redisnew.company.com:6379
time_interval: 1m
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - result.datasource.access == 'proxy'
- - not result.datasource.isDefault
- - result.datasource.name == 'datasource-redis'
- - result.datasource.orgId == 1
- - result.datasource.type == 'redis-datasource'
- - result.datasource.url == 'https://redisnew.company.com:6379'
+ - result.changed
+ - result.datasource.access == 'proxy'
+ - not result.datasource.isDefault
+ - result.datasource.name == 'datasource-redis'
+ - result.datasource.orgId == 1
+ - result.datasource.type == 'redis-datasource'
+ - result.datasource.url == 'https://redisnew.company.com:6379'
-- name: Delete redis-datasource datasource
+- name: Delete redis-datasource datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-redis
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: absent
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
+ - result.changed
- name: Delete redis-datasource datasource (idempotency)
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-redis
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: absent
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
+ - not result.changed
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/tempo.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/tempo.yml
new file mode 100644
index 000000000..51ab52513
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/tempo.yml
@@ -0,0 +1,79 @@
+---
+- name: Create tempo datasource
+ register: result
+ community.grafana.grafana_datasource:
+ name: datasource-tempo
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ org_id: "1"
+ ds_type: tempo
+ ds_url: tempo.company.com:3100
+
+- ansible.builtin.debug:
+ var: result
+
+- ansible.builtin.assert:
+ that:
+ - result.changed
+ - result.msg == 'Datasource datasource-tempo created'
+
+- name: Check tempo datasource creation idempotency
+ register: result
+ community.grafana.grafana_datasource:
+ name: datasource-tempo
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ org_id: "1"
+ ds_type: tempo
+ ds_url: tempo.company.com:3100
+
+- ansible.builtin.debug:
+ var: result
+
+- ansible.builtin.assert:
+ that:
+ - not result.changed
+ - result.datasource.basicAuth == false
+ - result.datasource.isDefault == false
+ - result.datasource.jsonData.tlsAuth == false
+ - result.datasource.jsonData.tlsAuthWithCACert == false
+ - result.datasource.secureJsonFields.httpHeaderValue1 == true
+ - result.datasource.name == 'datasource-tempo'
+ - result.datasource.orgId == 1
+ - result.datasource.type == 'tempo'
+ - result.datasource.url == 'tempo.company.com:3100'
+ - result.datasource.withCredentials == false
+
+- name: Delete tempo datasource
+ register: result
+ community.grafana.grafana_datasource:
+ name: datasource-tempo
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: absent
+
+- ansible.builtin.debug:
+ var: result
+
+- ansible.builtin.assert:
+ that:
+ - result.changed
+
+- name: Delete tempo datasource
+ register: result
+ community.grafana.grafana_datasource:
+ name: datasource-tempo
+ grafana_url: "{{ grafana_url }}"
+ grafana_user: "{{ grafana_username }}"
+ grafana_password: "{{ grafana_password }}"
+ state: absent
+
+- ansible.builtin.debug:
+ var: result
+
+- ansible.builtin.assert:
+ that:
+ - not result.changed
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/thruk.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/thruk.yml
index 3ecc92d94..74f7c4dfa 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/thruk.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/thruk.yml
@@ -1,78 +1,79 @@
+---
- name: Create thruk datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-thruk
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
org_id: "1"
ds_type: sni-thruk-datasource
- ds_url: "https://thruk.company.com/sitename/thruk"
- tls_skip_verify: yes
- validate_certs: no
+ ds_url: https://thruk.company.com/sitename/thruk
+ tls_skip_verify: true
+ validate_certs: false
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - "result.msg == 'Datasource datasource-thruk created'"
+ - result.changed
+ - result.msg == 'Datasource datasource-thruk created'
- name: Check thruk datasource creation idempotency
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-thruk
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: sni-thruk-datasource
- ds_url: "https://thruk.company.com/sitename/thruk"
- tls_skip_verify: yes
- validate_certs: no
+ ds_url: https://thruk.company.com/sitename/thruk
+ tls_skip_verify: true
+ validate_certs: false
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
- - result.datasource.basicAuth == false
- - result.datasource.access == 'proxy'
- - result.datasource.isDefault == false
- - result.datasource.jsonData.tlsAuth == false
- - result.datasource.jsonData.tlsAuthWithCACert == false
- - result.datasource.name == 'datasource-thruk'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'sni-thruk-datasource'
- - result.datasource.url == 'https://thruk.company.com/sitename/thruk'
- - result.datasource.user == ''
- - result.datasource.withCredentials == false
+ - not result.changed
+ - result.datasource.basicAuth == false
+ - result.datasource.access == 'proxy'
+ - result.datasource.isDefault == false
+ - result.datasource.jsonData.tlsAuth == false
+ - result.datasource.jsonData.tlsAuthWithCACert == false
+ - result.datasource.name == 'datasource-thruk'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'sni-thruk-datasource'
+ - result.datasource.url == 'https://thruk.company.com/sitename/thruk'
+ - result.datasource.user == ''
+ - result.datasource.withCredentials == false
- name: Delete thruk datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-thruk
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: absent
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
+ - result.changed
- name: Delete thruk datasource (idempotency)
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-thruk
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: absent
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
+ - not result.changed
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/uid.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/uid.yml
index 71102a074..7a472b42f 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/uid.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/uid.yml
@@ -1,253 +1,254 @@
+---
- name: Create datasource with uid
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-with-uid
uid: uid1
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: prometheus
ds_url: https://prometheus.company.com:8086
- basic_auth_user: "admin"
- basic_auth_password: "admin"
- validate_certs: False
- is_default: no
+ basic_auth_user: admin
+ basic_auth_password: admin
+ validate_certs: false
+ is_default: false
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - "result.msg == 'Datasource datasource-with-uid created'"
+ - result.changed
+ - result.msg == 'Datasource datasource-with-uid created'
- name: Create datasource without uid
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-without-uid
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: prometheus
ds_url: https://prometheus.company.com:8086
- basic_auth_user: "admin"
- basic_auth_password: "admin"
- validate_certs: False
- is_default: no
+ basic_auth_user: admin
+ basic_auth_password: admin
+ validate_certs: false
+ is_default: false
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - "result.msg == 'Datasource datasource-without-uid created'"
+ - result.changed
+ - result.msg == 'Datasource datasource-without-uid created'
- name: Check datasource creation idempotency with uid
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-with-uid
uid: uid1
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: prometheus
ds_url: https://prometheus.company.com:8086
- basic_auth_user: "admin"
- basic_auth_password: "admin"
- validate_certs: False
- is_default: no
+ basic_auth_user: admin
+ basic_auth_password: admin
+ validate_certs: false
+ is_default: false
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
- - result.datasource.access == 'proxy'
- - result.datasource.isDefault == false
- - result.datasource.jsonData.tlsAuth == false
- - result.datasource.name == 'datasource-with-uid'
- - result.datasource.uid == 'uid1'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'prometheus'
- - result.datasource.url == 'https://prometheus.company.com:8086'
- - result.datasource.user == ''
- - result.datasource.withCredentials == false
+ - not result.changed
+ - result.datasource.access == 'proxy'
+ - result.datasource.isDefault == false
+ - result.datasource.jsonData.tlsAuth == false
+ - result.datasource.name == 'datasource-with-uid'
+ - result.datasource.uid == 'uid1'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'prometheus'
+ - result.datasource.url == 'https://prometheus.company.com:8086'
+ - result.datasource.user == ''
+ - result.datasource.withCredentials == false
- name: Check datasource creation idempotency without uid
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-without-uid
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: prometheus
ds_url: https://prometheus.company.com:8086
- basic_auth_user: "admin"
- basic_auth_password: "admin"
- validate_certs: False
- is_default: no
+ basic_auth_user: admin
+ basic_auth_password: admin
+ validate_certs: false
+ is_default: false
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
- - result.datasource.access == 'proxy'
- - result.datasource.isDefault == false
- - result.datasource.jsonData.tlsAuth == false
- - result.datasource.name == 'datasource-without-uid'
- - result.datasource.uid
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'prometheus'
- - result.datasource.url == 'https://prometheus.company.com:8086'
- - result.datasource.user == ''
- - result.datasource.withCredentials == false
+ - not result.changed
+ - result.datasource.access == 'proxy'
+ - result.datasource.isDefault == false
+ - result.datasource.jsonData.tlsAuth == false
+ - result.datasource.name == 'datasource-without-uid'
+ - result.datasource.uid
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'prometheus'
+ - result.datasource.url == 'https://prometheus.company.com:8086'
+ - result.datasource.user == ''
+ - result.datasource.withCredentials == false
- name: Set uid for datasource with random uid
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-without-uid
uid: uid3
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: prometheus
ds_url: https://prometheus.company.com:8086
- basic_auth_user: "admin"
- basic_auth_password: "admin"
- validate_certs: False
- is_default: no
+ basic_auth_user: admin
+ basic_auth_password: admin
+ validate_certs: false
+ is_default: false
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - result.datasource.access == 'proxy'
- - result.datasource.isDefault == false
- - result.datasource.jsonData.tlsAuth == false
- - result.datasource.name == 'datasource-without-uid'
- - result.datasource.uid == 'uid3'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'prometheus'
- - result.datasource.url == 'https://prometheus.company.com:8086'
- - result.datasource.user == ''
- - result.datasource.withCredentials == false
+ - result.changed
+ - result.datasource.access == 'proxy'
+ - result.datasource.isDefault == false
+ - result.datasource.jsonData.tlsAuth == false
+ - result.datasource.name == 'datasource-without-uid'
+ - result.datasource.uid == 'uid3'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'prometheus'
+ - result.datasource.url == 'https://prometheus.company.com:8086'
+ - result.datasource.user == ''
+ - result.datasource.withCredentials == false
- name: Change uid for datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-with-uid
uid: uid2
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: prometheus
ds_url: https://prometheus.company.com:8086
- basic_auth_user: "admin"
- basic_auth_password: "admin"
- validate_certs: False
- is_default: no
+ basic_auth_user: admin
+ basic_auth_password: admin
+ validate_certs: false
+ is_default: false
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - result.datasource.access == 'proxy'
- - result.datasource.isDefault == false
- - result.datasource.jsonData.tlsAuth == false
- - result.datasource.name == 'datasource-with-uid'
- - result.datasource.uid == 'uid2'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'prometheus'
- - result.datasource.url == 'https://prometheus.company.com:8086'
- - result.datasource.user == ''
- - result.datasource.withCredentials == false
+ - result.changed
+ - result.datasource.access == 'proxy'
+ - result.datasource.isDefault == false
+ - result.datasource.jsonData.tlsAuth == false
+ - result.datasource.name == 'datasource-with-uid'
+ - result.datasource.uid == 'uid2'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'prometheus'
+ - result.datasource.url == 'https://prometheus.company.com:8086'
+ - result.datasource.user == ''
+ - result.datasource.withCredentials == false
- name: Delete datasource-with-uid
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-with-uid
uid: uid1
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: prometheus
ds_url: https://prometheus.company.com:8086
- basic_auth_user: "admin"
- basic_auth_password: "admin"
- validate_certs: False
- is_default: no
+ basic_auth_user: admin
+ basic_auth_password: admin
+ validate_certs: false
+ is_default: false
state: absent
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
+ - result.changed
- name: Delete datasource-without-uid
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-without-uid
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: prometheus
ds_url: https://prometheus.company.com:8086
- basic_auth_user: "admin"
- basic_auth_password: "admin"
- validate_certs: False
- is_default: no
+ basic_auth_user: admin
+ basic_auth_password: admin
+ validate_certs: false
+ is_default: false
state: absent
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
+ - result.changed
- name: Delete datasource-with-uid (idempotency)
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-with-uid
uid: uid1
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: prometheus
ds_url: https://prometheus.company.com:8086
- basic_auth_user: "admin"
- basic_auth_password: "admin"
- validate_certs: False
- is_default: no
+ basic_auth_user: admin
+ basic_auth_password: admin
+ validate_certs: false
+ is_default: false
state: absent
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
+ - not result.changed
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/zabbix.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/zabbix.yml
index c8a8236bf..d238efb3e 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/zabbix.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/zabbix.yml
@@ -1,114 +1,115 @@
+---
- name: Create zabbix datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-zabbix
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: alexanderzobnin-zabbix-datasource
ds_url: https://zabbix.company.com
zabbix_user: grafana
- zabbix_password: '******'
+ zabbix_password: "******"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - not result.datasource.isDefault
- - result.datasource.jsonData.username == 'grafana'
- - result.datasource.name == 'datasource-zabbix'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'alexanderzobnin-zabbix-datasource'
- - result.datasource.url == 'https://zabbix.company.com'
- - result.datasource.user == ''
- - not result.datasource.withCredentials
- - "result.msg == 'Datasource datasource-zabbix created'"
+ - result.changed
+ - not result.datasource.isDefault
+ - result.datasource.jsonData.username == 'grafana'
+ - result.datasource.name == 'datasource-zabbix'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'alexanderzobnin-zabbix-datasource'
+ - result.datasource.url == 'https://zabbix.company.com'
+ - result.datasource.user == ''
+ - not result.datasource.withCredentials
+ - result.msg == 'Datasource datasource-zabbix created'
- name: Create zabbix datasource (idempotency)
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-zabbix
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: alexanderzobnin-zabbix-datasource
ds_url: https://zabbix.company.com
zabbix_user: grafana
- zabbix_password: '******'
+ zabbix_password: "******"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
- - not result.datasource.isDefault
- - result.datasource.jsonData.username == 'grafana'
- - result.datasource.name == 'datasource-zabbix'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'alexanderzobnin-zabbix-datasource'
- - result.datasource.url == 'https://zabbix.company.com'
- - result.datasource.user == ''
- - not result.datasource.withCredentials
+ - not result.changed
+ - not result.datasource.isDefault
+ - result.datasource.jsonData.username == 'grafana'
+ - result.datasource.name == 'datasource-zabbix'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'alexanderzobnin-zabbix-datasource'
+ - result.datasource.url == 'https://zabbix.company.com'
+ - result.datasource.user == ''
+ - not result.datasource.withCredentials
- name: Update zabbix datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-zabbix
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
- org_id: '1'
+ org_id: "1"
ds_type: alexanderzobnin-zabbix-datasource
ds_url: https://zabbix.example.com
zabbix_user: grafana
- zabbix_password: '******'
+ zabbix_password: "******"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
- - not result.datasource.isDefault
- - result.datasource.jsonData.username == 'grafana'
- - result.datasource.name == 'datasource-zabbix'
- - result.datasource.orgId == 1
- - ('password' not in result.datasource) or (result.datasource.password == '')
- - result.datasource.type == 'alexanderzobnin-zabbix-datasource'
- - result.datasource.url == 'https://zabbix.example.com'
- - result.datasource.user == ''
- - not result.datasource.withCredentials
- - "result.msg == 'Datasource datasource-zabbix updated'"
+ - result.changed
+ - not result.datasource.isDefault
+ - result.datasource.jsonData.username == 'grafana'
+ - result.datasource.name == 'datasource-zabbix'
+ - result.datasource.orgId == 1
+ - ('password' not in result.datasource) or (result.datasource.password == '')
+ - result.datasource.type == 'alexanderzobnin-zabbix-datasource'
+ - result.datasource.url == 'https://zabbix.example.com'
+ - result.datasource.user == ''
+ - not result.datasource.withCredentials
+ - result.msg == 'Datasource datasource-zabbix updated'
- name: Delete zabbix datasource
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-zabbix
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: absent
-- assert:
+- ansible.builtin.assert:
that:
- - result.changed
+ - result.changed
- name: Delete zabbix datasource (idempotency)
register: result
- grafana_datasource:
+ community.grafana.grafana_datasource:
name: datasource-zabbix
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
grafana_password: "{{ grafana_password }}"
state: absent
-- assert:
+- ansible.builtin.assert:
that:
- - not result.changed
+ - not result.changed
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/defaults/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/defaults/main.yml
index 8b9c9348a..4abf9bb43 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/defaults/main.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/defaults/main.yml
@@ -1,7 +1,5 @@
---
-grafana_url: "http://grafana:3000/"
-grafana_username: "admin"
-grafana_password: "admin"
-
-...
+grafana_url: http://grafana:3000/
+grafana_username: admin
+grafana_password: admin
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/runme.sh b/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/runme.sh
new file mode 100755
index 000000000..9daa487db
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/runme.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+set -eux
+
+ansible-playbook site.yml --check
+ansible-playbook site.yml
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/site.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/site.yml
new file mode 100644
index 000000000..2041400ea
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/site.yml
@@ -0,0 +1,6 @@
+---
+- name: Run tests for grafana_folder
+ hosts: localhost
+ tasks:
+ - ansible.builtin.include_role:
+ name: ../../grafana_folder
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/tasks/create-delete.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/tasks/create-delete.yml
new file mode 100644
index 000000000..c818c2ef1
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/tasks/create-delete.yml
@@ -0,0 +1,58 @@
+---
+- name: Create a Folder
+ community.grafana.grafana_folder:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ title: grafana_working_group
+ state: present
+ register: result
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ - result.folder.title == 'grafana_working_group'
+ when: not ansible_check_mode
+
+- name: Test folder creation idempotency
+ community.grafana.grafana_folder:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ title: grafana_working_group
+ state: present
+ register: result
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ - result.folder.title == 'grafana_working_group'
+ when: not ansible_check_mode
+
+- name: Delete a Folder
+ community.grafana.grafana_folder:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ title: grafana_working_group
+ state: absent
+ register: result
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == true
+ when: not ansible_check_mode
+
+- name: Test folder deletion idempotency
+ community.grafana.grafana_folder:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ title: grafana_working_group
+ state: absent
+ register: result
+
+- ansible.builtin.assert:
+ that:
+ - result.changed == false
+ when: not ansible_check_mode
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/tasks/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/tasks/main.yml
index c6a520560..0ac91f375 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/tasks/main.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/tasks/main.yml
@@ -1,55 +1,6 @@
---
+- name: Folder creation and deletion
+ ansible.builtin.include_tasks: create-delete.yml
-- name: Create a Folder
- grafana_folder:
- url: "{{ grafana_url }}"
- url_username: "{{ grafana_username }}"
- url_password: "{{ grafana_password }}"
- title: "grafana_working_group"
- state: present
- register: result
-
-- assert:
- that:
- - "result.changed == true"
- - "result.folder.title == 'grafana_working_group'"
-
-- name: Test folder creation idempotency
- grafana_folder:
- url: "{{ grafana_url }}"
- url_username: "{{ grafana_username }}"
- url_password: "{{ grafana_password }}"
- title: "grafana_working_group"
- state: present
- register: result
-
-- assert:
- that:
- - "result.changed == false"
- - "result.folder.title == 'grafana_working_group'"
-
-- name: Delete a Folder
- grafana_folder:
- url: "{{ grafana_url }}"
- url_username: "{{ grafana_username }}"
- url_password: "{{ grafana_password }}"
- title: "grafana_working_group"
- state: absent
- register: result
-
-- assert:
- that:
- - "result.changed == true"
-
-- name: Test folder deletion idempotency
- grafana_folder:
- url: "{{ grafana_url }}"
- url_username: "{{ grafana_username }}"
- url_password: "{{ grafana_password }}"
- title: "grafana_working_group"
- state: absent
- register: result
-
-- assert:
- that:
- - "result.changed == false"
+- name: Folder creation and deletion for organization
+ ansible.builtin.include_tasks: org.yml
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/tasks/org.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/tasks/org.yml
new file mode 100644
index 000000000..f30d48c14
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/tasks/org.yml
@@ -0,0 +1,7 @@
+---
+- module_defaults:
+ community.grafana.grafana_folder:
+ org_name: Main Org.
+ block:
+ - name: Folder creation and deletion
+ ansible.builtin.include_tasks: create-delete.yml
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/defaults/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/defaults/main.yml
index 8b9c9348a..4abf9bb43 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/defaults/main.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/defaults/main.yml
@@ -1,7 +1,5 @@
---
-grafana_url: "http://grafana:3000/"
-grafana_username: "admin"
-grafana_password: "admin"
-
-...
+grafana_url: http://grafana:3000/
+grafana_username: admin
+grafana_password: admin
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/runme.sh b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/runme.sh
new file mode 100755
index 000000000..867afb0d3
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/runme.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+set -eux
+
+ansible-playbook site.yml
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/site.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/site.yml
new file mode 100644
index 000000000..e20f44e32
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/site.yml
@@ -0,0 +1,6 @@
+---
+- name: Run tests for grafana_notification_channel
+ hosts: localhost
+ tasks:
+ - ansible.builtin.include_role:
+ name: ../../grafana_notification_channel
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/dingding.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/dingding.yml
index 7279e313b..80d2f07d8 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/dingding.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/dingding.yml
@@ -1,19 +1,19 @@
---
- name: Create dingding notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: dingding
name: dingding
type: dingding
dingding_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- result.changed == True
- result.channel.name == "dingding"
@@ -22,19 +22,19 @@
- name: Create dingding notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: dingding
name: dingding
type: dingding
dingding_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- result.changed == False
- result.channel.name == "dingding"
@@ -43,32 +43,32 @@
- name: Delete dingding notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: dingding
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- result.changed == True
- name: Delete dingding notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: dingding
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/discord.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/discord.yml
index 29cfece70..30c70d63e 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/discord.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/discord.yml
@@ -1,19 +1,19 @@
---
- name: Create discord notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: discord
name: discord
type: discord
discord_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- result.changed == True
- result.channel.name == "discord"
@@ -22,19 +22,19 @@
- name: Create discord notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: discord
name: discord
type: discord
discord_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- result.changed == False
- result.channel.name == "discord"
@@ -43,32 +43,32 @@
- name: Delete discord notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: discord
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- result.changed == True
- name: Delete discord notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: discord
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/email.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/email.yml
index 85a236c9e..29e188755 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/email.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/email.yml
@@ -1,7 +1,7 @@
---
- name: Create email notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: email
name: email
type: email
@@ -10,21 +10,21 @@
- bar@example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "email"
- result.channel.type == "email"
- result.channel.uid == "email"
- name: Create email notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: email
name: email
type: email
@@ -33,47 +33,47 @@
- bar@example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- result.channel.name == "email"
- result.channel.type == "email"
- result.channel.uid == "email"
- name: Delete discord notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: email
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
- - "result.state == 'absent'"
+ - result.changed == True
+ - result.state == 'absent'
- name: Delete discord notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: email
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/googlechat.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/googlechat.yml
index abc7db644..8acdf0a68 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/googlechat.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/googlechat.yml
@@ -1,74 +1,74 @@
---
- name: Create googlechat notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: googlechat
name: googlechat
type: googlechat
googlechat_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "googlechat"
- result.channel.uid == "googlechat"
- result.channel.type == "googlechat"
- name: Create googlechat notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: googlechat
name: googlechat
type: googlechat
googlechat_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- result.channel.name == "googlechat"
- result.channel.uid == "googlechat"
- result.channel.type == "googlechat"
- name: Delete googlechat notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: googlechat
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- name: Delete googlechat notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: googlechat
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/hipchat.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/hipchat.yml
index 4a9ec1704..6423cafc8 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/hipchat.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/hipchat.yml
@@ -1,74 +1,74 @@
---
- name: Create hipchat notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: hipchat
name: hipchat
type: hipchat
hipchat_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "hipchat"
- result.channel.type == "hipchat"
- result.channel.uid == "hipchat"
- name: Create hipchat notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: hipchat
name: hipchat
type: hipchat
hipchat_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- result.channel.name == "hipchat"
- result.channel.type == "hipchat"
- result.channel.uid == "hipchat"
- name: Delete hipchat notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: hipchat
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- name: Delete hipchat notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: hipchat
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/kafka.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/kafka.yml
index ffc208acb..d8ec9cad3 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/kafka.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/kafka.yml
@@ -1,7 +1,7 @@
---
- name: Create kafka notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: kafka
name: kafka
type: kafka
@@ -9,21 +9,21 @@
kafka_topic: test
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "kafka"
- result.channel.uid == "kafka"
- result.channel.type == "kafka"
- name: Create kafka notification channel (idempotentcy)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: kafka
name: kafka
type: kafka
@@ -31,46 +31,46 @@
kafka_topic: test
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- result.channel.name == "kafka"
- result.channel.uid == "kafka"
- result.channel.type == "kafka"
- name: Delete kafka notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: kafka
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- name: Delete kafka notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: kafka
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/line.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/line.yml
index 83a1863ba..dde928c3e 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/line.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/line.yml
@@ -1,74 +1,74 @@
---
- name: Create line notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: line
name: line
type: line
line_token: xxx
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.uid == "line"
- result.channel.name == "line"
- result.channel.type == "line"
- name: Create line notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: line
name: line
type: line
line_token: xxx
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- result.channel.uid == "line"
- result.channel.name == "line"
- result.channel.type == "line"
- name: Delete line notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: line
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- name: Delete line notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: line
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/main.yml
index ada6338c7..af0b2f861 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/main.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/main.yml
@@ -1,20 +1,34 @@
---
- block:
- - include: dingding.yml
- - include: discord.yml
- - include: email.yml
- - include: googlechat.yml
- - include: hipchat.yml
- - include: kafka.yml
-# - include: line.yml
- - include: teams.yml
- - include: opsgenie.yml
- - include: pagerduty.yml
- - include: prometheus.yml
- - include: pushover.yml
- - include: sensu.yml
- - include: slack-and-beyond.yml
- - include: telegram.yml
-# - include: threema.yml
- - include: victorops.yml
- - include: webhook.yml
+ - ansible.builtin.include_tasks:
+ file: dingding.yml
+ - ansible.builtin.include_tasks:
+ file: discord.yml
+ - ansible.builtin.include_tasks:
+ file: email.yml
+ - ansible.builtin.include_tasks:
+ file: googlechat.yml
+ - ansible.builtin.include_tasks:
+ file: hipchat.yml
+ - ansible.builtin.include_tasks:
+ file: kafka.yml
+ - ansible.builtin.include_tasks:
+ file: teams.yml
+ - ansible.builtin.include_tasks:
+ file: opsgenie.yml
+ - ansible.builtin.include_tasks:
+ file: pagerduty.yml
+ - ansible.builtin.include_tasks:
+ file: prometheus.yml
+ - ansible.builtin.include_tasks:
+ file: pushover.yml
+ - ansible.builtin.include_tasks:
+ file: sensu.yml
+ - ansible.builtin.include_tasks:
+ file: slack-and-beyond.yml
+ - ansible.builtin.include_tasks:
+ file: telegram.yml
+ - ansible.builtin.include_tasks:
+ file: victorops.yml
+ - ansible.builtin.include_tasks:
+ file: webhook.yml
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/opsgenie.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/opsgenie.yml
index f871fe719..cd1048b86 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/opsgenie.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/opsgenie.yml
@@ -1,7 +1,7 @@
---
- name: Create opsgenie notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: opsgenie
name: opsgenie
type: opsgenie
@@ -9,21 +9,21 @@
opsgenie_api_key: xxx
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "opsgenie"
- result.channel.type == "opsgenie"
- result.channel.uid == "opsgenie"
- name: Create opsgenie notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: opsgenie
name: opsgenie
type: opsgenie
@@ -31,47 +31,47 @@
opsgenie_api_key: xxx
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- result.channel.name == "opsgenie"
- result.channel.type == "opsgenie"
- result.channel.uid == "opsgenie"
- name: Delete opsgenie notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: opsgenie
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
- - "result.state == 'absent'"
+ - result.changed == True
+ - result.state == 'absent'
- name: Delete opsgenie notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: opsgenie
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/pagerduty.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/pagerduty.yml
index a8fa940b0..40fd00468 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/pagerduty.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/pagerduty.yml
@@ -1,74 +1,74 @@
---
- name: Create pagerduty notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: pagerduty
name: pagerduty
type: pagerduty
pagerduty_integration_key: xxx
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "pagerduty"
- result.channel.type == "pagerduty"
- result.channel.uid == "pagerduty"
- name: Create pagerduty notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: pagerduty
name: pagerduty
type: pagerduty
pagerduty_integration_key: xxx
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- result.channel.name == "pagerduty"
- result.channel.type == "pagerduty"
- result.channel.uid == "pagerduty"
- name: Delete pagerduty notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: pagerduty
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- name: Delete pagerduty notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: pagerduty
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/prometheus.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/prometheus.yml
index 40810eaf3..c85d26f2e 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/prometheus.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/prometheus.yml
@@ -1,74 +1,74 @@
---
- name: Create prometheus notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: prometheus
name: prometheus
type: prometheus
prometheus_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "prometheus"
- result.channel.uid == "prometheus"
- result.channel.type == "prometheus-alertmanager"
- name: Create prometheus notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: prometheus
name: prometheus
type: prometheus
prometheus_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- result.channel.name == "prometheus"
- result.channel.uid == "prometheus"
- result.channel.type == "prometheus-alertmanager"
- name: Delete prometheus notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: prometheus
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- name: Delete prometheus notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: prometheus
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/pushover.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/pushover.yml
index 894bd71e6..ee7b9bea4 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/pushover.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/pushover.yml
@@ -1,7 +1,7 @@
---
- name: Create pushover notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: pushover
name: pushover
type: pushover
@@ -9,21 +9,21 @@
pushover_user_key: yyy
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "pushover"
- result.channel.uid == "pushover"
- result.channel.type == "pushover"
- name: Create pushover notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: pushover
name: pushover
type: pushover
@@ -31,46 +31,46 @@
pushover_user_key: yyy
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- result.channel.name == "pushover"
- result.channel.uid == "pushover"
- result.channel.type == "pushover"
- name: Delete pushover notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: pushover
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- name: Delete pushover notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: pushover
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/sensu.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/sensu.yml
index 01619b719..a46ef1d0a 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/sensu.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/sensu.yml
@@ -1,74 +1,74 @@
---
- name: Create sensu notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: sensu
name: sensu
type: sensu
sensu_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "sensu"
- result.channel.type == "sensu"
- result.channel.uid == "sensu"
- name: Create sensu notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: sensu
name: sensu
type: sensu
sensu_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- result.channel.name == "sensu"
- result.channel.type == "sensu"
- result.channel.uid == "sensu"
- name: Delete sensu notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: sensu
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- name: Delete sensu notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: sensu
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/slack-and-beyond.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/slack-and-beyond.yml
index 0748c8bdb..1cbab6d5c 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/slack-and-beyond.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/slack-and-beyond.yml
@@ -1,110 +1,110 @@
---
- name: Create slack notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: slack
name: slack
type: slack
slack_url: https://hooks.slack.com/services/xxx/yyy/zzz
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "slack"
- result.channel.type == "slack"
- result.channel.uid == "slack"
- name: Create slack notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: slack
name: slack
type: slack
slack_url: https://hooks.slack.com/services/xxx/yyy/zzz
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- result.channel.name == "slack"
- result.channel.type == "slack"
- result.channel.uid == "slack"
- name: Check slack notification channel idempotency
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: slack
name: slack
type: slack
slack_url: https://hooks.slack.com/services/xxx/yyy/zzz
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- name: Update slack notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: slack
name: slack
type: slack
slack_url: https://hooks.slack.com/services/xxx/yyy/fff
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- name: Delete slack notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
state: absent
uid: slack
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- name: Delete slack notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
state: absent
uid: slack
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/teams.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/teams.yml
index cfc44aef3..d9c7471c5 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/teams.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/teams.yml
@@ -1,74 +1,74 @@
---
- name: Create teams notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: teams
name: teams
type: teams
teams_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "teams"
- result.channel.uid == "teams"
- result.channel.type == "teams"
- name: Create teams notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: teams
name: teams
type: teams
teams_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- result.channel.name == "teams"
- result.channel.uid == "teams"
- result.channel.type == "teams"
- name: Delete teams notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: teams
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- name: Delete teams notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: teams
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/telegram.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/telegram.yml
index 98a7a3c6d..38e27ef57 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/telegram.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/telegram.yml
@@ -1,7 +1,7 @@
---
- name: Create telegram notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: telegram
name: telegram
type: telegram
@@ -9,21 +9,21 @@
telegram_chat_id: yyy
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "telegram"
- result.channel.type == "telegram"
- result.channel.uid == "telegram"
- name: Create telegram notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: telegram
name: telegram
type: telegram
@@ -31,46 +31,46 @@
telegram_chat_id: yyy
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- result.channel.name == "telegram"
- result.channel.type == "telegram"
- result.channel.uid == "telegram"
- name: Delete telegram notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: telegram
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- name: Delete telegram notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: telegram
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/threema.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/threema.yml
index 7858b6977..c61eae316 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/threema.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/threema.yml
@@ -1,7 +1,7 @@
---
- name: Create threema notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: threema
name: threema
type: threema
@@ -10,21 +10,21 @@
threema_api_secret: zzz
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "threema"
- result.channel.type == "threema"
- result.channel.uid == "threema"
- name: Create threema notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: threema
name: threema
type: threema
@@ -33,46 +33,46 @@
threema_api_secret: zzz
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "threema"
- result.channel.type == "threema"
- result.channel.uid == "threema"
- name: Delete threema notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: threema
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- name: Delete threema notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: threema
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/victorops.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/victorops.yml
index 3779e813a..e21679132 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/victorops.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/victorops.yml
@@ -1,74 +1,74 @@
---
- name: Create victorops notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: victorops
name: victorops
type: victorops
victorops_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "victorops"
- result.channel.type == "victorops"
- result.channel.uid == "victorops"
- name: Create victorops notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: victorops
name: victorops
type: victorops
victorops_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- result.channel.name == "victorops"
- result.channel.type == "victorops"
- result.channel.uid == "victorops"
- name: Delete victorops notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: victorops
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- name: Delete victorops notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: victorops
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/webhook.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/webhook.yml
index c9efd9193..5a00878f9 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/webhook.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/webhook.yml
@@ -1,74 +1,74 @@
---
- name: Create webhook notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: webhook
name: webhook
type: webhook
webhook_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- result.channel.name == "webhook"
- result.channel.uid == "webhook"
- result.channel.type == "webhook"
- name: Create webhook notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: webhook
name: webhook
type: webhook
webhook_url: https://example.org
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
- result.channel.name == "webhook"
- result.channel.uid == "webhook"
- result.channel.type == "webhook"
- name: Delete webhook notification channel
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: webhook
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == True"
+ - result.changed == True
- name: Delete webhook notification channel (idempotency)
register: result
- grafana_notification_channel:
+ community.grafana.grafana_notification_channel:
uid: webhook
state: absent
grafana_url: "{{ grafana_url }}"
grafana_user: "{{ grafana_username }}"
- grafana_password: "{{ grafana_password}}"
+ grafana_password: "{{ grafana_password }}"
-- debug:
+- ansible.builtin.debug:
var: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == False"
+ - result.changed == False
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/defaults/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/defaults/main.yml
index 7bb77ea3f..3edac8598 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/defaults/main.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/defaults/main.yml
@@ -1,4 +1,4 @@
---
-grafana_url: "http://grafana:3000/"
-grafana_username: "admin"
-grafana_password: "admin"
+grafana_url: http://grafana:3000/
+grafana_username: admin
+grafana_password: admin
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/runme.sh b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/runme.sh
new file mode 100755
index 000000000..9daa487db
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/runme.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+set -eux
+
+ansible-playbook site.yml --check
+ansible-playbook site.yml
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/site.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/site.yml
new file mode 100644
index 000000000..e2e4900bd
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/site.yml
@@ -0,0 +1,6 @@
+---
+- name: Run tests for grafana_organization
+ hosts: localhost
+ tasks:
+ - ansible.builtin.include_role:
+ name: ../../grafana_organization
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/tasks/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/tasks/main.yml
index f8ccdf3bf..936b147cb 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/tasks/main.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/tasks/main.yml
@@ -1,5 +1,4 @@
---
-
- name: Create a Grafana organization
community.grafana.grafana_organization:
url: "{{ grafana_url }}"
@@ -8,13 +7,15 @@
name: orgtest
state: present
register: result
-- assert:
+
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.failed == false"
- - "result.org.name == 'orgtest'"
+ - result.changed == true
+ - result.failed == false
+ - result.org.name == 'orgtest'
+ when: not ansible_check_mode
-- name: check idempotency Grafana organization
+- name: Check idempotency Grafana organization
community.grafana.grafana_organization:
url: "{{ grafana_url }}"
url_username: "{{ grafana_username }}"
@@ -22,11 +23,13 @@
name: orgtest
state: present
register: result
-- assert:
+
+- ansible.builtin.assert:
that:
- - "result.changed == false"
- - "result.failed == false"
- - "result.org.name == 'orgtest'"
+ - result.changed == false
+ - result.failed == false
+ - result.org.name == 'orgtest'
+ when: not ansible_check_mode
- name: Delete a Grafana organization
community.grafana.grafana_organization:
@@ -36,13 +39,15 @@
name: orgtest
state: absent
register: result
-- assert:
+
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.failed == false"
- - "result.msg |length > 0"
+ - result.changed == true
+ - result.failed == false
+ - result.msg |length > 0
+ when: not ansible_check_mode
-- name: check idempotency delete a Grafana organization
+- name: Check idempotency delete a Grafana organization
community.grafana.grafana_organization:
url: "{{ grafana_url }}"
url_username: "{{ grafana_username }}"
@@ -50,8 +55,10 @@
name: orgtest
state: absent
register: result
-- assert:
+
+- ansible.builtin.assert:
that:
- - "result.changed == false"
- - "result.failed == false"
- - "result.msg == 'No org found, nothing to do'"
+ - result.changed == false
+ - result.failed == false
+ - result.msg == 'No org found, nothing to do'
+ when: not ansible_check_mode
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/defaults/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/defaults/main.yml
new file mode 100644
index 000000000..3edac8598
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/defaults/main.yml
@@ -0,0 +1,4 @@
+---
+grafana_url: http://grafana:3000/
+grafana_username: admin
+grafana_password: admin
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/runme.sh b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/runme.sh
new file mode 100755
index 000000000..9daa487db
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/runme.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+set -eux
+
+ansible-playbook site.yml --check
+ansible-playbook site.yml
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/site.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/site.yml
new file mode 100644
index 000000000..80e5ea916
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/site.yml
@@ -0,0 +1,6 @@
+---
+- name: Run tests for grafana_organization_user
+ hosts: localhost
+ tasks:
+ - ansible.builtin.include_role:
+ name: ../../grafana_organization_user
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/tasks/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/tasks/main.yml
new file mode 100644
index 000000000..73b0482ac
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization_user/tasks/main.yml
@@ -0,0 +1,172 @@
+---
+- name: Create test user (default org 1)
+ community.grafana.grafana_user:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ name: orgtest
+ email: orgtest@example.com
+ login: orgtest
+ password: userpassword
+ state: present
+ register: result
+
+- name: Remove user from organization (default org 1)
+ community.grafana.grafana_organization_user:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ login: orgtest
+ state: absent
+ register: result
+- ansible.builtin.assert:
+ that:
+ - result.failed == false
+ - result.changed == true
+ when: not ansible_check_mode
+
+- name: Check idempotency on user removal from org
+ community.grafana.grafana_organization_user:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ login: orgtest
+ state: absent
+ register: result
+- ansible.builtin.assert:
+ that:
+ - result.failed == false
+ - result.changed == false
+ when: not ansible_check_mode
+
+- name: Add user to organization
+ community.grafana.grafana_organization_user:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ login: orgtest
+ role: viewer
+ state: present
+ register: result
+- ansible.builtin.assert:
+ that:
+ - result.failed == false
+ - result.changed == true
+ - result.user.orgId == 1
+ - result.user.role == 'Viewer'
+ when: not ansible_check_mode
+
+- name: Update existing user role
+ community.grafana.grafana_organization_user:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ login: orgtest
+ role: editor
+ state: present
+ register: result
+- ansible.builtin.assert:
+ that:
+ - result.failed == false
+ - result.changed == true
+ - result.user.orgId == 1
+ - result.user.role == 'Editor'
+ when: not ansible_check_mode
+
+- name: Check idempotency on user update
+ community.grafana.grafana_organization_user:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ login: orgtest
+ role: editor
+ state: present
+ register: result
+- ansible.builtin.assert:
+ that:
+ - result.failed == false
+ - result.changed == false
+ when: not ansible_check_mode
+
+- name: Create a new organization
+ community.grafana.grafana_organization:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ name: neworgtest
+ state: present
+ register: org
+
+- name: Add user to the new organization by org_id
+ community.grafana.grafana_organization_user:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ org_id: "{{ org.org.id }}"
+ login: orgtest
+ role: admin
+ state: present
+ register: result
+ when: not ansible_check_mode
+
+- ansible.builtin.assert:
+ that:
+ - result.failed == false
+ - result.changed == true
+ - result.user.orgId == org.org.id
+ - result.user.role == 'Admin'
+ when: not ansible_check_mode
+
+- name: Remove user from new organization by org_id
+ community.grafana.grafana_organization_user:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ org_id: "{{ org.org.id }}"
+ login: orgtest
+ state: absent
+ register: result
+ when: not ansible_check_mode
+
+- ansible.builtin.assert:
+ that:
+ - result.failed == false
+ - result.changed == true
+ when: not ansible_check_mode
+
+- name: Add user to the new organization by org_name
+ community.grafana.grafana_organization_user:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ org_name: "{{ org.org.name }}"
+ login: orgtest
+ role: admin
+ state: present
+ register: result
+ when: not ansible_check_mode
+
+- ansible.builtin.assert:
+ that:
+ - result.failed == false
+ - result.changed == true
+ - result.user.orgId == org.org.id
+ - result.user.role == 'Admin'
+ when: not ansible_check_mode
+
+- name: Remove user from new organization by org_name
+ community.grafana.grafana_organization_user:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ org_name: "{{ org.org.name }}"
+ login: orgtest
+ state: absent
+ register: result
+ when: not ansible_check_mode
+
+- ansible.builtin.assert:
+ that:
+ - result.failed == false
+ - result.changed == true
+ when: not ansible_check_mode
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_team/defaults/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_team/defaults/main.yml
index 8b9c9348a..4abf9bb43 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_team/defaults/main.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_team/defaults/main.yml
@@ -1,7 +1,5 @@
---
-grafana_url: "http://grafana:3000/"
-grafana_username: "admin"
-grafana_password: "admin"
-
-...
+grafana_url: http://grafana:3000/
+grafana_username: admin
+grafana_password: admin
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_team/runme.sh b/ansible_collections/community/grafana/tests/integration/targets/grafana_team/runme.sh
new file mode 100755
index 000000000..867afb0d3
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_team/runme.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/env bash
+
+set -eux
+
+ansible-playbook site.yml
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_team/site.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_team/site.yml
new file mode 100644
index 000000000..c8a618891
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_team/site.yml
@@ -0,0 +1,6 @@
+---
+- name: Run tests for grafana_team
+ hosts: localhost
+ tasks:
+ - ansible.builtin.include_role:
+ name: ../../grafana_team
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_team/tasks/create_user.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_team/tasks/create_user.yml
index 6971d07b6..9641e7185 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_team/tasks/create_user.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_team/tasks/create_user.yml
@@ -1,29 +1,30 @@
+---
- name: Create John Doe for tests purpose through uri module
- uri:
+ ansible.builtin.uri:
url: "{{ grafana_url }}api/admin/users"
method: POST
user: "{{ grafana_username }}"
password: "{{ grafana_password }}"
- force_basic_auth: yes
+ force_basic_auth: true
body:
- name: "John"
- email: "john+doe@example.com"
- login: "john"
- password: "userpassword"
+ name: John
+ email: john+doe@example.com
+ login: john
+ password: userpassword
body_format: json
status_code: 200
- name: Create Jane Doe for tests purpose through uri module
- uri:
+ ansible.builtin.uri:
url: "{{ grafana_url }}api/admin/users"
method: POST
user: "{{ grafana_username }}"
password: "{{ grafana_password }}"
- force_basic_auth: yes
+ force_basic_auth: true
body:
- name: "Jane"
- email: "jane.doe@example.com"
- login: "jane"
- password: "userpassword"
+ name: Jane
+ email: jane.doe@example.com
+ login: jane
+ password: userpassword
body_format: json
status_code: 200
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_team/tasks/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_team/tasks/main.yml
index 2d74581b7..d43eb8286 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_team/tasks/main.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_team/tasks/main.yml
@@ -1,187 +1,198 @@
---
-
- name: Create a Team
- grafana_team:
- url: "{{ grafana_url }}"
- url_username: "{{ grafana_username }}"
- url_password: "{{ grafana_password }}"
- name: "grafana_working_group"
- email: "foo.bar@example.com"
- state: present
+ community.grafana.grafana_team:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ name: grafana working group
+ email: foo.bar@example.com
+ state: present
+ skip_version_check: true
register: result
-- set_fact:
+- ansible.builtin.set_fact:
# From Grafana 9.0.0, the API user automatically becomes a member of the team
auto_member: "{{ result.team.memberCount == 1 }}"
-- set_fact:
+- ansible.builtin.set_fact:
expected_members: "{{ auto_member | ternary(['********@localhost'], []) }}"
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.team.name == 'grafana_working_group'"
- - "result.team.email == 'foo.bar@example.com'"
- - "result.team.memberCount == (expected_members|length)"
- - "result.team.members == expected_members"
+ - result.changed == true
+ - result.team.name == 'grafana working group'
+ - result.team.email == 'foo.bar@example.com'
+ - result.team.memberCount == (expected_members|length)
+ - result.team.members == expected_members
+ when: not ansible_check_mode
- name: Check idempotency on team creation
- grafana_team:
- url: "{{ grafana_url }}"
- url_username: "{{ grafana_username }}"
- url_password: "{{ grafana_password }}"
- name: "grafana_working_group"
- email: "foo.bar@example.com"
- state: present
+ community.grafana.grafana_team:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ name: grafana working group
+ email: foo.bar@example.com
+ state: present
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == false"
- - "result.team.name == 'grafana_working_group'"
- - "result.team.email == 'foo.bar@example.com'"
- - "result.team.memberCount == (expected_members|length)"
- - "result.team.members == expected_members"
+ - result.changed == false
+ - result.team.name == 'grafana working group'
+ - result.team.email == 'foo.bar@example.com'
+ - result.team.memberCount == (expected_members|length)
+ - result.team.members == expected_members
+ when: not ansible_check_mode
- name: Check a team can be deleted
- grafana_team:
- url: "{{ grafana_url }}"
- url_username: "{{ grafana_username }}"
- url_password: "{{ grafana_password }}"
- name: "grafana_working_group"
- email: "foo.bar@example.com"
- state: absent
+ community.grafana.grafana_team:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ name: grafana working group
+ email: foo.bar@example.com
+ state: absent
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.message == 'Team deleted'"
+ - result.changed == true
+ - result.message == 'Team deleted'
+ when: not ansible_check_mode
- name: Check idempotency on team deletion
- grafana_team:
- url: "{{ grafana_url }}"
- url_username: "{{ grafana_username }}"
- url_password: "{{ grafana_password }}"
- name: "grafana_working_group"
- email: "foo.bar@example.com"
- state: absent
+ community.grafana.grafana_team:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ name: grafana working group
+ email: foo.bar@example.com
+ state: absent
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == false"
- - "result.message == 'No team found'"
+ - result.changed == false
+ - result.message == 'No team found'
+ when: not ansible_check_mode
- name: Create users for tests purpose
- import_tasks: create_user.yml
+ ansible.builtin.import_tasks:
+ file: create_user.yml
- name: Create a Team with members
- grafana_team:
- url: "{{ grafana_url }}"
- url_username: "{{ grafana_username }}"
- url_password: "{{ grafana_password }}"
- name: "grafana_working_group"
- email: "foo.bar@example.com"
- members:
- - "john+doe@example.com"
- - "jane.doe@example.com"
- state: present
+ community.grafana.grafana_team:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ name: grafana working group
+ email: foo.bar@example.com
+ members:
+ - john+doe@example.com
+ - jane.doe@example.com
+ state: present
register: result
-- set_fact:
- expected_members: "{{ auto_member | ternary(['********@localhost', 'jane.doe@example.com', 'john+doe@example.com'], ['jane.doe@example.com', 'john+doe@example.com']) }}"
+- ansible.builtin.set_fact:
+ expected_members: "{{ auto_member | ternary(['********@localhost', 'jane.doe@example.com', 'john+doe@example.com'], ['jane.doe@example.com', 'john+doe@example.com'])
+ }}"
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.team.name == 'grafana_working_group'"
- - "result.team.email == 'foo.bar@example.com'"
- - "result.team.memberCount == (expected_members|length)"
- - "result.team.members == expected_members"
+ - result.changed == true
+ - result.team.name == 'grafana working group'
+ - result.team.email == 'foo.bar@example.com'
+ - result.team.memberCount == (expected_members|length)
+ - result.team.members == expected_members
+ when: not ansible_check_mode
- name: Ensure a Team exists with member not enforced
- grafana_team:
- url: "{{ grafana_url }}"
- url_username: "{{ grafana_username }}"
- url_password: "{{ grafana_password }}"
- name: "grafana_working_group"
- email: "foo.bar@example.com"
- members:
- - "john+doe@example.com"
- state: present
+ community.grafana.grafana_team:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ name: grafana working group
+ email: foo.bar@example.com
+ members:
+ - john+doe@example.com
+ state: present
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == false"
- - "result.team.name == 'grafana_working_group'"
- - "result.team.email == 'foo.bar@example.com'"
- - "result.team.memberCount == (expected_members|length)"
- - "result.team.members == expected_members"
-
-- set_fact:
+ - result.changed == false
+ - result.team.name == 'grafana working group'
+ - result.team.email == 'foo.bar@example.com'
+ - result.team.memberCount == (expected_members|length)
+ - result.team.members == expected_members
+ when: not ansible_check_mode
+
+- ansible.builtin.set_fact:
enforced_members: "{{ auto_member | ternary(['admin@localhost', 'john+doe@example.com'], ['john+doe@example.com']) }}"
expected_members: "{{ auto_member | ternary(['********@localhost', 'john+doe@example.com'], ['john+doe@example.com']) }}"
- name: Ensure a Team exists with member enforced
- grafana_team:
- url: "{{ grafana_url }}"
- url_username: "{{ grafana_username }}"
- url_password: "{{ grafana_password }}"
- name: "grafana_working_group"
- email: "foo.bar@example.com"
- members: "{{ enforced_members }}"
- enforce_members: true
- state: present
+ community.grafana.grafana_team:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ name: grafana working group
+ email: foo.bar@example.com
+ members: "{{ enforced_members }}"
+ enforce_members: true
+ state: present
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.team.name == 'grafana_working_group'"
- - "result.team.email == 'foo.bar@example.com'"
- - "result.team.memberCount == (expected_members|length)"
- - "result.team.members == expected_members"
+ - result.changed == true
+ - result.team.name == 'grafana working group'
+ - result.team.email == 'foo.bar@example.com'
+ - result.team.memberCount == (expected_members|length)
+ - result.team.members == expected_members
- name: Ensure a Team exists with members omitted
- grafana_team:
- url: "{{ grafana_url }}"
- url_username: "{{ grafana_username }}"
- url_password: "{{ grafana_password }}"
- name: "grafana_working_group"
- email: "foo.bar@example.com"
- state: present
+ community.grafana.grafana_team:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ name: grafana working group
+ email: foo.bar@example.com
+ state: present
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == false"
- - "result.team.name == 'grafana_working_group'"
- - "result.team.email == 'foo.bar@example.com'"
- - "result.team.memberCount == (expected_members|length)"
- - "result.team.members == expected_members"
+ - result.changed == false
+ - result.team.name == 'grafana working group'
+ - result.team.email == 'foo.bar@example.com'
+ - result.team.memberCount == (expected_members|length)
+ - result.team.members == expected_members
+ when: not ansible_check_mode
- name: Add new member to existing Team
- grafana_team:
- url: "{{ grafana_url }}"
- url_username: "{{ grafana_username }}"
- url_password: "{{ grafana_password }}"
- name: "grafana_working_group"
- email: "foo.bar@example.com"
- members:
- - "john+doe@example.com"
- - "jane.doe@example.com"
- state: present
+ community.grafana.grafana_team:
+ url: "{{ grafana_url }}"
+ url_username: "{{ grafana_username }}"
+ url_password: "{{ grafana_password }}"
+ name: grafana working group
+ email: foo.bar@example.com
+ members:
+ - john+doe@example.com
+ - jane.doe@example.com
+ state: present
register: result
-- set_fact:
- expected_members: "{{ auto_member | ternary(['********@localhost', 'jane.doe@example.com', 'john+doe@example.com'], ['jane.doe@example.com', 'john+doe@example.com']) }}"
+- ansible.builtin.set_fact:
+ expected_members: "{{ auto_member | ternary(['********@localhost', 'jane.doe@example.com', 'john+doe@example.com'], ['jane.doe@example.com', 'john+doe@example.com'])
+ }}"
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.team.name == 'grafana_working_group'"
- - "result.team.email == 'foo.bar@example.com'"
- - "result.team.memberCount == (expected_members|length)"
- - "result.team.members == expected_members"
+ - result.changed == true
+ - result.team.name == 'grafana working group'
+ - result.team.email == 'foo.bar@example.com'
+ - result.team.memberCount == (expected_members|length)
+ - result.team.members == expected_members
+ when: not ansible_check_mode
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_user/defaults/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_user/defaults/main.yml
index 7bb77ea3f..3edac8598 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_user/defaults/main.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_user/defaults/main.yml
@@ -1,4 +1,4 @@
---
-grafana_url: "http://grafana:3000/"
-grafana_username: "admin"
-grafana_password: "admin"
+grafana_url: http://grafana:3000/
+grafana_username: admin
+grafana_password: admin
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_user/runme.sh b/ansible_collections/community/grafana/tests/integration/targets/grafana_user/runme.sh
new file mode 100755
index 000000000..9daa487db
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_user/runme.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+set -eux
+
+ansible-playbook site.yml --check
+ansible-playbook site.yml
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_user/site.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_user/site.yml
new file mode 100644
index 000000000..b080803f8
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_user/site.yml
@@ -0,0 +1,6 @@
+---
+- name: Run tests for grafana_user
+ hosts: localhost
+ tasks:
+ - ansible.builtin.include_role:
+ name: ../../grafana_user
diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_user/tasks/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_user/tasks/main.yml
index c62801653..83a3891e1 100644
--- a/ansible_collections/community/grafana/tests/integration/targets/grafana_user/tasks/main.yml
+++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_user/tasks/main.yml
@@ -1,237 +1,251 @@
---
- name: Create new admin
- grafana_user:
+ community.grafana.grafana_user:
url: "{{ grafana_url }}"
url_username: "{{ grafana_username }}"
url_password: "{{ grafana_password }}"
- name: "Harley Quinn"
+ name: Harley Quinn
email: harley.quinn@gotham.city
login: harley
password: Wy3ta6ob6M3wHELv58MPfqOe126RTnWpcYfEhyJm
is_admin: true
state: present
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.failed == false"
- - "result.user.name == 'Harley Quinn'"
- - "result.user.email == 'harley.quinn@gotham.city'"
- - "result.user.isGrafanaAdmin == true"
+ - result.changed == true
+ - result.failed == false
+ - result.user.name == 'Harley Quinn'
+ - result.user.email == 'harley.quinn@gotham.city'
+ - result.user.isGrafanaAdmin == true
+ when: not ansible_check_mode
- name: Check idempotency on admin creation
- grafana_user:
+ community.grafana.grafana_user:
url: "{{ grafana_url }}"
url_username: "{{ grafana_username }}"
url_password: "{{ grafana_password }}"
- name: "Harley Quinn"
+ name: Harley Quinn
email: harley.quinn@gotham.city
login: harley
password: Wy3ta6ob6M3wHELv58MPfqOe126RTnWpcYfEhyJm
is_admin: true
state: present
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == false"
- - "result.user.name == 'Harley Quinn'"
- - "result.user.email == 'harley.quinn@gotham.city'"
- - "result.user.isGrafanaAdmin == true"
+ - result.changed == false
+ - result.user.name == 'Harley Quinn'
+ - result.user.email == 'harley.quinn@gotham.city'
+ - result.user.isGrafanaAdmin == true
+ when: not ansible_check_mode
- name: Check user creation with Grafana API
- uri:
+ ansible.builtin.uri:
url: "{{ grafana_url }}api/users/lookup?loginOrEmail=harley"
user: "{{ grafana_username }}"
password: "{{ grafana_password }}"
- force_basic_auth: yes
+ force_basic_auth: true
status_code: 200
headers:
Accept: application/json
Content-Type: application/json
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.json.name == 'Harley Quinn'"
- - "result.json.email == 'harley.quinn@gotham.city'"
- - "result.json.isGrafanaAdmin == true"
+ - result.json.name == 'Harley Quinn'
+ - result.json.email == 'harley.quinn@gotham.city'
+ - result.json.isGrafanaAdmin == true
+ when: not ansible_check_mode
- name: Create a Grafana user without password (expect failure)
- grafana_user:
+ community.grafana.grafana_user:
url: "{{ grafana_url }}"
url_username: "{{ grafana_username }}"
url_password: "{{ grafana_password }}"
- name: "Bruce Wayne"
+ name: Bruce Wayne
email: batman@gotham.city
login: batman
state: present
register: result
- ignore_errors: yes
-- assert:
+ ignore_errors: true
+- ansible.builtin.assert:
that:
- - "result.changed == false"
- - "result.failed == true"
+ - result.changed == false
+ - result.failed == true
- "result.msg == 'missing required arguments: password'"
+ when: not ansible_check_mode
- name: Create a Grafana user
- grafana_user:
+ community.grafana.grafana_user:
url: "{{ grafana_url }}"
url_username: "{{ grafana_username }}"
url_password: "{{ grafana_password }}"
- name: "Bruce Wayne"
+ name: Bruce Wayne
email: batman@gotham.city
login: batman
password: robin
state: present
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.user.name == 'Bruce Wayne'"
- - "result.user.email == 'batman@gotham.city'"
- - "result.user.isGrafanaAdmin == false"
+ - result.changed == true
+ - result.user.name == 'Bruce Wayne'
+ - result.user.email == 'batman@gotham.city'
+ - result.user.isGrafanaAdmin == false
+ when: not ansible_check_mode
- name: Check idempotency on user creation (password not requiered)
- grafana_user:
+ community.grafana.grafana_user:
url: "{{ grafana_url }}"
url_username: "{{ grafana_username }}"
url_password: "{{ grafana_password }}"
- name: "Bruce Wayne"
+ name: Bruce Wayne
email: batman@gotham.city
login: batman
state: present
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == false"
- - "result.user.name == 'Bruce Wayne'"
- - "result.user.email == 'batman@gotham.city'"
- - "result.user.isGrafanaAdmin == false"
+ - result.changed == false
+ - result.user.name == 'Bruce Wayne'
+ - result.user.email == 'batman@gotham.city'
+ - result.user.isGrafanaAdmin == false
+ when: not ansible_check_mode
- name: Check user creation with Grafana API
- uri:
+ ansible.builtin.uri:
url: "{{ grafana_url }}api/users/lookup?loginOrEmail=batman"
user: "{{ grafana_username }}"
password: "{{ grafana_password }}"
- force_basic_auth: yes
+ force_basic_auth: true
status_code: 200
headers:
Accept: application/json
Content-Type: application/json
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.json.name == 'Bruce Wayne'"
- - "result.json.email == 'batman@gotham.city'"
- - "result.json.isGrafanaAdmin == false"
+ - result.json.name == 'Bruce Wayne'
+ - result.json.email == 'batman@gotham.city'
+ - result.json.isGrafanaAdmin == false
+ when: not ansible_check_mode
- name: Update Grafana user
- grafana_user:
+ community.grafana.grafana_user:
url: "{{ grafana_url }}"
url_username: "{{ grafana_username }}"
url_password: "{{ grafana_password }}"
- name: "The Dark Knight"
+ name: The Dark Knight
email: thedarkknight@gotham.city
login: batman
password: robin
is_admin: true
state: present
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.user.name == 'The Dark Knight'"
- - "result.user.email == 'thedarkknight@gotham.city'"
- - "result.user.isGrafanaAdmin == true"
+ - result.changed == true
+ - result.user.name == 'The Dark Knight'
+ - result.user.email == 'thedarkknight@gotham.city'
+ - result.user.isGrafanaAdmin == true
+ when: not ansible_check_mode
- name: Check user update with Grafana API
- uri:
+ ansible.builtin.uri:
url: "{{ grafana_url }}api/users/lookup?loginOrEmail=batman"
user: "{{ grafana_username }}"
password: "{{ grafana_password }}"
- force_basic_auth: yes
+ force_basic_auth: true
status_code: 200
headers:
Accept: application/json
Content-Type: application/json
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.json.name == 'The Dark Knight'"
- - "result.json.email == 'thedarkknight@gotham.city'"
- - "result.json.isGrafanaAdmin == true"
+ - result.json.name == 'The Dark Knight'
+ - result.json.email == 'thedarkknight@gotham.city'
+ - result.json.isGrafanaAdmin == true
+ when: not ansible_check_mode
- name: Delete a Grafana user
- grafana_user:
+ community.grafana.grafana_user:
url: "{{ grafana_url }}"
url_username: "{{ grafana_username }}"
url_password: "{{ grafana_password }}"
login: batman
state: absent
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.message == 'User deleted'"
+ - result.changed == true
+ - result.message == 'User deleted'
+ when: not ansible_check_mode
- name: Check idempotency on user deletion
- grafana_user:
+ community.grafana.grafana_user:
url: "{{ grafana_url }}"
url_username: "{{ grafana_username }}"
url_password: "{{ grafana_password }}"
login: batman
state: absent
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == false"
- - "result.message == 'No user found, nothing to do'"
+ - result.changed == false
+ - result.message == 'No user found, nothing to do'
+ when: not ansible_check_mode
- name: Check user deletion with Grafana API (expect 404 Not Found)
- uri:
+ ansible.builtin.uri:
url: "{{ grafana_url }}api/users/lookup?loginOrEmail=batman"
user: "{{ grafana_username }}"
password: "{{ grafana_password }}"
- force_basic_auth: yes
+ force_basic_auth: true
status_code: 404
headers:
Accept: application/json
Content-Type: application/json
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.json.message | lower == 'user not found'"
+ - result.json.message | lower == 'user not found'
+ when: not ansible_check_mode
- name: Create a Grafana user with character encoding
- grafana_user:
+ community.grafana.grafana_user:
url: "{{ grafana_url }}"
url_username: "{{ grafana_username }}"
url_password: "{{ grafana_password }}"
- name: "Bruce Wayne"
+ name: Bruce Wayne
email: bruce+wayne@gotham.city
login: bruce+wayne@gotham.city
password: robin
state: present
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == true"
- - "result.user.name == 'Bruce Wayne'"
- - "result.user.email == 'bruce+wayne@gotham.city'"
- - "result.user.isGrafanaAdmin == false"
+ - result.changed == true
+ - result.user.name == 'Bruce Wayne'
+ - result.user.email == 'bruce+wayne@gotham.city'
+ - result.user.isGrafanaAdmin == false
+ when: not ansible_check_mode
- name: Check idempotency on user creation (password not requiered)
- grafana_user:
+ community.grafana.grafana_user:
url: "{{ grafana_url }}"
url_username: "{{ grafana_username }}"
url_password: "{{ grafana_password }}"
- name: "Bruce Wayne"
+ name: Bruce Wayne
email: bruce+wayne@gotham.city
login: bruce+wayne@gotham.city
state: present
register: result
-- assert:
+- ansible.builtin.assert:
that:
- - "result.changed == false"
- - "result.user.name == 'Bruce Wayne'"
- - "result.user.email == 'bruce+wayne@gotham.city'"
- - "result.user.isGrafanaAdmin == false"
+ - result.changed == false
+ - result.user.name == 'Bruce Wayne'
+ - result.user.email == 'bruce+wayne@gotham.city'
+ - result.user.isGrafanaAdmin == false
+ when: not ansible_check_mode
diff --git a/ansible_collections/community/grafana/tests/requirements.yml b/ansible_collections/community/grafana/tests/requirements.yml
new file mode 100644
index 000000000..b9d14e2c3
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/requirements.yml
@@ -0,0 +1,3 @@
+collections:
+ - name: community.grafana
+ version: 1.5.3
diff --git a/ansible_collections/community/grafana/tests/sanity/ignore-2.16.txt b/ansible_collections/community/grafana/tests/sanity/ignore-2.16.txt
new file mode 100644
index 000000000..5c82494f9
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/sanity/ignore-2.16.txt
@@ -0,0 +1,4 @@
+plugins/modules/grafana_dashboard.py validate-modules:invalid-argument-name
+tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py pep8:W291
+hacking/check_fragment.sh shebang
+hacking/find_grafana_versions.py shebang
diff --git a/ansible_collections/community/grafana/tests/sanity/ignore-2.17.txt b/ansible_collections/community/grafana/tests/sanity/ignore-2.17.txt
new file mode 100644
index 000000000..5c82494f9
--- /dev/null
+++ b/ansible_collections/community/grafana/tests/sanity/ignore-2.17.txt
@@ -0,0 +1,4 @@
+plugins/modules/grafana_dashboard.py validate-modules:invalid-argument-name
+tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py pep8:W291
+hacking/check_fragment.sh shebang
+hacking/find_grafana_versions.py shebang
diff --git a/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_datasource/test_grafana_datasource.py b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_datasource/test_grafana_datasource.py
index d2fba0fe1..ff8e4f242 100644
--- a/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_datasource/test_grafana_datasource.py
+++ b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_datasource/test_grafana_datasource.py
@@ -1,7 +1,7 @@
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
from unittest import TestCase
-from unittest.mock import call, patch, MagicMock
+from unittest.mock import patch
from ansible_collections.community.grafana.plugins.modules import grafana_datasource
from ansible.module_utils._text import to_bytes
from ansible.module_utils import basic
@@ -13,200 +13,207 @@ __metaclass__ = type
def set_module_args(args):
"""prepare arguments so that they will be picked up during module creation"""
- args = json.dumps({'ANSIBLE_MODULE_ARGS': args})
+ args = json.dumps({"ANSIBLE_MODULE_ARGS": args})
basic._ANSIBLE_ARGS = to_bytes(args)
def exit_json(*args, **kwargs):
"""function to patch over exit_json; package return data into an exception"""
- if 'changed' not in kwargs:
- kwargs['changed'] = False
+ if "changed" not in kwargs:
+ kwargs["changed"] = False
raise AnsibleExitJson(kwargs)
def fail_json(*args, **kwargs):
"""function to patch over fail_json; package return data into an exception"""
- kwargs['failed'] = True
+ kwargs["failed"] = True
raise AnsibleFailJson(kwargs)
class AnsibleExitJson(Exception):
"""Exception class to be raised by module.exit_json and caught by the test case"""
+
pass
class AnsibleFailJson(Exception):
"""Exception class to be raised by module.fail_json and caught by the test case"""
+
pass
class GrafanaDatasource(TestCase):
-
def setUp(self):
self.authorization = basic_auth_header("admin", "admin")
- self.mock_module_helper = patch.multiple(basic.AnsibleModule,
- exit_json=exit_json,
- fail_json=fail_json)
+ self.mock_module_helper = patch.multiple(
+ basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json
+ )
self.mock_module_helper.start()
self.addCleanup(self.mock_module_helper.stop)
def test_payload_prometheus(self):
expected_payload = {
- 'access': 'proxy',
- 'basicAuth': False,
- 'database': '',
- 'isDefault': False,
- 'jsonData': {
- 'tlsAuth': False,
- 'tlsAuthWithCACert': False,
- 'tlsSkipVerify': True
+ "access": "proxy",
+ "basicAuth": False,
+ "database": "",
+ "isDefault": False,
+ "jsonData": {
+ "tlsAuth": False,
+ "tlsAuthWithCACert": False,
+ "tlsSkipVerify": True,
},
- 'name': 'openshift_prometheus',
- 'uid': 'xyz123',
- 'orgId': 1,
- 'secureJsonData': {},
- 'type': 'prometheus',
- 'url': 'https://openshift-monitoring.company.com',
- 'user': '',
- 'withCredentials': False
+ "name": "openshift_prometheus",
+ "uid": "xyz123",
+ "orgId": 1,
+ "secureJsonData": {},
+ "type": "prometheus",
+ "url": "https://openshift-monitoring.company.com",
+ "user": "",
+ "withCredentials": False,
}
- set_module_args({
- 'url': 'https://grafana.example.com',
- 'url_username': 'admin',
- 'url_password': 'admin',
- 'name': 'openshift_prometheus',
- 'uid': 'xyz123',
- 'ds_type': 'prometheus',
- 'ds_url': 'https://openshift-monitoring.company.com',
- 'access': 'proxy',
- 'tls_skip_verify': 'true',
- })
+ set_module_args(
+ {
+ "url": "https://grafana.example.com",
+ "url_username": "admin",
+ "url_password": "admin",
+ "name": "openshift_prometheus",
+ "uid": "xyz123",
+ "ds_type": "prometheus",
+ "ds_url": "https://openshift-monitoring.company.com",
+ "access": "proxy",
+ "tls_skip_verify": "true",
+ }
+ )
module = grafana_datasource.setup_module_object()
payload = grafana_datasource.get_datasource_payload(module.params)
self.assertEqual(payload, expected_payload)
def test_payload_prometheus_with_basic_auth(self):
expected_payload = {
- 'access': 'proxy',
- 'basicAuth': True,
- 'basicAuthUser': 'admin',
- 'database': '',
- 'isDefault': False,
- 'jsonData': {
- 'tlsAuth': False,
- 'tlsAuthWithCACert': False,
- 'tlsSkipVerify': True
+ "access": "proxy",
+ "basicAuth": True,
+ "basicAuthUser": "admin",
+ "database": "",
+ "isDefault": False,
+ "jsonData": {
+ "tlsAuth": False,
+ "tlsAuthWithCACert": False,
+ "tlsSkipVerify": True,
},
- 'name': 'openshift_prometheus',
- 'uid': 'xyz123',
- 'orgId': 1,
- 'secureJsonData': {'basicAuthPassword': 'admin'},
- 'type': 'prometheus',
- 'url': 'https://openshift-monitoring.company.com',
- 'user': '',
- 'withCredentials': False
+ "name": "openshift_prometheus",
+ "uid": "xyz123",
+ "orgId": 1,
+ "secureJsonData": {"basicAuthPassword": "admin"},
+ "type": "prometheus",
+ "url": "https://openshift-monitoring.company.com",
+ "user": "",
+ "withCredentials": False,
}
- set_module_args({
- 'url': 'https://grafana.example.com',
- 'url_username': 'admin',
- 'url_password': 'admin',
- 'name': 'openshift_prometheus',
- 'uid': 'xyz123',
- 'ds_type': 'prometheus',
- 'ds_url': 'https://openshift-monitoring.company.com',
- 'access': 'proxy',
- 'basic_auth_user': 'admin',
- 'basic_auth_password': 'admin',
- 'tls_skip_verify': 'true',
- })
+ set_module_args(
+ {
+ "url": "https://grafana.example.com",
+ "url_username": "admin",
+ "url_password": "admin",
+ "name": "openshift_prometheus",
+ "uid": "xyz123",
+ "ds_type": "prometheus",
+ "ds_url": "https://openshift-monitoring.company.com",
+ "access": "proxy",
+ "basic_auth_user": "admin",
+ "basic_auth_password": "admin",
+ "tls_skip_verify": "true",
+ }
+ )
module = grafana_datasource.setup_module_object()
payload = grafana_datasource.get_datasource_payload(module.params)
self.assertEqual(payload, expected_payload)
def test_payload_influxdb(self):
expected_payload = {
- 'access': 'proxy',
- 'basicAuth': False,
- 'database': 'telegraf',
- 'isDefault': False,
- 'jsonData': {
- 'timeInterval': '>10s',
- 'tlsAuth': False,
- 'tlsAuthWithCACert': True
- },
- 'name': 'datasource-influxdb',
- 'uid': 'xyz123',
- 'orgId': 1,
- 'secureJsonData': {
- 'tlsCACert': '/etc/ssl/certs/ca.pem'
+ "access": "proxy",
+ "basicAuth": False,
+ "database": "telegraf",
+ "isDefault": False,
+ "jsonData": {
+ "timeInterval": ">10s",
+ "tlsAuth": False,
+ "tlsAuthWithCACert": True,
},
- 'type': 'influxdb',
- 'url': 'https://influx.company.com:8086',
- 'user': '',
- 'withCredentials': False
+ "name": "datasource-influxdb",
+ "uid": "xyz123",
+ "orgId": 1,
+ "secureJsonData": {"tlsCACert": "/etc/ssl/certs/ca.pem"},
+ "type": "influxdb",
+ "url": "https://influx.company.com:8086",
+ "user": "",
+ "withCredentials": False,
}
- set_module_args({
- 'url': 'https://grafana.example.com',
- 'url_username': 'admin',
- 'url_password': 'admin',
- 'name': 'datasource-influxdb',
- 'uid': 'xyz123',
- 'ds_type': 'influxdb',
- 'ds_url': 'https://influx.company.com:8086',
- 'database': 'telegraf',
- 'time_interval': '>10s',
- 'tls_ca_cert': '/etc/ssl/certs/ca.pem'
- })
+ set_module_args(
+ {
+ "url": "https://grafana.example.com",
+ "url_username": "admin",
+ "url_password": "admin",
+ "name": "datasource-influxdb",
+ "uid": "xyz123",
+ "ds_type": "influxdb",
+ "ds_url": "https://influx.company.com:8086",
+ "database": "telegraf",
+ "time_interval": ">10s",
+ "tls_ca_cert": "/etc/ssl/certs/ca.pem",
+ }
+ )
module = grafana_datasource.setup_module_object()
payload = grafana_datasource.get_datasource_payload(module.params)
self.assertEqual(payload, expected_payload)
def test_payload_elastic(self):
expected_payload = {
- 'access': 'proxy',
- 'basicAuth': True,
- 'basicAuthUser': 'grafana',
- 'database': '[logstash_]YYYY.MM.DD',
- 'isDefault': False,
- 'jsonData': {
- 'esVersion': 56,
- 'interval': 'Daily',
- 'maxConcurrentShardRequests': 42,
- 'timeField': '@timestamp',
- 'timeInterval': '1m',
- 'tlsAuth': False,
- 'tlsAuthWithCACert': True
+ "access": "proxy",
+ "basicAuth": True,
+ "basicAuthUser": "grafana",
+ "database": "[logstash_]YYYY.MM.DD",
+ "isDefault": False,
+ "jsonData": {
+ "esVersion": 56,
+ "interval": "Daily",
+ "maxConcurrentShardRequests": 42,
+ "timeField": "@timestamp",
+ "timeInterval": "1m",
+ "tlsAuth": False,
+ "tlsAuthWithCACert": True,
},
- 'name': 'datasource-elastic',
- 'uid': 'xyz123',
- 'orgId': 1,
- 'secureJsonData': {
- 'basicAuthPassword': 'grafana',
- 'tlsCACert': '/etc/ssl/certs/ca.pem'
+ "name": "datasource-elastic",
+ "uid": "xyz123",
+ "orgId": 1,
+ "secureJsonData": {
+ "basicAuthPassword": "grafana",
+ "tlsCACert": "/etc/ssl/certs/ca.pem",
},
- 'type': 'elasticsearch',
- 'url': 'https://elastic.company.com:9200',
- 'user': '',
- 'withCredentials': False
+ "type": "elasticsearch",
+ "url": "https://elastic.company.com:9200",
+ "user": "",
+ "withCredentials": False,
}
- set_module_args({
- 'url': 'https://grafana.example.com',
- 'url_username': 'admin',
- 'url_password': 'admin',
- 'name': 'datasource-elastic',
- 'uid': 'xyz123',
- 'ds_type': 'elasticsearch',
- 'ds_url': 'https://elastic.company.com:9200',
- 'database': '[logstash_]YYYY.MM.DD',
- 'basic_auth_user': 'grafana',
- 'basic_auth_password': 'grafana',
- 'time_field': '@timestamp',
- 'time_interval': '1m',
- 'interval': 'Daily',
- 'es_version': 56,
- 'max_concurrent_shard_requests': 42,
- 'tls_ca_cert': '/etc/ssl/certs/ca.pem'
- })
+ set_module_args(
+ {
+ "url": "https://grafana.example.com",
+ "url_username": "admin",
+ "url_password": "admin",
+ "name": "datasource-elastic",
+ "uid": "xyz123",
+ "ds_type": "elasticsearch",
+ "ds_url": "https://elastic.company.com:9200",
+ "database": "[logstash_]YYYY.MM.DD",
+ "basic_auth_user": "grafana",
+ "basic_auth_password": "grafana",
+ "time_field": "@timestamp",
+ "time_interval": "1m",
+ "interval": "Daily",
+ "es_version": 56,
+ "max_concurrent_shard_requests": 42,
+ "tls_ca_cert": "/etc/ssl/certs/ca.pem",
+ }
+ )
module = grafana_datasource.setup_module_object()
payload = grafana_datasource.get_datasource_payload(module.params)
self.assertEqual(payload, expected_payload)
diff --git a/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py
index b3b025c4e..ec691a467 100644
--- a/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py
+++ b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py
@@ -1,4 +1,4 @@
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
from unittest import TestCase
from unittest.mock import patch, MagicMock
@@ -53,14 +53,13 @@ Error: ✗ plugin does not exist
class GrafanaPlugin(TestCase):
-
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_plugin.grafana_cli_bin')
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_plugin.grafana_cli_bin"
+ )
def test_plugin_install_zip(self, mock_grafana_cli_bin):
mock_grafana_cli_bin.return_value = "grafana-cli plugins"
- params = {
- "name": "alexanderzobnin-zabbix-app"
- }
+ params = {"name": "alexanderzobnin-zabbix-app"}
module = MagicMock()
module.run_command.return_value = run_command_install_zip()
@@ -68,13 +67,13 @@ class GrafanaPlugin(TestCase):
result = grafana_plugin.get_grafana_plugin_version(module, params)
self.assertEqual(result, None)
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_plugin.grafana_cli_bin')
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_plugin.grafana_cli_bin"
+ )
def test_plugin_ls(self, mock_grafana_cli_bin):
mock_grafana_cli_bin.return_value = "grafana-cli plugins"
- params = {
- "name": "alexanderzobnin-zabbix-app"
- }
+ params = {"name": "alexanderzobnin-zabbix-app"}
module = MagicMock()
module.run_command.return_value = run_command_ls()
@@ -82,13 +81,13 @@ class GrafanaPlugin(TestCase):
result = grafana_plugin.get_grafana_plugin_version(module, params)
self.assertEqual(result, "3.10.5")
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_plugin.grafana_cli_bin')
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_plugin.grafana_cli_bin"
+ )
def test_plugin_uninstall(self, mock_grafana_cli_bin):
mock_grafana_cli_bin.return_value = "grafana-cli plugins"
- params = {
- "name": "alexanderzobnin-zabbix-app"
- }
+ params = {"name": "alexanderzobnin-zabbix-app"}
module = MagicMock()
module.run_command.return_value = run_command_uninstall()
@@ -96,13 +95,13 @@ class GrafanaPlugin(TestCase):
result = grafana_plugin.get_grafana_plugin_version(module, params)
self.assertEqual(result, None)
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_plugin.grafana_cli_bin')
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_plugin.grafana_cli_bin"
+ )
def test_plugin_uninstall_again(self, mock_grafana_cli_bin):
mock_grafana_cli_bin.return_value = "grafana-cli plugins"
- params = {
- "name": "alexanderzobnin-zabbix-app"
- }
+ params = {"name": "alexanderzobnin-zabbix-app"}
module = MagicMock()
module.run_command.return_value = run_command_uninstall_again()
diff --git a/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_team/test_grafana_team.py b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_team/test_grafana_team.py
index c59953afa..8efba998b 100644
--- a/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_team/test_grafana_team.py
+++ b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_team/test_grafana_team.py
@@ -1,7 +1,7 @@
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
from unittest import TestCase
-from unittest.mock import patch, MagicMock
+from unittest.mock import patch
from ansible_collections.community.grafana.plugins.modules import grafana_team
from ansible.module_utils._text import to_bytes
from ansible.module_utils import basic
@@ -21,30 +21,32 @@ class MockedReponse(object):
def exit_json(*args, **kwargs):
"""function to patch over exit_json; package return data into an exception"""
- if 'changed' not in kwargs:
- kwargs['changed'] = False
+ if "changed" not in kwargs:
+ kwargs["changed"] = False
raise AnsibleExitJson(kwargs)
def fail_json(*args, **kwargs):
"""function to patch over fail_json; package return data into an exception"""
- kwargs['failed'] = True
+ kwargs["failed"] = True
raise AnsibleFailJson(kwargs)
class AnsibleExitJson(Exception):
"""Exception class to be raised by module.exit_json and caught by the test case"""
+
pass
class AnsibleFailJson(Exception):
"""Exception class to be raised by module.fail_json and caught by the test case"""
+
pass
def set_module_args(args):
"""prepare arguments so that they will be picked up during module creation"""
- args = json.dumps({'ANSIBLE_MODULE_ARGS': args})
+ args = json.dumps({"ANSIBLE_MODULE_ARGS": args})
basic._ANSIBLE_ARGS = to_bytes(args)
@@ -65,7 +67,10 @@ def get_low_version_resp():
def team_exists_resp():
- server_response = json.dumps({"totalCount": 1, "teams": [{"name": "MyTestTeam", "email": "email@test.com"}]}, sort_keys=True)
+ server_response = json.dumps(
+ {"totalCount": 1, "teams": [{"name": "MyTestTeam", "email": "email@test.com"}]},
+ sort_keys=True,
+ )
return (MockedReponse(server_response), {"status": 200})
@@ -90,21 +95,26 @@ def team_deleted_resp():
def team_members_resp():
- server_response = json.dumps([{
- "orgId": 1,
- "teamId": 2,
- "userId": 3,
- "email": "user1@email.com",
- "login": "user1",
- "avatarUrl": r"\/avatar\/1b3c32f6386b0185c40d359cdc733a79"
- }, {
- "orgId": 1,
- "teamId": 2,
- "userId": 2,
- "email": "user2@email.com",
- "login": "user2",
- "avatarUrl": r"\/avatar\/cad3c68da76e45d10269e8ef02f8e73e"
- }])
+ server_response = json.dumps(
+ [
+ {
+ "orgId": 1,
+ "teamId": 2,
+ "userId": 3,
+ "email": "user1@email.com",
+ "login": "user1",
+ "avatarUrl": r"\/avatar\/1b3c32f6386b0185c40d359cdc733a79",
+ },
+ {
+ "orgId": 1,
+ "teamId": 2,
+ "userId": 2,
+ "email": "user2@email.com",
+ "login": "user2",
+ "avatarUrl": r"\/avatar\/cad3c68da76e45d10269e8ef02f8e73e",
+ },
+ ]
+ )
return (MockedReponse(server_response), {"status": 200})
@@ -124,12 +134,11 @@ def delete_team_member_resp():
class GrafanaTeamsTest(TestCase):
-
def setUp(self):
self.authorization = basic_auth_header("admin", "admin")
- self.mock_module_helper = patch.multiple(basic.AnsibleModule,
- exit_json=exit_json,
- fail_json=fail_json)
+ self.mock_module_helper = patch.multiple(
+ basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json
+ )
self.mock_module_helper.start()
self.addCleanup(self.mock_module_helper.stop)
@@ -139,112 +148,148 @@ class GrafanaTeamsTest(TestCase):
with self.assertRaises(AnsibleFailJson) as result:
grafana_team.main()
- err, arg_list = result.exception.args[0]['msg'].split(':')
- missing_args = [item.strip() for item in arg_list.split(',')]
- self.assertEqual(err, 'missing required arguments')
+ err, arg_list = result.exception.args[0]["msg"].split(":")
+ self.assertEqual(err, "missing required arguments")
self.assertEqual(arg_list, ["name", "email", "url"])
def test_module_setup_fails_without_name(self):
- set_module_args({
- 'email': 'email@test.com',
- 'url': 'http://grafana.example.com'
- })
+ set_module_args(
+ {"email": "email@test.com", "url": "http://grafana.example.com"}
+ )
with self.assertRaises(AnsibleFailJson) as result:
grafana_team.main()
- self.assertEqual(result.exception.args[0]['msg'], 'missing required arguments: name')
+ self.assertEqual(
+ result.exception.args[0]["msg"], "missing required arguments: name"
+ )
def test_module_setup_fails_without_email(self):
- set_module_args({
- 'name': 'MyTestTeam',
- 'url': 'http://grafana.example.com'
- })
+ set_module_args({"name": "MyTestTeam", "url": "http://grafana.example.com"})
with self.assertRaises(AnsibleFailJson) as result:
grafana_team.main()
- self.assertEqual(result.exception.args[0]['msg'], 'missing required arguments: email')
+ self.assertEqual(
+ result.exception.args[0]["msg"], "missing required arguments: email"
+ )
def test_module_setup_fails_without_url(self):
- set_module_args({
- 'name': 'MyTestTeam',
- 'email': 'email@test.com',
- })
+ set_module_args(
+ {
+ "name": "MyTestTeam",
+ "email": "email@test.com",
+ }
+ )
with self.assertRaises(AnsibleFailJson) as result:
grafana_team.main()
- self.assertEqual(result.exception.args[0]['msg'], 'missing required arguments: url')
+ self.assertEqual(
+ result.exception.args[0]["msg"], "missing required arguments: url"
+ )
def test_module_setup_fails_with_mutually_exclusive_auth_methods(self):
- set_module_args({
- 'name': 'MyTestTeam',
- 'email': 'email@test.com',
- 'url': 'http://grafana.example.com',
- 'grafana_user': 'admin',
- 'grafana_api_key': 'random_api_key',
- })
+ set_module_args(
+ {
+ "name": "MyTestTeam",
+ "email": "email@test.com",
+ "url": "http://grafana.example.com",
+ "grafana_user": "admin",
+ "grafana_api_key": "random_api_key",
+ }
+ )
with self.assertRaises(AnsibleFailJson) as result:
grafana_team.main()
- self.assertEqual(result.exception.args[0]['msg'], 'parameters are mutually exclusive: url_username|grafana_api_key')
-
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version')
+ self.assertEqual(
+ result.exception.args[0]["msg"],
+ "parameters are mutually exclusive: url_username|grafana_api_key",
+ )
+
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version"
+ )
def test_module_fails_with_low_grafana_version(self, mock_get_version):
- set_module_args({
- 'name': 'MyTestTeam',
- 'email': 'email@test.com',
- 'url': 'http://grafana.example.com',
- 'grafana_user': 'admin',
- 'grafana_password': 'admin',
- })
+ set_module_args(
+ {
+ "name": "MyTestTeam",
+ "email": "email@test.com",
+ "url": "http://grafana.example.com",
+ "grafana_user": "admin",
+ "grafana_password": "admin",
+ }
+ )
- module = grafana_team.setup_module_object()
mock_get_version.return_value = get_low_version_resp()
with self.assertRaises(AnsibleFailJson) as result:
grafana_team.main()
- self.assertEqual(result.exception.args[0]['msg'], 'Teams API is available starting Grafana v5')
-
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version')
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url')
- def test_module_failure_with_unauthorized_resp(self, mock_fetch_url, mock_get_version):
- set_module_args({
- 'name': 'MyTestTeam',
- 'email': 'email@test.com',
- 'url': 'http://grafana.example.com',
- })
- module = grafana_team.setup_module_object()
+ self.assertEqual(
+ result.exception.args[0]["msg"],
+ "Teams API is available starting Grafana v5",
+ )
+
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version"
+ )
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url"
+ )
+ def test_module_failure_with_unauthorized_resp(
+ self, mock_fetch_url, mock_get_version
+ ):
+ set_module_args(
+ {
+ "name": "MyTestTeam",
+ "email": "email@test.com",
+ "url": "http://grafana.example.com",
+ }
+ )
mock_fetch_url.return_value = unauthorized_resp()
mock_get_version.return_value = get_version_resp()
with self.assertRaises(AnsibleFailJson) as result:
grafana_team.main()
- self.assertTrue(result.exception.args[0]['msg'].startswith('Unauthorized to perform action'))
-
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version')
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url')
- def test_module_failure_with_permission_denied_resp(self, mock_fetch_url, mock_get_version):
- set_module_args({
- 'name': 'MyTestTeam',
- 'email': 'email@test.com',
- 'url': 'http://grafana.example.com',
- })
- module = grafana_team.setup_module_object()
+ self.assertTrue(
+ result.exception.args[0]["msg"].startswith("Unauthorized to perform action")
+ )
+
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version"
+ )
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url"
+ )
+ def test_module_failure_with_permission_denied_resp(
+ self, mock_fetch_url, mock_get_version
+ ):
+ set_module_args(
+ {
+ "name": "MyTestTeam",
+ "email": "email@test.com",
+ "url": "http://grafana.example.com",
+ }
+ )
mock_fetch_url.return_value = permission_denied_resp()
mock_get_version.return_value = get_version_resp()
with self.assertRaises(AnsibleFailJson) as result:
grafana_team.main()
- self.assertTrue(result.exception.args[0]['msg'].startswith('Permission Denied'))
-
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version')
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url')
+ self.assertTrue(result.exception.args[0]["msg"].startswith("Permission Denied"))
+
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version"
+ )
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url"
+ )
def test_get_team_method_with_existing_team(self, mock_fetch_url, mock_get_version):
- set_module_args({
- 'state': 'present',
- 'name': 'MyTestTeam',
- 'email': 'email@test.com',
- 'url': 'http://grafana.example.com'
- })
+ set_module_args(
+ {
+ "state": "present",
+ "name": "MyTestTeam",
+ "email": "email@test.com",
+ "url": "http://grafana.example.com",
+ }
+ )
module = grafana_team.setup_module_object()
mock_fetch_url.return_value = team_exists_resp()
mock_get_version.return_value = get_version_resp()
@@ -252,21 +297,34 @@ class GrafanaTeamsTest(TestCase):
grafana_iface = grafana_team.GrafanaTeamInterface(module)
res = grafana_iface.get_team("MyTestTeam")
mock_fetch_url.assert_called_once_with(
- module, 'http://grafana.example.com/api/teams/search?name=MyTestTeam',
+ module,
+ "http://grafana.example.com/api/teams/search?name=MyTestTeam",
data=None,
- headers={'Content-Type': 'application/json', 'Authorization': self.authorization},
- method='GET')
- self.assertEquals(res, {"email": "email@test.com", "name": "MyTestTeam"})
-
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version')
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url')
- def test_get_team_method_with_non_existing_team(self, mock_fetch_url, mock_get_version):
- set_module_args({
- 'state': 'present',
- 'name': 'MyTestTeam',
- 'email': 'email@test.com',
- 'url': 'http://grafana.example.com'
- })
+ headers={
+ "Content-Type": "application/json",
+ "Authorization": self.authorization,
+ },
+ method="GET",
+ )
+ self.assertEqual(res, {"email": "email@test.com", "name": "MyTestTeam"})
+
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version"
+ )
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url"
+ )
+ def test_get_team_method_with_non_existing_team(
+ self, mock_fetch_url, mock_get_version
+ ):
+ set_module_args(
+ {
+ "state": "present",
+ "name": "MyTestTeam",
+ "email": "email@test.com",
+ "url": "http://grafana.example.com",
+ }
+ )
module = grafana_team.setup_module_object()
mock_fetch_url.return_value = team_not_found_resp()
mock_get_version.return_value = get_version_resp()
@@ -274,21 +332,32 @@ class GrafanaTeamsTest(TestCase):
grafana_iface = grafana_team.GrafanaTeamInterface(module)
res = grafana_iface.get_team("MyTestTeam")
mock_fetch_url.assert_called_once_with(
- module, 'http://grafana.example.com/api/teams/search?name=MyTestTeam',
+ module,
+ "http://grafana.example.com/api/teams/search?name=MyTestTeam",
data=None,
- headers={'Content-Type': 'application/json', 'Authorization': self.authorization},
- method='GET')
- self.assertEquals(res, None)
-
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version')
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url')
+ headers={
+ "Content-Type": "application/json",
+ "Authorization": self.authorization,
+ },
+ method="GET",
+ )
+ self.assertEqual(res, None)
+
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version"
+ )
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url"
+ )
def test_create_team_method(self, mock_fetch_url, mock_get_version):
- set_module_args({
- 'state': 'present',
- 'name': 'MyTestTeam',
- 'email': 'email@test.com',
- 'url': 'http://grafana.example.com'
- })
+ set_module_args(
+ {
+ "state": "present",
+ "name": "MyTestTeam",
+ "email": "email@test.com",
+ "url": "http://grafana.example.com",
+ }
+ )
module = grafana_team.setup_module_object()
mock_fetch_url.return_value = team_created_resp()
mock_get_version.return_value = get_version_resp()
@@ -297,21 +366,34 @@ class GrafanaTeamsTest(TestCase):
res = grafana_iface.create_team("MyTestTeam", "email@test.com")
mock_fetch_url.assert_called_once_with(
- module, 'http://grafana.example.com/api/teams',
- data=json.dumps({"email": "email@test.com", "name": "MyTestTeam"}, sort_keys=True),
- headers={'Content-Type': 'application/json', 'Authorization': self.authorization},
- method='POST')
- self.assertEquals(res, {"message": "Team created", "teamId": 2})
-
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version')
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url')
+ module,
+ "http://grafana.example.com/api/teams",
+ data=json.dumps(
+ {"email": "email@test.com", "name": "MyTestTeam"}, sort_keys=True
+ ),
+ headers={
+ "Content-Type": "application/json",
+ "Authorization": self.authorization,
+ },
+ method="POST",
+ )
+ self.assertEqual(res, {"message": "Team created", "teamId": 2})
+
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version"
+ )
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url"
+ )
def test_update_team_method(self, mock_fetch_url, mock_get_version):
- set_module_args({
- 'state': 'present',
- 'name': 'MyTestTeam',
- 'email': 'email@test.com',
- 'url': 'http://grafana.example.com'
- })
+ set_module_args(
+ {
+ "state": "present",
+ "name": "MyTestTeam",
+ "email": "email@test.com",
+ "url": "http://grafana.example.com",
+ }
+ )
module = grafana_team.setup_module_object()
mock_fetch_url.return_value = team_updated_resp()
mock_get_version.return_value = get_version_resp()
@@ -319,21 +401,34 @@ class GrafanaTeamsTest(TestCase):
grafana_iface = grafana_team.GrafanaTeamInterface(module)
res = grafana_iface.update_team(2, "MyTestTeam", "email@test.com")
mock_fetch_url.assert_called_once_with(
- module, 'http://grafana.example.com/api/teams/2',
- data=json.dumps({"email": "email@test.com", "name": "MyTestTeam"}, sort_keys=True),
- headers={'Content-Type': 'application/json', 'Authorization': self.authorization},
- method='PUT')
- self.assertEquals(res, {"message": "Team updated"})
-
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version')
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url')
+ module,
+ "http://grafana.example.com/api/teams/2",
+ data=json.dumps(
+ {"email": "email@test.com", "name": "MyTestTeam"}, sort_keys=True
+ ),
+ headers={
+ "Content-Type": "application/json",
+ "Authorization": self.authorization,
+ },
+ method="PUT",
+ )
+ self.assertEqual(res, {"message": "Team updated"})
+
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version"
+ )
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url"
+ )
def test_delete_team_method(self, mock_fetch_url, mock_get_version):
- set_module_args({
- 'state': 'absent',
- 'name': 'MyTestTeam',
- 'email': 'email@test.com',
- 'url': 'http://grafana.example.com'
- })
+ set_module_args(
+ {
+ "state": "absent",
+ "name": "MyTestTeam",
+ "email": "email@test.com",
+ "url": "http://grafana.example.com",
+ }
+ )
module = grafana_team.setup_module_object()
mock_fetch_url.return_value = team_deleted_resp()
mock_get_version.return_value = get_version_resp()
@@ -341,21 +436,32 @@ class GrafanaTeamsTest(TestCase):
grafana_iface = grafana_team.GrafanaTeamInterface(module)
res = grafana_iface.delete_team(2)
mock_fetch_url.assert_called_once_with(
- module, 'http://grafana.example.com/api/teams/2',
+ module,
+ "http://grafana.example.com/api/teams/2",
data=None,
- headers={'Content-Type': 'application/json', 'Authorization': self.authorization},
- method='DELETE')
- self.assertEquals(res, {"message": "Team deleted"})
-
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version')
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url')
+ headers={
+ "Content-Type": "application/json",
+ "Authorization": self.authorization,
+ },
+ method="DELETE",
+ )
+ self.assertEqual(res, {"message": "Team deleted"})
+
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version"
+ )
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url"
+ )
def test_get_team_members_method(self, mock_fetch_url, mock_get_version):
- set_module_args({
- 'state': 'present',
- 'name': 'MyTestTeam',
- 'email': 'email@test.com',
- 'url': 'http://grafana.example.com'
- })
+ set_module_args(
+ {
+ "state": "present",
+ "name": "MyTestTeam",
+ "email": "email@test.com",
+ "url": "http://grafana.example.com",
+ }
+ )
module = grafana_team.setup_module_object()
mock_fetch_url.return_value = team_members_resp()
mock_get_version.return_value = get_version_resp()
@@ -363,21 +469,34 @@ class GrafanaTeamsTest(TestCase):
grafana_iface = grafana_team.GrafanaTeamInterface(module)
res = grafana_iface.get_team_members(2)
mock_fetch_url.assert_called_once_with(
- module, 'http://grafana.example.com/api/teams/2/members',
+ module,
+ "http://grafana.example.com/api/teams/2/members",
data=None,
- headers={'Content-Type': 'application/json', 'Authorization': self.authorization},
- method='GET')
- self.assertEquals(res, ["user1@email.com", "user2@email.com"])
-
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version')
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url')
- def test_get_team_members_method_no_members_returned(self, mock_fetch_url, mock_get_version):
- set_module_args({
- 'state': 'present',
- 'name': 'MyTestTeam',
- 'email': 'email@test.com',
- 'url': 'http://grafana.example.com'
- })
+ headers={
+ "Content-Type": "application/json",
+ "Authorization": self.authorization,
+ },
+ method="GET",
+ )
+ self.assertEqual(res, ["user1@email.com", "user2@email.com"])
+
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version"
+ )
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url"
+ )
+ def test_get_team_members_method_no_members_returned(
+ self, mock_fetch_url, mock_get_version
+ ):
+ set_module_args(
+ {
+ "state": "present",
+ "name": "MyTestTeam",
+ "email": "email@test.com",
+ "url": "http://grafana.example.com",
+ }
+ )
module = grafana_team.setup_module_object()
mock_fetch_url.return_value = team_members_no_members_resp()
mock_get_version.return_value = get_version_resp()
@@ -385,63 +504,96 @@ class GrafanaTeamsTest(TestCase):
grafana_iface = grafana_team.GrafanaTeamInterface(module)
res = grafana_iface.get_team_members(2)
mock_fetch_url.assert_called_once_with(
- module, 'http://grafana.example.com/api/teams/2/members',
+ module,
+ "http://grafana.example.com/api/teams/2/members",
data=None,
- headers={'Content-Type': 'application/json', 'Authorization': self.authorization},
- method='GET')
- self.assertEquals(res, [])
-
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version')
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url')
+ headers={
+ "Content-Type": "application/json",
+ "Authorization": self.authorization,
+ },
+ method="GET",
+ )
+ self.assertEqual(res, [])
+
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version"
+ )
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url"
+ )
def test_add_team_member_method(self, mock_fetch_url, mock_get_version):
- set_module_args({
- 'state': 'present',
- 'name': 'MyTestTeam',
- 'email': 'email@test.com',
- 'url': 'http://grafana.example.com'
- })
+ set_module_args(
+ {
+ "state": "present",
+ "name": "MyTestTeam",
+ "email": "email@test.com",
+ "url": "http://grafana.example.com",
+ }
+ )
module = grafana_team.setup_module_object()
mock_fetch_url.return_value = add_team_member_resp()
mock_get_version.return_value = get_version_resp()
grafana_iface = grafana_team.GrafanaTeamInterface(module)
- with patch.object(grafana_team.GrafanaTeamInterface, 'get_user_id_from_mail') as mock_get_user_id_from_mail:
+ with patch.object(
+ grafana_team.GrafanaTeamInterface, "get_user_id_from_mail"
+ ) as mock_get_user_id_from_mail:
mock_get_user_id_from_mail.return_value = 42
res = grafana_iface.add_team_member(2, "another@test.com")
mock_fetch_url.assert_called_once_with(
- module, 'http://grafana.example.com/api/teams/2/members',
- data=json.dumps({'userId': 42}),
- headers={'Content-Type': 'application/json', 'Authorization': self.authorization},
- method='POST')
- self.assertEquals(res, None)
-
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version')
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url')
+ module,
+ "http://grafana.example.com/api/teams/2/members",
+ data=json.dumps({"userId": 42}),
+ headers={
+ "Content-Type": "application/json",
+ "Authorization": self.authorization,
+ },
+ method="POST",
+ )
+ self.assertEqual(res, None)
+
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.GrafanaTeamInterface.get_version"
+ )
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_team.fetch_url"
+ )
def test_delete_team_member_method(self, mock_fetch_url, mock_get_version):
- set_module_args({
- 'state': 'present',
- 'name': 'MyTestTeam',
- 'email': 'email@test.com',
- 'url': 'http://grafana.example.com'
- })
+ set_module_args(
+ {
+ "state": "present",
+ "name": "MyTestTeam",
+ "email": "email@test.com",
+ "url": "http://grafana.example.com",
+ }
+ )
module = grafana_team.setup_module_object()
mock_fetch_url.return_value = delete_team_member_resp()
mock_get_version.return_value = get_version_resp()
grafana_iface = grafana_team.GrafanaTeamInterface(module)
- with patch.object(grafana_team.GrafanaTeamInterface, 'get_user_id_from_mail') as mock_get_user_id_from_mail:
+ with patch.object(
+ grafana_team.GrafanaTeamInterface, "get_user_id_from_mail"
+ ) as mock_get_user_id_from_mail:
mock_get_user_id_from_mail.return_value = 42
res = grafana_iface.delete_team_member(2, "another@test.com")
mock_fetch_url.assert_called_once_with(
- module, 'http://grafana.example.com/api/teams/2/members/42',
+ module,
+ "http://grafana.example.com/api/teams/2/members/42",
data=None,
- headers={'Content-Type': 'application/json', 'Authorization': self.authorization},
- method='DELETE')
- self.assertEquals(res, None)
+ headers={
+ "Content-Type": "application/json",
+ "Authorization": self.authorization,
+ },
+ method="DELETE",
+ )
+ self.assertEqual(res, None)
def test_diff_members_function(self):
list1 = ["foo@example.com", "bar@example.com"]
list2 = ["bar@example.com", "random@example.com"]
res = grafana_team.diff_members(list1, list2)
- self.assertEquals(res, {"to_del": ["random@example.com"], "to_add": ["foo@example.com"]})
+ self.assertEqual(
+ res, {"to_del": ["random@example.com"], "to_add": ["foo@example.com"]}
+ )
diff --git a/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_user/test_grafana_user.py b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_user/test_grafana_user.py
index 925c01655..09d0dce05 100644
--- a/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_user/test_grafana_user.py
+++ b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_user/test_grafana_user.py
@@ -1,7 +1,7 @@
-from __future__ import (absolute_import, division, print_function)
+from __future__ import absolute_import, division, print_function
from unittest import TestCase
-from unittest.mock import call, patch, MagicMock
+from unittest.mock import call, patch
from ansible_collections.community.grafana.plugins.modules import grafana_user
from ansible.module_utils._text import to_bytes
from ansible.module_utils import basic
@@ -21,30 +21,32 @@ class MockedReponse(object):
def exit_json(*args, **kwargs):
"""function to patch over exit_json; package return data into an exception"""
- if 'changed' not in kwargs:
- kwargs['changed'] = False
+ if "changed" not in kwargs:
+ kwargs["changed"] = False
raise AnsibleExitJson(kwargs)
def fail_json(*args, **kwargs):
"""function to patch over fail_json; package return data into an exception"""
- kwargs['failed'] = True
+ kwargs["failed"] = True
raise AnsibleFailJson(kwargs)
class AnsibleExitJson(Exception):
"""Exception class to be raised by module.exit_json and caught by the test case"""
+
pass
class AnsibleFailJson(Exception):
"""Exception class to be raised by module.fail_json and caught by the test case"""
+
pass
def set_module_args(args):
"""prepare arguments so that they will be picked up during module creation"""
- args = json.dumps({'ANSIBLE_MODULE_ARGS': args})
+ args = json.dumps({"ANSIBLE_MODULE_ARGS": args})
basic._ANSIBLE_ARGS = to_bytes(args)
@@ -59,75 +61,94 @@ def user_already_exists_resp():
def user_created_resp():
- server_response = json.dumps({
- "id": 2,
- "email": "robin@gotham.com",
- "name": "Robin",
- "login": "adrobinmin",
- "theme": "light",
- "orgId": 1,
- "isGrafanaAdmin": False,
- "isDisabled": False,
- "isExternal": False,
- "authLabels": None,
- "updatedAt": "2019-09-25T14:44:37+01:00",
- "createdAt": "2019-09-25T14:44:37+01:00"
- }, sort_keys=True)
+ server_response = json.dumps(
+ {
+ "id": 2,
+ "email": "robin@gotham.com",
+ "name": "Robin",
+ "login": "adrobinmin",
+ "theme": "light",
+ "orgId": 1,
+ "isGrafanaAdmin": False,
+ "isDisabled": False,
+ "isExternal": False,
+ "authLabels": None,
+ "updatedAt": "2019-09-25T14:44:37+01:00",
+ "createdAt": "2019-09-25T14:44:37+01:00",
+ },
+ sort_keys=True,
+ )
return (MockedReponse(server_response), {"status": 200})
class GrafanaUserTest(TestCase):
-
def setUp(self):
self.authorization = basic_auth_header("admin", "changeme")
- self.mock_module_helper = patch.multiple(basic.AnsibleModule,
- exit_json=exit_json,
- fail_json=fail_json)
+ self.mock_module_helper = patch.multiple(
+ basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json
+ )
self.mock_module_helper.start()
self.addCleanup(self.mock_module_helper.stop)
# create an already existing user
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_user.fetch_url')
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_user.fetch_url"
+ )
def test_create_user_existing_user(self, mock_fetch_url):
- set_module_args({
- 'url': 'https://grafana.example.com',
- 'url_username': 'admin',
- 'url_password': 'changeme',
- 'name': 'Joker',
- 'email': 'joker@gotham.com',
- 'login': 'joker',
- 'password': 'oups',
- 'state': 'present'
- })
+ set_module_args(
+ {
+ "url": "https://grafana.example.com",
+ "url_username": "admin",
+ "url_password": "changeme",
+ "name": "Joker",
+ "email": "joker@gotham.com",
+ "login": "joker",
+ "password": "oups",
+ "state": "present",
+ }
+ )
module = grafana_user.setup_module_object()
mock_fetch_url.return_value = user_already_exists_resp()
grafana_iface = grafana_user.GrafanaUserInterface(module)
with self.assertRaises(AnsibleFailJson):
- grafana_iface.create_user(
- 'Joker', 'joker@gotham.com', 'joker', 'oups')
+ grafana_iface.create_user("Joker", "joker@gotham.com", "joker", "oups")
mock_fetch_url.assert_called_once_with(
module,
- 'https://grafana.example.com/api/admin/users',
- data=json.dumps({'name': 'Joker', 'email': 'joker@gotham.com',
- 'login': 'joker', 'password': 'oups'}, sort_keys=True),
- headers={'Content-Type': 'application/json',
- 'Authorization': self.authorization},
- method='POST')
+ "https://grafana.example.com/api/admin/users",
+ data=json.dumps(
+ {
+ "name": "Joker",
+ "email": "joker@gotham.com",
+ "login": "joker",
+ "password": "oups",
+ },
+ sort_keys=True,
+ ),
+ headers={
+ "Content-Type": "application/json",
+ "Authorization": self.authorization,
+ },
+ method="POST",
+ )
# create a new user
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_user.fetch_url')
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_user.fetch_url"
+ )
def test_create_user_new_user(self, mock_fetch_url):
- set_module_args({
- 'url': 'https://grafana.example.com',
- 'url_username': 'admin',
- 'url_password': 'changeme',
- 'name': 'Robin',
- 'email': 'robin@gotham.com',
- 'login': 'robin',
- 'password': 'oups',
- 'state': 'present'
- })
+ set_module_args(
+ {
+ "url": "https://grafana.example.com",
+ "url_username": "admin",
+ "url_password": "changeme",
+ "name": "Robin",
+ "email": "robin@gotham.com",
+ "login": "robin",
+ "password": "oups",
+ "state": "present",
+ }
+ )
module = grafana_user.setup_module_object()
mock_fetch_url.return_value = user_created_resp()
@@ -136,54 +157,71 @@ class GrafanaUserTest(TestCase):
# first call to create user
call(
module,
- 'https://grafana.example.com/api/admin/users',
- data=json.dumps({'name': 'Robin', 'email': 'robin@gotham.com',
- 'login': 'robin', 'password': 'oups'}, sort_keys=True),
- headers={'Content-Type': 'application/json',
- 'Authorization': self.authorization},
- method='POST'),
-
+ "https://grafana.example.com/api/admin/users",
+ data=json.dumps(
+ {
+ "name": "Robin",
+ "email": "robin@gotham.com",
+ "login": "robin",
+ "password": "oups",
+ },
+ sort_keys=True,
+ ),
+ headers={
+ "Content-Type": "application/json",
+ "Authorization": self.authorization,
+ },
+ method="POST",
+ ),
# second call to return created user
call(
module,
- 'https://grafana.example.com/api/users/lookup?loginOrEmail=robin',
+ "https://grafana.example.com/api/users/lookup?loginOrEmail=robin",
data=None,
- headers={'Content-Type': 'application/json',
- 'Authorization': self.authorization},
- method='GET'),
+ headers={
+ "Content-Type": "application/json",
+ "Authorization": self.authorization,
+ },
+ method="GET",
+ ),
]
grafana_iface = grafana_user.GrafanaUserInterface(module)
- result = grafana_iface.create_user(
- 'Robin', 'robin@gotham.com', 'robin', 'oups')
-
- mock_fetch_url.assert_has_calls(
- expected_fetch_url_calls, any_order=False)
-
- self.assertEquals(result, {
- "id": 2,
- "email": "robin@gotham.com",
- "name": "Robin",
- "login": "adrobinmin",
- "theme": "light",
- "orgId": 1,
- "isGrafanaAdmin": False,
- "isDisabled": False,
- "isExternal": False,
- "authLabels": None,
- "updatedAt": "2019-09-25T14:44:37+01:00",
- "createdAt": "2019-09-25T14:44:37+01:00"
- })
-
- @patch('ansible_collections.community.grafana.plugins.modules.grafana_user.fetch_url')
+ result = grafana_iface.create_user("Robin", "robin@gotham.com", "robin", "oups")
+
+ mock_fetch_url.assert_has_calls(expected_fetch_url_calls, any_order=False)
+
+ self.assertEqual(
+ result,
+ {
+ "id": 2,
+ "email": "robin@gotham.com",
+ "name": "Robin",
+ "login": "adrobinmin",
+ "theme": "light",
+ "orgId": 1,
+ "isGrafanaAdmin": False,
+ "isDisabled": False,
+ "isExternal": False,
+ "authLabels": None,
+ "updatedAt": "2019-09-25T14:44:37+01:00",
+ "createdAt": "2019-09-25T14:44:37+01:00",
+ },
+ )
+
+ @patch(
+ "ansible_collections.community.grafana.plugins.modules.grafana_user.fetch_url"
+ )
def test_delete_user(self, mock_fetch_url):
- set_module_args({
- 'url': 'https://grafana.example.com',
- 'url_username': 'admin',
- 'url_password': 'changeme',
- 'login': 'batman',
- 'state': 'absent'
- })
+ set_module_args(
+ {
+ "url": "https://grafana.example.com",
+ "url_username": "admin",
+ "url_password": "changeme",
+ "login": "batman",
+ "state": "absent",
+ }
+ )
module = grafana_user.setup_module_object()
mock_fetch_url.return_value = user_deleted_resp()
@@ -192,9 +230,12 @@ class GrafanaUserTest(TestCase):
result = grafana_iface.delete_user(user_id)
mock_fetch_url.assert_called_once_with(
module,
- 'https://grafana.example.com/api/admin/users/42',
+ "https://grafana.example.com/api/admin/users/42",
data=None,
- headers={'Content-Type': 'application/json',
- 'Authorization': self.authorization},
- method='DELETE')
- self.assertEquals(result, {"message": "User deleted"})
+ headers={
+ "Content-Type": "application/json",
+ "Authorization": self.authorization,
+ },
+ method="DELETE",
+ )
+ self.assertEqual(result, {"message": "User deleted"})