guardia-itsm/cicd/scripts/notify/itsm_callback.sh
2026-05-30 23:02:43 +09:00

143 lines
5.8 KiB
Bash

#!/usr/bin/env bash
# =============================================================================
# GUARDiA ITSM 결과 콜백 스크립트
# Jenkins Stage 8: ITSM Callback에서 호출
# 사용: itsm_callback.sh <STATUS> [MESSAGE]
# STATUS: BUILDING|TESTING|DEPLOYING|COMPLETED|FAILED|UNSTABLE|PENDING_APPROVAL|ROLLED_BACK
# =============================================================================
set -euo pipefail
STATUS="${1:-FAILED}"
MESSAGE="${2:-파이프라인 실행 완료}"
# ── 환경변수 ─────────────────────────────────────────────────────────────────
ITSM_URL="${ITSM_URL:-http://itsm.agency.go.kr:8000}"
ITSM_CALLBACK_URL="${ITSM_CALLBACK_URL:-${ITSM_URL}/api/vibe/callback}"
ITSM_TOKEN="${ITSM_TOKEN:-}" # withCredentials로 주입
ITSM_SESSION_ID="${ITSM_SESSION_ID:-}" # Jenkins 파라미터
ITSM_SR_ID="${ITSM_SR_ID:-}" # Jenkins 파라미터
BUILD_NUMBER="${BUILD_NUMBER:-0}"
BUILD_URL="${BUILD_URL:-}"
DEPLOY_ENV="${DEPLOY_ENV:-dev}"
JOB_NAME="${JOB_NAME:-unknown-job}"
STAGE_NAME="${STAGE_NAME:-}"
LOG_DIR="${WORKSPACE:-/tmp}/build-logs"
CALLBACK_LOG="${LOG_DIR}/itsm-callback.log"
GREEN='\033[0;32m'; RED='\033[0;31m'; YELLOW='\033[1;33m'; NC='\033[0m'
log() { echo -e "${GREEN}[ITSM]${NC} $*" | tee -a "${CALLBACK_LOG}"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*" | tee -a "${CALLBACK_LOG}"; }
err() { echo -e "${RED}[ERROR]${NC} $*" | tee -a "${CALLBACK_LOG}"; }
mkdir -p "${LOG_DIR}"
# ── 세션 ID 없으면 경고 후 종료 (비배포 브랜치 등) ─────────────────────────
if [[ -z "${ITSM_SESSION_ID}" ]]; then
warn "ITSM_SESSION_ID가 설정되지 않았습니다 — 콜백 건너뜀"
exit 0
fi
log "ITSM 콜백: ${STATUS}${MESSAGE}"
# ── 빌드 로그 요약 수집 ──────────────────────────────────────────────────────
get_log_summary() {
local log_type="$1"
local log_file="${LOG_DIR}/${log_type}-"*".log" 2>/dev/null
if compgen -G "${log_file}" > /dev/null; then
tail -n 5 "$(ls ${log_file} | tail -1)" 2>/dev/null | tr '\n' ' ' | \
sed 's/["\t]/ /g' | cut -c1-200 || echo ""
else
echo ""
fi
}
BUILD_LOG_SUMMARY=$(get_log_summary "build")
TEST_LOG_SUMMARY=$(get_log_summary "test")
DEPLOY_LOG_SUMMARY=$(get_log_summary "deploy")
HC_LOG_SUMMARY=$(get_log_summary "healthcheck")
# ── 현재 타임스탬프 ──────────────────────────────────────────────────────────
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
# ── JSON 페이로드 구성 ───────────────────────────────────────────────────────
JSON_PAYLOAD=$(cat <<JSONEOF
{
"session_id": "${ITSM_SESSION_ID}",
"sr_id": "${ITSM_SR_ID}",
"status": "${STATUS}",
"stage": "${STAGE_NAME}",
"message": "${MESSAGE}",
"build_number": "${BUILD_NUMBER}",
"build_url": "${BUILD_URL}",
"deploy_env": "${DEPLOY_ENV}",
"job_name": "${JOB_NAME}",
"timestamp": "${TIMESTAMP}",
"logs": {
"build": "${BUILD_LOG_SUMMARY}",
"test": "${TEST_LOG_SUMMARY}",
"deploy": "${DEPLOY_LOG_SUMMARY}",
"health_check": "${HC_LOG_SUMMARY}"
}
}
JSONEOF
)
# ── HTTP 콜백 전송 (재시도 3회) ──────────────────────────────────────────────
send_callback() {
local retries=3
local attempt=0
while [[ ${attempt} -lt ${retries} ]]; do
attempt=$((attempt + 1))
log " 콜백 전송 시도 ${attempt}/${retries}: ${ITSM_CALLBACK_URL}"
local http_code
http_code=$(curl \
--silent \
--output "${LOG_DIR}/callback-response.json" \
--write-out "%{http_code}" \
--max-time 30 \
--connect-timeout 10 \
--request POST \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${ITSM_TOKEN}" \
--data "${JSON_PAYLOAD}" \
"${ITSM_CALLBACK_URL}" 2>/dev/null || echo "000")
if [[ "${http_code}" =~ ^2[0-9]{2}$ ]]; then
log "✅ 콜백 성공: HTTP ${http_code}"
if [[ -f "${LOG_DIR}/callback-response.json" ]]; then
log " 응답: $(cat ${LOG_DIR}/callback-response.json)"
fi
return 0
else
warn " 콜백 실패: HTTP ${http_code}"
if [[ ${attempt} -lt ${retries} ]]; then
sleep $((attempt * 5))
fi
fi
done
err "ITSM 콜백 실패 (${retries}회 재시도 후)"
err "URL: ${ITSM_CALLBACK_URL}"
err "상태: ${STATUS}"
# 콜백 실패는 파이프라인 실패로 처리하지 않음
return 0
}
# ── 로컬 로그에도 기록 ────────────────────────────────────────────────────────
log_locally() {
local history_file="${LOG_DIR}/pipeline-history.log"
echo "${TIMESTAMP}|${JOB_NAME}|${BUILD_NUMBER}|${STATUS}|${MESSAGE}|${DEPLOY_ENV}" \
>> "${history_file}"
}
# ── 메인 ─────────────────────────────────────────────────────────────────────
main() {
log_locally
send_callback
log "ITSM 콜백 처리 완료: ${STATUS}"
}
main "$@"