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

516 lines
15 KiB
Text
Raw Permalink Normal View History

# 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
}