provisioning-core/nulib/domain/workspace/config_commands.nu

515 lines
15 KiB
Text
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Workspace Configuration Management Commands
# Provides commands to view, edit, validate, and manage workspace configurations
use platform/user/config.nu [list-workspaces get-active-workspace get-workspace-path get-user-config-dir]
use tools/nickel/process.nu [ncl-eval-soft]
# Get active workspace context or load by name
def get-workspace-context [
workspace_name?: string
] {
if ($workspace_name | is-empty) {
let active = (get-active-workspace)
if ($active | is-empty) {
print "❌ No active workspace found. Use 'provisioning workspace activate <name>'"
exit 1
}
let path = (get-workspace-path $active)
{
name: $active
path: $path
}
} else {
let contexts = (list-workspaces)
# First try to match by name
let found = ($contexts | where name == $workspace_name | first)
if ($found | is-empty) {
let input_as_path = if ($workspace_name | path exists) {
$workspace_name | path expand
} else {
let rel_path = ($env.PWD | path join $workspace_name)
if ($rel_path | path exists) {
$rel_path | path expand
} else {
$workspace_name | path expand
}
}
let path_exists = ($input_as_path | path exists)
if $path_exists {
let found_by_path = ($contexts | where (path | path expand) == $input_as_path | first)
if ($found_by_path | is-not-empty) {
return $found_by_path
}
let config_file_nickel = ($input_as_path | path join "config" | path join "provisioning.ncl")
let config_file_yaml = ($input_as_path | path join "config" | path join "provisioning.yaml")
if (($config_file_nickel | path exists) or ($config_file_yaml | path exists)) {
return {
name: ($input_as_path | path basename)
path: $input_as_path
}
}
}
let found_by_exact_path = ($contexts | where path == $workspace_name | first)
if ($found_by_exact_path | is-not-empty) {
return $found_by_exact_path
}
print $"❌ Workspace '($workspace_name)' not found"
exit 1
}
$found
}
}
# Show complete workspace configuration
export def "workspace-config-show" [
workspace_name?: string
--format: string = "yaml" # yaml, json, toml, nickel
] {
let workspace = (get-workspace-context $workspace_name)
let config_dir = ($workspace.path | path join "config")
let decl_file = ($config_dir | path join "provisioning.ncl")
let yaml_file = ($config_dir | path join "provisioning.yaml")
let config_file = if ($decl_file | path exists) {
let ncl_ok = (ncl-eval-soft $decl_file [] null | is-not-empty)
if $ncl_ok {
$decl_file
} else if ($yaml_file | path exists) {
$yaml_file
} else {
$decl_file
}
} else if ($yaml_file | path exists) {
$yaml_file
} else {
null
}
if ($config_file | is-empty) {
print "❌ No workspace configuration found (neither .ncl nor .yaml)"
exit 1
}
let config = if ($config_file | str ends-with ".ncl") {
let file_dir = ($config_file | path dirname)
let file_name = ($config_file | path basename)
let decl_mod_exists = (($file_dir | path join "nickel.mod") | path exists)
let parsed = if $decl_mod_exists {
let res = (do { ^sh -c $"cd '($file_dir)' && nickel export ($file_name) --format json" } | complete)
if ($res.stdout | is-not-empty) { $res.stdout | from json } else { null }
} else {
ncl-eval-soft $config_file [] null
}
if ($parsed | is-empty) {
print "❌ Failed to load Nickel config: empty output"
exit 1
}
if (($parsed | columns) | any { |col| $col == "workspace_config" }) {
$parsed.workspace_config
} else {
$parsed
}
} else {
open $config_file
}
let config_type = if ($config_file | str ends-with ".ncl") { "Nickel" } else { "YAML" }
match $format {
"yaml" => {
print $"Configuration ($config_type): ($config_file)"
print ""
($config | to yaml)
}
"json" => {
print $"Configuration ($config_type): ($config_file)"
print ""
($config | to json)
}
"toml" => {
print $"Configuration ($config_type): ($config_file)"
print ""
($config | to toml)
}
"nickel" => {
if ($config_file | str ends-with ".ncl") {
open $config_file
} else {
print " Configuration is stored in YAML format, not Nickel"
print " Use --format=yaml to view the config"
($config | to json)
}
}
_ => ($config | to yaml)
}
}
# Validate workspace configuration
export def "workspace-config-validate" [
workspace_name?: string
] {
let workspace = (get-workspace-context $workspace_name)
print $"🔍 Validating workspace: ($workspace.name)"
print ""
mut all_valid = true
let config_dir = ($workspace.path | path join "config")
let decl_file = ($config_dir | path join "provisioning.ncl")
let yaml_file = ($config_dir | path join "provisioning.yaml")
let config_file = if ($decl_file | path exists) {
let ncl_ok = (ncl-eval-soft $decl_file [] null | is-not-empty)
if $ncl_ok {
$decl_file
} else if ($yaml_file | path exists) {
$yaml_file
} else {
$decl_file
}
} else if ($yaml_file | path exists) {
$yaml_file
} else {
null
}
if ($config_file | is-empty) {
print "✓ Main config: (not found)"
print " ❌ No Nickel (.ncl) or YAML (.yaml) config file found"
$all_valid = false
} else {
let config_type = if ($config_file | str ends-with ".ncl") { "Nickel" } else { "YAML" }
print $"✓ Main config: ($config_file) [($config_type)]"
let config = if ($config_file | str ends-with ".ncl") {
let file_dir = ($config_file | path dirname)
let file_name = ($config_file | path basename)
let decl_mod_exists = (($file_dir | path join "nickel.mod") | path exists)
let parsed = if $decl_mod_exists {
let res = (do { ^sh -c $"cd '($file_dir)' && nickel export ($file_name) --format json" } | complete)
if ($res.stdout | is-not-empty) { $res.stdout | from json } else { null }
} else {
ncl-eval-soft $config_file [] null
}
if ($parsed | is-empty) {
print $" ❌ Nickel compilation failed, but YAML fallback not available"
$all_valid = false
{}
} else {
if (($parsed | columns) | any { |col| $col == "workspace_config" }) {
$parsed.workspace_config
} else {
$parsed
}
}
} else {
open $config_file
}
if ($config | is-not-empty) {
if ($config_file | str ends-with ".ncl") {
print " ✅ Valid Nickel (schema validated)"
} else {
print " ✅ Valid YAML"
}
if ($config | get workspace? | default null | is-empty) {
print $" ⚠️ Missing 'workspace' section"
}
if ($config | get paths? | default null | is-empty) {
print $" ⚠️ Missing 'paths' section"
}
}
}
print ""
print "Providers:"
let providers_dir = ($workspace.path | path join "config" | path join "providers")
if ($providers_dir | path exists) {
let provider_files = (glob $"($providers_dir)/*.toml")
if ($provider_files | is-empty) {
print " ⚠️ No provider configs found"
} else {
for file in $provider_files {
let provider_name = ($file | path basename | str replace ".toml" "")
print $" ✓ ($provider_name): ($file)"
let _ = (open $file)
print $" ✅ Valid TOML"
}
}
} else {
print " ⚠️ No providers directory"
}
print ""
print "Platform Services:"
let platform_dir = ($workspace.path | path join "config" | path join "platform")
if ($platform_dir | path exists) {
let platform_files = (glob $"($platform_dir)/*.toml")
if ($platform_files | is-empty) {
print " ⚠️ No platform service configs found"
} else {
for file in $platform_files {
let service_name = ($file | path basename | str replace ".toml" "")
print $" ✓ ($service_name): ($file)"
let _ = (open $file)
print $" ✅ Valid TOML"
}
}
} else {
print " ⚠️ No platform services directory"
}
print ""
print "KMS Configuration:"
let kms_file = ($workspace.path | path join "config" | path join "kms.toml")
if ($kms_file | path exists) {
print $" ✓ KMS config: ($kms_file)"
let _ = (open $kms_file)
print $" ✅ Valid TOML"
} else {
print " ⚠️ KMS not configured"
}
print ""
if $all_valid {
print "✅ Validation complete - all configs are valid"
} else {
print "❌ Validation failed - some configs have errors"
}
$all_valid
}
# Generate provider config for workspace
export def "workspace-config-generate-provider" [
provider_name: string
workspace_name?: string
] {
let workspace = (get-workspace-context $workspace_name)
let provisioning_path = $env.PROVISIONING_PATH?
if ($provisioning_path | is-empty) {
print "❌ PROVISIONING_PATH environment variable not set"
exit 1
}
let template_dir = ($provisioning_path | path join "catalog" | path join "providers" | path join $provider_name)
let template_file = ($template_dir | path join "config.defaults.toml")
if not ($template_file | path exists) {
print "❌ Provider template not found: ($provider_name)"
exit 1
}
let output_dir = ($workspace.path | path join "config" | path join "providers")
mkdir $output_dir
let output_file = ($output_dir | path join $"($provider_name).toml")
let template = (open $template_file)
let content = (
$template
| str replace --all "{{workspace.path}}" $workspace.path
| str replace --all "{{workspace.name}}" $workspace.name
)
$content | save $output_file
print $"✅ Provider config generated: ($output_file)"
print $"💡 Edit the file to customize settings"
}
# Edit configuration file
export def "workspace-config-edit" [
config_type: string # provider, platform, kms, main
name?: string # provider/platform name (not needed for kms/main)
workspace_name?: string
] {
let workspace = (get-workspace-context $workspace_name)
let config_file = match $config_type {
"main" => ($workspace.path | path join "config" | path join "provisioning.yaml")
"provider" => {
if ($name | is-empty) {
print "❌ Provider name required"
exit 1
}
($workspace.path | path join "config" | path join "providers" | path join $"($name).toml")
}
"platform" => {
if ($name | is-empty) {
print "❌ Platform service name required"
exit 1
}
($workspace.path | path join "config" | path join "platform" | path join $"($name).toml")
}
"kms" => ($workspace.path | path join "config" | path join "kms.toml")
_ => {
print "❌ Unknown config type: ($config_type)"
exit 1
}
}
if not ($config_file | path exists) {
print "❌ Config file not found: ($config_file)"
exit 1
}
let editor = ($env.EDITOR? | default "vi")
^$editor $config_file
}
# Show configuration hierarchy
export def "workspace-config-hierarchy" [
workspace_name?: string
] {
let workspace = (get-workspace-context $workspace_name)
print $"📊 Configuration Hierarchy for: ($workspace.name)"
print "=================================================="
print ""
print "Priority (highest to lowest):"
print ""
print "5. Environment Variables (highest)"
print " PROVISIONING_*"
print ""
print "4. User Context"
let user_config = ((get-user-config-dir) | path join $"ws_($workspace.name).yaml")
print $" ($user_config)"
if ($user_config | path exists) {
print " ✅ Exists"
} else {
print " ⚠️ Not found"
}
print ""
print "3. Platform Services"
let platform_dir = ($workspace.path | path join "config" | path join "platform")
print $" ($platform_dir)/"
if ($platform_dir | path exists) {
let files = (ls $"($platform_dir)/*.toml" | get name)
if ($files | is-empty) {
print " ⚠️ No platform configs"
} else {
for file in $files {
print $" • ($file | path basename)"
}
}
} else {
print " ⚠️ No platform configs"
}
print ""
print "2. Provider Configs"
let providers_dir = ($workspace.path | path join "config" | path join "providers")
print $" ($providers_dir)/"
if ($providers_dir | path exists) {
let files = (ls $"($providers_dir)/*.toml" | get name)
if ($files | is-empty) {
print " ⚠️ No provider configs"
} else {
for file in $files {
print $" • ($file | path basename)"
}
}
} else {
print " ⚠️ No provider configs"
}
print ""
print "1. Workspace Config (lowest)"
let main_config = ($workspace.path | path join "config" | path join "provisioning.yaml")
print $" ($main_config)"
if ($main_config | path exists) {
print " ✅ Exists"
} else {
print " ❌ Not found"
}
}
# List all configuration files for workspace
export def "workspace-config-list" [
workspace_name?: string
--type: string = "all" # all, provider, platform, kms, main
] {
let workspace = (get-workspace-context $workspace_name)
print $"📋 Configuration Files for: ($workspace.name)"
print "=================================================="
print ""
mut configs = []
if ($type == "all" or $type == "main") {
let main_config = ($workspace.path | path join "config" | path join "provisioning.yaml")
if ($main_config | path exists) {
$configs = ($configs | append {
type: "main"
name: "provisioning.yaml"
path: $main_config
exists: true
})
}
}
if ($type == "all" or $type == "provider") {
let providers_dir = ($workspace.path | path join "config" | path join "providers")
if ($providers_dir | path exists) {
let provider_files = (ls $"($providers_dir)/*.toml" | get name)
for file in $provider_files {
$configs = ($configs | append {
type: "provider"
name: ($file | path basename | str replace ".toml" "")
path: $file
exists: true
})
}
}
}
if ($type == "all" or $type == "platform") {
let platform_dir = ($workspace.path | path join "config" | path join "platform")
if ($platform_dir | path exists) {
let platform_files = (ls $"($platform_dir)/*.toml" | get name)
for file in $platform_files {
$configs = ($configs | append {
type: "platform"
name: ($file | path basename | str replace ".toml" "")
path: $file
exists: true
})
}
}
}
if ($type == "all" or $type == "kms") {
let kms_file = ($workspace.path | path join "config" | path join "kms.toml")
if ($kms_file | path exists) {
$configs = ($configs | append {
type: "kms"
name: "kms"
path: $kms_file
exists: true
})
}
}
$configs | table
}