chore: add current provisioning state before migration

This commit is contained in:
Jesús Pérez 2025-09-22 23:11:41 +01:00
parent a9703b4748
commit 50745b0f22
660 changed files with 88126 additions and 0 deletions

102
providers/local/bin/install.sh Executable file
View file

@ -0,0 +1,102 @@
#!/bin/bash
# Info: Script to install provider
# Author: JesusPerezLorenzo
# Release: 1.0
# Date: 15-04-2024
[ "$DEBUG" == "-x" ] && set -x
USAGE="install [ tool-name: upctl, etc | all | info] [--update]
As alternative use environment var TOOL_TO_INSTALL with a list-of-tools (separeted with spaces)
Versions are set in ./versions file
This can be called by directly with an argumet or from an other script
"
ORG=$(pwd)
function _info_tools {
local match=$1
local info_keys
info_keys="info version site"
if [ -z "$match" ] || [ "$match" == "all" ] || [ "$match" == "-" ]; then
match="all"
fi
echo "$PROVIDER_TITLE"
[ ! -r "$PROVIDERS_PATH/$PROVIDER_NAME/provisioning.yaml" ] && return
echo "-------------------------------------------------------"
case "$match" in
"i" | "?" | "info")
for key in $info_keys
do
echo -n "$key:"
[ "$key" != "version" ] && echo -ne "\t"
echo " $(grep "^$key:" "$PROVIDERS_PATH/$PROVIDER_NAME/provisioning.yaml" | sed "s/$key: //g")"
done
;;
"all")
cat "$PROVIDERS_PATH/$PROVIDER_NAME/provisioning.yaml"
;;
*)
echo -e "$match:\t $(grep "^$match:" "$PROVIDERS_PATH/$PROVIDER_NAME/provisioning.yaml" | sed "s/$match: //g")"
esac
echo "________________________________________________________"
}
function _install_tools {
local match=$1
shift
local options
options="$*"
local has_tool
local tool_version
OS="$(uname | tr '[:upper:]' '[:lower:]')"
ORG_OS=$(uname)
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')"
ORG_ARCH="$(uname -m)"
}
function _on_tools {
local tools_list=$1
[ -z "$tools_list" ] || [[ "$tools_list" == -* ]] && tools_list=${TOOL_TO_INSTALL:-all}
case $tools_list in
"all")
_install_tools "all" "$@"
;;
"info" | "i" | "?")
shift
_info_tools "$@"
;;
*)
for tool in $tools_list
do
[[ "$tool" == -* ]] && continue
_install_tools "$tool" "${*//$tool/}"
done
esac
}
set -o allexport
## shellcheck disable=SC1090
[ -n "$PROVISIONING_ENV" ] && [ -r "$PROVISIONING_ENV" ] && source "$PROVISIONING_ENV"
[ -r "../env-provisioning" ] && source ../env-provisioning
[ -r "env-provisioning" ] && source ./env-provisioning
#[ -r ".env" ] && source .env set
set +o allexport
export PROVISIONING=${PROVISIONING:-/usr/local/provisioning}
PROVIDERS_PATH=${PROVIDERS_PATH:-"$PROVISIONING/providers"}
PROVIDER_NAME="local"
PROVIDER_TITLE="Local"
if [ -r "$(dirname "$0")/../versions" ] ; then
. "$(dirname "$0")"/../versions
elif [ -r "$(dirname "$0")/versions" ] ; then
. "$(dirname "$0")"/versions
fi
[ "$1" == "-h" ] && echo "$USAGE" && shift
[ "$1" == "check" ] && CHECK_ONLY="yes" && shift
[ -n "$1" ] && cd /tmp && _on_tools "$@"
[ -z "$1" ] && _on_tools "$@"

View file

@ -0,0 +1,5 @@
export-env {
$env.LOCAL_API_URL = ($env | get -o LOCAL_API_URL | default "")
$env.LOCAL_AUTH = ($env | get -o LOCAL_AUTH | default "")
$env.LOCAL_INTERFACE = ($env | get -o LOCAL_INTERFACE | default "CLI") # API or CLI
}

View file

@ -0,0 +1,4 @@
use env.nu
export use servers.nu *
export use usage.nu *
export use utils.nu *

View file

