#!/bin/bash # Setup and validate Slack integration for StemeDB alerting # # Usage: # ./setup-slack.sh # Full validation # ./setup-slack.sh --validate-only # Skip test message posting # ./setup-slack.sh --dry-run # Show what would be done set -euo pipefail # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Configuration (override with environment variables) SLACK_WEBHOOK_CRITICAL="${SLACK_WEBHOOK_CRITICAL:-}" SLACK_WEBHOOK_WARNING="${SLACK_WEBHOOK_WARNING:-}" SLACK_WEBHOOK_INFO="${SLACK_WEBHOOK_INFO:-}" SLACK_CHANNEL_CRITICAL="${SLACK_CHANNEL_CRITICAL:-#stemedb-alerts-critical}" SLACK_CHANNEL_WARNING="${SLACK_CHANNEL_WARNING:-#stemedb-alerts-warning}" SLACK_CHANNEL_INFO="${SLACK_CHANNEL_INFO:-#stemedb-alerts-info}" # Modes VALIDATE_ONLY=false DRY_RUN=false # Parse arguments for arg in "$@"; do case $arg in --validate-only) VALIDATE_ONLY=true shift ;; --dry-run) DRY_RUN=true shift ;; --help) echo "Usage: $0 [--validate-only] [--dry-run] [--help]" echo "" echo "Options:" echo " --validate-only Skip test message posting" echo " --dry-run Show what would be done without executing" echo " --help Show this help message" echo "" echo "Environment variables:" echo " SLACK_WEBHOOK_CRITICAL Webhook URL for critical alerts" echo " SLACK_WEBHOOK_WARNING Webhook URL for warning alerts" echo " SLACK_WEBHOOK_INFO Webhook URL for info alerts" echo " SLACK_CHANNEL_CRITICAL Channel name (default: #stemedb-alerts-critical)" echo " SLACK_CHANNEL_WARNING Channel name (default: #stemedb-alerts-warning)" echo " SLACK_CHANNEL_INFO Channel name (default: #stemedb-alerts-info)" exit 0 ;; *) echo "Unknown argument: $arg" echo "Use --help for usage information" exit 1 ;; esac done # Helper functions log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } check_dependency() { if ! command -v "$1" &> /dev/null; then log_error "Required command '$1' not found" return 1 fi } # Validation step 1: Check dependencies validate_dependencies() { log_info "Checking dependencies..." local missing=0 for cmd in curl jq; do if ! check_dependency "$cmd"; then missing=1 fi done if [ $missing -eq 1 ]; then log_error "Missing required dependencies. Install curl and jq." return 1 fi log_info "✓ All dependencies present" return 0 } # Validation step 2: Validate webhook URLs validate_webhook_urls() { log_info "Validating Slack webhook URLs..." local failed=0 # Validate critical webhook if [ -z "$SLACK_WEBHOOK_CRITICAL" ]; then log_error "SLACK_WEBHOOK_CRITICAL not set" log_info "Set it with: export SLACK_WEBHOOK_CRITICAL='https://hooks.slack.com/services/...'" failed=1 elif [[ ! "$SLACK_WEBHOOK_CRITICAL" =~ ^https://hooks\.slack\.com/services/ ]]; then log_error "SLACK_WEBHOOK_CRITICAL has invalid format" log_info "Expected format: https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXX" failed=1 else log_info "✓ Critical webhook URL format valid" fi # Validate warning webhook if [ -z "$SLACK_WEBHOOK_WARNING" ]; then log_warn "SLACK_WEBHOOK_WARNING not set (optional)" elif [[ ! "$SLACK_WEBHOOK_WARNING" =~ ^https://hooks\.slack\.com/services/ ]]; then log_error "SLACK_WEBHOOK_WARNING has invalid format" failed=1 else log_info "✓ Warning webhook URL format valid" fi # Validate info webhook if [ -z "$SLACK_WEBHOOK_INFO" ]; then log_warn "SLACK_WEBHOOK_INFO not set (optional)" elif [[ ! "$SLACK_WEBHOOK_INFO" =~ ^https://hooks\.slack\.com/services/ ]]; then log_error "SLACK_WEBHOOK_INFO has invalid format" failed=1 else log_info "✓ Info webhook URL format valid" fi return $failed } # Validation step 3: Test message posting test_message_posting() { log_info "Testing message posting to Slack channels..." if [ "$DRY_RUN" = true ]; then log_info "[DRY RUN] Would send test messages to Slack" return 0 fi if [ "$VALIDATE_ONLY" = true ]; then log_info "Skipping test messages (--validate-only mode)" return 0 fi local failed=0 # Test critical channel if [ -n "$SLACK_WEBHOOK_CRITICAL" ]; then log_info "Sending test message to $SLACK_CHANNEL_CRITICAL..." local response response=$(curl -X POST "$SLACK_WEBHOOK_CRITICAL" \ -H 'Content-Type: application/json' \ -d '{ "channel": "'"$SLACK_CHANNEL_CRITICAL"'", "username": "StemeDB Alerts", "icon_emoji": ":warning:", "attachments": [{ "color": "danger", "title": "🔴 CRITICAL: StemeDB Setup Test", "text": "This is a test message from setup-slack.sh. Safe to ignore.", "fields": [ { "title": "Severity", "value": "CRITICAL", "short": true }, { "title": "Timestamp", "value": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'", "short": true } ], "footer": "StemeDB Monitoring" }] }' 2>&1) if [ "$response" = "ok" ]; then log_info "✓ Test message sent to $SLACK_CHANNEL_CRITICAL" else log_error "Failed to send message to $SLACK_CHANNEL_CRITICAL" log_error "Response: $response" failed=1 fi fi # Test warning channel if [ -n "$SLACK_WEBHOOK_WARNING" ]; then log_info "Sending test message to $SLACK_CHANNEL_WARNING..." local response response=$(curl -X POST "$SLACK_WEBHOOK_WARNING" \ -H 'Content-Type: application/json' \ -d '{ "channel": "'"$SLACK_CHANNEL_WARNING"'", "username": "StemeDB Alerts", "icon_emoji": ":warning:", "attachments": [{ "color": "warning", "title": "🟡 WARNING: StemeDB Setup Test", "text": "This is a test message from setup-slack.sh. Safe to ignore.", "fields": [ { "title": "Severity", "value": "WARNING", "short": true }, { "title": "Timestamp", "value": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'", "short": true } ], "footer": "StemeDB Monitoring" }] }' 2>&1) if [ "$response" = "ok" ]; then log_info "✓ Test message sent to $SLACK_CHANNEL_WARNING" else log_warn "Failed to send message to $SLACK_CHANNEL_WARNING" log_warn "Response: $response" fi fi # Test info channel if [ -n "$SLACK_WEBHOOK_INFO" ]; then log_info "Sending test message to $SLACK_CHANNEL_INFO..." local response response=$(curl -X POST "$SLACK_WEBHOOK_INFO" \ -H 'Content-Type: application/json' \ -d '{ "channel": "'"$SLACK_CHANNEL_INFO"'", "username": "StemeDB Alerts", "icon_emoji": ":information_source:", "attachments": [{ "color": "good", "title": "â„šī¸ INFO: StemeDB Setup Test", "text": "This is a test message from setup-slack.sh. Safe to ignore.", "fields": [ { "title": "Severity", "value": "INFO", "short": true }, { "title": "Timestamp", "value": "'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'", "short": true } ], "footer": "StemeDB Monitoring" }] }' 2>&1) if [ "$response" = "ok" ]; then log_info "✓ Test message sent to $SLACK_CHANNEL_INFO" else log_warn "Failed to send message to $SLACK_CHANNEL_INFO" log_warn "Response: $response" fi fi return $failed } # Validation step 4: Verify formatting renders correctly verify_formatting() { log_info "Verifying message formatting..." if [ "$DRY_RUN" = true ] || [ "$VALIDATE_ONLY" = true ]; then log_info "Skipping formatting verification (requires manual check)" return 0 fi log_info "Please check Slack channels to verify:" log_info " 1. Messages appear in correct channels" log_info " 2. Color coding is correct (red=critical, yellow=warning, green=info)" log_info " 3. Formatting renders properly (fields, footer, emoji)" log_info " 4. Bot icon and username are correct" return 0 } # Validation step 5: Check Alertmanager configuration verify_alertmanager_config() { log_info "Verifying Alertmanager Slack configuration..." local alertmanager_config="/etc/prometheus/alertmanager.yml" if [ ! -f "$alertmanager_config" ]; then log_warn "Alertmanager config not found at $alertmanager_config" log_info "Ensure Slack receivers are configured in Alertmanager" return 0 fi # Verify Slack receiver is configured if grep -q "slack_configs" "$alertmanager_config"; then log_info "✓ Slack receivers configured in Alertmanager" # Count configured Slack receivers local slack_count slack_count=$(grep -c "api_url:" "$alertmanager_config" || echo "0") log_info " Found $slack_count Slack webhook(s) configured" # Check for channel routing if grep -q "channel:" "$alertmanager_config"; then log_info " ✓ Channel routing configured" else log_warn " Warning: No explicit channel routing found" fi else log_warn "No Slack receivers found in Alertmanager config" log_info "Add Slack receivers to $alertmanager_config" fi return 0 } # Main execution main() { echo "=========================================" echo "StemeDB Slack Setup Validation" echo "=========================================" echo "" if [ "$DRY_RUN" = true ]; then log_info "Running in DRY RUN mode - no changes will be made" fi local failed=0 # Run validation steps validate_dependencies || failed=1 validate_webhook_urls || failed=1 test_message_posting || failed=1 verify_formatting || failed=1 verify_alertmanager_config || failed=1 echo "" echo "=========================================" if [ $failed -eq 0 ]; then log_info "✓ Slack validation PASSED" echo "=========================================" exit 0 else log_error "✗ Slack validation FAILED" echo "=========================================" exit 1 fi } # Run main function main