398 lines
16 KiB
Text
398 lines
16 KiB
Text
|
|
|
||
|
|
use primitives/io/interface.nu [_ansi _print get-provisioning-no-terminal get-provisioning-out]
|
||
|
|
use primitives/infra/init.nu [get-provisioning-name get-provisioning-infra-path get-workspace-path]
|
||
|
|
use platform/config/accessor/functions.nu [get-providers-path get-taskservs-path]
|
||
|
|
use domain/utils/on_select.nu [run_on_selection]
|
||
|
|
|
||
|
|
def get-default-settings [] : nothing -> string { "settings.ncl" }
|
||
|
|
|
||
|
|
export def get_provisioning_info [
|
||
|
|
dir_path: string
|
||
|
|
target: string
|
||
|
|
] {
|
||
|
|
# task root path target will be empty
|
||
|
|
let item = if $target != "" { $target } else { ($dir_path | path basename) }
|
||
|
|
let full_path = if $target != "" { $"($dir_path)/($item)" } else { $dir_path }
|
||
|
|
if not ($full_path | path exists) {
|
||
|
|
_print $"🛑 NO path found for (_ansi cyan)($full_path)(_ansi reset)"
|
||
|
|
return []
|
||
|
|
}
|
||
|
|
ls -s $full_path | where {|el|(
|
||
|
|
$el.type == "dir"
|
||
|
|
# discard paths with "_" prefix
|
||
|
|
and ($el.name != "generate" )
|
||
|
|
and ($el.name | str starts-with "_") == false
|
||
|
|
and (
|
||
|
|
# When target is empty (listing all tasks), accept all directories
|
||
|
|
# When target is specified (looking for modes), require default or install script
|
||
|
|
if $target == "" {
|
||
|
|
true
|
||
|
|
} else {
|
||
|
|
# for main task directory at least has default
|
||
|
|
($full_path | path join $el.name | path join "default" | path exists)
|
||
|
|
# for modes in task directory at least has install-task.sh file
|
||
|
|
or ($"($full_path)/($el.name)/install-($item).sh" | path exists)
|
||
|
|
}
|
||
|
|
)
|
||
|
|
)} |
|
||
|
|
each {|it|
|
||
|
|
if ($"($full_path)/($it.name)" | path exists) and ($"($full_path)/($it.name)/provisioning.toml" | path exists) {
|
||
|
|
# load provisioning.toml for info and vers
|
||
|
|
let provisioning_data = open $"($full_path)/($it.name)/provisioning.toml"
|
||
|
|
{ task: $item, mode: ($it.name), info: $provisioning_data.info, vers: $provisioning_data.release}
|
||
|
|
} else {
|
||
|
|
{ task: $item, mode: ($it.name), info: "", vers: ""}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
export def providers_list [
|
||
|
|
mode?: string
|
||
|
|
] {
|
||
|
|
let configured_path = (get-providers-path)
|
||
|
|
let providers_path = if ($configured_path | is-empty) {
|
||
|
|
# Fallback to system providers directory
|
||
|
|
($env.PROVISIONING | path join "catalog/providers")
|
||
|
|
} else {
|
||
|
|
$configured_path
|
||
|
|
}
|
||
|
|
if ($providers_path | is-empty) or (not ($providers_path | path exists)) { return [] }
|
||
|
|
ls -s $providers_path | where {|it| (
|
||
|
|
($it.name | str starts-with "_") == false
|
||
|
|
and ($providers_path | path join $it.name | path type) == "dir"
|
||
|
|
and ($providers_path | path join $it.name | path join "templates" | path exists)
|
||
|
|
)
|
||
|
|
} |
|
||
|
|
each {|it|
|
||
|
|
let it_path = ($providers_path | path join $it.name | path join "provisioning.yaml")
|
||
|
|
if ($it_path | path exists) {
|
||
|
|
# load provisioning.yaml for info and vers
|
||
|
|
let provisioning_data = (open $it_path | default {})
|
||
|
|
let tools = match $mode {
|
||
|
|
"list" | "selection" => ($provisioning_data | get tools? | default {} | transpose key value | get key? | default [] | str join ',')
|
||
|
|
_ => ($provisioning_data | get tools? | default [])
|
||
|
|
}
|
||
|
|
{ name: ($it.name), info: ($provisioning_data | get info? | default ""), tools: $tools }
|
||
|
|
} else {
|
||
|
|
{ name: ($it.name), info: "", vers: "", source: "", site: ""}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
def detect_infra_context [] {
|
||
|
|
let env_infra = ($env.PROVISIONING_INFRA? | default "")
|
||
|
|
if ($env_infra | is-not-empty) {
|
||
|
|
return $env_infra
|
||
|
|
}
|
||
|
|
|
||
|
|
let current_path = pwd
|
||
|
|
|
||
|
|
if not ($current_path | str contains "/infra/") {
|
||
|
|
return ""
|
||
|
|
}
|
||
|
|
|
||
|
|
let after_infra = (
|
||
|
|
$current_path
|
||
|
|
| str index-of "/infra/"
|
||
|
|
)
|
||
|
|
|
||
|
|
if ($after_infra == null) {
|
||
|
|
return ""
|
||
|
|
}
|
||
|
|
|
||
|
|
let start_pos = $after_infra + ("/infra/" | str length)
|
||
|
|
let remainder = ($current_path | str substring $start_pos..)
|
||
|
|
|
||
|
|
let first_component = (
|
||
|
|
$remainder
|
||
|
|
| split row "/"
|
||
|
|
| get 0
|
||
|
|
)
|
||
|
|
|
||
|
|
if ($first_component | is-empty) {
|
||
|
|
return ""
|
||
|
|
}
|
||
|
|
|
||
|
|
$first_component
|
||
|
|
}
|
||
|
|
|
||
|
|
def get_infra_taskservs [infra_name: string] {
|
||
|
|
let current_path = pwd
|
||
|
|
|
||
|
|
let infra_taskservs_path = if ($current_path | str contains "/infra/") {
|
||
|
|
(
|
||
|
|
$current_path
|
||
|
|
| path dirname
|
||
|
|
| path dirname
|
||
|
|
| path join "infra"
|
||
|
|
| path join $infra_name
|
||
|
|
| path join "taskservs"
|
||
|
|
)
|
||
|
|
} else {
|
||
|
|
let workspace_base = if ($current_path | path basename) == "workspace_librecloud" {
|
||
|
|
$current_path
|
||
|
|
} else if ($current_path | path join "workspace_librecloud" | path exists) {
|
||
|
|
$current_path | path join "workspace_librecloud"
|
||
|
|
} else {
|
||
|
|
""
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($workspace_base | is-empty) {
|
||
|
|
return []
|
||
|
|
}
|
||
|
|
|
||
|
|
$workspace_base
|
||
|
|
| path join "infra"
|
||
|
|
| path join $infra_name
|
||
|
|
| path join "taskservs"
|
||
|
|
}
|
||
|
|
|
||
|
|
if not ($infra_taskservs_path | path exists) {
|
||
|
|
return []
|
||
|
|
}
|
||
|
|
|
||
|
|
ls -s $infra_taskservs_path | where {|el|
|
||
|
|
($el.name | str ends-with ".ncl") or ($el.type == "dir" and ($el.name | str starts-with "_") == false)
|
||
|
|
} | each {|it|
|
||
|
|
let task_name = if ($it.name | str ends-with ".ncl") {
|
||
|
|
$it.name | str replace ".ncl" ""
|
||
|
|
} else {
|
||
|
|
$it.name
|
||
|
|
}
|
||
|
|
|
||
|
|
let provisioning_taskservs = ($env.PROVISIONING_TASKSERVS_PATH? | default "")
|
||
|
|
if ($provisioning_taskservs | is-empty) or (not ($provisioning_taskservs | path exists)) {
|
||
|
|
{ task: $task_name, mode: "configured", info: "", vers: "" }
|
||
|
|
} else {
|
||
|
|
let global_tasks = get_provisioning_info $provisioning_taskservs "" | each { |it2|
|
||
|
|
get_provisioning_info ($provisioning_taskservs | path join $it2.mode) ""
|
||
|
|
} | flatten
|
||
|
|
|
||
|
|
let matching = $global_tasks | where {|t| $t.task == $task_name}
|
||
|
|
if ($matching | length) > 0 {
|
||
|
|
$matching | get 0
|
||
|
|
} else {
|
||
|
|
{ task: $task_name, mode: "local", info: "", vers: "" }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export def taskservs_list [
|
||
|
|
] {
|
||
|
|
let infra_context = detect_infra_context
|
||
|
|
|
||
|
|
if ($infra_context | is-not-empty) {
|
||
|
|
return (get_infra_taskservs $infra_context)
|
||
|
|
}
|
||
|
|
|
||
|
|
let provisioning_taskservs = ($env.PROVISIONING_TASKSERVS_PATH? | default "")
|
||
|
|
|
||
|
|
if ($provisioning_taskservs | is-empty) {
|
||
|
|
return []
|
||
|
|
}
|
||
|
|
|
||
|
|
if not ($provisioning_taskservs | path exists) {
|
||
|
|
return []
|
||
|
|
}
|
||
|
|
|
||
|
|
get_provisioning_info $provisioning_taskservs "" |
|
||
|
|
each { |it|
|
||
|
|
get_provisioning_info ($provisioning_taskservs | path join $it.mode) ""
|
||
|
|
} | flatten
|
||
|
|
}
|
||
|
|
export def cluster_list [
|
||
|
|
] {
|
||
|
|
let current_path = pwd
|
||
|
|
let workspace_base = if ($current_path | path basename) == "workspace_librecloud" {
|
||
|
|
$current_path
|
||
|
|
} else if ($current_path | path join "workspace_librecloud" | path exists) {
|
||
|
|
$current_path | path join "workspace_librecloud"
|
||
|
|
} else {
|
||
|
|
""
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($workspace_base | is-empty) {
|
||
|
|
return []
|
||
|
|
}
|
||
|
|
|
||
|
|
let clusters_path = $workspace_base | path join ".clusters"
|
||
|
|
|
||
|
|
if not ($clusters_path | path exists) {
|
||
|
|
return []
|
||
|
|
}
|
||
|
|
|
||
|
|
get_provisioning_info $clusters_path "" |
|
||
|
|
each { |it|
|
||
|
|
get_provisioning_info ($clusters_path | path join $it.mode) ""
|
||
|
|
} | flatten | default []
|
||
|
|
}
|
||
|
|
export def infras_list [
|
||
|
|
] {
|
||
|
|
let current_path = pwd
|
||
|
|
let workspace_base = if ($current_path | path basename) == "workspace_librecloud" {
|
||
|
|
$current_path
|
||
|
|
} else if ($current_path | path join "workspace_librecloud" | path exists) {
|
||
|
|
$current_path | path join "workspace_librecloud"
|
||
|
|
} else {
|
||
|
|
""
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($workspace_base | is-empty) {
|
||
|
|
return []
|
||
|
|
}
|
||
|
|
|
||
|
|
let infra_path = $workspace_base | path join "infra"
|
||
|
|
|
||
|
|
if not ($infra_path | path exists) {
|
||
|
|
return []
|
||
|
|
}
|
||
|
|
|
||
|
|
ls -s $infra_path | where {|el|
|
||
|
|
$el.type == "dir" and ($infra_path | path join $el.name | path join "defs" | path exists)
|
||
|
|
} | each { |it|
|
||
|
|
{ name: $it.name, modified: $it.modified, size: $it.size}
|
||
|
|
} | flatten | default []
|
||
|
|
}
|
||
|
|
export def on_list [
|
||
|
|
target_list: string
|
||
|
|
cmd: string
|
||
|
|
ops: string
|
||
|
|
] {
|
||
|
|
match $target_list {
|
||
|
|
"providers" | "p" => {
|
||
|
|
_print $"\n(_ansi green)PROVIDERS(_ansi reset) list: \n"
|
||
|
|
let list_items = (providers_list "selection")
|
||
|
|
if ($list_items | length) == 0 {
|
||
|
|
_print $"🛑 no items found for (_ansi cyan)providers list(_ansi reset)"
|
||
|
|
return []
|
||
|
|
}
|
||
|
|
if $cmd == "-" { return $list_items }
|
||
|
|
if ($cmd | is-empty) {
|
||
|
|
_print ($list_items | to json) "json" "result" "table"
|
||
|
|
} else {
|
||
|
|
if (get-provisioning-out | is-not-empty) or (get-provisioning-no-terminal) { return ""}
|
||
|
|
let selection_pos = ($list_items | each {|it|
|
||
|
|
match ($it.name | str length) {
|
||
|
|
2..5 => $"($it.name)\t\t ($it.info) \tversion: ($it.vers)",
|
||
|
|
_ => $"($it.name)\t ($it.info) \tversion: ($it.vers)",
|
||
|
|
}
|
||
|
|
} | input list --index (
|
||
|
|
$"(_ansi default_dimmed)Select one item for (_ansi cyan_bold)($cmd)(_ansi reset)" +
|
||
|
|
$" \(use arrow keys and press [enter] or [escape] to exit\)( _ansi reset)"
|
||
|
|
)
|
||
|
|
)
|
||
|
|
if $selection_pos != null {
|
||
|
|
let item_selec = if ($list_items | length) > $selection_pos { $list_items | get $selection_pos } else { null }
|
||
|
|
let item_path = ((get-providers-path) | path join $item_selec.name)
|
||
|
|
if not ($item_path | path exists) { _print $"Path ($item_path) not found" }
|
||
|
|
(run_on_selection $cmd $item_selec.name $item_path
|
||
|
|
($item_path | path join "nulib" | path join $item_selec.name | path join "servers.nu") (get-providers-path))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return []
|
||
|
|
},
|
||
|
|
"taskservs" | "t" => {
|
||
|
|
_print $"\n(_ansi blue)TASKSERVICESS(_ansi reset) list: \n"
|
||
|
|
let list_items = (taskservs_list)
|
||
|
|
if ($list_items | length) == 0 {
|
||
|
|
_print $"🛑 no items found for (_ansi cyan)taskservs list(_ansi reset)"
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if $cmd == "-" { return $list_items }
|
||
|
|
if ($cmd | is-empty) {
|
||
|
|
_print ($list_items | to json) "json" "result" "table"
|
||
|
|
return []
|
||
|
|
} else {
|
||
|
|
if (get-provisioning-out | is-not-empty) or (get-provisioning-no-terminal) { return ""}
|
||
|
|
let selection_pos = ($list_items | each {|it|
|
||
|
|
match ($it.task | str length) {
|
||
|
|
2..4 => $"($it.task)\t\t ($it.mode)\t\t($it.info)\t($it.vers)",
|
||
|
|
5 => $"($it.task)\t\t ($it.mode)\t\t($it.info)\t($it.vers)",
|
||
|
|
12 => $"($it.task)\t ($it.mode)\t\t($it.info)\t($it.vers)",
|
||
|
|
15..20 => $"($it.task) ($it.mode)\t\t($it.info)\t($it.vers)",
|
||
|
|
_ => $"($it.task)\t ($it.mode)\t\t($it.info)\t($it.vers)",
|
||
|
|
}
|
||
|
|
} | input list --index (
|
||
|
|
$"(_ansi default_dimmed)Select one item for (_ansi cyan_bold)($cmd)(_ansi reset)" +
|
||
|
|
$" \(use arrow keys and press [enter] or [escape] to exit\)( _ansi reset)"
|
||
|
|
)
|
||
|
|
)
|
||
|
|
if $selection_pos != null {
|
||
|
|
let item_selec = if ($list_items | length) > $selection_pos { $list_items | get $selection_pos } else { null }
|
||
|
|
let item_path = $"((get-taskservs-path))/($item_selec.task)/($item_selec.mode)"
|
||
|
|
if not ($item_path | path exists) { _print $"Path ($item_path) not found" }
|
||
|
|
run_on_selection $cmd $item_selec.task $item_path ($item_path | path join $"install-($item_selec.task).sh") (get-taskservs-path)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return []
|
||
|
|
},
|
||
|
|
"clusters" | "c" => {
|
||
|
|
_print $"\n(_ansi purple)Cluster(_ansi reset) list: \n"
|
||
|
|
let list_items = (cluster_list)
|
||
|
|
if ($list_items | length) == 0 {
|
||
|
|
_print $"🛑 no items found for (_ansi cyan)cluster list(_ansi reset)"
|
||
|
|
return []
|
||
|
|
}
|
||
|
|
if $cmd == "-" { return $list_items }
|
||
|
|
if ($cmd | is-empty) {
|
||
|
|
_print ($list_items | to json) "json" "result" "table"
|
||
|
|
} else {
|
||
|
|
if (get-provisioning-out | is-not-empty) or (get-provisioning-no-terminal) { return ""}
|
||
|
|
let selection = (cluster_list | input list)
|
||
|
|
_print $"($cmd) ($selection)"
|
||
|
|
}
|
||
|
|
return []
|
||
|
|
},
|
||
|
|
"infras" | "i" => {
|
||
|
|
_print $"\n(_ansi cyan)Infrastructures(_ansi reset) list: \n"
|
||
|
|
let list_items = (infras_list)
|
||
|
|
if ($list_items | length) == 0 {
|
||
|
|
_print $"🛑 no items found for (_ansi cyan)infras list(_ansi reset)"
|
||
|
|
return []
|
||
|
|
}
|
||
|
|
if $cmd == "-" { return $list_items }
|
||
|
|
if ($cmd | is-empty) {
|
||
|
|
_print ($list_items | to json) "json" "result" "table"
|
||
|
|
} else {
|
||
|
|
if (get-provisioning-out | is-not-empty) or (get-provisioning-no-terminal) { return ""}
|
||
|
|
let selection_pos = ($list_items | each {|it|
|
||
|
|
match ($it.name | str length) {
|
||
|
|
2..5 => $"($it.name)\t\t ($it.modified) -- ($it.size)",
|
||
|
|
12 => $"($it.name)\t ($it.modified) -- ($it.size)",
|
||
|
|
15..20 => $"($it.name) ($it.modified) -- ($it.size)",
|
||
|
|
_ => $"($it.name)\t ($it.modified) -- ($it.size)",
|
||
|
|
}
|
||
|
|
} | input list --index (
|
||
|
|
$"(_ansi default_dimmed)Select one item for (_ansi cyan_bold)($cmd)(_ansi reset)" +
|
||
|
|
$" \(use arrow keys and [enter] or [escape] to exit\)( _ansi reset)"
|
||
|
|
)
|
||
|
|
)
|
||
|
|
if $selection_pos != null {
|
||
|
|
let item_selec = if ($list_items | length) > $selection_pos { $list_items | get $selection_pos } else { null }
|
||
|
|
let item_path = $"((get-workspace-path))/($item_selec.name)"
|
||
|
|
if not ($item_path | path exists) { _print $"Path ($item_path) not found" }
|
||
|
|
run_on_selection $cmd $item_selec.name $item_path ($item_path | path join (get-default-settings)) (get-provisioning-infra-path)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return []
|
||
|
|
},
|
||
|
|
"help" | "h" | _ => {
|
||
|
|
if $target_list != "help" or $target_list != "h" {
|
||
|
|
_print $"🛑 Not found ((get-provisioning-name)) target list option (_ansi red)($target_list)(_ansi reset)"
|
||
|
|
}
|
||
|
|
_print (
|
||
|
|
$"Use (_ansi blue_bold)((get-provisioning-name))(_ansi reset) (_ansi green)list(_ansi reset)" +
|
||
|
|
$" [ providers (_ansi green)p(_ansi reset) | tasks (_ansi green)t(_ansi reset) | " +
|
||
|
|
$"infras (_ansi cyan)i(_ansi reset) ] to list items" +
|
||
|
|
$"\n(_ansi default_dimmed)add(_ansi reset) --onsel (_ansi yellow_bold)e(_ansi reset)dit | " +
|
||
|
|
$"(_ansi yellow_bold)v(_ansi reset)iew | (_ansi yellow_bold)l(_ansi reset)ist | (_ansi yellow_bold)t(_ansi reset)ree | " +
|
||
|
|
$"(_ansi yellow_bold)c(_ansi reset)ode | (_ansi yellow_bold)s(_ansi reset)hell | (_ansi yellow_bold)n(_ansi reset)u"
|
||
|
|
)
|
||
|
|
return []
|
||
|
|
},
|
||
|
|
_ => {
|
||
|
|
_print $"🛑 invalid_option $list ($ops)"
|
||
|
|
return []
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|