diff --git a/plugins/module_utils/base.py b/plugins/module_utils/base.py index 7d51601d..e69552bf 100644 --- a/plugins/module_utils/base.py +++ b/plugins/module_utils/base.py @@ -17,7 +17,10 @@ # Copyright: (c) 2019, RĂ©mi REY (@rrey) from __future__ import absolute_import, division, print_function -from ansible.module_utils.urls import url_argument_spec +from ansible.module_utils.urls import fetch_url, url_argument_spec +from ansible.module_utils._text import to_text + +import json __metaclass__ = type @@ -52,3 +55,28 @@ def grafana_required_together(): def grafana_mutually_exclusive(): return [["url_username", "grafana_api_key"]] + + +class BaseInterface: + def check_required_version(self, minimum_version): + if not self._module.params.get("skip_version_check"): + try: + response, info = fetch_url( + self._module, + "%s/api/health" % (self.grafana_url), + headers=self.headers, + method="GET", + ) + content = json.loads(response.read()) + version = content.get("version") + major_version = int(version.split(".")[0]) + + except GrafanaError as e: + self._module.fail_json(failed=True, msg=to_text(e)) + + if major_version < int(minimum_version): + self._module.fail_json( + failed=True, + msg="Need at least Grafana version %s to use this feature." + % minimum_version, + ) diff --git a/plugins/modules/grafana_folder.py b/plugins/modules/grafana_folder.py index 07a3400a..01fab9e9 100644 --- a/plugins/modules/grafana_folder.py +++ b/plugins/modules/grafana_folder.py @@ -165,7 +165,13 @@ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.urls import fetch_url, basic_auth_header -from ansible_collections.community.grafana.plugins.module_utils import base +from ansible_collections.community.grafana.plugins.module_utils.base import ( + BaseInterface, + grafana_argument_spec, + grafana_required_together, + grafana_mutually_exclusive, + clean_url, +) from ansible.module_utils.six.moves.urllib.parse import quote from ansible.module_utils._text import to_text @@ -176,8 +182,9 @@ class GrafanaError(Exception): pass -class GrafanaFolderInterface(object): +class GrafanaFolderInterface(BaseInterface): def __init__(self, module): + super().__init__() self._module = module # {{{ Authentication header self.headers = {"Content-Type": "application/json"} @@ -190,16 +197,8 @@ def __init__(self, module): module.params["url_username"], module.params["url_password"] ) # }}} - self.grafana_url = base.clean_url(module.params.get("url")) - if module.params.get("skip_version_check") is False: - try: - grafana_version = self.get_version() - except GrafanaError as e: - self._module.fail_json(failed=True, msg=to_text(e)) - if grafana_version["major"] < 5: - self._module.fail_json( - failed=True, msg="Folders API is available starting Grafana v5" - ) + self.grafana_url = clean_url(module.params.get("url")) + self.check_required_version(minimum_version="5") def _send_request(self, url, data=None, headers=None, method="GET"): if data is not None: @@ -233,17 +232,6 @@ def _send_request(self, url, data=None, headers=None, method="GET"): failed=True, msg="Grafana Folders API answered with HTTP %d" % status_code ) - def get_version(self): - url = "/api/health" - response = self._send_request( - url, data=None, headers=self.headers, method="GET" - ) - version = response.get("version") - if version is not None: - major, minor, rev = version.split(".") - return {"major": int(major), "minor": int(minor), "rev": int(rev)} - raise GrafanaError("Failed to retrieve version from '%s'" % url) - def create_folder(self, title): url = "/api/folders" folder = dict(title=title) @@ -270,13 +258,13 @@ def setup_module_object(): module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=False, - required_together=base.grafana_required_together(), - mutually_exclusive=base.grafana_mutually_exclusive(), + required_together=grafana_required_together(), + mutually_exclusive=grafana_mutually_exclusive(), ) return module -argument_spec = base.grafana_argument_spec() +argument_spec = grafana_argument_spec() argument_spec.update( name=dict(type="str", aliases=["title"], required=True), state=dict(type="str", default="present", choices=["present", "absent"]), diff --git a/plugins/modules/grafana_team.py b/plugins/modules/grafana_team.py index 787b4345..4b330c44 100644 --- a/plugins/modules/grafana_team.py +++ b/plugins/modules/grafana_team.py @@ -172,7 +172,13 @@ from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.urls import fetch_url, basic_auth_header from ansible.module_utils._text import to_text -from ansible_collections.community.grafana.plugins.module_utils import base +from ansible_collections.community.grafana.plugins.module_utils.base import ( + BaseInterface, + grafana_argument_spec, + grafana_required_together, + grafana_mutually_exclusive, + clean_url, +) from ansible.module_utils.six.moves.urllib.parse import quote __metaclass__ = type @@ -182,8 +188,9 @@ class GrafanaError(Exception): pass -class GrafanaTeamInterface(object): +class GrafanaTeamInterface(BaseInterface): def __init__(self, module): + super().__init__() self._module = module # {{{ Authentication header self.headers = {"Content-Type": "application/json"} @@ -196,16 +203,7 @@ def __init__(self, module): module.params["url_username"], module.params["url_password"] ) # }}} - self.grafana_url = base.clean_url(module.params.get("url")) - if module.params.get("skip_version_check") is False: - try: - grafana_version = self.get_version() - except GrafanaError as e: - self._module.fail_json(failed=True, msg=to_text(e)) - if grafana_version["major"] < 5: - self._module.fail_json( - failed=True, msg="Teams API is available starting Grafana v5" - ) + self.grafana_url = clean_url(module.params.get("url")) def _send_request(self, url, data=None, headers=None, method="GET"): if data is not None: @@ -235,17 +233,6 @@ def _send_request(self, url, data=None, headers=None, method="GET"): failed=True, msg="Grafana Teams API answered with HTTP %d" % status_code ) - def get_version(self): - url = "/api/health" - response = self._send_request( - url, data=None, headers=self.headers, method="GET" - ) - version = response.get("version") - if version is not None: - major, minor, rev = version.split(".") - return {"major": int(major), "minor": int(minor), "rev": int(rev)} - raise GrafanaError("Failed to retrieve version from '%s'" % url) - def create_team(self, name, email): url = "/api/teams" team = dict(email=email, name=name) @@ -307,13 +294,13 @@ def setup_module_object(): module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=False, - required_together=base.grafana_required_together(), - mutually_exclusive=base.grafana_mutually_exclusive(), + required_together=grafana_required_together(), + mutually_exclusive=grafana_mutually_exclusive(), ) return module -argument_spec = base.grafana_argument_spec() +argument_spec = grafana_argument_spec() argument_spec.update( name=dict(type="str", required=True), email=dict(type="str", required=True), @@ -334,6 +321,8 @@ def main(): grafana_iface = GrafanaTeamInterface(module) + check_required_version(grafana_iface, minimum_version="5") + changed = False if state == "present": team = grafana_iface.get_team(name)