#!/usr/bin/python3 from ansible.module_utils.basic import AnsibleModule import requests import json class InfluxdbAuth: def __init__(self, api_url, api_token, org, user, permissions): self.api_url = api_url self.headers = {'Authorization': 'Token {}'.format(api_token)} self.org = org self.user = user self.permissions = permissions def exists(self): url = '{}/api/v2/authorizations'.format(self.api_url) r = requests.get( url, headers=self.headers, params={'org': self.org, 'user': self.user} ) if r.status_code == 404: return False elif r.status_code == 200: data = json.loads(r.text) for auth in data['authorizations']: if self.check_permissions(auth['permissions']): self.id = auth['id'] self.status = auth['status'] self.description = auth['description'] return True return False raise Exception( 'Influxdb', 'Bad status code {}: {}'.format(r.status_code, r.text) ) def check_permissions(self, permissions): for pa in self.permissions: find = False for pb in permissions: if pa['action'] != pb['action']: continue if pa['resource']['type'] != pb['resource']['type']: continue if 'org' in pa['resource'] and 'org' in pb['resource']: if pa['resource']['org'] != pb['resource']['org']: continue if 'name' in pa['resource'] and 'name' in pb['resource']: if pa['resource']['name'] != pb['resource']['name']: continue find = True break if not find: return False return True def transform_permissions(self): permissions = list() for perm in self.permissions: org = None if 'org' in perm['resource'] and 'orgID' not in perm['resource']: org = perm['resource']['org'] perm['resource']['orgID'] = self.get_orgid(org) if 'name' in perm['resource'] and 'id' not in perm['resource']: if perm['resource']['type'] == 'buckets': if org is None: org = self.org perm['resource']['id'] = self.get_bucketid( perm['resource']['name'], org) permissions.append(perm) return permissions def has_changed(self, status, description): if self.status != status: return True if self.description != description: return True return False def create(self, status, description): url = '{}/api/v2/authorizations'.format(self.api_url) r = requests.post( url, headers=self.headers, json={ 'userID': self.get_userid(self.user, self.org), 'orgID': self.get_orgid(self.org), 'status': status, 'description': description, 'permissions': self.transform_permissions() } ) if r.status_code != 201: raise Exception( 'Influxdb', 'Bad status code {}: {}'.format(r.status_code, r.text) ) def delete(self): url = '{}/api/v2/authorizations/{}'.format(self.api_url, self.id) r = requests.delete(url, headers=self.headers) if r.status_code != 204: raise Exception( 'Influxdb', 'Bad status code {}: {}'.format(r.status_code, r.text) ) def update(self, status, description): url = '{}/api/v2/authorizations/{}'.format(self.api_url, self.id) r = requests.patch( url, headers=self.headers, json={ 'description': description, 'status': status } ) if r.status_code != 200: raise Exception( 'Influxdb', 'Bad status code {}: {}'.format(r.status_code, r.text) ) def get_bucketid(self, bucket_name, org): url = '{}/api/v2/buckets'.format(self.api_url) r = requests.get( url, headers=self.headers, params={'name': bucket_name, 'org': org} ) if r.status_code != 200: raise Exception( 'Influxdb', 'Bad status code {}: {}'.format(r.status_code, r.text) ) data = json.loads(r.text) for bucket in data['buckets']: if bucket['name'] == bucket_name: return bucket['id'] raise Exception('Influxdb', 'Don\'t get the bucketID') def get_orgid(self, org_name): url = '{}/api/v2/orgs'.format(self.api_url) r = requests.get(url, headers=self.headers, params={'org': org_name}) if r.status_code != 200: raise Exception( 'Influxdb', 'Bad status code {}: {}'.format(r.status_code, r.text) ) data = json.loads(r.text) for org in data['orgs']: if org['name'] == org_name: return org['id'] raise Exception('Influxdb', 'Don\'t get the orgID') def get_userid(self, user_name, org): url = '{}/api/v2/users'.format(self.api_url) r = requests.get( url, headers=self.headers, params={'name': user_name, 'org': org} ) if r.status_code != 200: raise Exception( 'Influxdb', 'Bad status code {}: {}'.format(r.status_code, r.text) ) data = json.loads(r.text) for user in data['users']: if user['name'] == user_name: return user['id'] raise Exception('Influxdb', 'Don\'t get the userID') def main(): fields = { 'user': {'type': 'str', 'required': True}, 'org': {'type': 'str', 'required': True}, 'permissions': {'type': 'list', 'required': True}, 'status': {'type': 'str', 'default': 'active', 'choice': ['active', 'inactive']}, 'description': {'type': 'str', 'default': ''}, 'api_url': {'type': 'str', 'default': 'http://127.0.0.1:8086'}, 'api_token': {'type': 'str', 'required': True}, 'state': {'type': 'str', 'default': 'present', 'choice': ['present', 'absent']}, } module = AnsibleModule(argument_spec=fields) auth = InfluxdbAuth( module.params['api_url'], module.params['api_token'], module.params['org'], module.params['user'], module.params['permissions'], ) changed = False if auth.exists(): if module.params['state'] == 'absent': auth.delete() changed = True elif auth.has_changed(module.params['status'], module.params['description']): auth.update(module.params['status'], module.params['description']) changed = True elif module.params['state'] == 'present': auth.create(module.params['status'], module.params['description']) changed = True module.exit_json(changed=changed) if __name__ == '__main__': main()