268 lines
7.7 KiB
Bash
268 lines
7.7 KiB
Bash
#!/bin/bash
|
|
# Operational Risk Verification Script
|
|
# Usage: ./scripts/verify-operational-risk.sh
|
|
|
|
set -e
|
|
|
|
PROJECT_NAME="runtime-role-matrix-live-202607141522-v4"
|
|
REPORT_DIR="docs/reviewer/reports"
|
|
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m'
|
|
|
|
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
|
|
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
|
|
|
# Create report directory
|
|
mkdir -p "${REPORT_DIR}"
|
|
|
|
log_info "Starting Operational Risk Verification for ${PROJECT_NAME}"
|
|
|
|
# Initialize risk assessment
|
|
RISK_SCORE=0
|
|
RISK_ITEMS="[]"
|
|
|
|
# 1. Monitoring Configuration
|
|
echo ""
|
|
log_info "=== 1. Monitoring Configuration ==="
|
|
|
|
MONITORING_SCORE=0
|
|
|
|
# Check for monitoring configuration files
|
|
if [ -f "monitoring/prometheus.yml" ] || [ -f "monitoring/grafana.json" ]; then
|
|
log_info "Monitoring configuration found"
|
|
MONITORING_SCORE=$((MONITORING_SCORE + 25))
|
|
else
|
|
log_warn "No monitoring configuration found"
|
|
fi
|
|
|
|
# Check for metrics endpoints
|
|
if grep -r "metrics" . --include="*.java" --include="*.js" --include="*.ts" -l 2>/dev/null | head -1 > /dev/null; then
|
|
log_info "Metrics endpoints detected"
|
|
MONITORING_SCORE=$((MONITORING_SCORE + 25))
|
|
else
|
|
log_warn "No metrics endpoints detected"
|
|
fi
|
|
|
|
# Check for health endpoints
|
|
if grep -r "health" . --include="*.java" --include="*.js" --include="*.ts" -l 2>/dev/null | head -1 > /dev/null; then
|
|
log_info "Health endpoints detected"
|
|
MONITORING_SCORE=$((MONITORING_SCORE + 25))
|
|
else
|
|
log_warn "No health endpoints detected"
|
|
fi
|
|
|
|
# Check for logging configuration
|
|
if [ -f "logging/logback.xml" ] || [ -f "logging/log4j2.xml" ] || [ -f "logging/config.js" ]; then
|
|
log_info "Logging configuration found"
|
|
MONITORING_SCORE=$((MONITORING_SCORE + 25))
|
|
else
|
|
log_warn "No logging configuration found"
|
|
fi
|
|
|
|
log_info "Monitoring Score: ${MONITORING_SCORE}/100"
|
|
RISK_SCORE=$((RISK_SCORE + (100 - MONITORING_SCORE)))
|
|
|
|
# 2. Alert Configuration
|
|
echo ""
|
|
log_info "=== 2. Alert Configuration ==="
|
|
|
|
ALERT_SCORE=0
|
|
|
|
if [ -f "monitoring/alerts.yml" ] || [ -f "monitoring/alerts.json" ]; then
|
|
log_info "Alert configuration found"
|
|
ALERT_SCORE=$((ALERT_SCORE + 50))
|
|
else
|
|
log_warn "No alert configuration found"
|
|
fi
|
|
|
|
if [ -f "monitoring/notifications.config" ]; then
|
|
log_info "Notification configuration found"
|
|
ALERT_SCORE=$((ALERT_SCORE + 50))
|
|
else
|
|
log_warn "No notification configuration found"
|
|
fi
|
|
|
|
log_info "Alert Score: ${ALERT_SCORE}/100"
|
|
RISK_SCORE=$((RISK_SCORE + (100 - ALERT_SCORE)))
|
|
|
|
# 3. Rollback Capability
|
|
echo ""
|
|
log_info "=== 3. Rollback Capability ==="
|
|
|
|
ROLLBACK_SCORE=0
|
|
|
|
if [ -f "scripts/rollback.sh" ] || [ -f "scripts/rollback.py" ]; then
|
|
log_info "Rollback script found"
|
|
ROLLBACK_SCORE=$((ROLLBACK_SCORE + 50))
|
|
else
|
|
log_warn "No rollback script found"
|
|
fi
|
|
|
|
if [ -f "docker-compose.yml" ] || [ -f "kubernetes/" ]; then
|
|
log_info "Container orchestration detected"
|
|
ROLLBACK_SCORE=$((ROLLBACK_SCORE + 50))
|
|
else
|
|
log_warn "No container orchestration detected"
|
|
fi
|
|
|
|
log_info "Rollback Score: ${ROLLBACK_SCORE}/100"
|
|
RISK_SCORE=$((RISK_SCORE + (100 - ROLLBACK_SCORE)))
|
|
|
|
# 4. Documentation
|
|
echo ""
|
|
log_info "=== 4. Documentation ==="
|
|
|
|
DOC_SCORE=0
|
|
|
|
if [ -f "docs/OPERATIONAL.md" ] || [ -f "docs/runbook.md" ]; then
|
|
log_info "Operational documentation found"
|
|
DOC_SCORE=$((DOC_SCORE + 50))
|
|
else
|
|
log_warn "No operational documentation found"
|
|
fi
|
|
|
|
if [ -f "README.md" ]; then
|
|
log_info "README found"
|
|
DOC_SCORE=$((DOC_SCORE + 50))
|
|
else
|
|
log_warn "No README found"
|
|
fi
|
|
|
|
log_info "Documentation Score: ${DOC_SCORE}/100"
|
|
RISK_SCORE=$((RISK_SCORE + (100 - DOC_SCORE)))
|
|
|
|
# 5. Security
|
|
echo ""
|
|
log_info "=== 5. Security Configuration ==="
|
|
|
|
SECURITY_SCORE=0
|
|
|
|
if [ -f ".env.example" ]; then
|
|
log_info "Environment template found"
|
|
SECURITY_SCORE=$((SECURITY_SCORE + 20))
|
|
else
|
|
log_warn "No environment template found"
|
|
fi
|
|
|
|
if [ -f "security/sast-config.yml" ] || [ -f ".sast.yml" ]; then
|
|
log_info "SAST configuration found"
|
|
SECURITY_SCORE=$((SECURITY_SCORE + 20))
|
|
else
|
|
log_warn "No SAST configuration found"
|
|
fi
|
|
|
|
if [ -f "security/dependency-check.gradle" ] || [ -f ".snyk" ]; then
|
|
log_info "Dependency scanning configured"
|
|
SECURITY_SCORE=$((SECURITY_SCORE + 20))
|
|
else
|
|
log_warn "No dependency scanning configured"
|
|
fi
|
|
|
|
if [ -f "SECRETS.md" ] || grep -r "secrets" . --include="*.md" -l 2>/dev/null | head -1 > /dev/null; then
|
|
log_info "Secrets management documented"
|
|
SECURITY_SCORE=$((SECURITY_SCORE + 20))
|
|
else
|
|
log_warn "No secrets management documentation"
|
|
fi
|
|
|
|
if [ -f ".dockerignore" ] || [ -f ".gitignore" ]; then
|
|
log_info "Security ignore files present"
|
|
SECURITY_SCORE=$((SECURITY_SCORE + 20))
|
|
else
|
|
log_warn "No security ignore files"
|
|
fi
|
|
|
|
log_info "Security Score: ${SECURITY_SCORE}/100"
|
|
RISK_SCORE=$((RISK_SCORE + (100 - SECURITY_SCORE)))
|
|
|
|
# Calculate overall risk level
|
|
AVG_SCORE=$(( (MONITORING_SCORE + ALERT_SCORE + ROLLBACK_SCORE + DOC_SCORE + SECURITY_SCORE) / 5 ))
|
|
|
|
if [ ${AVG_SCORE} -ge 80 ]; then
|
|
RISK_LEVEL="LOW"
|
|
elif [ ${AVG_SCORE} -ge 60 ]; then
|
|
RISK_LEVEL="MEDIUM"
|
|
elif [ ${AVG_SCORE} -ge 40 ]; then
|
|
RISK_LEVEL="HIGH"
|
|
else
|
|
RISK_LEVEL="CRITICAL"
|
|
fi
|
|
|
|
# Generate report
|
|
echo ""
|
|
log_info "=== Generating Risk Assessment Report ==="
|
|
|
|
cat > "${REPORT_DIR}/operational_risk_${TIMESTAMP}.json" << EOF
|
|
{
|
|
"project": "${PROJECT_NAME}",
|
|
"timestamp": "${TIMESTAMP}",
|
|
"verification_type": "operational_risk",
|
|
"assessment": {
|
|
"monitoring": {
|
|
"score": ${MONITORING_SCORE},
|
|
"max_score": 100,
|
|
"status": $([ ${MONITORING_SCORE} -ge 75 ] && echo ""passed"" || echo ""needs_improvement"")
|
|
},
|
|
"alerts": {
|
|
"score": ${ALERT_SCORE},
|
|
"max_score": 100,
|
|
"status": $([ ${ALERT_SCORE} -ge 75 ] && echo ""passed"" || echo ""needs_improvement"")
|
|
},
|
|
"rollback": {
|
|
"score": ${ROLLBACK_SCORE},
|
|
"max_score": 100,
|
|
"status": $([ ${ROLLBACK_SCORE} -ge 75 ] && echo ""passed"" || echo ""needs_improvement"")
|
|
},
|
|
"documentation": {
|
|
"score": ${DOC_SCORE},
|
|
"max_score": 100,
|
|
"status": $([ ${DOC_SCORE} -ge 75 ] && echo ""passed"" || echo ""needs_improvement"")
|
|
},
|
|
"security": {
|
|
"score": ${SECURITY_SCORE},
|
|
"max_score": 100,
|
|
"status": $([ ${SECURITY_SCORE} -ge 75 ] && echo ""passed"" || echo ""needs_improvement"")
|
|
}
|
|
},
|
|
"overall_score": ${AVG_SCORE},
|
|
"risk_level": "${RISK_LEVEL}",
|
|
"recommendations": [
|
|
$([ ${MONITORING_SCORE} -lt 75 ] && echo '"Implement comprehensive monitoring and metrics collection"' || echo ''),
|
|
$([ ${ALERT_SCORE} -lt 75 ] && echo '"Configure alerting rules and notification channels"' || echo ''),
|
|
$([ ${ROLLBACK_SCORE} -lt 75 ] && echo '"Develop and test rollback procedures"' || echo ''),
|
|
$([ ${DOC_SCORE} -lt 75 ] && echo '"Create operational documentation and runbooks"' || echo ''),
|
|
$([ ${SECURITY_SCORE} -lt 75 ] && echo '"Enhance security configuration and scanning"' || echo '')
|
|
]
|
|
}
|
|
EOF
|
|
|
|
log_info "Risk assessment report: ${REPORT_DIR}/operational_risk_${TIMESTAMP}.json"
|
|
|
|
# Final summary
|
|
echo ""
|
|
echo "========================================"
|
|
log_info "Operational Risk Assessment Summary"
|
|
echo "========================================"
|
|
echo "Monitoring: ${MONITORING_SCORE}/100"
|
|
echo "Alerts: ${ALERT_SCORE}/100"
|
|
echo "Rollback: ${ROLLBACK_SCORE}/100"
|
|
echo "Documentation: ${DOC_SCORE}/100"
|
|
echo "Security: ${SECURITY_SCORE}/100"
|
|
echo "----------------------------------------"
|
|
echo "Overall Score: ${AVG_SCORE}/100"
|
|
echo "Risk Level: ${RISK_LEVEL}"
|
|
echo "========================================"
|
|
|
|
if [ "${RISK_LEVEL}" = "LOW" ] || [ "${RISK_LEVEL}" = "MEDIUM" ]; then
|
|
log_info "Risk assessment: ACCEPTABLE"
|
|
exit 0
|
|
else
|
|
log_warn "Risk assessment: NEEDS ATTENTION"
|
|
exit 1
|
|
fi
|