Add Oracle Aggregator and CCIP Integration
- Introduced Aggregator.sol for Chainlink-compatible oracle functionality, including round-based updates and access control. - Added OracleWithCCIP.sol to extend Aggregator with CCIP cross-chain messaging capabilities. - Created .gitmodules to include OpenZeppelin contracts as a submodule. - Developed a comprehensive deployment guide in NEXT_STEPS_COMPLETE_GUIDE.md for Phase 2 and smart contract deployment. - Implemented Vite configuration for the orchestration portal, supporting both Vue and React frameworks. - Added server-side logic for the Multi-Cloud Orchestration Portal, including API endpoints for environment management and monitoring. - Created scripts for resource import and usage validation across non-US regions. - Added tests for CCIP error handling and integration to ensure robust functionality. - Included various new files and directories for the orchestration portal and deployment scripts.
This commit is contained in:
23
scripts/lib/common/colors.sh
Executable file
23
scripts/lib/common/colors.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
# Common color definitions for scripts
|
||||
# Usage: source "$SCRIPT_DIR/lib/common/colors.sh"
|
||||
|
||||
# Color codes
|
||||
readonly RED='\033[0;31m'
|
||||
readonly GREEN='\033[0;32m'
|
||||
readonly YELLOW='\033[1;33m'
|
||||
readonly BLUE='\033[0;34m'
|
||||
readonly MAGENTA='\033[0;35m'
|
||||
readonly CYAN='\033[0;36m'
|
||||
readonly WHITE='\033[1;37m'
|
||||
readonly BOLD='\033[1m'
|
||||
readonly NC='\033[0m' # No Color
|
||||
|
||||
# Color functions for output
|
||||
color_red() { echo -e "${RED}$*${NC}"; }
|
||||
color_green() { echo -e "${GREEN}$*${NC}"; }
|
||||
color_yellow() { echo -e "${YELLOW}$*${NC}"; }
|
||||
color_blue() { echo -e "${BLUE}$*${NC}"; }
|
||||
color_cyan() { echo -e "${CYAN}$*${NC}"; }
|
||||
color_bold() { echo -e "${BOLD}$*${NC}"; }
|
||||
|
||||
45
scripts/lib/common/env.sh
Executable file
45
scripts/lib/common/env.sh
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
# Environment loader and profile support
|
||||
# Provides: load_env [--profile <name>] [--file <path>] and helpers
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
DEFAULT_ENV_FILE="${DEFAULT_ENV_FILE:-.env}"
|
||||
|
||||
load_env() {
|
||||
local profile=""; local file="$DEFAULT_ENV_FILE"; local opt
|
||||
while [[ $# -gt 0 ]]; do
|
||||
opt="$1"
|
||||
case "$opt" in
|
||||
--profile)
|
||||
profile="$2"; shift 2;;
|
||||
--file)
|
||||
file="$2"; shift 2;;
|
||||
*)
|
||||
break;;
|
||||
esac
|
||||
done
|
||||
if [ -f "$file" ]; then
|
||||
# shellcheck disable=SC2046
|
||||
set -a; . "$file"; set +a
|
||||
fi
|
||||
if [ -n "$profile" ]; then
|
||||
local pf="${file}.${profile}"
|
||||
if [ -f "$pf" ]; then
|
||||
# shellcheck disable=SC2046
|
||||
set -a; . "$pf"; set +a
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
require_env() {
|
||||
local name="$1"
|
||||
if [ -z "${!name:-}" ]; then
|
||||
echo "Missing required env: $name" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
current_profile() {
|
||||
echo "${ENV_PROFILE:-}"
|
||||
}
|
||||
58
scripts/lib/common/error-handling.sh
Executable file
58
scripts/lib/common/error-handling.sh
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env bash
|
||||
# Error handling functions
|
||||
# Usage: source "$SCRIPT_DIR/lib/common/error-handling.sh"
|
||||
|
||||
# Source logging if not already sourced
|
||||
[ -z "$(type -t log_error)" ] && source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/logging.sh"
|
||||
|
||||
# Error exit function
|
||||
error_exit() {
|
||||
local message="$1"
|
||||
local exit_code="${2:-1}"
|
||||
|
||||
log_error "$message"
|
||||
exit "$exit_code"
|
||||
}
|
||||
|
||||
# Cleanup function registry
|
||||
declare -a CLEANUP_FUNCTIONS=()
|
||||
|
||||
# Register cleanup function
|
||||
register_cleanup() {
|
||||
local func="$1"
|
||||
CLEANUP_FUNCTIONS+=("$func")
|
||||
}
|
||||
|
||||
# Execute cleanup functions
|
||||
cleanup_on_exit() {
|
||||
local exit_code=$?
|
||||
|
||||
for func in "${CLEANUP_FUNCTIONS[@]}"; do
|
||||
if type -t "$func" >/dev/null; then
|
||||
"$func" || true
|
||||
fi
|
||||
done
|
||||
|
||||
exit $exit_code
|
||||
}
|
||||
|
||||
# Setup error traps
|
||||
setup_error_traps() {
|
||||
# Trap ERR - command failures
|
||||
trap 'error_exit "Line $LINENO: Command failed: $BASH_COMMAND" $?' ERR
|
||||
|
||||
# Trap EXIT - cleanup
|
||||
trap 'cleanup_on_exit' EXIT
|
||||
|
||||
# Trap INT - Ctrl+C
|
||||
trap 'log_warn "Interrupted by user"; exit 130' INT
|
||||
|
||||
# Trap TERM - termination
|
||||
trap 'log_warn "Terminated"; exit 143' TERM
|
||||
}
|
||||
|
||||
# Check if error handling is enabled
|
||||
is_error_handling_enabled() {
|
||||
[[ $- == *e* ]]
|
||||
}
|
||||
|
||||
71
scripts/lib/common/logging.sh
Executable file
71
scripts/lib/common/logging.sh
Executable file
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env bash
|
||||
# Common logging functions for scripts
|
||||
# Usage: source "$SCRIPT_DIR/lib/common/logging.sh"
|
||||
|
||||
# Source colors if not already sourced
|
||||
[ -z "${RED:-}" ] && source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/colors.sh"
|
||||
|
||||
# Logging levels (idempotent & safe to re-source)
|
||||
: "${LOG_LEVEL_DEBUG:=0}"
|
||||
: "${LOG_LEVEL_INFO:=1}"
|
||||
: "${LOG_LEVEL_WARN:=2}"
|
||||
: "${LOG_LEVEL_ERROR:=0}"
|
||||
# Mark as readonly if not already
|
||||
readonly LOG_LEVEL_DEBUG 2>/dev/null || true
|
||||
readonly LOG_LEVEL_INFO 2>/dev/null || true
|
||||
readonly LOG_LEVEL_WARN 2>/dev/null || true
|
||||
readonly LOG_LEVEL_ERROR 2>/dev/null || true
|
||||
|
||||
# Default log level
|
||||
: "${LOG_LEVEL:=$LOG_LEVEL_INFO}"
|
||||
|
||||
# Logging functions
|
||||
log_debug() {
|
||||
[ "$LOG_LEVEL" -le "$LOG_LEVEL_DEBUG" ] && echo -e "${CYAN}[DEBUG]${NC} $*" >&2
|
||||
}
|
||||
|
||||
log_info() {
|
||||
[ "$LOG_LEVEL" -le "$LOG_LEVEL_INFO" ] && echo -e "${GREEN}[INFO]${NC} $*"
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
[ "$LOG_LEVEL" -le "$LOG_LEVEL_WARN" ] && echo -e "${YELLOW}[WARN]${NC} $*" >&2
|
||||
}
|
||||
|
||||
log_error() {
|
||||
[ "$LOG_LEVEL" -le "$LOG_LEVEL_ERROR" ] && echo -e "${RED}[ERROR]${NC} $*" >&2
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}✓${NC} $*"
|
||||
}
|
||||
|
||||
log_failure() {
|
||||
echo -e "${RED}✗${NC} $*"
|
||||
}
|
||||
|
||||
log_section() {
|
||||
local title="$1"
|
||||
echo ""
|
||||
echo -e "${BOLD}${BLUE}════════════════════════════════════════════════════════════════${NC}"
|
||||
echo -e "${BOLD}${BLUE} ${title}${NC}"
|
||||
echo -e "${BOLD}${BLUE}════════════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
log_subsection() {
|
||||
local title="$1"
|
||||
echo ""
|
||||
echo -e "${CYAN}${title}${NC}"
|
||||
echo "$(printf '─%.0s' {1..60})"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Print separator line
|
||||
print_separator() {
|
||||
local char="${1:-=}"
|
||||
local width="${2:-80}"
|
||||
printf "%.0s${char}" $(seq 1 "$width")
|
||||
echo
|
||||
}
|
||||
|
||||
48
scripts/lib/common/metadata.sh
Executable file
48
scripts/lib/common/metadata.sh
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
# Metadata and help utilities for scripts
|
||||
# Provides simple helpers to print script usage and header information.
|
||||
|
||||
# Print a standardized usage/help message using optional variables:
|
||||
# SCRIPT_NAME, SCRIPT_DESC, SCRIPT_USAGE, SCRIPT_OPTIONS, SCRIPT_ENVVARS, SCRIPT_REQUIREMENTS, SCRIPT_EXAMPLE
|
||||
script_usage() {
|
||||
local name="${SCRIPT_NAME:-${0##*/}}"
|
||||
echo "${name}"
|
||||
[ -n "${SCRIPT_DESC:-}" ] && echo "Description: ${SCRIPT_DESC}"
|
||||
if [ -n "${SCRIPT_USAGE:-}" ]; then
|
||||
echo "Usage: ${SCRIPT_USAGE}"
|
||||
else
|
||||
echo "Usage: ${name} [options]"
|
||||
fi
|
||||
if [ -n "${SCRIPT_OPTIONS:-}" ]; then
|
||||
echo
|
||||
echo "Options:"
|
||||
# shellcheck disable=SC2001
|
||||
echo "${SCRIPT_OPTIONS}" | sed 's/^/ /'
|
||||
fi
|
||||
if [ -n "${SCRIPT_ENVVARS:-}" ]; then
|
||||
echo
|
||||
echo "Environment:"
|
||||
# shellcheck disable=SC2001
|
||||
echo "${SCRIPT_ENVVARS}" | sed 's/^/ /'
|
||||
fi
|
||||
if [ -n "${SCRIPT_REQUIREMENTS:-}" ]; then
|
||||
echo
|
||||
echo "Requires: ${SCRIPT_REQUIREMENTS}"
|
||||
fi
|
||||
if [ -n "${SCRIPT_EXAMPLE:-}" ]; then
|
||||
echo
|
||||
echo "Example:"
|
||||
# shellcheck disable=SC2001
|
||||
echo "${SCRIPT_EXAMPLE}" | sed 's/^/ /'
|
||||
fi
|
||||
}
|
||||
|
||||
# Handle -h/--help; call after sourcing init and setting metadata vars
|
||||
handle_help() {
|
||||
case "${1:-}" in
|
||||
-h|--help)
|
||||
script_usage
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
}
|
||||
25
scripts/lib/common/paths.sh
Executable file
25
scripts/lib/common/paths.sh
Executable file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
# Common path definitions for scripts
|
||||
# Usage: source "$SCRIPT_DIR/lib/common/paths.sh"
|
||||
|
||||
# Get script directory (works even when sourced)
|
||||
if [ -z "${SCRIPT_DIR:-}" ]; then
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-}")" && pwd)"
|
||||
# If sourced from another script, try to get the calling script's directory
|
||||
if [ "${BASH_SOURCE[0]:-}" = "${BASH_SOURCE[1]:-}" ]; then
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[1]:-}")" && pwd)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Project root (two levels up from scripts/)
|
||||
if [ -z "${PROJECT_ROOT:-}" ]; then
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||
fi
|
||||
|
||||
# Common directories
|
||||
readonly CONFIG_DIR="${PROJECT_ROOT}/config"
|
||||
readonly KEYS_DIR="${PROJECT_ROOT}/keys"
|
||||
readonly SCRIPTS_DIR="${PROJECT_ROOT}/scripts"
|
||||
readonly TERRAFORM_DIR="${PROJECT_ROOT}/terraform"
|
||||
readonly DOCS_DIR="${PROJECT_ROOT}/docs"
|
||||
|
||||
113
scripts/lib/common/retry.sh
Executable file
113
scripts/lib/common/retry.sh
Executable file
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env bash
|
||||
# Retry functions with exponential backoff
|
||||
# Usage: source "$SCRIPT_DIR/lib/common/retry.sh"
|
||||
|
||||
# Source logging if not already sourced
|
||||
[ -z "$(type -t log_info)" ] && source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/logging.sh"
|
||||
|
||||
# Retry a command with exponential backoff
|
||||
# Usage: retry_command <max_attempts> <delay> <command> [args...]
|
||||
retry_command() {
|
||||
local max_attempts="$1"
|
||||
local base_delay="$2"
|
||||
shift 2
|
||||
local command=("$@")
|
||||
|
||||
local attempt=1
|
||||
local delay="$base_delay"
|
||||
|
||||
while [ $attempt -le $max_attempts ]; do
|
||||
log_info "Attempt $attempt/$max_attempts: ${command[*]}"
|
||||
|
||||
if "${command[@]}"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ $attempt -lt $max_attempts ]; then
|
||||
log_warn "Command failed, retrying in ${delay}s..."
|
||||
sleep "$delay"
|
||||
delay=$((delay * 2)) # Exponential backoff
|
||||
fi
|
||||
|
||||
((attempt++)) || true
|
||||
done
|
||||
|
||||
log_error "Command failed after $max_attempts attempts: ${command[*]}"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Retry a function with exponential backoff
|
||||
# Usage: retry_function <max_attempts> <delay> <function_name> [args...]
|
||||
retry_function() {
|
||||
local max_attempts="$1"
|
||||
local base_delay="$2"
|
||||
local func_name="$3"
|
||||
shift 3
|
||||
local args=("$@")
|
||||
|
||||
local attempt=1
|
||||
local delay="$base_delay"
|
||||
|
||||
while [ $attempt -le $max_attempts ]; do
|
||||
log_info "Attempt $attempt/$max_attempts: $func_name"
|
||||
|
||||
if "$func_name" "${args[@]}"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ $attempt -lt $max_attempts ]; then
|
||||
log_warn "Function failed, retrying in ${delay}s..."
|
||||
sleep "$delay"
|
||||
delay=$((delay * 2)) # Exponential backoff
|
||||
fi
|
||||
|
||||
((attempt++)) || true
|
||||
done
|
||||
|
||||
log_error "Function failed after $max_attempts attempts: $func_name"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Wait for a condition to be true
|
||||
# Usage: wait_for_condition <timeout> <interval> <condition_command>
|
||||
wait_for_condition() {
|
||||
local timeout="$1"
|
||||
local interval="$2"
|
||||
shift 2
|
||||
local condition=("$@")
|
||||
|
||||
local elapsed=0
|
||||
|
||||
while [ $elapsed -lt $timeout ]; do
|
||||
if "${condition[@]}"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
sleep "$interval"
|
||||
elapsed=$((elapsed + interval))
|
||||
done
|
||||
|
||||
log_error "Condition not met within ${timeout}s: ${condition[*]}"
|
||||
return 1
|
||||
}
|
||||
|
||||
# Wait for a service to be ready
|
||||
# Usage: wait_for_service <url> <timeout> <interval>
|
||||
wait_for_service() {
|
||||
local url="$1"
|
||||
local timeout="${2:-60}"
|
||||
local interval="${3:-5}"
|
||||
|
||||
wait_for_condition "$timeout" "$interval" curl -sf "$url" >/dev/null
|
||||
}
|
||||
|
||||
# Wait for a file to exist
|
||||
# Usage: wait_for_file <file_path> <timeout> <interval>
|
||||
wait_for_file() {
|
||||
local file_path="$1"
|
||||
local timeout="${2:-60}"
|
||||
local interval="${3:-5}"
|
||||
|
||||
wait_for_condition "$timeout" "$interval" test -f "$file_path"
|
||||
}
|
||||
|
||||
81
scripts/lib/common/utils.sh
Executable file
81
scripts/lib/common/utils.sh
Executable file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env bash
|
||||
# Common utility functions
|
||||
# Usage: source "$SCRIPT_DIR/lib/common/utils.sh"
|
||||
|
||||
# Source colors if not already sourced
|
||||
[ -z "${RED:-}" ] && source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/colors.sh"
|
||||
|
||||
# Check if command exists
|
||||
command_exists() {
|
||||
command -v "$1" &> /dev/null
|
||||
}
|
||||
|
||||
# Require command (exits if not found)
|
||||
require_command() {
|
||||
local cmd="$1"
|
||||
local install_hint="${2:-}"
|
||||
|
||||
if ! command_exists "$cmd"; then
|
||||
echo -e "${RED}Error: $cmd not found${NC}" >&2
|
||||
[ -n "$install_hint" ] && echo -e "${YELLOW}Hint: $install_hint${NC}" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Confirm action
|
||||
confirm() {
|
||||
local prompt="${1:-Are you sure?}"
|
||||
local default="${2:-n}"
|
||||
|
||||
if [ "$default" = "y" ]; then
|
||||
local options="[Y/n]"
|
||||
else
|
||||
local options="[y/N]"
|
||||
fi
|
||||
|
||||
read -p "$(echo -e "${YELLOW}${prompt} ${options}: ${NC}")" -n 1 -r
|
||||
echo
|
||||
|
||||
if [[ $REPLY =~ ^[Yy]$ ]] || ([ "$default" = "y" ] && [[ -z $REPLY ]]); then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Wait for user input
|
||||
press_enter_to_continue() {
|
||||
read -p "$(echo -e "${CYAN}Press Enter to continue...${NC}")"
|
||||
}
|
||||
|
||||
# Print header box
|
||||
print_header() {
|
||||
local title="$1"
|
||||
local width="${2:-80}"
|
||||
|
||||
echo "╔$(printf '═%.0s' $(seq 1 $((width-2))))╗"
|
||||
printf "║ %-${width-4}s ║\n" "$title"
|
||||
echo "╚$(printf '═%.0s' $(seq 1 $((width-2))))╝"
|
||||
echo
|
||||
}
|
||||
|
||||
# Print centered text
|
||||
print_centered() {
|
||||
local text="$1"
|
||||
local width="${2:-80}"
|
||||
printf "%*s\n" $(((${#text} + width) / 2)) "$text"
|
||||
}
|
||||
|
||||
# Trim whitespace
|
||||
trim() {
|
||||
local var="$*"
|
||||
var="${var#"${var%%[![:space:]]*}"}" # Remove leading whitespace
|
||||
var="${var%"${var##*[![:space:]]}"}" # Remove trailing whitespace
|
||||
echo "$var"
|
||||
}
|
||||
|
||||
# Check if running in dry-run mode
|
||||
is_dry_run() {
|
||||
[ "${DRY_RUN:-0}" = "1" ] || [ "${DRY_RUN:-0}" = "true" ]
|
||||
}
|
||||
|
||||
211
scripts/lib/common/validation.sh
Executable file
211
scripts/lib/common/validation.sh
Executable file
@@ -0,0 +1,211 @@
|
||||
#!/usr/bin/env bash
|
||||
# Validation functions for scripts
|
||||
# Usage: source "$SCRIPT_DIR/lib/common/validation.sh"
|
||||
|
||||
# Source colors and logging if not already sourced
|
||||
[ -z "${RED:-}" ] && source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/colors.sh"
|
||||
[ -z "$(type -t log_error)" ] && source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/logging.sh"
|
||||
|
||||
# Validate required environment variable
|
||||
validate_required() {
|
||||
local var_name="$1"
|
||||
local var_value="${!var_name:-}"
|
||||
|
||||
if [ -z "$var_value" ]; then
|
||||
log_error "$var_name is required but not set"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Validate file exists
|
||||
validate_file_exists() {
|
||||
local file_path="$1"
|
||||
local description="${2:-File}"
|
||||
|
||||
if [ ! -f "$file_path" ]; then
|
||||
log_error "$description not found: $file_path"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Validate directory exists
|
||||
validate_directory_exists() {
|
||||
local dir_path="$1"
|
||||
local description="${2:-Directory}"
|
||||
|
||||
if [ ! -d "$dir_path" ]; then
|
||||
log_error "$description not found: $dir_path"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Validate JSON file
|
||||
validate_json() {
|
||||
local json_file="$1"
|
||||
|
||||
if ! python3 -m json.tool "$json_file" >/dev/null 2>&1; then
|
||||
log_error "Invalid JSON file: $json_file"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Validate YAML file
|
||||
validate_yaml() {
|
||||
local yaml_file="$1"
|
||||
|
||||
if ! command -v yamllint &>/dev/null; then
|
||||
log_warn "yamllint not installed, skipping YAML validation"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! yamllint "$yaml_file" >/dev/null 2>&1; then
|
||||
log_error "Invalid YAML file: $yaml_file"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Validate TOML file
|
||||
validate_toml() {
|
||||
local toml_file="$1"
|
||||
|
||||
if ! python3 -c "import tomllib; open('$toml_file', 'rb').read()" 2>/dev/null; then
|
||||
log_error "Invalid TOML file: $toml_file"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Validate URL format
|
||||
validate_url() {
|
||||
local url="$1"
|
||||
|
||||
if [[ ! "$url" =~ ^https?:// ]]; then
|
||||
log_error "Invalid URL format: $url"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Validate IP address
|
||||
validate_ip() {
|
||||
local ip="$1"
|
||||
|
||||
if [[ ! "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
|
||||
log_error "Invalid IP address format: $ip"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check each octet is 0-255
|
||||
IFS='.' read -ra ADDR <<< "$ip"
|
||||
for i in "${ADDR[@]}"; do
|
||||
if [ "$i" -gt 255 ] || [ "$i" -lt 0 ]; then
|
||||
log_error "Invalid IP address: $ip (octet out of range)"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
# Validate port number
|
||||
validate_port() {
|
||||
local port="$1"
|
||||
|
||||
if [[ ! "$port" =~ ^[0-9]+$ ]] || [ "$port" -lt 1 ] || [ "$port" -gt 65535 ]; then
|
||||
log_error "Invalid port number: $port (must be 1-65535)"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Validate Ethereum address
|
||||
validate_eth_address() {
|
||||
local address="$1"
|
||||
|
||||
if [[ ! "$address" =~ ^0x[0-9a-fA-F]{40}$ ]]; then
|
||||
log_error "Invalid Ethereum address format: $address"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Validate chain ID
|
||||
validate_chain_id() {
|
||||
local chain_id="$1"
|
||||
|
||||
if [[ ! "$chain_id" =~ ^[0-9]+$ ]] || [ "$chain_id" -lt 1 ]; then
|
||||
log_error "Invalid chain ID: $chain_id"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Validate non-empty string
|
||||
validate_non_empty() {
|
||||
local value="$1"
|
||||
local name="${2:-Value}"
|
||||
|
||||
if [ -z "$value" ]; then
|
||||
log_error "$name cannot be empty"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Validate numeric value
|
||||
validate_numeric() {
|
||||
local value="$1"
|
||||
local name="${2:-Value}"
|
||||
|
||||
if [[ ! "$value" =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
|
||||
log_error "$name must be numeric: $value"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Validate positive number
|
||||
validate_positive() {
|
||||
local value="$1"
|
||||
local name="${2:-Value}"
|
||||
|
||||
if ! validate_numeric "$value" "$name"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if (( $(echo "$value <= 0" | bc -l) )); then
|
||||
log_error "$name must be positive: $value"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Validate command exists
|
||||
validate_command() {
|
||||
local cmd="$1"
|
||||
|
||||
if ! command -v "$cmd" &>/dev/null; then
|
||||
log_error "Command not found: $cmd"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Validate multiple requirements
|
||||
validate_all() {
|
||||
local failed=0
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
if ! "$@"; then
|
||||
failed=1
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
return $failed
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user