#!/bin/bash # Task to validate VM parameters (alpine::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") local staging_network=$(get_network_from_ip "$staging_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 if [[ "$ip_network" != "$staging_network" ]]; then output_warning "staging IP ($staging_ip) is in a different network than primary IP ($ip)" 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 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 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" =~ ^alpine ]]; then output_warning "ISO filename ('${filename}') should typically begin with 'alpine'" 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 '^alpinelinux[0-9]+\.[0-9]+$'; then output_status "error" "Invalid os_variant '$variant'. Must be in format 'alpinelinuxX.XX' (e.g. alpinelinux3.20)" 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_ip "$PT_staging_ip" "staging_ip" # Validate network relationships after individual validations pass validate_network_relationships "$PT_network" "$PT_ip_with_cidr" "$PT_gateway_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" # If we get here, all validations passed output_status "success" "All parameters validated successfully"