Compare commits
11 Commits
master
...
c7203f58ff
Author | SHA1 | Date | |
---|---|---|---|
c7203f58ff
|
|||
2e0d83cca1
|
|||
35882ca1a9 | |||
4e7f33338e
|
|||
ddc6c2bb4d
|
|||
f9e29a4e30 | |||
c26e962898
|
|||
38c117d6fa | |||
ecb9724ee3
|
|||
4373e0a4a2
|
|||
19b71c9933 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
.*.swp
|
||||
*.retry
|
||||
vars_auth.yml
|
||||
|
10
inv.yml
10
inv.yml
@@ -6,6 +6,12 @@ all:
|
||||
ssh_args: -o ControlMaster=auto -o ControlPersist=60s
|
||||
# ansible_host: 192.168.122.139
|
||||
unpriv_user: thoto
|
||||
ed-c7-2:
|
||||
ansible_user: root
|
||||
ansible_host: ed-c7-2.virt.uller.thoto.net
|
||||
# ansible_host: 192.168.123.60 # + jumphost
|
||||
ssh_args: -o ControlMaster=auto -o ControlPersist=60s
|
||||
unpriv_user: thoto
|
||||
children:
|
||||
htcondor:
|
||||
hosts:
|
||||
@@ -13,3 +19,7 @@ all:
|
||||
slurm:
|
||||
hosts:
|
||||
ed-c7-1:
|
||||
cobald:
|
||||
hosts:
|
||||
ed-c7-1:
|
||||
ed-c7-2:
|
||||
|
21
play.yml
21
play.yml
@@ -1,11 +1,23 @@
|
||||
---
|
||||
- hosts: all
|
||||
vars_files: ['vars-auth.yml']
|
||||
tasks:
|
||||
- name: "install epel repo" # for htop etc.
|
||||
yum:
|
||||
name: epel-release
|
||||
state: present
|
||||
|
||||
- name: "install tools"
|
||||
yum:
|
||||
name: [ vim-enhanced, htop, screen, bind-utils, nmap-ncat, net-tools ]
|
||||
state: present
|
||||
|
||||
- name: "install ssh-key"
|
||||
authorized_key:
|
||||
user: thoto
|
||||
key: "{{ssh_key}}"
|
||||
state: present
|
||||
|
||||
- hosts: htcondor
|
||||
pre_tasks:
|
||||
- name: "install htcondor repo"
|
||||
@@ -54,3 +66,12 @@
|
||||
vars:
|
||||
slurm_user: slurm # or root
|
||||
tags: slurm
|
||||
|
||||
- hosts: cobald
|
||||
roles:
|
||||
- name: "setup docker"
|
||||
role: docker
|
||||
tags: docker
|
||||
- name: "install cobald"
|
||||
role: cobald
|
||||
tags: cobald
|
||||
|
5
roles/cobald/defaults/main.yml
Normal file
5
roles/cobald/defaults/main.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
influx_admin_user: my-user
|
||||
influx_admin_pw: my-password
|
||||
influx_org: my-org
|
||||
influx_pubport: 28086
|
||||
influx_bucket: batleth
|
7
roles/cobald/files/cobald-entrypoint.sh
Normal file
7
roles/cobald/files/cobald-entrypoint.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
[ -f /usr/local/lib/cobaldmodules/setup.py -a \
|
||||
-d /usr/local/lib/cobaldmodules/cobaldmodules ] && \
|
||||
pip3 install --no-deps --editable /usr/local/lib/cobaldmodules
|
||||
|
||||
exec "${@:-/bin/bash}"
|
55
roles/cobald/files/cobald.Dockerfile
Normal file
55
roles/cobald/files/cobald.Dockerfile
Normal file
@@ -0,0 +1,55 @@
|
||||
FROM docker.io/library/centos:7
|
||||
|
||||
RUN yum update -y && \
|
||||
yum install -y python3 git && pip3 install --upgrade pip && \
|
||||
yum clean all && rm -rf /var/cache/yum
|
||||
|
||||
ARG REPOCOBALD=https://github.com/MatterMiners/cobald
|
||||
ARG REPOTARDIS=https://github.com/MatterMiners/tardis
|
||||
|
||||
RUN git clone $REPOCOBALD /usr/local/src/cobald && \
|
||||
git clone $REPOTARDIS /usr/local/src/tardis
|
||||
|
||||
RUN mkdir /etc/cobald /var/log/cobald && \
|
||||
useradd -m -d /var/lib/cobald --no-log-init --system cobald && \
|
||||
chown cobald:cobald /var/log/cobald
|
||||
|
||||
#RUN mkdir /cobald && python3 -m venv /cobald && source /cobald/bin/activate &&\
|
||||
# pip3 install --upgrade pip && pip3 install cobald
|
||||
|
||||
RUN mkdir /usr/local/src/cobaldmodules /usr/local/lib/cobaldmodules && \
|
||||
ln -s /usr/local/src/cobaldmodules/setup.py \
|
||||
/usr/local/lib/cobaldmodules/setup.py && \
|
||||
ln -s /usr/local/src/cobaldmodules/cobaldmodules \
|
||||
/usr/local/lib/cobaldmodules/cobaldmodules && \
|
||||
chown cobald:cobald /usr/local/lib/cobaldmodules
|
||||
|
||||
RUN pip3 install --editable /usr/local/src/cobald && \
|
||||
pip3 install --editable /usr/local/src/cobald[contrib]
|
||||
|
||||
RUN pip3 install --editable /usr/local/src/tardis&& \
|
||||
pip3 install --editable /usr/local/src/tardis[contrib]
|
||||
|
||||
ENV PYTHONPATH=/usr/local/src/cobaldmodules
|
||||
|
||||
# pip3 install --editable .
|
||||
# pip3 install --editable .[contrib]
|
||||
# pip3 install --upgrade --editable /etc/cobald/modules/
|
||||
# su cobald -c "python3 -m cobald.daemon /etc/cobald/config.yaml"
|
||||
|
||||
VOLUME /usr/local/src/cobaldmodules
|
||||
|
||||
VOLUME /etc/cobald
|
||||
|
||||
COPY cobald-entrypoint.sh /usr/local/sbin/docker-entrypoint.sh
|
||||
|
||||
RUN chmod 755 /usr/local/sbin/docker-entrypoint.sh
|
||||
|
||||
ENTRYPOINT /usr/local/sbin/docker-entrypoint.sh
|
||||
|
||||
RUN yum -y install iproute &&\
|
||||
yum clean all && rm -rf /var/cache/yum
|
||||
|
||||
USER cobald
|
||||
|
||||
CMD "python3 -m cobald.daemon /etc/cobald/config.yaml"
|
540
roles/cobald/files/influxdb-dashboard-cobald.json
Normal file
540
roles/cobald/files/influxdb-dashboard-cobald.json
Normal file
@@ -0,0 +1,540 @@
|
||||
{
|
||||
"meta": {
|
||||
"version": "1",
|
||||
"type": "dashboard",
|
||||
"name": "cobald-Template",
|
||||
"description": "template created from dashboard: cobald"
|
||||
},
|
||||
"content": {
|
||||
"data": {
|
||||
"type": "dashboard",
|
||||
"attributes": {
|
||||
"name": "cobald",
|
||||
"description": ""
|
||||
},
|
||||
"relationships": {
|
||||
"label": {
|
||||
"data": []
|
||||
},
|
||||
"cell": {
|
||||
"data": [
|
||||
{
|
||||
"type": "cell",
|
||||
"id": "078ad2e135410000"
|
||||
},
|
||||
{
|
||||
"type": "cell",
|
||||
"id": "078ba588b6c10000"
|
||||
},
|
||||
{
|
||||
"type": "cell",
|
||||
"id": "078ba5e53a810000"
|
||||
},
|
||||
{
|
||||
"type": "cell",
|
||||
"id": "078c36c747010000"
|
||||
}
|
||||
]
|
||||
},
|
||||
"variable": {
|
||||
"data": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"included": [
|
||||
{
|
||||
"id": "078ad2e135410000",
|
||||
"type": "cell",
|
||||
"attributes": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 4,
|
||||
"h": 4
|
||||
},
|
||||
"relationships": {
|
||||
"view": {
|
||||
"data": {
|
||||
"type": "view",
|
||||
"id": "078ad2e135410000"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "078ba588b6c10000",
|
||||
"type": "cell",
|
||||
"attributes": {
|
||||
"x": 0,
|
||||
"y": 4,
|
||||
"w": 4,
|
||||
"h": 4
|
||||
},
|
||||
"relationships": {
|
||||
"view": {
|
||||
"data": {
|
||||
"type": "view",
|
||||
"id": "078ba588b6c10000"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "078ba5e53a810000",
|
||||
"type": "cell",
|
||||
"attributes": {
|
||||
"x": 4,
|
||||
"y": 4,
|
||||
"w": 4,
|
||||
"h": 4
|
||||
},
|
||||
"relationships": {
|
||||
"view": {
|
||||
"data": {
|
||||
"type": "view",
|
||||
"id": "078ba5e53a810000"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "078c36c747010000",
|
||||
"type": "cell",
|
||||
"attributes": {
|
||||
"x": 4,
|
||||
"y": 0,
|
||||
"w": 4,
|
||||
"h": 4
|
||||
},
|
||||
"relationships": {
|
||||
"view": {
|
||||
"data": {
|
||||
"type": "view",
|
||||
"id": "078c36c747010000"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "view",
|
||||
"id": "078ad2e135410000",
|
||||
"attributes": {
|
||||
"name": "Name this Cell",
|
||||
"properties": {
|
||||
"shape": "chronograf-v2",
|
||||
"queries": [
|
||||
{
|
||||
"text": "from(bucket: \"batleth\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r[\"tardis_machine_name\"] == \"678162c190d5\")\n |> window(every: 10s)\n |> count()\n |> duplicate(column: \"_stop\", as: \"_time\")\n |> window(every: inf)\n |> yield()",
|
||||
"editMode": "advanced",
|
||||
"name": "",
|
||||
"builderConfig": {
|
||||
"buckets": [],
|
||||
"tags": [
|
||||
{
|
||||
"key": "_measurement",
|
||||
"values": [],
|
||||
"aggregateFunctionType": "filter"
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"name": "mean"
|
||||
}
|
||||
],
|
||||
"aggregateWindow": {
|
||||
"period": "auto",
|
||||
"fillValues": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"axes": {
|
||||
"x": {
|
||||
"bounds": [
|
||||
"",
|
||||
""
|
||||
],
|
||||
"label": "",
|
||||
"prefix": "",
|
||||
"suffix": "",
|
||||
"base": "10",
|
||||
"scale": "linear"
|
||||
},
|
||||
"y": {
|
||||
"bounds": [
|
||||
"",
|
||||
""
|
||||
],
|
||||
"label": "",
|
||||
"prefix": "",
|
||||
"suffix": "",
|
||||
"base": "10",
|
||||
"scale": "linear"
|
||||
}
|
||||
},
|
||||
"type": "xy",
|
||||
"legend": {},
|
||||
"geom": "line",
|
||||
"colors": [
|
||||
{
|
||||
"id": "2566435b-7ee0-4222-8ac0-b7f14ab783d9",
|
||||
"type": "scale",
|
||||
"hex": "#31C0F6",
|
||||
"name": "Nineteen Eighty Four",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"id": "9263bcff-35a0-4025-bacd-68a1bef54784",
|
||||
"type": "scale",
|
||||
"hex": "#A500A5",
|
||||
"name": "Nineteen Eighty Four",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"id": "2f04bd8c-2203-4be6-bc34-c25720d24379",
|
||||
"type": "scale",
|
||||
"hex": "#FF7E27",
|
||||
"name": "Nineteen Eighty Four",
|
||||
"value": 0
|
||||
}
|
||||
],
|
||||
"note": "",
|
||||
"showNoteWhenEmpty": false,
|
||||
"xColumn": "_time",
|
||||
"generateXAxisTicks": [],
|
||||
"xTotalTicks": 0,
|
||||
"xTickStart": 0,
|
||||
"xTickStep": 0,
|
||||
"yColumn": "_value",
|
||||
"generateYAxisTicks": [],
|
||||
"yTotalTicks": 0,
|
||||
"yTickStart": 0,
|
||||
"yTickStep": 0,
|
||||
"shadeBelow": false,
|
||||
"position": "overlaid",
|
||||
"timeFormat": "",
|
||||
"hoverDimension": "auto",
|
||||
"legendColorizeRows": true,
|
||||
"legendOpacity": 1,
|
||||
"legendOrientationThreshold": 100000000
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "view",
|
||||
"id": "078ba588b6c10000",
|
||||
"attributes": {
|
||||
"name": "states",
|
||||
"properties": {
|
||||
"shape": "chronograf-v2",
|
||||
"queries": [
|
||||
{
|
||||
"text": "from(bucket: \"batleth\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r._field == \"state\")\n |> group(columns: [\"_value\"], mode: \"by\")\n |> duplicate(column: \"_value\", as: \"state\")\n |> window(every: 10s)\n |> count(column: \"state\")\n |> rename(columns: {\"_value\": \"_field\", \"state\": \"_value\"})\n |> group(columns: [\"_field\"])\n |> yield()",
|
||||
"editMode": "advanced",
|
||||
"name": "",
|
||||
"builderConfig": {
|
||||
"buckets": [],
|
||||
"tags": [
|
||||
{
|
||||
"key": "_measurement",
|
||||
"values": [],
|
||||
"aggregateFunctionType": "filter"
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"name": "mean"
|
||||
}
|
||||
],
|
||||
"aggregateWindow": {
|
||||
"period": "auto",
|
||||
"fillValues": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"axes": {
|
||||
"x": {
|
||||
"bounds": [
|
||||
"",
|
||||
""
|
||||
],
|
||||
"label": "",
|
||||
"prefix": "",
|
||||
"suffix": "",
|
||||
"base": "10",
|
||||
"scale": "linear"
|
||||
},
|
||||
"y": {
|
||||
"bounds": [
|
||||
"",
|
||||
""
|
||||
],
|
||||
"label": "",
|
||||
"prefix": "",
|
||||
"suffix": "",
|
||||
"base": "10",
|
||||
"scale": "linear"
|
||||
}
|
||||
},
|
||||
"type": "xy",
|
||||
"legend": {},
|
||||
"geom": "line",
|
||||
"colors": [
|
||||
{
|
||||
"id": "9b960932-18d9-4f57-80ba-24998a06613d",
|
||||
"type": "scale",
|
||||
"hex": "#31C0F6",
|
||||
"name": "Nineteen Eighty Four",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"id": "c1742651-0d5e-4148-b9c0-92beb642417a",
|
||||
"type": "scale",
|
||||
"hex": "#A500A5",
|
||||
"name": "Nineteen Eighty Four",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"id": "756fa8cb-9d9c-4e45-9a4f-f2b106b0216a",
|
||||
"type": "scale",
|
||||
"hex": "#FF7E27",
|
||||
"name": "Nineteen Eighty Four",
|
||||
"value": 0
|
||||
}
|
||||
],
|
||||
"note": "",
|
||||
"showNoteWhenEmpty": false,
|
||||
"xColumn": "_stop",
|
||||
"generateXAxisTicks": [],
|
||||
"xTotalTicks": 0,
|
||||
"xTickStart": 0,
|
||||
"xTickStep": 0,
|
||||
"yColumn": "_value",
|
||||
"generateYAxisTicks": [],
|
||||
"yTotalTicks": 0,
|
||||
"yTickStart": 0,
|
||||
"yTickStep": 0,
|
||||
"shadeBelow": false,
|
||||
"position": "overlaid",
|
||||
"timeFormat": "",
|
||||
"hoverDimension": "auto",
|
||||
"legendColorizeRows": true,
|
||||
"legendOpacity": 1,
|
||||
"legendOrientationThreshold": 100000000
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "view",
|
||||
"id": "078ba5e53a810000",
|
||||
"attributes": {
|
||||
"name": "node fluctuation",
|
||||
"properties": {
|
||||
"shape": "chronograf-v2",
|
||||
"queries": [
|
||||
{
|
||||
"text": "f = (r, accumulator) => ({\n _value: accumulator._value + (if r._value == \"AvailableState\" then 1 else if r._value == \"DownState\" then -1 else 0)\n })\n\nfrom(bucket: \"batleth\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r._field == \"state\")\n |> group()\n |> window(every: 10s)\n |> reduce(fn: f, identity: {_value: 0})\n |> duplicate(column: \"_stop\", as: \"_time\")\n |> window(every: inf, timeColumn: \"_time\")\n |> yield()",
|
||||
"editMode": "advanced",
|
||||
"name": "",
|
||||
"builderConfig": {
|
||||
"buckets": [],
|
||||
"tags": [
|
||||
{
|
||||
"key": "_measurement",
|
||||
"values": [],
|
||||
"aggregateFunctionType": "filter"
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"name": "mean"
|
||||
}
|
||||
],
|
||||
"aggregateWindow": {
|
||||
"period": "auto",
|
||||
"fillValues": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"axes": {
|
||||
"x": {
|
||||
"bounds": [
|
||||
"",
|
||||
""
|
||||
],
|
||||
"label": "",
|
||||
"prefix": "",
|
||||
"suffix": "",
|
||||
"base": "10",
|
||||
"scale": "linear"
|
||||
},
|
||||
"y": {
|
||||
"bounds": [
|
||||
"",
|
||||
""
|
||||
],
|
||||
"label": "",
|
||||
"prefix": "",
|
||||
"suffix": "",
|
||||
"base": "10",
|
||||
"scale": "linear"
|
||||
}
|
||||
},
|
||||
"type": "xy",
|
||||
"legend": {},
|
||||
"geom": "line",
|
||||
"colors": [
|
||||
{
|
||||
"id": "9b960932-18d9-4f57-80ba-24998a06613d",
|
||||
"type": "scale",
|
||||
"hex": "#31C0F6",
|
||||
"name": "Nineteen Eighty Four",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"id": "c1742651-0d5e-4148-b9c0-92beb642417a",
|
||||
"type": "scale",
|
||||
"hex": "#A500A5",
|
||||
"name": "Nineteen Eighty Four",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"id": "756fa8cb-9d9c-4e45-9a4f-f2b106b0216a",
|
||||
"type": "scale",
|
||||
"hex": "#FF7E27",
|
||||
"name": "Nineteen Eighty Four",
|
||||
"value": 0
|
||||
}
|
||||
],
|
||||
"note": "",
|
||||
"showNoteWhenEmpty": false,
|
||||
"xColumn": "_time",
|
||||
"generateXAxisTicks": [],
|
||||
"xTotalTicks": 0,
|
||||
"xTickStart": 0,
|
||||
"xTickStep": 0,
|
||||
"yColumn": "_value",
|
||||
"generateYAxisTicks": [],
|
||||
"yTotalTicks": 0,
|
||||
"yTickStart": 0,
|
||||
"yTickStep": 0,
|
||||
"shadeBelow": false,
|
||||
"position": "overlaid",
|
||||
"timeFormat": "",
|
||||
"hoverDimension": "auto",
|
||||
"legendColorizeRows": true,
|
||||
"legendOpacity": 1,
|
||||
"legendOrientationThreshold": 100000000
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "view",
|
||||
"id": "078c36c747010000",
|
||||
"attributes": {
|
||||
"name": "nodes running",
|
||||
"properties": {
|
||||
"shape": "chronograf-v2",
|
||||
"queries": [
|
||||
{
|
||||
"text": "from(bucket: \"batleth\")\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n |> filter(fn: (r) => r._field == \"state\")\n |> group()\n |> window(every: 10s)\n |> reduce(fn: (r, accumulator) => ({\n _value: accumulator._value + (\n if r._value == \"AvailableState\" then 1 \n else if r._value == \"DownState\" then -1 \n else 0)\n }), identity: {_value: 0})\n |> duplicate(column: \"_stop\", as: \"_time\")\n |> window(every: inf) //, timeColumn: \"_time\")\n |> cumulativeSum()\n// |> reduce(fn: (r, accumulator) => ({r with x: r._value * 2}), identity: {x:0})\n// |> map(fn: (r) => ({r with vnew: r._value*2}))\n// |> integral(unit: 10s, timeColumn: \"_stop\")\n// |> window(every: inf) //, timeColumn: \"_stop\")\n |> yield()",
|
||||
"editMode": "advanced",
|
||||
"name": "",
|
||||
"builderConfig": {
|
||||
"buckets": [],
|
||||
"tags": [
|
||||
{
|
||||
"key": "_measurement",
|
||||
"values": [],
|
||||
"aggregateFunctionType": "filter"
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"name": "mean"
|
||||
}
|
||||
],
|
||||
"aggregateWindow": {
|
||||
"period": "auto",
|
||||
"fillValues": false
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"axes": {
|
||||
"x": {
|
||||
"bounds": [
|
||||
"",
|
||||
""
|
||||
],
|
||||
"label": "",
|
||||
"prefix": "",
|
||||
"suffix": "",
|
||||
"base": "10",
|
||||
"scale": "linear"
|
||||
},
|
||||
"y": {
|
||||
"bounds": [
|
||||
"",
|
||||
""
|
||||
],
|
||||
"label": "",
|
||||
"prefix": "",
|
||||
"suffix": "",
|
||||
"base": "10",
|
||||
"scale": "linear"
|
||||
}
|
||||
},
|
||||
"type": "xy",
|
||||
"legend": {},
|
||||
"geom": "line",
|
||||
"colors": [
|
||||
{
|
||||
"id": "9b960932-18d9-4f57-80ba-24998a06613d",
|
||||
"type": "scale",
|
||||
"hex": "#31C0F6",
|
||||
"name": "Nineteen Eighty Four",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"id": "c1742651-0d5e-4148-b9c0-92beb642417a",
|
||||
"type": "scale",
|
||||
"hex": "#A500A5",
|
||||
"name": "Nineteen Eighty Four",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"id": "756fa8cb-9d9c-4e45-9a4f-f2b106b0216a",
|
||||
"type": "scale",
|
||||
"hex": "#FF7E27",
|
||||
"name": "Nineteen Eighty Four",
|
||||
"value": 0
|
||||
}
|
||||
],
|
||||
"note": "",
|
||||
"showNoteWhenEmpty": false,
|
||||
"xColumn": "_time",
|
||||
"generateXAxisTicks": [],
|
||||
"xTotalTicks": 0,
|
||||
"xTickStart": 0,
|
||||
"xTickStep": 0,
|
||||
"yColumn": "_value",
|
||||
"generateYAxisTicks": [],
|
||||
"yTotalTicks": 0,
|
||||
"yTickStart": 0,
|
||||
"yTickStep": 0,
|
||||
"shadeBelow": false,
|
||||
"position": "overlaid",
|
||||
"timeFormat": "",
|
||||
"hoverDimension": "auto",
|
||||
"legendColorizeRows": true,
|
||||
"legendOpacity": 1,
|
||||
"legendOrientationThreshold": 100000000
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"labels": []
|
||||
}
|
6
roles/cobald/files/influxdb.repo
Normal file
6
roles/cobald/files/influxdb.repo
Normal file
@@ -0,0 +1,6 @@
|
||||
[influxdb]
|
||||
name = InfluxDB Repository - RHEL \$releasever
|
||||
baseurl = https://repos.influxdata.com/rhel/\$releasever/\$basearch/stable
|
||||
enabled = 1
|
||||
gpgcheck = 1
|
||||
gpgkey = https://repos.influxdata.com/influxdb.key
|
8
roles/cobald/files/telegraf.Dockerfile
Normal file
8
roles/cobald/files/telegraf.Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
||||
FROM centos:7
|
||||
|
||||
COPY influxdb.repo /etc/yum.repos.d/influxdb.repo
|
||||
|
||||
RUN yum -y install telegraf &&\
|
||||
yum clean all && rm -rf /var/cache/yum
|
||||
|
||||
CMD telegraf
|
11
roles/cobald/library/TODO.md
Normal file
11
roles/cobald/library/TODO.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Tests
|
||||
ANSIBLE_LIBRARY=. ansible -m influx_bucket -a "base='http://192.168.122.140:28086' org='my-org' auth_token='87-fEnSlQldFi1T_CLHsrHxH-T9VKey-qzUbVH6tmR2QzL4oZzbUPwzS1wzOoIkyfmyGbRv75yLjYfztxziivw==' name='bucky' description='test 123'" localhost -vvv
|
||||
ANSIBLE_LIBRARY=. ansible -m influx_token -a "base='http://192.168.122.140:28086' org='my-org' auth_token='87-fEnSlQldFi1T_CLHsrHxH-T9VKey-qzUbVH6tmR2QzL4oZzbUPwzS1wzOoIkyfmyGbRv75yLjYfztxziivw==' key='foo' description='test 123' permissions=\"{{'[{\\\"action\\\": \\\"write\\\",\\\"resource\\\": {\\\"type\\\": \\\"buckets\\\"} }]'|from_json}}\"" localhost -vvv
|
||||
ANSIBLE_LIBRARY=. ansible -m influx_dashboard -create -a "base='http://192.168.122.140:28086' org='my-org' token='2Mji-PvTzgn2oie5p36pJ-vxqWCnxczMWGrnYz2nUHj6Q6XvdIGiLPmK4DjX16KGhOjxQ5dWymDusE8qJrhFFg==' data='{{lookup(\"file\", \"../files/influxdb-dashboard-cobald.json\")}}'" localhost -vvv
|
||||
Missing: lot of stuff, e.g. missing tokens, invalid data like bucket instead of buckets ...
|
||||
|
||||
# TODO
|
||||
* tests
|
||||
* state (present/absent)
|
||||
* `module_utils/urls.py` (https://github.com/ansible/ansible/blob/devel/lib/ansible/module_utils/urls.py)
|
||||
* see module notes
|
161
roles/cobald/library/influx_bucket.py
Executable file
161
roles/cobald/library/influx_bucket.py
Executable file
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env python
|
||||
import requests
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: influx2_bucket
|
||||
short_description: create bucket in influxdb2
|
||||
description: create bucket in influxdb2
|
||||
notes:
|
||||
- just works with influxdb version 2
|
||||
- does not remove buckets
|
||||
- no way to configure data retention
|
||||
|
||||
options:
|
||||
base:
|
||||
description: URL for path, e.g. `https://localhost:8086`
|
||||
type: str
|
||||
required: True
|
||||
org:
|
||||
description: influxdb2 organisation
|
||||
type: str
|
||||
required: True
|
||||
auth_token:
|
||||
description: influxdb2 authentication token
|
||||
type: str
|
||||
required: True
|
||||
name:
|
||||
description: name of the bucket
|
||||
type: str
|
||||
required: True
|
||||
force:
|
||||
description: force creation even if bucket already exists
|
||||
(adds a new one)
|
||||
type: bool
|
||||
required: False
|
||||
default: False
|
||||
author:
|
||||
- Thorsten M. (@thoto)
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
- name: "fetch auth token"
|
||||
raw: influx auth list --user my-user --hide-headers | cut -f 3
|
||||
register: influx_token_fetch
|
||||
delegate_to: ed-influxdb-2
|
||||
|
||||
- name: "create bucket"
|
||||
influx_bucket:
|
||||
base: "http://localhost:8086"
|
||||
org: "my-org"
|
||||
token: "{{influx_token_fetch.stdout_lines[0]}}"
|
||||
name: "bucky"
|
||||
'''
|
||||
|
||||
|
||||
def get_org_id(base, org_name, h):
|
||||
ro = requests.get("{base}/api/v2/orgs".format(base=base), headers=h,
|
||||
json={"org": org_name})
|
||||
ro.raise_for_status()
|
||||
org_id = [o["id"] for o in ro.json()["orgs"] if o["name"] == org_name]
|
||||
return org_id[0]
|
||||
|
||||
|
||||
class Bucket:
|
||||
def __init__(self, base, h, org, description, name):
|
||||
self.base = base
|
||||
self.h = h
|
||||
self.org_id = get_org_id(base, org, h)
|
||||
self.description = description
|
||||
self.name = name
|
||||
|
||||
self.result = None
|
||||
self.f = None
|
||||
|
||||
def check(self):
|
||||
ra = requests.get("{base}/api/v2/buckets".format(
|
||||
base=self.base),
|
||||
params={"orgID": self.org_id, "name": self.name},
|
||||
headers=self.h)
|
||||
if ra.status_code == 404:
|
||||
# orgID + name -> 404 on empty set. Just name -> 200 but buckets=[]
|
||||
x = []
|
||||
else:
|
||||
ra.raise_for_status()
|
||||
x = [i for i in ra.json()["buckets"]
|
||||
if self.name == i["name"] and i["orgID"] == self.org_id]
|
||||
assert(len(x) == 1 or len(x) == 0)
|
||||
|
||||
update = None
|
||||
if len(x) == 0: # create
|
||||
self.result = None
|
||||
self.f = lambda: self._create({
|
||||
"orgID": self.org_id,
|
||||
"description": self.description if self.description else None,
|
||||
"name": self.name,
|
||||
"retentionRules": []
|
||||
})
|
||||
else:
|
||||
self.result = x[0]
|
||||
if self.description == x[0].get("description", ""):
|
||||
return False # everything matches -> no change needed
|
||||
else:
|
||||
self.result = x[0]
|
||||
update = {"id": x[0]["id"],
|
||||
"description": self.description}
|
||||
self.f = lambda: self._update(**update)
|
||||
return True
|
||||
|
||||
def run(self):
|
||||
if not self.f:
|
||||
self.check()
|
||||
self.f()
|
||||
|
||||
def _update(self, id, description):
|
||||
ra = requests.patch(
|
||||
"{base}/api/v2/buckets/{id}".format(
|
||||
base=self.base, id=id),
|
||||
headers=self.h, json={"description": description})
|
||||
ra.raise_for_status()
|
||||
return ra
|
||||
|
||||
def _create(self, data):
|
||||
ra = requests.post("{base}/api/v2/buckets".format(base=self.base),
|
||||
headers=self.h, json=data)
|
||||
ra.raise_for_status()
|
||||
self.result = ra.json()
|
||||
return ra
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = dict(changed=False, message="")
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
base=dict(type="str", required=True),
|
||||
org=dict(type="str", required=True),
|
||||
auth_token=dict(type="str", required=True),
|
||||
name=dict(type="str", required=True),
|
||||
description=dict(type="str", default=""),
|
||||
force=dict(type="bool", default=False),
|
||||
),
|
||||
supports_check_mode=True
|
||||
)
|
||||
h = {"Authorization": "Token {token}".format(
|
||||
token=module.params["auth_token"])}
|
||||
b = Bucket(module.params["base"], h, org=module.params["org"],
|
||||
description=module.params["description"],
|
||||
name=module.params["name"])
|
||||
|
||||
changed = b.check()
|
||||
if b.result:
|
||||
result['bucket_id'] = b.result["id"]
|
||||
result['changed'] = changed
|
||||
|
||||
if module.check_mode:
|
||||
module.exit_json(**result)
|
||||
|
||||
if changed or module.params["force"]:
|
||||
b.run()
|
||||
result['bucket_id'] = b.result["id"]
|
||||
module.exit_json(**result)
|
147
roles/cobald/library/influx_dashboard.py
Executable file
147
roles/cobald/library/influx_dashboard.py
Executable file
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env python
|
||||
import json
|
||||
import requests
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: influx2_dashboard
|
||||
short_description: create dashboard in influxdb2
|
||||
description: create dashboard in influxdb2
|
||||
notes:
|
||||
- just works with influxdb version 2
|
||||
- does not create dashboard description
|
||||
- does not update dashboards
|
||||
- just creates a dashboard if it does not exist.
|
||||
|
||||
options:
|
||||
base:
|
||||
description: URL for path, e.g. `https://localhost:8086`
|
||||
type: str
|
||||
required: True
|
||||
org:
|
||||
description: influxdb2 organisation
|
||||
type: str
|
||||
required: True
|
||||
auth_token:
|
||||
description: influxdb2 authentication token
|
||||
type: str
|
||||
required: True
|
||||
data:
|
||||
description: exported dashboard json file
|
||||
type: json
|
||||
required: True
|
||||
force:
|
||||
description: force creation even if dashboard already exists
|
||||
(adds a new one)
|
||||
type: bool
|
||||
required: False
|
||||
default: False
|
||||
author:
|
||||
- Thorsten M. (@thoto)
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
- name: "fetch auth token"
|
||||
raw: influx auth list --user my-user --hide-headers | cut -f 3
|
||||
register: influx_token_fetch
|
||||
delegate_to: ed-influxdb-2
|
||||
|
||||
- name: "create dashboard"
|
||||
influx_dashboard:
|
||||
base: "http://localhost:8086"
|
||||
org: "my-org"
|
||||
auth_token: "{{influx_token_fetch.stdout_lines[0]}}"
|
||||
data: "{{lookup('file', 'influxdb-dashboard-cobald.json')}}"
|
||||
'''
|
||||
|
||||
|
||||
def parse_dashboard_template(data):
|
||||
j = json.loads(data)
|
||||
|
||||
return {
|
||||
'name': j["content"]["data"]["attributes"]["name"],
|
||||
'cells': {i["relationships"]["view"]["data"]["id"]: i["attributes"]
|
||||
for i in j["content"]["included"] if i["type"] == "cell"},
|
||||
'views': {i["id"]: i["attributes"]
|
||||
for i in j["content"]["included"] if i["type"] == "view"},
|
||||
}
|
||||
|
||||
|
||||
def get_auth(base, org_name, token):
|
||||
h = {"Authorization": "Token {token}".format(token=token)}
|
||||
|
||||
rm = requests.get("{base}/api/v2/me".format(base=base), headers=h)
|
||||
rm.raise_for_status()
|
||||
# me_name = rm.json()["name"]
|
||||
me = rm.json()["id"]
|
||||
|
||||
ro = requests.get("{base}/api/v2/orgs".format(base=base), headers=h,
|
||||
json={"userID": me})
|
||||
ro.raise_for_status()
|
||||
org_id = [o["id"] for o in ro.json()["orgs"] if o["name"] == org_name]
|
||||
|
||||
return {"org_id": org_id[0], "org_name": org_name, "uid": me, "h": h}
|
||||
|
||||
|
||||
def check(base, auth, dashboard):
|
||||
h = auth["h"]
|
||||
rd = requests.get("{base}/api/v2/dashboards".format(base=base), headers=h)
|
||||
rd.raise_for_status()
|
||||
x = [i for i in rd.json()["dashboards"]
|
||||
if i["name"] == dashboard["name"] and i["orgID"] == auth["org_id"]]
|
||||
return len(x) == 0, x
|
||||
|
||||
|
||||
def create(base, auth, dashboard):
|
||||
h = auth["h"]
|
||||
|
||||
# create dashboard
|
||||
rd = requests.post("{base}/api/v2/dashboards".format(base=base), headers=h,
|
||||
json={"orgID": auth["org_id"],
|
||||
"name": dashboard["name"]})
|
||||
rd.raise_for_status()
|
||||
dash_id = rd.json()["id"]
|
||||
|
||||
for k, v in dashboard["cells"].items():
|
||||
# create cells in dashboard
|
||||
rc = requests.post(
|
||||
"{base}/api/v2/dashboards/{dash_id}/cells".format(
|
||||
base=base, dash_id=dash_id),
|
||||
headers=h, json=v)
|
||||
rc.raise_for_status()
|
||||
cell_id = rc.json()["id"]
|
||||
|
||||
# create view of cell in dashboard
|
||||
rv = requests.patch(
|
||||
"{base}/api/v2/dashboards/{dash_id}/cells/{cell_id}/view".format(
|
||||
base=base, dash_id=dash_id, cell_id=cell_id),
|
||||
headers=h, json=dashboard["views"][k])
|
||||
rv.raise_for_status()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = dict(changed=False, message="")
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
base=dict(type="str", required=True),
|
||||
org=dict(type="str", required=True),
|
||||
auth_token=dict(type="str", required=True),
|
||||
data=dict(type="json", required=True),
|
||||
force=dict(type="bool", default=False),
|
||||
),
|
||||
supports_check_mode=True
|
||||
)
|
||||
dashboard = parse_dashboard_template(module.params["data"])
|
||||
auth = get_auth(module.params["base"], module.params["org"],
|
||||
module.params["auth_token"])
|
||||
changed, x = check(module.params["base"], auth, dashboard)
|
||||
|
||||
result['changed'] = changed
|
||||
|
||||
if module.check_mode:
|
||||
module.exit_json(**result)
|
||||
|
||||
if changed or module.params["force"]:
|
||||
create(module.params["base"], auth, dashboard)
|
||||
module.exit_json(**result)
|
232
roles/cobald/library/influx_token.py
Executable file
232
roles/cobald/library/influx_token.py
Executable file
@@ -0,0 +1,232 @@
|
||||
#!/usr/bin/env python
|
||||
import requests
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: influx2_token
|
||||
short_description: generate token via influxdb2 api
|
||||
description: generate token via influxdb2 api
|
||||
notes:
|
||||
- just works with influxdb version 2
|
||||
- needs token to authenticate against API (use
|
||||
`influx auth list --user my-user --hide-headers | cut -f 3`
|
||||
- tokens may not be removed
|
||||
- permissions can not be updated. a new token is created and the old
|
||||
one is not removed.
|
||||
options:
|
||||
base:
|
||||
description: URL for path, e.g. `https://localhost:8086`
|
||||
type: str
|
||||
required: True
|
||||
org:
|
||||
description: influxdb2 organisation
|
||||
type: str
|
||||
required: True
|
||||
auth_token:
|
||||
description: influxdb2 authentication token
|
||||
type: str
|
||||
required: True
|
||||
key:
|
||||
description: some key used to identify token. This is put into
|
||||
the tokens description
|
||||
type: str
|
||||
required: True
|
||||
description:
|
||||
description: textual description for token. key gets appended
|
||||
type: str
|
||||
required: False
|
||||
permissions:
|
||||
description: list of permissions, each dict(action, resource)
|
||||
type: list
|
||||
required: True
|
||||
force:
|
||||
description: force creation even if dashboard already exists
|
||||
(adds a new one)
|
||||
type: bool
|
||||
required: False
|
||||
default: False
|
||||
author:
|
||||
- Thorsten M. (@thoto)
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
- name: "fetch auth token"
|
||||
raw: influx auth list --user my-user --hide-headers | cut -f 3
|
||||
register: influx_token_fetch
|
||||
delegate_to: ed-influxdb-2
|
||||
|
||||
- name: "create dashboard"
|
||||
influx_token:
|
||||
base: "http://localhost:8086"
|
||||
org: "my-org"
|
||||
auth_token: "{{influx_token_fetch.stdout_lines[0]}}"
|
||||
key: "foo123"
|
||||
description: "token for foo key"
|
||||
permissions:
|
||||
- action: "write"
|
||||
resource:
|
||||
type: "buckets"
|
||||
register: ed-influx-token
|
||||
|
||||
- debug: msg="Token: {{ed-influx-token.token}}"
|
||||
'''
|
||||
|
||||
|
||||
def get_org_id(base, org_name, h):
|
||||
ro = requests.get("{base}/api/v2/orgs".format(base=base), headers=h,
|
||||
json={"org": org_name})
|
||||
ro.raise_for_status()
|
||||
org_id = [o["id"] for o in ro.json()["orgs"] if o["name"] == org_name]
|
||||
return org_id[0]
|
||||
|
||||
|
||||
def marker(key):
|
||||
return "__ANSIBLE_TOKEN_{key}__".format(key=key)
|
||||
|
||||
|
||||
def _filter_perms(perms):
|
||||
for r in perms:
|
||||
r["resource"] = {k: v for k, v in r["resource"].items() if v}
|
||||
return perms
|
||||
|
||||
|
||||
class Token:
|
||||
def __init__(self, base, h, data):
|
||||
self.base = base
|
||||
self.h = h
|
||||
self.marker = marker(data["key"])
|
||||
|
||||
self.org_id = data["org_id"]
|
||||
self.perms = _filter_perms(data["perms"])
|
||||
self.description = data["description"]+" "+self.marker
|
||||
|
||||
self.result_token = None
|
||||
self.f = None
|
||||
|
||||
def check(self):
|
||||
ra = requests.get("{base}/api/v2/authorizations".format(
|
||||
base=self.base),
|
||||
params={"orgID": self.org_id},
|
||||
headers=self.h)
|
||||
ra.raise_for_status()
|
||||
|
||||
update = None
|
||||
for i in ra.json()["authorizations"]:
|
||||
if self.marker not in i["description"] \
|
||||
or i["orgID"] != self.org_id:
|
||||
continue
|
||||
if self._match_perms(self.perms, i["permissions"]):
|
||||
self.result_token = i
|
||||
if self.description == i["description"]:
|
||||
return False # everything matches -> no change needed
|
||||
else:
|
||||
update = {"auth_id": i["id"],
|
||||
"description": self.description}
|
||||
# TODO: may remove token because permissions do not match?
|
||||
if update:
|
||||
self.f = lambda: self._update(**update)
|
||||
else:
|
||||
self.result_token = None
|
||||
self.f = lambda: self._create({
|
||||
"orgID": self.org_id,
|
||||
"description": self.description,
|
||||
"permissions": self.perms
|
||||
})
|
||||
return True
|
||||
|
||||
def run(self):
|
||||
if not self.f:
|
||||
self.check()
|
||||
self.f()
|
||||
|
||||
def _match_perms(self, pa, pb):
|
||||
def g(match, lst):
|
||||
for idx, i in enumerate(lst):
|
||||
if i['action'] != match['action']:
|
||||
continue
|
||||
for k, v in match['resource'].items():
|
||||
if k not in i['resource'] or i['resource'][k] != v:
|
||||
continue
|
||||
else: # first best match
|
||||
return idx
|
||||
else:
|
||||
raise ValueError
|
||||
|
||||
b = [b.copy() for b in pb]
|
||||
for i in pa:
|
||||
try:
|
||||
b.pop(g(i, b))
|
||||
except ValueError:
|
||||
return False # permission i not present in b
|
||||
|
||||
if b: # not empty
|
||||
return False # some permissions in b not in a
|
||||
return True
|
||||
|
||||
def _update(self, auth_id, description):
|
||||
ra = requests.patch(
|
||||
"{base}/api/v2/authorizations/{auth_id}".format(
|
||||
base=self.base, auth_id=auth_id),
|
||||
headers=self.h, json={"description": description})
|
||||
ra.raise_for_status()
|
||||
return ra
|
||||
|
||||
def _create(self, data):
|
||||
ra = requests.post("{base}/api/v2/authorizations".format(
|
||||
base=self.base),
|
||||
headers=self.h, json=data)
|
||||
ra.raise_for_status()
|
||||
self.result_token = ra.json()
|
||||
return ra
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = dict(changed=False, message="")
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
base=dict(type="str", required=True),
|
||||
org=dict(type="str", required=True),
|
||||
auth_token=dict(type="str", required=True),
|
||||
key=dict(type="str", required=True),
|
||||
description=dict(type="str", default=""),
|
||||
permissions=dict(type="list", elements='dict', options=dict(
|
||||
action=dict(type='str', choices=['read', 'write'],
|
||||
required=True),
|
||||
resource=dict(type='dict', options=dict(
|
||||
id=dict(type='str'),
|
||||
name=dict(type='str'),
|
||||
org=dict(type='str'),
|
||||
orgID=dict(type='str'),
|
||||
type=dict(type='str', required=True, choices=[
|
||||
"authorizations", "buckets", "dashboards", "orgs",
|
||||
"sources", "tasks", "telegrafs", "users", "variables",
|
||||
"scrapers", "secrets", "labels", "views", "documents",
|
||||
"notificationRules", "notificationEndpoints", "checks",
|
||||
"dbrp", "flows", "annotations", "functions"]),
|
||||
), required=True),
|
||||
), required=True),
|
||||
force=dict(type="bool", default=False),
|
||||
),
|
||||
supports_check_mode=True
|
||||
)
|
||||
h = {"Authorization": "Token {token}".format(
|
||||
token=module.params["auth_token"])}
|
||||
t = Token(module.params["base"], h, {
|
||||
"org_id": get_org_id(module.params["base"], module.params["org"], h),
|
||||
"key": module.params["key"],
|
||||
"perms": module.params["permissions"],
|
||||
"description": module.params["description"]})
|
||||
|
||||
changed = t.check()
|
||||
if t.result_token:
|
||||
result['token'] = t.result_token["token"]
|
||||
result['changed'] = changed
|
||||
|
||||
if module.check_mode:
|
||||
module.exit_json(**result)
|
||||
|
||||
if changed or module.params["force"]:
|
||||
t.run()
|
||||
result['token'] = t.result_token["token"]
|
||||
module.exit_json(**result)
|
80
roles/cobald/tasks/influxdb.yml
Normal file
80
roles/cobald/tasks/influxdb.yml
Normal file
@@ -0,0 +1,80 @@
|
||||
#- file:
|
||||
# path: "/container/volumes/influxdb-backup/"
|
||||
# state: directory
|
||||
# owner: "{{unpriv_user}}"
|
||||
# group: docker
|
||||
|
||||
#- copy:
|
||||
# src: influxdb-dashboard-cobald.json
|
||||
# dest: /container/volumes/influxdb-backup/dash-cobald.json
|
||||
# owner: "{{unpriv_user}}"
|
||||
# group: docker
|
||||
|
||||
- docker_container:
|
||||
name: ed-influxdb-2 # -2 FIXME
|
||||
image: influxdb
|
||||
hostname: "{{influx_hostname}}"
|
||||
domainname: "{{influx_domainname}}"
|
||||
networks:
|
||||
- name: "{{ docker_network }}"
|
||||
published_ports:
|
||||
- "{{influx_pubport}}:8086"
|
||||
volumes:
|
||||
- "ed-influxdb-data-2:/var/lib/influxdb2" # -2 FIXME
|
||||
- "/container/volumes/influxdb-backup/:/backup"
|
||||
env:
|
||||
DOCKER_INFLUXDB_INIT_MODE: setup
|
||||
DOCKER_INFLUXDB_INIT_USERNAME: "{{influx_admin_user}}"
|
||||
DOCKER_INFLUXDB_INIT_PASSWORD: "{{influx_admin_pw}}"
|
||||
DOCKER_INFLUXDB_INIT_ORG: "{{influx_org}}"
|
||||
DOCKER_INFLUXDB_INIT_BUCKET: my-bucket
|
||||
state: started
|
||||
detach: True
|
||||
cleanup: True
|
||||
networks_cli_compatible: True
|
||||
|
||||
- add_host:
|
||||
name: ed-influxdb-2
|
||||
ansible_connection: docker
|
||||
# ansible_docker_extra_args: "-H=ssh://ed-c7-1.virt.magni.thoto.net" # FIXME
|
||||
ansible_docker_extra_args: "-H=ssh://{{ansible_host}}" # FIXME
|
||||
changed_when: False
|
||||
|
||||
- wait_for: # FIXME: does not work right -> fetch token fails
|
||||
port: "{{influx_pubport}}"
|
||||
|
||||
- name: "fetch auth token"
|
||||
raw: influx auth list --user my-user --hide-headers --json
|
||||
register: influx_token_fetch
|
||||
changed_when: False
|
||||
delegate_to: ed-influxdb-2
|
||||
|
||||
- set_fact:
|
||||
influx_admin_token:
|
||||
"{{(influx_token_fetch.stdout | from_json | first).token}}"
|
||||
|
||||
- influx_bucket:
|
||||
base: "http://localhost:{{influx_pubport}}"
|
||||
org: "my-org"
|
||||
auth_token: "{{influx_admin_token}}"
|
||||
name: "{{influx_bucket}}"
|
||||
|
||||
- name: "create dashboard"
|
||||
influx_dashboard:
|
||||
base: "http://localhost:{{influx_pubport}}"
|
||||
org: "my-org"
|
||||
auth_token: "{{influx_admin_token}}"
|
||||
data: "{{lookup('file', 'influxdb-dashboard-cobald.json')}}"
|
||||
|
||||
- influx_token:
|
||||
base: "http://localhost:{{influx_pubport}}"
|
||||
org: "my-org"
|
||||
auth_token: "{{influx_admin_token}}"
|
||||
description: cobald tardis telegraf monitoring plugin
|
||||
key: telegraf_cobaldtardis
|
||||
permissions:
|
||||
- action: write
|
||||
resource:
|
||||
type: buckets
|
||||
name: "{{influx_bucket}}"
|
||||
register: influx_telegraf_token
|
116
roles/cobald/tasks/main.yml
Normal file
116
roles/cobald/tasks/main.yml
Normal file
@@ -0,0 +1,116 @@
|
||||
- file:
|
||||
path: "/container/{{item}}/cobald/"
|
||||
state: directory
|
||||
owner: "{{unpriv_user}}"
|
||||
group: docker
|
||||
loop:
|
||||
- docker-images
|
||||
- volumes
|
||||
|
||||
- copy:
|
||||
src: cobald.Dockerfile
|
||||
dest: /container/docker-images/cobald/Dockerfile
|
||||
owner: "{{unpriv_user}}"
|
||||
group: docker
|
||||
register: cobald_cp_dockerfile
|
||||
|
||||
- copy:
|
||||
src: cobald-entrypoint.sh
|
||||
dest: /container/docker-images/cobald/cobald-entrypoint.sh
|
||||
owner: "{{unpriv_user}}"
|
||||
group: docker
|
||||
mode: 0755
|
||||
register: cobald_cp_files
|
||||
|
||||
- docker_image:
|
||||
name: "cobald"
|
||||
# pull: False
|
||||
build:
|
||||
pull: False
|
||||
path: "/container/docker-images/cobald/"
|
||||
source: build
|
||||
force_source: "{{cobald_cp_dockerfile.changed or cobald_cp_files.changed}}"
|
||||
|
||||
- copy:
|
||||
src: cobald-config/
|
||||
dest: /container/volumes/cobald
|
||||
owner: "{{unpriv_user}}"
|
||||
group: docker
|
||||
when: False
|
||||
|
||||
- set_fact:
|
||||
docker_network: slurm
|
||||
|
||||
- docker_network:
|
||||
name: "{{docker_network}}"
|
||||
state: present
|
||||
|
||||
# docker run -v $(pwd)/cobald-config-host:/etc/cobald -v $(pwd)/cobald:/cobald --rm -it cobald bash
|
||||
|
||||
- yum:
|
||||
name: git
|
||||
state: present
|
||||
|
||||
- git:
|
||||
repo: https://github.com/thoto/cobald
|
||||
dest: "~{{unpriv_user}}/cobald-src"
|
||||
version: bugfix/mixed_construction_methods
|
||||
become: yes
|
||||
become_user: "{{unpriv_user}}"
|
||||
register: cobald_git_pull
|
||||
|
||||
- git:
|
||||
repo: https://github.com/MatterMiners/tardis
|
||||
dest: "~{{unpriv_user}}/tardis-src"
|
||||
version: master
|
||||
become: yes
|
||||
become_user: "{{unpriv_user}}"
|
||||
register: tardis_git_pull
|
||||
|
||||
- name: "get unpriv_user {{unpriv_user}} uid and gid"
|
||||
getent:
|
||||
database: passwd
|
||||
key: "{{unpriv_user}}"
|
||||
|
||||
- import_tasks: telegraf.yml
|
||||
vars:
|
||||
docker_network: cobald
|
||||
|
||||
- name: run pip install
|
||||
docker_container:
|
||||
image: cobald
|
||||
name: "cobald-src-{{item.name}}-install"
|
||||
volumes:
|
||||
- "~{{unpriv_user}}/{{item.name}}-src:/usr/local/src/{{item.name}}:rw"
|
||||
state: started
|
||||
detach: False
|
||||
cleanup: True
|
||||
user: "{{getent_passwd[unpriv_user][1]}}:{{getent_passwd[unpriv_user][2]}}"
|
||||
entrypoint: ""
|
||||
command: |
|
||||
bash -c 'HOME=/tmp pip3 install --editable /usr/local/src/{{item.name}}'
|
||||
with_items:
|
||||
- name: cobald
|
||||
run: "{{cobald_git_pull.changed}}"
|
||||
- name: tardis
|
||||
run: "{{tardis_git_pull.changed}}"
|
||||
when: item.run
|
||||
|
||||
- docker_container:
|
||||
name: cobald
|
||||
image: cobald
|
||||
hostname: cobald
|
||||
domainname: cobald.local
|
||||
volumes:
|
||||
- "~{{unpriv_user}}/cobald:/etc/cobald"
|
||||
# - /container/volumes/cobald:/etc/cobald:ro
|
||||
- "~{{unpriv_user}}/cobald/modules:/usr/local/src/cobaldmodules"
|
||||
- "~{{unpriv_user}}/cobald-src:/usr/local/src/cobald:ro"
|
||||
- "~{{unpriv_user}}/tardis-src:/usr/local/src/tardis:ro"
|
||||
networks:
|
||||
- name: "{{docker_network}}"
|
||||
state: started
|
||||
detach: True
|
||||
cleanup: True
|
||||
interactive: True
|
||||
command: /bin/bash
|
62
roles/cobald/tasks/telegraf.yml
Normal file
62
roles/cobald/tasks/telegraf.yml
Normal file
@@ -0,0 +1,62 @@
|
||||
- file:
|
||||
path: "/container/{{item}}/telegraf/"
|
||||
state: directory
|
||||
owner: "{{unpriv_user}}"
|
||||
group: docker
|
||||
loop:
|
||||
- docker-images
|
||||
- volumes
|
||||
|
||||
- copy:
|
||||
src: telegraf.Dockerfile
|
||||
dest: /container/docker-images/telegraf/Dockerfile
|
||||
owner: "{{unpriv_user}}"
|
||||
group: docker
|
||||
register: cobald_cp_telegraf_dockerfile
|
||||
|
||||
- copy: # telegraf is found in influxdb repo
|
||||
src: influxdb.repo
|
||||
dest: /container/docker-images/telegraf/influxdb.repo
|
||||
owner: "{{unpriv_user}}"
|
||||
group: docker
|
||||
|
||||
- docker_image:
|
||||
name: "ed-telegraf"
|
||||
build:
|
||||
pull: False
|
||||
path: "/container/docker-images/telegraf/"
|
||||
source: build
|
||||
force_source: "{{cobald_cp_telegraf_dockerfile.changed}}"
|
||||
|
||||
- block:
|
||||
- import_tasks: influxdb.yml
|
||||
tags: influxdb
|
||||
|
||||
- template:
|
||||
src: telegraf.conf.j2
|
||||
dest: /container/volumes/telegraf/telegraf.conf
|
||||
owner: "{{unpriv_user}}"
|
||||
group: docker
|
||||
vars:
|
||||
# influx_url: "http://{{influx_hostname}}.{{influx_domainname}}:8086"
|
||||
influx_url: "http://{{influx_hostname}}:8086"
|
||||
influx_token: "{{influx_telegraf_token.token}}"
|
||||
vars:
|
||||
influx_hostname: "ed-influxdb"
|
||||
influx_domainname: "cobald.local"
|
||||
influx_bucket: batleth
|
||||
|
||||
- docker_container:
|
||||
name: ed-telegraf
|
||||
image: ed-telegraf
|
||||
hostname: telegraf
|
||||
domainname: cobald.local
|
||||
networks:
|
||||
- name: "{{docker_network | default('bridge') }}"
|
||||
volumes:
|
||||
- "/container/volumes/telegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro"
|
||||
state: started
|
||||
detach: True
|
||||
# cleanup: True
|
||||
networks_cli_compatible: True
|
||||
|
1829
roles/cobald/templates/telegraf.conf.j2
Normal file
1829
roles/cobald/templates/telegraf.conf.j2
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user