Skip to content

Commit

Permalink
Rebuild module to use influxdb-client library (#13)
Browse files Browse the repository at this point in the history
* update module influxdb2_organizations

* add influxdb bucket handler

* update workflow
  • Loading branch information
tbauriedel authored Sep 19, 2024
1 parent 7a5e97a commit 6481194
Show file tree
Hide file tree
Showing 27 changed files with 1,186 additions and 497 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/molecule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
name: Build

on:
push:
branches:
- "*"
pull_request:
branches:
- '*'
- "*"

jobs:
build:
Expand Down
850 changes: 674 additions & 176 deletions LICENSE

Large diffs are not rendered by default.

36 changes: 23 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
![Lint](https://github.com/tbauriedel/ansible-collection-influxdb2/actions/workflows/yamllint.yml/badge.svg)
![Lint](https://github.com/tbauriedel/ansible-collection-influxdb2/actions/workflows/yamllint.yml/badge.svg) ![Build](https://github.com/tbauriedel/ansible-collection-influxdb2/actions/workflows/molecule.yml/badge.svg)

> **Note:** Collection is work in progress
> **Note:** Collection is not production-ready yet
# ansible-collection-influxdb2

Expand All @@ -16,26 +16,36 @@ It was created with the aim of refreshing my Ansible knowledge and getting in to
* [Role: repos](roles/repos/README.md) - Install the official InfluxDb repositories
* [Role: influxdb2](roles/influxdb2/README.md) - Install and configure InfluxDBv2

## Modules

* [Module: influxdb2_organization](doc/modules/influxdb2_organization.py): Create, update and delete InfluxDBv2 organizations
* [Module: influxdb2_bucket](doc/modules/influxdb2_bucket.md.py): Create, update and delete InfluxDBv2 buckets

## Example

```
- hosts: all
become: true
- name: InfluxDB
hosts: all
vars:
influxdb_influxdb2_admin_token: 12345678abcdefg
influxdb_influxdb2_admin_token: 123456789abc!
influxdb_influxdb2_orgs:
- name: org1
desc: "This is a description"
token: "{{ influxdb_influxdb2_admin_token }}"
influxdb_influxdb2_buckets:
- name: foobar1
state: absent
org: default
token: "{{ influxdb_influxdb2admin_token }}"
host: "{{ influxdb_influxdb2_host }}"
- name: bucket-1
desc: "This is a description"
org: org1
token: "{{ influxdb_influxdb2_admin_token }}"
retention:
type: 'expire'
everySeconds: '50000'
shardGroupDurationSeconds: '0'
everySeconds: '60000'
shardGroupDurationSeconds: '7600'
collections:
tbauriedel.influxdb2
- tbauriedel.influxdb2
roles:
- repos
Expand Down
40 changes: 40 additions & 0 deletions doc/modules/influxdb2_bucket.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Ansible module: influxdb_bucket

This module creates, updates and deletes buckets from your InfluxDB2.

## Requirements

As this module uses the InfluxDB2 API you will need to install the InfluxDB2 Python3 library.

`pip3 install influxdb-client`

## Module arguments

* `name`: Bucket name
* `state`: State of the bucket ('present' or 'absent')
* `org`: Name of the corresponding organization
* `desc`: Description
* `token`: API token to manage the organization
* `host`: InfluxDB API Endpoint
* `retention`: Dict of retention rules containing a single object with the following fields
* `type`: Retention type
* `everySeconds`: Number of seconds to retain data (0 means forever)
* `shardGroupDurationSeconds`: Number of seconds to retain shard groups (**Caution**: The [default values](https://docs.influxdata.com/influxdb/v2/reference/internals/shards/#shard-group-duration) also correspond to the necessary minimum!)

## Example usage

```
- name: Manage bucket
tbauriedel.influxdb2.influxdb2_bucket:
name: "Example"
state: present
desc: "This is a bucket"
org: "{{ item.org }}"
token: "{{ item.token }}"
host: "{{ influxdb_influxdb2_host }}"
retention:
type: "{{ item.retention.type }}"
everySeconds: "{{ item.retention.everySeconds }}"
shardGroupDurationSeconds: "{{ item.retention.shardGroupDurationSeconds) }}"
loop: "{{ influxdb_influxdb2_buckets }}"
```
29 changes: 29 additions & 0 deletions doc/modules/influxdb2_organization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Ansible module: influxdb2_organization

This module creates, updates and deletes organizations from your InfluxDB2.

## Requirements

As this module uses the InfluxDB2 API you will need to install the InfluxDB2 Python3 library.

`pip3 install influxdb-client`

## Module arguments

* `name`: Organization name
* `state`: State of the organization ('present' or 'absent')
* `desc`: Description
* `token`: API token to manage the organization
* `host`: InfluxDB API Endpoint

## Example usage

```
- name: Manage organization
tbauriedel.influxdb2.influxdb2_organization:
name: "Example"
state: present
desc: "This is a organization"
token: "{{ influxdb_api_token }}"
host: "{{ http://localhost:8086 }}"
```
17 changes: 10 additions & 7 deletions molecule/influxdb2/converge.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
---
- name: Converge
hosts: all

vars:
influxdb_influxdb2_admin_token: 123456789abc!
influxdb_influxdb2_orgs:
- name: org1
desc: "This is a description"
token: "{{ influxdb_influxdb2_admin_token }}"

influxdb_influxdb2_buckets:
- name: foobar1
state: present
org: default
- name: bucket-1
desc: "This is a description"
org: org1
token: "{{ influxdb_influxdb2_admin_token }}"
host: "{{ influxdb_influxdb2_host }}"
retention:
type: 'expire'
everySeconds: 50000
shardGroupDurationSeconds: 0
everySeconds: '60000'
shardGroupDurationSeconds: '7600'

collections:
- tbauriedel.influxdb2
Expand Down
2 changes: 2 additions & 0 deletions molecule/influxdb2/molecule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ platforms:
pre_build_image: true
provisioner:
name: ansible
env:
ANSIBLE_VERBOSITY: 3
verifier:
name: ansible
5 changes: 4 additions & 1 deletion molecule/influxdb2/prepare.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@
tasks:
- name: Ensure python3-requests is installed
ansible.builtin.pip:
name: requests
name: "{{ item }}"
loop:
- requests
- influxdb_client
15 changes: 15 additions & 0 deletions plugins/module_utils/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# !/usr/bin/python3

# Copyright (c) 2024, Tobias Bauriedel <[email protected]>
# Licensed under the Apache License, Version 2.0 (the "License");
# You may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0


from influxdb_client import InfluxDBClient

class Api():
def new_client(host, token, timeout=10000) -> InfluxDBClient:
return InfluxDBClient(host, token, timeout=timeout)
118 changes: 118 additions & 0 deletions plugins/module_utils/influxdb2_bucket.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# !/usr/bin/python3

# Copyright (c) 2024, Tobias Bauriedel <[email protected]>
# Licensed under the Apache License, Version 2.0 (the "License");
# You may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0

from re import T
from influxdb_client import Bucket, BucketRetentionRules, Buckets
from ansible_collections.tbauriedel.influxdb2.plugins.module_utils.api import (
Api
)
from ansible_collections.tbauriedel.influxdb2.plugins.module_utils.influxdb2_organization import (
OrgApi
)


class BucketApi():
def __init__(self, name, state, desc, result, host, token, org, retention):
self.name = name
self.state = state
self.desc = desc
self.org = org
self.retention = retention
self.result = result

self.client = Api.new_client(host=host, token=token).buckets_api()

self.host = host
self.token = token

def return_result(self) -> dict:
return self.result

def handle(self):
if self.state == 'absent':
self.handle_absent()
elif self.state == 'present':
self.handle_present()

return

def handle_absent(self):
bucket = Bucket(name=self.name, description=self.desc, id="0", retention_rules=[BucketRetentionRules(type=self.retention['type'], every_seconds=int(
self.retention['everySeconds']), shard_group_duration_seconds=int(self.retention['shardGroupDurationSeconds']))])
for row in self.get_all().buckets:
if row.name != self.name:
continue
bucket = row
break

if bucket.id == "0":
return

self.delete(bucket.id)
self.result['changed'] = True
self.result['msg'] = self.name + " has been deleted"

return

def handle_present(self):
pre_bucket = Bucket(name=self.name, description=self.desc, id="0", retention_rules=[BucketRetentionRules(type=self.retention['type'], every_seconds=int(
self.retention['everySeconds']), shard_group_duration_seconds=int(self.retention['shardGroupDurationSeconds']))])

# fetch all buckets and save found bucket into pre_bucket
for row in self.get_all().buckets:
if row.name != self.name:
continue
pre_bucket = self.get_by_id(row.id)

break

# Create new bucket if not exists
if pre_bucket.id == "0":
bucket = self.create()
if bucket.id == '0':
self.result['changed'] = False
self.result['msg'] = self.name + \
" cant create new bucket because organization does not exists"
return

self.result['changed'] = True
self.result['msg'] = self.name + " has been created"
return

if (
pre_bucket.name != self.name or
(pre_bucket.description or "") != self.desc or
pre_bucket.retention_rules != [BucketRetentionRules(type=self.retention['type'], every_seconds=int(
self.retention['everySeconds']), shard_group_duration_seconds=int(self.retention['shardGroupDurationSeconds']))]
):
self.update(pre_bucket.id)
self.result['changed'] = True
self.result['msg'] = self.name + " has been updated"
return

def create(self) -> Bucket:
orgApi = OrgApi(host=self.host, token=self.token)
org = orgApi.get_by_name(self.org)
if org.status != 'inactive':
return self.client.create_bucket(bucket=Bucket(name=self.name, org_id=org.id, description=self.desc, retention_rules=[BucketRetentionRules(type=self.retention['type'], every_seconds=int(
self.retention['everySeconds']), shard_group_duration_seconds=int(self.retention['shardGroupDurationSeconds']))]))

return Bucket(name='', id='0')

def update(self, id) -> Bucket:
return self.client.update_bucket(bucket=Bucket(name=self.name, description=self.desc, id=id, retention_rules=[BucketRetentionRules(type=self.retention['type'], every_seconds=int(self.retention['everySeconds']), shard_group_duration_seconds=int(self.retention['shardGroupDurationSeconds']))]))

def delete(self, id):
return self.client.delete_bucket(bucket=id)

def get_all(self) -> Buckets:
return self.client.find_buckets()

def get_by_id(self, id) -> Bucket:
return self.client.find_bucket_by_id(id=id)
Loading

0 comments on commit 6481194

Please sign in to comment.