Compare commits
2 commits
73d2f44d74
...
e276c47686
| Author | SHA1 | Date | |
|---|---|---|---|
| e276c47686 | |||
| 8552656731 |
14 changed files with 780 additions and 490 deletions
|
|
@ -20,7 +20,7 @@ This documentation is automatically generated from your colmena flake configurat
|
||||||
## 🚀 Quick Actions
|
## 🚀 Quick Actions
|
||||||
|
|
||||||
### View Current Status
|
### View Current Status
|
||||||
\`\`\`bash
|
```bash
|
||||||
# Service status across fleet (if homelab CLI is available)
|
# Service status across fleet (if homelab CLI is available)
|
||||||
homelab services --global
|
homelab services --global
|
||||||
|
|
||||||
|
|
@ -29,22 +29,22 @@ homelab backups --global
|
||||||
|
|
||||||
# Overall status
|
# Overall status
|
||||||
homelab status
|
homelab status
|
||||||
\`\`\`
|
```
|
||||||
|
|
||||||
### Update Documentation
|
### Update Documentation
|
||||||
\`\`\`bash
|
```bash
|
||||||
# Regenerate all documentation
|
# Regenerate all documentation
|
||||||
homelab-generate-docs ./docs
|
homelab-generate-docs ./docs
|
||||||
|
|
||||||
# Generate in different directory
|
# Generate in different directory
|
||||||
homelab-generate-docs /path/to/output
|
homelab-generate-docs /path/to/output
|
||||||
\`\`\`
|
```
|
||||||
|
|
||||||
## 📋 Quick Stats
|
## 📋 Quick Stats
|
||||||
|
|
||||||
- **Total Nodes**: 2
|
- **Total Nodes**: 2
|
||||||
- **Homelab-Enabled Nodes**: 2
|
- **Homelab-Enabled Nodes**: 2
|
||||||
- **Generated**: tir 29 jul 16:57:16 CEST 2025
|
- **Generated**: ons 30 jul 00:20:46 CEST 2025
|
||||||
|
|
||||||
## 🛠️ Management Tools
|
## 🛠️ Management Tools
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,15 +11,15 @@
|
||||||
|--------|-------|
|
|--------|-------|
|
||||||
| Total Nodes | 2 |
|
| Total Nodes | 2 |
|
||||||
| Homelab-Enabled Nodes | 2 |
|
| Homelab-Enabled Nodes | 2 |
|
||||||
| Unique Services | 1 |
|
| Unique Services | 4 |
|
||||||
| Service Instances | 1 |
|
| Service Instances | 4 |
|
||||||
|
|
||||||
## Node Status
|
## Node Status
|
||||||
|
|
||||||
| Node | Homelab | Environment | Services | Monitoring | Backups | Proxy |
|
| Node | Homelab | Environment | Services | Monitoring | Backups | Proxy |
|
||||||
|------|---------|-------------|----------|------------|---------|-------|
|
|------|---------|-------------|----------|------------|---------|-------|
|
||||||
| `photos` | ✅ | production | 1 | ✅ | ❌ | ❌ |
|
| `photos` | ✅ | production | 1 | ✅ | ❌ | ❌ |
|
||||||
| `sandbox` | ✅ | production | 0 | ✅ | ✅ | ❌ |
|
| `sandbox` | ✅ | production | 3 | ✅ | ✅ | ❌ |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
| Node | Service Count | Services |
|
| Node | Service Count | Services |
|
||||||
|------|---------------|----------|
|
|------|---------------|----------|
|
||||||
| `photos` | 1 | minio |
|
| `photos` | 1 | minio |
|
||||||
| `sandbox` | 0 | |
|
| `sandbox` | 3 | gatus, grafana, prometheus |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,10 +61,10 @@
|
||||||
|
|
||||||
| Service | Enabled | Port | Description | Tags |
|
| Service | Enabled | Port | Description | Tags |
|
||||||
|---------|---------|------|-------------|------|
|
|---------|---------|------|-------------|------|
|
||||||
| `gatus` | ❌ | 8080 | Gatus Status Page | |
|
| `gatus` | ✅ | 8080 | Gatus Status Page | |
|
||||||
| `grafana` | ❌ | 3000 | Grafana Metrics Dashboard | |
|
| `grafana` | ✅ | 3000 | Grafana Metrics Dashboard | |
|
||||||
| `minio` | ❌ | 9000 | minio | |
|
| `minio` | ❌ | 9000 | minio | |
|
||||||
| `prometheus` | ❌ | 9090 | Prometheus Monitoring Server | |
|
| `prometheus` | ✅ | 9090 | Prometheus Monitoring Server | |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
452
docs/services.md
452
docs/services.md
|
|
@ -1,10 +1,13 @@
|
||||||
# Service Catalog
|
# Service Catalog
|
||||||
|
|
||||||
> Available services and their configuration options
|
> Complete service documentation with core options, feature integrations, and smart defaults
|
||||||
>
|
>
|
||||||
> Generated on: $(date)
|
> Generated on: $(date)
|
||||||
|
|
||||||
This document catalogs all available homelab services, their configuration options, and integration capabilities.
|
This document provides comprehensive documentation for homelab services, organized by:
|
||||||
|
- **Core Service Options**: The main service configuration
|
||||||
|
- **Feature Integrations**: Available monitoring, logging, and proxy features
|
||||||
|
- **Service Defaults**: What this service configures by default for each feature
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
|
|
@ -12,142 +15,252 @@ This document catalogs all available homelab services, their configuration optio
|
||||||
|
|
||||||
## Service Integration Matrix
|
## Service Integration Matrix
|
||||||
|
|
||||||
| Service | Monitoring | Logging | Proxy | Auth Default |
|
| Service | Core Options | Monitoring | Logging | Proxy | Deployments |
|
||||||
|---------|------------|---------|-------|--------------|
|
|---------|--------------|------------|---------|-------|-------------|
|
||||||
| `gatus` | ❌ | ❌ | ❌ | 🌐 |
|
| `gatus` | 11 | 📊 | 📝 | 🔀 | 1 |
|
||||||
| `grafana` | ❌ | ❌ | ❌ | 🌐 |
|
| `grafana` | 3 | 📊 | 📝 | 🔀 | 1 |
|
||||||
| `minio` | ❌ | ❌ | ❌ | 🌐 |
|
| `minio` | 4 | ❌ | ❌ | ❌ | 1 |
|
||||||
| `prometheus` | ❌ | ❌ | ❌ | 🌐 |
|
| `prometheus` | 12 | 📊 | 📝 | 🔀 | 1 |
|
||||||
|
|
||||||
**Legend:** ✅ = Enabled by default, ❌ = Available but disabled, 🔒 = Auth required, 🌐 = Public access
|
**Legend:** 📊📝🔀 = Feature available, ❌ = Feature not available
|
||||||
|
|
||||||
## Service Reference
|
## Service Documentation
|
||||||
|
|
||||||
### gatus
|
### gatus
|
||||||
|
|
||||||
**Description:** Gatus Status Page
|
**Deployment Status:** 1/2 nodes have this service enabled
|
||||||
|
|
||||||
**Default Port:** `8080`
|
#### Core Service Options
|
||||||
|
|
||||||
**Current Deployments:** 0 instance(s) on:
|
The main configuration options for gatus:
|
||||||
|
|
||||||
#### Default Integration Status
|
|
||||||
|
|
||||||
| Integration | Status | Default Configuration |
|
|
||||||
|-------------|--------|----------------------|
|
|
||||||
| 📊 Monitoring | ❌ Disabled | Available but requires `monitoring.enable = true` |
|
|
||||||
| 📝 Logging | ❌ Disabled | Available but requires `logging.enable = true` |
|
|
||||||
| 🔀 Proxy | ❌ Disabled | Available but requires `proxy.enable = true` |
|
|
||||||
|
|
||||||
#### Core Configuration
|
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
homelab.services.gatus = {
|
homelab.services.gatus = {
|
||||||
enable = true;
|
alerting = {}; # Gatus alerting configuration
|
||||||
port = 8080;
|
description = Gatus Status Page; # No description
|
||||||
description = "Gatus Status Page";
|
enable = false; # Whether to enable Gatus Status Page.
|
||||||
|
extraConfig = {}; # Additional Gatus configuration options
|
||||||
# Default integrations (adjust as needed)
|
port = 8080; # No description
|
||||||
# monitoring.enable = true; # ❌ Disabled by default
|
storage = {
|
||||||
# logging.enable = true; # ❌ Disabled by default
|
"type": "memory"
|
||||||
# proxy.enable = true; # ❌ Disabled by default
|
}; # Gatus storage configuration
|
||||||
|
ui.buttons = [
|
||||||
|
{
|
||||||
|
"link": "https://grafana.procopius.dk",
|
||||||
|
"name": "Grafana"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"link": "https://prometheus.procopius.dk",
|
||||||
|
"name": "Prometheus"
|
||||||
|
}
|
||||||
|
]; # Navigation buttons in the Gatus interface
|
||||||
|
ui.header = Homelab Services Status; # Header text for the Gatus interface
|
||||||
|
ui.link = https://status.procopius.dk; # Link in the Gatus header
|
||||||
|
ui.title = Homelab Status; # Title for the Gatus web interface
|
||||||
|
web.address = 0.0.0.0; # Web interface bind address
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Service-Specific Options
|
#### Feature Integrations
|
||||||
|
|
||||||
Available configuration options for gatus:
|
##### 📊 Monitoring Integration
|
||||||
|
|
||||||
|
Available monitoring options:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
homelab.services.gatus = {
|
homelab.services.gatus = {
|
||||||
# ... core options above ...
|
# ... core options above ...
|
||||||
|
|
||||||
# Service-specific configuration
|
monitoring.enable = true; # Enable monitoring for gatus
|
||||||
alerting = {};
|
monitoring.extraLabels = {}; # No description
|
||||||
extraConfig = {};
|
monitoring.healthCheck.conditions = [
|
||||||
storage = {"type":"memory"};
|
"[STATUS] == 200"
|
||||||
ui = {"buttons":[{"link":"https://grafana.procopius.dk","name":"Grafana"},{"link":"https://prometheus.procopius.dk","name":"Prometheus"}],"header":"Homelab Services Status","link":"https://status.procopius.dk","title":"Homelab Status"};
|
]; # Health check conditions. Setting conditions enables health checks.
|
||||||
web = {"address":"0.0.0.0"};
|
monitoring.healthCheck.enable = true; # No description
|
||||||
|
monitoring.healthCheck.extraChecks = []; # Additional health checks. Adding checks enables health monitoring.
|
||||||
|
# monitoring.healthCheck.path = <null or string>; # Health check endpoint path. Setting this enables health checks.
|
||||||
|
monitoring.metrics.enable = false; # No description
|
||||||
|
monitoring.metrics.extraEndpoints = []; # Additional metrics endpoints. Adding endpoints enables metrics collection.
|
||||||
|
# monitoring.metrics.path = <null or string>; # Metrics endpoint path. Setting this enables metrics collection.
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**gatus sets these monitoring defaults:**
|
||||||
|
```nix
|
||||||
|
enable = true;
|
||||||
|
extraLabels = {};
|
||||||
|
healthCheck = {"conditions":["[STATUS] == 200"],"enable":true,"extraChecks":[],"path":null};
|
||||||
|
metrics = {"enable":false,"extraEndpoints":[],"path":null};
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 📝 Logging Integration
|
||||||
|
|
||||||
|
Available logging options:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
homelab.services.gatus = {
|
||||||
|
# ... core options above ...
|
||||||
|
|
||||||
|
logging.enable = false; # Enable logging for gatus
|
||||||
|
logging.extraLabels = {}; # No description
|
||||||
|
logging.extraSources = []; # No description
|
||||||
|
logging.files = []; # No description
|
||||||
|
# logging.multiline = <null or (submodule)>; # No description
|
||||||
|
logging.parsing.extractFields = []; # No description
|
||||||
|
# logging.parsing.regex = <null or string>; # No description
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**gatus sets these logging defaults:**
|
||||||
|
```nix
|
||||||
|
enable = false;
|
||||||
|
extraLabels = {};
|
||||||
|
extraSources = [];
|
||||||
|
files = [];
|
||||||
|
multiline = null;
|
||||||
|
parsing = {"extractFields":[],"regex":null};
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 🔀 Proxy Integration
|
||||||
|
|
||||||
|
Available proxy options:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
homelab.services.gatus = {
|
||||||
|
# ... core options above ...
|
||||||
|
|
||||||
|
proxy.additionalSubdomains = []; # No description
|
||||||
|
proxy.enable = true; # Enable reverse proxy for gatus
|
||||||
|
proxy.enableAuth = false; # No description
|
||||||
|
proxy.subdomain = gatus; # No description
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**gatus sets these proxy defaults:**
|
||||||
|
```nix
|
||||||
|
additionalSubdomains = [];
|
||||||
|
enable = true;
|
||||||
|
enableAuth = false;
|
||||||
|
subdomain = gatus;
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### grafana
|
### grafana
|
||||||
|
|
||||||
**Description:** Grafana Metrics Dashboard
|
**Deployment Status:** 1/2 nodes have this service enabled
|
||||||
|
|
||||||
**Default Port:** `3000`
|
#### Core Service Options
|
||||||
|
|
||||||
**Current Deployments:** 0 instance(s) on:
|
The main configuration options for grafana:
|
||||||
|
|
||||||
#### Default Integration Status
|
|
||||||
|
|
||||||
| Integration | Status | Default Configuration |
|
|
||||||
|-------------|--------|----------------------|
|
|
||||||
| 📊 Monitoring | ❌ Disabled | Available but requires `monitoring.enable = true` |
|
|
||||||
| 📝 Logging | ❌ Disabled | Available but requires `logging.enable = true` |
|
|
||||||
| 🔀 Proxy | ❌ Disabled | Available but requires `proxy.enable = true` |
|
|
||||||
|
|
||||||
#### Core Configuration
|
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
homelab.services.grafana = {
|
homelab.services.grafana = {
|
||||||
enable = true;
|
description = Grafana Metrics Dashboard; # No description
|
||||||
port = 3000;
|
enable = false; # Whether to enable Grafana Dashboard.
|
||||||
description = "Grafana Metrics Dashboard";
|
port = 3000; # No description
|
||||||
|
|
||||||
# Default integrations (adjust as needed)
|
|
||||||
# monitoring.enable = true; # ❌ Disabled by default
|
|
||||||
# logging.enable = true; # ❌ Disabled by default
|
|
||||||
# proxy.enable = true; # ❌ Disabled by default
|
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Feature Integrations
|
||||||
|
|
||||||
|
##### 📊 Monitoring Integration
|
||||||
|
|
||||||
|
Available monitoring options:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
homelab.services.grafana = {
|
||||||
|
# ... core options above ...
|
||||||
|
|
||||||
|
monitoring.enable = true; # Enable monitoring for grafana
|
||||||
|
monitoring.extraLabels = {}; # No description
|
||||||
|
monitoring.healthCheck.conditions = [
|
||||||
|
"[STATUS] == 200"
|
||||||
|
]; # Health check conditions. Setting conditions enables health checks.
|
||||||
|
monitoring.healthCheck.enable = true; # No description
|
||||||
|
monitoring.healthCheck.extraChecks = []; # Additional health checks. Adding checks enables health monitoring.
|
||||||
|
# monitoring.healthCheck.path = <null or string>; # Health check endpoint path. Setting this enables health checks.
|
||||||
|
monitoring.metrics.enable = false; # No description
|
||||||
|
monitoring.metrics.extraEndpoints = []; # Additional metrics endpoints. Adding endpoints enables metrics collection.
|
||||||
|
# monitoring.metrics.path = <null or string>; # Metrics endpoint path. Setting this enables metrics collection.
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**grafana sets these monitoring defaults:**
|
||||||
|
```nix
|
||||||
|
enable = true;
|
||||||
|
extraLabels = {};
|
||||||
|
healthCheck = {"conditions":["[STATUS] == 200"],"enable":true,"extraChecks":[],"path":null};
|
||||||
|
metrics = {"enable":false,"extraEndpoints":[],"path":null};
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 📝 Logging Integration
|
||||||
|
|
||||||
|
Available logging options:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
homelab.services.grafana = {
|
||||||
|
# ... core options above ...
|
||||||
|
|
||||||
|
logging.enable = false; # Enable logging for grafana
|
||||||
|
logging.extraLabels = {}; # No description
|
||||||
|
logging.extraSources = []; # No description
|
||||||
|
logging.files = []; # No description
|
||||||
|
# logging.multiline = <null or (submodule)>; # No description
|
||||||
|
logging.parsing.extractFields = []; # No description
|
||||||
|
# logging.parsing.regex = <null or string>; # No description
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**grafana sets these logging defaults:**
|
||||||
|
```nix
|
||||||
|
enable = false;
|
||||||
|
extraLabels = {};
|
||||||
|
extraSources = [];
|
||||||
|
files = [];
|
||||||
|
multiline = null;
|
||||||
|
parsing = {"extractFields":[],"regex":null};
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 🔀 Proxy Integration
|
||||||
|
|
||||||
|
Available proxy options:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
homelab.services.grafana = {
|
||||||
|
# ... core options above ...
|
||||||
|
|
||||||
|
proxy.additionalSubdomains = []; # No description
|
||||||
|
proxy.enable = true; # Enable reverse proxy for grafana
|
||||||
|
proxy.enableAuth = false; # No description
|
||||||
|
proxy.subdomain = grafana; # No description
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**grafana sets these proxy defaults:**
|
||||||
|
```nix
|
||||||
|
additionalSubdomains = [];
|
||||||
|
enable = true;
|
||||||
|
enableAuth = false;
|
||||||
|
subdomain = grafana;
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### minio
|
### minio
|
||||||
|
|
||||||
**Description:** minio
|
**Deployment Status:** 1/2 nodes have this service enabled
|
||||||
|
|
||||||
**Default Port:** `9000`
|
#### Core Service Options
|
||||||
|
|
||||||
**Current Deployments:** 1 instance(s) on: photos
|
The main configuration options for minio:
|
||||||
|
|
||||||
#### Default Integration Status
|
|
||||||
|
|
||||||
| Integration | Status | Default Configuration |
|
|
||||||
|-------------|--------|----------------------|
|
|
||||||
| 📊 Monitoring | ❌ Disabled | Available but requires `monitoring.enable = true` |
|
|
||||||
| 📝 Logging | ❌ Disabled | Available but requires `logging.enable = true` |
|
|
||||||
| 🔀 Proxy | ❌ Disabled | Available but requires `proxy.enable = true` |
|
|
||||||
|
|
||||||
#### Core Configuration
|
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
homelab.services.minio = {
|
homelab.services.minio = {
|
||||||
enable = true;
|
enable = false; # Whether to enable Minio Object Storage.
|
||||||
port = 9000;
|
openFirewall = true; # Whether to open the ports specified in `port` and `webPort` in the firewall.
|
||||||
description = "minio";
|
port = 9000; # Port of the server.
|
||||||
|
webPort = 9001; # Port of the web UI (console).
|
||||||
# Default integrations (adjust as needed)
|
|
||||||
# monitoring.enable = true; # ❌ Disabled by default
|
|
||||||
# logging.enable = true; # ❌ Disabled by default
|
|
||||||
# proxy.enable = true; # ❌ Disabled by default
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Service-Specific Options
|
|
||||||
|
|
||||||
Available configuration options for minio:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
homelab.services.minio = {
|
|
||||||
# ... core options above ...
|
|
||||||
|
|
||||||
# Service-specific configuration
|
|
||||||
openFirewall = true;
|
|
||||||
webPort = 9001;
|
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -155,75 +268,132 @@ homelab.services.minio = {
|
||||||
|
|
||||||
### prometheus
|
### prometheus
|
||||||
|
|
||||||
**Description:** Prometheus Monitoring Server
|
**Deployment Status:** 1/2 nodes have this service enabled
|
||||||
|
|
||||||
**Default Port:** `9090`
|
#### Core Service Options
|
||||||
|
|
||||||
**Current Deployments:** 0 instance(s) on:
|
The main configuration options for prometheus:
|
||||||
|
|
||||||
#### Default Integration Status
|
|
||||||
|
|
||||||
| Integration | Status | Default Configuration |
|
|
||||||
|-------------|--------|----------------------|
|
|
||||||
| 📊 Monitoring | ❌ Disabled | Available but requires `monitoring.enable = true` |
|
|
||||||
| 📝 Logging | ❌ Disabled | Available but requires `logging.enable = true` |
|
|
||||||
| 🔀 Proxy | ❌ Disabled | Available but requires `proxy.enable = true` |
|
|
||||||
|
|
||||||
#### Core Configuration
|
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
homelab.services.prometheus = {
|
homelab.services.prometheus = {
|
||||||
enable = true;
|
alertmanager.enable = true; # Enable integration with Alertmanager
|
||||||
port = 9090;
|
alertmanager.url = alertmanager.lab:9093; # Alertmanager URL
|
||||||
description = "Prometheus Monitoring Server";
|
description = Prometheus Monitoring Server; # No description
|
||||||
|
enable = false; # Whether to enable Prometheus Monitoring Server.
|
||||||
# Default integrations (adjust as needed)
|
extraAlertingRules = []; # Additional alerting rules
|
||||||
# monitoring.enable = true; # ❌ Disabled by default
|
extraFlags = []; # Extra command line flags
|
||||||
# logging.enable = true; # ❌ Disabled by default
|
extraScrapeConfigs = []; # Additional scrape configurations
|
||||||
# proxy.enable = true; # ❌ Disabled by default
|
globalConfig = {
|
||||||
|
"evaluation_interval": "15s",
|
||||||
|
"scrape_interval": "15s"
|
||||||
|
}; # Global Prometheus configuration
|
||||||
|
port = 9090; # No description
|
||||||
|
retention = 15d; # How long to retain metrics data
|
||||||
|
ruleFiles = []; # Additional rule files to load
|
||||||
|
systemdServices = [
|
||||||
|
"prometheus.service",
|
||||||
|
"prometheus"
|
||||||
|
]; # Systemd services to monitor
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Service-Specific Options
|
#### Feature Integrations
|
||||||
|
|
||||||
Available configuration options for prometheus:
|
##### 📊 Monitoring Integration
|
||||||
|
|
||||||
|
Available monitoring options:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
homelab.services.prometheus = {
|
homelab.services.prometheus = {
|
||||||
# ... core options above ...
|
# ... core options above ...
|
||||||
|
|
||||||
# Service-specific configuration
|
monitoring.enable = true; # Enable monitoring for prometheus
|
||||||
alertmanager = {"enable":true,"url":"alertmanager.lab:9093"};
|
monitoring.extraLabels = {}; # No description
|
||||||
extraAlertingRules = [];
|
monitoring.healthCheck.conditions = [
|
||||||
extraFlags = [];
|
"[STATUS] == 200"
|
||||||
extraScrapeConfigs = [];
|
]; # Health check conditions. Setting conditions enables health checks.
|
||||||
globalConfig = {"evaluation_interval":"15s","scrape_interval":"15s"};
|
monitoring.healthCheck.enable = true; # No description
|
||||||
retention = 15d;
|
monitoring.healthCheck.extraChecks = []; # Additional health checks. Adding checks enables health monitoring.
|
||||||
ruleFiles = [];
|
# monitoring.healthCheck.path = <null or string>; # Health check endpoint path. Setting this enables health checks.
|
||||||
systemdServices = ["prometheus.service","prometheus"];
|
monitoring.metrics.enable = false; # No description
|
||||||
|
monitoring.metrics.extraEndpoints = []; # Additional metrics endpoints. Adding endpoints enables metrics collection.
|
||||||
|
# monitoring.metrics.path = <null or string>; # Metrics endpoint path. Setting this enables metrics collection.
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**prometheus sets these monitoring defaults:**
|
||||||
|
```nix
|
||||||
|
enable = true;
|
||||||
|
extraLabels = {};
|
||||||
|
healthCheck = {"conditions":["[STATUS] == 200"],"enable":true,"extraChecks":[],"path":null};
|
||||||
|
metrics = {"enable":false,"extraEndpoints":[],"path":null};
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 📝 Logging Integration
|
||||||
|
|
||||||
|
Available logging options:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
homelab.services.prometheus = {
|
||||||
|
# ... core options above ...
|
||||||
|
|
||||||
|
logging.enable = false; # Enable logging for prometheus
|
||||||
|
logging.extraLabels = {}; # No description
|
||||||
|
logging.extraSources = []; # No description
|
||||||
|
logging.files = []; # No description
|
||||||
|
# logging.multiline = <null or (submodule)>; # No description
|
||||||
|
logging.parsing.extractFields = []; # No description
|
||||||
|
# logging.parsing.regex = <null or string>; # No description
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**prometheus sets these logging defaults:**
|
||||||
|
```nix
|
||||||
|
enable = false;
|
||||||
|
extraLabels = {};
|
||||||
|
extraSources = [];
|
||||||
|
files = [];
|
||||||
|
multiline = null;
|
||||||
|
parsing = {"extractFields":[],"regex":null};
|
||||||
|
```
|
||||||
|
|
||||||
|
##### 🔀 Proxy Integration
|
||||||
|
|
||||||
|
Available proxy options:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
homelab.services.prometheus = {
|
||||||
|
# ... core options above ...
|
||||||
|
|
||||||
|
proxy.additionalSubdomains = []; # No description
|
||||||
|
proxy.enable = true; # Enable reverse proxy for prometheus
|
||||||
|
proxy.enableAuth = false; # No description
|
||||||
|
proxy.subdomain = prometheus; # No description
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
**prometheus sets these proxy defaults:**
|
||||||
|
```nix
|
||||||
|
additionalSubdomains = [];
|
||||||
|
enable = true;
|
||||||
|
enableAuth = false;
|
||||||
|
subdomain = prometheus;
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Integration Summary
|
## Feature Reference
|
||||||
|
|
||||||
### Available Integration Types
|
### Integration Features
|
||||||
|
|
||||||
| Integration | Purpose | Default Behavior | Configuration |
|
Homelab services can integrate with three main features:
|
||||||
|-------------|---------|------------------|---------------|
|
|
||||||
| **📊 Monitoring** | Prometheus metrics + health checks | Service-dependent | `monitoring.enable = true` |
|
|
||||||
| **📝 Logging** | Centralized log collection | Service-dependent | `logging.enable = true` |
|
|
||||||
| **🔀 Proxy** | Reverse proxy with SSL + auth | Service-dependent | `proxy.enable = true` |
|
|
||||||
|
|
||||||
### Integration Benefits
|
- **📊 Monitoring**: Prometheus metrics and health checks
|
||||||
|
- **📝 Logging**: Centralized log collection with Promtail/Loki
|
||||||
|
- **🔀 Proxy**: Reverse proxy with SSL and authentication
|
||||||
|
|
||||||
- **🔄 Automatic Discovery:** Enabled integrations are automatically discovered by fleet-wide services
|
Each service can import these features and set service-specific defaults.
|
||||||
- **📊 Unified Monitoring:** All metrics and health checks appear in Prometheus/Grafana
|
|
||||||
- **📝 Centralized Logging:** All logs are collected and indexed in Loki
|
|
||||||
- **🌐 Consistent Access:** All services get consistent subdomain access with SSL
|
|
||||||
- **🎯 Smart Defaults:** Each service comes with sensible default configurations
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*This service catalog is generated from actual service configurations across your homelab fleet.*
|
*This documentation is generated from actual NixOS module evaluations.*
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,9 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
# services.loki.enable = true;
|
# services.loki.enable = true;
|
||||||
# services.prometheus.enable = true;
|
services.prometheus.enable = true;
|
||||||
# services.grafana.enable = true;
|
services.grafana.enable = true;
|
||||||
# services.gatus.enable = true;
|
services.gatus.enable = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
system.stateVersion = "25.05";
|
system.stateVersion = "25.05";
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,18 @@ serviceName: {
|
||||||
with lib; let
|
with lib; let
|
||||||
cfg = config.homelab.services.${serviceName};
|
cfg = config.homelab.services.${serviceName};
|
||||||
homelabCfg = config.homelab;
|
homelabCfg = config.homelab;
|
||||||
|
|
||||||
|
shouldEnableLogging =
|
||||||
|
cfg.logging.files
|
||||||
|
!= []
|
||||||
|
|| cfg.logging.extraSources != [];
|
||||||
in {
|
in {
|
||||||
options.homelab.services.${serviceName}.logging = {
|
options.homelab.services.${serviceName}.logging = {
|
||||||
enable = mkEnableOption "logging for ${serviceName}";
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = "Enable logging for ${serviceName}";
|
||||||
|
default = shouldEnableLogging;
|
||||||
|
};
|
||||||
|
|
||||||
files = mkOption {
|
files = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
|
|
@ -51,10 +60,10 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf (cfg.enable && cfg.logging.enable) {
|
config = mkIf cfg.enable {
|
||||||
homelab.logging.sources =
|
homelab.logging.sources = mkIf cfg.logging.enable (
|
||||||
[
|
# Only create file source if files are specified
|
||||||
{
|
(optional (cfg.logging.files != []) {
|
||||||
name = "${serviceName}-logs";
|
name = "${serviceName}-logs";
|
||||||
type = "file";
|
type = "file";
|
||||||
files = {
|
files = {
|
||||||
|
|
@ -69,19 +78,15 @@ in {
|
||||||
environment = homelabCfg.environment;
|
environment = homelabCfg.environment;
|
||||||
};
|
};
|
||||||
pipelineStages =
|
pipelineStages =
|
||||||
mkIf (cfg.logging.parsing.regex != null) [
|
(optional (cfg.logging.parsing.regex != null) {
|
||||||
{
|
|
||||||
regex.expression = cfg.logging.parsing.regex;
|
regex.expression = cfg.logging.parsing.regex;
|
||||||
}
|
})
|
||||||
]
|
++ (optional (cfg.logging.parsing.extractFields != []) {
|
||||||
++ [
|
|
||||||
{
|
|
||||||
labels = listToAttrs (map (field: nameValuePair field null) cfg.logging.parsing.extractFields);
|
labels = listToAttrs (map (field: nameValuePair field null) cfg.logging.parsing.extractFields);
|
||||||
}
|
});
|
||||||
];
|
|
||||||
enabled = true;
|
enabled = true;
|
||||||
}
|
})
|
||||||
]
|
++ cfg.logging.extraSources
|
||||||
++ cfg.logging.extraSources;
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,47 +6,69 @@ serviceName: {
|
||||||
with lib; let
|
with lib; let
|
||||||
cfg = config.homelab.services.${serviceName};
|
cfg = config.homelab.services.${serviceName};
|
||||||
homelabCfg = config.homelab;
|
homelabCfg = config.homelab;
|
||||||
|
|
||||||
|
hasMetricsConfig =
|
||||||
|
cfg.monitoring.metrics.path
|
||||||
|
!= null
|
||||||
|
|| cfg.monitoring.metrics.extraEndpoints != [];
|
||||||
|
|
||||||
|
hasHealthCheckConfig =
|
||||||
|
cfg.monitoring.healthCheck.path
|
||||||
|
!= null
|
||||||
|
|| cfg.monitoring.healthCheck.conditions != []
|
||||||
|
|| cfg.monitoring.healthCheck.extraChecks != [];
|
||||||
in {
|
in {
|
||||||
# Define the service-specific monitoring options
|
# Define the service-specific monitoring options
|
||||||
options.homelab.services.${serviceName}.monitoring = {
|
options.homelab.services.${serviceName}.monitoring = {
|
||||||
enable = mkEnableOption "monitoring for ${serviceName}";
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = "Enable monitoring for ${serviceName}";
|
||||||
|
default = hasMetricsConfig || hasHealthCheckConfig;
|
||||||
|
};
|
||||||
|
|
||||||
metrics = {
|
metrics = {
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = hasMetricsConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
path = mkOption {
|
path = mkOption {
|
||||||
type = types.str;
|
type = types.nullOr types.str;
|
||||||
default = "/metrics";
|
default = null;
|
||||||
|
description = "Metrics endpoint path. Setting this enables metrics collection.";
|
||||||
};
|
};
|
||||||
|
|
||||||
extraEndpoints = mkOption {
|
extraEndpoints = mkOption {
|
||||||
type = types.listOf types.attrs;
|
type = types.listOf types.attrs;
|
||||||
default = [];
|
default = [];
|
||||||
|
description = "Additional metrics endpoints. Adding endpoints enables metrics collection.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
healthCheck = {
|
healthCheck = {
|
||||||
enable = mkOption {
|
enable = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = hasHealthCheckConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
path = mkOption {
|
path = mkOption {
|
||||||
type = types.str;
|
type = types.nullOr types.str;
|
||||||
default = "/health";
|
default = null;
|
||||||
|
description = "Health check endpoint path. Setting this enables health checks.";
|
||||||
|
example = "/health";
|
||||||
};
|
};
|
||||||
|
|
||||||
conditions = mkOption {
|
conditions = mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = ["[STATUS] == 200"];
|
default = ["[STATUS] == 200"];
|
||||||
|
description = "Health check conditions. Setting conditions enables health checks.";
|
||||||
|
example = ["[STATUS] == 200"];
|
||||||
};
|
};
|
||||||
|
|
||||||
extraChecks = mkOption {
|
extraChecks = mkOption {
|
||||||
type = types.listOf types.attrs;
|
type = types.listOf types.attrs;
|
||||||
default = [];
|
default = [];
|
||||||
|
description = "Additional health checks. Adding checks enables health monitoring.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -57,11 +79,10 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
# Generate the homelab config automatically when service is enabled
|
# Generate the homelab config automatically when service is enabled
|
||||||
config = mkIf (cfg.enable && cfg.monitoring.enable) {
|
config = mkIf cfg.enable {
|
||||||
homelab.monitoring = {
|
homelab.monitoring = mkIf cfg.monitoring.enable {
|
||||||
metrics =
|
metrics = mkIf hasMetricsConfig (
|
||||||
[
|
(optional (cfg.monitoring.metrics.path != null) {
|
||||||
{
|
|
||||||
name = "${serviceName}-main";
|
name = "${serviceName}-main";
|
||||||
host = homelabCfg.hostname;
|
host = homelabCfg.hostname;
|
||||||
port = cfg.port;
|
port = cfg.port;
|
||||||
|
|
@ -75,13 +96,12 @@ in {
|
||||||
node = homelabCfg.hostname;
|
node = homelabCfg.hostname;
|
||||||
environment = homelabCfg.environment;
|
environment = homelabCfg.environment;
|
||||||
};
|
};
|
||||||
}
|
})
|
||||||
]
|
++ cfg.monitoring.metrics.extraEndpoints
|
||||||
++ cfg.monitoring.metrics.extraEndpoints;
|
);
|
||||||
|
|
||||||
healthChecks =
|
healthChecks = mkIf hasHealthCheckConfig (
|
||||||
[
|
(optional (cfg.monitoring.healthCheck.path != null) {
|
||||||
{
|
|
||||||
name = "${serviceName}-health";
|
name = "${serviceName}-health";
|
||||||
host = homelabCfg.hostname;
|
host = homelabCfg.hostname;
|
||||||
port = cfg.port;
|
port = cfg.port;
|
||||||
|
|
@ -100,9 +120,9 @@ in {
|
||||||
environment = homelabCfg.environment;
|
environment = homelabCfg.environment;
|
||||||
};
|
};
|
||||||
enabled = true;
|
enabled = true;
|
||||||
}
|
})
|
||||||
]
|
++ cfg.monitoring.healthCheck.extraChecks
|
||||||
++ cfg.monitoring.healthCheck.extraChecks;
|
);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,11 @@ with lib; let
|
||||||
homelabCfg = config.homelab;
|
homelabCfg = config.homelab;
|
||||||
in {
|
in {
|
||||||
options.homelab.services.${serviceName}.proxy = {
|
options.homelab.services.${serviceName}.proxy = {
|
||||||
enable = mkEnableOption "reverse proxy for ${serviceName}";
|
enable = mkOption {
|
||||||
|
type = types.bool;
|
||||||
|
description = "Enable reverse proxy for ${serviceName}";
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
|
||||||
subdomain = mkOption {
|
subdomain = mkOption {
|
||||||
type = types.str;
|
type = types.str;
|
||||||
|
|
@ -39,8 +43,8 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf (cfg.enable && cfg.proxy.enable) {
|
config = mkIf cfg.enable {
|
||||||
homelab.reverseProxy.entries =
|
homelab.reverseProxy.entries = mkIf cfg.proxy.enable (
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
subdomain = cfg.proxy.subdomain;
|
subdomain = cfg.proxy.subdomain;
|
||||||
|
|
@ -59,6 +63,7 @@ in {
|
||||||
enableAuth = sub.enableAuth;
|
enableAuth = sub.enableAuth;
|
||||||
enableSSL = true;
|
enableSSL = true;
|
||||||
})
|
})
|
||||||
cfg.proxy.additionalSubdomains;
|
cfg.proxy.additionalSubdomains
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -219,8 +219,7 @@ in {
|
||||||
homelab.services.${serviceName}.monitoring.enable = mkDefault true;
|
homelab.services.${serviceName}.monitoring.enable = mkDefault true;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Smart defaults for Gatus
|
{
|
||||||
(mkIf cfg.monitoring.enable {
|
|
||||||
homelab.services.${serviceName}.monitoring = mkDefault {
|
homelab.services.${serviceName}.monitoring = mkDefault {
|
||||||
metrics = {
|
metrics = {
|
||||||
path = "/metrics";
|
path = "/metrics";
|
||||||
|
|
@ -240,9 +239,9 @@ in {
|
||||||
tier = "monitoring";
|
tier = "monitoring";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
}
|
||||||
|
|
||||||
(mkIf cfg.logging.enable {
|
{
|
||||||
homelab.services.${serviceName}.logging = mkDefault {
|
homelab.services.${serviceName}.logging = mkDefault {
|
||||||
files = ["/var/log/gatus/gatus.log"];
|
files = ["/var/log/gatus/gatus.log"];
|
||||||
parsing = {
|
parsing = {
|
||||||
|
|
@ -255,13 +254,13 @@ in {
|
||||||
application = "gatus";
|
application = "gatus";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
}
|
||||||
|
|
||||||
(mkIf cfg.proxy.enable {
|
{
|
||||||
homelab.services.${serviceName}.proxy = mkDefault {
|
homelab.services.${serviceName}.proxy = mkDefault {
|
||||||
subdomain = "status";
|
subdomain = "status";
|
||||||
enableAuth = false; # Status page should be public
|
enableAuth = false; # Status page should be public
|
||||||
};
|
};
|
||||||
})
|
}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ in {
|
||||||
}
|
}
|
||||||
|
|
||||||
# Smart defaults for Grafana
|
# Smart defaults for Grafana
|
||||||
(mkIf cfg.logging.enable {
|
{
|
||||||
# Grafana-specific log setup
|
# Grafana-specific log setup
|
||||||
homelab.services.${serviceName}.logging = mkDefault {
|
homelab.services.${serviceName}.logging = mkDefault {
|
||||||
files = ["/var/log/grafana/grafana.log"];
|
files = ["/var/log/grafana/grafana.log"];
|
||||||
|
|
@ -59,9 +59,8 @@ in {
|
||||||
component = "dashboard";
|
component = "dashboard";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
}
|
||||||
|
{
|
||||||
(mkIf cfg.monitoring.enable {
|
|
||||||
homelab.services.${serviceName}.monitoring = mkDefault {
|
homelab.services.${serviceName}.monitoring = mkDefault {
|
||||||
metrics.path = "/metrics";
|
metrics.path = "/metrics";
|
||||||
healthCheck = {
|
healthCheck = {
|
||||||
|
|
@ -73,14 +72,13 @@ in {
|
||||||
tier = "monitoring";
|
tier = "monitoring";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
}
|
||||||
|
{
|
||||||
(mkIf cfg.proxy.enable {
|
|
||||||
# Grafana needs auth by default (admin interface)
|
# Grafana needs auth by default (admin interface)
|
||||||
homelab.services.${serviceName}.proxy = mkDefault {
|
homelab.services.${serviceName}.proxy = mkDefault {
|
||||||
subdomain = "grafana";
|
subdomain = "grafana";
|
||||||
# enableAuth = true;
|
# enableAuth = true;
|
||||||
};
|
};
|
||||||
})
|
}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,6 @@ in {
|
||||||
|
|
||||||
# Service configuration with smart defaults
|
# Service configuration with smart defaults
|
||||||
config = mkIf cfg.enable (mkMerge [
|
config = mkIf cfg.enable (mkMerge [
|
||||||
# Core Prometheus service
|
|
||||||
{
|
{
|
||||||
services.prometheus = {
|
services.prometheus = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
@ -203,39 +202,21 @@ in {
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [cfg.port];
|
networking.firewall.allowedTCPPorts = [cfg.port];
|
||||||
|
|
||||||
homelab.services.${serviceName}.monitoring.enable = mkDefault true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Smart defaults for Prometheus
|
|
||||||
(mkIf cfg.monitoring.enable {
|
|
||||||
homelab.services.${serviceName}.monitoring = mkDefault {
|
|
||||||
metrics = {
|
|
||||||
path = "/metrics";
|
|
||||||
extraEndpoints = [];
|
|
||||||
};
|
|
||||||
healthCheck = {
|
|
||||||
path = "/-/healthy";
|
|
||||||
conditions = ["[STATUS] == 200" "[RESPONSE_TIME] < 1000"];
|
|
||||||
extraChecks = [
|
|
||||||
{
|
{
|
||||||
name = "prometheus-ready";
|
homelab.services.${serviceName}.monitoring = {
|
||||||
port = cfg.port;
|
metrics.path = "/metrics";
|
||||||
path = "/-/ready";
|
healthCheck.path = "/-/healthy"; # ✅ Enables health checks
|
||||||
conditions = ["[STATUS] == 200"];
|
healthCheck.conditions = ["[STATUS] == 200" "[RESPONSE_TIME] < 1000"];
|
||||||
group = "monitoring";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
extraLabels = {
|
extraLabels = {
|
||||||
component = "monitoring-server";
|
component = "monitoring-server";
|
||||||
tier = "monitoring";
|
tier = "monitoring";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
}
|
||||||
|
{
|
||||||
(mkIf cfg.logging.enable {
|
homelab.services.${serviceName}.logging = {
|
||||||
homelab.services.${serviceName}.logging = mkDefault {
|
|
||||||
files = ["/var/log/prometheus/prometheus.log"];
|
files = ["/var/log/prometheus/prometheus.log"];
|
||||||
parsing = {
|
parsing = {
|
||||||
# Prometheus log format: ts=2024-01-01T12:00:00.000Z caller=main.go:123 level=info msg="message"
|
# Prometheus log format: ts=2024-01-01T12:00:00.000Z caller=main.go:123 level=info msg="message"
|
||||||
|
|
@ -247,13 +228,11 @@ in {
|
||||||
application = "prometheus";
|
application = "prometheus";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
})
|
}
|
||||||
|
{
|
||||||
(mkIf cfg.proxy.enable {
|
homelab.services.${serviceName}.proxy = {
|
||||||
homelab.services.${serviceName}.proxy = mkDefault {
|
enableAuth = true;
|
||||||
subdomain = "prometheus";
|
|
||||||
enableAuth = true; # Admin interface needs protection
|
|
||||||
};
|
};
|
||||||
})
|
}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ writeShellScriptBin "homelab-docs-readme" ''
|
||||||
## 🚀 Quick Actions
|
## 🚀 Quick Actions
|
||||||
|
|
||||||
### View Current Status
|
### View Current Status
|
||||||
\`\`\`bash
|
```bash
|
||||||
# Service status across fleet (if homelab CLI is available)
|
# Service status across fleet (if homelab CLI is available)
|
||||||
homelab services --global
|
homelab services --global
|
||||||
|
|
||||||
|
|
@ -39,16 +39,16 @@ writeShellScriptBin "homelab-docs-readme" ''
|
||||||
|
|
||||||
# Overall status
|
# Overall status
|
||||||
homelab status
|
homelab status
|
||||||
\`\`\`
|
```
|
||||||
|
|
||||||
### Update Documentation
|
### Update Documentation
|
||||||
\`\`\`bash
|
```bash
|
||||||
# Regenerate all documentation
|
# Regenerate all documentation
|
||||||
homelab-generate-docs ./docs
|
homelab-generate-docs ./docs
|
||||||
|
|
||||||
# Generate in different directory
|
# Generate in different directory
|
||||||
homelab-generate-docs /path/to/output
|
homelab-generate-docs /path/to/output
|
||||||
\`\`\`
|
```
|
||||||
|
|
||||||
## 📋 Quick Stats
|
## 📋 Quick Stats
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
# homelab-docs-services.nix - Service documentation generator CLI
|
|
||||||
{
|
{
|
||||||
writeShellScriptBin,
|
writeShellScriptBin,
|
||||||
jq,
|
jq,
|
||||||
|
|
@ -10,261 +9,376 @@ writeShellScriptBin "homelab-docs-services" ''
|
||||||
cat << 'EOF'
|
cat << 'EOF'
|
||||||
# Service Catalog
|
# Service Catalog
|
||||||
|
|
||||||
> Available services and their configuration options
|
> Complete service documentation with core options, feature integrations, and smart defaults
|
||||||
>
|
>
|
||||||
> Generated on: $(date)
|
> Generated on: $(date)
|
||||||
|
|
||||||
This document catalogs all available homelab services, their configuration options, and integration capabilities.
|
This document provides comprehensive documentation for homelab services, organized by:
|
||||||
|
- **Core Service Options**: The main service configuration
|
||||||
|
- **Feature Integrations**: Available monitoring, logging, and proxy features
|
||||||
|
- **Service Defaults**: What this service configures by default for each feature
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Get all services and their configurations
|
# Extract comprehensive service information
|
||||||
services_catalog=$(colmena eval -E '{ nodes, pkgs, lib, ... }:
|
echo "Extracting service information..." >&2
|
||||||
|
services_catalog=$(colmena eval -E '
|
||||||
|
{ nodes, pkgs, lib, ... }:
|
||||||
let
|
let
|
||||||
# Collect all services from all nodes to build a complete catalog
|
# Helper to extract option information
|
||||||
allServiceConfigs = lib.flatten (lib.mapAttrsToList (nodeName: node:
|
extractOptions = path: options:
|
||||||
if (node.config.homelab.enable or false) then
|
lib.flatten (lib.mapAttrsToList (name: value:
|
||||||
lib.mapAttrsToList (serviceName: service: {
|
let
|
||||||
inherit serviceName;
|
currentPath = path ++ [name];
|
||||||
config = {
|
pathStr = lib.concatStringsSep "." currentPath;
|
||||||
# Core service options
|
in
|
||||||
enable = service.enable or false;
|
if (value._type or null) == "option" then
|
||||||
port = service.port or null;
|
[{
|
||||||
description = service.description or serviceName;
|
name = pathStr;
|
||||||
tags = service.tags or [];
|
type = value.type.description or "unknown";
|
||||||
|
default = value.default or null;
|
||||||
# Integration options
|
defaultText = if value ? defaultText then value.defaultText.text or null else null;
|
||||||
monitoring = {
|
description = value.description or "No description";
|
||||||
enabled = service.monitoring.enable or false;
|
readOnly = value.readOnly or false;
|
||||||
metricsPath = service.monitoring.metrics.path or "/metrics";
|
}]
|
||||||
healthPath = service.monitoring.healthCheck.path or "/health";
|
else if lib.isAttrs value && !(lib.hasAttr "_type" value) then
|
||||||
extraLabels = service.monitoring.extraLabels or {};
|
extractOptions currentPath value
|
||||||
};
|
|
||||||
|
|
||||||
logging = {
|
|
||||||
enabled = service.logging.enable or false;
|
|
||||||
files = service.logging.files or [];
|
|
||||||
extraLabels = service.logging.extraLabels or {};
|
|
||||||
};
|
|
||||||
|
|
||||||
proxy = {
|
|
||||||
enabled = service.proxy.enable or false;
|
|
||||||
subdomain = service.proxy.subdomain or serviceName;
|
|
||||||
enableAuth = service.proxy.enableAuth or false;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Service-specific options (everything else)
|
|
||||||
serviceSpecific = removeAttrs service [
|
|
||||||
"enable" "port" "description" "tags"
|
|
||||||
"monitoring" "logging" "proxy"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
deployedOn = nodeName;
|
|
||||||
}) (node.config.homelab.services or {})
|
|
||||||
else []
|
else []
|
||||||
) nodes);
|
) options);
|
||||||
|
|
||||||
# Group by service name and merge configurations
|
# Get first node for option definitions
|
||||||
serviceGroups = lib.groupBy (svc: svc.serviceName) allServiceConfigs;
|
firstNode = lib.head (lib.attrValues nodes);
|
||||||
|
homelabServices = firstNode.options.homelab.services or {};
|
||||||
|
|
||||||
# Get unique services with merged configuration examples
|
# Process each service
|
||||||
uniqueServices = lib.mapAttrs (serviceName: instances:
|
serviceInfo = lib.mapAttrs (serviceName: serviceOptions:
|
||||||
let
|
let
|
||||||
# Take the first enabled instance as the canonical example
|
allOptions = extractOptions [] serviceOptions;
|
||||||
enabledInstances = lib.filter (inst: inst.config.enable) instances;
|
|
||||||
canonicalConfig = if enabledInstances != [] then (lib.head enabledInstances).config else (lib.head instances).config;
|
# Separate core options from feature options
|
||||||
|
coreOptions = lib.filter (opt:
|
||||||
|
!(lib.hasPrefix "monitoring." opt.name) &&
|
||||||
|
!(lib.hasPrefix "logging." opt.name) &&
|
||||||
|
!(lib.hasPrefix "proxy." opt.name)
|
||||||
|
) allOptions;
|
||||||
|
|
||||||
|
monitoringOptions = lib.filter (opt: lib.hasPrefix "monitoring." opt.name) allOptions;
|
||||||
|
loggingOptions = lib.filter (opt: lib.hasPrefix "logging." opt.name) allOptions;
|
||||||
|
proxyOptions = lib.filter (opt: lib.hasPrefix "proxy." opt.name) allOptions;
|
||||||
|
|
||||||
|
# Get actual service configuration to see what defaults are set
|
||||||
|
serviceConfigs = lib.mapAttrs (nodeName: node:
|
||||||
|
let
|
||||||
|
serviceConfig = node.config.homelab.services.''${serviceName} or null;
|
||||||
|
in
|
||||||
|
if serviceConfig != null then {
|
||||||
|
exists = true;
|
||||||
|
enabled = serviceConfig.enable or false;
|
||||||
|
# Extract the computed configuration values
|
||||||
|
monitoring = serviceConfig.monitoring or {};
|
||||||
|
logging = serviceConfig.logging or {};
|
||||||
|
proxy = serviceConfig.proxy or {};
|
||||||
|
# Get other core options
|
||||||
|
coreConfig = removeAttrs serviceConfig ["monitoring" "logging" "proxy"];
|
||||||
|
} else {
|
||||||
|
exists = false;
|
||||||
|
}
|
||||||
|
) nodes;
|
||||||
|
|
||||||
|
# Find a node where this service exists to get default values
|
||||||
|
nodeWithService = lib.findFirst (nodeName: serviceConfigs.''${nodeName}.exists) null (lib.attrNames nodes);
|
||||||
|
exampleConfig = if nodeWithService != null then serviceConfigs.''${nodeWithService} else null;
|
||||||
|
|
||||||
in {
|
in {
|
||||||
inherit serviceName;
|
inherit serviceName;
|
||||||
config = canonicalConfig;
|
coreOptions = coreOptions;
|
||||||
deploymentCount = lib.length (lib.filter (inst: inst.config.enable) instances);
|
features = {
|
||||||
deployedOn = lib.unique (map (inst: inst.deployedOn or "unknown") enabledInstances);
|
monitoring = {
|
||||||
|
available = monitoringOptions != [];
|
||||||
|
options = monitoringOptions;
|
||||||
|
defaults = if exampleConfig != null then exampleConfig.monitoring else {};
|
||||||
|
};
|
||||||
|
logging = {
|
||||||
|
available = loggingOptions != [];
|
||||||
|
options = loggingOptions;
|
||||||
|
defaults = if exampleConfig != null then exampleConfig.logging else {};
|
||||||
|
};
|
||||||
|
proxy = {
|
||||||
|
available = proxyOptions != [];
|
||||||
|
options = proxyOptions;
|
||||||
|
defaults = if exampleConfig != null then exampleConfig.proxy else {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
deployment = {
|
||||||
|
totalNodes = lib.length (lib.filter (cfg: cfg.exists) (lib.attrValues serviceConfigs));
|
||||||
|
enabledNodes = lib.length (lib.filter (cfg: cfg.exists && cfg.enabled) (lib.attrValues serviceConfigs));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
) serviceGroups;
|
) homelabServices;
|
||||||
|
|
||||||
in {
|
in {
|
||||||
services = uniqueServices;
|
services = serviceInfo;
|
||||||
totalUniqueServices = lib.length (lib.attrNames uniqueServices);
|
totalServices = lib.length (lib.attrNames serviceInfo);
|
||||||
}')
|
}
|
||||||
|
')
|
||||||
|
|
||||||
total_services=$(echo "$services_catalog" | ${jq}/bin/jq -r '.totalUniqueServices')
|
total_services=$(echo "$services_catalog" | ${jq}/bin/jq -r '.totalServices')
|
||||||
|
|
||||||
echo "## Overview"
|
echo "## Overview"
|
||||||
echo
|
echo
|
||||||
echo "**Total Available Services:** $total_services"
|
echo "**Total Available Services:** $total_services"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# Create a summary table of services and their default integrations
|
# Service matrix
|
||||||
echo "## Service Integration Matrix"
|
echo "## Service Integration Matrix"
|
||||||
echo
|
echo
|
||||||
echo "| Service | Monitoring | Logging | Proxy | Auth Default |"
|
echo "| Service | Core Options | Monitoring | Logging | Proxy | Deployments |"
|
||||||
echo "|---------|------------|---------|-------|--------------|"
|
echo "|---------|--------------|------------|---------|-------|-------------|"
|
||||||
|
|
||||||
echo "$services_catalog" | ${jq}/bin/jq -r '.services | to_entries[] | .key' | sort | while read -r service; do
|
echo "$services_catalog" | ${jq}/bin/jq -r '.services | keys[]' | sort | while read -r service; do
|
||||||
service_data=$(echo "$services_catalog" | ${jq}/bin/jq -r ".services[\"$service\"]")
|
service_data=$(echo "$services_catalog" | ${jq}/bin/jq -r ".services[\"$service\"]")
|
||||||
|
|
||||||
monitoring_enabled=$(echo "$service_data" | ${jq}/bin/jq -r '.config.monitoring.enabled')
|
core_count=$(echo "$service_data" | ${jq}/bin/jq -r '.coreOptions | length')
|
||||||
logging_enabled=$(echo "$service_data" | ${jq}/bin/jq -r '.config.logging.enabled')
|
has_monitoring=$(echo "$service_data" | ${jq}/bin/jq -r '.features.monitoring.available')
|
||||||
proxy_enabled=$(echo "$service_data" | ${jq}/bin/jq -r '.config.proxy.enabled')
|
has_logging=$(echo "$service_data" | ${jq}/bin/jq -r '.features.logging.available')
|
||||||
auth_default=$(echo "$service_data" | ${jq}/bin/jq -r '.config.proxy.enableAuth')
|
has_proxy=$(echo "$service_data" | ${jq}/bin/jq -r '.features.proxy.available')
|
||||||
|
enabled_deployments=$(echo "$service_data" | ${jq}/bin/jq -r '.deployment.enabledNodes')
|
||||||
|
|
||||||
monitoring_icon=$(if [[ "$monitoring_enabled" == "true" ]]; then echo "✅"; else echo "❌"; fi)
|
monitoring_icon=$(if [[ "$has_monitoring" == "true" ]]; then echo "📊"; else echo "❌"; fi)
|
||||||
logging_icon=$(if [[ "$logging_enabled" == "true" ]]; then echo "✅"; else echo "❌"; fi)
|
logging_icon=$(if [[ "$has_logging" == "true" ]]; then echo "📝"; else echo "❌"; fi)
|
||||||
proxy_icon=$(if [[ "$proxy_enabled" == "true" ]]; then echo "✅"; else echo "❌"; fi)
|
proxy_icon=$(if [[ "$has_proxy" == "true" ]]; then echo "🔀"; else echo "❌"; fi)
|
||||||
auth_icon=$(if [[ "$auth_default" == "true" ]]; then echo "🔒"; else echo "🌐"; fi)
|
|
||||||
|
|
||||||
echo "| \`$service\` | $monitoring_icon | $logging_icon | $proxy_icon | $auth_icon |"
|
echo "| \`$service\` | $core_count | $monitoring_icon | $logging_icon | $proxy_icon | $enabled_deployments |"
|
||||||
done
|
done
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "**Legend:** ✅ = Enabled by default, ❌ = Available but disabled, 🔒 = Auth required, 🌐 = Public access"
|
echo "**Legend:** 📊📝🔀 = Feature available, ❌ = Feature not available"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
echo "## Service Reference"
|
echo "## Service Documentation"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# Process each service
|
# Process each service
|
||||||
echo "$services_catalog" | ${jq}/bin/jq -r '.services | to_entries[] | .key' | sort | while read -r service; do
|
echo "$services_catalog" | ${jq}/bin/jq -r '.services | keys[]' | sort | while read -r service; do
|
||||||
echo "### $service"
|
echo "### $service"
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# Get service details
|
|
||||||
service_data=$(echo "$services_catalog" | ${jq}/bin/jq -r ".services[\"$service\"]")
|
service_data=$(echo "$services_catalog" | ${jq}/bin/jq -r ".services[\"$service\"]")
|
||||||
|
enabled_deployments=$(echo "$service_data" | ${jq}/bin/jq -r '.deployment.enabledNodes')
|
||||||
|
total_deployments=$(echo "$service_data" | ${jq}/bin/jq -r '.deployment.totalNodes')
|
||||||
|
|
||||||
description=$(echo "$service_data" | ${jq}/bin/jq -r '.config.description // "No description available"')
|
if [[ "$total_deployments" -gt 0 ]]; then
|
||||||
port=$(echo "$service_data" | ${jq}/bin/jq -r '.config.port // "N/A"')
|
echo "**Deployment Status:** $enabled_deployments/$total_deployments nodes have this service enabled"
|
||||||
tags=$(echo "$service_data" | ${jq}/bin/jq -r '.config.tags | join(", ")')
|
|
||||||
deployment_count=$(echo "$service_data" | ${jq}/bin/jq -r '.deploymentCount')
|
|
||||||
deployed_on=$(echo "$service_data" | ${jq}/bin/jq -r '.deployedOn | join(", ")')
|
|
||||||
|
|
||||||
echo "**Description:** $description"
|
|
||||||
echo
|
|
||||||
echo "**Default Port:** \`$port\`"
|
|
||||||
echo
|
|
||||||
if [[ -n "$tags" && "$tags" != "" ]]; then
|
|
||||||
echo "**Tags:** $tags"
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
echo "**Current Deployments:** $deployment_count instance(s) on: $deployed_on"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Integration Status Overview
|
|
||||||
monitoring_enabled=$(echo "$service_data" | ${jq}/bin/jq -r '.config.monitoring.enabled')
|
|
||||||
logging_enabled=$(echo "$service_data" | ${jq}/bin/jq -r '.config.logging.enabled')
|
|
||||||
proxy_enabled=$(echo "$service_data" | ${jq}/bin/jq -r '.config.proxy.enabled')
|
|
||||||
|
|
||||||
echo "#### Default Integration Status"
|
|
||||||
echo
|
|
||||||
echo "| Integration | Status | Default Configuration |"
|
|
||||||
echo "|-------------|--------|----------------------|"
|
|
||||||
|
|
||||||
# Monitoring status
|
|
||||||
if [[ "$monitoring_enabled" == "true" ]]; then
|
|
||||||
metrics_path=$(echo "$service_data" | ${jq}/bin/jq -r '.config.monitoring.metricsPath')
|
|
||||||
health_path=$(echo "$service_data" | ${jq}/bin/jq -r '.config.monitoring.healthPath')
|
|
||||||
echo "| 📊 Monitoring | ✅ **Enabled** | Metrics: \`$metrics_path\`, Health: \`$health_path\` |"
|
|
||||||
else
|
else
|
||||||
echo "| 📊 Monitoring | ❌ Disabled | Available but requires \`monitoring.enable = true\` |"
|
echo "**Deployment Status:** Available but not configured"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Logging status
|
|
||||||
if [[ "$logging_enabled" == "true" ]]; then
|
|
||||||
log_files=$(echo "$service_data" | ${jq}/bin/jq -r '.config.logging.files | length')
|
|
||||||
if [[ "$log_files" -gt 0 ]]; then
|
|
||||||
echo "| 📝 Logging | ✅ **Enabled** | Collecting $log_files log file(s) |"
|
|
||||||
else
|
|
||||||
echo "| 📝 Logging | ✅ **Enabled** | Auto-configured log collection |"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "| 📝 Logging | ❌ Disabled | Available but requires \`logging.enable = true\` |"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Proxy status
|
|
||||||
if [[ "$proxy_enabled" == "true" ]]; then
|
|
||||||
subdomain=$(echo "$service_data" | ${jq}/bin/jq -r '.config.proxy.subdomain')
|
|
||||||
enable_auth=$(echo "$service_data" | ${jq}/bin/jq -r '.config.proxy.enableAuth')
|
|
||||||
auth_status=$(if [[ "$enable_auth" == "true" ]]; then echo "🔒 Auth required"; else echo "🌐 Public access"; fi)
|
|
||||||
echo "| 🔀 Proxy | ✅ **Enabled** | Subdomain: \`$subdomain\`, $auth_status |"
|
|
||||||
else
|
|
||||||
echo "| 🔀 Proxy | ❌ Disabled | Available but requires \`proxy.enable = true\` |"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# Core Configuration
|
# Core Service Configuration
|
||||||
echo "#### Core Configuration"
|
echo "#### Core Service Options"
|
||||||
echo
|
echo
|
||||||
echo "\`\`\`nix"
|
echo "The main configuration options for $service:"
|
||||||
|
echo
|
||||||
|
echo '```nix'
|
||||||
echo "homelab.services.$service = {"
|
echo "homelab.services.$service = {"
|
||||||
echo " enable = true;"
|
|
||||||
if [[ "$port" != "N/A" ]]; then
|
echo "$service_data" | ${jq}/bin/jq -r '.coreOptions[] | @base64' | while IFS= read -r option_b64; do
|
||||||
echo " port = $port;"
|
option=$(echo "$option_b64" | base64 -d)
|
||||||
|
|
||||||
|
name=$(echo "$option" | ${jq}/bin/jq -r '.name')
|
||||||
|
type=$(echo "$option" | ${jq}/bin/jq -r '.type')
|
||||||
|
default_val=$(echo "$option" | ${jq}/bin/jq -r '.default')
|
||||||
|
description=$(echo "$option" | ${jq}/bin/jq -r '.description')
|
||||||
|
read_only=$(echo "$option" | ${jq}/bin/jq -r '.readOnly')
|
||||||
|
|
||||||
|
if [[ "$read_only" == "true" ]]; then
|
||||||
|
continue
|
||||||
fi
|
fi
|
||||||
echo " description = \"$description\";"
|
|
||||||
if [[ -n "$tags" && "$tags" != "" ]]; then
|
clean_description=$(echo "$description" | sed 's/"/\\"/g' | tr -d $'\n\r')
|
||||||
echo " tags = [ $(echo "$tags" | sed 's/, /" "/g' | sed 's/^/"/; s/$/"/') ];"
|
|
||||||
fi
|
if [[ "$default_val" == "null" ]]; then
|
||||||
echo
|
echo " # $name = <$type>; # $clean_description"
|
||||||
echo " # Default integrations (adjust as needed)"
|
|
||||||
if [[ "$monitoring_enabled" == "true" ]]; then
|
|
||||||
echo " monitoring.enable = true; # ✅ Enabled by default"
|
|
||||||
else
|
else
|
||||||
echo " # monitoring.enable = true; # ❌ Disabled by default"
|
echo " $name = $default_val; # $clean_description"
|
||||||
fi
|
|
||||||
if [[ "$logging_enabled" == "true" ]]; then
|
|
||||||
echo " logging.enable = true; # ✅ Enabled by default"
|
|
||||||
else
|
|
||||||
echo " # logging.enable = true; # ❌ Disabled by default"
|
|
||||||
fi
|
|
||||||
if [[ "$proxy_enabled" == "true" ]]; then
|
|
||||||
echo " proxy.enable = true; # ✅ Enabled by default"
|
|
||||||
else
|
|
||||||
echo " # proxy.enable = true; # ❌ Disabled by default"
|
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
echo "};"
|
echo "};"
|
||||||
echo "\`\`\`"
|
echo '```'
|
||||||
echo
|
echo
|
||||||
|
|
||||||
# Service-specific options
|
# Feature Integrations
|
||||||
service_specific=$(echo "$service_data" | ${jq}/bin/jq -r '.config.serviceSpecific')
|
has_monitoring=$(echo "$service_data" | ${jq}/bin/jq -r '.features.monitoring.available')
|
||||||
if [[ "$service_specific" != "{}" && "$service_specific" != "null" ]]; then
|
has_logging=$(echo "$service_data" | ${jq}/bin/jq -r '.features.logging.available')
|
||||||
echo "#### Service-Specific Options"
|
has_proxy=$(echo "$service_data" | ${jq}/bin/jq -r '.features.proxy.available')
|
||||||
|
|
||||||
|
if [[ "$has_monitoring" == "true" || "$has_logging" == "true" || "$has_proxy" == "true" ]]; then
|
||||||
|
echo "#### Feature Integrations"
|
||||||
echo
|
echo
|
||||||
echo "Available configuration options for $service:"
|
|
||||||
|
# Monitoring Feature
|
||||||
|
if [[ "$has_monitoring" == "true" ]]; then
|
||||||
|
echo "##### 📊 Monitoring Integration"
|
||||||
echo
|
echo
|
||||||
echo "\`\`\`nix"
|
echo "Available monitoring options:"
|
||||||
|
echo
|
||||||
|
echo '```nix'
|
||||||
echo "homelab.services.$service = {"
|
echo "homelab.services.$service = {"
|
||||||
echo " # ... core options above ..."
|
echo " # ... core options above ..."
|
||||||
echo
|
echo
|
||||||
echo " # Service-specific configuration"
|
|
||||||
echo "$service_specific" | ${jq}/bin/jq -r 'to_entries[] | " \(.key) = \(.value | tostring);"'
|
echo "$service_data" | ${jq}/bin/jq -r '.features.monitoring.options[] | @base64' | while IFS= read -r option_b64; do
|
||||||
|
option=$(echo "$option_b64" | base64 -d)
|
||||||
|
|
||||||
|
name=$(echo "$option" | ${jq}/bin/jq -r '.name')
|
||||||
|
type=$(echo "$option" | ${jq}/bin/jq -r '.type')
|
||||||
|
default_val=$(echo "$option" | ${jq}/bin/jq -r '.default')
|
||||||
|
description=$(echo "$option" | ${jq}/bin/jq -r '.description')
|
||||||
|
read_only=$(echo "$option" | ${jq}/bin/jq -r '.readOnly')
|
||||||
|
|
||||||
|
if [[ "$read_only" == "true" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
clean_description=$(echo "$description" | sed 's/"/\\"/g' | tr -d $'\n\r')
|
||||||
|
|
||||||
|
if [[ "$default_val" == "null" ]]; then
|
||||||
|
echo " # $name = <$type>; # $clean_description"
|
||||||
|
else
|
||||||
|
echo " $name = $default_val; # $clean_description"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
echo "};"
|
echo "};"
|
||||||
echo "\`\`\`"
|
echo '```'
|
||||||
|
|
||||||
|
# Show service-specific monitoring defaults
|
||||||
|
monitoring_defaults=$(echo "$service_data" | ${jq}/bin/jq -r '.features.monitoring.defaults')
|
||||||
|
if [[ "$monitoring_defaults" != "{}" && "$monitoring_defaults" != "null" ]]; then
|
||||||
echo
|
echo
|
||||||
|
echo "**$service sets these monitoring defaults:**"
|
||||||
|
echo '```nix'
|
||||||
|
echo "$monitoring_defaults" | ${jq}/bin/jq -r 'to_entries[] | " \(.key) = \(.value);"'
|
||||||
|
echo '```'
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Logging Feature
|
||||||
|
if [[ "$has_logging" == "true" ]]; then
|
||||||
|
echo "##### 📝 Logging Integration"
|
||||||
|
echo
|
||||||
|
echo "Available logging options:"
|
||||||
|
echo
|
||||||
|
echo '```nix'
|
||||||
|
echo "homelab.services.$service = {"
|
||||||
|
echo " # ... core options above ..."
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "$service_data" | ${jq}/bin/jq -r '.features.logging.options[] | @base64' | while IFS= read -r option_b64; do
|
||||||
|
option=$(echo "$option_b64" | base64 -d)
|
||||||
|
|
||||||
|
name=$(echo "$option" | ${jq}/bin/jq -r '.name')
|
||||||
|
type=$(echo "$option" | ${jq}/bin/jq -r '.type')
|
||||||
|
default_val=$(echo "$option" | ${jq}/bin/jq -r '.default')
|
||||||
|
description=$(echo "$option" | ${jq}/bin/jq -r '.description')
|
||||||
|
read_only=$(echo "$option" | ${jq}/bin/jq -r '.readOnly')
|
||||||
|
|
||||||
|
if [[ "$read_only" == "true" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
clean_description=$(echo "$description" | sed 's/"/\\"/g' | tr -d $'\n\r')
|
||||||
|
|
||||||
|
if [[ "$default_val" == "null" ]]; then
|
||||||
|
echo " # $name = <$type>; # $clean_description"
|
||||||
|
else
|
||||||
|
echo " $name = $default_val; # $clean_description"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "};"
|
||||||
|
echo '```'
|
||||||
|
|
||||||
|
# Show service-specific logging defaults
|
||||||
|
logging_defaults=$(echo "$service_data" | ${jq}/bin/jq -r '.features.logging.defaults')
|
||||||
|
if [[ "$logging_defaults" != "{}" && "$logging_defaults" != "null" ]]; then
|
||||||
|
echo
|
||||||
|
echo "**$service sets these logging defaults:**"
|
||||||
|
echo '```nix'
|
||||||
|
echo "$logging_defaults" | ${jq}/bin/jq -r 'to_entries[] | " \(.key) = \(.value);"'
|
||||||
|
echo '```'
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Proxy Feature
|
||||||
|
if [[ "$has_proxy" == "true" ]]; then
|
||||||
|
echo "##### 🔀 Proxy Integration"
|
||||||
|
echo
|
||||||
|
echo "Available proxy options:"
|
||||||
|
echo
|
||||||
|
echo '```nix'
|
||||||
|
echo "homelab.services.$service = {"
|
||||||
|
echo " # ... core options above ..."
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "$service_data" | ${jq}/bin/jq -r '.features.proxy.options[] | @base64' | while IFS= read -r option_b64; do
|
||||||
|
option=$(echo "$option_b64" | base64 -d)
|
||||||
|
|
||||||
|
name=$(echo "$option" | ${jq}/bin/jq -r '.name')
|
||||||
|
type=$(echo "$option" | ${jq}/bin/jq -r '.type')
|
||||||
|
default_val=$(echo "$option" | ${jq}/bin/jq -r '.default')
|
||||||
|
description=$(echo "$option" | ${jq}/bin/jq -r '.description')
|
||||||
|
read_only=$(echo "$option" | ${jq}/bin/jq -r '.readOnly')
|
||||||
|
|
||||||
|
if [[ "$read_only" == "true" ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
clean_description=$(echo "$description" | sed 's/"/\\"/g' | tr -d $'\n\r')
|
||||||
|
|
||||||
|
if [[ "$default_val" == "null" ]]; then
|
||||||
|
echo " # $name = <$type>; # $clean_description"
|
||||||
|
else
|
||||||
|
echo " $name = $default_val; # $clean_description"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "};"
|
||||||
|
echo '```'
|
||||||
|
|
||||||
|
# Show service-specific proxy defaults
|
||||||
|
proxy_defaults=$(echo "$service_data" | ${jq}/bin/jq -r '.features.proxy.defaults')
|
||||||
|
if [[ "$proxy_defaults" != "{}" && "$proxy_defaults" != "null" ]]; then
|
||||||
|
echo
|
||||||
|
echo "**$service sets these proxy defaults:**"
|
||||||
|
echo '```nix'
|
||||||
|
echo "$proxy_defaults" | ${jq}/bin/jq -r 'to_entries[] | " \(.key) = \(.value);"'
|
||||||
|
echo '```'
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "---"
|
echo "---"
|
||||||
echo
|
echo
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "## Integration Summary"
|
echo "## Feature Reference"
|
||||||
echo
|
echo
|
||||||
echo "### Available Integration Types"
|
echo "### Integration Features"
|
||||||
echo
|
echo
|
||||||
echo "| Integration | Purpose | Default Behavior | Configuration |"
|
echo "Homelab services can integrate with three main features:"
|
||||||
echo "|-------------|---------|------------------|---------------|"
|
|
||||||
echo "| **📊 Monitoring** | Prometheus metrics + health checks | Service-dependent | \`monitoring.enable = true\` |"
|
|
||||||
echo "| **📝 Logging** | Centralized log collection | Service-dependent | \`logging.enable = true\` |"
|
|
||||||
echo "| **🔀 Proxy** | Reverse proxy with SSL + auth | Service-dependent | \`proxy.enable = true\` |"
|
|
||||||
echo
|
echo
|
||||||
echo "### Integration Benefits"
|
echo "- **📊 Monitoring**: Prometheus metrics and health checks"
|
||||||
|
echo "- **📝 Logging**: Centralized log collection with Promtail/Loki"
|
||||||
|
echo "- **🔀 Proxy**: Reverse proxy with SSL and authentication"
|
||||||
echo
|
echo
|
||||||
echo "- **🔄 Automatic Discovery:** Enabled integrations are automatically discovered by fleet-wide services"
|
echo "Each service can import these features and set service-specific defaults."
|
||||||
echo "- **📊 Unified Monitoring:** All metrics and health checks appear in Prometheus/Grafana"
|
|
||||||
echo "- **📝 Centralized Logging:** All logs are collected and indexed in Loki"
|
|
||||||
echo "- **🌐 Consistent Access:** All services get consistent subdomain access with SSL"
|
|
||||||
echo "- **🎯 Smart Defaults:** Each service comes with sensible default configurations"
|
|
||||||
echo
|
echo
|
||||||
echo "---"
|
echo "---"
|
||||||
echo
|
echo
|
||||||
echo "*This service catalog is generated from actual service configurations across your homelab fleet.*"
|
echo "*This documentation is generated from actual NixOS module evaluations.*"
|
||||||
''
|
''
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue