bolt/vm_automation/ubuntu/tasks/validate_vm_parameters.sh

232 lines
7.6 KiB
Bash
Executable File

#!/bin/bash
# Task to validate VM parameters (ubuntu::validate_vm_parameters)
# Array to store warnings
WARNINGS=()
# Function to output status messages in JSON format
output_status() {
local status=$1
local message=$2
local warnings_json=""
if [ ${#WARNINGS[@]} -gt 0 ]; then
warnings_json=", \"warnings\": ["
for i in "${!WARNINGS[@]}"; do
if [ $i -gt 0 ]; then
warnings_json="${warnings_json}, "
fi
warnings_json="${warnings_json}\"${WARNINGS[$i]}\""
done
warnings_json="${warnings_json}]"
fi
echo "{ \"status\": \"$status\", \"message\": \"$message\"${warnings_json} }"
if [ "$status" = "error" ]; then
exit 1
fi
}
# Function to output warning messages
output_warning() {
local message=$1
WARNINGS+=("$message")
}
# Function to get network portion of IP
get_network_from_ip() {
local ip=$1
echo "$ip" | cut -d'.' -f1-3
}
# Function to validate network relationships
validate_network_relationships() {
local network=$1
local ip_with_cidr=$2
local gateway_ip=$3
local staging_ip=$4
# Extract IP from CIDR notation
local ip=$(echo "$ip_with_cidr" | cut -d'/' -f1)
local cidr=$(echo "$ip_with_cidr" | cut -d'/' -f2)
# Get network portions
local ip_network=$(get_network_from_ip "$ip")
local gateway_network=$(get_network_from_ip "$gateway_ip")
# Check CIDR is /24
if [[ "$cidr" != "24" ]]; then
output_warning "Network mask /24 is typical, found /$cidr"
fi
# Check gateway ends in .1
if [[ ! "$gateway_ip" =~ \.1$ ]]; then
output_warning "Gateway typically ends in .1, found $gateway_ip"
fi
# Validate network relationships
if [[ "$ip_network" != "$gateway_network" ]]; then
output_status "error" "IP ($ip) and gateway ($gateway_ip) must be in the same network"
fi
# Network-specific validations
if [[ "$network" == "wan-verizon" ]]; then
if [[ ! "$ip_network" =~ ^100\.40\.223$ ]]; then
output_warning "wan-verizon network typically uses 100.40.223.0/24 range, but got ${ip_network}.0/${cidr}"
fi
if [[ "$gateway_ip" != "100.40.223.1" ]]; then
output_warning "wan-verizon network typically uses 100.40.223.1 as gateway, but got ${gateway_ip}"
fi
if [[ "$staging_ip" != "public" ]]; then
output_warning "wan-verizon network typically uses 'public' for staging_ip, but got '${staging_ip}'"
fi
elif [[ "$network" == "moeny-internal" ]]; then
if [[ ! "$ip_network" =~ ^10\.44\.0$ ]]; then
output_warning "moeny-internal network typically uses 10.44.0.0/24 range, but got ${ip_network}.0/${cidr}"
fi
if [[ "$gateway_ip" != "10.44.0.1" ]]; then
output_warning "moeny-internal network typically uses 10.44.0.1 as gateway, but got ${gateway_ip}"
fi
if [[ "$staging_ip" != "internal" ]]; then
output_warning "moeny-internal network typically uses 'internal' for staging_ip, but got '${staging_ip}'"
fi
fi
}
# Function to validate target host
validate_target_host() {
local host=$1
if [[ "$host" != "vortex" && "$host" != "astrocore" ]]; then
output_status "error" "Invalid target_host '$host'. Must be either vortex or astrocore"
fi
}
# Function to validate hostname format
validate_hostname() {
local hostname=$1
local param_name=$2
if ! echo "$hostname" | grep -qE '^[a-zA-Z0-9-]+$'; then
output_status "error" "Invalid $param_name '$hostname'. Must contain only alphanumeric characters and hyphens."
fi
}
# Function to validate network
validate_network() {
local network=$1
if [[ "$network" != "wan-verizon" && "$network" != "moeny-internal" ]]; then
output_status "error" "Invalid network '$network'. Must be either wan-verizon or moeny-internal"
fi
}
# Function to validate IP with CIDR
validate_ip_with_cidr() {
local ip_cidr=$1
local ip=$(echo "$ip_cidr" | cut -d'/' -f1)
local cidr=$(echo "$ip_cidr" | cut -d'/' -f2)
# Validate IP
if ! echo "$ip" | grep -qE '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'; then
output_status "error" "Invalid IP address format in ip_with_cidr '$ip_cidr'"
fi
# Validate CIDR
if ! [[ "$cidr" =~ ^[0-9]+$ ]] || [ "$cidr" -lt 0 ] || [ "$cidr" -gt 32 ]; then
output_status "error" "Invalid CIDR prefix in ip_with_cidr '$ip_cidr'. Must be between 0 and 32."
fi
}
# Function to validate IP address
validate_ip() {
local ip=$1
local param_name=$2
if ! echo "$ip" | grep -qE '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'; then
output_status "error" "Invalid $param_name IP address: '$ip'"
fi
}
# Function to validate ISO path
validate_iso_path() {
local path=$1
if [[ ! "$path" =~ ^/.+\.iso$ ]]; then
output_status "error" "Invalid iso_path '$path'. Must be absolute path ending in .iso"
fi
# Extract just the filename from the path
local filename=$(basename "$path")
if [[ ! "$filename" =~ ^ubuntu ]]; then
output_warning "ISO filename ('${filename}') should typically begin with 'ubuntu'"
fi
}
# Function to validate staging IP
validate_staging_ip() {
local staging_ip=$1
if [[ "$staging_ip" != "public" && "$staging_ip" != "internal" ]]; then
output_status "error" "Invalid staging_ip '$staging_ip'. Must be either public or internal"
fi
}
# Function to validate positive integer
validate_positive_integer() {
local value=$1
local name=$2
if ! [[ "$value" =~ ^[0-9]+$ ]] || [ "$value" -le 0 ]; then
output_status "error" "Invalid $name '$value'. Must be a positive integer."
fi
}
# Function to validate disk path
validate_disk_path() {
local path=$1
if [[ ! "$path" =~ ^/ ]]; then
output_status "error" "Invalid disk_path '$path'. Must be an absolute path."
fi
}
# Function to validate OS variant
validate_os_variant() {
local variant=$1
if ! echo "$variant" | grep -qE '^ubuntu[0-9]{2}\.[0-9]{2}$'; then
output_status "error" "Invalid os_variant '$variant'. Must be in format 'ubuntuXX.XX' (e.g. ubuntu22.04)"
fi
}
# Function to validate name relationships
validate_name_relationships() {
local vm_name=$1
local hostname=$2
if [[ "$vm_name" != "$hostname" ]]; then
output_warning "vm_name ('${vm_name}') typically matches hostname ('${hostname}')"
fi
}
# Parse JSON input from PT_* environment variables
validate_target_host "$PT_target_host"
validate_hostname "$PT_vm_name" "vm_name"
validate_hostname "$PT_hostname" "hostname"
# Validate name relationships
validate_name_relationships "$PT_vm_name" "$PT_hostname"
validate_network "$PT_network"
validate_ip_with_cidr "$PT_ip_with_cidr"
validate_ip "$PT_gateway_ip" "gateway_ip"
validate_iso_path "$PT_iso_path"
validate_staging_ip "$PT_staging_ip"
validate_hostname "$PT_dns_hostname" "dns_hostname"
validate_positive_integer "$PT_dns_ttl" "dns_ttl"
validate_positive_integer "$PT_ram" "RAM"
validate_positive_integer "$PT_vcpus" "vCPUs"
validate_positive_integer "$PT_disk_size" "disk_size"
validate_disk_path "$PT_disk_path"
validate_os_variant "$PT_os_variant"
validate_ip "$PT_nameserver1" "primary nameserver"
validate_ip "$PT_nameserver2" "secondary nameserver"
validate_ip "$PT_nameserver3" "tertiary nameserver"
# Validate network relationships after individual validations pass
validate_network_relationships "$PT_network" "$PT_ip_with_cidr" "$PT_gateway_ip" "$PT_staging_ip"
# If we get here, all validations passed
output_status "success" "All parameters validated successfully"