ansible-role-influxdb/library/influxdb_auth.py

235 lines
7.5 KiB
Python

#!/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()