a1a17e81a1
Includes updated JS challenge scripts with Claude-User whitelist, same-site referer bypass, Blackbox-Exporter allowed bot, and all new exporters, cheat sheets, and automation scripts.
574 lines
22 KiB
Bash
Executable File
574 lines
22 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
#########################################################################################
|
|
#### ssm-fleet-runner.sh — Run commands across EC2 instances via AWS Systems Manager ####
|
|
#### Supports tag-based targeting, output collection, patch scanning, and inventory ####
|
|
#### Requires: bash 4+, aws-cli v2, jq ####
|
|
#### ####
|
|
#### Author: Phil Connor ####
|
|
#### Contact: contact@mylinux.work ####
|
|
#### License: MIT ####
|
|
#### Version 1.01 ####
|
|
#### ####
|
|
#### Usage: ####
|
|
#### ./ssm-fleet-runner.sh --run "uptime" --tag Environment=production ####
|
|
#### ####
|
|
#### See --help for all options. ####
|
|
#########################################################################################
|
|
|
|
set -euo pipefail
|
|
|
|
# ── Defaults ──────────────────────────────────────────────────────────
|
|
AWS_REGION="${AWS_REGION:-}"
|
|
INSTANCE_IDS="${INSTANCE_IDS:-}"
|
|
SSM_TAG_KEY="${SSM_TAG_KEY:-}"
|
|
SSM_TAG_VALUE="${SSM_TAG_VALUE:-}"
|
|
SSM_TIMEOUT="${SSM_TIMEOUT:-600}"
|
|
SSM_MAX_CONCURRENCY="${SSM_MAX_CONCURRENCY:-50}"
|
|
OUTPUT_FORMAT="${OUTPUT_FORMAT:-text}"
|
|
OUTPUT_DIR="${OUTPUT_DIR:-}"
|
|
VERBOSE="${VERBOSE:-false}"
|
|
COLOR="${COLOR:-auto}"
|
|
|
|
# ── State ─────────────────────────────────────────────────────────────
|
|
SCRIPT_NAME="$(basename "$0")"
|
|
readonly SCRIPT_NAME
|
|
RUN_MODE=""
|
|
COMMAND_TEXT=""
|
|
SCRIPT_FILE=""
|
|
START_TIME=""
|
|
ALL_INSTANCES="false"
|
|
|
|
# ── Colors ────────────────────────────────────────────────────────────
|
|
setup_colors() {
|
|
if [[ "$COLOR" == "never" ]]; then
|
|
RED="" GREEN="" YELLOW="" BLUE="" BOLD="" DIM="" RESET=""
|
|
return
|
|
fi
|
|
if [[ "$COLOR" == "always" ]] || [[ -t 1 ]]; then
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[0;33m'
|
|
BLUE='\033[0;34m'
|
|
BOLD='\033[1m'
|
|
DIM='\033[2m'
|
|
RESET='\033[0m'
|
|
else
|
|
RED="" GREEN="" YELLOW="" BLUE="" BOLD="" DIM="" RESET=""
|
|
fi
|
|
}
|
|
|
|
# ── Logging ───────────────────────────────────────────────────────────
|
|
log() { echo -e "${BLUE}[INFO]${RESET} $*"; }
|
|
warn() { echo -e "${YELLOW}[WARN]${RESET} $*" >&2; }
|
|
err() { echo -e "${RED}[ERROR]${RESET} $*" >&2; }
|
|
verbose() { if [[ "$VERBOSE" == "true" ]]; then echo -e "${DIM}[DEBUG]${RESET} $*"; fi; }
|
|
|
|
die() { err "$*"; exit 1; }
|
|
|
|
elapsed() {
|
|
local end_time
|
|
end_time=$(date +%s)
|
|
echo "$(( end_time - START_TIME ))s"
|
|
}
|
|
|
|
# ── AWS CLI wrapper ───────────────────────────────────────────────────
|
|
aws_cmd() {
|
|
local args=("$@")
|
|
[[ -n "$AWS_REGION" ]] && args+=(--region "$AWS_REGION")
|
|
verbose "aws ${args[*]}"
|
|
aws "${args[@]}"
|
|
}
|
|
|
|
# ── Dependency check ──────────────────────────────────────────────────
|
|
check_deps() {
|
|
for cmd in aws jq; do
|
|
if ! command -v "$cmd" &>/dev/null; then
|
|
die "${cmd} is required but not installed"
|
|
fi
|
|
done
|
|
|
|
if ! aws sts get-caller-identity &>/dev/null; then
|
|
die "AWS credentials not configured or expired"
|
|
fi
|
|
|
|
if [[ -z "$AWS_REGION" ]]; then
|
|
AWS_REGION=$(aws configure get region 2>/dev/null || echo "")
|
|
if [[ -z "$AWS_REGION" ]]; then
|
|
die "AWS_REGION is required (set via env var or aws configure)"
|
|
fi
|
|
fi
|
|
|
|
verbose "Using region: ${AWS_REGION}"
|
|
}
|
|
|
|
# ── Resolve target instances ─────────────────────────────────────────
|
|
resolve_targets() {
|
|
local targets=()
|
|
|
|
if [[ -n "$INSTANCE_IDS" ]]; then
|
|
IFS=',' read -ra targets <<< "$INSTANCE_IDS"
|
|
echo "${targets[@]}"
|
|
return
|
|
fi
|
|
|
|
if [[ -n "$SSM_TAG_KEY" ]]; then
|
|
aws_cmd ssm describe-instance-information \
|
|
--filters "Key=tag:${SSM_TAG_KEY},Values=${SSM_TAG_VALUE:-*}" \
|
|
--query 'InstanceInformationList[*].InstanceId' \
|
|
--output text 2>/dev/null | tr '\t' ' '
|
|
return
|
|
fi
|
|
|
|
if [[ "$ALL_INSTANCES" == "true" ]]; then
|
|
aws_cmd ssm describe-instance-information \
|
|
--query 'InstanceInformationList[*].InstanceId' \
|
|
--output text 2>/dev/null | tr '\t' ' '
|
|
return
|
|
fi
|
|
|
|
die "No targets specified. Use --instance-ids, --tag, or --all-instances"
|
|
}
|
|
|
|
# ── Get instance name ────────────────────────────────────────────────
|
|
get_instance_name() {
|
|
local instance_id="$1"
|
|
# shellcheck disable=SC2016
|
|
aws_cmd ec2 describe-instances \
|
|
--instance-ids "$instance_id" \
|
|
--query 'Reservations[0].Instances[0].Tags[?Key==`Name`].Value | [0]' \
|
|
--output text 2>/dev/null || echo "N/A"
|
|
}
|
|
|
|
# ══════════════════════════════════════════════════════════════════════
|
|
# RUN COMMAND MODE
|
|
# ══════════════════════════════════════════════════════════════════════
|
|
|
|
do_run() {
|
|
local command_to_run="$COMMAND_TEXT"
|
|
|
|
if [[ "$RUN_MODE" == "script" ]]; then
|
|
if [[ ! -f "$SCRIPT_FILE" ]]; then
|
|
die "Script file not found: ${SCRIPT_FILE}"
|
|
fi
|
|
command_to_run=$(cat "$SCRIPT_FILE")
|
|
fi
|
|
|
|
log "Resolving target instances..."
|
|
local targets_str
|
|
targets_str=$(resolve_targets)
|
|
|
|
if [[ -z "$targets_str" ]]; then
|
|
die "No SSM-managed instances found matching criteria"
|
|
fi
|
|
|
|
local -a target_array
|
|
read -ra target_array <<< "$targets_str"
|
|
local count=${#target_array[@]}
|
|
log "Found ${count} target instance(s)"
|
|
|
|
# Build target specification
|
|
local target_spec
|
|
if [[ -n "$INSTANCE_IDS" ]]; then
|
|
target_spec="--instance-ids ${target_array[*]}"
|
|
elif [[ -n "$SSM_TAG_KEY" ]]; then
|
|
target_spec="--targets Key=tag:${SSM_TAG_KEY},Values=${SSM_TAG_VALUE:-*}"
|
|
else
|
|
target_spec="--instance-ids ${target_array[*]}"
|
|
fi
|
|
|
|
log "Sending command to ${count} instance(s)..."
|
|
verbose "Command: ${command_to_run:0:100}..."
|
|
|
|
local cmd_id
|
|
# shellcheck disable=SC2086
|
|
cmd_id=$(aws_cmd ssm send-command \
|
|
--document-name "AWS-RunShellScript" \
|
|
--parameters "commands=[\"${command_to_run}\"]" \
|
|
$target_spec \
|
|
--timeout-seconds "$SSM_TIMEOUT" \
|
|
--max-concurrency "${SSM_MAX_CONCURRENCY}" \
|
|
--query 'Command.CommandId' \
|
|
--output text 2>/dev/null) || die "Failed to send SSM command"
|
|
|
|
log "Command ID: ${cmd_id}"
|
|
log "Waiting for completion (timeout: ${SSM_TIMEOUT}s)..."
|
|
|
|
# Poll for completion
|
|
local attempts=0
|
|
local max_attempts=$((SSM_TIMEOUT / 5))
|
|
local all_done="false"
|
|
|
|
while [[ "$all_done" != "true" && "$attempts" -lt "$max_attempts" ]]; do
|
|
sleep 5
|
|
((attempts++)) || true
|
|
|
|
local status_json
|
|
status_json=$(aws_cmd ssm list-command-invocations \
|
|
--command-id "$cmd_id" \
|
|
--query 'CommandInvocations[*].{Id:InstanceId,Status:Status}' \
|
|
--output json 2>/dev/null) || continue
|
|
|
|
local pending
|
|
pending=$(echo "$status_json" | jq '[.[] | select(.Status == "InProgress" or .Status == "Pending")] | length')
|
|
if [[ "$pending" -eq 0 ]]; then
|
|
all_done="true"
|
|
fi
|
|
|
|
verbose "Poll ${attempts}: ${pending} still in progress"
|
|
done
|
|
|
|
# Collect results
|
|
collect_results "$cmd_id" "${target_array[@]}"
|
|
}
|
|
|
|
collect_results() {
|
|
local cmd_id="$1"
|
|
shift
|
|
local instances=("$@")
|
|
|
|
local success=0 failed=0 timed_out=0
|
|
|
|
echo ""
|
|
for instance_id in "${instances[@]}"; do
|
|
local result_json
|
|
result_json=$(aws_cmd ssm get-command-invocation \
|
|
--command-id "$cmd_id" \
|
|
--instance-id "$instance_id" \
|
|
--output json 2>/dev/null) || continue
|
|
|
|
local status stdout stderr
|
|
status=$(echo "$result_json" | jq -r '.Status')
|
|
stdout=$(echo "$result_json" | jq -r '.StandardOutputContent // ""')
|
|
stderr=$(echo "$result_json" | jq -r '.StandardErrorContent // ""')
|
|
|
|
local name
|
|
name=$(get_instance_name "$instance_id")
|
|
[[ "$name" == "None" ]] && name="N/A"
|
|
|
|
case "$status" in
|
|
Success)
|
|
echo -e " ${GREEN}✓${RESET} ${instance_id} (${name})"
|
|
((success++)) || true
|
|
;;
|
|
Failed)
|
|
echo -e " ${RED}✗${RESET} ${instance_id} (${name}) — failed"
|
|
((failed++)) || true
|
|
;;
|
|
TimedOut)
|
|
echo -e " ${YELLOW}⏱${RESET} ${instance_id} (${name}) — timed out"
|
|
((timed_out++)) || true
|
|
;;
|
|
*)
|
|
echo -e " ${DIM}?${RESET} ${instance_id} (${name}) — ${status}"
|
|
;;
|
|
esac
|
|
|
|
if [[ -n "$stdout" && "$OUTPUT_FORMAT" == "text" ]]; then
|
|
# shellcheck disable=SC2001
|
|
echo "$stdout" | sed 's/^/ /'
|
|
echo ""
|
|
fi
|
|
|
|
if [[ -n "$stderr" && "$VERBOSE" == "true" ]]; then
|
|
echo -e " ${RED}stderr:${RESET}"
|
|
# shellcheck disable=SC2001
|
|
echo "$stderr" | sed 's/^/ /'
|
|
echo ""
|
|
fi
|
|
|
|
# Save to output directory
|
|
if [[ -n "$OUTPUT_DIR" ]]; then
|
|
mkdir -p "$OUTPUT_DIR"
|
|
echo "$stdout" > "${OUTPUT_DIR}/${instance_id}.stdout.txt"
|
|
[[ -n "$stderr" ]] && echo "$stderr" > "${OUTPUT_DIR}/${instance_id}.stderr.txt"
|
|
fi
|
|
done
|
|
|
|
if [[ "$OUTPUT_FORMAT" == "json" ]]; then
|
|
aws_cmd ssm list-command-invocations \
|
|
--command-id "$cmd_id" \
|
|
--details \
|
|
--output json 2>/dev/null
|
|
fi
|
|
|
|
echo ""
|
|
log "Summary: success=${success}, failed=${failed}, timed_out=${timed_out}"
|
|
log "Completed in $(elapsed)"
|
|
}
|
|
|
|
# ══════════════════════════════════════════════════════════════════════
|
|
# PATCH SCAN MODE
|
|
# ══════════════════════════════════════════════════════════════════════
|
|
|
|
do_patch_scan() {
|
|
log "Running patch compliance scan..."
|
|
local targets_str
|
|
targets_str=$(resolve_targets)
|
|
|
|
if [[ -z "$targets_str" ]]; then
|
|
die "No SSM-managed instances found matching criteria"
|
|
fi
|
|
|
|
local -a target_array
|
|
read -ra target_array <<< "$targets_str"
|
|
log "Scanning ${#target_array[@]} instance(s) for patch compliance..."
|
|
|
|
local target_spec
|
|
if [[ -n "$SSM_TAG_KEY" ]]; then
|
|
target_spec="--targets Key=tag:${SSM_TAG_KEY},Values=${SSM_TAG_VALUE:-*}"
|
|
else
|
|
target_spec="--instance-ids ${target_array[*]}"
|
|
fi
|
|
|
|
local cmd_id
|
|
# shellcheck disable=SC2086
|
|
cmd_id=$(aws_cmd ssm send-command \
|
|
--document-name "AWS-RunPatchBaseline" \
|
|
--parameters '{"Operation":["Scan"]}' \
|
|
$target_spec \
|
|
--timeout-seconds "$SSM_TIMEOUT" \
|
|
--query 'Command.CommandId' \
|
|
--output text 2>/dev/null) || die "Failed to send patch scan command"
|
|
|
|
log "Command ID: ${cmd_id}"
|
|
log "Waiting for scan completion..."
|
|
|
|
sleep 10
|
|
|
|
local attempts=0
|
|
local max_attempts=$((SSM_TIMEOUT / 10))
|
|
while [[ "$attempts" -lt "$max_attempts" ]]; do
|
|
sleep 10
|
|
((attempts++)) || true
|
|
|
|
local pending
|
|
# shellcheck disable=SC2016
|
|
pending=$(aws_cmd ssm list-command-invocations \
|
|
--command-id "$cmd_id" \
|
|
--query 'CommandInvocations[?Status==`InProgress` || Status==`Pending`] | length(@)' \
|
|
--output text 2>/dev/null) || continue
|
|
|
|
if [[ "$pending" -eq 0 ]]; then
|
|
break
|
|
fi
|
|
verbose "Poll ${attempts}: ${pending} still scanning..."
|
|
done
|
|
|
|
# Display results
|
|
echo ""
|
|
printf " ${BOLD}%-22s %-14s %s${RESET}\n" "INSTANCE" "STATUS" "DETAILS"
|
|
printf " %s\n" "$(printf '%.0s─' {1..55})"
|
|
|
|
aws_cmd ssm list-command-invocations \
|
|
--command-id "$cmd_id" \
|
|
--query 'CommandInvocations[*].{Id:InstanceId,Status:Status,Detail:StatusDetails}' \
|
|
--output json 2>/dev/null | jq -c '.[]' | while IFS= read -r inv; do
|
|
local iid status detail
|
|
iid=$(echo "$inv" | jq -r '.Id')
|
|
status=$(echo "$inv" | jq -r '.Status')
|
|
detail=$(echo "$inv" | jq -r '.Detail')
|
|
|
|
local icon="$GREEN✓$RESET"
|
|
[[ "$status" != "Success" ]] && icon="$RED✗$RESET"
|
|
|
|
printf " %-22s ${icon} %-12s %s\n" "$iid" "$status" "$detail"
|
|
done
|
|
|
|
echo ""
|
|
log "Patch scan completed in $(elapsed)"
|
|
}
|
|
|
|
# ══════════════════════════════════════════════════════════════════════
|
|
# PATCH INSTALL MODE
|
|
# ══════════════════════════════════════════════════════════════════════
|
|
|
|
do_patch_install() {
|
|
log "Running patch installation..."
|
|
warn "This will install patches and may require reboots"
|
|
|
|
local targets_str
|
|
targets_str=$(resolve_targets)
|
|
|
|
local -a target_array
|
|
read -ra target_array <<< "$targets_str"
|
|
log "Installing patches on ${#target_array[@]} instance(s)..."
|
|
|
|
local target_spec
|
|
if [[ -n "$SSM_TAG_KEY" ]]; then
|
|
target_spec="--targets Key=tag:${SSM_TAG_KEY},Values=${SSM_TAG_VALUE:-*}"
|
|
else
|
|
target_spec="--instance-ids ${target_array[*]}"
|
|
fi
|
|
|
|
local cmd_id
|
|
# shellcheck disable=SC2086
|
|
cmd_id=$(aws_cmd ssm send-command \
|
|
--document-name "AWS-RunPatchBaseline" \
|
|
--parameters '{"Operation":["Install"],"RebootOption":["RebootIfNeeded"]}' \
|
|
$target_spec \
|
|
--timeout-seconds "$SSM_TIMEOUT" \
|
|
--query 'Command.CommandId' \
|
|
--output text 2>/dev/null) || die "Failed to send patch install command"
|
|
|
|
log "Command ID: ${cmd_id}"
|
|
log "Patches being installed — monitor with: aws ssm list-command-invocations --command-id ${cmd_id}"
|
|
log "Completed in $(elapsed)"
|
|
}
|
|
|
|
# ══════════════════════════════════════════════════════════════════════
|
|
# INVENTORY MODE
|
|
# ══════════════════════════════════════════════════════════════════════
|
|
|
|
do_inventory() {
|
|
log "Collecting software inventory..."
|
|
|
|
local targets_str
|
|
targets_str=$(resolve_targets)
|
|
|
|
local -a target_array
|
|
read -ra target_array <<< "$targets_str"
|
|
|
|
echo ""
|
|
printf " ${BOLD}%-22s %-16s %-12s %-14s %s${RESET}\n" "INSTANCE" "PLATFORM" "AGENT_VER" "IP" "NAME"
|
|
printf " %s\n" "$(printf '%.0s─' {1..80})"
|
|
|
|
for iid in "${target_array[@]}"; do
|
|
local info_json
|
|
info_json=$(aws_cmd ssm describe-instance-information \
|
|
--filters "Key=InstanceIds,Values=${iid}" \
|
|
--query 'InstanceInformationList[0]' \
|
|
--output json 2>/dev/null) || continue
|
|
|
|
local platform agent_ver ip_addr name
|
|
platform=$(echo "$info_json" | jq -r '.PlatformName // "Unknown"')
|
|
agent_ver=$(echo "$info_json" | jq -r '.AgentVersion // "?"')
|
|
ip_addr=$(echo "$info_json" | jq -r '.IPAddress // "?"')
|
|
name=$(get_instance_name "$iid")
|
|
[[ "$name" == "None" ]] && name="N/A"
|
|
|
|
printf " %-22s %-16s %-12s %-14s %s\n" "$iid" "${platform:0:16}" "${agent_ver:0:12}" "$ip_addr" "${name:0:20}"
|
|
done
|
|
|
|
echo ""
|
|
log "Inventory complete — ${#target_array[@]} instance(s)"
|
|
log "Completed in $(elapsed)"
|
|
}
|
|
|
|
# ══════════════════════════════════════════════════════════════════════
|
|
# HELP
|
|
# ══════════════════════════════════════════════════════════════════════
|
|
|
|
show_help() {
|
|
cat <<EOF
|
|
Usage: $SCRIPT_NAME [MODE] [OPTIONS]
|
|
|
|
Run commands across EC2 instances via AWS Systems Manager.
|
|
|
|
MODES:
|
|
--run COMMAND Run a shell command on target instances
|
|
--script FILE Run a script file on target instances
|
|
--patch-scan Scan instances for patch compliance
|
|
--patch-install Install patches (may reboot instances)
|
|
--inventory Collect instance inventory
|
|
|
|
TARGETING:
|
|
--instance-ids IDS Comma-separated instance IDs
|
|
--tag KEY=VALUE Target instances by tag
|
|
--all-instances Target all SSM-managed instances
|
|
|
|
OPTIONS:
|
|
--timeout SECS Command timeout (default: $SSM_TIMEOUT)
|
|
--max-concurrency N Max concurrent executions (default: $SSM_MAX_CONCURRENCY)
|
|
--format FORMAT Output: text (default), json, csv
|
|
--output-dir DIR Save per-instance output to directory
|
|
--verbose Debug output
|
|
--no-color Disable colored output
|
|
--help, -h Show this help
|
|
|
|
ENVIRONMENT VARIABLES:
|
|
AWS_PROFILE AWS CLI profile
|
|
AWS_REGION AWS region
|
|
INSTANCE_IDS Comma-separated instance IDs
|
|
SSM_TAG_KEY Target tag key
|
|
SSM_TAG_VALUE Target tag value
|
|
SSM_TIMEOUT Command timeout in seconds (default: 600)
|
|
SSM_MAX_CONCURRENCY Max concurrent executions (default: 50)
|
|
OUTPUT_FORMAT Output format (default: text)
|
|
VERBOSE Debug output (default: false)
|
|
COLOR Color mode: auto, always, never
|
|
|
|
EXAMPLES:
|
|
# Run uptime on tagged instances
|
|
./$SCRIPT_NAME --run "uptime" --tag Environment=production
|
|
|
|
# Run a script file
|
|
./$SCRIPT_NAME --script /opt/scripts/check.sh --instance-ids i-0abc123,i-0def456
|
|
|
|
# Patch compliance scan
|
|
./$SCRIPT_NAME --patch-scan --tag PatchGroup=web
|
|
|
|
# Collect inventory
|
|
./$SCRIPT_NAME --inventory --all-instances
|
|
|
|
# Save output per instance
|
|
./$SCRIPT_NAME --run "df -h" --tag Role=web --output-dir /tmp/df-results
|
|
EOF
|
|
}
|
|
|
|
# ══════════════════════════════════════════════════════════════════════
|
|
# MAIN
|
|
# ══════════════════════════════════════════════════════════════════════
|
|
|
|
main() {
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--run) RUN_MODE="run"; COMMAND_TEXT="$2"; shift 2 ;;
|
|
--script) RUN_MODE="script"; SCRIPT_FILE="$2"; shift 2 ;;
|
|
--patch-scan) RUN_MODE="patch-scan"; shift ;;
|
|
--patch-install) RUN_MODE="patch-install"; shift ;;
|
|
--inventory) RUN_MODE="inventory"; shift ;;
|
|
--instance-ids) INSTANCE_IDS="$2"; shift 2 ;;
|
|
--tag)
|
|
local tag_pair="$2"
|
|
SSM_TAG_KEY="${tag_pair%%=*}"
|
|
SSM_TAG_VALUE="${tag_pair#*=}"
|
|
shift 2
|
|
;;
|
|
--all-instances) ALL_INSTANCES="true"; shift ;;
|
|
--timeout) SSM_TIMEOUT="$2"; shift 2 ;;
|
|
--max-concurrency) SSM_MAX_CONCURRENCY="$2"; shift 2 ;;
|
|
--format) OUTPUT_FORMAT="$2"; shift 2 ;;
|
|
--output-dir) OUTPUT_DIR="$2"; shift 2 ;;
|
|
--verbose) VERBOSE="true"; shift ;;
|
|
--no-color) COLOR="never"; shift ;;
|
|
--help|-h) show_help; exit 0 ;;
|
|
*) die "Unknown option: $1 (see --help)" ;;
|
|
esac
|
|
done
|
|
|
|
setup_colors
|
|
|
|
if [[ -z "$RUN_MODE" ]]; then err "No mode specified"; echo ""; show_help; exit 1; fi
|
|
|
|
START_TIME=$(date +%s)
|
|
|
|
echo ""
|
|
echo -e "${BOLD}SSM Fleet Runner${RESET}"
|
|
echo "Region: ${AWS_REGION:-$(aws configure get region 2>/dev/null || echo 'default')}"
|
|
echo "Mode: ${RUN_MODE}"
|
|
echo "Time: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
echo ""
|
|
|
|
check_deps
|
|
|
|
case "$RUN_MODE" in
|
|
run|script) do_run ;;
|
|
patch-scan) do_patch_scan ;;
|
|
patch-install) do_patch_install ;;
|
|
inventory) do_inventory ;;
|
|
esac
|
|
}
|
|
|
|
main "$@"
|