@ -0,0 +1,575 @@
#!/usr/bin/env nu
use std
export def local_query_servers [
find: string
cols: string
] {
# TODO FIX
let res = (^upctl server list -o json err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete)
if $res.exit_code == 0 {
$res.stdout | from json | get servers
} else {
if $env.PROVISIONING_DEBUG {
(throw-error "🛑 local server list " $"($res.exit_code) ($res.stdout)" "local query server" --span (metadata $res).span)
} else {
print $"🛑 Error local server list: ($res.exit_code) ($res.stdout | ^grep 'error')"
}
}
}
export def local_server_info [
server: record
check: bool
] {
let hostname = $server.hostname
# TODO FIX
let res = (^upctl server show $hostname -o json err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete)
if $res.exit_code == 0 {
$res.stdout | from json
} else if $check {
{}
} else {
if $env.PROVISIONING_DEBUG {
(throw-error "🛑 local server show" $"($res.exit_code) ($res.stdout)" $"local server info ($hostname)" --span (metadata $res).span)
} else {
print $"🛑 local server show ($hostname):($res.stdout | ^grep 'error')"
}
}
}
export def local_on_prov_server [
server?: record
infra?: string
] {
let info = if ( $env.CURRENT_FILE? | into string ) != "" { (^grep "^# Info:" $env.CURRENT_FILE ) | str replace "# Info: " "" } else { "" }
print $env.CURRENT_FILE
$" From LOCAL ($info) "
}
# infrastructure and services
export def local [
args: list<string> # Args for create command
--server(-s): record
#hostname?: string # Server hostname in settings
--serverpos (-p): int # Server position in settings
--check (-c) # Only check mode no servers will be created
--wait (-w) # Wait servers to be created
--infra (-i): string # Infra path
--settings (-s): string # Settings path
--outfile (-o): string # Output file
--debug (-x) # Use Debug mode
] {
if $debug { $env.PROVISIONING_DEBUG = true }
let target = ($args | get -o 0 | default "")
let task = ($args | get -o 1 | default "")
let cmd_args = if ($args | length) > 1 { ($args | drop nth ..1) } else { [] }
match ($task) {
"help" | "h" | "" => {
print "TODO local help"
if not $env.PROVISIONING_DEBUG { end_run "" }
exit
},
_ => {
if ($args | find "help" | length) > 0 {
match $task {
"server" => {
print "SERVER "
local_server ($args | drop nth ..0)
#local_server ($args | drop nth ..1) --server $server
},
"inventory" => {
local_server ($args | drop nth ..0)
},
"ssh" => {
local_server ($args | drop nth ..0)
},
"delete" => {
local_server ($args | drop nth ..0)
# ($args | drop nth ..1) --server $server
},
_ => {
option_undefined "local" ""
print "TODO local help"
}
}
if not $env.PROVISIONING_DEBUG { end_run "" }
exit
}
}
}
#use utils/settings.nu [ load_settings ]
let curr_settings = if $infra != null {
if $settings != null {
(load_settings --infra $infra --settings $settings)
} else {
(load_settings --infra $infra)
}
} else {
if $settings != null {
(load_settings --settings $settings)
} else {
(load_settings)
}
}
match ($task) {
"get_ip" => {
local_get_ip $curr_settings $server ($cmd_args | get -o 0 | default "")
},
"server" => {
print (
local_server $cmd_args --server $server --settings $curr_settings --error_exit
)
},
"inventory" => {
},
"ssh" => {
},
"delete" => {
# ($args | drop nth ..1) --server $server
},
_ => {
option_undefined "local" ""
if not $env.PROVISIONING_DEBUG { end_run "" }
exit
}
}
}
export def local_get_ip [
settings: record
server: record
ip_type: string
] {
match $ip_type {
"private" | "prv" | "priv" => {
return $"($server.network_private_ip)"
},
_ => {
let ip = ($server.network_public_ip | default "")
# TODO FIX add NOT FOUND ERRORS
return $ip
#let result = (^upctl "server" "show" $server.hostname "-o" "json" | complete)
#if $result.exit_code == 0 {
# let data = ($result.stdout | from json)
# #let id = ($data.id? | default "")
# let ip_addresses = ($data.networking?.interfaces? | where {|it| ($it.type | str contains "public") }).ip_addresses?
# return $"(($ip_addresses | get -o 0).address? | get -o 0 | default '')"
#} else { "" }
}
}
}
# To create infrastructure and services
export def local_server [
args: list<string> # Args for create command
--server(-s): record
--error_exit
--status
#hostname?: string # Server hostname in settings
--serverpos (-p): int # Server position in settings
--check (-c) # Only check mode no servers will be created
--wait (-w) # Wait servers to be created
--infra (-i): string # Infra path
--settings (-s): record # Settings path
--outfile (-o): string # Output file
--debug (-x) # Use Debug mode
] {
let task = ($args | get -o 0)
let target = if ($args | length) > 1 { ($args | get -o 1) } else { "" }
let cmd_args = if ($args | length) > 1 { ($args | drop nth ..1) } else { [] }
match ($task) {
"help" | "h" | "" => {
print "TODO local server help"
if not $env.PROVISIONING_DEBUG { end_run "" }
exit
},
_ => {
if $target == "" or ($args | find "help" | length) > 0 {
match $task {
"server" => {
local_server $cmd_args
},
"status" => {
print $server
print $error_exit
}
"inventory" => {
print "TODO local server inventory help"
},
"ssh" => {
print "TODO local server ssh help"
},
"delete" => {
# ($args | drop nth ..1) --server $server
#local_delete_server $cmd_args true
},
_ => {
option_undefined "local" "server"
print "TODO local server help"
}
}
if not $env.PROVISIONING_DEBUG { end_run "" }
exit
}
}
}
let server_target = if $server != null {
$server
} else if $settings != null {
($settings.data.servers | where {|it| $it.hostname == $target } | get -o 0)
} else {
null
}
if $server_target == null {
if $error_exit {
let text = $"($args | str join ' ')"
(throw-error "🛑 local server" $text "" --span (metadata $server_target).span)
}
return ""
}
if $status or $task == "status" {
print "local server status "
return true
}
match $task {
"get_ip" => {
local_get_ip $settings $server_target ($cmd_args | get -o 0 | default "")
},
"stop" => {
print "TODO local server stop"
},
"start" => {
print "TODO local server start"
},
"restart" => {
print "TODO local server restart"
},
_ => {
option_undefined "local" "server"
if not $env.PROVISIONING_DEBUG { end_run "" }
exit
}
}
}
export def local_create_private_network [
settings: record
server: record
check: bool
] {
if $server == null {
print $"❗ No server found in settings "
return ""
}
# new_upctl network list -o json |
# let net_id = ($data.networks | get -o 0 ).uuid)
let zone = ( $server.zone? | default "")
if $zone == "" {
print $"($server.hostname) No zone found to CREATE network_privat_id"
return ""
}
let network_private_name = ($server.network_private_name? | default "")
if $network_private_name == "" {
print $"($server.hostname) No network_private_name found to CREATE network_privat_id"
return ""
}
let priv_cidr_block = ($server.priv_cidr_block | default "")
if $network_private_name == "" {
print $"($server.hostname) No priv_cidr_block found to CREATE network_privat_id"
return ""
}
# EXAMPLE_BASH private_net_id=$(upctl network list -o yaml | $YQ '.networks[] | select(.ip_networks.ip_network[].address == "'"$priv_cidr_block"'") | .uuid' 2>/dev/null | sed 's,",,g')
let result = (^upctl "network" "list" "-o" "json" | complete)
let private_net_id = if $result.exit_code == 0 {
let data = ($result.stdout | from json )
($data.networks? | find $priv_cidr_block | get -o 0 | get -o uuid | default "")
} else {
""
}
if $check and $private_net_id == "" {
print $"❗private_network will be register in a real creation request not in check state"
return ""
} else if $private_net_id == "" {
let result = (^upctl network create --name $network_private_name --zone $zone --ip-network $"address='($priv_cidr_block)',dhcp=true" -o json ) | complete
let new_net_id = if $result.exit_code == 0 {
(($result.stdout | from json | find $priv_cidr_block | get -o 0).uuid? | default "")
} else { "" }
if $new_net_id == "" {
(throw-error $"🛑 no private network ($network_private_name) found"
$"for server ($server.hostname) ip ($server.network_private_ip)"
$"local_check_requirements" --span (metadata $new_net_id.span))
return false
}
# Save changes ...
#use utils/settings.nu [ save_servers_settings save_settings_file ]
let match_text = " network_private_id = "
let defs_provider_path = $"($settings.data.server_path | get -o 0 | path dirname)/local_defaults"
save_servers_setings $settings $match_text $new_net_id
save_settings_file $settings $"($settings.src_path)/($settings.src)" $match_text $new_net_id
save_settings_file $settings $"($defs_provider_path)" $match_text $new_net_id
}
return true
}
export def local_check_server_requirements [
settings: record
server: record
check: bool
] {
if $server.provider != "local" { return false }
print ($"✅ (_ansi blue_bold)($server.hostname)(_ansi reset) with provider " +
$"(_ansi green_bold)($server.provider)(_ansi reset) ($server.zone) does not require creation !" )
true
}
export def local_make_settings [
settings: record
server: record
] {
# # _delete_settings
let out_settings_path = $"($settings.infra_fullpath)/($server.provider)_settings.yaml"
let data = if ($out_settings_path | path exists ) {
(open $out_settings_path | from yaml)
} else {
null
}
let task = if $data != null { "update" } else { "create" }
let uuid = (^upctl server show $server.hostname "-o" "json" | from json).uuid? | default ""
# echo "settings:" > "$out_settings"
# for server in $(_settings_hosts)
# do
if $uuid == "" {
return false
}
let ip_pub = (local_get_ip $settings $server "public")
let ip_priv = (local_get_ip $settings $server "private")
let server_settings = {
name: $server.hostname,
id: $uuid,
private_net: {
id: $server.network_private_id
name: $server.network_private_name
},
zone: $server.zone,
datetime: $env.NOW,
ip_addresses: {
pub: $ip_pub, priv: $ip_priv
}
}
let new_data = if $data != null and $data.servers? != null {
( $data.servers | each { |srv|
where {|it| $it.name != $server.hostname }
}) | append $server_settings
} else {
## create data record
{
servers: [ $server_settings ]
}
}
$new_data | to yaml | save --force $out_settings_path
print $"✅ local settings ($task) -> ($out_settings_path)"
true
}
export def local_delete_settings [
settings: record
server: record
] {
}
export def local_post_create_server [
settings: record
server: record
check: bool
] {
if $server != null {
return (local_storage_fix_size $settings $server 0)
}
true
}
export def local_modify_server [
settings: record
server: record
new_values: list
error_exit: bool
] {
# TODO LOCAL
return
let res = (^upctl server $server.hostname modify ...($new_values) | complete)
if $res.exit_code != 0 {
print $"❗ Server ($server.hostname) modify ($new_values | str join ' ') errors ($res.stdout ) "
if $error_exit {
exit 1
} else {
return "error"
}
}
}
export def local_storage_fix_size [
settings: record
server: record
storage_pos: int
] {
# TODO LOCAL
return
let total_size = ($server | get -o storages | get $storage_pos | get -o total | default 0)
if $total_size == 0 { return 0 }
let storage = (^upctl server show $server.hostname "-o" "json" | from json).storage_devices | (get -o $storage_pos)
if $storage == null { return 0 }
let curr_size = $storage.storage_size? | default 0
if $curr_size == 0 { return 0 }
if $curr_size != $total_size {
print (
$"Stop (_ansi blue_bold)($server.hostname)(_ansi reset) for storage (_ansi yellow_bold)($storage.storage)(_ansi reset)" +
$" from (_ansi purple_bold)($curr_size)(_ansi reset) to (_ansi green_bold)($total_size)(_ansi reset) ... "
)
if (local_change_server_state $settings $server "stop" "") == false {
print $"❗ Stop ($server.hostname) errors "
return "error"
}
let res = (^upctl storage modify --size $total_size $storage.storage | complete)
if $res.exit_code != 0 {
print $"❗ Storage modify errors ($res.stdout ) "
return "error"
}
let new_storage = (^upctl server show $server.hostname "-o" "json" | from json).storage_devices | (get -o $storage_pos)
let new_curr_size = $new_storage.storage_size? | default 0
print $"Start (_ansi blue_bold)($server.hostname)(_ansi reset) with new size (_ansi green_bold)($new_curr_size)(_ansi reset) ... "
if (local_change_server_state $settings $server "start" "") == false {
print $"❗ Errors to start ($server.hostname): ($res.stdout ) "
return "error"
}
return "storage"
}
""
}
export def local_status_server [
hostname: string
] {
let res = (^upctl server show $hostname "-o" "json" | complete)
if $res.exit_code != 0 {
print $"❗ status ($hostname) errors ($res.stdout ) "
return ""
}
return (($res.stdout | from json).state | default "")
}
export def local_server_exists [
server: record
error_exit: bool
] {
let res = (^upctl server show $server.hostname "-o" "json" err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete)
if $res.exit_code != 0 {
if $error_exit {
print $"❗ status ($server.hostname) errors ($res.stdout ) "
exit 1
} else {
return false
}
}
true
}
export def local_server_state [
server: record
new_state: string
error_exit: bool
wait: bool
settings: record
] {
}
export def local_server_is_running [
server: record
error_exit: bool
] {
true
#TODO FIX
# let res = (^upctl server show $server.hostname "-o" "json" err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete)
# if $res.exit_code != 0 {
# print $"❗ status ($server.hostname) errors ($res.stdout ) "
# if $error_exit {
# exit 1
# } else {
# return false
# }
# }
# (($res.stdout | from json).state? | str contains "started" | default false)
}
export def local_change_server_state [
settings: record
server: record
new_state: string
ops: string
] {
let state = (local_status_server $server.hostname)
if $state == "" { return false }
if ($state | str contains $new_state) { return true }
print $"Checking (_ansi blue_bold)($server.hostname)(_ansi reset) state (_ansi yellow_bold)($new_state)(_ansi reset) ..."
let val_timeout = if $server.running_timeout? != null { $server.running_timeout } else { 60 }
let wait = if $server.running_wait? != null { $server.running_wait } else { 10 }
let wait_duration = ($"($wait)sec"| into duration)
mut num = 0
while true {
let status = (local_status_server $server.hostname)
if $status == "" {
return false
} else if ($status | str contains "maintenance") == false {
print " "
break
} else if $val_timeout > 0 and $num > $val_timeout {
print $"\n🛑 (_ansi red)Timeout(_ansi reset) ($val_timeout) (_ansi blue)($server.hostname)(_ansi reset) (_ansi blue_bold)($new_state)(_ansi reset) (_ansi red_bold)failed(_ansi reset) "
return false
} else {
$num = $num + $wait
if $env.PROVISIONING_DEBUG {
print -n $"(_ansi blue_bold) 🌥 (_ansi reset)(_ansi green)($server.hostname)(_ansi reset)->($status) "
} else {
print -n $"(_ansi blue_bold) 🌥 (_ansi reset)"
}
sleep $wait_duration
}
}
let res = if ($ops | str contains "--type" ) {
(^upctl server $new_state --type ($ops | str replace "--type " "") $server.hostname | complete)
} else if $ops != "" {
(^upctl server $new_state $ops $server.hostname | complete)
} else {
(^upctl server $new_state $server.hostname | complete)
}
if $res.exit_code != 0 {
print $"❗Errors ($server.hostname) to ($new_state) ($res.stdout ) "
return false
}
$num = 0
while true {
let status = (local_status_server $server.hostname)
if ($status | str contains $new_state) {
print " "
return true
} else if $val_timeout > 0 and $num > $val_timeout {
print $"\n🛑 (_ansi red)Timeout(_ansi reset) ($val_timeout) (_ansi blue)($server.hostname)(_ansi reset) (_ansi blue_bold)($new_state)(_ansi reset) (_ansi red_bold)failed(_ansi reset) "
return false
} else {
$num = $num + $wait
if $env.PROVISIONING_DEBUG {
print -n $"(_ansi blue_bold) 🌥 (_ansi reset)(_ansi green)($server.hostname)(_ansi reset)->($status) "
} else {
print -n $"(_ansi blue_bold) 🌥 (_ansi reset)"
}
sleep $wait_duration
}
}
false
}
export def local_delete_server_storage [
settings: record
server: record
error_exit: bool
] {
print ($"✅ (_ansi blue_bold)($server.hostname)(_ansi reset) with provider " +
$"(_ansi green_bold)($server.provider)(_ansi reset) ($server.zone) does not require delete storage !" )
true
}
export def local_delete_server [
settings: record
server: record
keep_storage: bool
error_exit: bool
] {
print ($"✅ (_ansi blue_bold)($server.hostname)(_ansi reset) with provider " +
$"(_ansi green_bold)($server.provider)(_ansi reset) ($server.zone) does not require delete !" )
true
}

