1101 lines
44 KiB
Plaintext
1101 lines
44 KiB
Plaintext
#!/usr/bin/env nu
|
|
|
|
use lib.nu *
|
|
use cache.nu *
|
|
use std
|
|
use ../../../../core/nulib/lib_provisioning/utils/templates.nu run_from_template
|
|
#use ssh.nu ssh_cmd
|
|
#use ssh.nu scp_to
|
|
|
|
export def aws_query_servers [
|
|
find: string
|
|
cols: string
|
|
] {
|
|
print $find
|
|
print $cols
|
|
print "aws_query_servers"
|
|
exit 1
|
|
let res = (^aws 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 "🛑 aws server list " $"($res.exit_code) ($res.stdout)" "aws query server" --span (metadata $res).span)
|
|
} else {
|
|
print $"🛑 Error aws server list: ($res.exit_code) ($res.stdout | ^grep 'error')"
|
|
}
|
|
}
|
|
}
|
|
export def aws_server_info [
|
|
server: record
|
|
check: bool
|
|
] {
|
|
#--query "Reservations[*].Instances[*].{
|
|
let res = (^aws ec2 describe-instances --out json --filters $'"Name=tag:hostname,Values=($server.hostname)"' --filters "Name=instance-state-name,Values=running"
|
|
--query "Reservations[*].Instances[].{
|
|
id: InstanceId,
|
|
tags: Tags,
|
|
private_ips: NetworkInterfaces[],
|
|
public_ips: PublicIpAddress,
|
|
sgs: SecurityGroups[],
|
|
volumes: BlockDeviceMappings,
|
|
type: InstanceType,
|
|
status: State.Name
|
|
}"
|
|
--output json | complete)
|
|
if $res.exit_code == 0 {
|
|
let data = ($res.stdout | from json | get -o 0 | default {})
|
|
if ($data | is-empty) {
|
|
{}
|
|
} else {
|
|
($data | merge { hostname: $server.hostname})
|
|
}
|
|
} else if $check {
|
|
{}
|
|
} else {
|
|
if $env.PROVISIONING_DEBUG {
|
|
(throw-error "🛑 aws server " $"($res.exit_code) ($res.stdout)" $"aws server info ($server.hostname)" --span (metadata $res).span)
|
|
} else {
|
|
print $"🛑 aws server ($server.hostname):($res.stdout | ^grep 'error')"
|
|
{}
|
|
}
|
|
}
|
|
}
|
|
export def aws_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)AWS(_ansi reset)"
|
|
}
|
|
export def _aws_query_servers [
|
|
find: string
|
|
cols: string
|
|
] {
|
|
return [ { "hostname": "fsfsdf"} ]
|
|
let res = (^aws server list -o json | complete)
|
|
if $res.exit_code == 0 {
|
|
let result = if $find != "" {
|
|
$res.stdout | from json | get servers | find $find
|
|
} else {
|
|
$res.stdout | from json | get servers
|
|
}
|
|
if $cols != "" {
|
|
let field_list = ($cols | split row ",")
|
|
$result | select -o $field_list
|
|
} else {
|
|
$result
|
|
}
|
|
} else {
|
|
(throw-error "🛑 aws server list " $"($res.exit_code) ($res.stdout)" "aws query server" --span (metadata $res).span)
|
|
}
|
|
}
|
|
# infrastructure and services
|
|
export def aws [
|
|
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
|
|
] {
|
|
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 aws help"
|
|
if not $env.PROVISIONING_DEBUG { end_run "" }
|
|
exit
|
|
},
|
|
_ => {
|
|
if ($args | find "help" | length) > 0 {
|
|
match $task {
|
|
"server" => {
|
|
print "SERVER "
|
|
aws_server ($args | drop nth ..0)
|
|
},
|
|
"inventory" => {
|
|
aws_server ($args | drop nth ..0)
|
|
},
|
|
"ssh" => {
|
|
aws_server ($args | drop nth ..0)
|
|
},
|
|
"delete" => {
|
|
aws_server ($args | drop nth ..0)
|
|
# ($args | drop nth ..1) --server $server
|
|
},
|
|
_ => {
|
|
option_undefined "aws" ""
|
|
print "TODO aws 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) {
|
|
"server" => {
|
|
print (
|
|
aws_server $cmd_args --server $server --settings $curr_settings --error_exit
|
|
)
|
|
},
|
|
"inventory" => {
|
|
},
|
|
"ssh" => {
|
|
},
|
|
"delete" => {
|
|
# ($args | drop nth ..1) --server $server
|
|
},
|
|
_ => {
|
|
option_undefined "aws" ""
|
|
if not $env.PROVISIONING_DEBUG { end_run "" }
|
|
exit
|
|
}
|
|
}
|
|
}
|
|
export def aws_get_ip [
|
|
settings: record
|
|
server: record
|
|
ip_type: string
|
|
] {
|
|
match $ip_type {
|
|
"private" | "prv" | "priv" => {
|
|
$"($server.network_private_ip)"
|
|
},
|
|
_ => {
|
|
let res = (^aws ec2 describe-instances --filter $"Name=tag-value,Values=($server.hostname)" "Name=instance-state-name,Values=running"
|
|
--query "Reservations[*].Instances[0].PublicIpAddress"
|
|
--output text
|
|
err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete
|
|
)
|
|
if $res.exit_code == 0 {
|
|
($res.stdout | default {})
|
|
} else { "" }
|
|
}
|
|
}
|
|
}
|
|
# To create infrastructure and services
|
|
export def aws_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
|
|
] {
|
|
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 aws server help"
|
|
if not $env.PROVISIONING_DEBUG { end_run "" }
|
|
exit
|
|
},
|
|
_ => {
|
|
if $target == "" or ($args | find "help" | length) > 0 {
|
|
match $task {
|
|
"server" => {
|
|
aws_server $cmd_args
|
|
},
|
|
"status" => {
|
|
print $server
|
|
print $error_exit
|
|
}
|
|
"inventory" => {
|
|
print "TODO aws server inventory help"
|
|
},
|
|
"ssh" => {
|
|
print "TODO aws server ssh help"
|
|
},
|
|
"delete" => {
|
|
# ($args | drop nth ..1) --server $server
|
|
#aws_delete_server $cmd_args true
|
|
},
|
|
_ => {
|
|
option_undefined "aws" "server"
|
|
print "TODO aws 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 "🛑 aws server" $text "" --span (metadata $server_target).span)
|
|
}
|
|
return ""
|
|
}
|
|
if $status or $task == "status" {
|
|
print "aws server status "
|
|
return true
|
|
}
|
|
match $task {
|
|
"get_ip" => {
|
|
aws_get_ip $settings $server_target ($cmd_args | get -o 0 | default "")
|
|
},
|
|
"stop" => {
|
|
aws_server_state $server_target "stop" false true $settings
|
|
},
|
|
"start" => {
|
|
aws_server_state $server_target "start" false true $settings
|
|
},
|
|
"restart" => {
|
|
aws_server_state $server_target "restart" false true $settings
|
|
},
|
|
_ => {
|
|
option_undefined "aws" "server"
|
|
if not $env.PROVISIONING_DEBUG { end_run "" }
|
|
exit
|
|
}
|
|
}
|
|
}
|
|
export def aws_create_private_network [
|
|
settings: record
|
|
server: record
|
|
check: bool
|
|
] {
|
|
if $server == null {
|
|
print $"❗ No server found in settings "
|
|
return ""
|
|
}
|
|
# new_aws 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=$(aws network list -o yaml | $YQ '.networks[] | select(.ip_networks.ip_network[].address == "'"$priv_cidr_block"'") | .uuid' 2>/dev/null | sed 's,",,g')
|
|
let result = (^aws "network" "list" "-o" "json" | complete)
|
|
let private_net_id = if $result.exit_code == 0 {
|
|
let data = ($result.stdout | from json )
|
|
($data | get -o 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 = (^aws 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 | get -o 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)"
|
|
$"aws_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)/aws_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 aws_get_ssh_key [
|
|
server: record
|
|
] {
|
|
let res = (^aws ec2 describe-key-pairs --key-names $server.ssh_key_name
|
|
--query "KeyPairs[0].KeyPairId" --out text err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete)
|
|
if $res.exit_code != 0 {
|
|
print $"❗Error [($res.exit_code)] read (_ansi blue_bold)($server.provider)(_ansi reset) ssh_key (_ansi red_bold)($server.ssh_key_name)(_ansi reset) for server (_ansi green_bold)($server.hostname)(_ansi reset)"
|
|
""
|
|
} else {
|
|
($res.stdout | str trim)
|
|
}
|
|
}
|
|
export def aws_create_ssh_key [
|
|
server: record
|
|
] {
|
|
let res = (^aws ec2 import-key-pair --key-name $server.ssh_key_name --public-key-material $"fileb://($server.ssh_key_path)"
|
|
--query "KeyPairs[0].KeyPairId" --out text err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete)
|
|
if $res.exit_code != 0 {
|
|
print $"❗Error [($res.exit_code)] create (_ansi blue_bold)($server.provider)(_ansi reset) ssh_key (_ansi red_bold)($server.ssh_key_name)(_ansi reset) for server (_ansi green_bold)($server.hostname)(_ansi reset)"
|
|
""
|
|
} else {
|
|
print $"✅ (_ansi blue_bold)($server.provider)(_ansi reset) create ssh_key (_ansi cyan_bold)($server.ssh_key_name)(_ansi reset) for server (_ansi green_bold)($server.hostname)(_ansi reset)"
|
|
($res.stdout | str trim)
|
|
}
|
|
}
|
|
export def aws_check_server_requirements [
|
|
settings: record
|
|
server: record
|
|
check: bool
|
|
] {
|
|
print $"Check (_ansi blue)($server.provider)(_ansi reset) requirements for (_ansi green_bold)($server.hostname)(_ansi reset)"
|
|
if $server.provider != "aws" { return false }
|
|
if (^aws account get-contact-information --query "ContactInformation" --out text err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete).exit_code != 0 {
|
|
return false
|
|
}
|
|
if ($server.ssh_key_name | default "" | is-empty) {
|
|
print $"❗server (_ansi green_bold)($server.hostname)(_ansi reset) ssh_key (_ansi red_bold)($server.ssh_key_name)(_ansi reset) not found "
|
|
return false
|
|
}
|
|
let key_pair = (aws_get_ssh_key $server)
|
|
if ($key_pair | is-not-empty) { return true }
|
|
if $check {
|
|
print $"❗server (_ansi green_bold)($server.hostname)(_ansi reset) ssh_key (_ansi red_bold)($server.ssh_key_name)(_ansi reset) not found in (_ansi blue_bold)($server.provider)(_ansi reset)"
|
|
return true
|
|
}
|
|
if ($server.ssh_key_path | default "" | is-empty) or not ($server.ssh_key_path | path exists) {
|
|
print $"❗Error create (_ansi blue)($server.provider)(_ansi reset) for server (_ansi green_bold)($server.hostname)(_ansi reset) ssh_key (_ansi red_bold)($server.ssh_key_name)(_ansi reset)"
|
|
print $"❗server (_ansi green_bold)($server.hostname)(_ansi reset) ssh_key_path (_ansi red_bold)($server.ssh_key_path)(_ansi reset) for ssh_key (_ansi red_bold)($server.ssh_key_name)(_ansi reset) not found "
|
|
return false
|
|
}
|
|
let key_pair = (aws_create_ssh_key $server)
|
|
if ($key_pair | is-empty) {
|
|
print $"❗server (_ansi green_bold)($server.hostname)(_ansi reset) ssh_key (_ansi red_bold)($server.ssh_key_name)(_ansi reset) not found in (_ansi blue_bold)($server.provider)(_ansi reset)"
|
|
return false
|
|
}
|
|
return true
|
|
let private_net_id = if ($server.network_private_id? | default "") == "CREATE" {
|
|
print $"❗ ($server.network_private_id?) found will be created "
|
|
(aws_create_private_network $settings $server $check)
|
|
} else {
|
|
(aws_create_private_network $settings $server $check)
|
|
($server.network_private_id? | default "" )
|
|
}
|
|
let result = (^aws "network" "show" $private_net_id "-o" "json" | complete)
|
|
let privavet_net_id = if (not $check) and $result.exit_code != 0 {
|
|
let net_id = (aws_create_private_network $settings $server $check)
|
|
let res = (^aws "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)"
|
|
"aws_check_requirements" --span (metadata $server_private_ip).span)
|
|
return false
|
|
}
|
|
true
|
|
}
|
|
|
|
export def aws_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 = (^aws server show $server.hostname "-o" "json" | from json).uuid? | default ""
|
|
if $uuid == "" {
|
|
returm false
|
|
}
|
|
let ip_pub = (aws_get_ip $settings $server "public")
|
|
let ip_priv = (aws_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 $"✅ aws settings ($task) -> ($out_settings_path)"
|
|
true
|
|
}
|
|
export def aws_delete_settings [
|
|
settings: record
|
|
server: record
|
|
] {
|
|
}
|
|
export def aws_wait_storage [
|
|
settings: record
|
|
server: record
|
|
new_state: string
|
|
id: string
|
|
] {
|
|
let state = (^aws ec2 describe-volumes --volume-ids $id --query "Volumes[0].State")
|
|
if ($state | str contains $new_state) { return true }
|
|
print $"Checking volume ($id) state for (_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 = (^aws ec2 describe-volumes --volume-ids $id --query "Volumes[0].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) volume 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 aws_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 = if ($storage.item | get -o zone | is-empty) {
|
|
($volumes | get -o 0 | get -o AvailabilityZone)
|
|
} else {
|
|
($storage.item | 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)AvailavilityZone error(_ansi reset)"
|
|
)
|
|
return {}
|
|
}
|
|
let vol_device = if ($storage.item | get -o voldevice | str contains "/dev/") {
|
|
($storage.item | get -o voldevice)
|
|
} else {
|
|
("/dev/" | path join ($storage.item | get -o voldevice))
|
|
}
|
|
if ($vol_device | is-empty) {
|
|
print ($"❗ Create storage for ($server.hostname) (_ansi cyan_bold)($total_size)(_ansi reset) in " +
|
|
$"(_ansi blue_bold)($av_zone)(_ansi reset) (_ansi red)voldevice error(_ansi reset)"
|
|
)
|
|
return {}
|
|
}
|
|
let op_encrypted = if ($storage.item | get -o encrypted | default false) {
|
|
"--encrypted"
|
|
} else {
|
|
"--no-encrypted"
|
|
}
|
|
let res_create = (^aws ec2 create-volume --volume-type ($storage.item | get -o voltype) --size $total_size --availability-zone $av_zone $op_encrypted | 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 ($vol_device) (_ansi red)error(_ansi reset) ($res_create.stdout)"
|
|
)
|
|
return {}
|
|
}
|
|
let instance_id = ($server_info | get -o InstanceId | default "")
|
|
let vol = ($res_create.stdout | from json)
|
|
let vol_id = ($vol | get -o volumeId)
|
|
let new_state = "available"
|
|
if not (aws_wait_storage $settings $server $new_state $vol_id) {
|
|
print ($"❗ Error ($vol_id) storage for ($server.hostname) (_ansi cyan_bold)($total_size)(_ansi reset) device ($vol_device) " +
|
|
$"in (_ansi blue_bold)($av_zone)(_ansi reset) errors not in (_ansi red)($new_state)(_ansi reset) state"
|
|
)
|
|
^aws ec2 delete-volume --volume-id $vol_id
|
|
print $"❗ Attach ($vol_id) deleted"
|
|
return {}
|
|
}
|
|
if ($instance_id | is-empty) { return $vol }
|
|
let res_attach = (^aws ec2 attach-volume --volume-id $vol_id --device $vol_device --instance-id $instance_id | complete)
|
|
if $res_attach.exit_code != 0 {
|
|
print ($"❗ Attach ($vol_id) storage for (_ansi green_bold)($server.hostname)(_ansi reset) (_ansi cyan_bold)($total_size)(_ansi reset) " +
|
|
$"device ($vol_device) in (_ansi blue_bold)($av_zone)(_ansi reset) (_ansi red)errors(_ansi reset) " # ($res.stdout)"
|
|
)
|
|
^aws ec2 delete-volume --volume-id $vol_id
|
|
print $"❗ Attach (_ansi red_bold)($vol_id)(_ansi reset) deleted"
|
|
}
|
|
let res_vol = (^aws ec2 describe-volumes --volume-id $vol_id --filters $"Name=attachment.instance-id,Values=($instance_id)"
|
|
--query "Volumes[]" --output=json | complete)
|
|
if $res_vol.exit_code == 0 {
|
|
print ($"✅ Atached (_ansi yellow)($vol_id)(_ansi reset) 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)"
|
|
)
|
|
($res_vol.stdout | from json | get -o 0)
|
|
} 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)"
|
|
)
|
|
{}
|
|
}
|
|
}
|
|
def aws_vol_modify [
|
|
settings: record
|
|
server: record
|
|
store_size: int
|
|
vol_id: string
|
|
vol_size: int
|
|
] {
|
|
if $store_size <= 0 {
|
|
print $"🛑 new vol size (_ansi red_bold)($store_size)(_ansi reset) for (_ansi yellow)($vol_id)(_ansi reset) (_ansi green_bold)($server.hostname)(_ansi reset)"
|
|
return false
|
|
}
|
|
let curr_size = (^aws ec2 describe-volumes --volume-ids $vol_id --query "Volumes[0].Size")
|
|
if $curr_size == $vol_size { return true }
|
|
let res_modify = (^aws ec2 modify-volume --size $store_size --volume-id $vol_id | complete)
|
|
if $res_modify.exit_code != 0 {
|
|
print $"❗Modify ($vol_id) from ($vol_size) to ($store_size) for ($server.hostname) in ($server.provider) error "
|
|
if $env.PROVISIONING_DEBUG { print $res_modify.stdout }
|
|
return false
|
|
}
|
|
let new_state = "in-use"
|
|
let wait = if $server.running_wait? != null { $server.running_wait } else { 10 }
|
|
let wait_duration = ($"($wait)sec"| into duration)
|
|
print ($"(_ansi blue_bold) 🌥 (_ansi reset) waiting for volume (_ansi yellow)($vol_id)(_ansi reset) " +
|
|
$"for (_ansi green)($server.hostname)(_ansi reset)-> ($new_state) "
|
|
)
|
|
sleep $wait_duration
|
|
(aws_wait_storage $settings $server $new_state $vol_id)
|
|
}
|
|
def aws_part_resize [
|
|
settings: record
|
|
server: record
|
|
mount_path: string
|
|
] {
|
|
let ip = (mw_get_ip $settings $server $server.liveness_ip false )
|
|
if $ip == "" {
|
|
print $"🛑 No IP found for (_ansi green_bold)($server.hostname)(_ansi reset)"
|
|
return false
|
|
}
|
|
let template_name = "resize_storage"
|
|
let template_path = ($env.PROVISIONING_TEMPLATES_PATH | path join $"($template_name).j2")
|
|
let wk_file = $"($settings.wk_path)/($server.hostname)_($template_name)_cmd"
|
|
let wk_vars = $"($settings.wk_path)/($server.hostname)_($template_name)_vars.($env.PROVISIONING_WK_FORMAT)"
|
|
let run_file = $"($settings.wk_path)/on_($server.hostname)_($template_name)_run.sh"
|
|
let data_settings = ($settings.data | merge { wk_file: $wk_file, now: $env.NOW, provisioning_vers: ($env.PROVISIONING_VERS? | str replace "null" ""),
|
|
provider: ($settings.providers | where {|it| $it.provider == $server.provider} | get -o 0 | get -o settings | default {}),
|
|
server: $server })
|
|
if $env.PROVISIONING_WK_FORMAT == "json" {
|
|
$data_settings | to json | save --force $wk_vars
|
|
} else {
|
|
$data_settings | to yaml | save --force $wk_vars
|
|
}
|
|
let resize_storage_sh = ($settings.wk_path | path join $"($server.hostname)-($template_name).sh")
|
|
let result = (run_from_template $template_path $wk_vars $run_file $resize_storage_sh --only_make)
|
|
if $result and ($resize_storage_sh | path exists) {
|
|
open $resize_storage_sh | str replace "$MOUNT_PATH" $mount_path | save --force $resize_storage_sh
|
|
let target_cmd = $"/tmp/($template_name).sh"
|
|
#use ssh.nu scp_to ssh_cmd
|
|
if not (scp_to $settings $server [$resize_storage_sh] $target_cmd $ip) { return false }
|
|
print $"Running (_ansi blue_italic)($target_cmd | path basename)(_ansi reset) in (_ansi green_bold)($server.hostname)(_ansi reset)"
|
|
if not (ssh_cmd $settings $server true $target_cmd $ip) { return false }
|
|
if $env.PROVISIONING_SSH_DEBUG? != null and $env.PROVISIONING_SSH_DEBUG { return true }
|
|
if not $env.PROVISIONING_DEBUG {
|
|
(ssh_cmd $settings $server false $"rm -f ($target_cmd)" $ip)
|
|
}
|
|
true
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
export def aws_post_create_server [
|
|
settings: record
|
|
server: record
|
|
check: bool
|
|
] {
|
|
if $server != null {
|
|
(aws_storage_fix_size $settings $server 0)
|
|
} else {
|
|
true
|
|
}
|
|
# 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)
|
|
# aws_scan_settings "scan" $provider_path $settings $server false
|
|
# aws_scan_servers $provider_path $settings $server
|
|
# # let prov_settings = (load_provider_env $settings $server $provider_path)
|
|
}
|
|
export def aws_modify_server [
|
|
settings: record
|
|
server: record
|
|
new_values: list
|
|
error_exit: bool
|
|
] {
|
|
#let res = (^aws ec2 describe-instances --filter $"Name=tag-value,Values=($server.hostname)" "Name=instance-state-name,Values=running"
|
|
# TODO fix for AWS
|
|
return
|
|
let res = (^aws ec2 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"
|
|
}
|
|
}
|
|
}
|
|
def aws_get_volume [
|
|
vol_id: string
|
|
instance_id: string
|
|
] {
|
|
let res_vol = (^aws ec2 describe-volumes --volume-id $vol_id --filters $"Name=attachment.instance-id,Values=($instance_id)"
|
|
--query "Volumes[]" --output=json | complete)
|
|
if $res_vol.exit_code == 0 {
|
|
let vol = ($res_vol.stdout | from json | get -o 0)
|
|
#if ($vol | get -o SnapshotId | is-empty) {
|
|
$vol
|
|
#}
|
|
} else {
|
|
{}
|
|
}
|
|
}
|
|
def aws_get_all_volumes [
|
|
instance_id: string
|
|
instance_data: record
|
|
|
|
] {
|
|
$instance_data | get -o BlockDeviceMappings | default [] | each {|device|
|
|
let vol_id = ($device | get -o Ebs | get -o VolumeId | default "")
|
|
if ($vol_id | is-not-empty) {
|
|
(aws_get_volume $vol_id $instance_id)
|
|
}
|
|
}
|
|
}
|
|
export def aws_storage_fix_size [
|
|
settings: record
|
|
server: record
|
|
storage_pos: int
|
|
] {
|
|
let res = (^aws ec2 describe-instances --out json --filters $'"Name=tag:hostname,Values=($server.hostname)"' --filters "Name=instance-state-name,Values=running"
|
|
--query "Reservations[*].Instances[]" # ?State.Name!='terminated']
|
|
err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete
|
|
)
|
|
if $res.exit_code != 0 {
|
|
print $"❗Error: no info found for ($server.hostname) in ($server.provider) "
|
|
return false
|
|
}
|
|
let instance_data = ($res.stdout | from json | get -o 0 | default {} | into record)
|
|
let instance_id = ($instance_data | get -o InstanceId | default "")
|
|
let storages = ($server | get -o storages)
|
|
let volumes = (aws_get_all_volumes $instance_id $instance_data)
|
|
|
|
mut req_storage = false
|
|
for storage in ($storages | enumerate) {
|
|
let store_size = ($storage.item | get -o size | default 0)
|
|
let store_total = ($storage.item | get -o total | default 0)
|
|
if $store_total == 0 { continue }
|
|
let store_name = ($storage.item | get -o name | default "")
|
|
let volume = ($volumes | get -o $storage.index | default {})
|
|
let vol_size = ($volume | get -o Size | default 0)
|
|
let vol_id = ($volume | get -o VolumeId | default "")
|
|
|
|
let res_vol = (^aws ec2 describe-volumes --volume-id $vol_id --filters $"Name=attachment.instance-id,Values=($instance_id)"
|
|
--query "Volumes[]" --output=json | complete)
|
|
let store_parts = ($storage.item | get -o parts)
|
|
if ($volume | is-not-empty) {
|
|
if ($store_parts | length) == 0 {
|
|
if $vol_size != $store_size {
|
|
if $vol_size < $store_total {
|
|
print $"Store total ($store_total) < ($vol_size) for ($server.hostname) in ($server.provider) "
|
|
}
|
|
let store_mount_path = ($storage.item | get -o mount_path | default "")
|
|
if $store_mount_path == "/" or $store_name == "root" {
|
|
if (aws_vol_modify $settings $server $store_size $vol_id $vol_size) {
|
|
aws_part_resize $settings $server $store_mount_path
|
|
if not $req_storage { $req_storage = true }
|
|
}
|
|
}
|
|
}
|
|
} else if ($store_parts | length) > 0 {
|
|
let sum_size_parts = ($store_parts | each {|part| $part | get -o size | default 0} | math sum)
|
|
if $vol_size != $sum_size_parts {
|
|
if $env.PROVISIONING_DEBUG {
|
|
print $"Store total ($store_total) < ($vol_size) parts ($sum_size_parts) for ($server.hostname) in ($server.provider) "
|
|
print $store_parts
|
|
}
|
|
$store_parts | each {|part|
|
|
let part_mount_path = ($part | get -o mount_path)
|
|
let part_name = ($part | get -o name)
|
|
let volume_parts = (aws_get_volume $vol_id $instance_id)
|
|
let volume_parts_size = ($volume_parts | get -o Size | default 0)
|
|
if $part_mount_path == "/" or $part_name == "root" {
|
|
let part_size = ($part | get -o size)
|
|
if $volume_parts_size < $part_size and (aws_vol_modify $settings $server $part_size $vol_id $volume_parts_size) {
|
|
aws_part_resize $settings $server $part_mount_path
|
|
}
|
|
} else {
|
|
if $volume_parts_size < $sum_size_parts {
|
|
if not (aws_vol_modify $settings $server $sum_size_parts $vol_id $volume_parts_size) {
|
|
print $"❗Error store vol ($vol_id) modify to ($volume_parts_size) for ($server.hostname) in ($server.provider) "
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if not $req_storage { $req_storage = true }
|
|
}
|
|
}
|
|
} else {
|
|
print $"($store_size) ($store_total)"
|
|
let volume = if ($store_parts | length) == 0 {
|
|
print "Create storage volume"
|
|
(aws_create_storage $settings $server $instance_data $storage $volumes $store_total)
|
|
} else {
|
|
print "Create storage partitions"
|
|
if $env.PROVISIONING_DEBUG { print $store_parts }
|
|
let sum_size_parts = ($store_parts | each {|part| $part | get -o size | default 0} | math sum)
|
|
(aws_create_storage $settings $server $instance_data $storage $volumes $sum_size_parts)
|
|
}
|
|
if not $req_storage { $req_storage = true }
|
|
}
|
|
}
|
|
if $req_storage {
|
|
"storage"
|
|
} else {
|
|
""
|
|
}
|
|
}
|
|
export def aws_status_server [
|
|
hostname: string
|
|
id: string
|
|
] {
|
|
let res = if ($id | is-not-empty) {
|
|
(^aws ec2 describe-instances --instance-ids ($id | str trim)
|
|
--query "Reservations[*].Instances[0].[InstanceId,State.Name]"
|
|
--output text
|
|
| complete
|
|
#err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete
|
|
)
|
|
} else {
|
|
(^aws ec2 describe-instances --filter $"Name=tag-value,Values=($hostname)"
|
|
--query "Reservations[*].Instances[0].[InstanceId,State.Name]"
|
|
--output text
|
|
err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete
|
|
)
|
|
}
|
|
if $res.exit_code != 0 {
|
|
print $"❗ status ($hostname) errors ($res.stdout ) "
|
|
return "??"
|
|
}
|
|
($res.stdout | default "")
|
|
}
|
|
export def aws_server_state [
|
|
server: record
|
|
new_state: string
|
|
error_exit: bool
|
|
wait: bool
|
|
settings: record
|
|
] {
|
|
let res = (^aws ec2 describe-instances --filter $"Name=tag-value,Values=($server.hostname)"
|
|
--query "Reservations[*].Instances[0].[InstanceId,State.Name]"
|
|
--output 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) to ($new_state) errors ($res.stdout ) "
|
|
exit 1
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
let data = ($res.stdout | from json | get -o 0 | default [])
|
|
let instance_id = ($data | get -o 0 | default "")
|
|
let curr_state = ($data | get -o 1 | default "")
|
|
if ($instance_id |is-empty) {
|
|
print $"❗ state ($server.hostname) to ($new_state) errors (_ansi red)no server found(_ansi reset) "
|
|
return false
|
|
}
|
|
if ($curr_state |is-empty) {
|
|
print $"❗ state ($server.hostname) to ($new_state) errors (_ansi red)no current state found(_ansi reset) "
|
|
return false
|
|
}
|
|
match $new_state {
|
|
"start" if ($curr_state | str contains "running") => {
|
|
print $"❗ state ($server.hostname) to ($new_state) error is already (_ansi green)running(_ansi reset)"
|
|
return false
|
|
},
|
|
"stop" if ($curr_state | str contains "stopp") => {
|
|
print $"❗ state ($server.hostname) to ($new_state) error is (_ansi green)($curr_state)(_ansi reset)"
|
|
return false
|
|
}
|
|
"stop" if (aws_has_disable_stop $server $instance_id) => {
|
|
print $"❗ state ($server.hostname) to ($new_state) error settings (_ansi red)disabled_stop ($server.disable_stop)(_ansi reset)"
|
|
print $" Server DisableApiStop = true."
|
|
print ( $" Only (_ansi yellow)restart(_ansi reset) (_ansi default_dimmed)[aws reboot](_ansi reset) " +
|
|
$"or (_ansi yellow)delete(_ansi reset) (_ansi default_dimmed)[aws terminate](_ansi reset) to keep public IPs"
|
|
)
|
|
return false
|
|
}
|
|
}
|
|
let state_data = match $new_state {
|
|
"start" | "restart
|
|
" => {
|
|
print $"($new_state) for ($server.hostname) in ($server.provider)"
|
|
let task_key = if $new_state == "restart" { "reboot" } else { $new_state }
|
|
{ name: "running", res: (^aws ec2 $"($task_key)-instances" --instance-ids $instance_id err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete) }
|
|
},
|
|
"stop" => {
|
|
print $"($new_state) for ($server.hostname) in ($server.provider)"
|
|
{ name: "stopped", res: (^aws ec2 stop-instances --instance-ids $instance_id err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete) }
|
|
},
|
|
}
|
|
if $state_data.res.exit_code != 0 {
|
|
print $"❗ state ($server.hostname) to ($new_state) errors ($res.stdout ) "
|
|
return false
|
|
}
|
|
if $wait { aws_change_server_state $settings $server $state_data.name $instance_id }
|
|
true
|
|
}
|
|
export def aws_server_exists [
|
|
server: record
|
|
error_exit: bool
|
|
] {
|
|
let res = (^aws ec2 describe-instances --filter $"Name=tag-value,Values=($server.hostname)"
|
|
--query "Reservations[*].Instances[0].[InstanceId,State.Name]"
|
|
--output text
|
|
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
|
|
}
|
|
}
|
|
($res.stdout | lines | where {|it| $it | str contains "running" } | length) > 0
|
|
}
|
|
export def aws_server_is_running [
|
|
server: record
|
|
error_exit: bool
|
|
] {
|
|
let res = (^aws ec2 describe-instances --filter $"Name=tag-value,Values=($server.hostname)"
|
|
--query "Reservations[*].Instances[0].State.Name"
|
|
--output text
|
|
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 | str contains "running" | default false)
|
|
}
|
|
export def aws_change_server_state [
|
|
settings: record
|
|
server: record
|
|
new_state: string
|
|
id: string
|
|
ops: string = ""
|
|
] {
|
|
print $"Checking (_ansi blue_bold)($server.hostname)(_ansi reset) state (_ansi yellow_bold)($new_state)(_ansi reset) ..."
|
|
let state = (aws_status_server $server.hostname $id)
|
|
#if $state == "" { return false }
|
|
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 = (aws_status_server $server.hostname $id)
|
|
if ($status | str contains $new_state) {
|
|
return true
|
|
#} else 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 $"(_ansi blue_bold) 🌥 (_ansi reset) (_ansi green)($server.hostname)(_ansi reset)-> ($status | str trim) "
|
|
} else {
|
|
print -n $"(_ansi blue_bold) 🌥 (_ansi reset)"
|
|
}
|
|
sleep $wait_duration
|
|
}
|
|
}
|
|
false
|
|
}
|
|
export def aws_delete_server_storage [
|
|
settings: record
|
|
server: record
|
|
error_exit: bool
|
|
] {
|
|
let res = (^aws ec2 describe-volumes --filters $"Name=tag-value,Values=($server.hostname)*" --query "Volumes[*].VolumeId" --output json | complete)
|
|
if $res.exit_code == 0 {
|
|
let data = ($res.stdout | from json)
|
|
$data | default [] | each {|vol|
|
|
let res = (^aws ec2 delete-volume --volume-id $vol err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete)
|
|
if $res.exit_code != 0 {
|
|
print $"❗ Delete volume (_ansi blue_bold) ($vol) from ($server.hostname)(_ansi reset) (_ansi red_bold)errors(_ansi reset) ($res.stdout ) "
|
|
continue
|
|
}
|
|
print $"volume ($vol) from (_ansi blue_bold)($server.hostname)(_ansi reset) (_ansi green_bold)deleted(_ansi reset) ($res.stdout ) "
|
|
}
|
|
}
|
|
true
|
|
}
|
|
export def aws_delete_server [
|
|
settings: record
|
|
server: record
|
|
keep_storage: bool
|
|
error_exit: bool
|
|
] {
|
|
let res = (^aws ec2 describe-instances --filter $"Name=tag-value,Values=($server.hostname)" "Name=instance-state-name,Values=running"
|
|
--query "Reservations[*].Instances[*].InstanceId"
|
|
--output text
|
|
err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete
|
|
)
|
|
if $res.exit_code == 0 {
|
|
for id in ($res.stdout | str trim | split row " ") {
|
|
if (aws_has_disable_stop $server $id) {
|
|
print $"Change (_ansi yellow)disableApiStop(_ansi reset) for (_ansi blue_bold)($server.hostname)(_ansi reset) ..."
|
|
^aws ec2 modify-instance-attribute --instance-id $id --attribute disableApiStop --value false
|
|
}
|
|
let vols = if $keep_storage {
|
|
[]
|
|
} else {
|
|
let res_vols = (^aws ec2 describe-volumes --filters $"Name=attachment.instance-id,Values=($id)" --query "Volumes[*].VolumeId" --output json | complete)
|
|
if $res_vols.exit_code == 0 {
|
|
($res_vols.stdout | from json)
|
|
} else { [] }
|
|
}
|
|
let res = (^aws ec2 terminate-instances --instance-ids $"($id | str trim)" err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete)
|
|
if $res.exit_code != 0 {
|
|
#print $"❗ Delete (_ansi blue_bold)($server.hostname)(_ansi reset) (_ansi red_bold)errors(_ansi reset) ($res.stdout ) "
|
|
continue
|
|
}
|
|
aws_change_server_state $settings $server "terminated" $id
|
|
print $"(_ansi blue_bold)($server.hostname)(_ansi reset) (_ansi green_bold)deleted(_ansi reset) "
|
|
for vol in $vols {
|
|
if not $keep_storage {
|
|
let res = (^aws ec2 delete-volume --volume-id ($vol) err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete)
|
|
if $res.exit_code != 0 {
|
|
# print $"❗ Delete volume (_ansi blue_bold) ($vol) from ($server.hostname)(_ansi reset) (_ansi red_bold)errors(_ansi reset) ($res.stdout | str trim) "
|
|
continue
|
|
}
|
|
print $"volume ($vol) from (_ansi blue_bold)($server.hostname)(_ansi reset) (_ansi green_bold)deleted(_ansi reset) ($res.stdout | str trim) "
|
|
} else {
|
|
print $"volume ($vol) from (_ansi blue_bold)($server.hostname)(_ansi reset) (_ansi green_bold)deleted(_ansi reset) ($res.stdout | str trim) "
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if not $keep_storage {
|
|
aws_delete_server_storage $settings $server $error_exit
|
|
}
|
|
true
|
|
}
|
|
|
|
export def aws_server_id [
|
|
server: record
|
|
] {
|
|
let res = (^aws ec2 describe-instances --filter $"Name=tag-value,Values=($server.hostname)" "Name=instance-state-name,Values=running"
|
|
--query "Reservations[*].Instances[0].InstanceId"
|
|
--output text
|
|
err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete
|
|
)
|
|
if $res.exit_code != 0 or ($res.stdout | is-empty) {
|
|
print $"❗ No id found for server ($server.hostname) error"
|
|
return ""
|
|
}
|
|
($res.stdout | default "")
|
|
}
|
|
export def aws_has_disable_stop [
|
|
server: record
|
|
id: string
|
|
] {
|
|
let instance_id = if ($id | is-empty) {
|
|
(aws_server_id $server)
|
|
} else { $id }
|
|
let res = (^aws ec2 describe-instance-attribute --instance-id $instance_id
|
|
--attribute disableApiStop --query "DisableApiStop.Value" --output text
|
|
err> (if $nu.os-info.name == "windows" { "NUL" } else { "/dev/null" }) | complete
|
|
)
|
|
if $res.exit_code != 0 or ($res.stdout | is-empty) {
|
|
print $"❗ No value found for server ($server.hostname) DisableApiStop "
|
|
return false
|
|
}
|
|
true
|
|
}
|