2025-10-07 10:32:04 +01:00

190 lines
5.7 KiB
Plaintext

#!/usr/bin/env nu
# Cluster Discovery System
# Discovers available cluster definitions with metadata extraction
use ../lib_provisioning/config/accessor.nu config-get
# Discover all available clusters
export def discover-clusters []: nothing -> list<record> {
# Get absolute path to extensions directory from config
let clusters_path = (config-get "paths.clusters" | path expand)
if not ($clusters_path | path exists) {
error make { msg: $"Clusters path not found: ($clusters_path)" }
}
# Find all cluster directories with KCL modules
ls $clusters_path
| where type == "dir"
| each { |dir|
let cluster_name = ($dir.name | path basename)
let kcl_path = ($dir.name | path join "kcl")
let kcl_mod_path = ($kcl_path | path join "kcl.mod")
if ($kcl_mod_path | path exists) {
extract_cluster_metadata $cluster_name $kcl_path
}
}
| compact
| sort-by name
}
# Extract metadata from a cluster's KCL module
def extract_cluster_metadata [name: string, kcl_path: string]: nothing -> record {
let kcl_mod_path = ($kcl_path | path join "kcl.mod")
let mod_content = (open $kcl_mod_path | from toml)
# Find KCL schema files
let schema_files = (glob ($kcl_path | path join "*.k"))
let main_schema = ($schema_files | where ($it | str contains $name) | first | default "")
# Extract dependencies
let dependencies = ($mod_content.dependencies? | default {} | columns)
# Get description from schema file if available
let description = if ($main_schema != "") {
extract_schema_description $main_schema
} else {
$"($name | str title-case) cluster configuration"
}
# Extract cluster components from schema
let components = extract_cluster_components $main_schema
# Determine cluster type based on components
let cluster_type = determine_cluster_type $components
{
name: $name
type: "cluster"
cluster_type: $cluster_type
version: $mod_content.package.version
kcl_path: $kcl_path
main_schema: $main_schema
dependencies: $dependencies
components: $components
description: $description
available: true
last_updated: (ls $kcl_mod_path | get 0.modified)
}
}
# Extract description from KCL schema file
def extract_schema_description [schema_file: string]: nothing -> string {
if not ($schema_file | path exists) {
return ""
}
# Read first few lines to find description
let content = (open $schema_file | lines | take 10)
let description_lines = ($content | where ($it | str starts-with "# ") | take 3)
if ($description_lines | is-empty) {
return ""
}
$description_lines
| str replace "^# " ""
| str join " "
| str trim
}
# Extract cluster components from schema
def extract_cluster_components [schema_file: string]: nothing -> list<string> {
if not ($schema_file | path exists) {
return []
}
let content = (open $schema_file)
# Look for component patterns in the schema
let components = []
# Check for common component mentions
let common_components = [
"kubernetes", "k8s", "cilium", "calico", "nginx", "traefik",
"prometheus", "grafana", "redis", "postgres", "mysql",
"buildkit", "registry", "docker", "containerd"
]
$common_components | each { |comp|
if ($content | str contains $comp) {
$comp
}
} | compact
}
# Determine cluster type based on components
def determine_cluster_type [components: list<string>]: nothing -> string {
if ($components | any { |comp| $comp in ["buildkit", "registry", "docker"] }) {
"ci-cd"
} else if ($components | any { |comp| $comp in ["prometheus", "grafana"] }) {
"monitoring"
} else if ($components | any { |comp| $comp in ["nginx", "traefik"] }) {
"web"
} else if ($components | any { |comp| $comp in ["redis", "postgres", "mysql"] }) {
"database"
} else if ($components | any { |comp| $comp in ["kubernetes", "k8s"] }) {
"orchestration"
} else {
"application"
}
}
# Search clusters by name, type, or components
export def search-clusters [query: string]: nothing -> list<record> {
discover-clusters
| where (
($it.name | str contains $query) or
($it.cluster_type | str contains $query) or
($it.description | str contains $query) or
($it.components | any { |comp| $comp | str contains $query })
)
}
# Get specific cluster info
export def get-cluster-info [name: string]: nothing -> record {
let clusters = (discover-clusters)
let found = ($clusters | where name == $name | first)
if ($found | is-empty) {
error make { msg: $"Cluster '($name)' not found" }
}
$found
}
# List clusters by type
export def list-clusters-by-type [type: string]: nothing -> list<record> {
discover-clusters
| where cluster_type == $type
}
# Validate cluster availability
export def validate-clusters [names: list<string>]: nothing -> record {
let available = (discover-clusters | get name)
let missing = ($names | where ($it not-in $available))
let found = ($names | where ($it in $available))
{
requested: $names
found: $found
missing: $missing
valid: ($missing | is-empty)
}
}
# Get clusters that use specific components
export def find-clusters-with-component [component: string]: nothing -> list<record> {
discover-clusters
| where ($it.components | any { |comp| $comp == $component })
}
# List all available cluster types
export def list-cluster-types []: nothing -> list<string> {
discover-clusters
| get cluster_type
| uniq
| sort
}