services...
This commit is contained in:
parent
73d2f44d74
commit
8552656731
15 changed files with 918 additions and 490 deletions
|
|
@ -1,4 +1,3 @@
|
|||
# homelab-docs-services.nix - Service documentation generator CLI
|
||||
{
|
||||
writeShellScriptBin,
|
||||
jq,
|
||||
|
|
@ -10,261 +9,376 @@ writeShellScriptBin "homelab-docs-services" ''
|
|||
cat << 'EOF'
|
||||
# Service Catalog
|
||||
|
||||
> Available services and their configuration options
|
||||
> Complete service documentation with core options, feature integrations, and smart defaults
|
||||
>
|
||||
> 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
|
||||
|
||||
# Get all services and their configurations
|
||||
services_catalog=$(colmena eval -E '{ nodes, pkgs, lib, ... }:
|
||||
# Extract comprehensive service information
|
||||
echo "Extracting service information..." >&2
|
||||
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 [];
|
||||
# Helper to extract option information
|
||||
extractOptions = path: options:
|
||||
lib.flatten (lib.mapAttrsToList (name: value:
|
||||
let
|
||||
currentPath = path ++ [name];
|
||||
pathStr = lib.concatStringsSep "." currentPath;
|
||||
in
|
||||
if (value._type or null) == "option" then
|
||||
[{
|
||||
name = pathStr;
|
||||
type = value.type.description or "unknown";
|
||||
default = value.default or null;
|
||||
defaultText = if value ? defaultText then value.defaultText.text or null else null;
|
||||
description = value.description or "No description";
|
||||
readOnly = value.readOnly or false;
|
||||
}]
|
||||
else if lib.isAttrs value && !(lib.hasAttr "_type" value) then
|
||||
extractOptions currentPath value
|
||||
else []
|
||||
) options);
|
||||
|
||||
# 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 {};
|
||||
};
|
||||
# Get first node for option definitions
|
||||
firstNode = lib.head (lib.attrValues nodes);
|
||||
homelabServices = firstNode.options.homelab.services 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:
|
||||
# Process each service
|
||||
serviceInfo = lib.mapAttrs (serviceName: serviceOptions:
|
||||
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;
|
||||
allOptions = extractOptions [] serviceOptions;
|
||||
|
||||
# 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 {
|
||||
inherit serviceName;
|
||||
config = canonicalConfig;
|
||||
deploymentCount = lib.length (lib.filter (inst: inst.config.enable) instances);
|
||||
deployedOn = lib.unique (map (inst: inst.deployedOn or "unknown") enabledInstances);
|
||||
coreOptions = coreOptions;
|
||||
features = {
|
||||
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 {
|
||||
services = uniqueServices;
|
||||
totalUniqueServices = lib.length (lib.attrNames uniqueServices);
|
||||
}')
|
||||
services = serviceInfo;
|
||||
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
|
||||
echo "**Total Available Services:** $total_services"
|
||||
echo
|
||||
|
||||
# Create a summary table of services and their default integrations
|
||||
# Service matrix
|
||||
echo "## Service Integration Matrix"
|
||||
echo
|
||||
echo "| Service | Monitoring | Logging | Proxy | Auth Default |"
|
||||
echo "|---------|------------|---------|-------|--------------|"
|
||||
echo "| Service | Core Options | Monitoring | Logging | Proxy | Deployments |"
|
||||
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\"]")
|
||||
|
||||
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')
|
||||
core_count=$(echo "$service_data" | ${jq}/bin/jq -r '.coreOptions | length')
|
||||
has_monitoring=$(echo "$service_data" | ${jq}/bin/jq -r '.features.monitoring.available')
|
||||
has_logging=$(echo "$service_data" | ${jq}/bin/jq -r '.features.logging.available')
|
||||
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)
|
||||
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)
|
||||
monitoring_icon=$(if [[ "$has_monitoring" == "true" ]]; then echo "📊"; else echo "❌"; fi)
|
||||
logging_icon=$(if [[ "$has_logging" == "true" ]]; then echo "📝"; else echo "❌"; fi)
|
||||
proxy_icon=$(if [[ "$has_proxy" == "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
|
||||
|
||||
echo
|
||||
echo "**Legend:** ✅ = Enabled by default, ❌ = Available but disabled, 🔒 = Auth required, 🌐 = Public access"
|
||||
echo "**Legend:** 📊📝🔀 = Feature available, ❌ = Feature not available"
|
||||
echo
|
||||
|
||||
echo "## Service Reference"
|
||||
echo "## Service Documentation"
|
||||
echo
|
||||
|
||||
# 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
|
||||
|
||||
# Get service details
|
||||
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"')
|
||||
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\` |"
|
||||
if [[ "$total_deployments" -gt 0 ]]; then
|
||||
echo "**Deployment Status:** $enabled_deployments/$total_deployments nodes have this service enabled"
|
||||
else
|
||||
echo "| 📊 Monitoring | ❌ Disabled | Available but requires \`monitoring.enable = true\` |"
|
||||
echo "**Deployment Status:** Available but not configured"
|
||||
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"
|
||||
# Core Service Configuration
|
||||
echo "#### Core Service Options"
|
||||
echo
|
||||
echo "\`\`\`nix"
|
||||
echo "The main configuration options for $service:"
|
||||
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 "$service_data" | ${jq}/bin/jq -r '.coreOptions[] | @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
|
||||
|
||||
# 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 "\`\`\`"
|
||||
# Feature Integrations
|
||||
has_monitoring=$(echo "$service_data" | ${jq}/bin/jq -r '.features.monitoring.available')
|
||||
has_logging=$(echo "$service_data" | ${jq}/bin/jq -r '.features.logging.available')
|
||||
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
|
||||
|
||||
# Monitoring Feature
|
||||
if [[ "$has_monitoring" == "true" ]]; then
|
||||
echo "##### 📊 Monitoring Integration"
|
||||
echo
|
||||
echo "Available monitoring options:"
|
||||
echo
|
||||
echo '```nix'
|
||||
echo "homelab.services.$service = {"
|
||||
echo " # ... core options above ..."
|
||||
echo
|
||||
|
||||
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 '```'
|
||||
|
||||
# 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 "**$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
|
||||
|
||||
echo "---"
|
||||
echo
|
||||
done
|
||||
|
||||
echo "## Integration Summary"
|
||||
echo "## Feature Reference"
|
||||
echo
|
||||
echo "### Available Integration Types"
|
||||
echo "### Integration Features"
|
||||
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 "Homelab services can integrate with three main features:"
|
||||
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 "- **🔄 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 "Each service can import these features and set service-specific defaults."
|
||||
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