From 9931829d0309d74989730a2e3f43d4b8774b17fb Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Fri, 16 Jan 2026 19:33:02 -0800 Subject: [PATCH] Add pre-commit hooks for code quality (#19) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Add pre-commit framework with hooks for YAML, Ansible, Python, shell, TOML, JSON, and secret detection - Fix all 91+ ansible-lint violations (variable naming, handler capitalization, changed_when) - Fix shellcheck warnings in mise-tasks scripts - Document pre-commit setup in README.md ## Deployment and Testing - [x] All pre-commit hooks pass (`uvx pre-commit run --all-files`) - [x] Test ansible playbook with `--check` mode - [x] Run `mise run indri-services-check` after deploy 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: https://forge.tail8d86e.ts.net/eblume/blumeops/pulls/19 --- .ansible-lint | 19 + .claude/settings.json | 2 +- .gitignore | 9 + .pre-commit-config.yaml | 82 +++ .yamllint.yaml | 29 + README.md | 25 + ansible/inventory/hosts.yml | 1 + ansible/playbooks/indri.yml | 4 +- ansible/roles/alloy/handlers/main.yml | 3 +- ansible/roles/alloy/tasks/main.yml | 12 +- ansible/roles/borgmatic/handlers/main.yml | 3 +- ansible/roles/borgmatic/tasks/main.yml | 7 +- ansible/roles/devpi/handlers/main.yml | 3 +- ansible/roles/devpi/tasks/main.yml | 7 +- ansible/roles/devpi_metrics/handlers/main.yml | 3 +- ansible/roles/devpi_metrics/tasks/main.yml | 7 +- ansible/roles/forgejo/handlers/main.yml | 3 +- ansible/roles/forgejo/tasks/main.yml | 7 +- .../roles/grafana/files/dashboards/devpi.json | 123 ++-- .../roles/grafana/files/dashboards/loki.json | 36 +- .../files/dashboards/node-exporter-macos.json | 660 +++++++++++------- .../roles/grafana/files/dashboards/plex.json | 142 ++-- .../grafana/files/dashboards/postgresql.json | 32 +- .../files/dashboards/transmission.json | 142 ++-- ansible/roles/grafana/handlers/main.yml | 3 +- ansible/roles/grafana/tasks/main.yml | 12 +- ansible/roles/kiwix/handlers/main.yml | 3 +- ansible/roles/kiwix/tasks/main.yml | 41 +- ansible/roles/loki/handlers/main.yml | 3 +- ansible/roles/loki/tasks/main.yml | 6 +- ansible/roles/miniflux/handlers/main.yml | 3 +- ansible/roles/miniflux/tasks/main.yml | 6 +- ansible/roles/node_exporter/handlers/main.yml | 5 +- ansible/roles/node_exporter/tasks/main.yml | 6 +- ansible/roles/plex_metrics/defaults/main.yml | 4 +- ansible/roles/plex_metrics/handlers/main.yml | 3 +- ansible/roles/plex_metrics/tasks/main.yml | 9 +- .../plex_metrics/templates/plex-metrics.sh.j2 | 4 +- ansible/roles/postgresql/handlers/main.yml | 3 +- ansible/roles/postgresql/tasks/main.yml | 70 +- ansible/roles/prometheus/handlers/main.yml | 3 +- ansible/roles/prometheus/tasks/main.yml | 8 +- .../roles/tailscale_serve/defaults/main.yml | 2 +- ansible/roles/tailscale_serve/tasks/main.yml | 24 +- ansible/roles/transmission/handlers/main.yml | 3 +- ansible/roles/transmission/tasks/main.yml | 12 +- .../transmission_metrics/defaults/main.yml | 6 +- .../transmission_metrics/handlers/main.yml | 3 +- .../roles/transmission_metrics/tasks/main.yml | 9 +- .../templates/transmission-metrics.plist.j2 | 4 +- .../templates/transmission-metrics.sh.j2 | 2 +- mise-tasks/indri-services-check | 1 - mise-tasks/tailnet-preview | 6 +- mise-tasks/tailnet-up | 6 +- pulumi/Pulumi.tail8d86e.yaml | 1 + pulumi/Pulumi.yaml | 1 + pulumi/pyproject.toml | 5 +- 57 files changed, 1013 insertions(+), 625 deletions(-) create mode 100644 .ansible-lint create mode 100644 .pre-commit-config.yaml create mode 100644 .yamllint.yaml diff --git a/.ansible-lint b/.ansible-lint new file mode 100644 index 0000000..e6dbacf --- /dev/null +++ b/.ansible-lint @@ -0,0 +1,19 @@ +--- +# Ansible-lint configuration + +# Set profile to production for stricter checking +profile: production + +# Exclude paths +exclude_paths: + - .venv/ + - pulumi/.venv/ + +# Make ansible-lint aware of project structure +project_dir: ansible + +# Skip some rules that are too noisy for this project +skip_list: + - galaxy # Don't require galaxy metadata in roles + - yaml[line-length] # Don't enforce line length limits + - no-handler # Some tasks intentionally run conditionally, not as handlers diff --git a/.claude/settings.json b/.claude/settings.json index ffcd441..0967ef4 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -1 +1 @@ -{ } +{} diff --git a/.gitignore b/.gitignore index d6b130c..f6fe9e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,10 @@ .claude/settings.local.json + +# Python +__pycache__/ +*.py[cod] +*.pyo +.venv/ + +# OS +.DS_Store diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..c631dda --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,82 @@ +--- +# See https://pre-commit.com for more information +# Run: uvx pre-commit run --all-files +# Install: uvx pre-commit install + +repos: + # General file hygiene + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-added-large-files + args: ['--maxkb=1000'] + - id: check-merge-conflict + - id: check-json + - id: check-yaml + args: ['--unsafe'] # Allow custom tags (ansible uses them) + - id: check-toml + + # Secret detection + - repo: https://github.com/trufflesecurity/trufflehog + rev: v3.92.5 + hooks: + - id: trufflehog + entry: trufflehog git file://. --since-commit HEAD --no-verification --fail + stages: [pre-commit, pre-push] + + # YAML linting + - repo: https://github.com/adrienverge/yamllint + rev: v1.38.0 + hooks: + - id: yamllint + args: ['-c', '.yamllint.yaml'] + + # Ansible linting + - repo: local + hooks: + - id: ansible-lint + name: ansible-lint + entry: env ANSIBLE_ROLES_PATH=ansible/roles ansible-lint + language: python + files: ^ansible/ + additional_dependencies: + - ansible-lint>=26.1.1 + - ansible-core>=2.15 + + # Python - ruff for linting and formatting + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.14.13 + hooks: + - id: ruff + args: ['--fix'] + - id: ruff-format + + # Shell scripts - shellcheck and shfmt + - repo: https://github.com/shellcheck-py/shellcheck-py + rev: v0.10.0.1 + hooks: + - id: shellcheck + args: ['--severity=warning'] + + - repo: https://github.com/scop/pre-commit-shfmt + rev: v3.12.0-2 + hooks: + - id: shfmt + args: ['-i', '2', '-ci', '-bn'] # 2-space indent, case indent, binary newline + + # TOML - taplo + - repo: https://github.com/ComPWA/taplo-pre-commit + rev: v0.9.3 + hooks: + - id: taplo-format + - id: taplo-lint + + # JSON formatting (prettier for consistent style) + - repo: https://github.com/rbubley/mirrors-prettier + rev: v3.8.0 + hooks: + - id: prettier + types_or: [json] + args: ['--tab-width', '2'] diff --git a/.yamllint.yaml b/.yamllint.yaml new file mode 100644 index 0000000..81338de --- /dev/null +++ b/.yamllint.yaml @@ -0,0 +1,29 @@ +--- +extends: default + +rules: + line-length: + max: 120 + level: warning + truthy: + allowed-values: ['true', 'false', 'yes', 'no'] + comments: + min-spaces-from-content: 1 + braces: + min-spaces-inside: 0 + max-spaces-inside: 1 + brackets: + min-spaces-inside: 0 + max-spaces-inside: 0 + indentation: + spaces: 2 + indent-sequences: consistent + # Required for ansible-lint compatibility + comments-indentation: false + octal-values: + forbid-implicit-octal: true + forbid-explicit-octal: true + +ignore: + - .venv/ + - pulumi/.venv/ diff --git a/README.md b/README.md index a53df17..7da378f 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,31 @@ LLM-assisted development. I want to include a personal note here that I don't know entirely how I feel about LLMs in our current era, but it felt important to learn. +## Development + +### Pre-commit Hooks + +This repo uses [pre-commit](https://pre-commit.com) for code quality and consistency. Install hooks with: + +```bash +uvx pre-commit install +``` + +Run all hooks manually: + +```bash +uvx pre-commit run --all-files +``` + +Hooks include: +- **General**: trailing whitespace, end-of-file fixer, large files, merge conflicts +- **Secrets**: [TruffleHog](https://github.com/trufflesecurity/trufflehog) for secret detection +- **YAML**: yamllint, ansible-lint +- **Python**: ruff (linting + formatting) +- **Shell**: shellcheck, shfmt +- **TOML**: taplo +- **JSON**: prettier + ## Documentation Detailed documentation lives in my personal zettelkasten, which is not included in this repository. You can view the docs with: diff --git a/ansible/inventory/hosts.yml b/ansible/inventory/hosts.yml index 645c67a..b69f7a0 100644 --- a/ansible/inventory/hosts.yml +++ b/ansible/inventory/hosts.yml @@ -1,3 +1,4 @@ +--- all: children: servers: diff --git a/ansible/playbooks/indri.yml b/ansible/playbooks/indri.yml index c198ac8..0759ab6 100644 --- a/ansible/playbooks/indri.yml +++ b/ansible/playbooks/indri.yml @@ -19,7 +19,7 @@ - name: Set PostgreSQL superuser password fact ansible.builtin.set_fact: - pg_superuser_password: "{{ _pg_superuser_pw.stdout }}" + postgresql_superuser_password: "{{ _pg_superuser_pw.stdout }}" no_log: true tags: [postgresql] @@ -67,7 +67,7 @@ - name: Build PostgreSQL user password lookup ansible.builtin.set_fact: - pg_user_passwords: + postgresql_user_passwords: miniflux: "{{ _miniflux_db_pw.stdout }}" borgmatic: "{{ _borgmatic_db_pw.stdout }}" alloy: "{{ _pg_alloy_pw.stdout }}" diff --git a/ansible/roles/alloy/handlers/main.yml b/ansible/roles/alloy/handlers/main.yml index 9fc6e85..5948838 100644 --- a/ansible/roles/alloy/handlers/main.yml +++ b/ansible/roles/alloy/handlers/main.yml @@ -1,5 +1,6 @@ --- -- name: restart alloy +- name: Restart alloy ansible.builtin.command: brew services restart grafana-alloy async: 120 poll: 0 + changed_when: true diff --git a/ansible/roles/alloy/tasks/main.yml b/ansible/roles/alloy/tasks/main.yml index 4fb6225..644a6b2 100644 --- a/ansible/roles/alloy/tasks/main.yml +++ b/ansible/roles/alloy/tasks/main.yml @@ -31,7 +31,9 @@ - name: Fetch PostgreSQL metrics password from 1Password ansible.builtin.command: - cmd: op --vault {{ alloy_op_vault }} item get {{ alloy_op_postgres_item }} --fields {{ alloy_op_postgres_field }} --reveal + cmd: >- + op --vault {{ alloy_op_vault }} item get {{ alloy_op_postgres_item }} + --fields {{ alloy_op_postgres_field }} --reveal delegate_to: localhost register: alloy_postgres_password_result changed_when: false @@ -55,7 +57,7 @@ src: postgres_queries.yaml.j2 dest: "{{ alloy_config_dir }}/postgres_queries.yaml" mode: '0600' - notify: restart alloy + notify: Restart alloy when: alloy_collect_postgres | default(false) - name: Deploy alloy configuration @@ -63,11 +65,11 @@ src: config.alloy.j2 dest: "{{ alloy_config_dir }}/config.alloy" mode: '0600' - notify: restart alloy + notify: Restart alloy no_log: true - name: Ensure alloy service is started ansible.builtin.command: brew services start grafana-alloy - register: brew_start - changed_when: "'Successfully started' in brew_start.stdout" + register: alloy_brew_start + changed_when: "'Successfully started' in alloy_brew_start.stdout" failed_when: false diff --git a/ansible/roles/borgmatic/handlers/main.yml b/ansible/roles/borgmatic/handlers/main.yml index da0ce60..5fd6174 100644 --- a/ansible/roles/borgmatic/handlers/main.yml +++ b/ansible/roles/borgmatic/handlers/main.yml @@ -1,5 +1,6 @@ --- -- name: reload borgmatic +- name: Reload borgmatic ansible.builtin.shell: | launchctl unload ~/Library/LaunchAgents/mcquack.eblume.borgmatic.plist 2>/dev/null || true launchctl load ~/Library/LaunchAgents/mcquack.eblume.borgmatic.plist + changed_when: true diff --git a/ansible/roles/borgmatic/tasks/main.yml b/ansible/roles/borgmatic/tasks/main.yml index db0704d..aff9a6b 100644 --- a/ansible/roles/borgmatic/tasks/main.yml +++ b/ansible/roles/borgmatic/tasks/main.yml @@ -19,15 +19,16 @@ src: borgmatic.plist.j2 dest: ~/Library/LaunchAgents/mcquack.eblume.borgmatic.plist mode: '0644' - notify: reload borgmatic + notify: Reload borgmatic - name: Check if borgmatic LaunchAgent is loaded ansible.builtin.command: launchctl list mcquack.eblume.borgmatic - register: launchctl_check + register: borgmatic_launchctl_check changed_when: false failed_when: false - name: Load borgmatic LaunchAgent if not loaded ansible.builtin.command: launchctl load ~/Library/LaunchAgents/mcquack.eblume.borgmatic.plist - when: launchctl_check.rc != 0 + when: borgmatic_launchctl_check.rc != 0 + changed_when: true failed_when: false diff --git a/ansible/roles/devpi/handlers/main.yml b/ansible/roles/devpi/handlers/main.yml index 788895e..7e29c43 100644 --- a/ansible/roles/devpi/handlers/main.yml +++ b/ansible/roles/devpi/handlers/main.yml @@ -1,5 +1,6 @@ --- -- name: reload devpi +- name: Reload devpi ansible.builtin.shell: | launchctl unload ~/Library/LaunchAgents/mcquack.eblume.devpi.plist 2>/dev/null || true launchctl load ~/Library/LaunchAgents/mcquack.eblume.devpi.plist + changed_when: true diff --git a/ansible/roles/devpi/tasks/main.yml b/ansible/roles/devpi/tasks/main.yml index b35989c..2c6d03e 100644 --- a/ansible/roles/devpi/tasks/main.yml +++ b/ansible/roles/devpi/tasks/main.yml @@ -40,15 +40,16 @@ src: devpi.plist.j2 dest: ~/Library/LaunchAgents/mcquack.eblume.devpi.plist mode: '0644' - notify: reload devpi + notify: Reload devpi - name: Check if devpi LaunchAgent is loaded ansible.builtin.command: launchctl list mcquack.eblume.devpi - register: launchctl_check + register: devpi_launchctl_check changed_when: false failed_when: false - name: Load devpi LaunchAgent if not loaded ansible.builtin.command: launchctl load ~/Library/LaunchAgents/mcquack.eblume.devpi.plist - when: launchctl_check.rc != 0 + when: devpi_launchctl_check.rc != 0 + changed_when: true failed_when: false diff --git a/ansible/roles/devpi_metrics/handlers/main.yml b/ansible/roles/devpi_metrics/handlers/main.yml index c37757b..81bfd1d 100644 --- a/ansible/roles/devpi_metrics/handlers/main.yml +++ b/ansible/roles/devpi_metrics/handlers/main.yml @@ -1,5 +1,6 @@ --- -- name: reload devpi-metrics +- name: Reload devpi-metrics ansible.builtin.shell: | launchctl unload ~/Library/LaunchAgents/mcquack.eblume.devpi-metrics.plist 2>/dev/null || true launchctl load ~/Library/LaunchAgents/mcquack.eblume.devpi-metrics.plist + changed_when: true diff --git a/ansible/roles/devpi_metrics/tasks/main.yml b/ansible/roles/devpi_metrics/tasks/main.yml index e680641..b267648 100644 --- a/ansible/roles/devpi_metrics/tasks/main.yml +++ b/ansible/roles/devpi_metrics/tasks/main.yml @@ -22,15 +22,16 @@ src: devpi-metrics.plist.j2 dest: ~/Library/LaunchAgents/mcquack.eblume.devpi-metrics.plist mode: '0644' - notify: reload devpi-metrics + notify: Reload devpi-metrics - name: Check if devpi-metrics LaunchAgent is loaded ansible.builtin.command: launchctl list mcquack.eblume.devpi-metrics - register: launchctl_check + register: devpi_metrics_launchctl_check changed_when: false failed_when: false - name: Load devpi-metrics LaunchAgent if not loaded ansible.builtin.command: launchctl load ~/Library/LaunchAgents/mcquack.eblume.devpi-metrics.plist - when: launchctl_check.rc != 0 + when: devpi_metrics_launchctl_check.rc != 0 + changed_when: true failed_when: false diff --git a/ansible/roles/forgejo/handlers/main.yml b/ansible/roles/forgejo/handlers/main.yml index 313df92..dc67cbc 100644 --- a/ansible/roles/forgejo/handlers/main.yml +++ b/ansible/roles/forgejo/handlers/main.yml @@ -1,3 +1,4 @@ --- -- name: restart forgejo +- name: Restart forgejo ansible.builtin.command: brew services restart forgejo + changed_when: true diff --git a/ansible/roles/forgejo/tasks/main.yml b/ansible/roles/forgejo/tasks/main.yml index 0f45c2e..1e021c4 100644 --- a/ansible/roles/forgejo/tasks/main.yml +++ b/ansible/roles/forgejo/tasks/main.yml @@ -18,11 +18,12 @@ Forgejo config not found at /opt/homebrew/var/forgejo/custom/conf/app.ini This file contains secrets and is not managed by ansible. To restore from backup, run: - borgmatic --config ~/.config/borgmatic/config.yaml extract --archive latest --path /opt/homebrew/var/forgejo/custom/conf/app.ini + borgmatic --config ~/.config/borgmatic/config.yaml extract --archive latest \ + --path /opt/homebrew/var/forgejo/custom/conf/app.ini when: not forgejo_config.stat.exists - name: Ensure forgejo service is started ansible.builtin.command: brew services start forgejo - register: brew_start - changed_when: "'Successfully started' in brew_start.stdout" + register: forgejo_brew_start + changed_when: "'Successfully started' in forgejo_brew_start.stdout" failed_when: false diff --git a/ansible/roles/grafana/files/dashboards/devpi.json b/ansible/roles/grafana/files/dashboards/devpi.json index a317380..c2cf540 100644 --- a/ansible/roles/grafana/files/dashboards/devpi.json +++ b/ansible/roles/grafana/files/dashboards/devpi.json @@ -22,15 +22,15 @@ "thresholds": { "mode": "absolute", "steps": [ - {"color": "red", "value": null}, - {"color": "green", "value": 1} + { "color": "red", "value": null }, + { "color": "green", "value": 1 } ] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 0, "y": 0}, + "gridPos": { "h": 4, "w": 4, "x": 0, "y": 0 }, "id": 1, "options": { "colorMode": "value", @@ -47,7 +47,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "devpi_up", "refId": "A" } @@ -69,16 +69,16 @@ "thresholds": { "mode": "absolute", "steps": [ - {"color": "green", "value": null}, - {"color": "yellow", "value": 100}, - {"color": "red", "value": 1000} + { "color": "green", "value": null }, + { "color": "yellow", "value": 100 }, + { "color": "red", "value": 1000 } ] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 4, "y": 0}, + "gridPos": { "h": 4, "w": 4, "x": 4, "y": 0 }, "id": 2, "options": { "colorMode": "value", @@ -95,7 +95,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "devpi_web_whoosh_index_queue_size", "refId": "A" } @@ -116,15 +116,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "green", "value": null} - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 8, "y": 0}, + "gridPos": { "h": 4, "w": 4, "x": 8, "y": 0 }, "id": 3, "options": { "colorMode": "value", @@ -141,7 +139,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "devpi_serial", "refId": "A" } @@ -169,44 +167,47 @@ "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", - "hideFrom": {"legend": false, "tooltip": false, "viz": false}, + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, - "scaleDistribution": {"type": "linear"}, + "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, - "stacking": {"group": "A", "mode": "none"}, - "thresholdsStyle": {"mode": "off"} + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "green", "value": null} - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 8, "w": 12, "x": 0, "y": 4}, + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 4 }, "id": 4, "options": { - "legend": {"calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true}, - "tooltip": {"mode": "single", "sort": "none"} + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { "mode": "single", "sort": "none" } }, "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(devpi_server_storage_cache_hits[5m])", "legendFormat": "Storage Cache Hits", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(devpi_server_storage_cache_misses[5m])", "legendFormat": "Storage Cache Misses", "refId": "B" @@ -235,44 +236,47 @@ "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", - "hideFrom": {"legend": false, "tooltip": false, "viz": false}, + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, - "scaleDistribution": {"type": "linear"}, + "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, - "stacking": {"group": "A", "mode": "none"}, - "thresholdsStyle": {"mode": "off"} + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "green", "value": null} - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 8, "w": 12, "x": 12, "y": 4}, + "gridPos": { "h": 8, "w": 12, "x": 12, "y": 4 }, "id": 5, "options": { - "legend": {"calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true}, - "tooltip": {"mode": "single", "sort": "none"} + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { "mode": "single", "sort": "none" } }, "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(devpi_server_changelog_cache_hits[5m])", "legendFormat": "Changelog Cache Hits", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(devpi_server_changelog_cache_misses[5m])", "legendFormat": "Changelog Cache Misses", "refId": "B" @@ -301,44 +305,47 @@ "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", - "hideFrom": {"legend": false, "tooltip": false, "viz": false}, + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "insertNulls": false, "lineInterpolation": "linear", "lineWidth": 1, "pointSize": 5, - "scaleDistribution": {"type": "linear"}, + "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, - "stacking": {"group": "A", "mode": "none"}, - "thresholdsStyle": {"mode": "off"} + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "green", "value": null} - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 8, "w": 12, "x": 0, "y": 12}, + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 12 }, "id": 6, "options": { - "legend": {"calcs": [], "displayMode": "list", "placement": "bottom", "showLegend": true}, - "tooltip": {"mode": "single", "sort": "none"} + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { "mode": "single", "sort": "none" } }, "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "devpi_web_whoosh_index_queue_size", "legendFormat": "Index Queue Size", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "devpi_web_whoosh_index_error_queue_size", "legendFormat": "Index Error Queue Size", "refId": "B" @@ -360,15 +367,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "green", "value": null} - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 8, "w": 12, "x": 12, "y": 12}, + "gridPos": { "h": 8, "w": 12, "x": 12, "y": 12 }, "id": 7, "options": { "colorMode": "value", @@ -385,31 +390,31 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "devpi_server_storage_cache_size", "legendFormat": "Storage Cache Size", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "devpi_server_changelog_cache_size", "legendFormat": "Changelog Cache Size", "refId": "B" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "devpi_server_changelog_cache_items", "legendFormat": "Changelog Cache Items", "refId": "C" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "devpi_server_relpath_cache_size", "legendFormat": "Relpath Cache Size", "refId": "D" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "devpi_server_relpath_cache_items", "legendFormat": "Relpath Cache Items", "refId": "E" diff --git a/ansible/roles/grafana/files/dashboards/loki.json b/ansible/roles/grafana/files/dashboards/loki.json index 2968917..a6169db 100644 --- a/ansible/roles/grafana/files/dashboards/loki.json +++ b/ansible/roles/grafana/files/dashboards/loki.json @@ -69,9 +69,7 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - { "color": "green", "value": null } - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" }, @@ -115,9 +113,7 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - { "color": "green", "value": null } - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" }, @@ -239,7 +235,12 @@ "gridPos": { "h": 8, "w": 12, "x": 0, "y": 4 }, "id": 5, "options": { - "legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true }, + "legend": { + "calcs": ["mean", "max"], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, "tooltip": { "mode": "multi", "sort": "desc" } }, "pluginVersion": "10.0.0", @@ -303,7 +304,12 @@ "gridPos": { "h": 8, "w": 12, "x": 12, "y": 4 }, "id": 6, "options": { - "legend": { "calcs": ["mean", "max"], "displayMode": "table", "placement": "bottom", "showLegend": true }, + "legend": { + "calcs": ["mean", "max"], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, "tooltip": { "mode": "multi", "sort": "desc" } }, "pluginVersion": "10.0.0", @@ -361,7 +367,12 @@ "gridPos": { "h": 8, "w": 12, "x": 0, "y": 12 }, "id": 7, "options": { - "legend": { "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true }, + "legend": { + "calcs": ["lastNotNull"], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, "tooltip": { "mode": "multi", "sort": "desc" } }, "pluginVersion": "10.0.0", @@ -425,7 +436,12 @@ "gridPos": { "h": 8, "w": 12, "x": 12, "y": 12 }, "id": 8, "options": { - "legend": { "calcs": ["sum"], "displayMode": "table", "placement": "bottom", "showLegend": true }, + "legend": { + "calcs": ["sum"], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, "tooltip": { "mode": "multi", "sort": "desc" } }, "pluginVersion": "10.0.0", diff --git a/ansible/roles/grafana/files/dashboards/node-exporter-macos.json b/ansible/roles/grafana/files/dashboards/node-exporter-macos.json index c4f19de..c481112 100644 --- a/ansible/roles/grafana/files/dashboards/node-exporter-macos.json +++ b/ansible/roles/grafana/files/dashboards/node-exporter-macos.json @@ -10,39 +10,43 @@ "panels": [ { "collapsed": false, - "gridPos": {"h": 1, "w": 24, "x": 0, "y": 0}, + "gridPos": { "h": 1, "w": 24, "x": 0, "y": 0 }, "id": 100, "panels": [], "title": "Overview", "type": "row" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "thresholds"}, + "color": { "mode": "thresholds" }, "mappings": [], "thresholds": { "mode": "absolute", - "steps": [{"color": "green", "value": null}] + "steps": [{ "color": "green", "value": null }] }, "unit": "dtdurations" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 0, "y": 1}, + "gridPos": { "h": 4, "w": 4, "x": 0, "y": 1 }, "id": 1, "options": { "colorMode": "value", "graphMode": "none", "justifyMode": "auto", "orientation": "auto", - "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, "textMode": "auto" }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "time() - node_boot_time_seconds{instance=~\"$instance\"}", "refId": "A" } @@ -51,32 +55,36 @@ "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "thresholds"}, + "color": { "mode": "thresholds" }, "mappings": [], "thresholds": { "mode": "absolute", - "steps": [{"color": "blue", "value": null}] + "steps": [{ "color": "blue", "value": null }] }, "unit": "decbytes" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 4, "y": 1}, + "gridPos": { "h": 4, "w": 4, "x": 4, "y": 1 }, "id": 2, "options": { "colorMode": "value", "graphMode": "none", "justifyMode": "auto", "orientation": "auto", - "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, "textMode": "auto" }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "node_memory_total_bytes{instance=~\"$instance\"} or node_memory_MemTotal_bytes{instance=~\"$instance\"}", "refId": "A" } @@ -85,32 +93,36 @@ "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "thresholds"}, + "color": { "mode": "thresholds" }, "mappings": [], "thresholds": { "mode": "absolute", - "steps": [{"color": "purple", "value": null}] + "steps": [{ "color": "purple", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 8, "y": 1}, + "gridPos": { "h": 4, "w": 4, "x": 8, "y": 1 }, "id": 3, "options": { "colorMode": "value", "graphMode": "none", "justifyMode": "auto", "orientation": "auto", - "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, "textMode": "auto" }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "count(node_cpu_seconds_total{instance=~\"$instance\", mode=\"idle\"})", "refId": "A" } @@ -119,17 +131,17 @@ "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "thresholds"}, + "color": { "mode": "thresholds" }, "mappings": [], "thresholds": { "mode": "absolute", "steps": [ - {"color": "green", "value": null}, - {"color": "yellow", "value": 4}, - {"color": "red", "value": 8} + { "color": "green", "value": null }, + { "color": "yellow", "value": 4 }, + { "color": "red", "value": 8 } ] }, "unit": "short", @@ -137,19 +149,23 @@ }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 12, "y": 1}, + "gridPos": { "h": 4, "w": 4, "x": 12, "y": 1 }, "id": 4, "options": { "colorMode": "value", "graphMode": "area", "justifyMode": "auto", "orientation": "auto", - "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, "textMode": "auto" }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "node_load1{instance=~\"$instance\"}", "refId": "A" } @@ -158,17 +174,17 @@ "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "thresholds"}, + "color": { "mode": "thresholds" }, "mappings": [], "thresholds": { "mode": "absolute", "steps": [ - {"color": "green", "value": null}, - {"color": "yellow", "value": 4}, - {"color": "red", "value": 8} + { "color": "green", "value": null }, + { "color": "yellow", "value": 4 }, + { "color": "red", "value": 8 } ] }, "unit": "short", @@ -176,19 +192,23 @@ }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 16, "y": 1}, + "gridPos": { "h": 4, "w": 4, "x": 16, "y": 1 }, "id": 5, "options": { "colorMode": "value", "graphMode": "area", "justifyMode": "auto", "orientation": "auto", - "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, "textMode": "auto" }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "node_load5{instance=~\"$instance\"}", "refId": "A" } @@ -197,17 +217,17 @@ "type": "stat" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "thresholds"}, + "color": { "mode": "thresholds" }, "mappings": [], "thresholds": { "mode": "absolute", "steps": [ - {"color": "green", "value": null}, - {"color": "yellow", "value": 4}, - {"color": "red", "value": 8} + { "color": "green", "value": null }, + { "color": "yellow", "value": 4 }, + { "color": "red", "value": 8 } ] }, "unit": "short", @@ -215,19 +235,23 @@ }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 20, "y": 1}, + "gridPos": { "h": 4, "w": 4, "x": 20, "y": 1 }, "id": 6, "options": { "colorMode": "value", "graphMode": "area", "justifyMode": "auto", "orientation": "auto", - "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, "textMode": "auto" }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "node_load15{instance=~\"$instance\"}", "refId": "A" } @@ -237,17 +261,17 @@ }, { "collapsed": false, - "gridPos": {"h": 1, "w": 24, "x": 0, "y": 5}, + "gridPos": { "h": 1, "w": 24, "x": 0, "y": 5 }, "id": 101, "panels": [], "title": "CPU", "type": "row" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "palette-classic"}, + "color": { "mode": "palette-classic" }, "custom": { "axisBorderShow": false, "axisCenteredZero": false, @@ -258,54 +282,79 @@ "drawStyle": "line", "fillOpacity": 30, "gradientMode": "opacity", - "hideFrom": {"legend": false, "tooltip": false, "viz": false}, + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "insertNulls": false, "lineInterpolation": "smooth", "lineWidth": 1, "pointSize": 5, - "scaleDistribution": {"type": "linear"}, + "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, - "stacking": {"group": "A", "mode": "normal"}, - "thresholdsStyle": {"mode": "off"} + "stacking": { "group": "A", "mode": "normal" }, + "thresholdsStyle": { "mode": "off" } }, "mappings": [], "max": 100, "min": 0, "thresholds": { "mode": "absolute", - "steps": [{"color": "green", "value": null}] + "steps": [{ "color": "green", "value": null }] }, "unit": "percent" }, "overrides": [ { - "matcher": {"id": "byName", "options": "user"}, - "properties": [{"id": "color", "value": {"fixedColor": "blue", "mode": "fixed"}}] + "matcher": { "id": "byName", "options": "user" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "blue", "mode": "fixed" } + } + ] }, { - "matcher": {"id": "byName", "options": "system"}, - "properties": [{"id": "color", "value": {"fixedColor": "orange", "mode": "fixed"}}] + "matcher": { "id": "byName", "options": "system" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "orange", "mode": "fixed" } + } + ] }, { - "matcher": {"id": "byName", "options": "nice"}, - "properties": [{"id": "color", "value": {"fixedColor": "green", "mode": "fixed"}}] + "matcher": { "id": "byName", "options": "nice" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "green", "mode": "fixed" } + } + ] }, { - "matcher": {"id": "byName", "options": "iowait"}, - "properties": [{"id": "color", "value": {"fixedColor": "red", "mode": "fixed"}}] + "matcher": { "id": "byName", "options": "iowait" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "red", "mode": "fixed" } + } + ] } ] }, - "gridPos": {"h": 8, "w": 12, "x": 0, "y": 6}, + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 6 }, "id": 10, "options": { - "legend": {"calcs": ["mean", "lastNotNull"], "displayMode": "table", "placement": "right", "showLegend": true}, - "tooltip": {"mode": "multi", "sort": "desc"} + "legend": { + "calcs": ["mean", "lastNotNull"], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { "mode": "multi", "sort": "desc" } }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "avg by (mode) (rate(node_cpu_seconds_total{instance=~\"$instance\", mode!=\"idle\"}[5m])) * 100", "legendFormat": "{{mode}}", "refId": "A" @@ -315,10 +364,10 @@ "type": "timeseries" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "palette-classic"}, + "color": { "mode": "palette-classic" }, "custom": { "axisBorderShow": false, "axisCenteredZero": false, @@ -329,60 +378,80 @@ "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", - "hideFrom": {"legend": false, "tooltip": false, "viz": false}, + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "insertNulls": false, "lineInterpolation": "smooth", "lineWidth": 2, "pointSize": 5, - "scaleDistribution": {"type": "linear"}, + "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, - "stacking": {"group": "A", "mode": "none"}, - "thresholdsStyle": {"mode": "off"} + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", - "steps": [{"color": "green", "value": null}] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" }, "overrides": [ { - "matcher": {"id": "byName", "options": "1m"}, - "properties": [{"id": "color", "value": {"fixedColor": "red", "mode": "fixed"}}] + "matcher": { "id": "byName", "options": "1m" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "red", "mode": "fixed" } + } + ] }, { - "matcher": {"id": "byName", "options": "5m"}, - "properties": [{"id": "color", "value": {"fixedColor": "orange", "mode": "fixed"}}] + "matcher": { "id": "byName", "options": "5m" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "orange", "mode": "fixed" } + } + ] }, { - "matcher": {"id": "byName", "options": "15m"}, - "properties": [{"id": "color", "value": {"fixedColor": "yellow", "mode": "fixed"}}] + "matcher": { "id": "byName", "options": "15m" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "yellow", "mode": "fixed" } + } + ] } ] }, - "gridPos": {"h": 8, "w": 12, "x": 12, "y": 6}, + "gridPos": { "h": 8, "w": 12, "x": 12, "y": 6 }, "id": 11, "options": { - "legend": {"calcs": ["mean", "max", "lastNotNull"], "displayMode": "table", "placement": "right", "showLegend": true}, - "tooltip": {"mode": "multi", "sort": "desc"} + "legend": { + "calcs": ["mean", "max", "lastNotNull"], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { "mode": "multi", "sort": "desc" } }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "node_load1{instance=~\"$instance\"}", "legendFormat": "1m", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "node_load5{instance=~\"$instance\"}", "legendFormat": "5m", "refId": "B" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "node_load15{instance=~\"$instance\"}", "legendFormat": "15m", "refId": "C" @@ -393,18 +462,18 @@ }, { "collapsed": false, - "gridPos": {"h": 1, "w": 24, "x": 0, "y": 14}, + "gridPos": { "h": 1, "w": 24, "x": 0, "y": 14 }, "id": 102, "panels": [], "title": "Memory (macOS)", "type": "row" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "description": "macOS memory breakdown: Wired (cannot be paged out), Active (recently used), Compressed (compressed in memory), Inactive (not recently used), Free (unused)", "fieldConfig": { "defaults": { - "color": {"mode": "palette-classic"}, + "color": { "mode": "palette-classic" }, "custom": { "axisBorderShow": false, "axisCenteredZero": false, @@ -415,80 +484,110 @@ "drawStyle": "line", "fillOpacity": 30, "gradientMode": "opacity", - "hideFrom": {"legend": false, "tooltip": false, "viz": false}, + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "insertNulls": false, "lineInterpolation": "smooth", "lineWidth": 1, "pointSize": 5, - "scaleDistribution": {"type": "linear"}, + "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, - "stacking": {"group": "A", "mode": "normal"}, - "thresholdsStyle": {"mode": "off"} + "stacking": { "group": "A", "mode": "normal" }, + "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", - "steps": [{"color": "green", "value": null}] + "steps": [{ "color": "green", "value": null }] }, "unit": "bytes" }, "overrides": [ { - "matcher": {"id": "byName", "options": "Wired"}, - "properties": [{"id": "color", "value": {"fixedColor": "red", "mode": "fixed"}}] + "matcher": { "id": "byName", "options": "Wired" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "red", "mode": "fixed" } + } + ] }, { - "matcher": {"id": "byName", "options": "Active"}, - "properties": [{"id": "color", "value": {"fixedColor": "orange", "mode": "fixed"}}] + "matcher": { "id": "byName", "options": "Active" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "orange", "mode": "fixed" } + } + ] }, { - "matcher": {"id": "byName", "options": "Compressed"}, - "properties": [{"id": "color", "value": {"fixedColor": "purple", "mode": "fixed"}}] + "matcher": { "id": "byName", "options": "Compressed" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "purple", "mode": "fixed" } + } + ] }, { - "matcher": {"id": "byName", "options": "Inactive"}, - "properties": [{"id": "color", "value": {"fixedColor": "yellow", "mode": "fixed"}}] + "matcher": { "id": "byName", "options": "Inactive" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "yellow", "mode": "fixed" } + } + ] }, { - "matcher": {"id": "byName", "options": "Free"}, - "properties": [{"id": "color", "value": {"fixedColor": "green", "mode": "fixed"}}] + "matcher": { "id": "byName", "options": "Free" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "green", "mode": "fixed" } + } + ] } ] }, - "gridPos": {"h": 8, "w": 12, "x": 0, "y": 15}, + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 15 }, "id": 20, "options": { - "legend": {"calcs": ["mean", "lastNotNull"], "displayMode": "table", "placement": "right", "showLegend": true}, - "tooltip": {"mode": "multi", "sort": "desc"} + "legend": { + "calcs": ["mean", "lastNotNull"], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { "mode": "multi", "sort": "desc" } }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "node_memory_wired_bytes{instance=~\"$instance\"}", "legendFormat": "Wired", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "node_memory_active_bytes{instance=~\"$instance\"}", "legendFormat": "Active", "refId": "B" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "node_memory_compressed_bytes{instance=~\"$instance\"}", "legendFormat": "Compressed", "refId": "C" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "node_memory_inactive_bytes{instance=~\"$instance\"}", "legendFormat": "Inactive", "refId": "D" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "node_memory_free_bytes{instance=~\"$instance\"}", "legendFormat": "Free", "refId": "E" @@ -498,37 +597,41 @@ "type": "timeseries" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "description": "Memory pressure based on (total - free - inactive) / total", "fieldConfig": { "defaults": { - "color": {"mode": "thresholds"}, + "color": { "mode": "thresholds" }, "mappings": [], "max": 100, "min": 0, "thresholds": { "mode": "absolute", "steps": [ - {"color": "green", "value": null}, - {"color": "yellow", "value": 70}, - {"color": "red", "value": 90} + { "color": "green", "value": null }, + { "color": "yellow", "value": 70 }, + { "color": "red", "value": 90 } ] }, "unit": "percent" }, "overrides": [] }, - "gridPos": {"h": 8, "w": 4, "x": 12, "y": 15}, + "gridPos": { "h": 8, "w": 4, "x": 12, "y": 15 }, "id": 21, "options": { "orientation": "auto", - "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, "showThresholdLabels": false, "showThresholdMarkers": true }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "(1 - (node_memory_free_bytes{instance=~\"$instance\"} + node_memory_inactive_bytes{instance=~\"$instance\"}) / node_memory_total_bytes{instance=~\"$instance\"}) * 100", "refId": "A" } @@ -537,10 +640,10 @@ "type": "gauge" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "palette-classic"}, + "color": { "mode": "palette-classic" }, "custom": { "axisBorderShow": false, "axisCenteredZero": false, @@ -551,50 +654,65 @@ "drawStyle": "line", "fillOpacity": 20, "gradientMode": "opacity", - "hideFrom": {"legend": false, "tooltip": false, "viz": false}, + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "insertNulls": false, "lineInterpolation": "smooth", "lineWidth": 2, "pointSize": 5, - "scaleDistribution": {"type": "linear"}, + "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, - "stacking": {"group": "A", "mode": "none"}, - "thresholdsStyle": {"mode": "off"} + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", - "steps": [{"color": "green", "value": null}] + "steps": [{ "color": "green", "value": null }] }, "unit": "bytes" }, "overrides": [ { - "matcher": {"id": "byName", "options": "Used"}, - "properties": [{"id": "color", "value": {"fixedColor": "orange", "mode": "fixed"}}] + "matcher": { "id": "byName", "options": "Used" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "orange", "mode": "fixed" } + } + ] }, { - "matcher": {"id": "byName", "options": "Total"}, - "properties": [{"id": "color", "value": {"fixedColor": "blue", "mode": "fixed"}}] + "matcher": { "id": "byName", "options": "Total" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "blue", "mode": "fixed" } + } + ] } ] }, - "gridPos": {"h": 8, "w": 8, "x": 16, "y": 15}, + "gridPos": { "h": 8, "w": 8, "x": 16, "y": 15 }, "id": 22, "options": { - "legend": {"calcs": ["mean", "lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true}, - "tooltip": {"mode": "multi", "sort": "desc"} + "legend": { + "calcs": ["mean", "lastNotNull"], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { "mode": "multi", "sort": "desc" } }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "node_memory_swap_used_bytes{instance=~\"$instance\"}", "legendFormat": "Used", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "node_memory_swap_total_bytes{instance=~\"$instance\"}", "legendFormat": "Total", "refId": "B" @@ -605,17 +723,17 @@ }, { "collapsed": false, - "gridPos": {"h": 1, "w": 24, "x": 0, "y": 23}, + "gridPos": { "h": 1, "w": 24, "x": 0, "y": 23 }, "id": 103, "panels": [], "title": "Disk", "type": "row" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "palette-classic"}, + "color": { "mode": "palette-classic" }, "custom": { "axisBorderShow": false, "axisCenteredZero": false, @@ -626,50 +744,65 @@ "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", - "hideFrom": {"legend": false, "tooltip": false, "viz": false}, + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "insertNulls": false, "lineInterpolation": "smooth", "lineWidth": 2, "pointSize": 5, - "scaleDistribution": {"type": "linear"}, + "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, - "stacking": {"group": "A", "mode": "none"}, - "thresholdsStyle": {"mode": "off"} + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", - "steps": [{"color": "green", "value": null}] + "steps": [{ "color": "green", "value": null }] }, "unit": "Bps" }, "overrides": [ { - "matcher": {"id": "byRegexp", "options": ".*Read.*"}, - "properties": [{"id": "color", "value": {"fixedColor": "green", "mode": "fixed"}}] + "matcher": { "id": "byRegexp", "options": ".*Read.*" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "green", "mode": "fixed" } + } + ] }, { - "matcher": {"id": "byRegexp", "options": ".*Write.*"}, - "properties": [{"id": "color", "value": {"fixedColor": "blue", "mode": "fixed"}}] + "matcher": { "id": "byRegexp", "options": ".*Write.*" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "blue", "mode": "fixed" } + } + ] } ] }, - "gridPos": {"h": 8, "w": 12, "x": 0, "y": 24}, + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 24 }, "id": 30, "options": { - "legend": {"calcs": ["mean", "max", "lastNotNull"], "displayMode": "table", "placement": "right", "showLegend": true}, - "tooltip": {"mode": "multi", "sort": "desc"} + "legend": { + "calcs": ["mean", "max", "lastNotNull"], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { "mode": "multi", "sort": "desc" } }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(node_disk_read_bytes_total{instance=~\"$instance\", device=~\"$disk\"}[5m])", "legendFormat": "Read ({{device}})", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(node_disk_written_bytes_total{instance=~\"$instance\", device=~\"$disk\"}[5m])", "legendFormat": "Write ({{device}})", "refId": "B" @@ -679,10 +812,10 @@ "type": "timeseries" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "palette-classic"}, + "color": { "mode": "palette-classic" }, "custom": { "axisBorderShow": false, "axisCenteredZero": false, @@ -693,50 +826,65 @@ "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", - "hideFrom": {"legend": false, "tooltip": false, "viz": false}, + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "insertNulls": false, "lineInterpolation": "smooth", "lineWidth": 2, "pointSize": 5, - "scaleDistribution": {"type": "linear"}, + "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, - "stacking": {"group": "A", "mode": "none"}, - "thresholdsStyle": {"mode": "off"} + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", - "steps": [{"color": "green", "value": null}] + "steps": [{ "color": "green", "value": null }] }, "unit": "iops" }, "overrides": [ { - "matcher": {"id": "byRegexp", "options": ".*Read.*"}, - "properties": [{"id": "color", "value": {"fixedColor": "green", "mode": "fixed"}}] + "matcher": { "id": "byRegexp", "options": ".*Read.*" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "green", "mode": "fixed" } + } + ] }, { - "matcher": {"id": "byRegexp", "options": ".*Write.*"}, - "properties": [{"id": "color", "value": {"fixedColor": "blue", "mode": "fixed"}}] + "matcher": { "id": "byRegexp", "options": ".*Write.*" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "blue", "mode": "fixed" } + } + ] } ] }, - "gridPos": {"h": 8, "w": 12, "x": 12, "y": 24}, + "gridPos": { "h": 8, "w": 12, "x": 12, "y": 24 }, "id": 31, "options": { - "legend": {"calcs": ["mean", "max", "lastNotNull"], "displayMode": "table", "placement": "right", "showLegend": true}, - "tooltip": {"mode": "multi", "sort": "desc"} + "legend": { + "calcs": ["mean", "max", "lastNotNull"], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { "mode": "multi", "sort": "desc" } }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(node_disk_reads_completed_total{instance=~\"$instance\", device=~\"$disk\"}[5m])", "legendFormat": "Read IOPS ({{device}})", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(node_disk_writes_completed_total{instance=~\"$instance\", device=~\"$disk\"}[5m])", "legendFormat": "Write IOPS ({{device}})", "refId": "B" @@ -747,46 +895,50 @@ }, { "collapsed": false, - "gridPos": {"h": 1, "w": 24, "x": 0, "y": 32}, + "gridPos": { "h": 1, "w": 24, "x": 0, "y": 32 }, "id": 104, "panels": [], "title": "Filesystem", "type": "row" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "thresholds"}, + "color": { "mode": "thresholds" }, "mappings": [], "max": 100, "min": 0, "thresholds": { "mode": "absolute", "steps": [ - {"color": "green", "value": null}, - {"color": "yellow", "value": 70}, - {"color": "red", "value": 85} + { "color": "green", "value": null }, + { "color": "yellow", "value": 70 }, + { "color": "red", "value": 85 } ] }, "unit": "percent" }, "overrides": [] }, - "gridPos": {"h": 6, "w": 12, "x": 0, "y": 33}, + "gridPos": { "h": 6, "w": 12, "x": 0, "y": 33 }, "id": 40, "options": { "displayMode": "gradient", "minVizHeight": 10, "minVizWidth": 0, "orientation": "horizontal", - "reduceOptions": {"calcs": ["lastNotNull"], "fields": "", "values": false}, + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, "showUnfilled": true, "valueMode": "color" }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "(1 - node_filesystem_avail_bytes{instance=~\"$instance\", fstype!~\"autofs|devfs|tmpfs\"} / node_filesystem_size_bytes{instance=~\"$instance\", fstype!~\"autofs|devfs|tmpfs\"}) * 100", "legendFormat": "{{mountpoint}}", "refId": "A" @@ -796,10 +948,10 @@ "type": "bargauge" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "palette-classic"}, + "color": { "mode": "palette-classic" }, "custom": { "axisBorderShow": false, "axisCenteredZero": false, @@ -810,35 +962,40 @@ "drawStyle": "line", "fillOpacity": 20, "gradientMode": "opacity", - "hideFrom": {"legend": false, "tooltip": false, "viz": false}, + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "insertNulls": false, "lineInterpolation": "smooth", "lineWidth": 2, "pointSize": 5, - "scaleDistribution": {"type": "linear"}, + "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, - "stacking": {"group": "A", "mode": "none"}, - "thresholdsStyle": {"mode": "off"} + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", - "steps": [{"color": "green", "value": null}] + "steps": [{ "color": "green", "value": null }] }, "unit": "bytes" }, "overrides": [] }, - "gridPos": {"h": 6, "w": 12, "x": 12, "y": 33}, + "gridPos": { "h": 6, "w": 12, "x": 12, "y": 33 }, "id": 41, "options": { - "legend": {"calcs": ["lastNotNull"], "displayMode": "table", "placement": "right", "showLegend": true}, - "tooltip": {"mode": "multi", "sort": "desc"} + "legend": { + "calcs": ["lastNotNull"], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { "mode": "multi", "sort": "desc" } }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "node_filesystem_avail_bytes{instance=~\"$instance\", fstype!~\"autofs|devfs|tmpfs\"}", "legendFormat": "{{mountpoint}}", "refId": "A" @@ -849,17 +1006,17 @@ }, { "collapsed": false, - "gridPos": {"h": 1, "w": 24, "x": 0, "y": 39}, + "gridPos": { "h": 1, "w": 24, "x": 0, "y": 39 }, "id": 105, "panels": [], "title": "Network", "type": "row" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "palette-classic"}, + "color": { "mode": "palette-classic" }, "custom": { "axisBorderShow": false, "axisCenteredZero": false, @@ -870,50 +1027,65 @@ "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", - "hideFrom": {"legend": false, "tooltip": false, "viz": false}, + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "insertNulls": false, "lineInterpolation": "smooth", "lineWidth": 2, "pointSize": 5, - "scaleDistribution": {"type": "linear"}, + "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, - "stacking": {"group": "A", "mode": "none"}, - "thresholdsStyle": {"mode": "off"} + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", - "steps": [{"color": "green", "value": null}] + "steps": [{ "color": "green", "value": null }] }, "unit": "bps" }, "overrides": [ { - "matcher": {"id": "byRegexp", "options": ".*Receive.*"}, - "properties": [{"id": "color", "value": {"fixedColor": "green", "mode": "fixed"}}] + "matcher": { "id": "byRegexp", "options": ".*Receive.*" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "green", "mode": "fixed" } + } + ] }, { - "matcher": {"id": "byRegexp", "options": ".*Transmit.*"}, - "properties": [{"id": "color", "value": {"fixedColor": "blue", "mode": "fixed"}}] + "matcher": { "id": "byRegexp", "options": ".*Transmit.*" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "blue", "mode": "fixed" } + } + ] } ] }, - "gridPos": {"h": 8, "w": 12, "x": 0, "y": 40}, + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 40 }, "id": 50, "options": { - "legend": {"calcs": ["mean", "max", "lastNotNull"], "displayMode": "table", "placement": "right", "showLegend": true}, - "tooltip": {"mode": "multi", "sort": "desc"} + "legend": { + "calcs": ["mean", "max", "lastNotNull"], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { "mode": "multi", "sort": "desc" } }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(node_network_receive_bytes_total{instance=~\"$instance\", device=~\"$netdev\"}[5m]) * 8", "legendFormat": "Receive ({{device}})", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(node_network_transmit_bytes_total{instance=~\"$instance\", device=~\"$netdev\"}[5m]) * 8", "legendFormat": "Transmit ({{device}})", "refId": "B" @@ -923,10 +1095,10 @@ "type": "timeseries" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "palette-classic"}, + "color": { "mode": "palette-classic" }, "custom": { "axisBorderShow": false, "axisCenteredZero": false, @@ -937,50 +1109,65 @@ "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", - "hideFrom": {"legend": false, "tooltip": false, "viz": false}, + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "insertNulls": false, "lineInterpolation": "smooth", "lineWidth": 2, "pointSize": 5, - "scaleDistribution": {"type": "linear"}, + "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, - "stacking": {"group": "A", "mode": "none"}, - "thresholdsStyle": {"mode": "off"} + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", - "steps": [{"color": "green", "value": null}] + "steps": [{ "color": "green", "value": null }] }, "unit": "pps" }, "overrides": [ { - "matcher": {"id": "byRegexp", "options": ".*Receive.*"}, - "properties": [{"id": "color", "value": {"fixedColor": "green", "mode": "fixed"}}] + "matcher": { "id": "byRegexp", "options": ".*Receive.*" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "green", "mode": "fixed" } + } + ] }, { - "matcher": {"id": "byRegexp", "options": ".*Transmit.*"}, - "properties": [{"id": "color", "value": {"fixedColor": "blue", "mode": "fixed"}}] + "matcher": { "id": "byRegexp", "options": ".*Transmit.*" }, + "properties": [ + { + "id": "color", + "value": { "fixedColor": "blue", "mode": "fixed" } + } + ] } ] }, - "gridPos": {"h": 8, "w": 12, "x": 12, "y": 40}, + "gridPos": { "h": 8, "w": 12, "x": 12, "y": 40 }, "id": 51, "options": { - "legend": {"calcs": ["mean", "max", "lastNotNull"], "displayMode": "table", "placement": "right", "showLegend": true}, - "tooltip": {"mode": "multi", "sort": "desc"} + "legend": { + "calcs": ["mean", "max", "lastNotNull"], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { "mode": "multi", "sort": "desc" } }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(node_network_receive_packets_total{instance=~\"$instance\", device=~\"$netdev\"}[5m])", "legendFormat": "Receive ({{device}})", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(node_network_transmit_packets_total{instance=~\"$instance\", device=~\"$netdev\"}[5m])", "legendFormat": "Transmit ({{device}})", "refId": "B" @@ -990,10 +1177,10 @@ "type": "timeseries" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "fieldConfig": { "defaults": { - "color": {"mode": "palette-classic"}, + "color": { "mode": "palette-classic" }, "custom": { "axisBorderShow": false, "axisCenteredZero": false, @@ -1004,47 +1191,52 @@ "drawStyle": "line", "fillOpacity": 10, "gradientMode": "none", - "hideFrom": {"legend": false, "tooltip": false, "viz": false}, + "hideFrom": { "legend": false, "tooltip": false, "viz": false }, "insertNulls": false, "lineInterpolation": "smooth", "lineWidth": 2, "pointSize": 5, - "scaleDistribution": {"type": "linear"}, + "scaleDistribution": { "type": "linear" }, "showPoints": "never", "spanNulls": false, - "stacking": {"group": "A", "mode": "none"}, - "thresholdsStyle": {"mode": "off"} + "stacking": { "group": "A", "mode": "none" }, + "thresholdsStyle": { "mode": "off" } }, "mappings": [], "thresholds": { "mode": "absolute", - "steps": [{"color": "green", "value": null}] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 8, "w": 24, "x": 0, "y": 48}, + "gridPos": { "h": 8, "w": 24, "x": 0, "y": 48 }, "id": 52, "options": { - "legend": {"calcs": ["sum"], "displayMode": "table", "placement": "right", "showLegend": true}, - "tooltip": {"mode": "multi", "sort": "desc"} + "legend": { + "calcs": ["sum"], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { "mode": "multi", "sort": "desc" } }, "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(node_network_receive_errs_total{instance=~\"$instance\", device=~\"$netdev\"}[5m])", "legendFormat": "Receive Errors ({{device}})", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(node_network_transmit_errs_total{instance=~\"$instance\", device=~\"$netdev\"}[5m])", "legendFormat": "Transmit Errors ({{device}})", "refId": "B" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(node_network_receive_drop_total{instance=~\"$instance\", device=~\"$netdev\"}[5m])", "legendFormat": "Receive Drops ({{device}})", "refId": "C" @@ -1061,7 +1253,7 @@ "list": [ { "current": {}, - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "definition": "label_values(node_uname_info, instance)", "hide": 0, "includeAll": false, @@ -1081,7 +1273,7 @@ }, { "current": {}, - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "definition": "label_values(node_disk_read_bytes_total{instance=~\"$instance\"}, device)", "hide": 0, "includeAll": true, @@ -1101,7 +1293,7 @@ }, { "current": {}, - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "definition": "label_values(node_network_receive_bytes_total{instance=~\"$instance\"}, device)", "hide": 0, "includeAll": true, diff --git a/ansible/roles/grafana/files/dashboards/plex.json b/ansible/roles/grafana/files/dashboards/plex.json index 9cd8fc5..9eac21e 100644 --- a/ansible/roles/grafana/files/dashboards/plex.json +++ b/ansible/roles/grafana/files/dashboards/plex.json @@ -19,21 +19,31 @@ "mode": "thresholds" }, "mappings": [ - {"options": {"0": {"color": "red", "index": 0, "text": "DOWN"}}, "type": "value"}, - {"options": {"1": {"color": "green", "index": 1, "text": "UP"}}, "type": "value"} + { + "options": { + "0": { "color": "red", "index": 0, "text": "DOWN" } + }, + "type": "value" + }, + { + "options": { + "1": { "color": "green", "index": 1, "text": "UP" } + }, + "type": "value" + } ], "thresholds": { "mode": "absolute", "steps": [ - {"color": "red", "value": null}, - {"color": "green", "value": 1} + { "color": "red", "value": null }, + { "color": "green", "value": 1 } ] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 0, "y": 0}, + "gridPos": { "h": 4, "w": 4, "x": 0, "y": 0 }, "id": 1, "options": { "colorMode": "value", @@ -50,7 +60,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "plex_up", "refId": "A" } @@ -71,15 +81,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "blue", "value": null} - ] + "steps": [{ "color": "blue", "value": null }] }, "unit": "string" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 6, "x": 4, "y": 0}, + "gridPos": { "h": 4, "w": 6, "x": 4, "y": 0 }, "id": 2, "options": { "colorMode": "value", @@ -96,7 +104,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "plex_version_info", "format": "table", "instant": true, @@ -120,16 +128,16 @@ "thresholds": { "mode": "absolute", "steps": [ - {"color": "green", "value": null}, - {"color": "yellow", "value": 3}, - {"color": "orange", "value": 5} + { "color": "green", "value": null }, + { "color": "yellow", "value": 3 }, + { "color": "orange", "value": 5 } ] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 10, "y": 0}, + "gridPos": { "h": 4, "w": 4, "x": 10, "y": 0 }, "id": 3, "options": { "colorMode": "value", @@ -146,7 +154,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "plex_sessions_total", "refId": "A" } @@ -168,16 +176,16 @@ "thresholds": { "mode": "absolute", "steps": [ - {"color": "green", "value": null}, - {"color": "yellow", "value": 1}, - {"color": "orange", "value": 2} + { "color": "green", "value": null }, + { "color": "yellow", "value": 1 }, + { "color": "orange", "value": 2 } ] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 14, "y": 0}, + "gridPos": { "h": 4, "w": 4, "x": 14, "y": 0 }, "id": 4, "options": { "colorMode": "value", @@ -194,7 +202,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "plex_transcode_sessions_total", "refId": "A" } @@ -215,15 +223,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "purple", "value": null} - ] + "steps": [{ "color": "purple", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 6, "x": 18, "y": 0}, + "gridPos": { "h": 4, "w": 6, "x": 18, "y": 0 }, "id": 5, "options": { "colorMode": "value", @@ -240,7 +246,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "count(plex_library_items)", "refId": "A" } @@ -262,15 +268,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "blue", "value": null} - ] + "steps": [{ "color": "blue", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 6, "x": 0, "y": 4}, + "gridPos": { "h": 4, "w": 6, "x": 0, "y": 4 }, "id": 6, "options": { "colorMode": "value", @@ -287,7 +291,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "sum(plex_library_items{type=\"movie\"})", "refId": "A" } @@ -309,15 +313,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "green", "value": null} - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 6, "x": 6, "y": 4}, + "gridPos": { "h": 4, "w": 6, "x": 6, "y": 4 }, "id": 7, "options": { "colorMode": "value", @@ -334,7 +336,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "sum(plex_library_items{type=\"show\"})", "refId": "A" } @@ -356,15 +358,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "orange", "value": null} - ] + "steps": [{ "color": "orange", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 6, "x": 12, "y": 4}, + "gridPos": { "h": 4, "w": 6, "x": 12, "y": 4 }, "id": 8, "options": { "colorMode": "value", @@ -381,7 +381,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "sum(plex_library_items{type=\"artist\"})", "refId": "A" } @@ -403,15 +403,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "purple", "value": null} - ] + "steps": [{ "color": "purple", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 6, "x": 18, "y": 4}, + "gridPos": { "h": 4, "w": 6, "x": 18, "y": 4 }, "id": 9, "options": { "colorMode": "value", @@ -428,7 +426,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "sum(plex_library_items{type=\"photo\"})", "refId": "A" } @@ -481,28 +479,32 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "green", "value": null} - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" }, "overrides": [ { - "matcher": {"id": "byName", "options": "Playing"}, + "matcher": { "id": "byName", "options": "Playing" }, "properties": [ - {"id": "color", "value": {"fixedColor": "green", "mode": "fixed"}} + { + "id": "color", + "value": { "fixedColor": "green", "mode": "fixed" } + } ] }, { - "matcher": {"id": "byName", "options": "Paused"}, + "matcher": { "id": "byName", "options": "Paused" }, "properties": [ - {"id": "color", "value": {"fixedColor": "yellow", "mode": "fixed"}} + { + "id": "color", + "value": { "fixedColor": "yellow", "mode": "fixed" } + } ] } ] }, - "gridPos": {"h": 8, "w": 12, "x": 0, "y": 8}, + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 }, "id": 10, "options": { "legend": { @@ -519,13 +521,13 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "plex_sessions_playing", "legendFormat": "Playing", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "plex_sessions_paused", "legendFormat": "Paused", "refId": "B" @@ -579,28 +581,32 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "green", "value": null} - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" }, "overrides": [ { - "matcher": {"id": "byName", "options": "Video Transcode"}, + "matcher": { "id": "byName", "options": "Video Transcode" }, "properties": [ - {"id": "color", "value": {"fixedColor": "red", "mode": "fixed"}} + { + "id": "color", + "value": { "fixedColor": "red", "mode": "fixed" } + } ] }, { - "matcher": {"id": "byName", "options": "Audio Transcode"}, + "matcher": { "id": "byName", "options": "Audio Transcode" }, "properties": [ - {"id": "color", "value": {"fixedColor": "orange", "mode": "fixed"}} + { + "id": "color", + "value": { "fixedColor": "orange", "mode": "fixed" } + } ] } ] }, - "gridPos": {"h": 8, "w": 12, "x": 12, "y": 8}, + "gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 }, "id": 11, "options": { "legend": { @@ -617,13 +623,13 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "plex_transcode_video_sessions", "legendFormat": "Video Transcode", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "plex_transcode_audio_sessions", "legendFormat": "Audio Transcode", "refId": "B" @@ -637,7 +643,7 @@ "type": "loki", "uid": "loki" }, - "gridPos": {"h": 8, "w": 24, "x": 0, "y": 16}, + "gridPos": { "h": 8, "w": 24, "x": 0, "y": 16 }, "id": 12, "options": { "dedupStrategy": "none", @@ -651,7 +657,7 @@ }, "targets": [ { - "datasource": {"type": "loki", "uid": "loki"}, + "datasource": { "type": "loki", "uid": "loki" }, "expr": "{service=\"plex\"}", "refId": "A" } diff --git a/ansible/roles/grafana/files/dashboards/postgresql.json b/ansible/roles/grafana/files/dashboards/postgresql.json index 8a561c7..2b15afc 100644 --- a/ansible/roles/grafana/files/dashboards/postgresql.json +++ b/ansible/roles/grafana/files/dashboards/postgresql.json @@ -65,9 +65,7 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - { "color": "green", "value": null } - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" } @@ -108,9 +106,7 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - { "color": "green", "value": null } - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" } @@ -151,9 +147,7 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - { "color": "green", "value": null } - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "decbytes" } @@ -225,9 +219,7 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - { "color": "green", "value": null } - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" } @@ -300,9 +292,7 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - { "color": "green", "value": null } - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "decbytes" } @@ -375,9 +365,7 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - { "color": "green", "value": null } - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "ops" } @@ -465,9 +453,7 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - { "color": "green", "value": null } - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" } @@ -545,9 +531,7 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - { "color": "green", "value": null } - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" } diff --git a/ansible/roles/grafana/files/dashboards/transmission.json b/ansible/roles/grafana/files/dashboards/transmission.json index 85e5eeb..e6b4826 100644 --- a/ansible/roles/grafana/files/dashboards/transmission.json +++ b/ansible/roles/grafana/files/dashboards/transmission.json @@ -22,15 +22,15 @@ "thresholds": { "mode": "absolute", "steps": [ - {"color": "red", "value": null}, - {"color": "green", "value": 1} + { "color": "red", "value": null }, + { "color": "green", "value": 1 } ] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 0, "y": 0}, + "gridPos": { "h": 4, "w": 4, "x": 0, "y": 0 }, "id": 1, "options": { "colorMode": "value", @@ -47,7 +47,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "transmission_up", "refId": "A" } @@ -68,15 +68,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "green", "value": null} - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 4, "y": 0}, + "gridPos": { "h": 4, "w": 4, "x": 4, "y": 0 }, "id": 2, "options": { "colorMode": "value", @@ -93,7 +91,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "transmission_torrents_total", "refId": "A" } @@ -114,15 +112,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "blue", "value": null} - ] + "steps": [{ "color": "blue", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 8, "y": 0}, + "gridPos": { "h": 4, "w": 4, "x": 8, "y": 0 }, "id": 3, "options": { "colorMode": "value", @@ -139,7 +135,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "transmission_torrents_active", "refId": "A" } @@ -160,15 +156,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "orange", "value": null} - ] + "steps": [{ "color": "orange", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 12, "y": 0}, + "gridPos": { "h": 4, "w": 4, "x": 12, "y": 0 }, "id": 4, "options": { "colorMode": "value", @@ -185,7 +179,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "transmission_torrents_paused", "refId": "A" } @@ -206,15 +200,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "green", "value": null} - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "decbytes" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 16, "y": 0}, + "gridPos": { "h": 4, "w": 4, "x": 16, "y": 0 }, "id": 5, "options": { "colorMode": "value", @@ -231,7 +223,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "transmission_downloaded_bytes_total", "refId": "A" } @@ -252,15 +244,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "purple", "value": null} - ] + "steps": [{ "color": "purple", "value": null }] }, "unit": "decbytes" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 4, "x": 20, "y": 0}, + "gridPos": { "h": 4, "w": 4, "x": 20, "y": 0 }, "id": 6, "options": { "colorMode": "value", @@ -277,7 +267,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "transmission_uploaded_bytes_total", "refId": "A" } @@ -300,16 +290,16 @@ "thresholds": { "mode": "absolute", "steps": [ - {"color": "red", "value": null}, - {"color": "yellow", "value": 0.5}, - {"color": "green", "value": 1} + { "color": "red", "value": null }, + { "color": "yellow", "value": 0.5 }, + { "color": "green", "value": 1 } ] }, "unit": "none" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 8, "x": 0, "y": 4}, + "gridPos": { "h": 4, "w": 8, "x": 0, "y": 4 }, "id": 11, "options": { "colorMode": "value", @@ -326,7 +316,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "increase(transmission_uploaded_bytes_total[$__range]) / increase(transmission_downloaded_bytes_total[$__range])", "refId": "A" } @@ -348,15 +338,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "green", "value": null} - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "decbytes" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 8, "x": 8, "y": 4}, + "gridPos": { "h": 4, "w": 8, "x": 8, "y": 4 }, "id": 12, "options": { "colorMode": "value", @@ -373,7 +361,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "increase(transmission_downloaded_bytes_total[$__range])", "refId": "A" } @@ -395,15 +383,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "blue", "value": null} - ] + "steps": [{ "color": "blue", "value": null }] }, "unit": "decbytes" }, "overrides": [] }, - "gridPos": {"h": 4, "w": 8, "x": 16, "y": 4}, + "gridPos": { "h": 4, "w": 8, "x": 16, "y": 4 }, "id": 13, "options": { "colorMode": "value", @@ -420,7 +406,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "increase(transmission_uploaded_bytes_total[$__range])", "refId": "A" } @@ -473,28 +459,32 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "green", "value": null} - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "Bps" }, "overrides": [ { - "matcher": {"id": "byName", "options": "Download"}, + "matcher": { "id": "byName", "options": "Download" }, "properties": [ - {"id": "color", "value": {"fixedColor": "green", "mode": "fixed"}} + { + "id": "color", + "value": { "fixedColor": "green", "mode": "fixed" } + } ] }, { - "matcher": {"id": "byName", "options": "Upload"}, + "matcher": { "id": "byName", "options": "Upload" }, "properties": [ - {"id": "color", "value": {"fixedColor": "blue", "mode": "fixed"}} + { + "id": "color", + "value": { "fixedColor": "blue", "mode": "fixed" } + } ] } ] }, - "gridPos": {"h": 8, "w": 12, "x": 0, "y": 8}, + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 }, "id": 7, "options": { "legend": { @@ -511,13 +501,13 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "transmission_download_speed_bytes", "legendFormat": "Download", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "transmission_upload_speed_bytes", "legendFormat": "Upload", "refId": "B" @@ -571,15 +561,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "green", "value": null} - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "short" }, "overrides": [] }, - "gridPos": {"h": 8, "w": 12, "x": 12, "y": 8}, + "gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 }, "id": 8, "options": { "legend": { @@ -596,19 +584,19 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "transmission_torrents_total", "legendFormat": "Total", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "transmission_torrents_active", "legendFormat": "Active", "refId": "B" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "transmission_torrents_paused", "legendFormat": "Paused", "refId": "C" @@ -662,28 +650,32 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "green", "value": null} - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "Bps" }, "overrides": [ { - "matcher": {"id": "byName", "options": "Download Rate"}, + "matcher": { "id": "byName", "options": "Download Rate" }, "properties": [ - {"id": "color", "value": {"fixedColor": "green", "mode": "fixed"}} + { + "id": "color", + "value": { "fixedColor": "green", "mode": "fixed" } + } ] }, { - "matcher": {"id": "byName", "options": "Upload Rate"}, + "matcher": { "id": "byName", "options": "Upload Rate" }, "properties": [ - {"id": "color", "value": {"fixedColor": "blue", "mode": "fixed"}} + { + "id": "color", + "value": { "fixedColor": "blue", "mode": "fixed" } + } ] } ] }, - "gridPos": {"h": 8, "w": 24, "x": 0, "y": 16}, + "gridPos": { "h": 8, "w": 24, "x": 0, "y": 16 }, "id": 9, "options": { "legend": { @@ -700,13 +692,13 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(transmission_downloaded_bytes_total[5m])", "legendFormat": "Download Rate", "refId": "A" }, { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "rate(transmission_uploaded_bytes_total[5m])", "legendFormat": "Upload Rate", "refId": "B" @@ -761,15 +753,13 @@ "mappings": [], "thresholds": { "mode": "absolute", - "steps": [ - {"color": "green", "value": null} - ] + "steps": [{ "color": "green", "value": null }] }, "unit": "decbytes" }, "overrides": [] }, - "gridPos": {"h": 8, "w": 24, "x": 0, "y": 24}, + "gridPos": { "h": 8, "w": 24, "x": 0, "y": 24 }, "id": 10, "options": { "legend": { @@ -786,7 +776,7 @@ "pluginVersion": "10.0.0", "targets": [ { - "datasource": {"type": "prometheus", "uid": "prometheus"}, + "datasource": { "type": "prometheus", "uid": "prometheus" }, "expr": "transmission_torrents_size_bytes", "legendFormat": "Total Torrent Size", "refId": "A" diff --git a/ansible/roles/grafana/handlers/main.yml b/ansible/roles/grafana/handlers/main.yml index a2ce139..ad61ea4 100644 --- a/ansible/roles/grafana/handlers/main.yml +++ b/ansible/roles/grafana/handlers/main.yml @@ -1,3 +1,4 @@ --- -- name: restart grafana +- name: Restart grafana ansible.builtin.command: brew services restart grafana + changed_when: true diff --git a/ansible/roles/grafana/tasks/main.yml b/ansible/roles/grafana/tasks/main.yml index 7887487..ea31acc 100644 --- a/ansible/roles/grafana/tasks/main.yml +++ b/ansible/roles/grafana/tasks/main.yml @@ -19,31 +19,31 @@ src: grafana.ini.j2 dest: /opt/homebrew/etc/grafana/grafana.ini mode: '0644' - notify: restart grafana + notify: Restart grafana - name: Deploy grafana datasources config ansible.builtin.template: src: datasources.yaml.j2 dest: /opt/homebrew/etc/grafana/provisioning/datasources/datasources.yaml mode: '0644' - notify: restart grafana + notify: Restart grafana - name: Deploy grafana dashboards provider config ansible.builtin.template: src: dashboards.yaml.j2 dest: /opt/homebrew/etc/grafana/provisioning/dashboards/default.yaml mode: '0644' - notify: restart grafana + notify: Restart grafana - name: Deploy grafana dashboard JSON files ansible.builtin.copy: src: "dashboards/" dest: /opt/homebrew/etc/grafana/provisioning/dashboards/ mode: '0644' - notify: restart grafana + notify: Restart grafana - name: Ensure grafana service is started ansible.builtin.command: brew services start grafana - register: brew_start - changed_when: "'Successfully started' in brew_start.stdout" + register: grafana_brew_start + changed_when: "'Successfully started' in grafana_brew_start.stdout" failed_when: false diff --git a/ansible/roles/kiwix/handlers/main.yml b/ansible/roles/kiwix/handlers/main.yml index 0c4d6b2..ef6e408 100644 --- a/ansible/roles/kiwix/handlers/main.yml +++ b/ansible/roles/kiwix/handlers/main.yml @@ -1,5 +1,6 @@ --- -- name: restart kiwix-serve +- name: Restart kiwix-serve ansible.builtin.shell: | launchctl unload ~/Library/LaunchAgents/mcquack.eblume.kiwix-serve.plist 2>/dev/null || true launchctl load ~/Library/LaunchAgents/mcquack.eblume.kiwix-serve.plist + changed_when: true diff --git a/ansible/roles/kiwix/tasks/main.yml b/ansible/roles/kiwix/tasks/main.yml index 1239de2..950fd03 100644 --- a/ansible/roles/kiwix/tasks/main.yml +++ b/ansible/roles/kiwix/tasks/main.yml @@ -11,7 +11,7 @@ - name: Check transmission daemon is responding ansible.builtin.command: transmission-remote -l - register: transmission_check + register: kiwix_transmission_check changed_when: false failed_when: false when: kiwix_use_transmission @@ -19,7 +19,7 @@ - name: Fail if transmission is not running ansible.builtin.fail: msg: "Transmission daemon is not responding. Ensure transmission role ran successfully." - when: kiwix_use_transmission and transmission_check.rc != 0 + when: kiwix_use_transmission and kiwix_transmission_check.rc != 0 # Find which declared archives don't have torrents yet (single shell command) - name: Find declared archives missing from transmission @@ -37,7 +37,7 @@ {% endfor %} args: executable: /bin/bash - register: missing_torrents + register: kiwix_missing_torrents changed_when: false when: kiwix_use_transmission @@ -45,14 +45,14 @@ - name: Add missing torrents to transmission ansible.builtin.command: > transmission-remote -a "{{ kiwix_torrent_base_url }}/{{ item }}.torrent" - loop: "{{ missing_torrents.stdout_lines | default([]) }}" + loop: "{{ kiwix_missing_torrents.stdout_lines | default([]) }}" loop_control: label: "{{ item | basename }}" when: - kiwix_use_transmission - - missing_torrents.stdout_lines | default([]) | length > 0 - register: torrent_add - changed_when: torrent_add.rc == 0 + - kiwix_missing_torrents.stdout_lines | default([]) | length > 0 + register: kiwix_torrent_add + changed_when: kiwix_torrent_add.rc == 0 # --- Kiwix startup: serve whatever completed ZIM files exist --- # This is decoupled from the declared inventory - it just serves what's available. @@ -63,7 +63,7 @@ paths: "{{ transmission_download_dir }}" patterns: "*.zim" file_type: file - register: completed_zim_files + register: kiwix_completed_zim_files when: kiwix_use_transmission # Check which ZIM files already have symlinks in kiwix directory @@ -71,10 +71,10 @@ ansible.builtin.stat: path: "{{ kiwix_zim_dir }}/{{ item.path | basename }}" get_checksum: false - loop: "{{ completed_zim_files.files | default([]) }}" + loop: "{{ kiwix_completed_zim_files.files | default([]) }}" loop_control: label: "{{ item.path | basename }}" - register: existing_symlinks + register: kiwix_existing_symlinks when: kiwix_use_transmission # Create symlinks for any completed ZIM files not yet linked @@ -83,14 +83,14 @@ src: "{{ item.item.path }}" dest: "{{ kiwix_zim_dir }}/{{ item.item.path | basename }}" state: link - loop: "{{ existing_symlinks.results | default([]) }}" + loop: "{{ kiwix_existing_symlinks.results | default([]) }}" loop_control: label: "{{ item.item.path | basename }}" when: - kiwix_use_transmission - item.stat is defined - not item.stat.exists - notify: restart kiwix-serve + notify: Restart kiwix-serve # --- Fallback: Direct HTTP download (original behavior) --- - name: Check which ZIM archives exist (direct download mode) @@ -100,7 +100,7 @@ loop: "{{ kiwix_zim_archives }}" loop_control: label: "{{ item.filename }}" - register: zim_stat + register: kiwix_zim_stat when: not kiwix_use_transmission - name: Download missing ZIM archives (direct download mode) @@ -109,14 +109,14 @@ dest: "{{ kiwix_zim_dir }}/{{ item.item.filename }}" mode: '0644' timeout: 3600 - loop: "{{ zim_stat.results | default([]) }}" + loop: "{{ kiwix_zim_stat.results | default([]) }}" loop_control: label: "{{ item.item.filename | default('unknown') }}" when: - not kiwix_use_transmission - item.stat is defined - not item.stat.exists - notify: restart kiwix-serve + notify: Restart kiwix-serve # --- Determine which archives are available --- - name: Find available ZIM archives in kiwix directory @@ -124,11 +124,11 @@ paths: "{{ kiwix_zim_dir }}" patterns: "*.zim" file_type: any # includes symlinks - register: available_zim_files + register: kiwix_available_zim_files - name: Build list of available archive filenames ansible.builtin.set_fact: - kiwix_available_archives: "{{ available_zim_files.files | map(attribute='path') | map('basename') | list }}" + kiwix_available_archives: "{{ kiwix_available_zim_files.files | map(attribute='path') | map('basename') | list }}" # --- LaunchAgent deployment --- - name: Deploy kiwix-serve LaunchAgent plist @@ -136,15 +136,16 @@ src: kiwix-serve.plist.j2 dest: ~/Library/LaunchAgents/mcquack.eblume.kiwix-serve.plist mode: '0644' - notify: restart kiwix-serve + notify: Restart kiwix-serve - name: Check if kiwix-serve LaunchAgent is loaded ansible.builtin.command: launchctl list mcquack.eblume.kiwix-serve - register: launchctl_check + register: kiwix_launchctl_check changed_when: false failed_when: false - name: Load kiwix-serve LaunchAgent if not loaded ansible.builtin.command: launchctl load ~/Library/LaunchAgents/mcquack.eblume.kiwix-serve.plist - when: launchctl_check.rc != 0 + when: kiwix_launchctl_check.rc != 0 + changed_when: true failed_when: false diff --git a/ansible/roles/loki/handlers/main.yml b/ansible/roles/loki/handlers/main.yml index 9edd651..3470e8e 100644 --- a/ansible/roles/loki/handlers/main.yml +++ b/ansible/roles/loki/handlers/main.yml @@ -1,5 +1,6 @@ --- -- name: restart loki +- name: Restart loki ansible.builtin.command: brew services restart loki async: 120 poll: 0 + changed_when: true diff --git a/ansible/roles/loki/tasks/main.yml b/ansible/roles/loki/tasks/main.yml index fd05cdb..ab76419 100644 --- a/ansible/roles/loki/tasks/main.yml +++ b/ansible/roles/loki/tasks/main.yml @@ -29,10 +29,10 @@ src: loki-config.yaml.j2 dest: "{{ loki_config_file }}" mode: '0644' - notify: restart loki + notify: Restart loki - name: Ensure loki service is started ansible.builtin.command: brew services start loki - register: brew_start - changed_when: "'Successfully started' in brew_start.stdout" + register: loki_brew_start + changed_when: "'Successfully started' in loki_brew_start.stdout" failed_when: false diff --git a/ansible/roles/miniflux/handlers/main.yml b/ansible/roles/miniflux/handlers/main.yml index 936d0a3..cf38bf1 100644 --- a/ansible/roles/miniflux/handlers/main.yml +++ b/ansible/roles/miniflux/handlers/main.yml @@ -1,5 +1,6 @@ --- -- name: restart miniflux +- name: Restart miniflux ansible.builtin.command: brew services restart miniflux async: 120 poll: 0 + changed_when: true diff --git a/ansible/roles/miniflux/tasks/main.yml b/ansible/roles/miniflux/tasks/main.yml index 8c3f691..0d40284 100644 --- a/ansible/roles/miniflux/tasks/main.yml +++ b/ansible/roles/miniflux/tasks/main.yml @@ -54,11 +54,11 @@ src: miniflux.conf.j2 dest: "{{ miniflux_config_file }}" mode: '0600' - notify: restart miniflux + notify: Restart miniflux no_log: true - name: Ensure miniflux service is started ansible.builtin.command: brew services start miniflux - register: brew_start - changed_when: "'Successfully started' in brew_start.stdout" + register: miniflux_brew_start + changed_when: "'Successfully started' in miniflux_brew_start.stdout" failed_when: false diff --git a/ansible/roles/node_exporter/handlers/main.yml b/ansible/roles/node_exporter/handlers/main.yml index d2f9d11..fa0c59b 100644 --- a/ansible/roles/node_exporter/handlers/main.yml +++ b/ansible/roles/node_exporter/handlers/main.yml @@ -1,4 +1,5 @@ --- -- name: restart node_exporter +- name: Restart node_exporter ansible.builtin.command: brew services restart node_exporter - listen: restart node_exporter + listen: Restart node_exporter + changed_when: true diff --git a/ansible/roles/node_exporter/tasks/main.yml b/ansible/roles/node_exporter/tasks/main.yml index dd1bbae..55c0398 100644 --- a/ansible/roles/node_exporter/tasks/main.yml +++ b/ansible/roles/node_exporter/tasks/main.yml @@ -13,10 +13,10 @@ src: node_exporter.args.j2 dest: /opt/homebrew/etc/node_exporter.args mode: '0644' - notify: restart node_exporter + notify: Restart node_exporter - name: Ensure node_exporter service is started ansible.builtin.command: brew services start node_exporter - register: brew_start - changed_when: "'Successfully started' in brew_start.stdout" + register: node_exporter_brew_start + changed_when: "'Successfully started' in node_exporter_brew_start.stdout" failed_when: false diff --git a/ansible/roles/plex_metrics/defaults/main.yml b/ansible/roles/plex_metrics/defaults/main.yml index 667f641..f186506 100644 --- a/ansible/roles/plex_metrics/defaults/main.yml +++ b/ansible/roles/plex_metrics/defaults/main.yml @@ -2,10 +2,10 @@ # Plex metrics collection configuration # Plex server URL -plex_url: "http://localhost:32400" +plex_metrics_url: "http://localhost:32400" # Path to file containing Plex token (should have 600 permissions) -plex_token_file: "/Users/erichblume/.plex-token" +plex_metrics_token_file: "/Users/erichblume/.plex-token" # Metrics collection interval in seconds plex_metrics_interval: 60 diff --git a/ansible/roles/plex_metrics/handlers/main.yml b/ansible/roles/plex_metrics/handlers/main.yml index 128ecad..ab5d382 100644 --- a/ansible/roles/plex_metrics/handlers/main.yml +++ b/ansible/roles/plex_metrics/handlers/main.yml @@ -1,5 +1,6 @@ --- -- name: reload plex-metrics +- name: Reload plex-metrics ansible.builtin.shell: | launchctl unload ~/Library/LaunchAgents/mcquack.eblume.plex-metrics.plist 2>/dev/null || true launchctl load ~/Library/LaunchAgents/mcquack.eblume.plex-metrics.plist + changed_when: true diff --git a/ansible/roles/plex_metrics/tasks/main.yml b/ansible/roles/plex_metrics/tasks/main.yml index ea4be15..8225e27 100644 --- a/ansible/roles/plex_metrics/tasks/main.yml +++ b/ansible/roles/plex_metrics/tasks/main.yml @@ -10,22 +10,23 @@ src: plex-metrics.sh.j2 dest: "{{ plex_metrics_script }}" mode: '0755' - notify: reload plex-metrics + notify: Reload plex-metrics - name: Deploy plex-metrics LaunchAgent plist ansible.builtin.template: src: plex-metrics.plist.j2 dest: ~/Library/LaunchAgents/mcquack.eblume.plex-metrics.plist mode: '0644' - notify: reload plex-metrics + notify: Reload plex-metrics - name: Check if plex-metrics LaunchAgent is loaded ansible.builtin.command: launchctl list mcquack.eblume.plex-metrics - register: launchctl_check + register: plex_metrics_launchctl_check changed_when: false failed_when: false - name: Load plex-metrics LaunchAgent if not loaded ansible.builtin.command: launchctl load ~/Library/LaunchAgents/mcquack.eblume.plex-metrics.plist - when: launchctl_check.rc != 0 + when: plex_metrics_launchctl_check.rc != 0 + changed_when: true failed_when: false diff --git a/ansible/roles/plex_metrics/templates/plex-metrics.sh.j2 b/ansible/roles/plex_metrics/templates/plex-metrics.sh.j2 index e2f8b2e..01ea2eb 100644 --- a/ansible/roles/plex_metrics/templates/plex-metrics.sh.j2 +++ b/ansible/roles/plex_metrics/templates/plex-metrics.sh.j2 @@ -4,8 +4,8 @@ set -euo pipefail -PLEX_URL="{{ plex_url }}" -TOKEN_FILE="{{ plex_token_file }}" +PLEX_URL="{{ plex_metrics_url }}" +TOKEN_FILE="{{ plex_metrics_token_file }}" OUTPUT_FILE="{{ plex_metrics_dir }}/plex.prom" TEMP_FILE="${OUTPUT_FILE}.tmp" diff --git a/ansible/roles/postgresql/handlers/main.yml b/ansible/roles/postgresql/handlers/main.yml index a6ce462..0603e20 100644 --- a/ansible/roles/postgresql/handlers/main.yml +++ b/ansible/roles/postgresql/handlers/main.yml @@ -1,5 +1,6 @@ --- -- name: restart postgresql +- name: Restart postgresql ansible.builtin.command: brew services restart {{ postgresql_formula }} async: 120 poll: 0 + changed_when: true diff --git a/ansible/roles/postgresql/tasks/main.yml b/ansible/roles/postgresql/tasks/main.yml index d4c604b..851a01e 100644 --- a/ansible/roles/postgresql/tasks/main.yml +++ b/ansible/roles/postgresql/tasks/main.yml @@ -4,7 +4,7 @@ # Passwords are fetched from 1Password at runtime using the `op` CLI. # Requires: `op` authenticated on the control machine (run `op signin` first). -- name: Install {{ postgresql_formula }} via homebrew +- name: Install postgresql via homebrew community.general.homebrew: name: "{{ postgresql_formula }}" state: present @@ -17,49 +17,49 @@ ansible.builtin.command: cmd: op --vault {{ postgresql_op_vault }} item get {{ postgresql_op_superuser_item }} --fields password --reveal delegate_to: localhost - register: pg_superuser_password_result + register: postgresql_superuser_password_result changed_when: false no_log: true check_mode: false - when: pg_superuser_password is not defined + when: postgresql_superuser_password is not defined - name: Set superuser password fact ansible.builtin.set_fact: - pg_superuser_password: "{{ pg_superuser_password_result.stdout }}" + postgresql_superuser_password: "{{ postgresql_superuser_password_result.stdout }}" no_log: true - when: pg_superuser_password is not defined + when: postgresql_superuser_password is not defined - name: Fetch user passwords from 1Password ansible.builtin.command: cmd: op --vault {{ postgresql_op_vault }} item get {{ item.op_item }} --fields {{ item.op_field }} --reveal delegate_to: localhost loop: "{{ postgresql_users }}" - register: pg_user_passwords_result + register: postgresql_user_passwords_result changed_when: false no_log: true check_mode: false - when: pg_user_passwords is not defined + when: postgresql_user_passwords is not defined - name: Build user password lookup ansible.builtin.set_fact: - pg_user_passwords: "{{ pg_user_passwords | default({}) | combine({item.item.name: item.stdout}) }}" - loop: "{{ pg_user_passwords_result.results }}" + postgresql_user_passwords: "{{ postgresql_user_passwords | default({}) | combine({item.item.name: item.stdout}) }}" + loop: "{{ postgresql_user_passwords_result.results }}" no_log: true - when: pg_user_passwords is not defined + when: postgresql_user_passwords is not defined # === Initialize PostgreSQL cluster === - name: Check if postgresql data directory is initialized ansible.builtin.stat: path: "{{ postgresql_data_dir }}/PG_VERSION" - register: pg_data + register: postgresql_data_check - name: Create temporary password file for initdb ansible.builtin.copy: - content: "{{ pg_superuser_password }}" + content: "{{ postgresql_superuser_password }}" dest: /tmp/.pg_init_pwfile mode: '0600' - when: not pg_data.stat.exists + when: not postgresql_data_check.stat.exists no_log: true - name: Initialize postgresql database cluster with superuser password @@ -69,13 +69,14 @@ --locale=en_US.UTF-8 -E UTF-8 --pwfile=/tmp/.pg_init_pwfile {{ postgresql_data_dir }} - when: not pg_data.stat.exists + when: not postgresql_data_check.stat.exists + changed_when: true - name: Remove temporary password file ansible.builtin.file: path: /tmp/.pg_init_pwfile state: absent - when: not pg_data.stat.exists + when: not postgresql_data_check.stat.exists # === Configure and start PostgreSQL === @@ -84,19 +85,19 @@ src: pg_hba.conf.j2 dest: "{{ postgresql_config_dir }}/pg_hba.conf" mode: '0600' - notify: restart postgresql + notify: Restart postgresql - name: Ensure postgresql service is started ansible.builtin.command: brew services start {{ postgresql_formula }} - register: brew_start - changed_when: "'Successfully started' in brew_start.stdout" + register: postgresql_brew_start + changed_when: "'Successfully started' in postgresql_brew_start.stdout" failed_when: false - name: Wait for postgresql to accept connections ansible.builtin.command: > {{ postgresql_bin_dir }}/pg_isready -h localhost -p {{ postgresql_port }} - register: pg_ready - until: pg_ready.rc == 0 + register: postgresql_ready + until: postgresql_ready.rc == 0 retries: 10 delay: 2 changed_when: false @@ -108,9 +109,9 @@ {{ postgresql_bin_dir }}/psql -h localhost -U {{ postgresql_superuser }} -d postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname = '{{ item.name }}';" environment: - PGPASSWORD: "{{ pg_superuser_password }}" + PGPASSWORD: "{{ postgresql_superuser_password }}" loop: "{{ postgresql_users }}" - register: user_check + register: postgresql_user_check changed_when: false failed_when: false no_log: true @@ -118,10 +119,10 @@ - name: Create postgresql users with passwords ansible.builtin.command: > {{ postgresql_bin_dir }}/psql -h localhost -U {{ postgresql_superuser }} -d postgres -c - "CREATE USER {{ item.item.name }} WITH PASSWORD '{{ pg_user_passwords[item.item.name] }}';" + "CREATE USER {{ item.item.name }} WITH PASSWORD '{{ postgresql_user_passwords[item.item.name] }}';" environment: - PGPASSWORD: "{{ pg_superuser_password }}" - loop: "{{ user_check.results }}" + PGPASSWORD: "{{ postgresql_superuser_password }}" + loop: "{{ postgresql_user_check.results }}" when: item.stdout != "1" changed_when: true no_log: true @@ -129,9 +130,9 @@ - name: Update postgresql user passwords (idempotent) ansible.builtin.command: > {{ postgresql_bin_dir }}/psql -h localhost -U {{ postgresql_superuser }} -d postgres -c - "ALTER USER {{ item.name }} WITH PASSWORD '{{ pg_user_passwords[item.name] }}';" + "ALTER USER {{ item.name }} WITH PASSWORD '{{ postgresql_user_passwords[item.name] }}';" environment: - PGPASSWORD: "{{ pg_superuser_password }}" + PGPASSWORD: "{{ postgresql_superuser_password }}" loop: "{{ postgresql_users }}" changed_when: false no_log: true @@ -140,9 +141,10 @@ - name: Grant roles to users ansible.builtin.command: > - {{ postgresql_bin_dir }}/psql -h localhost -U {{ postgresql_superuser }} -d postgres -c "GRANT {{ item.1 }} TO {{ item.0.name }};" + {{ postgresql_bin_dir }}/psql -h localhost -U {{ postgresql_superuser }} + -d postgres -c "GRANT {{ item.1 }} TO {{ item.0.name }};" environment: - PGPASSWORD: "{{ pg_superuser_password }}" + PGPASSWORD: "{{ postgresql_superuser_password }}" loop: "{{ postgresql_users | subelements('roles', skip_missing=True) }}" changed_when: false no_log: true @@ -154,9 +156,9 @@ {{ postgresql_bin_dir }}/psql -h localhost -U {{ postgresql_superuser }} -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname = '{{ item.name }}';" environment: - PGPASSWORD: "{{ pg_superuser_password }}" + PGPASSWORD: "{{ postgresql_superuser_password }}" loop: "{{ postgresql_databases }}" - register: db_check + register: postgresql_db_check changed_when: false failed_when: false no_log: true @@ -167,8 +169,8 @@ --owner={{ item.item.owner }} {{ item.item.name }} environment: - PGPASSWORD: "{{ pg_superuser_password }}" - loop: "{{ db_check.results }}" + PGPASSWORD: "{{ postgresql_superuser_password }}" + loop: "{{ postgresql_db_check.results }}" when: item.stdout != "1" changed_when: true no_log: true @@ -181,7 +183,7 @@ ansible.builtin.copy: content: | # Managed by ansible - only read-only roles - localhost:{{ postgresql_port }}:*:borgmatic:{{ pg_user_passwords['borgmatic'] }} + localhost:{{ postgresql_port }}:*:borgmatic:{{ postgresql_user_passwords['borgmatic'] }} dest: ~/.pgpass mode: '0600' no_log: true diff --git a/ansible/roles/prometheus/handlers/main.yml b/ansible/roles/prometheus/handlers/main.yml index 996ba18..ee64300 100644 --- a/ansible/roles/prometheus/handlers/main.yml +++ b/ansible/roles/prometheus/handlers/main.yml @@ -1,3 +1,4 @@ --- -- name: restart prometheus +- name: Restart prometheus ansible.builtin.command: brew services restart prometheus + changed_when: true diff --git a/ansible/roles/prometheus/tasks/main.yml b/ansible/roles/prometheus/tasks/main.yml index 150c8ef..c21d642 100644 --- a/ansible/roles/prometheus/tasks/main.yml +++ b/ansible/roles/prometheus/tasks/main.yml @@ -9,17 +9,17 @@ src: prometheus.yml.j2 dest: /opt/homebrew/etc/prometheus.yml mode: '0644' - notify: restart prometheus + notify: Restart prometheus - name: Configure prometheus.args ansible.builtin.template: src: prometheus.args.j2 dest: /opt/homebrew/etc/prometheus.args mode: '0644' - notify: restart prometheus + notify: Restart prometheus - name: Ensure prometheus service is started ansible.builtin.command: brew services start prometheus - register: brew_start - changed_when: "'Successfully started' in brew_start.stdout" + register: prometheus_brew_start + changed_when: "'Successfully started' in prometheus_brew_start.stdout" failed_when: false diff --git a/ansible/roles/tailscale_serve/defaults/main.yml b/ansible/roles/tailscale_serve/defaults/main.yml index b739213..b076fcd 100644 --- a/ansible/roles/tailscale_serve/defaults/main.yml +++ b/ansible/roles/tailscale_serve/defaults/main.yml @@ -2,7 +2,7 @@ # Tailscale serve configuration for this host # Each service maps a Tailscale service name to local endpoints -tailscale_services: +tailscale_serve_services: - name: svc:grafana https: port: 443 diff --git a/ansible/roles/tailscale_serve/tasks/main.yml b/ansible/roles/tailscale_serve/tasks/main.yml index 247756f..bf7d7be 100644 --- a/ansible/roles/tailscale_serve/tasks/main.yml +++ b/ansible/roles/tailscale_serve/tasks/main.yml @@ -1,23 +1,24 @@ --- - name: Get current tailscale serve status ansible.builtin.command: tailscale serve status --json - register: serve_status + register: tailscale_serve_status changed_when: false - name: Parse serve status ansible.builtin.set_fact: - serve_config: "{{ ((serve_status.stdout | default('{}', true)) | from_json).Services | default({}) }}" + tailscale_serve_config: "{{ ((tailscale_serve_status.stdout | default('{}', true)) | from_json).Services | default({}) }}" # Configure HTTPS if service doesn't have Web config yet - name: Configure HTTPS services ansible.builtin.command: > tailscale serve --service="{{ item.name }}" --https={{ item.https.port }} {{ item.https.upstream }} - loop: "{{ tailscale_services }}" + loop: "{{ tailscale_serve_services }}" when: - item.https is defined - - serve_config[item.name] is not defined or serve_config[item.name].Web is not defined - register: https_result + - tailscale_serve_config[item.name] is not defined or tailscale_serve_config[item.name].Web is not defined + register: tailscale_serve_https_result + changed_when: true failed_when: false # Configure TCP if service doesn't have the specific port configured yet @@ -25,12 +26,13 @@ ansible.builtin.command: > tailscale serve --service="{{ item.name }}" --tcp={{ item.tcp.port }} {{ item.tcp.upstream }} - loop: "{{ tailscale_services }}" + loop: "{{ tailscale_serve_services }}" when: - item.tcp is defined - - serve_config[item.name] is not defined or - serve_config[item.name].TCP is not defined or - serve_config[item.name].TCP[item.tcp.port | string] is not defined or - serve_config[item.name].TCP[item.tcp.port | string].TCPForward is not defined - register: tcp_result + - tailscale_serve_config[item.name] is not defined or + tailscale_serve_config[item.name].TCP is not defined or + tailscale_serve_config[item.name].TCP[item.tcp.port | string] is not defined or + tailscale_serve_config[item.name].TCP[item.tcp.port | string].TCPForward is not defined + register: tailscale_serve_tcp_result + changed_when: true failed_when: false diff --git a/ansible/roles/transmission/handlers/main.yml b/ansible/roles/transmission/handlers/main.yml index d2c0d1c..db948a4 100644 --- a/ansible/roles/transmission/handlers/main.yml +++ b/ansible/roles/transmission/handlers/main.yml @@ -1,3 +1,4 @@ --- -- name: restart transmission +- name: Restart transmission ansible.builtin.command: brew services restart transmission-cli + changed_when: true diff --git a/ansible/roles/transmission/tasks/main.yml b/ansible/roles/transmission/tasks/main.yml index 9b941ca..f264b0d 100644 --- a/ansible/roles/transmission/tasks/main.yml +++ b/ansible/roles/transmission/tasks/main.yml @@ -29,12 +29,12 @@ dest: "{{ transmission_config_dir }}/settings.json" mode: '0600' check_mode: true - register: settings_check + register: transmission_settings_check - name: Stop transmission before config changes ansible.builtin.command: brew services stop transmission-cli - when: settings_check.changed - register: brew_stop + when: transmission_settings_check.changed + register: transmission_brew_stop changed_when: false failed_when: false @@ -43,10 +43,10 @@ src: settings.json.j2 dest: "{{ transmission_config_dir }}/settings.json" mode: '0600' - notify: restart transmission + notify: Restart transmission - name: Ensure transmission service is started ansible.builtin.command: brew services start transmission-cli - register: brew_start - changed_when: "'Successfully started' in brew_start.stdout" + register: transmission_brew_start + changed_when: "'Successfully started' in transmission_brew_start.stdout" failed_when: false diff --git a/ansible/roles/transmission_metrics/defaults/main.yml b/ansible/roles/transmission_metrics/defaults/main.yml index 7423637..9e9e2b0 100644 --- a/ansible/roles/transmission_metrics/defaults/main.yml +++ b/ansible/roles/transmission_metrics/defaults/main.yml @@ -1,7 +1,7 @@ --- -transmission_rpc_host: 127.0.0.1 -transmission_rpc_port: 9091 +transmission_metrics_rpc_host: 127.0.0.1 +transmission_metrics_rpc_port: 9091 transmission_metrics_dir: /opt/homebrew/var/node_exporter/textfile transmission_metrics_script: /Users/erichblume/bin/transmission-metrics transmission_metrics_interval: 60 # seconds between metric collection -transmission_log_dir: /opt/homebrew/var/log +transmission_metrics_log_dir: /opt/homebrew/var/log diff --git a/ansible/roles/transmission_metrics/handlers/main.yml b/ansible/roles/transmission_metrics/handlers/main.yml index c95a96d..5e4d922 100644 --- a/ansible/roles/transmission_metrics/handlers/main.yml +++ b/ansible/roles/transmission_metrics/handlers/main.yml @@ -1,5 +1,6 @@ --- -- name: reload transmission-metrics +- name: Reload transmission-metrics ansible.builtin.shell: | launchctl unload ~/Library/LaunchAgents/mcquack.eblume.transmission-metrics.plist 2>/dev/null || true launchctl load ~/Library/LaunchAgents/mcquack.eblume.transmission-metrics.plist + changed_when: true diff --git a/ansible/roles/transmission_metrics/tasks/main.yml b/ansible/roles/transmission_metrics/tasks/main.yml index 01fa31a..31323c9 100644 --- a/ansible/roles/transmission_metrics/tasks/main.yml +++ b/ansible/roles/transmission_metrics/tasks/main.yml @@ -4,22 +4,23 @@ src: transmission-metrics.sh.j2 dest: "{{ transmission_metrics_script }}" mode: '0755' - notify: reload transmission-metrics + notify: Reload transmission-metrics - name: Deploy transmission-metrics LaunchAgent plist ansible.builtin.template: src: transmission-metrics.plist.j2 dest: ~/Library/LaunchAgents/mcquack.eblume.transmission-metrics.plist mode: '0644' - notify: reload transmission-metrics + notify: Reload transmission-metrics - name: Check if transmission-metrics LaunchAgent is loaded ansible.builtin.command: launchctl list mcquack.eblume.transmission-metrics - register: launchctl_check + register: transmission_metrics_launchctl_check changed_when: false failed_when: false - name: Load transmission-metrics LaunchAgent if not loaded ansible.builtin.command: launchctl load ~/Library/LaunchAgents/mcquack.eblume.transmission-metrics.plist - when: launchctl_check.rc != 0 + when: transmission_metrics_launchctl_check.rc != 0 + changed_when: true failed_when: false diff --git a/ansible/roles/transmission_metrics/templates/transmission-metrics.plist.j2 b/ansible/roles/transmission_metrics/templates/transmission-metrics.plist.j2 index 3761007..a68e0c8 100644 --- a/ansible/roles/transmission_metrics/templates/transmission-metrics.plist.j2 +++ b/ansible/roles/transmission_metrics/templates/transmission-metrics.plist.j2 @@ -19,8 +19,8 @@ RunAtLoad StandardErrorPath - {{ transmission_log_dir }}/transmission-metrics.err.log + {{ transmission_metrics_log_dir }}/transmission-metrics.err.log StandardOutPath - {{ transmission_log_dir }}/transmission-metrics.out.log + {{ transmission_metrics_log_dir }}/transmission-metrics.out.log diff --git a/ansible/roles/transmission_metrics/templates/transmission-metrics.sh.j2 b/ansible/roles/transmission_metrics/templates/transmission-metrics.sh.j2 index 8eb12a0..0e394af 100644 --- a/ansible/roles/transmission_metrics/templates/transmission-metrics.sh.j2 +++ b/ansible/roles/transmission_metrics/templates/transmission-metrics.sh.j2 @@ -4,7 +4,7 @@ set -euo pipefail -RPC_URL="http://{{ transmission_rpc_host }}:{{ transmission_rpc_port }}/transmission/rpc" +RPC_URL="http://{{ transmission_metrics_rpc_host }}:{{ transmission_metrics_rpc_port }}/transmission/rpc" OUTPUT_FILE="{{ transmission_metrics_dir }}/transmission.prom" TEMP_FILE="${OUTPUT_FILE}.tmp" diff --git a/mise-tasks/indri-services-check b/mise-tasks/indri-services-check index a7b7593..3d0b375 100755 --- a/mise-tasks/indri-services-check +++ b/mise-tasks/indri-services-check @@ -6,7 +6,6 @@ set -euo pipefail # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' -YELLOW='\033[0;33m' NC='\033[0m' # No Color FAILED=0 diff --git a/mise-tasks/tailnet-preview b/mise-tasks/tailnet-preview index e387ad5..dd9e308 100755 --- a/mise-tasks/tailnet-preview +++ b/mise-tasks/tailnet-preview @@ -3,8 +3,10 @@ set -euo pipefail -export TAILSCALE_OAUTH_CLIENT_ID=$(op --vault vg6xf6vvfmoh5hqjjhlhbeoaie item get wi6bkf7bcccwfy4eu776ab4p4u --fields client_id) -export TAILSCALE_OAUTH_CLIENT_SECRET=$(op --vault vg6xf6vvfmoh5hqjjhlhbeoaie item get wi6bkf7bcccwfy4eu776ab4p4u --fields client_secret --reveal) +TAILSCALE_OAUTH_CLIENT_ID=$(op --vault vg6xf6vvfmoh5hqjjhlhbeoaie item get wi6bkf7bcccwfy4eu776ab4p4u --fields client_id) +export TAILSCALE_OAUTH_CLIENT_ID +TAILSCALE_OAUTH_CLIENT_SECRET=$(op --vault vg6xf6vvfmoh5hqjjhlhbeoaie item get wi6bkf7bcccwfy4eu776ab4p4u --fields client_secret --reveal) +export TAILSCALE_OAUTH_CLIENT_SECRET export TAILSCALE_TAILNET="tail8d86e.ts.net" cd "$(dirname "$0")/../pulumi" diff --git a/mise-tasks/tailnet-up b/mise-tasks/tailnet-up index 54fb798..4b097b6 100755 --- a/mise-tasks/tailnet-up +++ b/mise-tasks/tailnet-up @@ -3,8 +3,10 @@ set -euo pipefail -export TAILSCALE_OAUTH_CLIENT_ID=$(op --vault vg6xf6vvfmoh5hqjjhlhbeoaie item get wi6bkf7bcccwfy4eu776ab4p4u --fields client_id) -export TAILSCALE_OAUTH_CLIENT_SECRET=$(op --vault vg6xf6vvfmoh5hqjjhlhbeoaie item get wi6bkf7bcccwfy4eu776ab4p4u --fields client_secret --reveal) +TAILSCALE_OAUTH_CLIENT_ID=$(op --vault vg6xf6vvfmoh5hqjjhlhbeoaie item get wi6bkf7bcccwfy4eu776ab4p4u --fields client_id) +export TAILSCALE_OAUTH_CLIENT_ID +TAILSCALE_OAUTH_CLIENT_SECRET=$(op --vault vg6xf6vvfmoh5hqjjhlhbeoaie item get wi6bkf7bcccwfy4eu776ab4p4u --fields client_secret --reveal) +export TAILSCALE_OAUTH_CLIENT_SECRET export TAILSCALE_TAILNET="tail8d86e.ts.net" cd "$(dirname "$0")/../pulumi" diff --git a/pulumi/Pulumi.tail8d86e.yaml b/pulumi/Pulumi.tail8d86e.yaml index 712b360..3f6ee01 100644 --- a/pulumi/Pulumi.tail8d86e.yaml +++ b/pulumi/Pulumi.tail8d86e.yaml @@ -1,2 +1,3 @@ +--- config: tailscale:tailnet: tail8d86e.ts.net diff --git a/pulumi/Pulumi.yaml b/pulumi/Pulumi.yaml index ebfaed6..b1af300 100644 --- a/pulumi/Pulumi.yaml +++ b/pulumi/Pulumi.yaml @@ -1,3 +1,4 @@ +--- name: blumeops-tailnet runtime: name: python diff --git a/pulumi/pyproject.toml b/pulumi/pyproject.toml index 9b7d4aa..932eede 100644 --- a/pulumi/pyproject.toml +++ b/pulumi/pyproject.toml @@ -2,7 +2,4 @@ name = "blumeops-tailnet" version = "0.1.0" requires-python = ">=3.11" -dependencies = [ - "pulumi>=3.0.0", - "pulumi-tailscale>=0.24.0", -] +dependencies = ["pulumi>=3.0.0", "pulumi-tailscale>=0.24.0"]