Skip to content

Commit

Permalink
Merge pull request #6 from tbauriedel/enhancement/influxdb
Browse files Browse the repository at this point in the history
Add handling for buckets
  • Loading branch information
tbauriedel authored Jan 4, 2024
2 parents d06f4df + a1bd6c5 commit dd39616
Show file tree
Hide file tree
Showing 10 changed files with 304 additions and 6 deletions.
36 changes: 31 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,39 @@ The collection is still at a very experimental stage and is growing bit by bit a

It was created with the aim of refreshing my Ansible knowledge and getting in touch with Collections. Any hints for improvements are therefore welcome.

## Roles

* [Role: repos](roles/repos/README.md) - Install the official InfluxDb repositories
* [Role: influxdb](roles/influxdb/README.md) - Install and configure InfluxDB

## Example

```
- hosts: all
become: true
vars:
influxdb_influxdb_admin_token: 12345678abcdefg
influxdb_influxdb_buckets:
- name: foobar1
state: absent
org: default
token: "{{ influxdb_influxdb_admin_token }}"
host: "{{ influxdb_influxdb_host }}"
retention:
type: 'expire'
everySeconds: '50000'
shardGroupDurationSeconds: '0'
collections:
tbauriedel.influxdb
roles:
- repos
- influxdb
```

## Supported systems
| Distribution | Tested on |
|--------------|-----------|
| Ubuntu | 22.04 |
| Centos | 9 Stream |

## Roles

* [Role: repos](roles/repos/README.md) (add repositories)
* [Role: influxdb](roles/influxdb/README.md) (install and configure influxdb)
2 changes: 2 additions & 0 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Vagrant.configure("2") do |config|
ubuntu.vm.network "forwarded_port", guest: 8086, host: 8086
ubuntu.vm.provision "ansible" do |ansible|
ansible.playbook = "vagrant-tests.yml"
# ansible.verbose = "vvv"
end
end

Expand All @@ -17,6 +18,7 @@ Vagrant.configure("2") do |config|
centos.vm.network "forwarded_port", guest: 8086, host: 8087
centos.vm.provision "ansible" do |ansible|
ansible.playbook = "vagrant-tests.yml"
# ansible.verbose = "vvv"
end
end
end
17 changes: 17 additions & 0 deletions galaxy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace: tbauriedel
name: influxdb
version: 0.0.0
readme: README.md
authors:
- Tobias Bauriedel <[email protected]>
description: >
This collection manages InfluxDB components.
Including the official repositories, installation and configuration.
license:
- Apache-2.0
tags:
- collection
- influxdb
- metrics
dependencies: {}
repository: https://github.com/tbauriedel/ansible-collection-influxdb
121 changes: 121 additions & 0 deletions plugins/module_utils/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#!/usr/bin/python3

import json
import requests

class InfluxApi():
'''
Common api requests to for InfluxDBv2
'''
def get_bucket_status(module):
'''
Get state of single bucket of org from InfluxDB. Returns 'present' if found and 'absent' if not present.
'''
headers = {
'Authorization': 'Token ' + module.params['token']
}

url = module.params['host'] + '/api/v2/buckets?name=' + module.params['name'] + "&orgID=" + InfluxApi.get_orgID_by_name(module)
response = requests.get(url, headers=headers)
json_resp = json.loads(response.content)

if "code" in json_resp:
if json_resp["code"] == "not found":
return "absent"

for bucket in json_resp["buckets"]:
if bucket['name'] == module.params['name']:
return 'present'
else:
return 'absent'


def get_all_orgs(module):
'''
Get all organizations from InfluxDB. Queries.
Returns JSON.
'''

headers = {
'Authorization': 'Token ' + module.params['token']
}
response = requests.get(module.params['host'] + '/api/v2/orgs', headers=headers)

return json.loads(response.content)


def get_orgID_by_name(module):
'''
Get organization ID by name. Returns ID
If no organization is found by name, 'not found' will be returned.
'''

