chore: add current provisioning state before migration
This commit is contained in:
parent
a9703b4748
commit
50745b0f22
660 changed files with 88126 additions and 0 deletions
4
providers/upcloud/bin/get_plans.sh
Executable file
4
providers/upcloud/bin/get_plans.sh
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
[ -z "$1" ] && echo "no prefix plans found !!
|
||||
All plans can be display with: upctl server plans" && exit 1
|
||||
upctl server plans | grep $1 | awk '{ print $1}' | sed 's/^/\| "/g' | sed 's/$/"/g' | tr -d "\n"
|
||||
4
providers/upcloud/bin/get_zones.sh
Executable file
4
providers/upcloud/bin/get_zones.sh
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
[ -z "$1" ] && echo "no prefix zone found !!
|
||||
All zones can be display with: upctl zone list" && exit 1
|
||||
upctl zone list | grep $1 | awk '{ print $1}' | sed 's/^/\| "/g' | sed 's/$/"/g' | tr -d "\n"
|
||||
122
providers/upcloud/bin/install.sh
Executable file
122
providers/upcloud/bin/install.sh
Executable file
|
|
@ -0,0 +1,122 @@
|
|||
#!/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)"
|
||||
|
||||
UPCTL_VERSION=${UPCLOUD_UPCTL_VERSION:-}
|
||||
if [ -n "$UPCTL_VERSION" ] && [ "$match" == "all" ] || [ "$match" == "upctl" ] ; then
|
||||
has_upctl=$(type -P upctl)
|
||||
num_version="0"
|
||||
[ -n "$has_upctl" ] && upctl_version=$(upctl version | grep "Version" | cut -f2 -d":" | sed 's/ //g') && num_version=${upctl_version//\./}
|
||||
expected_version_num=${UPCTL_VERSION//\./}
|
||||
if [ -z "$CHECK_ONLY" ] && [ "$num_version" -lt "$expected_version_num" ] ; then
|
||||
mkdir -p upctl && cd upctl &&
|
||||
#curl -fsSLO $UPCLOUD_UPCTL_SOURCE/v${tool_version}/upcloud-cli_${tool_version}_${OS}_${ORG_ARCH}.tar.gz &&
|
||||
curl -fsSLO https://github.com/UpCloudLtd/upcloud-cli/releases/download/v${UPCTL_VERSION}/upcloud-cli_${UPCTL_VERSION}_${OS}_${ORG_ARCH}.tar.gz &&
|
||||
tar -xzf "upcloud-cli_${UPCTL_VERSION}_${OS}_${ORG_ARCH}.tar.gz" &&
|
||||
sudo mv upctl /usr/local/bin &&
|
||||
cd "$ORG" && rm -rf /tmp/upct "/upcloud-cli_${UPCTL_VERSION}_${OS}_${ORG_ARCH}.tar.gz"
|
||||
printf "%s\t%s\n" "upctl" "installed $UPCTL_VERSION"
|
||||
elif [ -n "$CHECK_ONLY" ] ; then
|
||||
printf "%s\t%s\t%s\n" "upctl" "$upctl_version" "expected $UPCTL_VERSION"
|
||||
else
|
||||
printf "%s\t%s\n" "upctl" "already $UPCTL_VERSION"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
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="upcloud"
|
||||
PROVIDER_TITLE="Upcloud"
|
||||
|
||||
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 "$@"
|
||||
362
providers/upcloud/nulib/upcloud/api.nu
Executable file
362
providers/upcloud/nulib/upcloud/api.nu
Executable file
|
|
@ -0,0 +1,362 @@
|
|||
#!/usr/bin/env nu
|
||||
# Info: UpCloud
|
||||
# api.nu
|
||||
|
||||
export def upcloud_api_auth [
|
||||
]: nothing -> string {
|
||||
let upcloud_auth = if (($env | get -o UPCLOUD_AUTH | default "") | is-empty) {
|
||||
let upcloud_username = ($env | get -o UPCLOUD_USERNAME | default "")
|
||||
let upcloud_password = ($env | get -o UPCLOUD_PASSWORD | default "")
|
||||
$"($upcloud_username):($upcloud_password)" | encode base64
|
||||
} else {
|
||||
($env | get -o UPCLOUD_AUTH | default "")
|
||||
}
|
||||
if $upcloud_auth == ":" or ($upcloud_auth | is-empty) {
|
||||
_print $"🛑 Not found (_ansi purple)UpCloud(_ansi reset) (_ansi red)credentials(_ansi reset)"
|
||||
return ""
|
||||
}
|
||||
$upcloud_auth
|
||||
}
|
||||
|
||||
export def upcloud_api_url [
|
||||
url_path: string
|
||||
]: nothing -> any {
|
||||
let upcloud_api_url = ($env | get -o UPCLOUD_API_URL | default "")
|
||||
if ($upcloud_api_url | is-empty) {
|
||||
_print $"🛑 Not found (_ansi purple)UpCloud(_ansi reset) (_ansi red)API URL(_ansi reset) not found"
|
||||
return ""
|
||||
}
|
||||
$"($upcloud_api_url)/($url_path)"
|
||||
}
|
||||
|
||||
export def upcloud_api_request [
|
||||
method: string
|
||||
url_path: string
|
||||
data?: any
|
||||
]: nothing -> any {
|
||||
let $upcloud_auth = (upcloud_api_auth)
|
||||
let upcloud_api_url = (upcloud_api_url $url_path)
|
||||
if ($upcloud_auth | is-empty) or ($upcloud_api_url | is-empty) { return "" }
|
||||
|
||||
# http options $"($upcloud_api_url)/($url_path)" --allow-errors --headers [Origin "https://api.upcloud.com" Access-Control-Request-Headers "Content-Type, X-Custom-Header" Access-Control-Request-Method GET, "Authorization" $" Basic ($upcloud_auth)"]
|
||||
let result = match $method {
|
||||
"post" => {
|
||||
if ($data | describe | str starts-with "record") {
|
||||
http post --content-type application/json --allow-errors --headers ["Authorization" $" Basic ($upcloud_auth)"] $upcloud_api_url $data
|
||||
} else {
|
||||
http post --allow-errors --headers ["Authorization" $" Basic ($upcloud_auth)"] $upcloud_api_url $data
|
||||
}
|
||||
},
|
||||
"put" => {
|
||||
http put --allow-errors --headers ["Authorization" $" Basic ($upcloud_auth)"] $upcloud_api_url $data
|
||||
}
|
||||
"delete" => {
|
||||
http delete --allow-errors --headers ["Authorization" $" Basic ($upcloud_auth)"] $upcloud_api_url
|
||||
}
|
||||
_ => {
|
||||
http get --allow-errors --headers ["Authorization" $" Basic ($upcloud_auth)"] $upcloud_api_url
|
||||
}
|
||||
}
|
||||
if ($result | describe) == "string" {
|
||||
if ($result | is-empty) { return "OK" }
|
||||
_print $"🛑 Error (_ansi purple)UpCloud(_ansi reset) (_ansi red)($upcloud_api_url)(_ansi reset):\n ($result)"
|
||||
return ""
|
||||
}
|
||||
let status = ($result | get -o status | default "")
|
||||
let error = ($result | get -o error | default "")
|
||||
if ($status | is-not-empty) or ($error | is-not-empty) {
|
||||
_print $"🛑 Error (_ansi purple)UpCloud(_ansi reset) (_ansi red)($upcloud_api_url)(_ansi reset)\n ($status) ($error))"
|
||||
return ""
|
||||
}
|
||||
$result
|
||||
}
|
||||
|
||||
export def upcloud_api_new_server [
|
||||
server: record
|
||||
]: nothing -> record {
|
||||
{
|
||||
hostname: "dev-wrkr",
|
||||
zone: "es-mad1",
|
||||
title: "dev-wrkr Debian server",
|
||||
labels: {
|
||||
label: [
|
||||
{
|
||||
"key": "test",
|
||||
"value": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
plan: "DEV-1xCPU-1GB",
|
||||
#plan: "DEV-1xCPU-4GB",
|
||||
metadata: "yes",
|
||||
simple_backup: "0400,dailies",
|
||||
timezone: "UTC",
|
||||
storage_devices: {
|
||||
storage_device: [
|
||||
{
|
||||
action: "clone",
|
||||
labels: [
|
||||
{
|
||||
"key": "foo",
|
||||
"value": "bar"
|
||||
}
|
||||
],
|
||||
storage: "01000000-0000-4000-8000-000020070100" # Debian GNU/Linux 12 (Bookworm)
|
||||
encrypted: "no",
|
||||
title: "dev-wrkr Debian from a template",
|
||||
#size: 50,
|
||||
size: 20,
|
||||
tier: "standard"
|
||||
#tier: "maxiops"
|
||||
}
|
||||
]
|
||||
},
|
||||
networking: {
|
||||
interfaces: {
|
||||
interface: [
|
||||
{
|
||||
ip_addresses: {
|
||||
ip_address: [
|
||||
{
|
||||
family: "IPv4"
|
||||
}
|
||||
]
|
||||
},
|
||||
type: "public"
|
||||
},
|
||||
{
|
||||
ip_addresses: {
|
||||
ip_address: [
|
||||
{
|
||||
family: "IPv4"
|
||||
}
|
||||
]
|
||||
},
|
||||
type: "utility"
|
||||
},
|
||||
{
|
||||
ip_addresses: {
|
||||
ip_address: [
|
||||
{
|
||||
family: "IPv6"
|
||||
}
|
||||
]
|
||||
},
|
||||
type: "public"
|
||||
},
|
||||
{
|
||||
type: "private",
|
||||
network: "03b1115c-522b-4608-ae08-9a4d32a2d16d"
|
||||
source_ip_filtering: "yes"
|
||||
ip_addresses: {
|
||||
ip_address: [
|
||||
{
|
||||
family: "IPv4",
|
||||
address: "10.11.2.11",
|
||||
dhcp_provided: "no"
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
login_user: {
|
||||
ssh_keys: {
|
||||
ssh_key: [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM5GLeuDFUdLl7p72xt4nCOmCrdwP5QG1F16kIAQQlMT cdci"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export def upcloud_api_list_servers [
|
||||
format?: string
|
||||
]: nothing -> list {
|
||||
let result = (upcloud_api_request "get" "server" )
|
||||
if ($result | is-empty) {
|
||||
return []
|
||||
}
|
||||
match $format {
|
||||
"main" => {
|
||||
mut servers_list = []
|
||||
for it in ($result | get -o servers | flatten) {
|
||||
let srv = ($it | get -o server )
|
||||
$servers_list = ($servers_list | append {
|
||||
state: ($srv| get -o state | default ""),
|
||||
hostname: ($srv| get -o hostname | default ""),
|
||||
uuid: ($srv| get -o uuid | default ""),
|
||||
title: ($srv| get -o title | default ""),
|
||||
plan: ($srv| get -o plan | default ""),
|
||||
zone: ($srv| get -o zone | default ""),
|
||||
memory_amount: ($srv| get -o memory_amount | default ""),
|
||||
core_number: ($srv| get -o core_number | default ""),
|
||||
simple_backup: ($srv| get -o simple_backup | default ""),
|
||||
server_group: ($srv| get -o server_group | default ""),
|
||||
})
|
||||
}
|
||||
$servers_list
|
||||
},
|
||||
_ => ($result | get -o servers | flatten)
|
||||
}
|
||||
}
|
||||
|
||||
export def upcloud_api_server_info [
|
||||
hostname: string
|
||||
]: nothing -> any {
|
||||
let servers_list = (upcloud_api_list_servers | where {|it| $it.server.hostname == $hostname })
|
||||
($servers_list | get -o 0 | get -o server | default "")
|
||||
}
|
||||
|
||||
export def upcloud_api_server_uuid [
|
||||
hostname: string
|
||||
uuid: string
|
||||
]: nothing -> string {
|
||||
if ($uuid | is-empty) {
|
||||
if ($hostname | is-empty) { return "" }
|
||||
(upcloud_api_server_info $hostname | get -o uuid | default "")
|
||||
} else { $uuid }
|
||||
}
|
||||
|
||||
export def upcloud_api_server_ip [
|
||||
server_info: record
|
||||
type: string = "public"
|
||||
family: string = "IPv4"
|
||||
]: nothing -> any {
|
||||
($server_info | get -o server | get -o networking | get -o interfaces | get -o interface
|
||||
| flatten | where {|item| $item.type == $type} | get -o ip_address
|
||||
| flatten | where {|it| $it.family == $family} | get -o address | get -o 0 | default ""
|
||||
)
|
||||
}
|
||||
export def upcloud_api_server_uuid_ip [
|
||||
uuid: string
|
||||
type: string = "public"
|
||||
family: string = "IPv4"
|
||||
]: nothing -> any {
|
||||
let result = (upcloud_api_request "get" $"server/($uuid)" )
|
||||
if ($result | is-empty) { return "" }
|
||||
(upcloud_api_server_ip $result $type $family)
|
||||
}
|
||||
export def upcloud_api_server_new_state [
|
||||
state: string
|
||||
uuid: string
|
||||
wait: int = 60
|
||||
]: nothing -> any {
|
||||
(upcloud_api_request
|
||||
"post"
|
||||
$"server/($uuid)/($state)"
|
||||
{ stop_server: { stop_type: "soft", timeout: $wait } }
|
||||
)
|
||||
}
|
||||
export def upcloud_api_server_state [
|
||||
hostname: string
|
||||
uuid: string
|
||||
]: nothing -> any {
|
||||
if ($uuid | is-not-empty) {
|
||||
(upcloud_api_request "get" $"server/($uuid)" | get -o state | default "" )
|
||||
} else if ($hostname | is-not-empty) {
|
||||
(upcloud_api_server_info $hostname | get -o state | default "")
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
export def upcloud_api_server_delete [
|
||||
hostname: string
|
||||
uuid: string
|
||||
# storages Controls what to do with storages related to the deleted server. 0, 1, true, false 0
|
||||
storage: bool = true
|
||||
# backups If storages are to be deleted, controls what to do with backups related to the storages. keep, keep_latest, delete keep
|
||||
backups: string = "delete"
|
||||
]: nothing -> any {
|
||||
let server_uuid = (upcloud_api_server_uuid $hostname $uuid)
|
||||
if ($server_uuid | is-empty) {
|
||||
_print $"🛑 Error (_ansi purple)UpCloud(_ansi reset) DELETE (_ansi red)($hostname) ($uuid)(_ansi reset)"
|
||||
return
|
||||
}
|
||||
(upcloud_api_request "delete" $"server/($uuid)?storages=($storage)&backups=($backups)")
|
||||
}
|
||||
export def upcloud_api_get_info [
|
||||
hostname: string
|
||||
type: string = "public"
|
||||
family: string = "IPv4"
|
||||
]: nothing -> string {
|
||||
let server = (upcloud_api_server_info $hostname)
|
||||
if ($server | is-empty) { return "" }
|
||||
# _print ($server | table -e)
|
||||
let uuid = ($server | get -o uuid | default "")
|
||||
if ($uuid | is-empty) { return "" }
|
||||
(upcloud_api_server_uuid_ip $uuid "public" "IPv4")
|
||||
}
|
||||
export def upcloud_api_test [
|
||||
]: nothing -> string {
|
||||
let hostname = "dev-wrkr"
|
||||
|
||||
# let result = (upcloud_api_request "get" "account")
|
||||
# if ($result | is-not-empty) and ($result | get -o account | get -o credits | default "" | is-not-empty) {
|
||||
# _print $"Account '($result | get -o account | get -o username | default "")' credit: ($result | get -o account | get -o credits)"
|
||||
# }
|
||||
|
||||
let server_info = (upcloud_api_server_info $hostname)
|
||||
if ($server_info | is-not-empty) {
|
||||
_print $"🛑 Error (_ansi purple)UpCloud(_ansi reset) create (_ansi red)($hostname)(_ansi reset)"
|
||||
_print $"Server (_ansi green)($hostname)(_ansi reset) ($server_info | get -o uuid | default "") => ($server_info | get -o state | default "")"
|
||||
} else {
|
||||
_print $"Server (_ansi green)($hostname)(_ansi reset) creation ..."
|
||||
let server_data = (upcloud_api_new_server {})
|
||||
let result = (upcloud_api_request "post" "server" { server: $server_data} )
|
||||
if ($result | is-not-empty) {
|
||||
let pub_ip = (upcloud_api_server_ip $result "public" "IPv4")
|
||||
if ($pub_ip | is-not-empty) {
|
||||
_print $"ssh -i $HOME/.ssh/id_cdci -l root ($pub_ip)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#let pub_ip = (upcloud_get_info $hostname "public" "IPv4")
|
||||
|
||||
_print $"Server (_ansi green)($hostname)(_ansi reset) state: (upcloud_api_server_state $hostname "")"
|
||||
|
||||
let servers_list = (upcloud_api_list_servers "main")
|
||||
_print ($servers_list | table -i false -e)
|
||||
let server = (upcloud_api_server_info $hostname)
|
||||
if ($server | is-empty) { exit }
|
||||
# _print ($server | table -e)
|
||||
let uuid = ($server | get -o uuid | default "")
|
||||
if ($uuid | is-empty) { exit }
|
||||
let pub_ip = (upcloud_api_server_uuid_ip $uuid "public" "IPv4")
|
||||
if ($pub_ip | is-not-empty) {
|
||||
_print $"ssh -i $HOME/.ssh/id_cdci -l root ($pub_ip)"
|
||||
}
|
||||
|
||||
let server_state = (upcloud_api_server_state $hostname "")
|
||||
if $server_state == "maintenance" or $server_state == "error" {
|
||||
_print $"🛑 Server (_ansi green)($hostname)(_ansi reset) in (_ansi red)($server_state)(_ansi reset) !!! "
|
||||
exit 1
|
||||
}
|
||||
if $server_state == "started" {
|
||||
let wait = 20
|
||||
let max_wait = 240
|
||||
mut wait_time = 0
|
||||
_print $"Server (_ansi green)($hostname)(_ansi reset) state: (_ansi yellow)($server_state)(_ansi reset)"
|
||||
_print $"Server (_ansi green)($hostname | default "")(_ansi reset) ($uuid) to (_ansi yellow)stop(_ansi reset) state ... try every ($wait)sec until ($max_wait)sec"
|
||||
_print -n $"(_ansi blue_bold) 🌥 (_ansi reset)"
|
||||
(upcloud_api_server_new_state "stop" $uuid 30)
|
||||
while true {
|
||||
if (upcloud_api_server_state $hostname "") == "stopped" { break }
|
||||
$wait_time = ($wait_time + $wait)
|
||||
if ($wait_time > $max_wait) {
|
||||
_print $"🛑 Server (_ansi green)($hostname)(_ansi reset) state (_ansi red)stop(_ansi reset) not found in ($max_wait)secs !!! "
|
||||
exit 1
|
||||
}
|
||||
print -n $"(_ansi blue_bold) 🌥 (_ansi reset) [($wait_time)]"
|
||||
sleep ($"($wait)sec"| into duration)
|
||||
}
|
||||
_print ""
|
||||
}
|
||||
let result = (upcloud_api_server_delete "" $uuid)
|
||||
if $result == "OK" {
|
||||
_print $"Server (_ansi green)($hostname)(_ansi reset) DELETED "
|
||||
_print (upcloud_api_server_info $hostname)
|
||||
}
|
||||
}
|
||||
93
providers/upcloud/nulib/upcloud/cache.nu
Normal file
93
providers/upcloud/nulib/upcloud/cache.nu
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
#!/usr/bin/env nu
|
||||
# Info: UpCloud
|
||||
|
||||
use std
|
||||
|
||||
export def upcloud_start_cache_info [
|
||||
settings: record
|
||||
server: record
|
||||
] {
|
||||
$""
|
||||
}
|
||||
export def upcloud_create_cache [
|
||||
settings: record
|
||||
server: record
|
||||
error_exit: bool
|
||||
] {
|
||||
if $settings == null {
|
||||
print $"❗ No settings found "
|
||||
return
|
||||
}
|
||||
let provider_path = (get_provider_data_path $settings $server)
|
||||
#use lib_provisioning/utils/settings.nu load_provider_env
|
||||
let data = (load_provider_env $settings $server $provider_path)
|
||||
if ($data | is-not-empty) or ($data | get -o main) != "?" {
|
||||
if $env.PROVISIONING_DEBUG {
|
||||
print $"UpCloud main data already exists in ($provider_path | path basename)"
|
||||
}
|
||||
}
|
||||
let result = (^upctl "server" "show" $server.hostname -o "json" err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" })| complete)
|
||||
let info_server = if $result.exit_code == 0 {
|
||||
($result.stdout | from json)
|
||||
} else { {} }
|
||||
let all_servers = if ($data.servers? == null) {
|
||||
{}
|
||||
} else if ($info_server | is-empty) {
|
||||
$data.servers
|
||||
} else {
|
||||
$data.servers | default {} | append $info_server
|
||||
}
|
||||
let new_data = ( $data | merge { servers: $all_servers})
|
||||
save_provider_env $new_data $settings $provider_path
|
||||
if $env.PROVISIONING_DEBUG { print $"Cache for ($server.provider) on ($server.hostname) saved in: ($provider_path | path basename)" }
|
||||
}
|
||||
export def upcloud_read_cache [
|
||||
settings: record
|
||||
server: record
|
||||
error_exit: bool
|
||||
] {
|
||||
if $settings == null {
|
||||
print $"❗ No settings found "
|
||||
return
|
||||
}
|
||||
}
|
||||
export def upcloud_clean_cache [
|
||||
settings: record
|
||||
server: record
|
||||
error_exit: bool
|
||||
] {
|
||||
if $settings == null {
|
||||
print $"❗ No settings found "
|
||||
return
|
||||
}
|
||||
let provider_path = (get_provider_data_path $settings $server)
|
||||
let data = (load_provider_env $settings $server $provider_path)
|
||||
if ($data.servers? == null) { return {} }
|
||||
if ($data.servers | where {|it| ($it.hostname? | default "") == $server.hostname} | length) == 0 {
|
||||
if $env.PROVISIONING_DEBUG {
|
||||
print $"❗server ($server.hostname) already deleted from ($provider_path | path basename)"
|
||||
}
|
||||
return
|
||||
}
|
||||
let all_servers = ( $data.servers? | default [] | where {|it| ($it.hostname? | is-not-empty) and ($it.hostname? | default "") != $server.hostname})
|
||||
if $env.PROVISIONING_DEBUG { print $"Cache for ($server.provider) delete ($server.hostname) in: ($provider_path | path basename)" }
|
||||
let new_data = if ($all_servers | length) == 0 {
|
||||
( $data | merge { servers: []})
|
||||
} else {
|
||||
( $data | merge { servers: $all_servers})
|
||||
}
|
||||
save_provider_env $new_data $settings $provider_path
|
||||
}
|
||||
export def upcloud_ip_from_cache [
|
||||
settings: record
|
||||
server: record
|
||||
error_exit: bool
|
||||
] {
|
||||
let data = ($settings.providers | find $server.provider | get -o settings | get -o servers | flatten
|
||||
| find $server.hostname | select -o ip_addresses)
|
||||
mut pub_ip = ""
|
||||
for it in $data {
|
||||
$pub_ip = ($it | get -o ip_addresses | find "public" | get -o address | get -o 0)
|
||||
}
|
||||
$pub_ip
|
||||
}
|
||||
6
providers/upcloud/nulib/upcloud/env.nu
Normal file
6
providers/upcloud/nulib/upcloud/env.nu
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
export-env {
|
||||
$env.UPCLOUD_API_URL = ($env | get -o UPCLOUD_API_URL | default "https://api.upcloud.com/1.3")
|
||||
$env.UPCLOUD_AUTH = ($env | get -o UPCLOUD_AUTH | default "")
|
||||
$env.UPCLOUD_INTERFACE = ($env | get -o UPCLOUD_INTERFACE | default "CLI") # API or CLI
|
||||
#$env.UPCLOUD_INTERFACE = ($env | get -o UPCLOUD_INTERFACE | default "API") # API or CLI
|
||||
}
|
||||
13
providers/upcloud/nulib/upcloud/list_nu_curl_defs.txt
Normal file
13
providers/upcloud/nulib/upcloud/list_nu_curl_defs.txt
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
upcloud_api_auth
|
||||
upcloud_api_url
|
||||
upcloud_api_request
|
||||
upcloud_api_new_server
|
||||
upcloud_api_list_servers
|
||||
upcloud_api_server_info
|
||||
upcloud_api_server_uuid
|
||||
upcloud_api_server_ip
|
||||
upcloud_api_server_uuid_ip
|
||||
upcloud_api_server_new_state
|
||||
upcloud_api_server_state
|
||||
upcloud_api_server_delete
|
||||
upcloud_api_get_info
|
||||
6
providers/upcloud/nulib/upcloud/mod.nu
Normal file
6
providers/upcloud/nulib/upcloud/mod.nu
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
use env.nu
|
||||
export use servers.nu *
|
||||
export use cache.nu *
|
||||
export use usage.nu *
|
||||
export use utils.nu *
|
||||
export use prices.nu *
|
||||
304
providers/upcloud/nulib/upcloud/prices.nu
Normal file
304
providers/upcloud/nulib/upcloud/prices.nu
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
export def upcloud_sel_data_table [
|
||||
data: any
|
||||
id: string
|
||||
] {
|
||||
($data | where {|it| $it.id == $id } | get -o table | get -o 0)
|
||||
}
|
||||
|
||||
export def upcloud_get_plan_prefix [
|
||||
id: string
|
||||
] {
|
||||
match $id {
|
||||
"general-purpose" | "general" => "",
|
||||
"developer-plans" | "dev" => "DEV-",
|
||||
"high-cpu-plans" | "high-cpu" | "cpu" => "HICPU-",
|
||||
"high-memory-plans" | "high-memory" | "memory" | "ram" => "HIMEM-",
|
||||
_ => "",
|
||||
}
|
||||
}
|
||||
export def upcloud_get_id_from_plan [
|
||||
plan: string
|
||||
] {
|
||||
if ($plan | str starts-with "HICPU-") {
|
||||
"high-cpu-plans"
|
||||
} else if ($plan | str starts-with "HIMEM-") {
|
||||
"high-memory-plans"
|
||||
} else if ($plan | str starts-with "DEV-") {
|
||||
"developer-plans"
|
||||
} else {
|
||||
"general-purpose"
|
||||
}
|
||||
}
|
||||
export def upcloud_sel_table_item [
|
||||
data: list
|
||||
key: string
|
||||
condition: string
|
||||
value: string
|
||||
] {
|
||||
($data | where {|it|
|
||||
let item_data = match $key {
|
||||
"memory" | "ram" => ($it | get $key | get 0 | str replace "GB" "" | str trim),
|
||||
_ => ($it | get $key | get 0 ),
|
||||
}
|
||||
(match $condition {
|
||||
"lt" | "<" => (($item_data | into int ) < ($value | str replace "GB" "" | into int)),
|
||||
"lte" | "<=" => (($item_data | into int ) <= ($value | str replace "GB" "" | into int)),
|
||||
_ => false
|
||||
})
|
||||
}| flatten)
|
||||
}
|
||||
export def upcloud_get_price [
|
||||
all_data: record
|
||||
key: string
|
||||
price_col: string = "global_price"
|
||||
] {
|
||||
let data = ($all_data | get -o item)
|
||||
let str_price_col = if ($price_col | is-empty) { "global_price" } else { $price_col }
|
||||
match ($all_data | get -o target) {
|
||||
"server" => {
|
||||
let table_key = if $key == "unit" { "hour" } else { $key }
|
||||
let value = ($data | get -o $str_price_col | flatten | get -o $table_key | default "" | str replace -a "€" "" )
|
||||
if $key == "unit" {
|
||||
$"($value | get -o 0) Hrs"
|
||||
} else if ($value | is-not-empty) {
|
||||
($value | get -o 0 | into float)
|
||||
} else {
|
||||
0
|
||||
}
|
||||
},
|
||||
"storage" => {
|
||||
# Index 0 should be part of the server PLAN
|
||||
let it = ($all_data | get -o src )
|
||||
if ($it | is-empty) or ($it | get -o item | is-empty) { return 0 }
|
||||
if ($it.index) == 0 { return 0 }
|
||||
let storage = $it.item
|
||||
let storage_type = match ($storage | get -o voltype) {
|
||||
"maxiops" => "MaxIOPS",
|
||||
"hdd" => "HDD",
|
||||
"custom" => "Custom image",
|
||||
}
|
||||
let month = ($data | find $storage_type | select $str_price_col | flatten | into record | get -o month | default "" | str replace -a "€" "" | into float)
|
||||
let hour = ($data | find $storage_type | select $str_price_col | flatten | into record | get -o hour | default "" | str replace -a "€" "" | into float)
|
||||
match $key {
|
||||
"unit" =>
|
||||
$"($data | find $storage_type | select $str_price_col | flatten | into record | get -o month | default "" | str replace -a "€" "") GB-Mo",
|
||||
"month" =>
|
||||
($data | find $storage_type | select $str_price_col | flatten | into record | get -o month | default "" | str replace -a "€" "" | into float),
|
||||
"day" =>
|
||||
(($data | find $storage_type | select $str_price_col | flatten | into record | get -o hour | default "" | str replace -a "€" "" | into float) * 24),
|
||||
"hour" =>
|
||||
($data | find $storage_type | select $str_price_col | flatten | into record | get -o hour | default "" | str replace -a "€" "" | into float),
|
||||
_ => 0,
|
||||
}
|
||||
},
|
||||
"networking" => {
|
||||
0
|
||||
},
|
||||
"backups" => {
|
||||
0
|
||||
},
|
||||
_ => {
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
export def upcloud_get_item_for_storage [
|
||||
server: record
|
||||
settings: record
|
||||
cloud_data: record
|
||||
] {
|
||||
let data = ($cloud_data | get -o $server.provider| get -o "block_storage")
|
||||
if ($data | is-empty) { return {} }
|
||||
($data | get -o table | get -o 0)
|
||||
}
|
||||
export def upcloud_get_item_for_server [
|
||||
server: record
|
||||
settings: record
|
||||
cloud_data: record
|
||||
] {
|
||||
let data = ($cloud_data | get -o $server.provider | get -o "servers")
|
||||
if ($data | is-empty) { return {} }
|
||||
let plan = ($server | get -o plan | default "")
|
||||
let key_id = (upcloud_get_id_from_plan $plan)
|
||||
let cloud_table_data = (upcloud_sel_data_table $data $key_id)
|
||||
if ($cloud_table_data | is-empty) { return {} }
|
||||
($cloud_table_data | where {|it|
|
||||
($it | get -o plan ) == $plan
|
||||
} | get -o 0)
|
||||
}
|
||||
export def upcloud_clean_table [
|
||||
id: string
|
||||
data: string
|
||||
target: string
|
||||
] {
|
||||
let table = ( $data | split row "<tr>" | where {|it| $it | str starts-with "<" } |
|
||||
each {|it| $it | str replace -a -r "<(\/td|sup|\/sup|small|\/small|b|\/b|br|\/tr|tbody|\/tbody|\/thead|\/th)>" "" }
|
||||
)
|
||||
let table_cols = if ($table | get 0 | str contains "<th>") {
|
||||
($table | get 0 | split row "<th>")
|
||||
} else {
|
||||
($table | get 0 | split row "<td>")
|
||||
}
|
||||
let cols = ($table_cols | where {|it| $it != "" } | str replace " *" " " |
|
||||
str trim | str downcase | str replace " " "_" | str replace 'price*' 'price')
|
||||
let plan_prefix = (upcloud_get_plan_prefix $id)
|
||||
let res = ( $table | drop nth 0 | each {|line| $line | split column "<td>" -c ...$cols } |
|
||||
each {|it|
|
||||
#if $target == "networking" => { print $it }
|
||||
match $target {
|
||||
"block-storage" => {
|
||||
$it |
|
||||
update storage_type $"($it | get -o 'storage_type' | get -o 0 )" |
|
||||
update global_price ($it| get -o global_price | get -o 0 | parse --regex "(?<month>.*?)/mo (?<hour>.*?)/h" | get -o 0) |
|
||||
update helsinki_price ($it| get -o helsinki_price | get -o 0 | parse --regex "(?<month>.*?)/mo (?<hour>.*?)/h" | get -o 0)
|
||||
},
|
||||
"object-storage" => {
|
||||
$it |
|
||||
update price ($it| get -o price | get -o 0 | parse --regex "(?<month>.*?)/mo (?<hour>.*?)/h" | get -o 0) |
|
||||
},
|
||||
"cloud-servers" | "servers" => {
|
||||
let helsinki_price = ($it| get -o helsinki_price | get -o 0 | default "")
|
||||
if ($helsinki_price | is-not-empty) {
|
||||
$it | insert plan $"($plan_prefix)($it | get -o 'cpu_cores' | get -o 0 )xCPU-($it | get -o 'memory' | get -o 0 | str replace ' ' '')" |
|
||||
update global_price ($it| get -o global_price | get -o 0 | default "" | parse --regex "(?<month>.*?)/mo (?<hour>.*?)/h" | get -o 0) |
|
||||
update helsinki_price ($it| get -o helsinki_price | get -o 0 | default "" | parse --regex "(?<month>.*?)/mo (?<hour>.*?)/h" | get -o 0)
|
||||
} else {
|
||||
$it | insert plan $"($plan_prefix)($it | get -o 'cpu_cores' | get -o 0 )xCPU-($it | get -o 'memory' | get -o 0 | str replace ' ' '')" |
|
||||
update global_price ($it| get -o global_price | get -o 0 | default "" | parse --regex "(?<month>.*?)/mo (?<hour>.*?)/h" | get -o 0) |
|
||||
}
|
||||
},
|
||||
"simple-backups" => {
|
||||
$it | update global_price ($it| get -o global_price | get -o 0 | parse --regex "(?<month>.*?)/mo (?<hour>.*?)/h" | get -o 0) |
|
||||
update helsinki_price ($it| get -o helsinki_price | get -o 0 | parse --regex "(?<month>.*?)/mo (?<hour>.*?)/h" | get -o 0)
|
||||
},
|
||||
"networking" => {
|
||||
$it | update price ($it| get -o price | get -o 0 | str replace "Price" "---" | str replace " " " " |
|
||||
parse --regex "(?<month>.*?)/mo (?<hour>.*?)/h|(?<price>.*)" | get -o 0)
|
||||
},
|
||||
_ => { $it },
|
||||
}
|
||||
})
|
||||
($res | flatten)
|
||||
}
|
||||
export def upcloud_get_provider_path [
|
||||
settings: record
|
||||
server: record
|
||||
] {
|
||||
let data_path = if ($settings.data.prov_data_dirpath | str starts-with "." ) {
|
||||
($settings.src_path | path join $settings.data.prov_data_dirpath)
|
||||
} else { $settings.data.prov_data_dirpath }
|
||||
if not ($data_path | path exists) { mkdir $data_path }
|
||||
($data_path | path join $"($server.provider)_prices.($env.PROVISIONING_WK_FORMAT)")
|
||||
}
|
||||
export def upcloud_load_infra_storages_info [
|
||||
settings: record
|
||||
server: record
|
||||
error_exit: bool
|
||||
] {
|
||||
let data = (upcloud_load_infra_servers_info $settings $server $error_exit)
|
||||
let res = ($data | get -o "block-storage")
|
||||
print ($res | table -e)
|
||||
$res
|
||||
}
|
||||
export def upcloud_load_infra_servers_info [
|
||||
settings: record
|
||||
server: record
|
||||
error_exit: bool
|
||||
]: nothing -> record {
|
||||
let provider_prices_path = (upcloud_get_provider_path $settings $server)
|
||||
let data = if ($provider_prices_path | path exists) {
|
||||
open $provider_prices_path
|
||||
} else {
|
||||
let url = "https://upcloud.com/pricing"
|
||||
let pricing_html_path = ($env.PROVISIONING_PROVIDERS_PATH | path join "upcloud" | path join "pricing.html")
|
||||
{ servers: (upcloud_load_infra $url $pricing_html_path "cloud-servers"),
|
||||
block_storage: (upcloud_load_infra $url $pricing_html_path "block-storage"),
|
||||
object_storage: (upcloud_load_infra $url $pricing_html_path "object-storage"),
|
||||
backups: (upcloud_load_infra $url $pricing_html_path "simple-backups"),
|
||||
networking: (upcloud_load_infra $url $pricing_html_path "networking"),
|
||||
}
|
||||
}
|
||||
if ($provider_prices_path | path exists) { return $data }
|
||||
if $env.PROVISIONING_WK_FORMAT == "json" {
|
||||
$data | to json | save -f $provider_prices_path
|
||||
} else {
|
||||
$data | to yaml | save -f $provider_prices_path
|
||||
}
|
||||
if $env.PROVISIONING_DEBUG { print $"Price for ($server.provider) in: ($provider_prices_path | path basename)" }
|
||||
$data
|
||||
}
|
||||
export def upcloud_load_infra [
|
||||
url: string
|
||||
html_path: string
|
||||
target: string = "servers"
|
||||
]: nothing -> list {
|
||||
let id_target = match $target {
|
||||
"object" | "object-storage" | "os" => "object-storage",
|
||||
"block" | "block-storage" | "bs" => "block-storage",
|
||||
"server" | "servers" | "s" => "cloud-servers",
|
||||
"backup" | "simple-backups" | "s" => "simple-backups",
|
||||
"network" | "networking" | "s" => "networking",
|
||||
_ => "cloud-servers",
|
||||
}
|
||||
# cookie error if use curl o http get
|
||||
let html_content = if ($html_path | path exists) {
|
||||
open -r $html_path
|
||||
} else {
|
||||
#let res = (http get $url -r )
|
||||
let res = (^curl -s $url | complete)
|
||||
if ($res.exit_code != 0) {
|
||||
print $"🛑 Error (_ansi red)($url)(_ansi reset):\n ($res.exit_code) ($res.stderr)"
|
||||
return ""
|
||||
} else { $res.stdout }
|
||||
}
|
||||
($html_content | split row "<section "| find $'id="($id_target)"' | split row role="tabpanel" | find "<table" | each {|it|
|
||||
let id = ($it | parse --regex 'id="(?<id>.*?)"' | get id | get -o 0 | str replace -r "-tab$" "")
|
||||
let title = ($it | parse --regex '<h3>(?<title>.*?)<\/h3>' | get title | get -o 0)
|
||||
let info = ($it | parse --regex '<\/h3><p>(?<info>.*?)<\/p>' | get info | get -o 0)
|
||||
let table = ($it | parse --regex '<table\s*(?<table>.*?)<\/table>' | get table | get -o 0)
|
||||
{ id: $id, table: (upcloud_clean_table $id $table $id_target), title: $title, info: $info }
|
||||
})
|
||||
# mut $group_data = {}
|
||||
# for item in $data {
|
||||
# print $item
|
||||
# let group = ($item | get -o id)
|
||||
# let table = ($item | get -o table)
|
||||
# print $group
|
||||
# print ($table | flatten | table -e)
|
||||
# if ($group | is-empty) { continue }
|
||||
# # if ($group_data | get -o $group | is-empty) {
|
||||
# # $group_data = ($group_data | merge { $group: [($item | reject id)]})
|
||||
# # } else {
|
||||
# # $group_data = ($group_data | merge { $group: ($group_data | get -o $group | append ($item | reject id))})
|
||||
# # }
|
||||
# }
|
||||
# exit
|
||||
# $group_data
|
||||
# each { |it| $it | parse --regex 'id="(?<id>.*?)"(?<other>.*)<h3>(?<title>.*)<\/h3><p>(?<info>.*)</p>(?.*)<table\s*(?<table>.*)<\/table>' }
|
||||
# where {|it| $it | str starts-with "<" } |
|
||||
#print ($cloud_servers | each {|it| select id table} | flatten | each {|it|
|
||||
#let res = ($cloud_servers | each {|it| select id table} | flatten | each {|it|
|
||||
# let id = ($it.id | str replace -r "-tab$" "")
|
||||
# { id: $id, table: (upcloud_clean_table $id $it.table) }
|
||||
# }
|
||||
#)
|
||||
}
|
||||
export def upcloud_test_infra_servers [
|
||||
] {
|
||||
let data_infra_servers = (upcloud_load_infra_servers "https://upcloud.com/pricing")
|
||||
let key_id = ($data_infra_servers | get id | input list "Select server group ")
|
||||
let cloud_data = (upcloud_sel_data_table $data_infra_servers $key_id)
|
||||
let mem_limit = (["4 GB" "8 GB" "16 GB" "32 GB" "64 GB" "96 GB" "128 GB" "256 GB" "512 GB" ] | input list "Select MEMORY limit ")
|
||||
|
||||
let items = (upcloud_sel_table_item $cloud_data "memory" "lte" $mem_limit)
|
||||
print ($items | table -e)
|
||||
#let line = ($cloud_servers | get 0 | get table | get 1 )
|
||||
print $"From ($key_id) with ($mem_limit)\n"
|
||||
print $"memory | cores | month | hour | plan "
|
||||
print "============================================="
|
||||
for line in $items {
|
||||
print ($"($line | get memory) \t| ($line | get cpu_cores) \t| (upcloud_get_price $line 'month')" +
|
||||
$" \t| (upcloud_get_price $line 'hour') | ($line | get plan) "
|
||||
)
|
||||
}
|
||||
}
|
||||
829
providers/upcloud/nulib/upcloud/servers.nu
Normal file
829
providers/upcloud/nulib/upcloud/servers.nu
Normal file
|
|
@ -0,0 +1,829 @@
|
|||
#!/usr/bin/env nu
|
||||
# Info: UpCloud
|
||||
# servers.nu
|
||||
|
||||
use std
|
||||
use api.nu *
|
||||
|
||||
export def upcloud_interface [
|
||||
]: nothing -> string {
|
||||
($env | get -o UPCLOUD_INTERFACE | default "CLI") # API or CLI
|
||||
}
|
||||
export def upcloud_use_api [
|
||||
]: nothing -> bool {
|
||||
(upcloud_interface) == "API"
|
||||
}
|
||||
export def upcloud_query_servers [
|
||||
find: string
|
||||
cols: string
|
||||
]: nothing -> list {
|
||||
if upcloud_use_api {
|
||||
upcloud_api_list_servers
|
||||
} else {
|
||||
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 "🛑 upctl server list " $"($res.exit_code) ($res.stdout)" "upcloud query server" --span (metadata $res).span)
|
||||
} else {
|
||||
print $"🛑 Error upctl server list: ($res.exit_code) ($res.stdout | ^grep 'error')"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export def upcloud_server_info [
|
||||
server: record
|
||||
check: bool
|
||||
]: nothing -> record {
|
||||
let hostname = $server.hostname
|
||||
if (upcloud_use_api) {
|
||||
upcloud_api_server_info $hostname
|
||||
} else {
|
||||
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 "🛑 upctl server show" $"($res.exit_code) ($res.stdout)" $"upcloud server info ($hostname)" --span (metadata $res).span)
|
||||
} else {
|
||||
print $"🛑 upctl server show ($hostname):($res.stdout | ^grep 'error')"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export def upcloud_on_prov_server [
|
||||
server?: record
|
||||
] {
|
||||
#let info = if ( $env.CURRENT_FILE? | into string ) != "" { (^grep "^# Info:" $env.CURRENT_FILE ) | str replace "# Info: " "" } else { "" }
|
||||
#$"From (_ansi purple_bold)UpCloud(_ansi reset)"
|
||||
}
|
||||
# infrastructure and services
|
||||
export def upcloud [
|
||||
args: list<string> # Args for create command
|
||||
--server(-s): record
|
||||
--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
|
||||
]: nothing -> any {
|
||||
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 upcloud help"
|
||||
if not $env.PROVISIONING_DEBUG { end_run "" }
|
||||
exit
|
||||
},
|
||||
_ => {
|
||||
if ($args | find "help" | length) > 0 {
|
||||
match $task {
|
||||
"server" => {
|
||||
print "SERVER "
|
||||
upcloud_server ($args | drop nth ..0)
|
||||
},
|
||||
"inventory" => {
|
||||
upcloud_server ($args | drop nth ..0)
|
||||
},
|
||||
"ssh" => {
|
||||
upcloud_server ($args | drop nth ..0)
|
||||
},
|
||||
"delete" => {
|
||||
upcloud_server ($args | drop nth ..0)
|
||||
# ($args | drop nth ..1) --server $server
|
||||
},
|
||||
_ => {
|
||||
option_undefined "upcloud" ""
|
||||
print "TODO upcloud 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" => {
|
||||
upcloud_get_ip $curr_settings $server ($cmd_args | get -o 0 | default "")
|
||||
},
|
||||
"server" => {
|
||||
print (
|
||||
upcloud_server $cmd_args --server $server --settings $curr_settings --error_exit
|
||||
)
|
||||
},
|
||||
"inventory" => {
|
||||
},
|
||||
"ssh" => {
|
||||
},
|
||||
"delete" => {
|
||||
# ($args | drop nth ..1) --server $server
|
||||
},
|
||||
_ => {
|
||||
option_undefined "upcloud" ""
|
||||
if not $env.PROVISIONING_DEBUG { end_run "" }
|
||||
exit
|
||||
}
|
||||
}
|
||||
}
|
||||
export def upcloud_get_ip [
|
||||
settings: record
|
||||
server: record
|
||||
ip_type?: string = "public"
|
||||
family?: string = "IPv4"
|
||||
]: nothing -> string {
|
||||
match $ip_type {
|
||||
"private" | "prv" | "priv" => {
|
||||
$"($server.network_private_ip)"
|
||||
},
|
||||
_ => {
|
||||
if (upcloud_use_api) {
|
||||
let server = (upcloud_api_server_info $server.hostname)
|
||||
if ($server | is-empty) { return "" }
|
||||
let uuid = ($server | get -o uuid | default "")
|
||||
if ($uuid | is-empty) { return "" }
|
||||
(upcloud_api_server_uuid_ip $uuid $ip_type $family)
|
||||
} else {
|
||||
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?
|
||||
$"(($ip_addresses | get -o 0).address? | get -o 0 | default '')"
|
||||
} else { "" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
# To create infrastructure and services
|
||||
export def upcloud_server [
|
||||
args: list<string> # Args for create command
|
||||
--server: record
|
||||
--error_exit
|
||||
--status
|
||||
--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
|
||||
]: nothing -> nothing {
|
||||
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 upcloud server help"
|
||||
if not $env.PROVISIONING_DEBUG { end_run "" }
|
||||
exit
|
||||
},
|
||||
_ => {
|
||||
if $target == "" or ($args | find "help" | length) > 0 {
|
||||
match $task {
|
||||
"server" => {
|
||||
upcloud_server $cmd_args
|
||||
},
|
||||
"status" => {
|
||||
print $server
|
||||
print $error_exit
|
||||
}
|
||||
"inventory" => {
|
||||
print "TODO upcloud server inventory help"
|
||||
},
|
||||
"ssh" => {
|
||||
print "TODO upcloud server ssh help"
|
||||
},
|
||||
"delete" => {
|
||||
# ($args | drop nth ..1) --server $server
|
||||
#upcloud_delete_server $cmd_args true
|
||||
},
|
||||
_ => {
|
||||
option_undefined "upcloud" "server"
|
||||
print "TODO upcloud 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 "🛑 upcloud server" $text "" --span (metadata $server_target).span)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
if $status or $task == "status" {
|
||||
print "upcloud server status "
|
||||
return true
|
||||
}
|
||||
match $task {
|
||||
"get_ip" => {
|
||||
upcloud_get_ip $settings $server_target ($cmd_args | get -o 0 | default "")
|
||||
},
|
||||
"stop" => {
|
||||
print "TODO upcloud server stop"
|
||||
},
|
||||
"start" => {
|
||||
print "TODO upcloud server start"
|
||||
},
|
||||
"restart" => {
|
||||
print "TODO upcloud server restart"
|
||||
},
|
||||
_ => {
|
||||
option_undefined "upcloud" "server"
|
||||
if not $env.PROVISIONING_DEBUG { end_run "" }
|
||||
exit
|
||||
}
|
||||
}
|
||||
}
|
||||
export def upcloud_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 ""
|
||||
}
|
||||
|
||||
let private_net_id = if (upcloud_use_api) {
|
||||
# TODO make it via API
|
||||
""
|
||||
} else {
|
||||
# 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)
|
||||
if $result.exit_code == 0 {
|
||||
let data = ($result.stdout | from json | get -o networks | find $priv_cidr_block | get -o 0 | get -o uuid | default "" | str trim)
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
if $check and ($private_net_id | is-empty) {
|
||||
print $"❗private_network will be register in a real creation request not in check state"
|
||||
return ""
|
||||
} else {
|
||||
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 uuid | default "")
|
||||
} else { "" }
|
||||
if ($new_net_id | is-empty) {
|
||||
(throw-error $"🛑 no private network '($network_private_name)' created"
|
||||
$"for server ($server.hostname) ip ($server.network_private_ip)\n($result.stdout)"
|
||||
$"upcloud_create_private_network" --span (metadata $new_net_id).span)
|
||||
exit
|
||||
}
|
||||
# Save changes ...
|
||||
#use utils/settings.nu [ save_servers_settings save_settings_file ]
|
||||
let match_text = " network_private_id = "
|
||||
let default_provider_path = ($settings.data | get -o servers_paths | get -o 0 | default "" | path dirname | path join $"($server.provider)_defaults.k")
|
||||
let old_text = 'network_private_id = "CREATE"'
|
||||
let new_text = $'network_private_id = "($new_net_id)"'
|
||||
save_settings_file $settings $default_provider_path $old_text $new_text
|
||||
return $new_net_id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
export def upcloud_check_server_requirements [
|
||||
settings: record
|
||||
server: record
|
||||
check: bool
|
||||
] {
|
||||
if $server.provider == "upcloud" {
|
||||
if (^upctl account show "-o" "json" err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete).exit_code != 0 and $check {
|
||||
(throw-error $"🛑 no account found"
|
||||
$"for server ($server.hostname)"
|
||||
"upcloud_check_server_requirements" --span (metadata $server.provider).span)
|
||||
exit
|
||||
}
|
||||
let private_net_id = if ($server.network_private_id? | default "") == "CREATE" {
|
||||
print $"❗($server.network_private_id?) found for (_ansi yellow)network_private_id(_ansi reset) will be created for ($server.priv_cidr_block | default '')"
|
||||
(upcloud_create_private_network $settings $server $check)
|
||||
} else {
|
||||
($server.network_private_id? | default "" )
|
||||
}
|
||||
if ($private_net_id | is-empty) and $check {
|
||||
return true
|
||||
}
|
||||
let result = (^upctl network show $private_net_id -o json | complete)
|
||||
let privavet_net_id = if (not $check) and $result.exit_code != 0 {
|
||||
let net_id = (upcloud_create_private_network $settings $server $check)
|
||||
let res = (^upctl "network" "show" $private_net_id "-o" "json" | complete)
|
||||
if $res.exit_code != 0 {
|
||||
print $"❗Error: no ($private_net_id) found "
|
||||
" "
|
||||
} else {
|
||||
let data = ($result.stdout | from json )
|
||||
($data.networks | get -o 0 | get -o uuid)
|
||||
}
|
||||
} else if $result.exit_code == 0 {
|
||||
let data = ($result.stdout | from json)
|
||||
($data.uuid)
|
||||
} else {
|
||||
""
|
||||
}
|
||||
let server_private_ip = ($server.network_private_ip? | default "")
|
||||
if $private_net_id == "" and $server_private_ip != "" {
|
||||
(throw-error $"🛑 no private network ($private_net_id) found"
|
||||
$"for server ($server.hostname) ip ($server_private_ip)"
|
||||
"upcloud_check_requirements" --span (metadata $server_private_ip).span)
|
||||
exit
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
export def upcloud_make_settings [
|
||||
settings: record
|
||||
server: record
|
||||
] {
|
||||
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 ""
|
||||
if $uuid == "" {
|
||||
return false
|
||||
}
|
||||
let ip_pub = (upcloud_get_ip $settings $server "public")
|
||||
let ip_priv = (upcloud_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 {
|
||||
{
|
||||
servers: [ $server_settings ]
|
||||
}
|
||||
}
|
||||
$new_data | to yaml | save --force $out_settings_path
|
||||
print $"✅ upcloud settings ($task) -> ($out_settings_path)"
|
||||
true
|
||||
}
|
||||
export def upcloud_delete_settings [
|
||||
settings: record
|
||||
server: record
|
||||
] {
|
||||
}
|
||||
export def upcloud_post_create_server [
|
||||
settings: record
|
||||
server: record
|
||||
check: bool
|
||||
] {
|
||||
mut req_storage = ""
|
||||
for storage in ($server | get -o storages | enumerate) {
|
||||
let res = (upcloud_storage_fix_size $settings $server $storage.index)
|
||||
if ($req_storage | is-empty) and ($res | is-not-empty) {
|
||||
$req_storage = $res
|
||||
}
|
||||
}
|
||||
$req_storage
|
||||
}
|
||||
export def upcloud_modify_server [
|
||||
settings: record
|
||||
server: record
|
||||
new_values: list
|
||||
error_exit: bool
|
||||
] {
|
||||
mut args = ""
|
||||
for item in $new_values {
|
||||
if ($item | get -o plan | is-not-empty) { $args = $args + $" --plan ($item.plan)" }
|
||||
}
|
||||
if ($args | is-empty) { return }
|
||||
print $"Stop (_ansi blue_bold)($server.hostname)(_ansi reset) to modify (_ansi yellow_bold)($args)(_ansi reset)"
|
||||
if (upcloud_change_server_state $settings $server "stop" "") == false {
|
||||
print $"❗ Stop ($server.hostname) errors "
|
||||
if $error_exit {
|
||||
exit 1
|
||||
} else {
|
||||
return "error"
|
||||
}
|
||||
}
|
||||
let res = (^upctl ...($"server modify ($server.hostname) ($args | str trim)" | split row " ") err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete)
|
||||
if $res.exit_code != 0 {
|
||||
print $"❗ Server ($server.hostname) modify ($args) errors ($res.stdout ) "
|
||||
}
|
||||
print $"Start (_ansi blue_bold)($server.hostname)(_ansi reset) with modifications (_ansi green_bold)($args)(_ansi reset) ... "
|
||||
if (upcloud_change_server_state $settings $server "start" "") == false {
|
||||
print $"❗ Errors to start ($server.hostname)"
|
||||
if $error_exit {
|
||||
exit 1
|
||||
} else {
|
||||
return "error"
|
||||
}
|
||||
}
|
||||
}
|
||||
export def upcloud_wait_storage [
|
||||
settings: record
|
||||
server: record
|
||||
new_state: string
|
||||
id: string
|
||||
] {
|
||||
print $"Checking storage ($id) state for (_ansi blue_bold)($server.hostname)(_ansi reset) state (_ansi yellow_bold)($new_state)(_ansi reset) ..."
|
||||
let state = (^upctl storage show $id -o json e> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | from json | get -o state)
|
||||
if ($state | str contains $new_state) { return true }
|
||||
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 = (^upctl storage show $id -o json e> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | from json | get -o state)
|
||||
if ($status | str contains $new_state) {
|
||||
return true
|
||||
} else if $val_timeout > 0 and $num > $val_timeout {
|
||||
print ($"\n🛑 (_ansi red)Timeout(_ansi reset) ($val_timeout) volume ($id) state for (_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 ($"(_ansi blue_bold) 🌥 (_ansi reset) storage state for (_ansi yellow)($id)(_ansi reset) " +
|
||||
$"for (_ansi green)($server.hostname)(_ansi reset)-> ($status | str trim) "
|
||||
)
|
||||
} else {
|
||||
print -n $"(_ansi blue_bold) 🌥 (_ansi reset)"
|
||||
}
|
||||
sleep $wait_duration
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
export def upcloud_create_storage [
|
||||
settings: record
|
||||
server: record
|
||||
server_info: record
|
||||
storage: record
|
||||
volumes: list
|
||||
total_size: int
|
||||
] {
|
||||
if $total_size <= 0 {
|
||||
print $"❗Create storage for ($server.hostname) size (_ansi red)($total_size) error(_ansi reset)"
|
||||
return {}
|
||||
}
|
||||
let av_zone = ($storage.item | get -o zone | default ($server | get -o zone))
|
||||
if ($av_zone | is-empty) {
|
||||
print ($"❗Create storage for (_ansi green_bold)($server.hostname)(_ansi reset) " +
|
||||
$"(_ansi cyan_bold)($total_size)(_ansi reset) (_ansi red)Zone error(_ansi reset)"
|
||||
)
|
||||
return {}
|
||||
}
|
||||
let vol_device = ($storage.item | get -o voldevice)
|
||||
let op_vol_device = if ($vol_device | is-not-empty) {
|
||||
$"--address ($vol_device)"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
let op_encrypted = if ($storage.item | get -o encrypted | default false) {
|
||||
"--encrypted"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
let $op_backup = if ($storage.item | get -o backup | is-not-empty) {
|
||||
( $" --backup-time ($storage.item | get -o backup | get -o time) " +
|
||||
$" --backup-interval ($storage.item | get -o backup | get -o interval) " +
|
||||
$" --backup-retention ($storage.item | get -o backup | get -o retention)"
|
||||
)
|
||||
} else {
|
||||
""
|
||||
}
|
||||
print ($"Create storage for ($server.hostname) (_ansi cyan_bold)($total_size)(_ansi reset) in " +
|
||||
$"(_ansi blue_bold)($av_zone)(_ansi reset) with name (_ansi yellow)($storage.item | get -o name)_($server | get -o hostname)(_ansi reset) ... "
|
||||
)
|
||||
let res_create = (^upctl storage create --title $"($storage.item | get -o name)_($server.hostname)" --size ($total_size)
|
||||
--tier ($storage.item | get -o voltype) --zone $av_zone $op_encrypted $op_backup -o json | complete)
|
||||
if $res_create.exit_code != 0 {
|
||||
print ($"❗ Create storage for ($server.hostname) (_ansi cyan_bold)($total_size)(_ansi reset) in " +
|
||||
$"(_ansi blue_bold)($av_zone)(_ansi reset) with ($storage.item | get -o name) (_ansi red)error(_ansi reset) ($res_create.stdout)"
|
||||
)
|
||||
return {}
|
||||
}
|
||||
let server_id = ($server_info | get -o uuid | default "")
|
||||
let vol = ($res_create.stdout | from json)
|
||||
let vol_id = ($vol | get -o uuid)
|
||||
let new_state = "online"
|
||||
if not (upcloud_wait_storage $settings $server $new_state $vol_id) {
|
||||
print ($"❗ Wait ($vol_id) storage for ($server.hostname) (_ansi cyan_bold)($total_size)(_ansi reset) ($storage.item | get -o name) " +
|
||||
$"in (_ansi blue_bold)($av_zone)(_ansi reset) errors not in (_ansi red)($new_state)(_ansi reset) state"
|
||||
)
|
||||
^upctl storage delete $vol_id
|
||||
print $"❗ Attach ($vol_id) deleted"
|
||||
return {}
|
||||
}
|
||||
let vol_device = ($storage.item | get -o voldevice)
|
||||
if ($server_id | is-empty) { return $vol }
|
||||
print ($"Attach storage for ($server.hostname) (_ansi cyan_bold)($total_size)(_ansi reset) in " +
|
||||
$"(_ansi blue_bold)($av_zone)(_ansi reset) with name (_ansi yellow)($storage.item | get -o name)_($server | get -o hostname)(_ansi reset) ... "
|
||||
)
|
||||
let res_attach = if ($vol_device | is-not-empty) {
|
||||
(^upctl server storage attach $server_id --storage $vol_id --address $vol_device -o "json" | complete)
|
||||
} else {
|
||||
(^upctl server storage attach $server_id --storage $vol_id -o "json" | complete)
|
||||
}
|
||||
if $res_attach.exit_code != 0 {
|
||||
print $res_attach.exit_code
|
||||
print ($"❗Attach ($vol_id) storage for (_ansi green_bold)($server.hostname)(_ansi reset) (_ansi cyan_bold)($total_size)(_ansi reset) " +
|
||||
$"($storage.item | get -o name) ($vol_device) in (_ansi blue_bold)($av_zone)(_ansi reset) (_ansi red)errors(_ansi reset) " +
|
||||
$"\n($res_attach.stdout)"
|
||||
)
|
||||
^upctl storage delete $vol_id
|
||||
print $"❗Attach (_ansi red_bold)($vol_id)(_ansi reset) deleted"
|
||||
return {}
|
||||
}
|
||||
let res_vol = (^upctl storage show $vol_id -o json | complete)
|
||||
if $res_vol.exit_code == 0 {
|
||||
let info_vol = ($res_vol.stdout | from json)
|
||||
print $info_vol
|
||||
if ($info_vol | get -o servers | get -o server | where {|srv| $srv == $server_id } | length) > 0 {
|
||||
print ($"✅ Atached (_ansi yellow)($vol_id)(_ansi reset) storage for ($server.hostname) (_ansi cyan_bold)($total_size)(_ansi reset) " +
|
||||
$"($storage.item | get -o name)(if $vol_device != "" { $' ($vol_device)'}) in (_ansi blue_bold)(_ansi blue_bold)($av_zone)(_ansi reset)(_ansi reset)"
|
||||
)
|
||||
} else {
|
||||
print ($"❗ Volume ($vol_id) storage for ($server.hostname) (_ansi cyan_bold)($total_size)(_ansi reset) " +
|
||||
$"device ($vol_device) in (_ansi blue_bold)(_ansi blue_bold)($av_zone)(_ansi reset)(_ansi reset) (_ansi red)error(_ansi reset) not ($server_id)"
|
||||
)
|
||||
}
|
||||
$info_vol
|
||||
} else {
|
||||
print ($"❗ Volume ($vol_id) storage for ($server.hostname) (_ansi cyan_bold)($total_size)(_ansi reset) " +
|
||||
$"device ($vol_device) in (_ansi blue_bold)(_ansi blue_bold)($av_zone)(_ansi reset)(_ansi reset) (_ansi red)errors(_ansi reset) ($res_vol.stdout)"
|
||||
)
|
||||
{}
|
||||
}
|
||||
}
|
||||
|
||||
export def upcloud_storage_fix_size [
|
||||
settings: record
|
||||
server: record
|
||||
storage_pos: int
|
||||
] {
|
||||
let total_size = ($server | get -o storages | get -o $storage_pos | get -o total | default 0)
|
||||
if $total_size == 0 { return 0 }
|
||||
let storage = (^upctl server show $server.hostname "-o" "json" | from json | get -o storage_devices | get -o $storage_pos)
|
||||
if $storage == null {
|
||||
let server_info = (^upctl server show $server.hostname "-o" "json" | from json)
|
||||
let volumes = ($server_info | get -o storage_devices | default [])
|
||||
let storage_data = { item: ($server | get -o storages | get -o $storage_pos), index: $storage_pos }
|
||||
upcloud_create_storage $settings $server $server_info $storage_data $volumes $total_size
|
||||
}
|
||||
let $curr_size = ($storage | get -o storage_size | default 0)
|
||||
if $curr_size == 0 { return 0 }
|
||||
#let storage_parts = ($server.storages? | get -o $storage_pos | get -o parts | default [])
|
||||
#if ($storage_parts | length) == 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 (upcloud_change_server_state $settings $server "stop" "") == false {
|
||||
print $"❗ Stop ($server.hostname) errors "
|
||||
return "error"
|
||||
}
|
||||
if $storage_pos == 0 {
|
||||
let res = (^upctl storage modify --size $total_size $storage.storage err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | 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 | get -o 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) ... "
|
||||
} else {
|
||||
let storage_settings = ($server | get -o storages | get -o $storage_pos)
|
||||
let new_storage = (^upctl storage $server.hostname "-o" "json" | from json | get -o storage_devices | get -o $storage_pos)
|
||||
let $op_backup = if ($storage_settings | get -o backup | is-not-empty) {
|
||||
( $" --backup-time ($storage_settings | get -o backup | get -o time) " +
|
||||
$" --backup-interval ($storage_settings | get -o backup | get -o interval) " +
|
||||
$" --backup-retention ($storage_settings | get -o backup | get -o retention)"
|
||||
)
|
||||
} else {
|
||||
""
|
||||
}
|
||||
let op_encrypted = if ($storage_settings | get -o encrypted | default false) { "--encrypted" } else { "" }
|
||||
let res_modify = (^upctl storage modify ($new_storage | get -o uuid) --size $total_size $op_encrypted $op_backup| complete)
|
||||
if $res_modify.exit_code != 0 {
|
||||
print ($"❗ Modify storage for ($server.hostname) (_ansi cyan_bold)($total_size)(_ansi reset) in " +
|
||||
$"(_ansi blue_bold)($storage.zone)(_ansi reset) with ($storage.item | get -o name) (_ansi red)error(_ansi reset) ($res_modify.stdout)"
|
||||
)
|
||||
return {}
|
||||
}
|
||||
}
|
||||
if (upcloud_change_server_state $settings $server "start" "") == false {
|
||||
print $"❗ Errors to start ($server.hostname) "
|
||||
return "error"
|
||||
}
|
||||
#return "storage"
|
||||
}
|
||||
"storage"
|
||||
}
|
||||
export def upcloud_status_server [
|
||||
hostname: string
|
||||
] {
|
||||
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 {
|
||||
print $"❗ status ($hostname) errors "
|
||||
if $env.PROVISIONING_DEBUG { print $res.stdout }
|
||||
return ""
|
||||
}
|
||||
return ($res.stdout | from json | get -o state | default "")
|
||||
}
|
||||
export def upcloud_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 $"❗ server ($server.hostname) exists errors ($res.stdout ) "
|
||||
exit 1
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
export def upcloud_server_state [
|
||||
server: record
|
||||
new_state: string
|
||||
error_exit: bool
|
||||
wait: bool
|
||||
settings: record
|
||||
] {
|
||||
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 $"❗ state ($server.hostname) errors ($res.stdout ) "
|
||||
exit 1
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
export def upcloud_server_is_running [
|
||||
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 {
|
||||
print $"❗ is running ($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 upcloud_change_server_state [
|
||||
settings: record
|
||||
server: record
|
||||
new_state: string
|
||||
ops: string
|
||||
] {
|
||||
let state = (upcloud_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)
|
||||
let res = if ($ops | str contains "--type" ) {
|
||||
(^upctl server $new_state --type ($ops | str replace "--type " "") $server.hostname err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete)
|
||||
} else if $ops != "" {
|
||||
(^upctl server $new_state $ops $server.hostname err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" })| complete)
|
||||
} else {
|
||||
(^upctl server $new_state $server.hostname err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete)
|
||||
}
|
||||
if $res.exit_code != 0 {
|
||||
print $"❗Errors ($server.hostname) to ($new_state) ($res.stdout ) "
|
||||
return false
|
||||
}
|
||||
mut num = 0
|
||||
while true {
|
||||
let status = (upcloud_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 upcloud_delete_server_storage [
|
||||
settings: record
|
||||
server: record
|
||||
error_exit: bool
|
||||
] {
|
||||
let res = (^upctl storage list --normal -o json | complete)
|
||||
if $res.exit_code == 0 {
|
||||
let data = ($res.stdout | from json)
|
||||
$data.storages? | default [] | each {|storage|
|
||||
if ($storage.title | str starts-with $server.hostname ) {
|
||||
if (upcloud_server_exists $server false) {
|
||||
print $"❗ (_ansi blue_bold)($server.hostname)(_ansi reset) (_ansi red_bold)exists(_ansi reset) can not delete storage (_ansi yellow)($storage.uuid)(_ansi reset)"
|
||||
} else {
|
||||
let del_res = (^upctl storage delete $storage.uuid err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete)
|
||||
if $del_res.exit_code != 0 {
|
||||
print $"❗ Delete storage (_ansi yellow)($storage.uuid)(_ansi reset) for (_ansi blue_bold)($server.hostname)(_ansi reset) (_ansi red_bold)errors(_ansi reset) ($del_res.stdout ) "
|
||||
} else {
|
||||
print $"(_ansi yellow)($storage.uuid)(_ansi reset) for (_ansi blue_bold)($server.hostname)(_ansi reset) (_ansi green_bold)deleted(_ansi reset) ($del_res.stdout ) "
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
export def upcloud_delete_server [
|
||||
settings: record
|
||||
server: record
|
||||
keep_storage: bool
|
||||
error_exit: bool
|
||||
] {
|
||||
if not (upcloud_change_server_state $settings $server "stop" "--type hard") {
|
||||
if $env.PROVISIONING_DEBUG { print $"❗ Stop (_ansi blue_bold)($server.hostname)(_ansi reset) errors " }
|
||||
return false
|
||||
}
|
||||
let ops = if $keep_storage { "" } else { "--delete-storages" }
|
||||
let res = (^upctl server delete $server.hostname $ops err> (std null-device) | complete)
|
||||
if $res.exit_code != 0 {
|
||||
print $"❗ Delete (_ansi blue_bold)($server.hostname)(_ansi reset) (_ansi red_bold)errors(_ansi reset) ($res.stdout ) "
|
||||
return false
|
||||
}
|
||||
print $"(_ansi blue_bold)($server.hostname)(_ansi reset) (_ansi green_bold)deleted(_ansi reset)"
|
||||
true
|
||||
}
|
||||
42
providers/upcloud/nulib/upcloud/usage.nu
Normal file
42
providers/upcloud/nulib/upcloud/usage.nu
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
#!/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
|
||||
UPCLOUD ($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.
|
||||
PROV: ($env.WK_CNPROV)
|
||||
"
|
||||
# ["hello" $name $title]
|
||||
}
|
||||
|
||||
24
providers/upcloud/nulib/upcloud/utils.nu
Normal file
24
providers/upcloud/nulib/upcloud/utils.nu
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
export def upcloud_check_requirements [
|
||||
settings: record
|
||||
fix_error: bool
|
||||
] {
|
||||
let has_upctl = (^bash -c "type -P upctl")
|
||||
if ($has_upctl | path exists) == false and $fix_error {
|
||||
( ^($env.PROVISIONING_NAME) "tools" "install" "upctl")
|
||||
}
|
||||
let has_upctl = (^bash -c "type -P upctl")
|
||||
if ($has_upctl | path exists) == false {
|
||||
(throw-error $"🛑 CLI command upclouds not found"
|
||||
"upcloud_check_requirements" --span (metadata $has_upctl).span)
|
||||
exit 1
|
||||
}
|
||||
let upctl_version = (^upctl version | grep "Version" | cut -f2 -d":" | sed 's/ //g')
|
||||
let req_version = (open $env.PROVISIONING_REQ_VERSIONS).upctl?.version? | default "")
|
||||
if ($upctl_version != $req_version ) and $fix_error {
|
||||
( ^($env.PROVISIONING_NAME) "tools" "update" "upctl")
|
||||
}
|
||||
let upctl_version = (^upctl version | grep "Version" | cut -f2 -d":" | sed 's/ //g')
|
||||
if $upctl_version != $req_version {
|
||||
print $"warning❗ upctl command as CLI for UpCloud ($upctl_version) with Provisioning is not ($req_version)"
|
||||
}
|
||||
}
|
||||
394
providers/upcloud/pricing.html
Normal file
394
providers/upcloud/pricing.html
Normal file
File diff suppressed because one or more lines are too long
9
providers/upcloud/provisioning.yaml
Normal file
9
providers/upcloud/provisioning.yaml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
version: 1.0
|
||||
info: UpCloud provisioning
|
||||
site: https://upcloudltd.github.io/upcloud-cli
|
||||
tools:
|
||||
upctl:
|
||||
version: 3.9.0
|
||||
source: https://github.com/UpCloudLtd/upcloud-cli/releases/download
|
||||
tags: https://github.com/UpCloudLtd/upcloud-cli/tags
|
||||
site: https://upcloudltd.github.io/upcloud-cli
|
||||
4
providers/upcloud/versions
Normal file
4
providers/upcloud/versions
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
UPCLOUD_UPCTL_VERSION="3.20.1"
|
||||
UPCLOUD_UPCTL_SOURCE="https://github.com/UpCloudLtd/upcloud-cli/releases/download"
|
||||
UPCLOUD_UPCTL_TAGS="https://github.com/UpCloudLtd/upcloud-cli/tags"
|
||||
UPCLOUD_UPCTL_SITE="https://upcloudltd.github.io/upcloud-cli"
|
||||
12
providers/upcloud/versions.yaml
Normal file
12
providers/upcloud/versions.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
upctl:
|
||||
version: 3.9.0
|
||||
fixed: false
|
||||
source: https://github.com/UpCloudLtd/upcloud-cli/releases
|
||||
tags: https://github.com/UpCloudLtd/upcloud-cli/tags
|
||||
site: https://upcloudltd.github.io/upcloud-cli
|
||||
detector:
|
||||
method: command
|
||||
command: upctl version
|
||||
pattern: Version:\s+(\d+\.\d+\.\d+)
|
||||
capture: capture0
|
||||
comparison: semantic
|
||||
12
providers/upcloud/versions.yaml.backup
Normal file
12
providers/upcloud/versions.yaml.backup
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
upctl:
|
||||
version: 3.9.0
|
||||
fixed: false
|
||||
source: https://github.com/UpCloudLtd/upcloud-cli/releases
|
||||
tags: https://github.com/UpCloudLtd/upcloud-cli/tags
|
||||
site: https://upcloudltd.github.io/upcloud-cli
|
||||
detector:
|
||||
method: command
|
||||
command: upctl version
|
||||
pattern: Version:\s+(\d+\.\d+\.\d+)
|
||||
capture: capture0
|
||||
comparison: semantic
|
||||
Loading…
Add table
Add a link
Reference in a new issue