#!/usr/bin/env python import requests from ansible.module_utils.basic import AnsibleModule DOCUMENTATION = r''' --- module: influx2_dashboard short_description: create dashboard in influxdb2 description: create dashboard in influxdb2 notes: - just works with influxdb version 2 - does not create dashboard description - does not update dashboards - just creates a dashboard if it does not exist. options: base: description: URL for path, e.g. `https://localhost:8086` type: str required: True org: description: influxdb2 organisation type: str required: True token: description: influxdb2 authentication token type: str required: True data: description: exported dashboard json file type: json required: True force: description: force creation even if dashboard already exists (adds a new one) type: bool required: False default: False author: - Thorsten M. (@thoto) ''' EXAMPLES = r''' - name: "fetch auth token" raw: influx auth list --user my-user --hide-headers | cut -f 3 register: influx_token_fetch delegate_to: ed-influxdb-2 - name: "create dashboard" influx_dashboard: base: "http://localhost:8086" org: "my-org" token: "{{influx_token_fetch.stdout_lines[0]}}" data: "{{lookup('file', 'influxdb-dashboard-cobald.json')}}" ''' def get_org_id(base, org_name, h): ro = requests.get("{base}/api/v2/orgs".format(base=base), headers=h, json={"org": org_name}) ro.raise_for_status() org_id = [o["id"] for o in ro.json()["orgs"] if o["name"] == org_name] return org_id[0] def marker(key): return "__ANSIBLE_TOKEN_{key}__".format(key=key) def _filter_perms(perms): for r in perms: r["resource"] = {k: v for k, v in r["resource"].items() if v} return perms class Token: def __init__(self, base, h, data): self.base = base self.h = h self.marker = marker(data["key"]) self.org_id = data["org_id"] self.perms = _filter_perms(data["perms"]) self.description = data["description"]+" "+self.marker self.result_token = None self.f = None def check(self): ra = requests.get("{base}/api/v2/authorizations".format( base=self.base), params={"orgID": self.org_id}, headers=self.h) ra.raise_for_status() x = [i for i in ra.json()["authorizations"] if self.marker in i["description"] and i["orgID"] == self.org_id] update = None for i in x: # FIXME: one loop if self._match_perms(self.perms, i["permissions"]): if self.description == i["description"]: self.result_token = i return False # everything matches -> no change needed else: self.result_token = i update = {"auth_id": i["id"], "description": self.description} # TODO: may remove token because permissions do not match? if update: self.f = lambda: self._update(**update) else: self.result_token = None self.f = lambda: self._create({ "orgID": self.org_id, # "permissions": self.perms, "description": self.description, "permissions": self.perms }) return True def run(self): if not self.f: self.check() ra = self.f() def _match_perms(self, pa, pb): a = pa.copy() b = pb.copy() for i in a: try: b.remove(i) except ValueError: return False # permission i not present in b if b: # not empty return False # some permissions in b not in a return True def _update(self, auth_id, description): ra = requests.patch( "{base}/api/v2/authorizations/{auth_id}".format( base=self.base, auth_id=auth_id), headers=self.h, json={"description": description}) ra.raise_for_status() return ra def _create(self, data): ra = requests.post("{base}/api/v2/authorizations".format( base=self.base), headers=self.h, json=data) ra.raise_for_status() self.result_token = ra.json() return ra if __name__ == "__main__": result = dict(changed=False, message="") module = AnsibleModule( argument_spec=dict( base=dict(type="str", required=True), org=dict(type="str", required=True), auth_token=dict(type="str", required=True), key=dict(type="str", required=True), description=dict(type="str", default=""), permissions=dict(type="list", elements='dict', options=dict( action=dict(type='str', choices=['read', 'write'], required=True), resource=dict(type='dict', options=dict( id=dict(type='str'), name=dict(type='str'), org=dict(type='str'), orgID=dict(type='str'), type=dict(type='str', required=True), ), required=True), ), required=True), force=dict(type="bool", default=False), ), supports_check_mode=True ) h = {"Authorization": "Token {token}".format( token=module.params["auth_token"])} t = Token(module.params["base"], h, { "org_id": get_org_id(module.params["base"], module.params["org"], h), "key": module.params["key"], # "perms": [{"action": "write", "resource": { "type": "buckets"}}], "perms": module.params["permissions"], "description": module.params["description"]}) changed = t.check() if t.result_token: result['token'] = t.result_token["token"] result['changed'] = changed if module.check_mode: module.exit_json(**result) if changed or module.params["force"]: t.run() result['token'] = t.result_token["token"] module.exit_json(**result)