orgs = InfluxApi.get_all_orgs(module)

for org in orgs['orgs']:
if org['name'] == module.params['org']:
return org['id']

return "not found"


def create_bucket(module):
'''
Create bucket
'''

headers = {
'Authorization': 'Token ' + module.params['token'],
'Content-type': 'application/json'
}

url = module.params['host'] + '/api/v2/buckets'
payload = {
'orgID': InfluxApi.get_orgID_by_name(module),
'name': module.params['name'],
'retentionRules': [
{
'type': module.params['retention']['type'],
'everySeconds': int(module.params['retention']['everySeconds']),
'shardGroupDurationSeconds': int(module.params['retention']['shardGroupDurationSeconds'])
}
]
}
response = requests.post(url, headers=headers, data=json.dumps(payload))

return response.status_code, response.content


def get_bucketID_by_name(module):
'''
Get bucket ID by name. Returns ID
If no bucket is found by name, 'not found' will be returned
'''

headers = {
'Authorization': 'Token ' + module.params['token']
}

url = module.params['host'] + '/api/v2/buckets?name=' + module.params['name'] + "&orgID=" + InfluxApi.get_orgID_by_name(module)
response = requests.get(url, headers=headers)
json_resp = json.loads(response.content)

for bucket in json_resp['buckets']:
return bucket['id']

return "not found"


def delete_bucket(module):
'''
Delete bucket
'''

headers = {
'Authorization': 'Token ' + module.params['token']
}

url = module.params['host'] + '/api/v2/buckets/' + InfluxApi.get_bucketID_by_name(module)
response = requests.delete(url, headers=headers)

return response.status_code, response.content
82 changes: 82 additions & 0 deletions plugins/modules/organize_bucket.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/python3

from ansible.module_utils.basic import AnsibleModule
from ansible_collections.tbauriedel.influxdb.plugins.module_utils.utils import (
InfluxApi
)

def run_module():
# Define new Module with arguments
module = AnsibleModule(
argument_spec=dict(
name=dict(type=str, required=True),
state=dict(type=str, required=True),
token=dict(type=str, Required=True, no_log=True),
host=dict(type=str, Required=True),
org=dict(type=str, required=False),
retention=dict(type=dict, required=False)
)
)

if module.params['state'] != 'absent' and module.params['state'] != 'present':
module.exit_json(
failed=True,
stderr="Invalid state provided. Use 'present' or 'absent'"
)

# Default result
result = dict(
changed=False,
failed=False,
rc=""
)

# Get state of current bucket
orgID = InfluxApi.get_orgID_by_name(module)
if orgID == "not found":
module.exit_json(dict(
failed=True,
stderr="No orgID found for given org name"
))

# Get state of bucket ('present' or 'absent')
bucketState = InfluxApi.get_bucket_status(module)

# Create bucket if not 'present' but 'present' in configuration
if module.params['state'] == 'present' and bucketState == 'absent':
result['debug'] = "Create bucket"

rc, content = InfluxApi.create_bucket(module)
result['rc'] = rc
if rc != 201:
module.exit_json(
failed=True,
stderr=content
)

result['changed'] = True

# Delete bucket if 'present' but 'absent' in configuration
elif module.params['state'] == 'absent' and bucketState == 'present':
result['debug'] = "Delete bucket"

rc, content = InfluxApi.delete_bucket(module)
result['rc'] = rc
if rc != 204:
module.exit_json(
failed=True,
stderr=content
)

result['changed'] = True

else:
result['debug'] = "Keep state of bucket"

module.exit_json(**result)

def main():
run_module()

if __name__ == '__main__':
main()
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# ansible collections
# - community.general
14 changes: 13 additions & 1 deletion roles/influxdb/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ At the moment the configuration is very basic. Over time, this role will be expa
**Configuration:**
* `influxdb_influxdb_bolt_path`: InfluxDB bolt-path
* `influxdb_influxdb_engine_path`: InfluxDB engine-path
* `influxdb_influxdb_extra_config`: Extra configuration
* `influxdb_influxdb_extra_config`: Some extra configuration

