From 4c7340ceaae96ac9365663dc5190d99c32b75ab1 Mon Sep 17 00:00:00 2001 From: Danny Webb Date: Fri, 4 Oct 2024 09:24:49 +0100 Subject: [PATCH] adding ability to target alertmanager datasources for silence creation / deletion --- plugins/modules/grafana_silence.py | 55 +++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/plugins/modules/grafana_silence.py b/plugins/modules/grafana_silence.py index 1b2b7091..5472a36e 100644 --- a/plugins/modules/grafana_silence.py +++ b/plugins/modules/grafana_silence.py @@ -69,6 +69,12 @@ type: list elements: dict required: true + alertmanager_datasource: + description: + - Which alertmanager datasource to target + type: str + required false + default: grafana state: description: - Delete the first occurrence of a silence with the same settings. Can be "absent" or "present". @@ -104,6 +110,23 @@ value: test state: present +- name: Create a silence against a specific datasource + community.grafana.grafana_silence: + grafana_url: "https://grafana.example.com" + grafana_api_key: "{{ some_api_token_value }}" + comment: "a testcomment" + created_by: "me" + starts_at: "2029-07-29T08:45:45.000Z" + ends_at: "2029-07-29T08:55:45.000Z" + matchers: + - isEqual: true + isRegex: true + name: environment + value: test + alertmanager_datasource: exampleDS + state: present + + - name: Delete a silence community.grafana.grafana_silence: grafana_url: "https://grafana.example.com" @@ -196,6 +219,8 @@ def __init__(self, module): self._module = module self.grafana_url = base.clean_url(module.params.get("url")) self.org_id = None + # Default here because you can't look up "grafana" DS via API + self.alertmanager_path = "grafana" # {{{ Authentication header self.headers = {"Content-Type": "application/json"} if module.params.get("grafana_api_key", None): @@ -224,6 +249,11 @@ def __init__(self, module): failed=True, msg="Silences API is available starting with Grafana v8", ) + + if module.params.get("alertmanager_datasource", None): + self.alertmanager_path = ( + self.datasource_by_name(module.params["alertmanager_datasource"]) + ) def _send_request(self, url, data=None, headers=None, method="GET"): if data is not None: @@ -268,6 +298,16 @@ def organization_by_name(self, org_name): failed=True, msg="Current user isn't member of organization: %s" % org_name ) + def datasource_by_name(self, datasource_name): + url = f"/api/datasources/name/{datasource_name}" + datasource = self._send_request(url, headers=self.headers, method="GET") + if datasource: + return datasource["uid"] + + return self._module.fail_json( + failed=True, msg=f"Datasource not found: {datasource_name}" + ) + def get_version(self): url = "/api/health" response = self._send_request( @@ -280,7 +320,7 @@ def get_version(self): raise GrafanaError("Failed to retrieve version from '%s'" % url) def create_silence(self, comment, created_by, starts_at, ends_at, matchers): - url = "/api/alertmanager/grafana/api/v2/silences" + url = f"/api/alertmanager/{self.alertmanager_path}/api/v2/silences" silence = dict( comment=comment, createdBy=created_by, @@ -297,7 +337,7 @@ def create_silence(self, comment, created_by, starts_at, ends_at, matchers): return response def get_silence(self, comment, created_by, starts_at, ends_at, matchers): - url = "/api/alertmanager/grafana/api/v2/silences" + url = f"/api/alertmanager/{self.alertmanager_path}/api/v2/silences" responses = self._send_request(url, headers=self.headers, method="GET") @@ -313,21 +353,17 @@ def get_silence(self, comment, created_by, starts_at, ends_at, matchers): return None def get_silence_by_id(self, silence_id): - url = "/api/alertmanager/grafana/api/v2/silence/{SilenceId}".format( - SilenceId=silence_id - ) + url = f"/api/alertmanager/{self.alertmanager_path}/api/v2/silence/{silence_id}" response = self._send_request(url, headers=self.headers, method="GET") return response def get_silences(self): - url = "/api/alertmanager/grafana/api/v2/silences" + url = f"/api/alertmanager/{self.alertmanager_path}/api/v2/silences" response = self._send_request(url, headers=self.headers, method="GET") return response def delete_silence(self, silence_id): - url = "/api/alertmanager/grafana/api/v2/silence/{SilenceId}".format( - SilenceId=silence_id - ) + url = f"/api/alertmanager/{self.alertmanager_path}/api/v2/silence/{silence_id}" response = self._send_request(url, headers=self.headers, method="DELETE") return response @@ -352,6 +388,7 @@ def setup_module_object(): org_name=dict(type="str"), skip_version_check=dict(type="bool", default=False), starts_at=dict(type="str", required=True), + alertmanager_datasource=dict(type=str), state=dict(type="str", choices=["present", "absent"], default="present"), )