View file

@ -0,0 +1,41 @@
#!/usr/bin/env nu
# myscript.nu
export def usage [provider: string, infra: string] {
let info = if ( $env.CURRENT_FILE? | into string ) != "" { (^grep "^# Info:" $env.CURRENT_FILE ) | str replace "# Info: " "" } else { "" }
# $(declare -F _usage_options >/dev/null && _usage_options)
$"
USAGE provisioning ($provider) -k cloud-path file-settings.yaml provider-options
DESCRIPTION
LOCAL ($info)
OPTIONS
-s server-hostname
with server-hostname target selection
-p provider-name
use provider name
do not need if 'current directory path basename' is not one of providers available
-new | new [provisioning-name]
create a new provisioning-directory-name by a copy of ($infra)
-k cloud-path-item
use cloud-path-item as base directory for settings
-x
Trace script with 'set -x'
providerslist | providers-list | providers list
Get available providers list
taskslist | tasks-list | tasks list
Get available tasks list
serviceslist | service-list
Get available services list
tools
Run core/on-tools info
-i
About this
-v
Print version
-h, --help
Print this help and exit.
"
# ["hello" $name $title]
}

View file

View file

@ -0,0 +1,4 @@
version: 1.0
info: Local provisioning
site: ""
tools: []

0
providers/local/versions Normal file
View file