diff --git a/README.md b/README.md index 5616c5e..d6b0889 100644 --- a/README.md +++ b/README.md @@ -214,10 +214,12 @@ be added to your Graphana instance. Feel free to edit and submit Pull Requests o ## TODO - [X] Finish adding support for serviceAccount - [X] Add support for lidarr -- [ ] Add metrics for Plex (Tautulli) -- [ ] Add metrics for transmission +- [X] Add metrics for Plex (Tautulli) +- [X] Add metrics for transmission - [ ] Add support for Readarr - [ ] Add support for sabnzbz - [ ] Add support for Overseer - [ ] Add support for Requestrr +- [ ] Fix transmission dashboard +- [ ] move secrets to secrets API diff --git a/charts/k8s-mediamanager/Chart.yaml b/charts/k8s-mediamanager/Chart.yaml index d7c99b5..d928f09 100644 --- a/charts/k8s-mediamanager/Chart.yaml +++ b/charts/k8s-mediamanager/Chart.yaml @@ -2,5 +2,5 @@ apiVersion: v2 name: k8s-mediamanager description: Kubernetes media manager helm chart based on onedr0p rootless images type: application -version: 1.1.0 -appVersion: "1.1.0" +version: 1.2.0 +appVersion: "1.2.0" diff --git a/charts/k8s-mediamanager/dashboards/transmission-dashboard.json b/charts/k8s-mediamanager/dashboards/transmission-dashboard.json new file mode 100644 index 0000000..b088545 --- /dev/null +++ b/charts/k8s-mediamanager/dashboards/transmission-dashboard.json @@ -0,0 +1,1594 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "gnetId": 15116, + "graphTooltip": 0, + "id": 3, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "decimals": 2, + "mappings": [ + { + "id": 0, + "op": "=", + "text": "N/A", + "type": 1, + "value": "null" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 0, + "y": 0 + }, + "id": 34, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "transmission_session_stats_downloaded_bytes{type=\"current\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Session Downloaded", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "decimals": 2, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 6, + "y": 0 + }, + "id": 30, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "transmission_session_stats_downloaded_bytes{type=\"cumulative\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "All Time Downloaded", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "decimals": 2, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgb(255, 172, 10)", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 12, + "y": 0 + }, + "id": 32, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "transmission_session_stats_uploaded_bytes{type=\"cumulative\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "refId": "A", + "useBackend": false + } + ], + "title": "All Time Uploaded", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "decimals": 2, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgb(255, 172, 10)", + "value": null + } + ] + }, + "unit": "decbytes" + }, + "overrides": [] + }, + "gridPos": { + "h": 5, + "w": 6, + "x": 18, + "y": 0 + }, + "id": 35, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "disableTextWrap": false, + "editorMode": "builder", + "expr": "transmission_session_stats_uploaded_bytes{type=\"current\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "__auto", + "refId": "A", + "useBackend": false + } + ], + "title": "Session Uploaded", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 0, + "y": 5 + }, + "id": 6, + "maxDataPoints": 100, + "options": { + "colorMode": "none", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "count(transmission_torrent_status != -1)", + "instant": true, + "interval": "", + "legendFormat": "__auto", + "refId": "A" + } + ], + "title": "Total Torrents", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "color": "rgb(33, 33, 35)", + "text": "0" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgb(33, 33, 35)", + "value": null + }, + { + "color": "#37872D", + "value": 1 + }, + { + "color": "#d44a3a" + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 3, + "y": 5 + }, + "id": 8, + "maxDataPoints": 100, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "sum(transmission_torrent_peers_sending_to_us)", + "instant": true, + "legendFormat": "__auto", + "refId": "A" + } + ], + "title": "Downloading From", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 2, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "transparent", + "value": null + }, + { + "color": "#37872D", + "value": 1 + } + ] + }, + "unit": "Bps" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 6, + "y": 5 + }, + "id": 12, + "maxDataPoints": 100, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "transmission_session_stats_download_speed_bytes", + "instant": true, + "legendFormat": "__auto", + "refId": "A" + } + ], + "title": "Global Download Speed", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 2, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "text": "N/A" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgb(33, 33, 35)", + "value": null + }, + { + "color": "rgba(237, 158, 40, 0.89)", + "value": 1 + }, + { + "color": "#d44a3a" + } + ] + }, + "unit": "Bps" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 12, + "y": 5 + }, + "id": 14, + "maxDataPoints": 100, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "transmission_session_stats_upload_speed_bytes", + "instant": true, + "refId": "A" + } + ], + "title": "Global Upload Speed", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [ + { + "options": { + "match": "null", + "result": { + "color": "rgb(33, 33, 35)", + "text": "0" + } + }, + "type": "special" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "rgb(33, 33, 35)", + "value": null + }, + { + "color": "red", + "value": 0 + }, + { + "color": "orange", + "value": 7 + }, + { + "color": "yellow", + "value": 15 + }, + { + "color": "green", + "value": 25 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 18, + "y": 5 + }, + "id": 10, + "maxDataPoints": 100, + "options": { + "colorMode": "background", + "graphMode": "none", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "mean" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "sum(transmission_torrent_peers_getting_from_us)", + "instant": true, + "refId": "A" + } + ], + "title": "Seeding To", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "decimals": 2, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + } + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 3, + "x": 21, + "y": 5 + }, + "id": 37, + "options": { + "minVizHeight": 75, + "minVizWidth": 75, + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showThresholdLabels": false, + "showThresholdMarkers": true, + "sizing": "auto", + "text": {} + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "disableTextWrap": false, + "editorMode": "code", + "exemplar": true, + "expr": "transmission_session_stats_uploaded_bytes{type=\"cumulative\"} / transmission_session_stats_downloaded_bytes{type=\"cumulative\"}", + "fullMetaSearch": false, + "includeNullMetadata": true, + "interval": "", + "legendFormat": "__auto", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Global Ratio", + "type": "gauge" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 2, + "links": [], + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 50 + }, + { + "color": "red", + "value": 70 + } + ] + }, + "unit": "Bps" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 2, + "interval": "5", + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "transmission_session_stats_download_speed_bytes", + "interval": "", + "legendFormat": "Downloaded", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "transmission_session_stats_upload_speed_bytes", + "interval": "", + "legendFormat": "Upload", + "range": true, + "refId": "B" + } + ], + "title": "Upload / Download Speeds", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisGridShow": true, + "axisLabel": "", + "axisPlacement": "left", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 11, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "smooth", + "lineStyle": { + "fill": "solid" + }, + "lineWidth": 1.4, + "pointSize": 1, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "decimals": 2, + "fieldMinMax": false, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "Bps" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 26, + "interval": "5", + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": false, + "width": 200 + }, + "tooltip": { + "hoverProximity": 1, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "disableTextWrap": false, + "editorMode": "builder", + "exemplar": false, + "expr": "topk(5, transmission_torrent_upload_bytes)", + "format": "time_series", + "fullMetaSearch": false, + "includeNullMetadata": true, + "instant": false, + "legendFormat": "{{name}}", + "range": true, + "refId": "A", + "useBackend": false + } + ], + "title": "Upload Speed by Torrent", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": { + "align": "auto", + "cellOptions": { + "type": "auto" + }, + "inspect": false + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "Progress" + }, + "properties": [ + { + "id": "unit", + "value": "percentunit" + }, + { + "id": "decimals", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Download Speed" + }, + "properties": [ + { + "id": "unit", + "value": "Bps" + }, + { + "id": "decimals", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Upload Speed" + }, + "properties": [ + { + "id": "unit", + "value": "Bps" + }, + { + "id": "decimals", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Bytes Downloaded" + }, + "properties": [ + { + "id": "unit", + "value": "decbytes" + }, + { + "id": "decimals", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Bytes Uploaded" + }, + "properties": [ + { + "id": "unit", + "value": "decbytes" + }, + { + "id": "decimals", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Date Added" + }, + "properties": [ + { + "id": "unit", + "value": "dateTimeAsSystem" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Ratio" + }, + "properties": [ + { + "id": "decimals", + "value": 2 + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Status" + }, + "properties": [ + { + "id": "mappings", + "value": [ + { + "options": { + "0": { + "color": "red", + "index": 0, + "text": "Stopped" + }, + "1": { + "color": "orange", + "index": 1, + "text": "Checking" + }, + "2": { + "color": "orange", + "index": 2, + "text": "Checking" + }, + "3": { + "color": "blue", + "index": 3, + "text": "Downloading" + }, + "4": { + "color": "blue", + "index": 4, + "text": "Downloading" + }, + "5": { + "color": "green", + "index": 5, + "text": "Seeding" + }, + "6": { + "color": "green", + "index": 6, + "text": "Seeding" + } + }, + "type": "value" + } + ] + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 23 + }, + "id": 24, + "options": { + "cellHeight": "sm", + "footer": { + "countRows": false, + "fields": "", + "reducer": [ + "sum" + ], + "show": false + }, + "frameIndex": 0, + "showHeader": true, + "sortBy": [ + { + "desc": true, + "displayName": "Upload Speed" + } + ] + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "disableTextWrap": false, + "editorMode": "builder", + "exemplar": false, + "expr": "transmission_torrent_added * 1000", + "format": "table", + "fullMetaSearch": false, + "hide": false, + "includeNullMetadata": false, + "instant": true, + "legendFormat": "Added", + "range": false, + "refId": "A", + "useBackend": false + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "exemplar": false, + "expr": "transmission_torrent_done", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "Done", + "range": false, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "exemplar": false, + "expr": "transmission_torrent_downloaded_ever_bytes", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "Bytes Downloaded", + "range": false, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "exemplar": false, + "expr": "transmission_torrent_peers_getting_from_us", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "Leechers", + "range": false, + "refId": "D" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "exemplar": false, + "expr": "transmission_torrent_peers_sending_to_us", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "Seeders", + "range": false, + "refId": "E" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "exemplar": false, + "expr": "transmission_torrent_ratio", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "Ratio", + "range": false, + "refId": "F" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "exemplar": false, + "expr": "transmission_torrent_uploaded_ever_bytes", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "Bytes Uploaded", + "range": false, + "refId": "G" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "exemplar": false, + "expr": "transmission_torrent_status", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "Status", + "range": false, + "refId": "H" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "exemplar": false, + "expr": "transmission_torrent_upload_bytes", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "Upload Speed", + "range": false, + "refId": "I" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "exemplar": false, + "expr": "transmission_torrent_download_bytes", + "format": "table", + "hide": false, + "instant": true, + "legendFormat": "Download Speed", + "range": false, + "refId": "J" + } + ], + "title": "Torrents", + "transformations": [ + { + "id": "concatenate", + "options": { + "frameNameLabel": "", + "frameNameMode": "drop" + } + }, + { + "id": "filterFieldsByName", + "options": { + "byVariable": false, + "include": { + "names": [ + "name 1", + "Value #A", + "Value #B", + "Value #C", + "Value #D", + "Value #E", + "Value #F", + "Value #G", + "Value #H", + "Value #J", + "Value #I" + ] + } + } + }, + { + "id": "organize", + "options": { + "excludeByName": {}, + "includeByName": {}, + "indexByName": { + "Value #A": 8, + "Value #B": 1, + "Value #C": 4, + "Value #D": 7, + "Value #E": 6, + "Value #F": 9, + "Value #G": 5, + "Value #H": 10, + "Value #I": 3, + "Value #J": 2, + "name 1": 0 + }, + "renameByName": { + "Value #A": "Date Added", + "Value #B": "Progress", + "Value #C": "Bytes Downloaded", + "Value #D": "Leechers", + "Value #E": "Seeders", + "Value #F": "Ratio", + "Value #G": "Bytes Uploaded", + "Value #H": "Status", + "Value #I": "Upload Speed", + "Value #J": "Download Speed", + "name 1": "Name" + } + } + } + ], + "type": "table" + }, + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "fieldConfig": { + "defaults": { + "decimals": 2, + "mappings": [ + { + "from": "", + "id": 2, + "operator": "", + "text": "N/A", + "to": "", + "type": 1, + "value": "null" + } + ], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "dark-red", + "value": null + }, + { + "color": "dark-orange", + "value": 0.25 + }, + { + "color": "#EAB839", + "value": 0.5 + }, + { + "color": "semi-dark-green", + "value": 0.75 + }, + { + "color": "rgb(206, 206, 206)", + "value": 1 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 10, + "w": 24, + "x": 0, + "y": 30 + }, + "id": 22, + "options": { + "displayMode": "lcd", + "maxVizHeight": 300, + "minVizHeight": 16, + "minVizWidth": 8, + "namePlacement": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showUnfilled": true, + "sizing": "auto", + "text": {}, + "valueMode": "color" + }, + "pluginVersion": "10.4.3", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "PBFA97CFB590B2093" + }, + "editorMode": "code", + "expr": "transmission_torrent_done < 1", + "instant": true, + "legendFormat": "{{name}}", + "refId": "A" + } + ], + "title": "Incomplete Torrents", + "type": "bargauge" + } + ], + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Transmission", + "uid": "OEyH9tQZk", + "version": 52, + "weekStart": "" + } \ No newline at end of file diff --git a/charts/k8s-mediamanager/templates/exportarr-dashboard.cm.yaml b/charts/k8s-mediamanager/templates/exportarr-dashboard.cm.yaml index 1a70d0f..644db8e 100644 --- a/charts/k8s-mediamanager/templates/exportarr-dashboard.cm.yaml +++ b/charts/k8s-mediamanager/templates/exportarr-dashboard.cm.yaml @@ -1,4 +1,4 @@ -{{ if or (.Values.prowlarr.exportarr.enabled) (.Values.sonarr.exportarr.enabled) (.Values.radarr.exportarr.enabled) }} +{{ if or (.Values.prowlarr.metrics.enabled) (.Values.sonarr.metrics.enabled) (.Values.radarr.metrics.enabled) }} apiVersion: v1 kind: ConfigMap metadata: diff --git a/charts/k8s-mediamanager/templates/lidarr/lidarr-resources.yaml b/charts/k8s-mediamanager/templates/lidarr/lidarr-resources.yaml index 49812b8..57990ef 100644 --- a/charts/k8s-mediamanager/templates/lidarr/lidarr-resources.yaml +++ b/charts/k8s-mediamanager/templates/lidarr/lidarr-resources.yaml @@ -78,6 +78,9 @@ spec: {{- include "k8s-mediamanager.selectorLabels" . | nindent 8 }} app: lidarr spec: + {{- if .Values.serviceAccount.create }} + serviceAccountName: {{ include "k8s-mediamanager.serviceAccountName" . }} + {{- end }} securityContext: runAsNonRoot: true runAsUser: {{ .Values.general.puid }} @@ -100,22 +103,22 @@ spec: drop: - ALL containers: - {{- if .Values.lidarr.exportarr.enabled }} + {{- if .Values.lidarr.metrics.enabled }} - name: metrics securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL - image: "{{ .Values.lidarr.exportarr.image }}:{{ .Values.lidarr.exportarr.imageTag }}" + image: "{{ .Values.lidarr.metrics.image }}:{{ .Values.lidarr.metrics.imageTag }}" imagePullPolicy: IfNotPresent args: - lidarr env: - name: PORT - value: {{ .Values.lidarr.exportarr.port | quote }} + value: {{ .Values.lidarr.metrics.port | quote }} - name: URL - value: "http://localhost:{{ .Values.lidarr.container.port }}{{ .Values.lidarr.exportarr.urlBase }}" + value: "http://localhost:{{ .Values.lidarr.container.port }}{{ .Values.lidarr.ingress.path }}" - name: APIKEY {{- if .Values.lidarr.apiKey }} value: {{ .Values.lidarr.apiKey }} @@ -127,20 +130,16 @@ spec: key: api-key {{- end }} ports: - - name: monitoring - containerPort: {{ .Values.lidarr.exportarr.port }} + - name: metrics + containerPort: {{ .Values.lidarr.metrics.port }} livenessProbe: httpGet: - path: /healthz - port: monitoring - failureThreshold: 5 - periodSeconds: 10 + path: /metrics + port: metrics readinessProbe: httpGet: - path: /healthz - port: monitoring - failureThreshold: 5 - periodSeconds: 10 + path: /metrics + port: metrics {{- end }} - name: {{ include "k8s-mediamanager.fullname" . }}-lidarr securityContext: @@ -153,13 +152,18 @@ spec: envFrom: - configMapRef: name: lidarr-config - image: "{{ .Values.lidarr.container.image }}:{{ .Values.lidarr.container.tag | default .Values.general.image_tag }}" + image: "{{ .Values.lidarr.container.image }}:{{ .Values.lidarr.container.tag }}" imagePullPolicy: Always + livenessProbe: + httpGet: + path: {{ .Values.lidarr.ingress.path }} + port: {{ .Values.lidarr.container.port }} + initialDelaySeconds: 10 readinessProbe: - tcpSocket: + httpGet: + path: {{ .Values.lidarr.ingress.path }} port: {{ .Values.lidarr.container.port }} initialDelaySeconds: 10 - periodSeconds: 20 ports: - name: lidarr-port containerPort: {{ .Values.lidarr.container.port }} @@ -223,11 +227,11 @@ spec: nodePort: {{ .Values.lidarr.service.nodePort }} {{ end }} name: lidarr-port - {{- if .Values.sonarr.exportarr.enabled }} - - port: {{ .Values.sonarr.exportarr.port }} - targetPort: {{ .Values.sonarr.exportarr.port }} + {{- if .Values.sonarr.metrics.enabled }} + - port: {{ .Values.sonarr.metrics.port }} + targetPort: {{ .Values.sonarr.metrics.port }} protocol: TCP - name: monitoring + name: metrics {{- end }} selector: app: lidarr @@ -267,7 +271,7 @@ spec: number: {{ .Values.lidarr.service.port }} {{ end }} --- -{{ if .Values.lidarr.exportarr.serviceMonitor }} +{{ if .Values.lidarr.metrics.serviceMonitor }} apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: @@ -279,7 +283,7 @@ spec: matchLabels: app: lidarr endpoints: - - port: monitoring + - port: metrics scheme: http path: /metrics {{ end }} diff --git a/charts/k8s-mediamanager/templates/plex/plex-resources.yml b/charts/k8s-mediamanager/templates/plex/plex-resources.yml index ed29c1a..d037e1d 100644 --- a/charts/k8s-mediamanager/templates/plex/plex-resources.yml +++ b/charts/k8s-mediamanager/templates/plex/plex-resources.yml @@ -25,7 +25,34 @@ spec: {{- toYaml . | nindent 4 }} {{- end }} {{- end }} +{{- with .Values.plex.tautulli.volume }} --- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ .name }} + {{ with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{ with .labels }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + accessModes: + - {{ .accessModes }} + resources: + requests: + storage: {{ .storage }} + storageClassName: {{ .storageClassName }} + {{ with .selector }} + selector: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +--- +### PLEX ### CONFIGMAP apiVersion: v1 kind: ConfigMap @@ -36,6 +63,39 @@ data: PUID: "{{ .Values.general.puid }}" PLEX_CLAIM: {{ .Values.plex.claim }} --- +### TAUTULLI +### INIT-CONTAINER +apiVersion: v1 +kind: ConfigMap +metadata: + name: init-tautulli-cm +data: + config.ini: | + [General] + http_host = :: + http_port = {{ .Values.plex.tautulli.container.port }} + http_root = {{ .Values.plex.tautulli.ingress.path }} + pms_ip = localhost + pms_port = {{ .Values.plex.container.port }} + pms_url = "http://localhost:{{ .Values.plex.container.port }}" + launch_browser = 0 + init-tautulli.sh: | + #!/bin/bash + echo "### Initializing config" + if [ ! -f /tautulli-config/config.ini ]; then + cp -n /init-tautulli/config.ini /tautulli-config/config.ini + echo "### No configuration found, intialized with default settings ###" + fi +--- +### CONFIGMAP +apiVersion: v1 +kind: ConfigMap +metadata: + name: tautulli-config +data: + PGID: "{{ .Values.general.pgid }}" + PUID: "{{ .Values.general.puid }}" +--- ### DEPLOYMENT apiVersion: apps/v1 kind: Deployment @@ -54,7 +114,9 @@ spec: {{- include "k8s-mediamanager.selectorLabels" . | nindent 8 }} app: plex spec: + {{- if .Values.serviceAccount.create }} serviceAccountName: {{ include "k8s-mediamanager.serviceAccountName" . }} + {{- end }} securityContext: runAsNonRoot: true runAsUser: {{ .Values.general.puid }} @@ -66,14 +128,75 @@ spec: - name: media persistentVolumeClaim: claimName: {{ .Values.general.sharedStorage.persistentVolumeClaim.claimName }} - - name: config + - name: plex-config persistentVolumeClaim: claimName: {{ .Values.plex.volume.name }} + - name: tautulli-config + persistentVolumeClaim: + claimName: {{ .Values.plex.tautulli.volume.name }} + - name: init-tautulli-cm + configMap: + defaultMode: 493 + name: init-tautulli-cm {{- if .Values.plex.extraVolumes }} {{- toYaml .Values.plex.extraVolumes | nindent 8}} {{- end }} hostNetwork: {{ .Values.plex.hostNetwork }} + initContainers: + - name: tautuli-config + image: docker.io/ubuntu:groovy + command: ["/init-tautulli/init-tautulli.sh"] + imagePullPolicy: IfNotPresent + volumeMounts: + - mountPath: /init-tautulli + name: init-tautulli-cm + - name: tautulli-config + mountPath: /tautulli-config + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL containers: + - name: {{ include "k8s-mediamanager.fullname" . }}-tautulli + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + command: ["python", "Tautulli.py"] + args: [ + "--config", "/config/config.ini", + "--datadir", "/config", + "--port", {{ .Values.plex.tautulli.container.port | quote }} + ] + envFrom: + - configMapRef: + name: tautulli-config + image: "{{ .Values.plex.tautulli.container.image }}:{{ .Values.plex.tautulli.container.tag }}" + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: {{ .Values.plex.tautulli.ingress.path }} + port: {{ .Values.plex.tautulli.container.port }} + initialDelaySeconds: 10 + readinessProbe: + httpGet: + path: {{ .Values.plex.tautulli.ingress.path }} + port: {{ .Values.plex.tautulli.container.port }} + initialDelaySeconds: 10 + ports: + - name: tautulli-port + containerPort: {{ .Values.plex.tautulli.container.port }} + protocol: TCP + volumeMounts: + - name: tautulli-config + mountPath: /config + {{- if .Values.plex.extraVolumeMounts }} + {{- toYaml .Values.plex.extraVolumeMounts | nindent 12}} + {{- end }} + resources: + {{- toYaml .Values.plex.tautulli.resources | nindent 12 }} - name: {{ include "k8s-mediamanager.fullname" . }}-plex securityContext: allowPrivilegeEscalation: false @@ -83,22 +206,24 @@ spec: envFrom: - configMapRef: name: plex-config - image: "{{ .Values.plex.container.image }}:{{ .Values.plex.container.tag | default .Values.general.image_tag }}" - imagePullPolicy: Always + image: "{{ .Values.plex.container.image }}:{{ .Values.plex.container.tag }}" + imagePullPolicy: IfNotPresent livenessProbe: httpGet: path: /identity port: {{ .Values.plex.container.port }} + initialDelaySeconds: 10 readinessProbe: httpGet: path: /identity port: {{ .Values.plex.container.port }} + initialDelaySeconds: 10 ports: - name: plex-port containerPort: {{ .Values.plex.container.port }} protocol: TCP volumeMounts: - - name: config + - name: plex-config mountPath: /config - name: media mountPath: /movies @@ -138,12 +263,38 @@ spec: targetPort: {{ .Values.plex.container.port }} protocol: TCP name: plex-port -{{ if eq .Values.plex.service.type "NodePort" }} + {{ if eq .Values.plex.service.type "NodePort" }} nodePort: {{ .Values.plex.service.nodePort }} -{{ end }} + {{ end }} selector: app: plex - +--- +{{ if .Values.plex.tautulli.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "k8s-mediamanager.fullname" . }}-tautulli + labels: + {{- include "k8s-mediamanager.labels" . | nindent 4 }} + app: plex +spec: + ipFamilyPolicy: {{ .Values.general.ipFamilyPolicy }} + ipFamilies: + {{ if .Values.general.ipFamilies }} + {{- toYaml .Values.general.ipFamilies | nindent 4 }} + {{- end }} + type: {{ .Values.plex.tautulli.service.type }} + ports: + - port: {{ .Values.plex.tautulli.service.port }} + targetPort: {{ .Values.plex.tautulli.container.port }} + protocol: TCP + name: tautulli-port + {{ if eq .Values.plex.tautulli.service.type "NodePort" }} + nodePort: {{ .Values.plex.tautulli.service.nodePort }} + {{ end }} + selector: + app: plex +{{ end }} --- ### INGRESS {{ if .Values.plex.ingress.enabled }} @@ -178,4 +329,38 @@ spec: port: number: {{ .Values.plex.service.port }} {{ end }} +--- +{{ if .Values.plex.tautulli.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "k8s-mediamanager.fullname" . }}-tautulli + labels: + {{- include "k8s-mediamanager.labels" . | nindent 4 }} + app: plex + {{- with .Values.plex.tautulli.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.plex.tautulli.ingress.tls.enabled }} + tls: + - hosts: + - {{ .Values.general.ingress_host | quote }} + secretName: {{ .Values.general.ingress_host }}-tls + {{ end }} + ingressClassName: {{ .Values.general.ingress.ingressClassName }} + ingressClassName: {{ .Values.general.ingress.ingressClassName }} + rules: + - host: {{ .Values.general.ingress_host | quote }} + http: + paths: + - path: {{ .Values.plex.tautulli.ingress.path }} + pathType: Prefix + backend: + service: + name: {{ include "k8s-mediamanager.fullname" . }}-tautulli + port: + number: {{ .Values.plex.tautulli.service.port }} +{{ end }} {{ end }} diff --git a/charts/k8s-mediamanager/templates/prowlarr/prowlarr-resources.yml b/charts/k8s-mediamanager/templates/prowlarr/prowlarr-resources.yml index 807d527..7aef88b 100644 --- a/charts/k8s-mediamanager/templates/prowlarr/prowlarr-resources.yml +++ b/charts/k8s-mediamanager/templates/prowlarr/prowlarr-resources.yml @@ -75,7 +75,9 @@ spec: {{- include "k8s-mediamanager.selectorLabels" . | nindent 8 }} app: prowlarr spec: + {{- if .Values.serviceAccount.create }} serviceAccountName: {{ include "k8s-mediamanager.serviceAccountName" . }} + {{- end }} securityContext: runAsNonRoot: true runAsUser: {{ .Values.general.puid }} @@ -87,6 +89,7 @@ spec: - name: config-prowlarr image: docker.io/ubuntu:groovy command: ["/init-prowlarr/init-prowlarr.sh"] + imagePullPolicy: IfNotPresent volumeMounts: - mountPath: /init-prowlarr name: init-files-prowlarr @@ -98,22 +101,22 @@ spec: drop: - ALL containers: - {{- if .Values.prowlarr.exportarr.enabled}} + {{- if .Values.prowlarr.metrics.enabled}} - name: metrics securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL - image: "{{ .Values.prowlarr.exportarr.image }}:{{ .Values.prowlarr.exportarr.imageTag }}" + image: "{{ .Values.prowlarr.metrics.image }}:{{ .Values.prowlarr.metrics.imageTag }}" imagePullPolicy: IfNotPresent args: - prowlarr env: - name: PORT - value: {{ .Values.prowlarr.exportarr.port | quote }} + value: {{ .Values.prowlarr.metrics.port | quote }} - name: URL - value: "http://localhost:{{ .Values.prowlarr.container.port }}{{ .Values.prowlarr.exportarr.urlBase }}" + value: "http://localhost:{{ .Values.prowlarr.container.port }}{{ .Values.prowlarr.ingress.path }}" - name: APIKEY {{- if .Values.prowlarr.apiKey }} value: {{ .Values.prowlarr.apiKey }} @@ -125,22 +128,20 @@ spec: key: api-key {{- end }} - name: PROWLARR__BACKFILL - value: {{ .Values.prowlarr.exportarr.backfill | quote }} + value: {{ .Values.prowlarr.metrics.backfill | quote }} ports: - - name: monitoring - containerPort: {{ .Values.prowlarr.exportarr.port }} + - name: metrics + containerPort: {{ .Values.prowlarr.metrics.port }} livenessProbe: httpGet: - path: /healthz - port: monitoring - failureThreshold: 5 - periodSeconds: 10 + path: /metrics + port: metrics + initialDelaySeconds: 10 readinessProbe: httpGet: - path: /healthz - port: monitoring - failureThreshold: 5 - periodSeconds: 10 + path: /metrics + port: metrics + initialDelaySeconds: 10 {{- end }} - name: {{ include "k8s-mediamanager.fullname" . }}-prowlarr securityContext: @@ -151,16 +152,18 @@ spec: envFrom: - configMapRef: name: prowlarr-config - image: "{{ .Values.prowlarr.container.image }}:{{ .Values.prowlarr.container.tag | default .Values.general.image_tag }}" + image: "{{ .Values.prowlarr.container.image }}:{{ .Values.prowlarr.container.tag }}" imagePullPolicy: Always livenessProbe: httpGet: - path: / + path: {{ .Values.prowlarr.ingress.path }} port: {{ .Values.prowlarr.container.port }} + initialDelaySeconds: 10 readinessProbe: httpGet: - path: / + path: {{ .Values.prowlarr.ingress.path }} port: {{ .Values.prowlarr.container.port }} + initialDelaySeconds: 10 ports: - name: prowlarr-port containerPort: {{ .Values.prowlarr.container.port }} @@ -218,11 +221,11 @@ spec: nodePort: {{ .Values.prowlarr.service.nodePort }} {{ end }} name: prowlarr-port - {{- if .Values.prowlarr.exportarr.enabled }} - - port: {{ .Values.prowlarr.exportarr.port }} - targetPort: {{ .Values.prowlarr.exportarr.port }} + {{- if .Values.prowlarr.metrics.enabled }} + - port: {{ .Values.prowlarr.metrics.port }} + targetPort: {{ .Values.prowlarr.metrics.port }} protocol: TCP - name: monitoring + name: metrics {{- end }} selector: app: prowlarr @@ -261,7 +264,7 @@ spec: number: {{ .Values.prowlarr.service.port }} {{ end }} --- -{{ if .Values.prowlarr.exportarr.serviceMonitor }} +{{ if .Values.prowlarr.metrics.serviceMonitor }} apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: @@ -273,7 +276,7 @@ spec: matchLabels: app: prowlarr endpoints: - - port: monitoring + - port: metrics scheme: http path: /metrics {{ end }} diff --git a/charts/k8s-mediamanager/templates/radarr/radarr-resources.yml b/charts/k8s-mediamanager/templates/radarr/radarr-resources.yml index 328256a..60c58cc 100644 --- a/charts/k8s-mediamanager/templates/radarr/radarr-resources.yml +++ b/charts/k8s-mediamanager/templates/radarr/radarr-resources.yml @@ -78,6 +78,9 @@ spec: {{- include "k8s-mediamanager.selectorLabels" . | nindent 8 }} app: radarr spec: + {{- if .Values.serviceAccount.create }} + serviceAccountName: {{ include "k8s-mediamanager.serviceAccountName" . }} + {{- end }} securityContext: runAsNonRoot: true runAsUser: {{ .Values.general.puid }} @@ -100,22 +103,22 @@ spec: drop: - ALL containers: - {{- if .Values.radarr.exportarr.enabled }} + {{- if .Values.radarr.metrics.enabled }} - name: metrics securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL - image: "{{ .Values.radarr.exportarr.image }}:{{ .Values.radarr.exportarr.imageTag }}" + image: "{{ .Values.radarr.metrics.image }}:{{ .Values.radarr.metrics.imageTag }}" imagePullPolicy: IfNotPresent args: - radarr env: - name: PORT - value: {{ .Values.radarr.exportarr.port | quote }} + value: {{ .Values.radarr.metrics.port | quote }} - name: URL - value: "http://localhost:{{ .Values.radarr.container.port }}{{ .Values.radarr.exportarr.urlBase }}" + value: "http://localhost:{{ .Values.radarr.container.port }}{{ .Values.radarr.ingress.path}}" - name: APIKEY {{- if .Values.radarr.apiKey }} value: {{ .Values.radarr.apiKey }} @@ -127,20 +130,18 @@ spec: key: api-key {{- end }} ports: - - name: monitoring - containerPort: {{ .Values.radarr.exportarr.port }} + - name: metrics + containerPort: {{ .Values.radarr.metrics.port }} livenessProbe: httpGet: - path: /healthz - port: monitoring - failureThreshold: 5 - periodSeconds: 10 + path: /metrics + port: metrics + initialDelaySeconds: 10 readinessProbe: httpGet: - path: /healthz - port: monitoring - failureThreshold: 5 - periodSeconds: 10 + path: /metrics + port: metrics + initialDelaySeconds: 10 {{- end }} - name: {{ include "k8s-mediamanager.fullname" . }}-radarr securityContext: @@ -153,13 +154,18 @@ spec: envFrom: - configMapRef: name: radarr-config - image: "{{ .Values.radarr.container.image }}:{{ .Values.radarr.container.tag | default .Values.general.image_tag }}" + image: "{{ .Values.radarr.container.image }}:{{ .Values.radarr.container.tag }}" imagePullPolicy: Always + livenessProbe: + httpGet: + path: {{ .Values.radarr.ingress.path }} + port: {{ .Values.radarr.container.port }} + initialDelaySeconds: 10 readinessProbe: - tcpSocket: + httpGet: + path: {{ .Values.radarr.ingress.path }} port: {{ .Values.radarr.container.port }} initialDelaySeconds: 10 - periodSeconds: 20 ports: - name: radarr-port containerPort: {{ .Values.radarr.container.port }} @@ -223,11 +229,11 @@ spec: nodePort: {{ .Values.radarr.service.nodePort }} {{ end }} name: radarr-port - {{- if .Values.sonarr.exportarr.enabled }} - - port: {{ .Values.sonarr.exportarr.port }} - targetPort: {{ .Values.sonarr.exportarr.port }} + {{- if .Values.sonarr.metrics.enabled }} + - port: {{ .Values.sonarr.metrics.port }} + targetPort: {{ .Values.sonarr.metrics.port }} protocol: TCP - name: monitoring + name: metrics {{- end }} selector: app: radarr @@ -267,7 +273,7 @@ spec: number: {{ .Values.radarr.service.port }} {{ end }} --- -{{ if .Values.radarr.exportarr.serviceMonitor }} +{{ if .Values.radarr.metrics.serviceMonitor }} apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: @@ -279,7 +285,7 @@ spec: matchLabels: app: radarr endpoints: - - port: monitoring + - port: metrics scheme: http path: /metrics {{ end }} diff --git a/charts/k8s-mediamanager/templates/sonarr/sonarr-resources.yml b/charts/k8s-mediamanager/templates/sonarr/sonarr-resources.yml index 7a55af9..a42ed68 100644 --- a/charts/k8s-mediamanager/templates/sonarr/sonarr-resources.yml +++ b/charts/k8s-mediamanager/templates/sonarr/sonarr-resources.yml @@ -77,7 +77,9 @@ spec: {{- include "k8s-mediamanager.selectorLabels" . | nindent 8 }} app: sonarr spec: + {{- if .Values.serviceAccount.create }} serviceAccountName: {{ include "k8s-mediamanager.serviceAccountName" . }} + {{- end }} securityContext: runAsNonRoot: true runAsUser: {{ .Values.general.puid }} @@ -100,22 +102,22 @@ spec: drop: - ALL containers: - {{- if .Values.sonarr.exportarr.enabled }} + {{- if .Values.sonarr.metrics.enabled }} - name: metrics securityContext: allowPrivilegeEscalation: false capabilities: drop: - ALL - image: "{{ .Values.radarr.exportarr.image }}:{{ .Values.radarr.exportarr.imageTag }}" + image: "{{ .Values.radarr.metrics.image }}:{{ .Values.radarr.metrics.imageTag }}" imagePullPolicy: IfNotPresent args: - sonarr env: - name: PORT - value: {{ .Values.sonarr.exportarr.port | quote }} + value: {{ .Values.sonarr.metrics.port | quote }} - name: URL - value: "http://localhost:{{ .Values.sonarr.container.port }}{{ .Values.sonarr.exportarr.urlBase }}" + value: "http://localhost:{{ .Values.sonarr.container.port }}{{ .Values.sonarr.ingress.path }}" - name: APIKEY {{- if .Values.sonarr.apiKey }} value: {{ .Values.sonarr.apiKey }} @@ -127,20 +129,18 @@ spec: key: api-key {{- end }} ports: - - name: monitoring - containerPort: {{ .Values.sonarr.exportarr.port | default 9090 }} + - name: metrics + containerPort: {{ .Values.sonarr.metrics.port | default 9090 }} livenessProbe: httpGet: - path: /healthz - port: monitoring - failureThreshold: 5 - periodSeconds: 10 + path: /metrics + port: metrics + initialDelaySeconds: 10 readinessProbe: httpGet: - path: /healthz - port: monitoring - failureThreshold: 5 - periodSeconds: 10 + path: /metrics + port: metrics + initialDelaySeconds: 10 {{- end }} - name: {{ include "k8s-mediamanager.fullname" . }}-sonarr securityContext: @@ -153,13 +153,18 @@ spec: envFrom: - configMapRef: name: sonarr-config - image: "{{ .Values.sonarr.container.image }}:{{ .Values.sonarr.container.tag | default .Values.general.image_tag }}" + image: "{{ .Values.sonarr.container.image }}:{{ .Values.sonarr.container.tag }}" imagePullPolicy: Always + livenessProbe: + httpGet: + path: {{ .Values.sonarr.ingress.path }} + port: {{ .Values.sonarr.container.port }} + initialDelaySeconds: 10 readinessProbe: - tcpSocket: + httpGet: + path: {{ .Values.sonarr.ingress.path }} port: {{ .Values.sonarr.container.port }} initialDelaySeconds: 10 - periodSeconds: 20 ports: - name: sonarr-port containerPort: {{ .Values.sonarr.container.port }} @@ -217,11 +222,11 @@ spec: nodePort: {{ .Values.sonarr.service.nodePort }} {{ end }} name: sonarr-port - {{- if .Values.sonarr.exportarr.enabled }} - - port: {{ .Values.sonarr.exportarr.port }} - targetPort: {{ .Values.sonarr.exportarr.port }} + {{- if .Values.sonarr.metrics.enabled }} + - port: {{ .Values.sonarr.metrics.port }} + targetPort: {{ .Values.sonarr.metrics.port }} protocol: TCP - name: monitoring + name: metrics {{- end }} selector: app: sonarr @@ -260,7 +265,7 @@ spec: number: {{ .Values.sonarr.service.port }} {{ end }} --- -{{ if .Values.sonarr.exportarr.serviceMonitor }} +{{ if .Values.sonarr.metrics.serviceMonitor }} apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: @@ -272,7 +277,7 @@ spec: matchLabels: app: sonarr endpoints: - - port: monitoring + - port: metrics scheme: http path: /metrics {{ end }} diff --git a/charts/k8s-mediamanager/templates/transmission-dashboard.cm.yaml b/charts/k8s-mediamanager/templates/transmission-dashboard.cm.yaml new file mode 100644 index 0000000..b129074 --- /dev/null +++ b/charts/k8s-mediamanager/templates/transmission-dashboard.cm.yaml @@ -0,0 +1,11 @@ +{{ if .Values.transmission.metrics.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: transmission-dashboard + labels: + grafana_dashboard: "1" + {{- include "k8s-mediamanager.labels" . | nindent 4 }} +data: +{{ (.Files.Glob "dashboards/transmission-dashboard.json").AsConfig | indent 2 }} +{{ end }} diff --git a/charts/k8s-mediamanager/templates/transmission/transmission-resources.yml b/charts/k8s-mediamanager/templates/transmission/transmission-resources.yml index 24c7a68..d4ce5fc 100644 --- a/charts/k8s-mediamanager/templates/transmission/transmission-resources.yml +++ b/charts/k8s-mediamanager/templates/transmission/transmission-resources.yml @@ -64,7 +64,9 @@ spec: {{- include "k8s-mediamanager.selectorLabels" . | nindent 8 }} app: transmission spec: + {{- if .Values.serviceAccount.create }} serviceAccountName: {{ include "k8s-mediamanager.serviceAccountName" . }} + {{- end }} securityContext: runAsNonRoot: true runAsUser: {{ .Values.general.puid }} @@ -73,6 +75,38 @@ spec: seccompProfile: type: RuntimeDefault containers: + - name: metrics + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + image: "{{ .Values.transmission.metrics.image }}:{{ .Values.transmission.metrics.imageTag }}" + imagePullPolicy: IfNotPresent + env: + - name: WEB_PATH + value: /metrics + - name: WEB_PORT + value: "{{ .Values.transmission.metrics.port }}" + - name: TRANSMISSION_ADD + value: "http://localhost:{{ .Values.transmission.container.port.rpc }}{{ .Values.transmission.ingress.path }}" + - name: TRANSMISSION_USERNAME + value: "{{ .Values.transmission.config.auth.username }}" + - name: TRANSMISSION_PASSWORD + value: "{{ .Values.transmission.config.auth.password }}" + ports: + - name: metrics + containerPort: {{ .Values.transmission.metrics.port | default 9090 }} + livenessProbe: + httpGet: + path: /metrics + port: metrics + initialDelaySeconds: 10 + readinessProbe: + httpGet: + path: /metrics + port: metrics + initialDelaySeconds: 10 - name: {{ include "k8s-mediamanager.fullname" . }}-transmission securityContext: allowPrivilegeEscalation: false @@ -82,14 +116,16 @@ spec: envFrom: - configMapRef: name: transmission-config - image: "{{ .Values.transmission.container.image }}:{{ .Values.transmission.container.tag | default .Values.general.image_tag }}" + image: "{{ .Values.transmission.container.image }}:{{ .Values.transmission.container.tag }}" imagePullPolicy: Always livenessProbe: tcpSocket: port: {{ .Values.transmission.container.port.rpc }} + initialDelaySeconds: 10 readinessProbe: tcpSocket: port: {{ .Values.transmission.container.port.rpc }} + initialDelaySeconds: 10 ports: - name: trans-port containerPort: {{ .Values.transmission.container.port.rpc }} @@ -152,9 +188,15 @@ spec: targetPort: {{ .Values.transmission.container.port.rpc }} protocol: TCP name: trans-port -{{ if eq .Values.transmission.service.rpc.type "NodePort" }} + {{ if eq .Values.transmission.service.rpc.type "NodePort" }} nodePort: {{ .Values.transmission.service.rpc.nodePort }} -{{ end }} + {{ end }} + {{- if .Values.transmission.metrics.enabled }} + - port: {{ .Values.transmission.metrics.port }} + targetPort: {{ .Values.transmission.metrics.port }} + protocol: TCP + name: metrics + {{- end }} selector: app: transmission --- @@ -177,16 +219,16 @@ spec: targetPort: {{ .Values.transmission.container.port.peer }} protocol: TCP name: trans-peer-tcp -{{ if eq .Values.transmission.service.peer.type "NodePort" }} + {{ if eq .Values.transmission.service.peer.type "NodePort" }} nodePort: {{ .Values.transmission.service.peer.nodePort }} -{{ end }} + {{ end }} - port: {{ .Values.transmission.service.peer.port }} targetPort: {{ .Values.transmission.container.port.peer }} protocol: UDP name: trans-peer-udp -{{ if eq .Values.transmission.service.peer.type "NodePort" }} + {{ if eq .Values.transmission.service.peer.type "NodePort" }} nodePort: {{ .Values.transmission.service.peer.nodePortUDP }} -{{ end }} + {{ end }} selector: app: transmission --- @@ -223,4 +265,21 @@ spec: port: number: {{ .Values.transmission.service.rpc.port }} {{ end }} +--- +{{ if .Values.transmission.metrics.serviceMonitor }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "k8s-mediamanager.fullname" . }}-transmission + labels: + app: transmission +spec: + selector: + matchLabels: + app: transmission + endpoints: + - port: metrics + scheme: http + path: /metrics +{{ end }} {{ end }} diff --git a/charts/k8s-mediamanager/values.yaml b/charts/k8s-mediamanager/values.yaml index e782e0d..eb660f9 100644 --- a/charts/k8s-mediamanager/values.yaml +++ b/charts/k8s-mediamanager/values.yaml @@ -39,10 +39,9 @@ general: subPaths: tv: media/tv movies: media/movies + music: media/music downloads: downloads transmission: transmission - sabnzbd: sabnzbd - config: config ingress: ingressClassName: "" @@ -80,6 +79,39 @@ plex: storageClassName: "" extraVolumes: {} extraVolumeMounts: {} + tautulli: + enabled: true + container: + image: ghcr.io/tautulli/tautulli + tag: v2.14.4 + nodeSelector: {} + port: 8181 + service: + type: ClusterIP # ClusterIP, NodePort, LoadBalancer + port: 8181 + nodePort: # Only required if service type is NodePort + ingress: + enabled: true + path: /tautulli + annotations: {} + tls: + enabled: false + secretName: "" + resources: + requests: + cpu: "50m" + memory: "96Mi" + limits: + cpu: "150m" + memory: "128Mi" + volume: + name: tautulli-config + accessModes: "ReadWriteOnce" + storage: "1Gi" + storageClassName: "" + extraVolumes: {} + extraVolumeMounts: {} + prowlarr: enabled: true @@ -116,13 +148,12 @@ prowlarr: storageClassName: "" extraVolumes: {} extraVolumeMounts: {} - exportarr: + metrics: image: ghcr.io/onedr0p/exportarr imageTag: v2.0.1 enabled: true serviceMonitor: true port: 9090 - urlBase: "/prowlarr" backfill: true radarr: @@ -161,13 +192,12 @@ radarr: storageClassName: "" extraVolumes: {} extraVolumeMounts: {} - exportarr: + metrics: image: ghcr.io/onedr0p/exportarr imageTag: v2.0.1 enabled: true serviceMonitor: true port: 9090 - urlBase: "/radarr" sonarr: enabled: true @@ -204,13 +234,12 @@ sonarr: storageClassName: "" extraVolumes: {} extraVolumeMounts: {} - exportarr: + metrics: image: ghcr.io/onedr0p/exportarr imageTag: v2.0.1 enabled: true serviceMonitor: true port: 9090 - urlBase: /sonarr lidarr: enabled: true @@ -247,13 +276,12 @@ lidarr: storageClassName: "" extraVolumes: {} extraVolumeMounts: {} - exportarr: + metrics: image: ghcr.io/onedr0p/exportarr imageTag: v2.0.1 enabled: true serviceMonitor: true port: 9090 - urlBase: /lidarr transmission: enabled: true @@ -300,3 +328,9 @@ transmission: storageClassName: "" extraVolumes: {} extraVolumeMounts: {} + metrics: + enabled: true + image: docker.io/evanofslack/transmission-exporter + imageTag: latest + serviceMonitor: true + port: 19091 \ No newline at end of file