270 lines
11 KiB
Nix
270 lines
11 KiB
Nix
# homelab-docs-services.nix - Service documentation generator CLI
|
|
{
|
|
writeShellScriptBin,
|
|
jq,
|
|
}:
|
|
writeShellScriptBin "homelab-docs-services" ''
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
cat << 'EOF'
|
|
# Service Catalog
|
|
|
|
> Available services and their configuration options
|
|
>
|
|
> Generated on: $(date)
|
|
|
|
This document catalogs all available homelab services, their configuration options, and integration capabilities.
|
|
|
|
EOF
|
|
|
|
# Get all services and their configurations
|
|
services_catalog=$(colmena eval -E '{ nodes, pkgs, lib, ... }:
|
|
let
|
|
# Collect all services from all nodes to build a complete catalog
|
|
allServiceConfigs = lib.flatten (lib.mapAttrsToList (nodeName: node:
|
|
if (node.config.homelab.enable or false) then
|
|
lib.mapAttrsToList (serviceName: service: {
|
|
inherit serviceName;
|
|
config = {
|
|
# Core service options
|
|
enable = service.enable or false;
|
|
port = service.port or null;
|
|
description = service.description or serviceName;
|
|
tags = service.tags or [];
|
|
|
|
# Integration options
|
|
monitoring = {
|
|
enabled = service.monitoring.enable or false;
|
|
metricsPath = service.monitoring.metrics.path or "/metrics";
|
|
healthPath = service.monitoring.healthCheck.path or "/health";
|
|
extraLabels = service.monitoring.extraLabels or {};
|
|
};
|
|
|
|
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 []
|
|
) nodes);
|
|
|
|
# Group by service name and merge configurations
|
|
serviceGroups = lib.groupBy (svc: svc.serviceName) allServiceConfigs;
|
|
|
|
# Get unique services with merged configuration examples
|
|
uniqueServices = lib.mapAttrs (serviceName: instances:
|
|
let
|
|
# Take the first enabled instance as the canonical example
|
|
enabledInstances = lib.filter (inst: inst.config.enable) instances;
|
|
canonicalConfig = if enabledInstances != [] then (lib.head enabledInstances).config else (lib.head instances).config;
|
|
in {
|
|
inherit serviceName;
|
|
config = canonicalConfig;
|
|
deploymentCount = lib.length (lib.filter (inst: inst.config.enable) instances);
|
|
deployedOn = lib.unique (map (inst: inst.deployedOn or "unknown") enabledInstances);
|
|
}
|
|
) serviceGroups;
|
|
|
|
in {
|
|
services = uniqueServices;
|
|
totalUniqueServices = lib.length (lib.attrNames uniqueServices);
|
|
}')
|
|
|
|
total_services=$(echo "$services_catalog" | ${jq}/bin/jq -r '.totalUniqueServices')
|
|
|
|
echo "## Overview"
|
|
echo
|
|
echo "**Total Available Services:** $total_services"
|
|
echo
|
|
|
|
# Create a summary table of services and their default integrations
|
|
echo "## Service Integration Matrix"
|
|
echo
|
|
echo "| Service | Monitoring | Logging | Proxy | Auth Default |"
|
|
echo "|---------|------------|---------|-------|--------------|"
|
|
|
|
echo "$services_catalog" | ${jq}/bin/jq -r '.services | to_entries[] | .key' | sort | while read -r service; do
|
|
service_data=$(echo "$services_catalog" | ${jq}/bin/jq -r ".services[\"$service\"]")
|
|
|
|
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')
|
|
auth_default=$(echo "$service_data" | ${jq}/bin/jq -r '.config.proxy.enableAuth')
|
|
|
|
monitoring_icon=$(if [[ "$monitoring_enabled" == "true" ]]; then echo "✅"; else echo "❌"; fi)
|
|
logging_icon=$(if [[ "$logging_enabled" == "true" ]]; then echo "✅"; else echo "❌"; fi)
|
|
proxy_icon=$(if [[ "$proxy_enabled" == "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 |"
|
|
done
|
|
|
|
echo
|
|
echo "**Legend:** ✅ = Enabled by default, ❌ = Available but disabled, 🔒 = Auth required, 🌐 = Public access"
|
|
echo
|
|
|
|
echo "## Service Reference"
|
|
echo
|
|
|
|
# Process each service
|
|
echo "$services_catalog" | ${jq}/bin/jq -r '.services | to_entries[] | .key' | sort | while read -r service; do
|
|
echo "### $service"
|
|
echo
|
|
|
|
# Get service details
|
|
service_data=$(echo "$services_catalog" | ${jq}/bin/jq -r ".services[\"$service\"]")
|
|
|
|
description=$(echo "$service_data" | ${jq}/bin/jq -r '.config.description // "No description available"')
|
|
port=$(echo "$service_data" | ${jq}/bin/jq -r '.config.port // "N/A"')
|
|
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
|
|
echo "| 📊 Monitoring | ❌ Disabled | Available but requires \`monitoring.enable = true\` |"
|
|
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
|
|
|
|
# Core Configuration
|
|
echo "#### Core Configuration"
|
|
echo
|
|
echo "\`\`\`nix"
|
|
echo "homelab.services.$service = {"
|
|
echo " enable = true;"
|
|
if [[ "$port" != "N/A" ]]; then
|
|
echo " port = $port;"
|
|
fi
|
|
echo " description = \"$description\";"
|
|
if [[ -n "$tags" && "$tags" != "" ]]; then
|
|
echo " tags = [ $(echo "$tags" | sed 's/, /" "/g' | sed 's/^/"/; s/$/"/') ];"
|
|
fi
|
|
echo
|
|
echo " # Default integrations (adjust as needed)"
|
|
if [[ "$monitoring_enabled" == "true" ]]; then
|
|
echo " monitoring.enable = true; # ✅ Enabled by default"
|
|
else
|
|
echo " # monitoring.enable = true; # ❌ Disabled by default"
|
|
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
|
|
echo "};"
|
|
echo "\`\`\`"
|
|
echo
|
|
|
|
# Service-specific options
|
|
service_specific=$(echo "$service_data" | ${jq}/bin/jq -r '.config.serviceSpecific')
|
|
if [[ "$service_specific" != "{}" && "$service_specific" != "null" ]]; then
|
|
echo "#### Service-Specific Options"
|
|
echo
|
|
echo "Available configuration options for $service:"
|
|
echo
|
|
echo "\`\`\`nix"
|
|
echo "homelab.services.$service = {"
|
|
echo " # ... core options above ..."
|
|
echo
|
|
echo " # Service-specific configuration"
|
|
echo "$service_specific" | ${jq}/bin/jq -r 'to_entries[] | " \(.key) = \(.value | tostring);"'
|
|
echo "};"
|
|
echo "\`\`\`"
|
|
echo
|
|
fi
|
|
|
|
echo "---"
|
|
echo
|
|
done
|
|
|
|
echo "## Integration Summary"
|
|
echo
|
|
echo "### Available Integration Types"
|
|
echo
|
|
echo "| Integration | Purpose | Default Behavior | Configuration |"
|
|
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 "### Integration Benefits"
|
|
echo
|
|
echo "- **🔄 Automatic Discovery:** Enabled integrations are automatically discovered by fleet-wide services"
|
|
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 "*This service catalog is generated from actual service configurations across your homelab fleet.*"
|
|
''
|