refactor: Extract helpers from complex OVH and Latitude functions (#384)

OVH: Extract _ovh_extract_public_ipv4() and _ovh_extract_status() from
wait_for_ovh_instance() to reduce inline Python and improve readability.

Latitude: Extract _latitude_extract_error(), _latitude_get_ssh_key_ids(),
and _latitude_build_server_body() from create_server() and
latitude_register_ssh_key(). Deduplicates error extraction logic used in
two places.

Agent: complexity-hunter

Co-authored-by: A <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
A 2026-02-11 01:00:42 -08:00 committed by GitHub
parent 928062b0f8
commit 6debf956a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 79 additions and 62 deletions

View file

@ -101,6 +101,56 @@ print(projects[0]['id'])
echo "$project_id"
}
# Extract first error detail from Latitude.sh JSON:API error response
_latitude_extract_error() {
python3 -c "
import json,sys
try:
d=json.loads(sys.stdin.read())
errors = d.get('errors', [])
if isinstance(errors, list) and errors:
print(errors[0].get('detail', errors[0].get('title', 'Unknown error')))
else:
print('Unknown error')
except: print(sys.stdin.read())
" 2>/dev/null || cat
}
# Get all SSH key IDs from Latitude.sh account
_latitude_get_ssh_key_ids() {
local ssh_keys_response
ssh_keys_response=$(latitude_api GET "/ssh_keys")
echo "$ssh_keys_response" | python3 -c "
import json, sys
data = json.loads(sys.stdin.read())
ids = [k['id'] for k in data.get('data', [])]
print(json.dumps(ids))
" 2>/dev/null || echo "[]"
}
# Build JSON:API request body for Latitude.sh server creation
# $1=hostname $2=plan $3=site $4=os $5=project_id $6=ssh_key_ids_json
_latitude_build_server_body() {
local hostname="$1" plan="$2" site="$3" os="$4" project_id="$5" ssh_key_ids="$6"
python3 -c "
import json
body = {
'data': {
'type': 'servers',
'attributes': {
'hostname': '$hostname',
'plan': '$plan',
'site': '$site',
'operating_system': '$os',
'project': '$project_id',
'ssh_keys': $ssh_key_ids
}
}
}
print(json.dumps(body))
"
}
# Check if SSH key is registered with Latitude.sh
latitude_check_ssh_key() {
local fingerprint="$1"
@ -140,17 +190,7 @@ print(json.dumps(body))
fi
local error_msg
error_msg=$(echo "$response" | python3 -c "
import json,sys
try:
d=json.loads(sys.stdin.read())
errors = d.get('errors', [])
if isinstance(errors, list) and errors:
print(errors[0].get('detail', errors[0].get('title', 'Unknown error')))
else:
print('Unknown error')
except: print(sys.stdin.read())
" 2>/dev/null || echo "$response")
error_msg=$(echo "$response" | _latitude_extract_error)
log_error "API Error: $error_msg"
log_error ""
log_error "Common causes:"
@ -196,34 +236,11 @@ create_server() {
project_id=$(get_latitude_project_id) || return 1
# Get all SSH key IDs
local ssh_keys_response
ssh_keys_response=$(latitude_api GET "/ssh_keys")
local ssh_key_ids
ssh_key_ids=$(echo "$ssh_keys_response" | python3 -c "
import json, sys
data = json.loads(sys.stdin.read())
ids = [k['id'] for k in data.get('data', [])]
print(json.dumps(ids))
" 2>/dev/null || echo "[]")
ssh_key_ids=$(_latitude_get_ssh_key_ids)
local body
body=$(python3 -c "
import json
body = {
'data': {
'type': 'servers',
'attributes': {
'hostname': '$hostname',
'plan': '$plan',
'site': '$site',
'operating_system': '$os',
'project': '$project_id',
'ssh_keys': $ssh_key_ids
}
}
}
print(json.dumps(body))
")
body=$(_latitude_build_server_body "$hostname" "$plan" "$site" "$os" "$project_id" "$ssh_key_ids")
local response
response=$(latitude_api POST "/servers" "$body")
@ -232,17 +249,7 @@ print(json.dumps(body))
if ! echo "$response" | python3 -c "import json,sys; d=json.loads(sys.stdin.read()); sys.exit(0 if 'data' in d else 1)" 2>/dev/null; then
log_error "Failed to create Latitude.sh server"
local error_msg
error_msg=$(echo "$response" | python3 -c "
import json,sys
try:
d=json.loads(sys.stdin.read())
errors = d.get('errors', [])
if isinstance(errors, list) and errors:
print(errors[0].get('detail', errors[0].get('title', 'Unknown error')))
else:
print('Unknown error')
except: print(sys.stdin.read())
" 2>/dev/null || echo "$response")
error_msg=$(echo "$response" | _latitude_extract_error)
log_error "API Error: $error_msg"
log_error ""
log_error "Common issues:"

View file

@ -417,6 +417,29 @@ create_ovh_instance() {
log_info "Instance created: ID=$OVH_INSTANCE_ID"
}
# Extract public IPv4 address from OVH instance JSON response
# Prefers public type; falls back to first IPv4
_ovh_extract_public_ipv4() {
python3 -c "
import json, sys
data = json.loads(sys.stdin.read())
for addr in data.get('ipAddresses', []):
if addr.get('version', 0) == 4 and addr.get('type', '') == 'public':
print(addr['ip'])
sys.exit(0)
for addr in data.get('ipAddresses', []):
if addr.get('version', 0) == 4:
print(addr['ip'])
sys.exit(0)
print('')
"
}
# Extract instance status from OVH API response
_ovh_extract_status() {
python3 -c "import json,sys; print(json.loads(sys.stdin.read()).get('status',''))" 2>/dev/null || echo ""
}
# Wait for OVH instance to be ACTIVE and get IP
wait_for_ovh_instance() {
local instance_id="$1"
@ -431,23 +454,10 @@ wait_for_ovh_instance() {
response=$(ovh_api_call GET "/cloud/project/${OVH_PROJECT_ID}/instance/${instance_id}")
local status
status=$(echo "$response" | python3 -c "import json,sys; print(json.loads(sys.stdin.read()).get('status',''))" 2>/dev/null || echo "")
status=$(echo "$response" | _ovh_extract_status)
if [[ "${status}" == "ACTIVE" ]]; then
OVH_SERVER_IP=$(echo "$response" | python3 -c "
import json, sys
data = json.loads(sys.stdin.read())
for addr in data.get('ipAddresses', []):
if addr.get('version', 0) == 4 and addr.get('type', '') == 'public':
print(addr['ip'])
sys.exit(0)
# Fallback: first IPv4
for addr in data.get('ipAddresses', []):
if addr.get('version', 0) == 4:
print(addr['ip'])
sys.exit(0)
print('')
")
OVH_SERVER_IP=$(echo "$response" | _ovh_extract_public_ipv4)
export OVH_SERVER_IP
if [[ -n "${OVH_SERVER_IP}" ]]; then
log_info "Instance active: IP=$OVH_SERVER_IP"