-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
#!/bin/bash
# Inspection Rule Execution Script
# This script executes inspection rules based on rule names and returns results in JSON format
# Usage: ./inspect-script.sh "rule1,rule2,rule3"
set -euo pipefail
# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
RESULTS_FILE="/tmp/inspect_results_$(date +%s).json"
YAML_FILE="${SCRIPT_DIR}/inspect.yaml"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Logging functions
log_info() {
echo -e "${GREEN}[INFO]${NC} $1" >&2
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1" >&2
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1" >&2
}
# Function to check if required tools are available
check_dependencies() {
local missing_tools=()
if ! command -v jq &> /dev/null; then
missing_tools+=("jq")
fi
if ! command -v yq &> /dev/null; then
missing_tools+=("yq")
fi
if [ ${#missing_tools[@]} -ne 0 ]; then
log_error "Missing required tools: ${missing_tools[*]}"
log_error "Please install them before running this script"
exit 1
fi
}
# Function to execute a single command and capture result
execute_command() {
local rule_id="$1"
local rule_name="$2"
local command="$3"
local category="$4"
local description="$5"
log_info "Executing rule: $rule_id ($rule_name)"
log_info "Command: $command"
local start_time=$(date +%s.%N)
local temp_output=$(mktemp)
local temp_error=$(mktemp)
# Execute command and capture output and exit code
set +e
eval "$command" > "$temp_output" 2> "$temp_error"
local exit_code=$?
set -e
local end_time=$(date +%s.%N)
local duration=$(echo "$end_time - $start_time" | bc -l)
local duration_ms=$(echo "$duration * 1000" | bc -l | cut -d. -f1)
# Read output and error
local output=$(cat "$temp_output")
local error_output=$(cat "$temp_error")
# Combine output and error if there's an error
if [ $exit_code -ne 0 ] && [ -n "$error_output" ]; then
output="$output\nError: $error_output"
fi
# Clean up temp files
rm -f "$temp_output" "$temp_error"
# Create result JSON
local result=$(jq -n \
--arg rule_id "$rule_id" \
--arg rule_name "$rule_name" \
--arg command "$command" \
--arg category "$category" \
--arg description "$description" \
--argjson exit_code "$exit_code" \
--arg output "$output" \
--argjson success "$([ $exit_code -eq 0 ] && echo true || echo false)" \
--argjson execution_time_ms "$duration_ms" \
--arg timestamp "$(date -Iseconds)" \
'{
ruleId: $rule_id,
ruleName: $rule_name,
command: $command,
category: $category,
description: $description,
exitCode: $exit_code,
output: $output,
success: $success,
executionTimeMs: $execution_time_ms,
timestamp: $timestamp
}')
echo "$result"
# Log result
if [ $exit_code -eq 0 ]; then
log_info "Rule $rule_id completed successfully (${duration_ms}ms)"
else
log_error "Rule $rule_id failed with exit code $exit_code (${duration_ms}ms)"
fi
}
# Function to get rule definition from YAML
get_rule_definition() {
local rule_id="$1"
if [ ! -f "$YAML_FILE" ]; then
log_error "YAML file not found: $YAML_FILE"
return 1
fi
# Extract rule definition using yq
yq eval ".[] | select(.id == \"$rule_id\")" "$YAML_FILE"
}
# Function to execute rules based on rule names
execute_rules() {
local rule_names="$1"
local results=()
# Parse comma-separated rule names
IFS=',' read -ra RULES <<< "$rule_names"
for rule_name in "${RULES[@]}"; do
# Trim whitespace
rule_name=$(echo "$rule_name" | xargs)
if [ -z "$rule_name" ]; then
continue
fi
log_info "Processing rule: $rule_name"
# Get rule definition from YAML
rule_def=$(get_rule_definition "$rule_name")
if [ -z "$rule_def" ]; then
log_warn "Rule not found: $rule_name"
# Create error result
error_result=$(jq -n \
--arg rule_id "$rule_name" \
--arg rule_name "$rule_name" \
--arg command "" \
--arg category "Error" \
--arg description "Rule not found" \
--argjson exit_code -1 \
--arg output "Rule not found: $rule_name" \
--argjson success false \
--argjson execution_time_ms 0 \
--arg timestamp "$(date -Iseconds)" \
'{
ruleId: $rule_id,
ruleName: $rule_name,
command: $command,
category: $category,
description: $description,
exitCode: $exit_code,
output: $output,
success: $success,
executionTimeMs: $execution_time_ms,
timestamp: $timestamp
}')
results+=("$error_result")
continue
fi
# Extract rule properties
local rule_id=$(echo "$rule_def" | yq eval '.id' -)
local name=$(echo "$rule_def" | yq eval '.name' -)
local command=$(echo "$rule_def" | yq eval '.rule' -)
local category=$(echo "$rule_def" | yq eval '.category' -)
local description=$(echo "$rule_def" | yq eval '.reason' -)
local type=$(echo "$rule_def" | yq eval '.type' -)
# Check if it's a COMMAND type rule
if [ "$type" != "COMMAND" ]; then
log_warn "Rule $rule_name is not a COMMAND type rule, skipping"
continue
fi
# Execute the command
result=$(execute_command "$rule_id" "$name" "$command" "$category" "$description")
results+=("$result")
done
# Create final JSON array
printf '%s\n' "${results[@]}" | jq -s '.' | tee $RESULTS_FILE
}
# Main function
main() {
if [ $# -eq 0 ]; then
echo "Usage: $0 <rule-names> <result-file> <rule-file>"
echo "Example: $0 \"docker-version,system-info,disk-usage\" /tmp/result0 inspect.yml "
echo ""
echo "Available rules:"
if [ -f "$YAML_FILE" ]; then
yq eval '.[].id' "$YAML_FILE" | sed 's/^/ - /'
else
echo " (inspect.yaml not found)"
fi
exit 1
fi
local rule_names="$1"
RESULTS_FILE="${2:-$RESULTS_FILE}"
YAML_FILE="${3:-$YAML_FILE}"
log_info "Starting inspection rule execution"
log_info "Rule names: $rule_names"
# Check dependencies
check_dependencies
# Execute rules and output results
execute_rules "$rule_names"
log_info "Inspection completed"
}
# Run main function with all arguments
main "$@"
Metadata
Metadata
Assignees
Labels
No labels