**Setup:**
* `influxdb_influxdb_host`: HTTP address of InfluxDB (default: 'http://localhost:8086')
Expand All @@ -19,6 +19,18 @@ At the moment the configuration is very basic. Over time, this role will be expa
* `influxdb_influxdb_primary_org`: Primary organization (default: 'default')
* `influxdb_influxdb_primary_bucket`: Primary bucket (default: 'default')
* `influxdb_influxdb_retention`: Retention for primary bucket (default: '0')
* `influxdb_influxdb_admin_token`: Admin API token created in the setup (default: 'Random123ChangeMe!')

**Buckets**
* `influxdb_influxdb_buckets`: List of buckets to manage
* `name`: Name of bucket. (watch [bucket naming restrictions](https://docs.influxdata.com/influxdb/v2/admin/buckets/create-bucket/?t=InfluxDB+API#bucket-naming-restrictions))
* `state`: state of bucket ('present' or 'absent')
* `org`: InfluxDB organization name
* `token`: API token to manage the bucket
* `retention`: List of retention rules containing a single object with the following fields
* `type`: expire
* `everySeconds`: Number of seconds to retain data (0 means forever)
* `shardGroupDurationSeconds`: Number of seconds to retain shard groups (0 means forever)

Defaults can be viewed in vars/defaults.yml

Expand Down
3 changes: 3 additions & 0 deletions roles/influxdb/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,7 @@ influxdb_influxdb_primary_user:
password: ChangeMe123!
influxdb_influxdb_primary_org: default
influxdb_influxdb_primary_bucket: default
influxdb_influxdb_admin_token: "Random123ChangeMe!"
influxdb_influxdb_retention: 0

influxdb_influxdb_buckets: []
18 changes: 18 additions & 0 deletions roles/influxdb/tasks/setup.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
---
- name: Ensure admin setup token is definded
ansible.builtin.fail:
msg: Variable influxdb_influxdb_admin_token is not defined in variables
when: influxdb_influxdb_admin_token == ""

- name: Ensure InfluxDB is set up
ansible.builtin.command: influx setup \
--host "{{ influxdb_influxdb_host }}" \
Expand All @@ -7,6 +12,7 @@
--org "{{ influxdb_influxdb_primary_org }}" \
--bucket "{{ influxdb_influxdb_primary_bucket }}" \
--retention "{{ influxdb_influxdb_retention }}" \
--token "{{ influxdb_influxdb_admin_token }}" \
--force
register: _influx_setup
failed_when:
Expand All @@ -15,3 +21,15 @@
changed_when: _influx_setup.rc == 0

# TODO add handling for orgs, buckets, etc.
- name: Organize buckets
tbauriedel.influxdb.organize_bucket:
name: "{{ item.name }}"
state: "{{ item.state }}"
org: "{{ item.org }}"
token: "{{ item.token }}"
host: "{{ influxdb_influxdb_host }}"
retention:
type: "{{ item.retention.type }}"
everySeconds: "{{ item.retention.everySeconds }}"
shardGroupDurationSeconds: "{{ item.retention.shardGroupDurationSeconds }}"
loop: "{{ influxdb_influxdb_buckets }}"
15 changes: 15 additions & 0 deletions vagrant-tests.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
---
- hosts: all
become: true
vars:
influxdb_influxdb_admin_token: 12345678abcdefg
influxdb_influxdb_buckets:
- name: foobar1
state: absent
org: default
token: "{{ influxdb_influxdb_admin_token }}"
host: "{{ influxdb_influxdb_host }}"
retention:
type: 'expire'
everySeconds: 50000
shardGroupDurationSeconds: 0

collections:
tbauriedel.influxdb

roles:
- repos
Expand Down

0 comments on commit dd39616

Please sign in to comment.