diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 12:04:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 12:04:41 +0000 |
commit | 975f66f2eebe9dadba04f275774d4ab83f74cf25 (patch) | |
tree | 89bd26a93aaae6a25749145b7e4bca4a1e75b2be /ansible_collections/community/grafana/tests | |
parent | Initial commit. (diff) | |
download | ansible-975f66f2eebe9dadba04f275774d4ab83f74cf25.tar.xz ansible-975f66f2eebe9dadba04f275774d4ab83f74cf25.zip |
Adding upstream version 7.7.0+dfsg.upstream/7.7.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/community/grafana/tests')
66 files changed, 4749 insertions, 0 deletions
diff --git a/ansible_collections/community/grafana/tests/.gitignore b/ansible_collections/community/grafana/tests/.gitignore new file mode 100644 index 000000000..ea1472ec1 --- /dev/null +++ b/ansible_collections/community/grafana/tests/.gitignore @@ -0,0 +1 @@ +output/ diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/aliases b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/aliases new file mode 100644 index 000000000..a6dafcf8c --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/aliases @@ -0,0 +1 @@ +shippable/posix/group1 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 new file mode 100644 index 000000000..8b9c9348a --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/defaults/main.yml @@ -0,0 +1,7 @@ +--- + +grafana_url: "http://grafana:3000/" +grafana_username: "admin" +grafana_password: "admin" + +... diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/files/dashboard.json b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/files/dashboard.json new file mode 100644 index 000000000..70287fa74 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/files/dashboard.json @@ -0,0 +1,85 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": 11, + "links": [], + "panels": [ + { + "content": "\n# Title\n\nFor markdown syntax help: [commonmark.org/help](https://commonmark.org/help/)\n\n\n\n", + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 0 + }, + "id": 2, + "mode": "markdown", + "options": {}, + "targets": [ + { + "expr": "", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Panel Title", + "type": "text" + } + ], + "schemaVersion": 18, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "test", + "uid": "9ZlJIhhWk", + "version": 7 + }
\ No newline at end of file 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 new file mode 100644 index 000000000..04b17f727 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-export.yml @@ -0,0 +1,33 @@ +--- +- set_fact: + dashboard_uid: "{{ result.uid }}" + +- name: Check export grafana dashboard to file + grafana_dashboard: + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + state: export + path: /tmp/dashboard.json + overwrite: true + uid: "{{ dashboard_uid }}" + register: result + +- debug: + var: result + +- assert: + that: + - "result.changed == true" + - "result.msg == 'Dashboard {{ dashboard_uid }} exported to /tmp/dashboard.json'" + +- name: Load /tmp/dashboard.json or fail if missing + set_fact: + exported_dashboard_lines: "{{ lookup('file', '/tmp/dashboard.json').splitlines() }}" + +- name: Assert that exported dashboard contains formatted JSON + assert: + that: + - "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 new file mode 100644 index 000000000..f4f3d9f4d --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-folder-destination.yml @@ -0,0 +1,33 @@ +--- +- 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." + +- assert: + that: + - "result.changed == false" + - "result.failed == true" + - "result.msg == expected_error" 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 new file mode 100644 index 000000000..93df1666a --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-file.yml @@ -0,0 +1,44 @@ +--- +- 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 new file mode 100644 index 000000000..3b81ebf71 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-id.yml @@ -0,0 +1,40 @@ +--- +- name: Check import grafana dashboard from id + 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 + register: result + +- debug: + var: result + +- assert: + that: + - "result.changed == true" + - "result.msg == 'Dashboard Zabbix Host Status created'" + +- name: Check import grafana dashboard from id idempotency + 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 + register: result + +- debug: + var: result + +- assert: + that: + - "result.changed == false" + - "result.msg == 'Dashboard Zabbix Host Status unchanged.'" 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 new file mode 100644 index 000000000..5146fc9a0 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/dashboard-from-url.yml @@ -0,0 +1,39 @@ +--- + +- name: Check import grafana dashboard from url + 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 + register: result + +- debug: + var: result + +- assert: + that: + - "result.changed == true" + - "result.msg == 'Dashboard Zabbix Host Status created'" + +- name: Check import grafana dashboard from url idempotency + 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 + register: result + +- debug: + var: result + +- assert: + that: + - "result.changed == false" + - "result.msg == 'Dashboard Zabbix Host Status unchanged.'" 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 new file mode 100644 index 000000000..2013324fb --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/delete-dashboard.yml @@ -0,0 +1,16 @@ +- name: Check delete dashboard is working + grafana_dashboard: + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + state: absent + uid: "{{ result.uid }}" + register: result + +- debug: + var: result + +- assert: + that: + - "result.changed == true" + - "result.msg == 'Dashboard {{ result.uid }} deleted'" 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 new file mode 100644 index 000000000..4d9138fcf --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_dashboard/tasks/main.yml @@ -0,0 +1,7 @@ +- 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 diff --git a/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/aliases b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/aliases new file mode 100644 index 000000000..a6dafcf8c --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/aliases @@ -0,0 +1 @@ +shippable/posix/group1 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 new file mode 100644 index 000000000..8b9c9348a --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/defaults/main.yml @@ -0,0 +1,7 @@ +--- + +grafana_url: "http://grafana:3000/" +grafana_username: "admin" +grafana_password: "admin" + +... 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 new file mode 100644 index 000000000..a96691893 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/azure.yml @@ -0,0 +1,123 @@ +- name: Create azure datasource + register: result + grafana_datasource: + name: datasource-azure + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + org_id: '1' + ds_type: grafana-azure-monitor-datasource + ds_url: http://example.com + azure_client: client1 + azure_tenant: tenant1 + azure_secret: secret1 + azure_cloud: azuremonitor + +- debug: + var: result + +- 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 + +- name: Check azure datasource creation idempotency + register: result + grafana_datasource: + name: datasource-azure + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + org_id: '1' + ds_type: grafana-azure-monitor-datasource + ds_url: http://example.com + azure_client: client1 + azure_tenant: tenant1 + azure_secret: secret1 + azure_cloud: azuremonitor + +- debug: + var: result + +- 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 + +- name: Delete azure datasource + register: result + grafana_datasource: + name: datasource-azure + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + org_id: '1' + ds_type: grafana-azure-monitor-datasource + ds_url: http://example.com + azure_client: client1 + azure_tenant: tenant1 + azure_secret: secret1 + azure_cloud: azuremonitor + state: absent + +- debug: + var: result + +- assert: + that: + - result.changed + - "result.msg == 'Datasource datasource-azure deleted.'" + +- name: Delete azure datasource (idempotency) + register: result + grafana_datasource: + name: datasource-azure + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + org_id: '1' + ds_type: grafana-azure-monitor-datasource + ds_url: http://example.com + azure_client: client1 + azure_tenant: tenant1 + azure_secret: secret1 + azure_cloud: azuremonitor + state: absent + +- debug: + var: result + +- assert: + that: + - 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 new file mode 100644 index 000000000..50268ea8f --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/cloudwatch.yml @@ -0,0 +1,111 @@ +- name: Create cloudwatch datasource + register: result + grafana_datasource: + name: datasource-cloudwatch + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + org_id: '1' + ds_type: cloudwatch + ds_url: http://monitoring.us-west-1.amazonaws.com + aws_auth_type: keys + aws_default_region: us-west-1 + aws_access_key: speakFriendAndEnter + aws_secret_key: mel10n + aws_custom_metrics_namespaces: n1,n2 + +- debug: + var: result + +- 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 + +- name: Check cloudwatch datasource creation idempotency + register: result + grafana_datasource: + name: datasource-cloudwatch + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: cloudwatch + ds_url: http://monitoring.us-west-1.amazonaws.com + aws_auth_type: keys + aws_default_region: us-west-1 + aws_access_key: speakFriendAndEnter + aws_secret_key: mel10n + aws_custom_metrics_namespaces: n1,n2 + +- debug: + var: result + +- 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 + +- name: Delete cloudwatch datasource + register: result + grafana_datasource: + name: datasource-cloudwatch + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + state: absent + +- debug: + var: result + +- assert: + that: + - result.changed + - "result.msg == 'Datasource datasource-cloudwatch deleted.'" + +- name: Delete cloudwatch datasource (idempotency) + register: result + grafana_datasource: + name: datasource-cloudwatch + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + state: absent + +- debug: + var: result + +- assert: + that: + - 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 new file mode 100644 index 000000000..73b258426 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/elastic.yml @@ -0,0 +1,313 @@ +--- +- name: Create elasticsearch datasource with legacy elasticsearch format + register: result + grafana_datasource: + name: "datasource/elasticLegacy" + uid: "myuid" + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: elasticsearch + ds_url: https://elastic.company.com:9200 + database: '[logstash_]YYYY.MM.DD' + basic_auth_user: grafana + 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: + var: result + +- 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'" + +- name: Create elasticsearch datasource with new elsaticsearch version format + register: result + grafana_datasource: + name: "datasource/elastic" + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: elasticsearch + ds_url: https://elastic.company.com:9200 + database: '[logstash_]YYYY.MM.DD' + basic_auth_user: grafana + basic_auth_password: '******' + time_field: '@timestamp' + time_interval: 1m + interval: Daily + es_version: "7.10+" + max_concurrent_shard_requests: 42 + tls_ca_cert: /etc/ssl/certs/ca.pem + +- debug: + var: result + +- 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'" + +- name: Check elasticsearch datasource creation idempotency + register: result + grafana_datasource: + name: "datasource/elastic" + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: elasticsearch + ds_url: https://elastic.company.com:9200 + database: '[logstash_]YYYY.MM.DD' + basic_auth_user: grafana + basic_auth_password: '******' + time_field: '@timestamp' + time_interval: 1m + interval: Daily + es_version: "7.10+" + max_concurrent_shard_requests: 42 + tls_ca_cert: /etc/ssl/certs/ca.pem + +- debug: + var: result + +- 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 + +- name: update elasticsearch datasource creation + register: result + grafana_datasource: + name: "datasource/elastic" + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: elasticsearch + ds_url: https://elastic.example.com:9200 + database: '[logstash_]YYYY.MM.DD' + basic_auth_user: grafana + basic_auth_password: '******' + time_field: '@timestamp' + time_interval: 1m + interval: Daily + es_version: "7.10+" + max_concurrent_shard_requests: 42 + tls_ca_cert: /etc/ssl/certs/ca.pem + +- debug: + var: result + +- 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 + +- name: update elasticsearch datasource (ignoring secureJsonData) + register: result + grafana_datasource: + name: "datasource/elastic" + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: elasticsearch + ds_url: https://elastic.example.com:9200 + database: '[logstash_]YYYY.MM.DD' + basic_auth_user: grafana + basic_auth_password: '******' + time_field: '@timestamp' + time_interval: 1m + interval: Daily + 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" + additional_secure_json_data: + secureTest: "secure" + +- debug: + var: result + +- 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' + +- name: update elasticsearch datasource (including secureJsonData) + register: result + grafana_datasource: + name: "datasource/elastic" + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: elasticsearch + ds_url: https://elastic.example.com:9200 + database: '[logstash_]YYYY.MM.DD' + basic_auth_user: grafana + basic_auth_password: '******' + time_field: '@timestamp' + time_interval: 1m + interval: Daily + 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" + additional_secure_json_data: + secureTest: "secure" + +- debug: + var: result + +- 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 + +- name: Delete elasticsearch datasource + register: result + grafana_datasource: + name: "datasource/elastic" + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + state: absent + +- assert: + that: + - result.changed + +- name: Delete elasticsearch datasource (idempotency) + register: result + grafana_datasource: + name: "datasource/elastic" + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + state: absent + +- assert: + that: + - 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 new file mode 100644 index 000000000..731a19d8f --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/errors.yml @@ -0,0 +1,18 @@ +--- +- name: Create datasource without `ds_type` and `ds_url` (expect failure) + register: result + grafana_datasource: + name: datasource-postgres + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + ignore_errors: true + +- debug: + var: result + +- assert: + that: + - 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 new file mode 100644 index 000000000..da61833f6 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/influx.yml @@ -0,0 +1,88 @@ +- name: Create influxdb datasource + register: result + grafana_datasource: + name: datasource-influxdb + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: influxdb + ds_url: https://influx.company.com:8086 + database: telegraf + time_interval: '>10s' + tls_ca_cert: /etc/ssl/certs/ca.pem + +- debug: + var: result + +- assert: + that: + - result.changed + - "result.msg == 'Datasource datasource-influxdb created'" + +- name: Check influxdb datasource creation idempotency + register: result + grafana_datasource: + name: datasource-influxdb + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: influxdb + ds_url: https://influx.company.com:8086 + database: telegraf + time_interval: '>10s' + tls_ca_cert: /etc/ssl/certs/ca.pem + +- debug: + var: result + +- 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 + +- name: Delete influxdb datasource + register: result + grafana_datasource: + name: datasource-influxdb + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + state: absent + +- debug: + var: result + +- assert: + that: + - result.changed + +- name: Delete influxdb datasource (idempotency) + register: result + grafana_datasource: + name: datasource-influxdb + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + state: absent + +- debug: + var: result + +- assert: + that: + - 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 new file mode 100644 index 000000000..f80677d8d --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/issues.yml @@ -0,0 +1,46 @@ +--- + +- name: test datasource name with slash + register: result + grafana_datasource: + name: "datasource/elastic" + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: elasticsearch + ds_url: https://elastic.company.com:9200 + database: '[logstash_]YYYY.MM.DD' + basic_auth_user: grafana + 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: + 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'" + +... 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 new file mode 100644 index 000000000..68eca9802 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/loki.yml @@ -0,0 +1,82 @@ +- name: Create loki datasource + register: result + grafana_datasource: + name: datasource-loki + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + org_id: '1' + ds_type: loki + ds_url: https://loki.company.com:3100 + +- debug: + var: result + +- assert: + that: + - result.changed + - "result.msg == 'Datasource datasource-loki created'" + +- name: Check loki datasource creation idempotency + register: result + grafana_datasource: + name: datasource-loki + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: loki + ds_url: https://loki.company.com:3100 + +- debug: + var: result + +- 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 + +- name: Delete loki datasource + register: result + grafana_datasource: + name: datasource-loki + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + state: absent + +- debug: + var: result + +- assert: + that: + - result.changed + - "result.msg == 'Datasource datasource-loki deleted.'" + +- name: Delete loki datasource (idempotency) + register: result + grafana_datasource: + name: datasource-loki + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + state: absent + +- debug: + var: result + +- assert: + that: + - 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 new file mode 100644 index 000000000..b5798e9a8 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/main.yml @@ -0,0 +1,16 @@ +--- + +- 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 + +... 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 new file mode 100644 index 000000000..80221f012 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/postgres.yml @@ -0,0 +1,93 @@ +- name: Create postgres datasource + register: result + grafana_datasource: + name: datasource-postgres + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: postgres + ds_url: postgres.company.com:5432 + database: db + user: postgres + password: iampgroot + sslmode: verify-full + additional_json_data: + timescaledb: true + +- debug: + var: result + +- assert: + that: + - result.changed + - "result.msg == 'Datasource datasource-postgres created'" + +- name: Check postgres datasource creation idempotency + register: result + grafana_datasource: + name: datasource-postgres + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: postgres + ds_url: postgres.company.com:5432 + database: db + user: postgres + password: iampgroot + sslmode: verify-full + additional_json_data: + timescaledb: true + +- debug: + var: result + +- 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 + +- name: Delete postgres datasource + register: result + grafana_datasource: + name: datasource-postgres + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + state: absent + +- debug: + var: result + +- assert: + that: + - result.changed + +- name: Delete postgres datasource + register: result + grafana_datasource: + name: datasource-postgres + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + state: absent + +- debug: + var: result + +- 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 new file mode 100644 index 000000000..933695354 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/redis.yml @@ -0,0 +1,101 @@ +- name: Create redis datasource + register: result + grafana_datasource: + name: datasource-redis + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: redis-datasource + ds_url: https://redis.company.com:6379 + time_interval: 1m + +- debug: + var: result + +- 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'" + +- name: Check redis-datasource datasource creation idempotency + register: result + grafana_datasource: + name: datasource-redis + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: redis-datasource + ds_url: https://redis.company.com:6379 + time_interval: 1m + +- debug: + var: result + +- 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' + +- name: update redis-datasource datasource creation + register: result + grafana_datasource: + name: datasource-redis + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: redis-datasource + ds_url: https://redisnew.company.com:6379 + time_interval: 1m + +- debug: + var: result + +- 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' + +- name: Delete redis-datasource datasource + register: result + grafana_datasource: + name: datasource-redis + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + state: absent + +- assert: + that: + - result.changed + +- name: Delete redis-datasource datasource (idempotency) + register: result + grafana_datasource: + name: datasource-redis + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + state: absent + +- 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 new file mode 100644 index 000000000..3ecc92d94 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/thruk.yml @@ -0,0 +1,78 @@ +- name: Create thruk datasource + register: result + 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 + +- debug: + var: result + +- assert: + that: + - result.changed + - "result.msg == 'Datasource datasource-thruk created'" + +- name: Check thruk datasource creation idempotency + register: result + 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 + +- 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 + +- name: Delete thruk datasource + register: result + grafana_datasource: + name: datasource-thruk + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + state: absent + +- debug: + var: result + +- assert: + that: + - result.changed + +- name: Delete thruk datasource (idempotency) + register: result + grafana_datasource: + name: datasource-thruk + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + state: absent + +- assert: + that: + - 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 new file mode 100644 index 000000000..71102a074 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/uid.yml @@ -0,0 +1,253 @@ +- name: Create datasource with uid + register: result + grafana_datasource: + name: datasource-with-uid + uid: uid1 + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + 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 + +- debug: + var: result + +- assert: + that: + - result.changed + - "result.msg == 'Datasource datasource-with-uid created'" + +- name: Create datasource without uid + register: result + grafana_datasource: + name: datasource-without-uid + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + 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 + +- debug: + var: result + +- assert: + that: + - result.changed + - "result.msg == 'Datasource datasource-without-uid created'" + +- name: Check datasource creation idempotency with uid + register: result + grafana_datasource: + name: datasource-with-uid + uid: uid1 + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + 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 + +- debug: + var: result + +- 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 + +- name: Check datasource creation idempotency without uid + register: result + grafana_datasource: + name: datasource-without-uid + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + 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 + +- debug: + var: result + +- 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 + +- name: Set uid for datasource with random uid + register: result + grafana_datasource: + name: datasource-without-uid + uid: uid3 + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + 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 + +- debug: + var: result + +- 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 + +- name: Change uid for datasource + register: result + grafana_datasource: + name: datasource-with-uid + uid: uid2 + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + 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 + +- debug: + var: result + +- 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 + +- name: Delete datasource-with-uid + register: result + grafana_datasource: + name: datasource-with-uid + uid: uid1 + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + 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 + state: absent + +- debug: + var: result + +- assert: + that: + - result.changed + +- name: Delete datasource-without-uid + register: result + grafana_datasource: + name: datasource-without-uid + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + 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 + state: absent + +- debug: + var: result + +- assert: + that: + - result.changed + +- name: Delete datasource-with-uid (idempotency) + register: result + grafana_datasource: + name: datasource-with-uid + uid: uid1 + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + 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 + + state: absent + +- debug: + var: result + +- assert: + that: + - 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 new file mode 100644 index 000000000..c8a8236bf --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_datasource/tasks/zabbix.yml @@ -0,0 +1,114 @@ +- name: Create zabbix datasource + register: result + grafana_datasource: + name: datasource-zabbix + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: alexanderzobnin-zabbix-datasource + ds_url: https://zabbix.company.com + zabbix_user: grafana + zabbix_password: '******' + +- debug: + var: result + +- 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'" + +- name: Create zabbix datasource (idempotency) + register: result + grafana_datasource: + name: datasource-zabbix + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: alexanderzobnin-zabbix-datasource + ds_url: https://zabbix.company.com + zabbix_user: grafana + zabbix_password: '******' + +- debug: + var: result + +- 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 + +- name: Update zabbix datasource + register: result + grafana_datasource: + name: datasource-zabbix + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + org_id: '1' + ds_type: alexanderzobnin-zabbix-datasource + ds_url: https://zabbix.example.com + zabbix_user: grafana + zabbix_password: '******' + +- debug: + var: result + +- 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'" + +- name: Delete zabbix datasource + register: result + grafana_datasource: + name: datasource-zabbix + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + state: absent + +- assert: + that: + - result.changed + +- name: Delete zabbix datasource (idempotency) + register: result + grafana_datasource: + name: datasource-zabbix + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password }}" + state: absent + +- assert: + that: + - 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 new file mode 100644 index 000000000..8b9c9348a --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/defaults/main.yml @@ -0,0 +1,7 @@ +--- + +grafana_url: "http://grafana:3000/" +grafana_username: "admin" +grafana_password: "admin" + +... 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 new file mode 100644 index 000000000..c6a520560 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_folder/tasks/main.yml @@ -0,0 +1,55 @@ +--- + +- 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" 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 new file mode 100644 index 000000000..8b9c9348a --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/defaults/main.yml @@ -0,0 +1,7 @@ +--- + +grafana_url: "http://grafana:3000/" +grafana_username: "admin" +grafana_password: "admin" + +... 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 new file mode 100644 index 000000000..7279e313b --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/dingding.yml @@ -0,0 +1,74 @@ +--- +- name: Create dingding notification channel + register: result + 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}}" + +- debug: + var: result + +- assert: + that: + - result.changed == True + - result.channel.name == "dingding" + - result.channel.uid == "dingding" + - result.channel.type == "dingding" + +- name: Create dingding notification channel (idempotency) + register: result + 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}}" + +- debug: + var: result + +- assert: + that: + - result.changed == False + - result.channel.name == "dingding" + - result.channel.uid == "dingding" + - result.channel.type == "dingding" + +- name: Delete dingding notification channel + register: result + grafana_notification_channel: + uid: dingding + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - result.changed == True + +- name: Delete dingding notification channel (idempotency) + register: result + grafana_notification_channel: + uid: dingding + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- 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 new file mode 100644 index 000000000..29cfece70 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/discord.yml @@ -0,0 +1,74 @@ +--- +- name: Create discord notification channel + register: result + 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}}" + +- debug: + var: result + +- assert: + that: + - result.changed == True + - result.channel.name == "discord" + - result.channel.type == "discord" + - result.channel.uid == "discord" + +- name: Create discord notification channel (idempotency) + register: result + 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}}" + +- debug: + var: result + +- assert: + that: + - result.changed == False + - result.channel.name == "discord" + - result.channel.type == "discord" + - result.channel.uid == "discord" + +- name: Delete discord notification channel + register: result + grafana_notification_channel: + uid: discord + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - result.changed == True + +- name: Delete discord notification channel (idempotency) + register: result + grafana_notification_channel: + uid: discord + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- 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 new file mode 100644 index 000000000..85a236c9e --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/email.yml @@ -0,0 +1,79 @@ +--- +- name: Create email notification channel + register: result + grafana_notification_channel: + uid: email + name: email + type: email + email_addresses: + - foo@example.org + - bar@example.org + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: email + name: email + type: email + email_addresses: + - foo@example.org + - bar@example.org + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: email + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + - "result.state == 'absent'" + +- name: Delete discord notification channel (idempotency) + register: result + grafana_notification_channel: + uid: email + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..abc7db644 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/googlechat.yml @@ -0,0 +1,74 @@ +--- +- name: Create googlechat notification channel + register: result + 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}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: googlechat + name: googlechat + type: googlechat + googlechat_url: https://example.org + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: googlechat + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + +- name: Delete googlechat notification channel (idempotency) + register: result + grafana_notification_channel: + uid: googlechat + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..4a9ec1704 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/hipchat.yml @@ -0,0 +1,74 @@ +--- +- name: Create hipchat notification channel + register: result + 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}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: hipchat + name: hipchat + type: hipchat + hipchat_url: https://example.org + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: hipchat + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + +- name: Delete hipchat notification channel (idempotency) + register: result + grafana_notification_channel: + uid: hipchat + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..ffc208acb --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/kafka.yml @@ -0,0 +1,76 @@ +--- +- name: Create kafka notification channel + register: result + grafana_notification_channel: + uid: kafka + name: kafka + type: kafka + kafka_url: https://example.org + kafka_topic: test + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: kafka + name: kafka + type: kafka + kafka_url: https://example.org + kafka_topic: test + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: kafka + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + +- name: Delete kafka notification channel (idempotency) + register: result + grafana_notification_channel: + uid: kafka + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..83a1863ba --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/line.yml @@ -0,0 +1,74 @@ +--- +- name: Create line notification channel + register: result + grafana_notification_channel: + uid: line + name: line + type: line + line_token: xxx + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: line + name: line + type: line + line_token: xxx + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: line + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + +- name: Delete line notification channel (idempotency) + register: result + grafana_notification_channel: + uid: line + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..ada6338c7 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/main.yml @@ -0,0 +1,20 @@ +--- +- 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 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 new file mode 100644 index 000000000..f871fe719 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/opsgenie.yml @@ -0,0 +1,77 @@ +--- +- name: Create opsgenie notification channel + register: result + grafana_notification_channel: + uid: opsgenie + name: opsgenie + type: opsgenie + opsgenie_url: https://example.org + opsgenie_api_key: xxx + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: opsgenie + name: opsgenie + type: opsgenie + opsgenie_url: https://example.org + opsgenie_api_key: xxx + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: opsgenie + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + - "result.state == 'absent'" + +- name: Delete opsgenie notification channel (idempotency) + register: result + grafana_notification_channel: + uid: opsgenie + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..a8fa940b0 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/pagerduty.yml @@ -0,0 +1,74 @@ +--- +- name: Create pagerduty notification channel + register: result + 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}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: pagerduty + name: pagerduty + type: pagerduty + pagerduty_integration_key: xxx + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: pagerduty + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + +- name: Delete pagerduty notification channel (idempotency) + register: result + grafana_notification_channel: + uid: pagerduty + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..40810eaf3 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/prometheus.yml @@ -0,0 +1,74 @@ +--- +- name: Create prometheus notification channel + register: result + 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}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: prometheus + name: prometheus + type: prometheus + prometheus_url: https://example.org + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: prometheus + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + +- name: Delete prometheus notification channel (idempotency) + register: result + grafana_notification_channel: + uid: prometheus + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..894bd71e6 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/pushover.yml @@ -0,0 +1,76 @@ +--- +- name: Create pushover notification channel + register: result + grafana_notification_channel: + uid: pushover + name: pushover + type: pushover + pushover_api_token: xxx + pushover_user_key: yyy + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: pushover + name: pushover + type: pushover + pushover_api_token: xxx + pushover_user_key: yyy + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: pushover + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + +- name: Delete pushover notification channel (idempotency) + register: result + grafana_notification_channel: + uid: pushover + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..01619b719 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/sensu.yml @@ -0,0 +1,74 @@ +--- +- name: Create sensu notification channel + register: result + 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}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: sensu + name: sensu + type: sensu + sensu_url: https://example.org + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: sensu + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + +- name: Delete sensu notification channel (idempotency) + register: result + grafana_notification_channel: + uid: sensu + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..0748c8bdb --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/slack-and-beyond.yml @@ -0,0 +1,110 @@ +--- +- name: Create slack notification channel + register: result + 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}}" + +- debug: + var: result + +- assert: + that: + - "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: + 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}}" + +- debug: + var: result + +- assert: + that: + - "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: + 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}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == False" + +- name: Update slack notification channel + register: result + 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}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + +- name: Delete slack notification channel + register: result + grafana_notification_channel: + state: absent + uid: slack + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + +- name: Delete slack notification channel (idempotency) + register: result + grafana_notification_channel: + state: absent + uid: slack + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..cfc44aef3 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/teams.yml @@ -0,0 +1,74 @@ +--- +- name: Create teams notification channel + register: result + 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}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: teams + name: teams + type: teams + teams_url: https://example.org + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: teams + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + +- name: Delete teams notification channel (idempotency) + register: result + grafana_notification_channel: + uid: teams + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..98a7a3c6d --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/telegram.yml @@ -0,0 +1,76 @@ +--- +- name: Create telegram notification channel + register: result + grafana_notification_channel: + uid: telegram + name: telegram + type: telegram + telegram_bot_token: xxx + telegram_chat_id: yyy + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: telegram + name: telegram + type: telegram + telegram_bot_token: xxx + telegram_chat_id: yyy + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: telegram + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + +- name: Delete telegram notification channel (idempotency) + register: result + grafana_notification_channel: + uid: telegram + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..7858b6977 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/threema.yml @@ -0,0 +1,78 @@ +--- +- name: Create threema notification channel + register: result + grafana_notification_channel: + uid: threema + name: threema + type: threema + threema_gateway_id: "*xxxxxxx" + threema_recipient_id: yyyyyyyy + threema_api_secret: zzz + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: threema + name: threema + type: threema + threema_gateway_id: xxx + threema_recepient_id: yyy + threema_api_secret: zzz + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: threema + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + +- name: Delete threema notification channel (idempotency) + register: result + grafana_notification_channel: + uid: threema + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..3779e813a --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/victorops.yml @@ -0,0 +1,74 @@ +--- +- name: Create victorops notification channel + register: result + 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}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: victorops + name: victorops + type: victorops + victorops_url: https://example.org + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: victorops + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + +- name: Delete victorops notification channel (idempotency) + register: result + grafana_notification_channel: + uid: victorops + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..c9efd9193 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_notification_channel/tasks/webhook.yml @@ -0,0 +1,74 @@ +--- +- name: Create webhook notification channel + register: result + 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}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: webhook + name: webhook + type: webhook + webhook_url: https://example.org + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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: + uid: webhook + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "result.changed == True" + +- name: Delete webhook notification channel (idempotency) + register: result + grafana_notification_channel: + uid: webhook + state: absent + grafana_url: "{{ grafana_url }}" + grafana_user: "{{ grafana_username }}" + grafana_password: "{{ grafana_password}}" + +- debug: + var: result + +- assert: + that: + - "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 new file mode 100644 index 000000000..7bb77ea3f --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/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/tasks/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/tasks/main.yml new file mode 100644 index 000000000..f8ccdf3bf --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_organization/tasks/main.yml @@ -0,0 +1,57 @@ +--- + +- name: Create a Grafana organization + community.grafana.grafana_organization: + url: "{{ grafana_url }}" + url_username: "{{ grafana_username }}" + url_password: "{{ grafana_password }}" + name: orgtest + state: present + register: result +- assert: + that: + - "result.changed == true" + - "result.failed == false" + - "result.org.name == 'orgtest'" + +- name: check idempotency Grafana organization + community.grafana.grafana_organization: + url: "{{ grafana_url }}" + url_username: "{{ grafana_username }}" + url_password: "{{ grafana_password }}" + name: orgtest + state: present + register: result +- assert: + that: + - "result.changed == false" + - "result.failed == false" + - "result.org.name == 'orgtest'" + +- name: Delete a Grafana organization + community.grafana.grafana_organization: + url: "{{ grafana_url }}" + url_username: "{{ grafana_username }}" + url_password: "{{ grafana_password }}" + name: orgtest + state: absent + register: result +- assert: + that: + - "result.changed == true" + - "result.failed == false" + - "result.msg |length > 0" + +- name: check idempotency delete a Grafana organization + community.grafana.grafana_organization: + url: "{{ grafana_url }}" + url_username: "{{ grafana_username }}" + url_password: "{{ grafana_password }}" + name: orgtest + state: absent + register: result +- assert: + that: + - "result.changed == false" + - "result.failed == false" + - "result.msg == 'No org found, nothing to do'" 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 new file mode 100644 index 000000000..8b9c9348a --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_team/defaults/main.yml @@ -0,0 +1,7 @@ +--- + +grafana_url: "http://grafana:3000/" +grafana_username: "admin" +grafana_password: "admin" + +... 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 new file mode 100644 index 000000000..6971d07b6 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_team/tasks/create_user.yml @@ -0,0 +1,29 @@ +- name: Create John Doe for tests purpose through uri module + uri: + url: "{{ grafana_url }}api/admin/users" + method: POST + user: "{{ grafana_username }}" + password: "{{ grafana_password }}" + force_basic_auth: yes + body: + 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: + url: "{{ grafana_url }}api/admin/users" + method: POST + user: "{{ grafana_username }}" + password: "{{ grafana_password }}" + force_basic_auth: yes + body: + 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 new file mode 100644 index 000000000..2d74581b7 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_team/tasks/main.yml @@ -0,0 +1,187 @@ +--- + +- 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 + register: result + +- 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: + expected_members: "{{ auto_member | ternary(['********@localhost'], []) }}" + +- 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" + +- 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 + register: result + +- 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" + +- 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 + register: result + +- assert: + that: + - "result.changed == true" + - "result.message == 'Team deleted'" + +- 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 + register: result + +- assert: + that: + - "result.changed == false" + - "result.message == 'No team found'" + +- name: Create users for tests purpose + import_tasks: 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 + 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']) }}" + +- 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" + +- 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 + register: result + +- 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: + 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 + register: result + +- 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" + +- 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 + register: result + +- 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" + +- 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 + 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']) }}" + +- 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" 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 new file mode 100644 index 000000000..7bb77ea3f --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_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_user/tasks/main.yml b/ansible_collections/community/grafana/tests/integration/targets/grafana_user/tasks/main.yml new file mode 100644 index 000000000..c62801653 --- /dev/null +++ b/ansible_collections/community/grafana/tests/integration/targets/grafana_user/tasks/main.yml @@ -0,0 +1,237 @@ +--- +- name: Create new admin + grafana_user: + url: "{{ grafana_url }}" + url_username: "{{ grafana_username }}" + url_password: "{{ grafana_password }}" + name: "Harley Quinn" + email: harley.quinn@gotham.city + login: harley + password: Wy3ta6ob6M3wHELv58MPfqOe126RTnWpcYfEhyJm + is_admin: true + state: present + register: result +- assert: + that: + - "result.changed == true" + - "result.failed == false" + - "result.user.name == 'Harley Quinn'" + - "result.user.email == 'harley.quinn@gotham.city'" + - "result.user.isGrafanaAdmin == true" + +- name: Check idempotency on admin creation + grafana_user: + url: "{{ grafana_url }}" + url_username: "{{ grafana_username }}" + url_password: "{{ grafana_password }}" + name: "Harley Quinn" + email: harley.quinn@gotham.city + login: harley + password: Wy3ta6ob6M3wHELv58MPfqOe126RTnWpcYfEhyJm + is_admin: true + state: present + register: result +- assert: + that: + - "result.changed == false" + - "result.user.name == 'Harley Quinn'" + - "result.user.email == 'harley.quinn@gotham.city'" + - "result.user.isGrafanaAdmin == true" + +- name: Check user creation with Grafana API + uri: + url: "{{ grafana_url }}api/users/lookup?loginOrEmail=harley" + user: "{{ grafana_username }}" + password: "{{ grafana_password }}" + force_basic_auth: yes + status_code: 200 + headers: + Accept: application/json + Content-Type: application/json + register: result +- assert: + that: + - "result.json.name == 'Harley Quinn'" + - "result.json.email == 'harley.quinn@gotham.city'" + - "result.json.isGrafanaAdmin == true" + +- name: Create a Grafana user without password (expect failure) + grafana_user: + url: "{{ grafana_url }}" + url_username: "{{ grafana_username }}" + url_password: "{{ grafana_password }}" + name: "Bruce Wayne" + email: batman@gotham.city + login: batman + state: present + register: result + ignore_errors: yes +- assert: + that: + - "result.changed == false" + - "result.failed == true" + - "result.msg == 'missing required arguments: password'" + +- name: Create a Grafana user + grafana_user: + url: "{{ grafana_url }}" + url_username: "{{ grafana_username }}" + url_password: "{{ grafana_password }}" + name: "Bruce Wayne" + email: batman@gotham.city + login: batman + password: robin + state: present + register: result +- assert: + that: + - "result.changed == true" + - "result.user.name == 'Bruce Wayne'" + - "result.user.email == 'batman@gotham.city'" + - "result.user.isGrafanaAdmin == false" + +- name: Check idempotency on user creation (password not requiered) + grafana_user: + url: "{{ grafana_url }}" + url_username: "{{ grafana_username }}" + url_password: "{{ grafana_password }}" + name: "Bruce Wayne" + email: batman@gotham.city + login: batman + state: present + register: result +- assert: + that: + - "result.changed == false" + - "result.user.name == 'Bruce Wayne'" + - "result.user.email == 'batman@gotham.city'" + - "result.user.isGrafanaAdmin == false" + +- name: Check user creation with Grafana API + uri: + url: "{{ grafana_url }}api/users/lookup?loginOrEmail=batman" + user: "{{ grafana_username }}" + password: "{{ grafana_password }}" + force_basic_auth: yes + status_code: 200 + headers: + Accept: application/json + Content-Type: application/json + register: result +- assert: + that: + - "result.json.name == 'Bruce Wayne'" + - "result.json.email == 'batman@gotham.city'" + - "result.json.isGrafanaAdmin == false" + +- name: Update Grafana user + grafana_user: + url: "{{ grafana_url }}" + url_username: "{{ grafana_username }}" + url_password: "{{ grafana_password }}" + name: "The Dark Knight" + email: thedarkknight@gotham.city + login: batman + password: robin + is_admin: true + state: present + register: result +- assert: + that: + - "result.changed == true" + - "result.user.name == 'The Dark Knight'" + - "result.user.email == 'thedarkknight@gotham.city'" + - "result.user.isGrafanaAdmin == true" + +- name: Check user update with Grafana API + uri: + url: "{{ grafana_url }}api/users/lookup?loginOrEmail=batman" + user: "{{ grafana_username }}" + password: "{{ grafana_password }}" + force_basic_auth: yes + status_code: 200 + headers: + Accept: application/json + Content-Type: application/json + register: result +- assert: + that: + - "result.json.name == 'The Dark Knight'" + - "result.json.email == 'thedarkknight@gotham.city'" + - "result.json.isGrafanaAdmin == true" + +- name: Delete a Grafana user + grafana_user: + url: "{{ grafana_url }}" + url_username: "{{ grafana_username }}" + url_password: "{{ grafana_password }}" + login: batman + state: absent + register: result +- assert: + that: + - "result.changed == true" + - "result.message == 'User deleted'" + +- name: Check idempotency on user deletion + grafana_user: + url: "{{ grafana_url }}" + url_username: "{{ grafana_username }}" + url_password: "{{ grafana_password }}" + login: batman + state: absent + register: result +- assert: + that: + - "result.changed == false" + - "result.message == 'No user found, nothing to do'" + +- name: Check user deletion with Grafana API (expect 404 Not Found) + uri: + url: "{{ grafana_url }}api/users/lookup?loginOrEmail=batman" + user: "{{ grafana_username }}" + password: "{{ grafana_password }}" + force_basic_auth: yes + status_code: 404 + headers: + Accept: application/json + Content-Type: application/json + register: result +- assert: + that: + - "result.json.message | lower == 'user not found'" + +- name: Create a Grafana user with character encoding + grafana_user: + url: "{{ grafana_url }}" + url_username: "{{ grafana_username }}" + url_password: "{{ grafana_password }}" + name: "Bruce Wayne" + email: bruce+wayne@gotham.city + login: bruce+wayne@gotham.city + password: robin + state: present + register: result +- assert: + that: + - "result.changed == true" + - "result.user.name == 'Bruce Wayne'" + - "result.user.email == 'bruce+wayne@gotham.city'" + - "result.user.isGrafanaAdmin == false" + +- name: Check idempotency on user creation (password not requiered) + grafana_user: + url: "{{ grafana_url }}" + url_username: "{{ grafana_username }}" + url_password: "{{ grafana_password }}" + name: "Bruce Wayne" + email: bruce+wayne@gotham.city + login: bruce+wayne@gotham.city + state: present + register: result +- assert: + that: + - "result.changed == false" + - "result.user.name == 'Bruce Wayne'" + - "result.user.email == 'bruce+wayne@gotham.city'" + - "result.user.isGrafanaAdmin == false" diff --git a/ansible_collections/community/grafana/tests/sanity/ignore-2.10.txt b/ansible_collections/community/grafana/tests/sanity/ignore-2.10.txt new file mode 100644 index 000000000..5c82494f9 --- /dev/null +++ b/ansible_collections/community/grafana/tests/sanity/ignore-2.10.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.11.txt b/ansible_collections/community/grafana/tests/sanity/ignore-2.11.txt new file mode 100644 index 000000000..68cb96ab4 --- /dev/null +++ b/ansible_collections/community/grafana/tests/sanity/ignore-2.11.txt @@ -0,0 +1,6 @@ +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 +hacking/find_grafana_versions.py future-import-boilerplate!skip +hacking/find_grafana_versions.py metaclass-boilerplate!skip diff --git a/ansible_collections/community/grafana/tests/sanity/ignore-2.12.txt b/ansible_collections/community/grafana/tests/sanity/ignore-2.12.txt new file mode 100644 index 000000000..5c82494f9 --- /dev/null +++ b/ansible_collections/community/grafana/tests/sanity/ignore-2.12.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.13.txt b/ansible_collections/community/grafana/tests/sanity/ignore-2.13.txt new file mode 100644 index 000000000..5c82494f9 --- /dev/null +++ b/ansible_collections/community/grafana/tests/sanity/ignore-2.13.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.14.txt b/ansible_collections/community/grafana/tests/sanity/ignore-2.14.txt new file mode 100644 index 000000000..5c82494f9 --- /dev/null +++ b/ansible_collections/community/grafana/tests/sanity/ignore-2.14.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.15.txt b/ansible_collections/community/grafana/tests/sanity/ignore-2.15.txt new file mode 100644 index 000000000..5c82494f9 --- /dev/null +++ b/ansible_collections/community/grafana/tests/sanity/ignore-2.15.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.9.txt b/ansible_collections/community/grafana/tests/sanity/ignore-2.9.txt new file mode 100644 index 000000000..476a7a42e --- /dev/null +++ b/ansible_collections/community/grafana/tests/sanity/ignore-2.9.txt @@ -0,0 +1,3 @@ +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 new file mode 100644 index 000000000..d2fba0fe1 --- /dev/null +++ b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_datasource/test_grafana_datasource.py @@ -0,0 +1,212 @@ +from __future__ import (absolute_import, division, print_function) + +from unittest import TestCase +from unittest.mock import call, patch, MagicMock +from ansible_collections.community.grafana.plugins.modules import grafana_datasource +from ansible.module_utils._text import to_bytes +from ansible.module_utils import basic +from ansible.module_utils.urls import basic_auth_header +import json + +__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}) + 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 + raise AnsibleExitJson(kwargs) + + +def fail_json(*args, **kwargs): + """function to patch over fail_json; package return data into an exception""" + 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.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 + }, + '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', + }) + 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 + }, + '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', + }) + 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' + }, + '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' + }) + 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 + }, + '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 + } + 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 new file mode 100644 index 000000000..b3b025c4e --- /dev/null +++ b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_plugin/test_grafana_plugin.py @@ -0,0 +1,111 @@ +from __future__ import (absolute_import, division, print_function) + +from unittest import TestCase +from unittest.mock import patch, MagicMock +from ansible_collections.community.grafana.plugins.modules import grafana_plugin + +__metaclass__ = type + + +def run_command_ls(): + STDERR = "" + STDOUT = """ +installed plugins: +alexanderzobnin-zabbix-app @ 3.10.5 + +Restart grafana after installing plugins . <service grafana-server restart> +""" + return 0, STDOUT, STDERR + + +def run_command_install_zip(): + STDERR = "" + STDOUT = """ +installing alexanderzobnin-grafana-zabbix @ +from: /home/grafana//alexanderzobnin-grafana-zabbix-v3.10.5-1-g2219691.zip +into: /var/lib/grafana/plugins + +... Installed alexanderzobnin-grafana-zabbix successfully + +Restart grafana after installing plugins . <service grafana-server restart> + +""" + return 0, STDOUT, STDERR + + +def run_command_uninstall(): + STDERR = "" + STDOUT = """ +Removing plugin: alexanderzobnin-zabbix-app + +Restart grafana after installing plugins . <service grafana-server restart> +""" + return 0, STDOUT, STDERR + + +def run_command_uninstall_again(): + STDERR = "" + STDOUT = """ +Removing plugin: alexanderzobnin-zabbix-app +Error: ✗ plugin does not exist +""" + return 1, STDOUT, STDERR + + +class GrafanaPlugin(TestCase): + + @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" + } + + module = MagicMock() + module.run_command.return_value = run_command_install_zip() + + 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') + def test_plugin_ls(self, mock_grafana_cli_bin): + mock_grafana_cli_bin.return_value = "grafana-cli plugins" + + params = { + "name": "alexanderzobnin-zabbix-app" + } + + module = MagicMock() + module.run_command.return_value = run_command_ls() + + 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') + def test_plugin_uninstall(self, mock_grafana_cli_bin): + mock_grafana_cli_bin.return_value = "grafana-cli plugins" + + params = { + "name": "alexanderzobnin-zabbix-app" + } + + module = MagicMock() + module.run_command.return_value = run_command_uninstall() + + 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') + def test_plugin_uninstall_again(self, mock_grafana_cli_bin): + mock_grafana_cli_bin.return_value = "grafana-cli plugins" + + params = { + "name": "alexanderzobnin-zabbix-app" + } + + module = MagicMock() + module.run_command.return_value = run_command_uninstall_again() + + result = grafana_plugin.get_grafana_plugin_version(module, params) + self.assertEqual(result, None) 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 new file mode 100644 index 000000000..c59953afa --- /dev/null +++ b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_team/test_grafana_team.py @@ -0,0 +1,447 @@ +from __future__ import (absolute_import, division, print_function) + +from unittest import TestCase +from unittest.mock import patch, MagicMock +from ansible_collections.community.grafana.plugins.modules import grafana_team +from ansible.module_utils._text import to_bytes +from ansible.module_utils import basic +from ansible.module_utils.urls import basic_auth_header +import json + +__metaclass__ = type + + +class MockedReponse(object): + def __init__(self, data): + self.data = data + + def read(self): + return self.data + + +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 + raise AnsibleExitJson(kwargs) + + +def fail_json(*args, **kwargs): + """function to patch over fail_json; package return data into an exception""" + 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}) + basic._ANSIBLE_ARGS = to_bytes(args) + + +def unauthorized_resp(): + return (None, {"status": 401}) + + +def permission_denied_resp(): + return (None, {"status": 403}) + + +def get_version_resp(): + return {"major": 6, "minor": 0, "rev": 0} + + +def get_low_version_resp(): + return {"major": 4, "minor": 6, "rev": 0} + + +def team_exists_resp(): + server_response = json.dumps({"totalCount": 1, "teams": [{"name": "MyTestTeam", "email": "email@test.com"}]}, sort_keys=True) + return (MockedReponse(server_response), {"status": 200}) + + +def team_not_found_resp(): + server_response = json.dumps({"totalCount": 0, "teams": []}) + return (MockedReponse(server_response), {"status": 200}) + + +def team_created_resp(): + server_response = json.dumps({"message": "Team created", "teamId": 2}) + return (MockedReponse(server_response), {"status": 200}) + + +def team_updated_resp(): + server_response = json.dumps({"message": "Team updated"}) + return (MockedReponse(server_response), {"status": 200}) + + +def team_deleted_resp(): + server_response = json.dumps({"message": "Team deleted"}) + return (MockedReponse(server_response), {"status": 200}) + + +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" + }]) + return (MockedReponse(server_response), {"status": 200}) + + +def team_members_no_members_resp(): + server_response = json.dumps([]) + return (MockedReponse(server_response), {"status": 200}) + + +def add_team_member_resp(): + server_response = json.dumps({"message": "Member added to Team"}) + return (MockedReponse(server_response), {"status": 200}) + + +def delete_team_member_resp(): + server_response = json.dumps({"message": "Team Member removed"}) + return (MockedReponse(server_response), {"status": 200}) + + +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.start() + self.addCleanup(self.mock_module_helper.stop) + + def test_module_setup_fails_without_params(self): + set_module_args({}) + + 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') + 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' + }) + + with self.assertRaises(AnsibleFailJson) as result: + grafana_team.main() + 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' + }) + + with self.assertRaises(AnsibleFailJson) as result: + grafana_team.main() + 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', + }) + + with self.assertRaises(AnsibleFailJson) as result: + grafana_team.main() + 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', + }) + + 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') + 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', + }) + + 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() + 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() + 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') + 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' + }) + module = grafana_team.setup_module_object() + mock_fetch_url.return_value = team_exists_resp() + mock_get_version.return_value = get_version_resp() + + 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', + 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' + }) + module = grafana_team.setup_module_object() + mock_fetch_url.return_value = team_not_found_resp() + mock_get_version.return_value = get_version_resp() + + 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', + 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') + 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' + }) + module = grafana_team.setup_module_object() + mock_fetch_url.return_value = team_created_resp() + mock_get_version.return_value = get_version_resp() + + grafana_iface = grafana_team.GrafanaTeamInterface(module) + + 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') + 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' + }) + module = grafana_team.setup_module_object() + mock_fetch_url.return_value = team_updated_resp() + mock_get_version.return_value = get_version_resp() + + 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') + 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' + }) + module = grafana_team.setup_module_object() + mock_fetch_url.return_value = team_deleted_resp() + mock_get_version.return_value = get_version_resp() + + 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', + 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') + 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' + }) + module = grafana_team.setup_module_object() + mock_fetch_url.return_value = team_members_resp() + mock_get_version.return_value = get_version_resp() + + 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', + 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' + }) + module = grafana_team.setup_module_object() + mock_fetch_url.return_value = team_members_no_members_resp() + mock_get_version.return_value = get_version_resp() + + 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', + 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') + 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' + }) + 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: + 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') + 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' + }) + 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: + 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', + data=None, + headers={'Content-Type': 'application/json', 'Authorization': self.authorization}, + method='DELETE') + self.assertEquals(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"]}) 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 new file mode 100644 index 000000000..925c01655 --- /dev/null +++ b/ansible_collections/community/grafana/tests/unit/modules/grafana/grafana_user/test_grafana_user.py @@ -0,0 +1,200 @@ +from __future__ import (absolute_import, division, print_function) + +from unittest import TestCase +from unittest.mock import call, patch, MagicMock +from ansible_collections.community.grafana.plugins.modules import grafana_user +from ansible.module_utils._text import to_bytes +from ansible.module_utils import basic +from ansible.module_utils.urls import basic_auth_header +import json + +__metaclass__ = type + + +class MockedReponse(object): + def __init__(self, data): + self.data = data + + def read(self): + return self.data + + +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 + raise AnsibleExitJson(kwargs) + + +def fail_json(*args, **kwargs): + """function to patch over fail_json; package return data into an exception""" + 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}) + basic._ANSIBLE_ARGS = to_bytes(args) + + +def user_deleted_resp(): + server_response = json.dumps({"message": "User deleted"}) + return (MockedReponse(server_response), {"status": 200}) + + +def user_already_exists_resp(): + server_response = json.dumps({"message": "failed to create user"}) + return (MockedReponse(server_response), {"status": 500}) + + +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) + 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.start() + self.addCleanup(self.mock_module_helper.stop) + + # create an already existing user + @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' + }) + 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') + 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') + + # create a new user + @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' + }) + module = grafana_user.setup_module_object() + + mock_fetch_url.return_value = user_created_resp() + + expected_fetch_url_calls = [ + # 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'), + + # second call to return created user + call( + module, + 'https://grafana.example.com/api/users/lookup?loginOrEmail=robin', + data=None, + 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') + 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' + }) + module = grafana_user.setup_module_object() + mock_fetch_url.return_value = user_deleted_resp() + + grafana_iface = grafana_user.GrafanaUserInterface(module) + user_id = 42 + result = grafana_iface.delete_user(user_id) + mock_fetch_url.assert_called_once_with( + module, + '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"}) |