Compare commits
15 commits
Author | SHA1 | Date | |
---|---|---|---|
7df2a42795 | |||
fb6e522c98 | |||
af0ceb440d | |||
d183af929b | |||
46e58a0aff | |||
c6f6fd0b17 | |||
ff4b88063e | |||
b19cfba1fa | |||
0bacd505f0 | |||
9b5275aa2b | |||
bfb5bd0233 | |||
58d940562a | |||
16f58ca642 | |||
85c60f40eb | |||
e3c806f89b |
29 changed files with 1043 additions and 521 deletions
18
.forgejo/workflows/molecule.yml
Normal file
18
.forgejo/workflows/molecule.yml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
---
|
||||||
|
on: [push]
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: code.waks.be/nishiki/molecule:docker
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- run: ansible-lint .
|
||||||
|
- run: yamllint .
|
||||||
|
molecule:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: code.waks.be/nishiki/molecule:docker
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- run: molecule test
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
.kitchen/*
|
.kitchen/*
|
||||||
|
*.pyc
|
||||||
|
|
10
.gitlab-ci.yml
Normal file
10
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
image: nishiki/molecule:docker
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- molecule --version
|
||||||
|
|
||||||
|
molecule:
|
||||||
|
stage: test
|
||||||
|
script:
|
||||||
|
- molecule test
|
27
.kitchen.yml
27
.kitchen.yml
|
@ -1,27 +0,0 @@
|
||||||
---
|
|
||||||
driver:
|
|
||||||
name: docker_cli
|
|
||||||
|
|
||||||
transport:
|
|
||||||
name: docker_cli
|
|
||||||
|
|
||||||
provisioner:
|
|
||||||
name: ansible_playbook
|
|
||||||
hosts: localhost
|
|
||||||
require_ansible_repo: false
|
|
||||||
require_ansible_omnibus: false
|
|
||||||
require_chef_for_busser: true
|
|
||||||
ansible_verbose: false
|
|
||||||
ansible_inventory: ./test/integration/inventory
|
|
||||||
|
|
||||||
platforms:
|
|
||||||
- name: debian-9
|
|
||||||
driver_config:
|
|
||||||
image: "nishiki/debian9:ansible-<%= ENV['ANSIBLE_VERSION'] ? ENV['ANSIBLE_VERSION'] : '2.7' %>"
|
|
||||||
command: /bin/systemd
|
|
||||||
volume:
|
|
||||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
|
||||||
security_opt: seccomp=unconfined
|
|
||||||
|
|
||||||
suites:
|
|
||||||
- name: default
|
|
|
@ -2,11 +2,11 @@
|
||||||
extends: default
|
extends: default
|
||||||
|
|
||||||
ignore: |
|
ignore: |
|
||||||
.kitchen/*
|
.kitchen*
|
||||||
vendor/
|
vendor/
|
||||||
|
.forgejo/
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
line-length:
|
line-length:
|
||||||
max: 120
|
max: 120
|
||||||
level: warning
|
level: warning
|
||||||
truthy: false
|
|
||||||
|
|
34
CHANGELOG.md
34
CHANGELOG.md
|
@ -5,6 +5,40 @@ Which is based on [Keep A Changelog](http://keepachangelog.com/)
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Break
|
||||||
|
|
||||||
|
- upgrade to influxdb 2
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- test: use personal docker registry
|
||||||
|
|
||||||
|
## [2.0.0] 2021-08-18
|
||||||
|
|
||||||
|
### Break
|
||||||
|
|
||||||
|
- change user's privileges
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- add retention policies
|
||||||
|
- add support for debian 11
|
||||||
|
- add support for debian 10 and python3
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- test: replace kitchen to molecule
|
||||||
|
- chore: use FQCN for module name
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- fix no_log
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- remove support for debian 9
|
||||||
|
- the influxdb_api_password variable isn't set by default
|
||||||
|
|
||||||
## [1.0.0] 2019-04-12
|
## [1.0.0] 2019-04-12
|
||||||
|
|
||||||
- first version
|
- first version
|
||||||
|
|
8
Gemfile
8
Gemfile
|
@ -1,8 +0,0 @@
|
||||||
source 'https://rubygems.org'
|
|
||||||
|
|
||||||
group :development do
|
|
||||||
gem 'kitchen-ansible'
|
|
||||||
gem 'kitchen-docker_cli'
|
|
||||||
gem 'rubocop', '0.50.0'
|
|
||||||
gem 'test-kitchen'
|
|
||||||
end
|
|
93
Gemfile.lock
93
Gemfile.lock
|
@ -1,93 +0,0 @@
|
||||||
GEM
|
|
||||||
remote: https://rubygems.org/
|
|
||||||
specs:
|
|
||||||
ast (2.4.0)
|
|
||||||
builder (3.2.3)
|
|
||||||
erubis (2.7.0)
|
|
||||||
ffi (1.10.0)
|
|
||||||
gssapi (1.2.0)
|
|
||||||
ffi (>= 1.0.1)
|
|
||||||
gyoku (1.3.1)
|
|
||||||
builder (>= 2.1.2)
|
|
||||||
httpclient (2.8.3)
|
|
||||||
kitchen-ansible (0.47.4)
|
|
||||||
mixlib-shellout (>= 2.3.2)
|
|
||||||
net-ssh (>= 3)
|
|
||||||
test-kitchen (>= 1.17.0)
|
|
||||||
kitchen-docker_cli (0.19.0)
|
|
||||||
test-kitchen (>= 1.3)
|
|
||||||
little-plugger (1.1.4)
|
|
||||||
logging (2.2.2)
|
|
||||||
little-plugger (~> 1.1)
|
|
||||||
multi_json (~> 1.10)
|
|
||||||
mixlib-install (3.11.11)
|
|
||||||
mixlib-shellout
|
|
||||||
mixlib-versioning
|
|
||||||
thor
|
|
||||||
mixlib-shellout (2.4.4)
|
|
||||||
mixlib-versioning (1.2.7)
|
|
||||||
multi_json (1.13.1)
|
|
||||||
net-scp (2.0.0)
|
|
||||||
net-ssh (>= 2.6.5, < 6.0.0)
|
|
||||||
net-ssh (5.2.0)
|
|
||||||
net-ssh-gateway (2.0.0)
|
|
||||||
net-ssh (>= 4.0.0)
|
|
||||||
nori (2.6.0)
|
|
||||||
parallel (1.17.0)
|
|
||||||
parser (2.6.2.1)
|
|
||||||
ast (~> 2.4.0)
|
|
||||||
powerpack (0.1.2)
|
|
||||||
rainbow (2.2.2)
|
|
||||||
rake
|
|
||||||
rake (12.3.2)
|
|
||||||
rubocop (0.50.0)
|
|
||||||
parallel (~> 1.10)
|
|
||||||
parser (>= 2.3.3.1, < 3.0)
|
|
||||||
powerpack (~> 0.1)
|
|
||||||
rainbow (>= 2.2.2, < 3.0)
|
|
||||||
ruby-progressbar (~> 1.7)
|
|
||||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
|
||||||
ruby-progressbar (1.10.0)
|
|
||||||
rubyntlm (0.6.2)
|
|
||||||
rubyzip (1.2.2)
|
|
||||||
test-kitchen (2.0.1)
|
|
||||||
mixlib-install (~> 3.6)
|
|
||||||
mixlib-shellout (>= 1.2, < 3.0)
|
|
||||||
net-scp (>= 1.1, < 3.0)
|
|
||||||
net-ssh (>= 2.9, < 6.0)
|
|
||||||
net-ssh-gateway (>= 1.2, < 3.0)
|
|
||||||
thor (~> 0.19)
|
|
||||||
winrm (~> 2.0)
|
|
||||||
winrm-elevated (~> 1.0)
|
|
||||||
winrm-fs (~> 1.1)
|
|
||||||
thor (0.20.3)
|
|
||||||
unicode-display_width (1.5.0)
|
|
||||||
winrm (2.3.1)
|
|
||||||
builder (>= 2.1.2)
|
|
||||||
erubis (~> 2.7)
|
|
||||||
gssapi (~> 1.2)
|
|
||||||
gyoku (~> 1.0)
|
|
||||||
httpclient (~> 2.2, >= 2.2.0.2)
|
|
||||||
logging (>= 1.6.1, < 3.0)
|
|
||||||
nori (~> 2.0)
|
|
||||||
rubyntlm (~> 0.6.0, >= 0.6.1)
|
|
||||||
winrm-elevated (1.1.1)
|
|
||||||
winrm (~> 2.0)
|
|
||||||
winrm-fs (~> 1.0)
|
|
||||||
winrm-fs (1.3.2)
|
|
||||||
erubis (~> 2.7)
|
|
||||||
logging (>= 1.6.1, < 3.0)
|
|
||||||
rubyzip (~> 1.1)
|
|
||||||
winrm (~> 2.0)
|
|
||||||
|
|
||||||
PLATFORMS
|
|
||||||
ruby
|
|
||||||
|
|
||||||
DEPENDENCIES
|
|
||||||
kitchen-ansible
|
|
||||||
kitchen-docker_cli
|
|
||||||
rubocop (= 0.50.0)
|
|
||||||
test-kitchen
|
|
||||||
|
|
||||||
BUNDLED WITH
|
|
||||||
1.16.0
|
|
104
README.md
104
README.md
|
@ -1,48 +1,67 @@
|
||||||
# Ansible role: Influxdb
|
# Ansible role: Influxdb
|
||||||
|
|
||||||
[![Version](https://img.shields.io/badge/latest_version-1.0.0-green.svg)](https://git.yaegashi.fr/nishiki/ansible-role-influxdb/releases)
|
[![Version](https://img.shields.io/badge/latest_version-2.0.0-green.svg)](https://code.waks.be/nishiki/ansible-role-influxdb/releases)
|
||||||
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://git.yaegashi.fr/nishiki/ansible-role-influxdb/src/branch/master/LICENSE)
|
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://code.waks.be/nishiki/ansible-role-influxdb/src/branch/main/LICENSE)
|
||||||
|
[![Build](https://code.waks.be/nishiki/ansible-role-influxdb/actions/workflows/molecule.yml/badge.svg?branch=main)](https://code.waks.be/nishiki/ansible-role-influxdb/actions?workflow=molecule.yml)
|
||||||
|
|
||||||
Install and configure InfluxDB
|
Install and configure InfluxDB 2
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
* Ansible >= 2.7
|
- Ansible >= 2.10
|
||||||
* Debian Stretch
|
- Debian
|
||||||
|
- Bookworm
|
||||||
|
|
||||||
## Role variables
|
## Role variables
|
||||||
|
|
||||||
* `influxdb_databases` - array with the databases name
|
- `influxdb_init_username` - user created during the influxdb setup
|
||||||
* `influxdb_users` - array with the users informations
|
- `influxdb_init_org` - organization created during the influxdb setup
|
||||||
|
- `influxdb_init_bucket` - bucket created during the influxdb setup
|
||||||
|
- `influxdb_api_token` - token to manage influxdb
|
||||||
|
- `influxdb_orgs` - hash with organizations
|
||||||
|
|
||||||
```
|
```yaml
|
||||||
- name: test
|
myorg:
|
||||||
password: secret
|
description: it's a test
|
||||||
admin: true
|
state: present
|
||||||
state: present
|
```
|
||||||
```
|
|
||||||
|
|
||||||
* `influxdb_privileges` - array with the privileges
|
- `influxdb_buckets` - hash with the buckets
|
||||||
|
|
||||||
```
|
```yaml
|
||||||
- user: test
|
mybucket:
|
||||||
database: metric
|
description: KFC
|
||||||
privilege: WRITE
|
retention: 3600
|
||||||
state: present
|
org: neworg
|
||||||
```
|
state: present
|
||||||
|
```
|
||||||
|
|
||||||
* `influxdb_api_user` - set the api user if you have enabled http authentification
|
- `influxdb_users` - hash with the users
|
||||||
* `influxdb_api_password` - set the api password if you have enabled http authentification
|
|
||||||
* `influxdb_api_port` - set the api port (default: `8086`)
|
|
||||||
* `influxdb_config` - hash with the influxdb configuration (see [influxdb documentation](https://docs.influxdata.com/influxdb/v1.7/administration/config/))
|
|
||||||
|
|
||||||
```
|
```yaml
|
||||||
meta:
|
myuser:
|
||||||
dir: /var/lib/influxdb/meta
|
status: active
|
||||||
data:
|
state: present
|
||||||
dir: /var/lib/influxdb/data
|
```
|
||||||
wal-dir: /var/lib/influxdb/wal
|
|
||||||
```
|
- `influxdb_authorizations` - array with the authorizations
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- user: myuser
|
||||||
|
description: write bucket
|
||||||
|
org: neworg
|
||||||
|
status: active
|
||||||
|
state: present
|
||||||
|
permissions:
|
||||||
|
- action: write
|
||||||
|
resource:
|
||||||
|
type: buckets
|
||||||
|
org: myorg
|
||||||
|
name: mybucket
|
||||||
|
- action: read
|
||||||
|
resource:
|
||||||
|
type: buckets
|
||||||
|
```
|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
|
|
||||||
|
@ -54,25 +73,12 @@ Install and configure InfluxDB
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
### Test syntax with yamllint
|
### Test with molecule and docker
|
||||||
|
|
||||||
* install `python` and `python-pip`
|
- install [docker](https://docs.docker.com/engine/installation/)
|
||||||
* install yamllint `pip install yamllint`
|
- install `python3` and `python3-pip`
|
||||||
* run `yamllint .`
|
- install molecule and dependencies `pip3 install molecule molecule-plugins[docker] ansible-lint pytest-testinfra yamllint`
|
||||||
|
- run `molecule test`
|
||||||
### Test syntax with ansible-lint
|
|
||||||
|
|
||||||
* install `python` and `python-pip`
|
|
||||||
* install yamllint `pip install ansible-lint`
|
|
||||||
* run `ansible-lint .`
|
|
||||||
|
|
||||||
### Tests with docker
|
|
||||||
|
|
||||||
* install [docker](https://docs.docker.com/engine/installation/)
|
|
||||||
* install ruby
|
|
||||||
* install bundler `gem install bundler`
|
|
||||||
* install dependencies `bundle install`
|
|
||||||
* run the tests `kitchen test`
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,5 @@
|
||||||
---
|
---
|
||||||
influxdb_databases: []
|
influxdb_orgs: {}
|
||||||
influxdb_users: []
|
influxdb_buckets: {}
|
||||||
influxdb_privileges: []
|
influxdb_users: {}
|
||||||
influxdb_api_user: user
|
influxdb_authorizations: []
|
||||||
influxdb_api_password: password
|
|
||||||
influxdb_api_port: 8086
|
|
||||||
influxdb_default_config:
|
|
||||||
meta:
|
|
||||||
dir: /var/lib/influxdb/meta
|
|
||||||
data:
|
|
||||||
dir: /var/lib/influxdb/data
|
|
||||||
wal-dir: /var/lib/influxdb/wal
|
|
||||||
influxdb_config: {}
|
|
||||||
influxdb_full_config: '{{ influxdb_default_config|combine(influxdb_config) }}'
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
---
|
|
||||||
- name: restart influxdb
|
|
||||||
systemd:
|
|
||||||
name: influxdb
|
|
||||||
state: restarted
|
|
235
library/influxdb_auth.py
Normal file
235
library/influxdb_auth.py
Normal file
|
@ -0,0 +1,235 @@
|
||||||
|
#!/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()
|
163
library/influxdb_bucket.py
Normal file
163
library/influxdb_bucket.py
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
class InfluxdbBucket:
|
||||||
|
def __init__(self, api_url, api_token, name, org):
|
||||||
|
self.api_url = api_url
|
||||||
|
self.headers = {'Authorization': 'Token {}'.format(api_token)}
|
||||||
|
self.name = name
|
||||||
|
self.org = org
|
||||||
|
|
||||||
|
def exists(self):
|
||||||
|
url = '{}/api/v2/buckets'.format(self.api_url)
|
||||||
|
r = requests.get(
|
||||||
|
url,
|
||||||
|
headers=self.headers,
|
||||||
|
params={'name': self.name, 'org': self.org}
|
||||||
|
)
|
||||||
|
|
||||||
|
if r.status_code == 404:
|
||||||
|
return False
|
||||||
|
elif r.status_code == 200:
|
||||||
|
data = json.loads(r.text)
|
||||||
|
for bucket in data['buckets']:
|
||||||
|
if bucket['name'] == self.name:
|
||||||
|
self.id = bucket['id']
|
||||||
|
self.retention = bucket['retentionRules'][0]['everySeconds']
|
||||||
|
self.description = ''
|
||||||
|
if 'description' in bucket:
|
||||||
|
self.description = bucket['description']
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
raise Exception(
|
||||||
|
'Influxdb',
|
||||||
|
'Bad status code {}: {}'.format(r.status_code, r.text)
|
||||||
|
)
|
||||||
|
|
||||||
|
def has_changed(self, description, retention):
|
||||||
|
if self.description != description:
|
||||||
|
return True
|
||||||
|
if self.retention != retention:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_orgid(self):
|
||||||
|
url = '{}/api/v2/orgs'.format(self.api_url)
|
||||||
|
r = requests.get(url, headers=self.headers, params={'org': self.org})
|
||||||
|
|
||||||
|
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'] == self.org:
|
||||||
|
return org['id']
|
||||||
|
|
||||||
|
raise Exception('Influxdb', 'Don\'t get the orgID')
|
||||||
|
|
||||||
|
def create(self, description, retention):
|
||||||
|
url = '{}/api/v2/buckets'.format(self.api_url)
|
||||||
|
r = requests.post(
|
||||||
|
url,
|
||||||
|
headers=self.headers,
|
||||||
|
json={
|
||||||
|
'name': self.name,
|
||||||
|
'description': description,
|
||||||
|
'orgID': self.get_orgid(),
|
||||||
|
'retentionRules': [{
|
||||||
|
'everySeconds': retention,
|
||||||
|
'shardGroupDurationSeconds': 0,
|
||||||
|
'type': 'expire'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if r.status_code != 201:
|
||||||
|
raise Exception(
|
||||||
|
'Influxdb',
|
||||||
|
'Bad status code {}: {}'.format(r.status_code, r.text)
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
url = '{}/api/v2/buckets/{}'.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, description, retention):
|
||||||
|
url = '{}/api/v2/buckets/{}'.format(self.api_url, self.id)
|
||||||
|
r = requests.patch(
|
||||||
|
url,
|
||||||
|
headers=self.headers,
|
||||||
|
json={
|
||||||
|
'name': self.name,
|
||||||
|
'description': description,
|
||||||
|
'retentionRules': [{
|
||||||
|
'everySeconds': retention,
|
||||||
|
'shardGroupDurationSeconds': 0,
|
||||||
|
'type': 'expire'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if r.status_code != 200:
|
||||||
|
raise Exception(
|
||||||
|
'Influxdb',
|
||||||
|
'Bad status code {}: {}'.format(r.status_code, r.text)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
fields = {
|
||||||
|
'name': {'type': 'str', 'required': True},
|
||||||
|
'org': {'type': 'str', 'required': True},
|
||||||
|
'description': {'type': 'str', 'default': ''},
|
||||||
|
'retention': {'type': 'int', 'default': 0},
|
||||||
|
'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)
|
||||||
|
|
||||||
|
bucket = InfluxdbBucket(
|
||||||
|
module.params['api_url'],
|
||||||
|
module.params['api_token'],
|
||||||
|
module.params['name'],
|
||||||
|
module.params['org'],
|
||||||
|
)
|
||||||
|
changed = False
|
||||||
|
|
||||||
|
if bucket.exists():
|
||||||
|
if module.params['state'] == 'absent':
|
||||||
|
bucket.delete()
|
||||||
|
changed = True
|
||||||
|
elif bucket.has_changed(module.params['description'],
|
||||||
|
module.params['retention']):
|
||||||
|
bucket.update(
|
||||||
|
module.params['description'],
|
||||||
|
module.params['retention']
|
||||||
|
)
|
||||||
|
changed = True
|
||||||
|
elif module.params['state'] == 'present':
|
||||||
|
bucket.create(module.params['description'], module.params['retention'])
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
module.exit_json(changed=changed)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
112
library/influxdb_org.py
Normal file
112
library/influxdb_org.py
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
class InfluxdbOrg:
|
||||||
|
def __init__(self, api_url, api_token, name):
|
||||||
|
self.api_url = api_url
|
||||||
|
self.headers = {'Authorization': 'Token {}'.format(api_token)}
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def exists(self):
|
||||||
|
url = '{}/api/v2/orgs'.format(self.api_url)
|
||||||
|
r = requests.get(url, headers=self.headers, params={'org': self.name})
|
||||||
|
|
||||||
|
if r.status_code == 404:
|
||||||
|
return False
|
||||||
|
elif r.status_code == 200:
|
||||||
|
data = json.loads(r.text)
|
||||||
|
for org in data['orgs']:
|
||||||
|
if org['name'] == self.name:
|
||||||
|
self.id = org['id']
|
||||||
|
self.description = org['description']
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
raise Exception(
|
||||||
|
'Influxdb',
|
||||||
|
'Bad status code {}: {}'.format(r.status_code, r.text)
|
||||||
|
)
|
||||||
|
|
||||||
|
def has_changed(self, description):
|
||||||
|
if self.description == description:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def create(self, description):
|
||||||
|
url = '{}/api/v2/orgs'.format(self.api_url)
|
||||||
|
r = requests.post(
|
||||||
|
url,
|
||||||
|
headers=self.headers,
|
||||||
|
json={'name': self.name, 'description': description}
|
||||||
|
)
|
||||||
|
|
||||||
|
if r.status_code != 201:
|
||||||
|
raise Exception(
|
||||||
|
'Influxdb',
|
||||||
|
'Bad status code {}: {}'.format(r.status_code, r.text)
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
url = '{}/api/v2/orgs/{}'.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, description):
|
||||||
|
url = '{}/api/v2/orgs/{}'.format(self.api_url, self.id)
|
||||||
|
r = requests.patch(
|
||||||
|
url,
|
||||||
|
headers=self.headers,
|
||||||
|
json={'name': self.name, 'description': description}
|
||||||
|
)
|
||||||
|
|
||||||
|
if r.status_code != 200:
|
||||||
|
raise Exception(
|
||||||
|
'Influxdb',
|
||||||
|
'Bad status code {}: {}'.format(r.status_code, r.text)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
fields = {
|
||||||
|
'name': {'type': 'str', 'required': True},
|
||||||
|
'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)
|
||||||
|
|
||||||
|
org = InfluxdbOrg(
|
||||||
|
module.params['api_url'],
|
||||||
|
module.params['api_token'],
|
||||||
|
module.params['name'],
|
||||||
|
)
|
||||||
|
changed = False
|
||||||
|
|
||||||
|
if org.exists():
|
||||||
|
if module.params['state'] == 'absent':
|
||||||
|
org.delete()
|
||||||
|
changed = True
|
||||||
|
elif org.has_changed(module.params['description']):
|
||||||
|
org.update(module.params['description'])
|
||||||
|
changed = True
|
||||||
|
elif module.params['state'] == 'present':
|
||||||
|
org.create(module.params['description'])
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
module.exit_json(changed=changed)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -1,94 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import *
|
|
||||||
import requests
|
|
||||||
import json
|
|
||||||
|
|
||||||
class InfluxdbPrivilege:
|
|
||||||
def __init__(self, user, database, privilege, api_host, api_port, api_user, api_password):
|
|
||||||
self.user = user
|
|
||||||
self.database = database
|
|
||||||
self.privilege = privilege
|
|
||||||
self.api_host = api_host
|
|
||||||
self.api_port = api_port
|
|
||||||
self.api_user = api_user
|
|
||||||
self.api_password = api_password
|
|
||||||
self.change = False
|
|
||||||
self.get_info()
|
|
||||||
|
|
||||||
def request(self, query):
|
|
||||||
url = 'http://{}:{}/query?q={}'.format(self.api_host, self.api_port, requests.utils.quote(query))
|
|
||||||
|
|
||||||
if self.api_user is not None:
|
|
||||||
r = requests.get(url, auth=(self.api_user, self.api_password))
|
|
||||||
else:
|
|
||||||
r = requests.get(url)
|
|
||||||
|
|
||||||
if r.status_code != 200:
|
|
||||||
raise Exception('Influxdb', 'Bad status code {}: {}'.format(r.status_code, r.text))
|
|
||||||
|
|
||||||
return json.loads(r.text)
|
|
||||||
|
|
||||||
def get_info(self):
|
|
||||||
privileges = self.request(
|
|
||||||
'SHOW GRANTS FOR {}'.format(self.user),
|
|
||||||
)['results'][0]['series'][0]
|
|
||||||
|
|
||||||
if 'values' in privileges:
|
|
||||||
for privilege in privileges['values']:
|
|
||||||
if self.database == privilege[0]:
|
|
||||||
self.exist = True
|
|
||||||
if self.privilege != privilege[1]:
|
|
||||||
self.change = True
|
|
||||||
return
|
|
||||||
|
|
||||||
self.exist = False
|
|
||||||
|
|
||||||
def grant(self):
|
|
||||||
self.request(
|
|
||||||
'GRANT {} ON {} TO {}'.format(self.privilege, self.database, self.user)
|
|
||||||
)
|
|
||||||
|
|
||||||
def revoke(self):
|
|
||||||
self.request(
|
|
||||||
'REVOKE {} ON {} FROM {}'.format(self.privilege, self.database, self.user)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
fields = {
|
|
||||||
'user': { 'type': 'str', 'required': True },
|
|
||||||
'database': { 'type': 'str', 'required': True },
|
|
||||||
'privilege': { 'type': 'str', 'required': True, 'choices': ['ALL', 'WRITE', 'READ'] },
|
|
||||||
'api_user': { 'type': 'str' },
|
|
||||||
'api_password': { 'type': 'str' },
|
|
||||||
'api_host': { 'type': 'str', 'default': '127.0.0.1' },
|
|
||||||
'api_port': { 'type': 'int', 'default': 8086 },
|
|
||||||
'state': { 'type': 'str', 'default': 'present', 'choices': ['present', 'absent'] }
|
|
||||||
}
|
|
||||||
module = AnsibleModule(argument_spec=fields)
|
|
||||||
changed = False
|
|
||||||
|
|
||||||
influxdb_privilege = InfluxdbPrivilege(
|
|
||||||
module.params['user'],
|
|
||||||
module.params['database'],
|
|
||||||
module.params['privilege'],
|
|
||||||
module.params['api_host'],
|
|
||||||
module.params['api_port'],
|
|
||||||
module.params['api_user'],
|
|
||||||
module.params['api_password']
|
|
||||||
)
|
|
||||||
|
|
||||||
if module.params['state'] == 'present':
|
|
||||||
if not influxdb_privilege.exist or influxdb_privilege.change:
|
|
||||||
influxdb_privilege.grant()
|
|
||||||
changed = True
|
|
||||||
else:
|
|
||||||
if influxdb_privilege.exist:
|
|
||||||
influxdb_privilege.revoke()
|
|
||||||
changed = True
|
|
||||||
|
|
||||||
module.exit_json(changed=changed)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
69
library/influxdb_setup.py
Normal file
69
library/influxdb_setup.py
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
class InfluxdbSetup:
|
||||||
|
def __init__(self, api_url):
|
||||||
|
self.api_url = api_url
|
||||||
|
|
||||||
|
def already(self):
|
||||||
|
url = '{}/api/v2/setup'.format(self.api_url)
|
||||||
|
r = requests.get(url)
|
||||||
|
|
||||||
|
if r.status_code != 200:
|
||||||
|
raise Exception(
|
||||||
|
'Influxdb',
|
||||||
|
'Bad status code {}: {}'.format(r.status_code, r.text)
|
||||||
|
)
|
||||||
|
|
||||||
|
data = json.loads(r.text)
|
||||||
|
if 'allowed' not in data or data['allowed'] is True:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def run(self, username, org, bucket, token):
|
||||||
|
url = '{}/api/v2/setup'.format(self.api_url)
|
||||||
|
r = requests.post(url, json={
|
||||||
|
'username': username,
|
||||||
|
'org': org,
|
||||||
|
'bucket': bucket,
|
||||||
|
'token': token,
|
||||||
|
})
|
||||||
|
|
||||||
|
if r.status_code != 201:
|
||||||
|
raise Exception(
|
||||||
|
'Influxdb',
|
||||||
|
'Bad status code {}: {}'.format(r.status_code, r.text)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
fields = {
|
||||||
|
'username': {'type': 'str', 'required': True},
|
||||||
|
'org': {'type': 'str', 'required': True},
|
||||||
|
'bucket': {'type': 'str', 'required': True},
|
||||||
|
'token': {'type': 'str', 'required': True},
|
||||||
|
'api_url': {'type': 'str', 'default': 'http://127.0.0.1:8086'},
|
||||||
|
}
|
||||||
|
module = AnsibleModule(argument_spec=fields)
|
||||||
|
|
||||||
|
setup = InfluxdbSetup(
|
||||||
|
module.params['api_url'],
|
||||||
|
)
|
||||||
|
|
||||||
|
if setup.already() is True:
|
||||||
|
module.exit_json(changed=False)
|
||||||
|
setup.run(
|
||||||
|
module.params['username'],
|
||||||
|
module.params['org'],
|
||||||
|
module.params['bucket'],
|
||||||
|
module.params['token'],
|
||||||
|
)
|
||||||
|
module.exit_json(changed=True)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
124
library/influxdb_user.py
Normal file
124
library/influxdb_user.py
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
class InfluxdbUser:
|
||||||
|
def __init__(self, api_url, api_token, name):
|
||||||
|
self.api_url = api_url
|
||||||
|
self.headers = {'Authorization': 'Token {}'.format(api_token)}
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def exists(self):
|
||||||
|
url = '{}/api/v2/users'.format(self.api_url)
|
||||||
|
r = requests.get(
|
||||||
|
url,
|
||||||
|
headers=self.headers,
|
||||||
|
params={'name': self.name}
|
||||||
|
)
|
||||||
|
|
||||||
|
if r.status_code == 404:
|
||||||
|
return False
|
||||||
|
elif r.status_code == 200:
|
||||||
|
data = json.loads(r.text)
|
||||||
|
for user in data['users']:
|
||||||
|
if user['name'] == self.name:
|
||||||
|
self.id = user['id']
|
||||||
|
self.status = user['status']
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
raise Exception(
|
||||||
|
'Influxdb',
|
||||||
|
'Bad status code {}: {}'.format(r.status_code, r.text)
|
||||||
|
)
|
||||||
|
|
||||||
|
def has_changed(self, status):
|
||||||
|
if self.status != status:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def create(self, status):
|
||||||
|
url = '{}/api/v2/users'.format(self.api_url)
|
||||||
|
r = requests.post(
|
||||||
|
url,
|
||||||
|
headers=self.headers,
|
||||||
|
json={
|
||||||
|
'name': self.name,
|
||||||
|
'status': status
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if r.status_code != 201:
|
||||||
|
raise Exception(
|
||||||
|
'Influxdb',
|
||||||
|
'Bad status code {}: {}'.format(r.status_code, r.text)
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete(self):
|
||||||
|
url = '{}/api/v2/users/{}'.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):
|
||||||
|
url = '{}/api/v2/users/{}'.format(self.api_url, self.id)
|
||||||
|
r = requests.patch(
|
||||||
|
url,
|
||||||
|
headers=self.headers,
|
||||||
|
json={
|
||||||
|
'name': self.name,
|
||||||
|
'status': status
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if r.status_code != 200:
|
||||||
|
raise Exception(
|
||||||
|
'Influxdb',
|
||||||
|
'Bad status code {}: {}'.format(r.status_code, r.text)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
fields = {
|
||||||
|
'name': {'type': 'str', 'required': True},
|
||||||
|
'status': {'type': 'str',
|
||||||
|
'default': 'active',
|
||||||
|
'choice': ['active', 'inactive']},
|
||||||
|
'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)
|
||||||
|
|
||||||
|
user = InfluxdbUser(
|
||||||
|
module.params['api_url'],
|
||||||
|
module.params['api_token'],
|
||||||
|
module.params['name'],
|
||||||
|
)
|
||||||
|
changed = False
|
||||||
|
|
||||||
|
if user.exists():
|
||||||
|
if module.params['state'] == 'absent':
|
||||||
|
user.delete()
|
||||||
|
changed = True
|
||||||
|
elif user.has_changed(module.params['status']):
|
||||||
|
user.update(module.params['status'])
|
||||||
|
changed = True
|
||||||
|
elif module.params['state'] == 'present':
|
||||||
|
user.create(module.params['status'])
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
module.exit_json(changed=changed)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -1,16 +1,17 @@
|
||||||
---
|
---
|
||||||
galaxy_info:
|
galaxy_info:
|
||||||
role_name: Influxdb
|
role_name: influxdb
|
||||||
|
namespace: nishiki
|
||||||
author: Adrien Waksberg
|
author: Adrien Waksberg
|
||||||
company: Adrien Waksberg
|
company: Adrien Waksberg
|
||||||
description: Install and configure InfluxDB
|
description: Install and configure InfluxDB 2
|
||||||
license: Apache2
|
license: Apache2
|
||||||
min_ansible_version: 2.7
|
min_ansible_version: "2.10"
|
||||||
|
|
||||||
platforms:
|
platforms:
|
||||||
- name: Debian
|
- name: Debian
|
||||||
versions:
|
versions:
|
||||||
- stretch
|
- bookworm
|
||||||
|
|
||||||
galaxy_tags:
|
galaxy_tags:
|
||||||
- database
|
- database
|
||||||
|
|
40
molecule/default/converge.yml
Normal file
40
molecule/default/converge.yml
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
---
|
||||||
|
- name: Converge
|
||||||
|
hosts: all
|
||||||
|
roles:
|
||||||
|
- ansible-role-influxdb
|
||||||
|
vars:
|
||||||
|
influxdb_init_username: admin
|
||||||
|
influxdb_init_org: init_org
|
||||||
|
influxdb_init_bucket: test
|
||||||
|
influxdb_api_token: SuP3rS3cr3t
|
||||||
|
influxdb_orgs:
|
||||||
|
neworg:
|
||||||
|
description: it's a test
|
||||||
|
init_org:
|
||||||
|
state: absent
|
||||||
|
influxdb_buckets:
|
||||||
|
mybucket:
|
||||||
|
description: KFC
|
||||||
|
retention: 3600
|
||||||
|
org: neworg
|
||||||
|
influxdb_users:
|
||||||
|
telegraf:
|
||||||
|
user_inactive:
|
||||||
|
status: inactive
|
||||||
|
influxdb_authorizations:
|
||||||
|
- user: telegraf
|
||||||
|
description: write telegraf
|
||||||
|
org: neworg
|
||||||
|
status: active
|
||||||
|
permissions:
|
||||||
|
- action: write
|
||||||
|
resource:
|
||||||
|
type: buckets
|
||||||
|
org: neworg
|
||||||
|
name: mybucket
|
||||||
|
|
||||||
|
pre_tasks:
|
||||||
|
- name: Update apt cache
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
19
molecule/default/molecule.yml
Normal file
19
molecule/default/molecule.yml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
---
|
||||||
|
driver:
|
||||||
|
name: docker
|
||||||
|
platforms:
|
||||||
|
- name: debian12
|
||||||
|
image: code.waks.be/nishiki/molecule:debian12
|
||||||
|
privileged: true
|
||||||
|
volumes:
|
||||||
|
- /sys/fs/cgroup:/sys/fs/cgroup:rw
|
||||||
|
cgroupns_mode: host
|
||||||
|
command: /bin/systemd
|
||||||
|
capabilities:
|
||||||
|
- SYS_ADMIN
|
||||||
|
lint: |
|
||||||
|
set -e
|
||||||
|
yamllint .
|
||||||
|
ansible-lint .
|
||||||
|
verifier:
|
||||||
|
name: testinfra
|
48
molecule/default/tests/test_default.py
Normal file
48
molecule/default/tests/test_default.py
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import testinfra.utils.ansible_runner
|
||||||
|
|
||||||
|
CURL = ('curl --header "Authorization: Token SuP3rS3cr3t"'
|
||||||
|
' http://localhost:8086/api/v2')
|
||||||
|
|
||||||
|
|
||||||
|
def test_packages(host):
|
||||||
|
package = host.package('influxdb2')
|
||||||
|
assert package.is_installed
|
||||||
|
|
||||||
|
|
||||||
|
def test_service(host):
|
||||||
|
service = host.service('influxdb')
|
||||||
|
assert service.is_running
|
||||||
|
assert service.is_enabled
|
||||||
|
|
||||||
|
|
||||||
|
def test_sockets(host):
|
||||||
|
socket = host.socket('tcp://0.0.0.0:8086')
|
||||||
|
assert socket.is_listening
|
||||||
|
|
||||||
|
|
||||||
|
def test_users(host):
|
||||||
|
cmd = host.run('{}/users -X GET'.format(CURL))
|
||||||
|
assert cmd.succeeded
|
||||||
|
assert '"name": "admin"' in cmd.stdout
|
||||||
|
assert '"name": "telegraf"' in cmd.stdout
|
||||||
|
|
||||||
|
|
||||||
|
def test_org(host):
|
||||||
|
cmd = host.run('{}/orgs -X GET'.format(CURL))
|
||||||
|
assert cmd.succeeded
|
||||||
|
assert '"name": "neworg"' in cmd.stdout
|
||||||
|
assert '"name": "init_org"' not in cmd.stdout
|
||||||
|
|
||||||
|
|
||||||
|
def test_bucket(host):
|
||||||
|
cmd = host.run('{}/buckets -X GET'.format(CURL))
|
||||||
|
assert cmd.succeeded
|
||||||
|
assert '"name": "mybucket"' in cmd.stdout
|
||||||
|
assert '"everySeconds": 3600' in cmd.stdout
|
||||||
|
assert '"name": "test"' not in cmd.stdout
|
||||||
|
|
||||||
|
|
||||||
|
def test_auth(host):
|
||||||
|
cmd = host.run('{}/authorizations -X GET'.format(CURL))
|
||||||
|
assert cmd.succeeded
|
||||||
|
assert '"description": "write telegraf"' in cmd.stdout
|
|
@ -1,68 +0,0 @@
|
||||||
---
|
|
||||||
- name: copy config file
|
|
||||||
template:
|
|
||||||
src: influxdb.conf.j2
|
|
||||||
dest: /etc/influxdb/influxdb.conf
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: 0644
|
|
||||||
notify: restart influxdb
|
|
||||||
tags: influxdb
|
|
||||||
|
|
||||||
- name: start and enable service
|
|
||||||
systemd:
|
|
||||||
name: influxdb
|
|
||||||
state: started
|
|
||||||
enabled: yes
|
|
||||||
tags: influxdb
|
|
||||||
|
|
||||||
- name: wait http api is up
|
|
||||||
wait_for:
|
|
||||||
port: 8086
|
|
||||||
timeout: 10
|
|
||||||
tags: influxdb
|
|
||||||
|
|
||||||
- name: create users
|
|
||||||
influxdb_user:
|
|
||||||
user_name: '{{ item.name }}'
|
|
||||||
user_password: '{{ item.password }}'
|
|
||||||
admin: '{{ item.admin|default(false) }}'
|
|
||||||
username: '{{ influxdb_api_user }}'
|
|
||||||
password: '{{ influxdb_api_password }}'
|
|
||||||
loop: '{{ influxdb_users }}'
|
|
||||||
when: item.state is not defined or item.state != 'absent'
|
|
||||||
no_log: true
|
|
||||||
tags: influxdb
|
|
||||||
|
|
||||||
- name: delete users
|
|
||||||
influxdb_user:
|
|
||||||
user_name: '{{ item.name }}'
|
|
||||||
username: '{{ influxdb_api_user }}'
|
|
||||||
password: '{{ influxdb_api_password }}'
|
|
||||||
state: absent
|
|
||||||
loop: '{{ influxdb_users }}'
|
|
||||||
when: item.state is defined and item.state == 'absent'
|
|
||||||
no_log: true
|
|
||||||
tags: influxdb
|
|
||||||
|
|
||||||
- name: create databases
|
|
||||||
influxdb_database:
|
|
||||||
database_name: '{{ item }}'
|
|
||||||
username: '{{ influxdb_api_user }}'
|
|
||||||
password: '{{ influxdb_api_password }}'
|
|
||||||
loop: '{{ influxdb_databases }}'
|
|
||||||
no_log: true
|
|
||||||
tags: influxdb
|
|
||||||
|
|
||||||
- name: create privileges
|
|
||||||
influxdb_privilege:
|
|
||||||
user: '{{ item.user }}'
|
|
||||||
database: '{{ item.database }}'
|
|
||||||
privilege: '{{ item.privilege }}'
|
|
||||||
api_user: '{{ influxdb_api_user }}'
|
|
||||||
api_password: '{{ influxdb_api_password }}'
|
|
||||||
api_port: '{{ influxdb_api_port }}'
|
|
||||||
state: '{{ item.state|default("present") }}'
|
|
||||||
loop: '{{ influxdb_privileges }}'
|
|
||||||
no_log: true
|
|
||||||
tags: influxdb
|
|
|
@ -1,42 +0,0 @@
|
||||||
---
|
|
||||||
- name: install depencies packages
|
|
||||||
apt:
|
|
||||||
name: '{{ packages }}'
|
|
||||||
vars:
|
|
||||||
packages:
|
|
||||||
- apt-transport-https
|
|
||||||
- collectd-core
|
|
||||||
- python-pip
|
|
||||||
register: result
|
|
||||||
until: result is succeeded
|
|
||||||
retries: 2
|
|
||||||
tags: influxdb
|
|
||||||
|
|
||||||
- name: add key for influxdb repository
|
|
||||||
apt_key:
|
|
||||||
url: https://repos.influxdata.com/influxdb.key
|
|
||||||
register: result
|
|
||||||
until: result is succeeded
|
|
||||||
retries: 2
|
|
||||||
tags: influxdb
|
|
||||||
|
|
||||||
- name: add influxdb repository
|
|
||||||
apt_repository:
|
|
||||||
repo: 'deb https://repos.influxdata.com/debian {{ ansible_distribution_release }} stable'
|
|
||||||
tags: influxdb
|
|
||||||
|
|
||||||
- name: install influxdb package
|
|
||||||
apt:
|
|
||||||
name: influxdb
|
|
||||||
register: result
|
|
||||||
until: result is succeeded
|
|
||||||
retries: 2
|
|
||||||
tags: influxdb
|
|
||||||
|
|
||||||
- name: install python-influxdb
|
|
||||||
pip:
|
|
||||||
name: influxdb
|
|
||||||
register: result
|
|
||||||
until: result is succeeded
|
|
||||||
retries: 2
|
|
||||||
tags: influxdb
|
|
104
tasks/main.yml
104
tasks/main.yml
|
@ -1,3 +1,103 @@
|
||||||
---
|
---
|
||||||
- import_tasks: install.yml
|
- name: Install depencies packages
|
||||||
- import_tasks: config.yml
|
ansible.builtin.package:
|
||||||
|
name:
|
||||||
|
- apt-transport-https
|
||||||
|
- python3-requests
|
||||||
|
tags: influxdb
|
||||||
|
|
||||||
|
- name: Add key for influxdb repository
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: https://repos.influxdata.com/influxdata-archive_compat.key
|
||||||
|
dest: /etc/apt/keyrings/influx.asc
|
||||||
|
checksum: sha256:393e8779c89ac8d958f81f942f9ad7fb82a25e133faddaf92e15b16e6ac9ce4c
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0644"
|
||||||
|
tags: influxdb
|
||||||
|
|
||||||
|
- name: Add influxdb repository
|
||||||
|
ansible.builtin.apt_repository:
|
||||||
|
repo: "deb [signed-by=/etc/apt/keyrings/influx.asc] https://repos.influxdata.com/debian stable main"
|
||||||
|
tags: influxdb
|
||||||
|
|
||||||
|
- name: Install package
|
||||||
|
ansible.builtin.package:
|
||||||
|
name:
|
||||||
|
- influxdb2
|
||||||
|
tags: influxdb
|
||||||
|
|
||||||
|
- name: Start and enable service
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: influxdb
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
tags: influxdb
|
||||||
|
|
||||||
|
- name: Wait http api is up
|
||||||
|
ansible.builtin.wait_for:
|
||||||
|
port: 8086
|
||||||
|
timeout: 10
|
||||||
|
tags: influxdb
|
||||||
|
|
||||||
|
- name: Setup server
|
||||||
|
influxdb_setup:
|
||||||
|
api_url: http://127.0.0.1:8086
|
||||||
|
username: "{{ influxdb_init_username }}"
|
||||||
|
org: "{{ influxdb_init_org }}"
|
||||||
|
bucket: "{{ influxdb_init_bucket }}"
|
||||||
|
token: "{{ influxdb_api_token }}"
|
||||||
|
tags: influxdb
|
||||||
|
|
||||||
|
- name: Manage organisations
|
||||||
|
influxdb_org:
|
||||||
|
name: "{{ item.key }}"
|
||||||
|
description: "{{ item.value.description | default(omit) }}"
|
||||||
|
api_url: http://127.0.0.1:8086
|
||||||
|
api_token: "{{ influxdb_api_token }}"
|
||||||
|
state: "{{ item.value.state | default('present') }}"
|
||||||
|
loop: "{{ influxdb_orgs | dict2items }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.key }}"
|
||||||
|
tags: influxdb
|
||||||
|
|
||||||
|
- name: Manage buckets
|
||||||
|
influxdb_bucket:
|
||||||
|
name: "{{ item.key }}"
|
||||||
|
org: "{{ item.value.org }}"
|
||||||
|
description: "{{ item.value.description | default(omit) }}"
|
||||||
|
retention: "{{ item.value.retention | default(omit) }}"
|
||||||
|
api_url: http://127.0.0.1:8086
|
||||||
|
api_token: "{{ influxdb_api_token }}"
|
||||||
|
state: "{{ item.value.state | default('present') }}"
|
||||||
|
loop: "{{ influxdb_buckets | dict2items }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.key }}"
|
||||||
|
tags: influxdb
|
||||||
|
|
||||||
|
- name: Manage users
|
||||||
|
influxdb_user:
|
||||||
|
name: "{{ item.key }}"
|
||||||
|
status: "{{ item.value.status | default('active') }}"
|
||||||
|
api_url: http://127.0.0.1:8086
|
||||||
|
api_token: "{{ influxdb_api_token }}"
|
||||||
|
state: "{{ item.value.state | default('present') }}"
|
||||||
|
loop: "{{ influxdb_users | dict2items }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.key }}"
|
||||||
|
tags: influxdb
|
||||||
|
|
||||||
|
- name: Manage authorizations
|
||||||
|
influxdb_auth:
|
||||||
|
org: "{{ item.org }}"
|
||||||
|
user: "{{ item.user }}"
|
||||||
|
description: "{{ item.description | default(omit) }}"
|
||||||
|
permissions: "{{ item.permissions }}"
|
||||||
|
status: "{{ item.status | default('active') }}"
|
||||||
|
api_url: http://127.0.0.1:8086
|
||||||
|
api_token: "{{ influxdb_api_token }}"
|
||||||
|
state: "{{ item.state | default('present') }}"
|
||||||
|
loop: "{{ influxdb_authorizations }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.org }}/{{ item.user }}"
|
||||||
|
tags: influxdb
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# {{ ansible_managed }}
|
# {{ ansible_managed }}
|
||||||
{% for section, options in influxdb_full_config.iteritems() %}
|
{% for section, options in influxdb_full_config.items() %}
|
||||||
|
|
||||||
[{{ section }}]
|
[{{ section }}]
|
||||||
{% for option, value in options.iteritems() %}
|
{% for option, value in options.items() %}
|
||||||
{{ option }} = {% if value is sameas true %}true
|
{{ option }} = {% if value is sameas true %}true
|
||||||
{% elif value is sameas false %}false
|
{% elif value is sameas false %}false
|
||||||
{% elif value is string %}"{{ value }}"
|
{% elif value is string %}"{{ value }}"
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
E, [2019-01-17T09:43:25.055727 #24689] ERROR -- Kitchen: ------Exception-------
|
|
||||||
E, [2019-01-17T09:43:25.055802 #24689] ERROR -- Kitchen: Class: Kitchen::UserError
|
|
||||||
E, [2019-01-17T09:43:25.055823 #24689] ERROR -- Kitchen: Message: Kitchen YAML file /home/awaksberg/git/ansible-role-influxdb/test/integration/default/.kitchen.yml does not exist.
|
|
||||||
E, [2019-01-17T09:43:25.055835 #24689] ERROR -- Kitchen: ----------------------
|
|
||||||
E, [2019-01-17T09:43:25.055845 #24689] ERROR -- Kitchen: ------Backtrace-------
|
|
||||||
E, [2019-01-17T09:43:25.055854 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/loader/yaml.rb:65:in `read'
|
|
||||||
E, [2019-01-17T09:43:25.055863 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/config.rb:152:in `data'
|
|
||||||
E, [2019-01-17T09:43:25.055872 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/config.rb:131:in `suites'
|
|
||||||
E, [2019-01-17T09:43:25.055881 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/config.rb:182:in `filter_instances'
|
|
||||||
E, [2019-01-17T09:43:25.055891 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/config.rb:141:in `build_instances'
|
|
||||||
E, [2019-01-17T09:43:25.055900 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/config.rb:117:in `instances'
|
|
||||||
E, [2019-01-17T09:43:25.055909 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/command.rb:112:in `filtered_instances'
|
|
||||||
E, [2019-01-17T09:43:25.055918 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/command.rb:142:in `parse_subcommand'
|
|
||||||
E, [2019-01-17T09:43:25.055927 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/command/list.rb:30:in `call'
|
|
||||||
E, [2019-01-17T09:43:25.055936 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/cli.rb:52:in `perform'
|
|
||||||
E, [2019-01-17T09:43:25.055947 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/cli.rb:120:in `list'
|
|
||||||
E, [2019-01-17T09:43:25.055957 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/thor-0.20.3/lib/thor/command.rb:27:in `run'
|
|
||||||
E, [2019-01-17T09:43:25.055966 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'
|
|
||||||
E, [2019-01-17T09:43:25.055975 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/thor-0.20.3/lib/thor.rb:387:in `dispatch'
|
|
||||||
E, [2019-01-17T09:43:25.055984 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/thor-0.20.3/lib/thor/base.rb:466:in `start'
|
|
||||||
E, [2019-01-17T09:43:25.055993 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/bin/kitchen:13:in `block in <top (required)>'
|
|
||||||
E, [2019-01-17T09:43:25.056002 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/lib/kitchen/errors.rb:171:in `with_friendly_errors'
|
|
||||||
E, [2019-01-17T09:43:25.056011 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/gems/test-kitchen-1.23.5/bin/kitchen:13:in `<top (required)>'
|
|
||||||
E, [2019-01-17T09:43:25.056020 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/bin/kitchen:23:in `load'
|
|
||||||
E, [2019-01-17T09:43:25.056029 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/bin/kitchen:23:in `<main>'
|
|
||||||
E, [2019-01-17T09:43:25.056039 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/bin/ruby_executable_hooks:24:in `eval'
|
|
||||||
E, [2019-01-17T09:43:25.056048 #24689] ERROR -- Kitchen: /home/awaksberg/.rvm/gems/ruby-2.5.1/bin/ruby_executable_hooks:24:in `<main>'
|
|
||||||
E, [2019-01-17T09:43:25.056057 #24689] ERROR -- Kitchen: ----End Backtrace-----
|
|
|
@ -1,32 +0,0 @@
|
||||||
---
|
|
||||||
- hosts: localhost
|
|
||||||
connection: local
|
|
||||||
vars:
|
|
||||||
influxdb_users:
|
|
||||||
- name: paul
|
|
||||||
password: test
|
|
||||||
admin: yes
|
|
||||||
- name: adrien
|
|
||||||
password: test2
|
|
||||||
- name: antoine
|
|
||||||
state: absent
|
|
||||||
influxdb_databases:
|
|
||||||
- new_database
|
|
||||||
influxdb_privileges:
|
|
||||||
- user: adrien
|
|
||||||
database: new_database
|
|
||||||
privilege: WRITE
|
|
||||||
influxdb_config:
|
|
||||||
'[collectd]':
|
|
||||||
enabled: true
|
|
||||||
port: 25826
|
|
||||||
database: collectd
|
|
||||||
typesdb: /usr/share/collectd/types.db
|
|
||||||
|
|
||||||
roles:
|
|
||||||
- ansible-role-influxdb
|
|
||||||
|
|
||||||
pre_tasks:
|
|
||||||
- name: install collectd package
|
|
||||||
apt:
|
|
||||||
name: collectd-core
|
|
|
@ -1,50 +0,0 @@
|
||||||
require 'serverspec'
|
|
||||||
|
|
||||||
set :backend, :exec
|
|
||||||
|
|
||||||
puts
|
|
||||||
puts '================================'
|
|
||||||
puts %x(ansible --version)
|
|
||||||
puts '================================'
|
|
||||||
|
|
||||||
describe package('influxdb') do
|
|
||||||
it { should be_installed }
|
|
||||||
end
|
|
||||||
|
|
||||||
describe file('/etc/influxdb/influxdb.conf') do
|
|
||||||
it { should be_file }
|
|
||||||
it { should be_mode 644 }
|
|
||||||
it { should be_owned_by 'root' }
|
|
||||||
it { should be_grouped_into 'root' }
|
|
||||||
it { should contain 'enabled = true' }
|
|
||||||
end
|
|
||||||
|
|
||||||
describe service('influxdb') do
|
|
||||||
it { should be_enabled }
|
|
||||||
it { should be_running.under('systemd') }
|
|
||||||
end
|
|
||||||
|
|
||||||
describe port(8086) do
|
|
||||||
it { should be_listening.with('tcp6') }
|
|
||||||
end
|
|
||||||
|
|
||||||
describe port(25_826) do
|
|
||||||
it { should be_listening.with('udp6') }
|
|
||||||
end
|
|
||||||
|
|
||||||
describe command('influx -execute "SHOW USERS"') do
|
|
||||||
its(:exit_status) { should eq 0 }
|
|
||||||
its(:stdout) { should match(/paul\s+true/) }
|
|
||||||
its(:stdout) { should match(/adrien\s+false/) }
|
|
||||||
its(:stdout) { should_not match 'antoine' }
|
|
||||||
end
|
|
||||||
|
|
||||||
describe command('influx -execute "SHOW DATABASES"') do
|
|
||||||
its(:exit_status) { should eq 0 }
|
|
||||||
its(:stdout) { should match 'new_database' }
|
|
||||||
end
|
|
||||||
|
|
||||||
describe command('influx -execute "SHOW GRANTS FOR adrien"') do
|
|
||||||
its(:exit_status) { should eq 0 }
|
|
||||||
its(:stdout) { should match(/new_database\s+WRITE/) }
|
|
||||||
end
|
|
|
@ -1 +0,0 @@
|
||||||
localhost
|
|
Loading…
Reference in a new issue