From 22b17f55575f4f755111bbbd7c123f9275fdbc68 Mon Sep 17 00:00:00 2001 From: raccoon-mh Date: Sun, 17 May 2026 04:21:25 +0000 Subject: [PATCH 1/9] fix(nginx): add HTTPS proxy for cost-optimizer and fix iframe rendering - nginx.template.conf: replace X-Frame-Options SAMEORIGIN with Content-Security-Policy frame-ancestors on :7781 proxy block; add dedicated HTTPS server blocks for mc-cost-optimizer-be (:9090) and mc-cost-optimizer-alarm-service (:9000) - docker-compose.yaml: bind :9090/:9000 on mc-iam-manager-nginx; remove host port bindings from mc-cost-optimizer-be and alarm-service - 1_setup_auto.sh: add update_public_service_urls() to overwrite mc-cost-optimizer-fe base_url in DB with the public HTTPS proxy URL - 0_preset_prod.sh / 0_preset_dev.sh: substitute MC_COST_OPTIMIZER_BE_PORT and MC_COST_OPTIMIZER_ALARM_PORT into generated nginx.conf - .env.setup / .env: add MC_COST_OPTIMIZER_FE_PROXY_PORT=7781; replace real domain with placeholder in .env - README / README_kr: document :9090/:9000 proxy check commands, Known Issues section for FE JS bundle in-place patch, HSTS note --- README.md | 59 +++++++++++++++--- README_kr.md | 59 +++++++++++++++--- conf/docker/conf/mc-iam-manager/.env | 7 ++- conf/docker/conf/mc-iam-manager/.env.setup | 3 + .../conf/mc-iam-manager/0_preset_dev.sh | 52 ++++++++++------ .../conf/mc-iam-manager/0_preset_prod.sh | 17 ++++++ .../conf/mc-iam-manager/1_setup_auto.sh | 61 +++++++++++++++++++ .../conf/mc-iam-manager/nginx.template.conf | 54 +++++++++++++++- conf/docker/docker-compose.yaml | 10 +-- 9 files changed, 280 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 0f6097f..e179ffa 100644 --- a/README.md +++ b/README.md @@ -179,8 +179,10 @@ Or run individual steps manually using `conf/docker/conf/mc-iam-manager/1_setup_ ```shell curl -kI https://:33002 # Grafana dashboard proxy curl -kI https://:7781 # Cost Optimizer FE proxy +curl -k https://:9090/api/costopti/be/readyz # Cost Optimizer BE proxy +curl -k https://:9000/actuator/health 2>/dev/null || true # Cost Optimizer alarm proxy ``` -Expected: `HTTP/2 200` for both. +Expected: `:33002` and `:7781` return `HTTP/2 200`; `:9090/readyz` returns `Application is ready`. ## Step 6. Initialize CB-Tumblebug & Access the Web Console @@ -203,6 +205,48 @@ cd mc-admin-cli/bin ./cleanAll.sh ``` +> **When to run cleanAll.sh**: Always run a full clean before switching deployment modes (dev ↔ prod) or changing the domain. Re-running `installAll.sh` over an existing setup without cleaning first can leave stale certificates, nginx config, or DB state that conflicts with the new configuration. + +--- + +## Known Issues + +### Cost Optimizer iframe — BE API (in-place workaround required) + +The Cost Optimizer frontend JavaScript bundle contains hardcoded URL logic that selects the backend API host at runtime: + +| Access method | BE/alarm URL selected | Result | +|---|---|---| +| `localhost` | `http://localhost:9090` | OK (same-origin, no TLS) | +| IP address | `https://{ip}:9090` | OK — IAM nginx HTTPS proxy on :9090 | +| Domain | `https://{domain}:9090` | OK — IAM nginx HTTPS proxy on :9090 | + +After every container recreation, apply the following in-place patch to the FE bundle: + +```bash +# Find the actual bundle filename first +JS=$(docker exec mc-cost-optimizer-fe ls /usr/share/nginx/html/assets/index-*.js 2>/dev/null | head -1) + +docker exec mc-cost-optimizer-fe sh -c " + # IP branch: http:// → https:// + sed -i 's|t=\`http://\${r}:9090\`,i=\`http://\${r}:9000\`|t=\`https://\${r}:9090\`,i=\`https://\${r}:9000\`|g' $JS + # Domain branch: no-port https:// → explicit :9090/:9000 + sed -i 's|t=\`https://\${r}\`,i=\`https://\${r}\`|t=\`https://\${r}:9090\`,i=\`https://\${r}:9000\`|g' $JS +" +``` + +> **Root fix**: The mc-cost-optimizer-fe source code needs to be updated so it always uses `https://{host}:9090` for IP and domain cases. See `todo_mc-cost-optimizer.md` for the development team handoff. + +### HSTS Cache — switching between dev and prod on the same domain + +When you switch from Mode A (self-signed cert) to Mode B (Let's Encrypt) using the same domain, the browser's HSTS cache may block the connection during the transition. + +**Workaround**: +1. Use an incognito/private window for the first access after switching, **or** +2. Clear the HSTS cache manually: + - **Chrome/Edge**: navigate to `chrome://net-internals/#hsts` → "Delete domain security policies" → enter your domain → Delete + - **Firefox**: use a new browser profile or delete `SiteSecurityServiceState.txt` from your profile folder + ## Firewall Port Information @@ -235,12 +279,12 @@ The following ports should be registered in the firewall if needed: ### **MC-COST-OPTIMIZER** | Service | Port | Protocol | Description | |---------|------|----------|-------------| -| mc-cost-optimizer-fe | 7780 | TCP | Cost Optimizer Frontend | -| mc-cost-optimizer-be | 9090 | TCP | Cost Optimizer Backend | +| mc-cost-optimizer-fe | 7780 | TCP | Cost Optimizer Frontend (internal, accessed via :7781 HTTPS proxy) | +| mc-cost-optimizer-be | 9090 | TCP | Cost Optimizer Backend (internal, accessed via IAM nginx :9090 HTTPS proxy) | | mc-cost-optimizer-cost-collector | 8881 | TCP | Cost Collector | | mc-cost-optimizer-cost-processor | 18082 | TCP | Cost Processor | | mc-cost-optimizer-cost-selector | 8083 | TCP | Cost Selector | -| mc-cost-optimizer-alarm-service | 9000 | TCP | Alarm Service | +| mc-cost-optimizer-alarm-service | 9000 | TCP | Alarm Service (internal, accessed via IAM nginx :9000 HTTPS proxy) | | mc-cost-optimizer-asset-collector | 8091 | TCP | Asset Collector | | mc-cost-optimizer-db | 3307 | TCP | MariaDB | @@ -295,10 +339,11 @@ The following ports must be registered in the firewall: |---------|------|----------|-------------| | mc-iam-manager-nginx | 80, 443 | TCP | Nginx entry point (HTTP redirect + HTTPS web console) | | mc-iam-manager-nginx | 3001 | TCP | Web Console Frontend (HTTPS) | -| mc-iam-manager-nginx | 33002 | TCP | Grafana iframe proxy (HTTPS) — Mode B | -| mc-iam-manager-nginx | 7781 | TCP | Cost Optimizer FE iframe proxy (HTTPS) — Mode B | +| mc-iam-manager-nginx | 33002 | TCP | Grafana iframe proxy (HTTPS) | +| mc-iam-manager-nginx | 7781 | TCP | Cost Optimizer FE iframe proxy (HTTPS) | +| mc-iam-manager-nginx | 9090 | TCP | Cost Optimizer BE HTTPS proxy (required for iframe API calls) | +| mc-iam-manager-nginx | 9000 | TCP | Cost Optimizer alarm HTTPS proxy (required for iframe API calls) | | mc-web-console-api | 3000 | TCP | Web Console API | -| mc-cost-optimizer-fe | 7780 | TCP | Cost Optimizer Frontend (direct HTTP) | --- diff --git a/README_kr.md b/README_kr.md index acd306f..88d13ca 100644 --- a/README_kr.md +++ b/README_kr.md @@ -160,8 +160,10 @@ docker logs mc-iam-manager-post-initial | tail -5 ```shell curl -kI https://:33002 # Grafana 대시보드 프록시 curl -kI https://:7781 # Cost Optimizer FE 프록시 +curl -k https://:9090/api/costopti/be/readyz # Cost Optimizer BE 프록시 +curl -k https://:9000/actuator/health 2>/dev/null || true # Cost Optimizer alarm 프록시 ``` -기대 응답: 두 엔드포인트 모두 `HTTP/2 200` +기대 응답: `:33002` 및 `:7781`은 `HTTP/2 200`; `:9090/readyz`는 `Application is ready`. ## Step 6. CB-Tumblebug 초기화 및 웹 콘솔 접속 @@ -184,6 +186,48 @@ cd mc-admin-cli/bin ./cleanAll.sh ``` +> **cleanAll.sh를 실행해야 하는 경우**: 배포 모드 전환(dev ↔ prod)이나 도메인 변경 전에는 반드시 완전 초기화를 실행하세요. 기존 설정 위에 `installAll.sh`를 재실행하면 이전 인증서, nginx 설정, DB 상태가 충돌할 수 있습니다. + +--- + +## 알려진 이슈 + +### Cost Optimizer iframe — BE API (컨테이너 재생성 후 패치 필요) + +Cost Optimizer 프론트엔드 JavaScript 번들에는 런타임에 백엔드 API 호스트를 결정하는 로직이 하드코딩되어 있습니다: + +| 접속 방식 | 선택되는 BE/alarm URL | 결과 | +|---|---|---| +| `localhost` | `http://localhost:9090` | 정상 (동일 출처, TLS 불필요) | +| IP 주소 | `https://{ip}:9090` | 정상 — IAM nginx HTTPS 프록시(:9090) 경유 | +| 도메인 | `https://{domain}:9090` | 정상 — IAM nginx HTTPS 프록시(:9090) 경유 | + +**컨테이너 재생성 후 매번** 아래 in-place 패치를 적용해야 합니다: + +```bash +# 실제 번들 파일명 먼저 확인 +JS=$(docker exec mc-cost-optimizer-fe ls /usr/share/nginx/html/assets/index-*.js 2>/dev/null | head -1) + +docker exec mc-cost-optimizer-fe sh -c " + # IP 분기: http:// → https:// + sed -i 's|t=\`http://\${r}:9090\`,i=\`http://\${r}:9000\`|t=\`https://\${r}:9090\`,i=\`https://\${r}:9000\`|g' $JS + # 도메인 분기: 포트 없는 https:// → 명시적 :9090/:9000 + sed -i 's|t=\`https://\${r}\`,i=\`https://\${r}\`|t=\`https://\${r}:9090\`,i=\`https://\${r}:9000\`|g' $JS +" +``` + +> **근본 해결**: mc-cost-optimizer-fe 소스 코드에서 IP/도메인 분기 모두 `https://{host}:9090`을 사용하도록 수정 후 재빌드가 필요합니다. 개발팀 전달 사항은 `todo_mc-cost-optimizer.md` 참조. + +### HSTS 캐시 — 동일 도메인에서 dev ↔ prod 전환 시 + +Mode A(자체 서명 인증서) → Mode B(Let's Encrypt)로 같은 도메인을 사용해 전환할 경우, 브라우저의 HSTS 캐시로 인해 접속이 차단될 수 있습니다. + +**해결 방법**: +1. 전환 후 첫 접속에 시크릿/프라이빗 창 사용, **또는** +2. HSTS 캐시 수동 삭제: + - **Chrome/Edge**: `chrome://net-internals/#hsts` → "Delete domain security policies" → 도메인 입력 → Delete + - **Firefox**: 새 브라우저 프로파일 사용 또는 프로파일 폴더의 `SiteSecurityServiceState.txt` 삭제 + ## 방화벽 포트 정보 @@ -216,12 +260,12 @@ cd mc-admin-cli/bin ### **MC-COST-OPTIMIZER** | 서비스 | 포트 | 프로토콜 | 설명 | |---------|------|----------|-------------| -| mc-cost-optimizer-fe | 7780 | TCP | Cost Optimizer Frontend | -| mc-cost-optimizer-be | 9090 | TCP | Cost Optimizer Backend | +| mc-cost-optimizer-fe | 7780 | TCP | Cost Optimizer Frontend (내부 전용, :7781 HTTPS 프록시로 접근) | +| mc-cost-optimizer-be | 9090 | TCP | Cost Optimizer Backend (내부 전용, IAM nginx :9090 HTTPS 프록시로 접근) | | mc-cost-optimizer-cost-collector | 8881 | TCP | Cost Collector | | mc-cost-optimizer-cost-processor | 18082 | TCP | Cost Processor | | mc-cost-optimizer-cost-selector | 8083 | TCP | Cost Selector | -| mc-cost-optimizer-alarm-service | 9000 | TCP | Alarm Service | +| mc-cost-optimizer-alarm-service | 9000 | TCP | Alarm Service (내부 전용, IAM nginx :9000 HTTPS 프록시로 접근) | | mc-cost-optimizer-asset-collector | 8091 | TCP | Asset Collector | | mc-cost-optimizer-db | 3307 | TCP | MariaDB | @@ -276,10 +320,11 @@ cd mc-admin-cli/bin |---------|------|----------|-------------| | mc-iam-manager-nginx | 80, 443 | TCP | Nginx 진입점 (HTTP 리다이렉트 + HTTPS 웹 콘솔) | | mc-iam-manager-nginx | 3001 | TCP | 웹 콘솔 프론트엔드 (HTTPS) | -| mc-iam-manager-nginx | 33002 | TCP | Grafana iframe 프록시 (HTTPS) — Mode B | -| mc-iam-manager-nginx | 7781 | TCP | Cost Optimizer FE iframe 프록시 (HTTPS) — Mode B | +| mc-iam-manager-nginx | 33002 | TCP | Grafana iframe 프록시 (HTTPS) | +| mc-iam-manager-nginx | 7781 | TCP | Cost Optimizer FE iframe 프록시 (HTTPS) | +| mc-iam-manager-nginx | 9090 | TCP | Cost Optimizer BE HTTPS 프록시 (iframe API 호출에 필요) | +| mc-iam-manager-nginx | 9000 | TCP | Cost Optimizer alarm HTTPS 프록시 (iframe API 호출에 필요) | | mc-web-console-api | 3000 | TCP | Web Console API | -| mc-cost-optimizer-fe | 7780 | TCP | Cost Optimizer Frontend (직접 HTTP) | --- diff --git a/conf/docker/conf/mc-iam-manager/.env b/conf/docker/conf/mc-iam-manager/.env index 5266680..db00cf8 100644 --- a/conf/docker/conf/mc-iam-manager/.env +++ b/conf/docker/conf/mc-iam-manager/.env @@ -86,9 +86,12 @@ CSP_ROLE_PREFIX=mciam # === 외부 노출 도메인 (브라우저 ↔ nginx HTTPS) === # Mode A (도메인 없음): 로컬 자가서명 인증서. 0_preset_dev.sh 로 생성. -# Mode A (도메인 없음): 로컬 자가서명 인증서. 0_preset_dev.sh 로 생성. # MC_IAM_MANAGER_PUBLIC_DOMAIN=mciam.local # Mode B (운영): 아래 주석 해제 후 FQDN 설정. 0_preset_prod.sh + Let's Encrypt 필요. -MC_IAM_MANAGER_PUBLIC_DOMAIN=mciam.onecloudcon.com +# MC_IAM_MANAGER_PUBLIC_DOMAIN= +MC_IAM_MANAGER_PUBLIC_DOMAIN=mciam.local MC_IAM_MANAGER_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN} MC_IAM_MANAGER_PUBLIC_KEYCLOAK_HOST=${MC_IAM_MANAGER_PUBLIC_HOST}/auth + +# === 외부 iframe 프록시 포트 === +MC_COST_OPTIMIZER_FE_PROXY_PORT=7781 diff --git a/conf/docker/conf/mc-iam-manager/.env.setup b/conf/docker/conf/mc-iam-manager/.env.setup index fe8c016..db3877f 100644 --- a/conf/docker/conf/mc-iam-manager/.env.setup +++ b/conf/docker/conf/mc-iam-manager/.env.setup @@ -84,3 +84,6 @@ MC_IAM_MANAGER_PUBLIC_DOMAIN=mciam.local # MC_IAM_MANAGER_PUBLIC_DOMAIN= MC_IAM_MANAGER_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN} MC_IAM_MANAGER_PUBLIC_KEYCLOAK_HOST=${MC_IAM_MANAGER_PUBLIC_HOST}/auth + +# === 외부 iframe 프록시 포트 (docker-compose.yaml의 PROXY_PORT 값과 동일하게 유지) === +MC_COST_OPTIMIZER_FE_PROXY_PORT=7781 diff --git a/conf/docker/conf/mc-iam-manager/0_preset_dev.sh b/conf/docker/conf/mc-iam-manager/0_preset_dev.sh index e87ffd7..936d87f 100755 --- a/conf/docker/conf/mc-iam-manager/0_preset_dev.sh +++ b/conf/docker/conf/mc-iam-manager/0_preset_dev.sh @@ -137,28 +137,40 @@ echo "✓ Certificate directory created successfully" ## 로컬환경(인증서) 설정 -# --- 3. hosts 파일에 도메인 추가 (관리자 권한 필요) --- -HOSTS_FILE="/etc/hosts" -echo "Checking ${MC_IAM_MANAGER_PUBLIC_DOMAIN} in ${HOSTS_FILE}..." - -if grep -E "^[[:space:]]*127\.0\.0\.1[[:space:]]+${MC_IAM_MANAGER_PUBLIC_DOMAIN}[[:space:]]*$" "${HOSTS_FILE}" > /dev/null; then - echo "✓ ${MC_IAM_MANAGER_PUBLIC_DOMAIN} already exists in ${HOSTS_FILE}. Skipping." +# IP 주소인지 도메인인지 판별 +if [[ "${MC_IAM_MANAGER_PUBLIC_DOMAIN}" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + IS_IP=true + SAN_ENTRY="IP:${MC_IAM_MANAGER_PUBLIC_DOMAIN}" + echo "✓ PUBLIC_DOMAIN is an IP address — skipping /etc/hosts modification" else - echo "Removing any existing entries for ${MC_IAM_MANAGER_PUBLIC_DOMAIN}..." - sed -i "/[[:space:]]*127\.0\.0\.1[[:space:]]\+${MC_IAM_MANAGER_PUBLIC_DOMAIN}[[:space:]]*$/d" "${HOSTS_FILE}" + IS_IP=false + SAN_ENTRY="DNS:${MC_IAM_MANAGER_PUBLIC_DOMAIN}" +fi + +# --- 3. hosts 파일에 도메인 추가 (도메인인 경우에만) --- +if [ "$IS_IP" = false ]; then + HOSTS_FILE="/etc/hosts" + echo "Checking ${MC_IAM_MANAGER_PUBLIC_DOMAIN} in ${HOSTS_FILE}..." - echo "Adding 127.0.0.1 ${MC_IAM_MANAGER_PUBLIC_DOMAIN} to ${HOSTS_FILE}..." - if echo "127.0.0.1 ${MC_IAM_MANAGER_PUBLIC_DOMAIN}" >> "${HOSTS_FILE}" 2>/dev/null; then - echo "✓ ${MC_IAM_MANAGER_PUBLIC_DOMAIN} added successfully to ${HOSTS_FILE}." + if grep -E "^[[:space:]]*127\.0\.0\.1[[:space:]]+${MC_IAM_MANAGER_PUBLIC_DOMAIN}[[:space:]]*$" "${HOSTS_FILE}" > /dev/null; then + echo "✓ ${MC_IAM_MANAGER_PUBLIC_DOMAIN} already exists in ${HOSTS_FILE}. Skipping." else - echo "⚠️ Failed to add to ${HOSTS_FILE} — run with sudo or manually add:" - echo " echo '127.0.0.1 ${MC_IAM_MANAGER_PUBLIC_DOMAIN}' | sudo tee -a ${HOSTS_FILE}" + echo "Removing any existing entries for ${MC_IAM_MANAGER_PUBLIC_DOMAIN}..." + sed -i "/[[:space:]]*127\.0\.0\.1[[:space:]]\+${MC_IAM_MANAGER_PUBLIC_DOMAIN}[[:space:]]*$/d" "${HOSTS_FILE}" + + echo "Adding 127.0.0.1 ${MC_IAM_MANAGER_PUBLIC_DOMAIN} to ${HOSTS_FILE}..." + if echo "127.0.0.1 ${MC_IAM_MANAGER_PUBLIC_DOMAIN}" >> "${HOSTS_FILE}" 2>/dev/null; then + echo "✓ ${MC_IAM_MANAGER_PUBLIC_DOMAIN} added successfully to ${HOSTS_FILE}." + else + echo "⚠️ Failed to add to ${HOSTS_FILE} — run with sudo or manually add:" + echo " echo '127.0.0.1 ${MC_IAM_MANAGER_PUBLIC_DOMAIN}' | sudo tee -a ${HOSTS_FILE}" + fi fi fi -# --- 4. Self-Signed Certificate 생성 --- -echo "Generating Self-Signed Certificate for ${MC_IAM_MANAGER_PUBLIC_DOMAIN}... ${CERT_DIR}" +# --- 4. Self-Signed Certificate 생성 (SAN 포함) --- +echo "Generating Self-Signed Certificate for ${MC_IAM_MANAGER_PUBLIC_DOMAIN} (SAN: ${SAN_ENTRY})... ${CERT_DIR}" # 기존 인증서 삭제 (새로 발급하기 위해) if [ -f "${CERT_DIR}/privkey.pem" ]; then @@ -168,8 +180,12 @@ fi openssl genrsa -out "${CERT_DIR}/privkey.pem" 2048 openssl req -new -key "${CERT_DIR}/privkey.pem" -out "${CERT_DIR}/csr.pem" -subj "/CN=${MC_IAM_MANAGER_PUBLIC_DOMAIN}" -openssl x509 -req -days 365 -in "${CERT_DIR}/csr.pem" -signkey "${CERT_DIR}/privkey.pem" -out "${CERT_DIR}/fullchain.pem" -rm "${CERT_DIR}/csr.pem" # CSR 파일 제거 +openssl x509 -req -days 365 \ + -in "${CERT_DIR}/csr.pem" \ + -signkey "${CERT_DIR}/privkey.pem" \ + -out "${CERT_DIR}/fullchain.pem" \ + -extfile <(printf "subjectAltName=${SAN_ENTRY}\nbasicConstraints=CA:FALSE\nkeyUsage=digitalSignature,keyEncipherment") +rm "${CERT_DIR}/csr.pem" if [ -f "${CERT_DIR}/fullchain.pem" ]; then echo "Self-Signed Certificate generated successfully at ${CERT_DIR}." @@ -206,6 +222,8 @@ if [ -n "$MC_IAM_MANAGER_PUBLIC_DOMAIN" ] && [ -n "$MC_IAM_MANAGER_KEYCLOAK_PORT -e "s/\${MC_IAM_MANAGER_KEYCLOAK_PORT}/$MC_IAM_MANAGER_KEYCLOAK_PORT/g" \ -e "s/\${MC_OBSERVABILITY_GRAFANA_PROXY_PORT}/$MC_OBSERVABILITY_GRAFANA_PROXY_PORT/g" \ -e "s/\${MC_COST_OPTIMIZER_FE_PROXY_PORT}/$MC_COST_OPTIMIZER_FE_PROXY_PORT/g" \ + -e "s/\${MC_COST_OPTIMIZER_BE_PORT}/$MC_COST_OPTIMIZER_BE_PORT/g" \ + -e "s/\${MC_COST_OPTIMIZER_ALARM_PORT}/$MC_COST_OPTIMIZER_ALARM_PORT/g" \ -e "s/mciam-manager/mc-iam-manager/g" \ -e "s/mciam-keycloak/mc-iam-manager-kc/g" \ "$TEMPLATE_FILE" > "$OUTPUT_FILE" diff --git a/conf/docker/conf/mc-iam-manager/0_preset_prod.sh b/conf/docker/conf/mc-iam-manager/0_preset_prod.sh index 4511cd5..97d6a9a 100755 --- a/conf/docker/conf/mc-iam-manager/0_preset_prod.sh +++ b/conf/docker/conf/mc-iam-manager/0_preset_prod.sh @@ -101,6 +101,23 @@ else echo "경고: MC_COST_OPTIMIZER_FE_PROXY_PORT 환경변수가 설정되지 않았습니다." fi +MC_COST_OPTIMIZER_BE_PORT=$(grep -m1 "^MC_COST_OPTIMIZER_BE_PORT=" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'" | xargs) +MC_COST_OPTIMIZER_ALARM_PORT=$(grep -m1 "^MC_COST_OPTIMIZER_ALARM_PORT=" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'" | xargs) + +if [ -n "$MC_COST_OPTIMIZER_BE_PORT" ]; then + sed -i "s/\${MC_COST_OPTIMIZER_BE_PORT}/$MC_COST_OPTIMIZER_BE_PORT/g" "$OUTPUT_FILE" + echo "✓ MC_COST_OPTIMIZER_BE_PORT 대치 완료: $MC_COST_OPTIMIZER_BE_PORT" +else + echo "경고: MC_COST_OPTIMIZER_BE_PORT 환경변수가 설정되지 않았습니다." +fi + +if [ -n "$MC_COST_OPTIMIZER_ALARM_PORT" ]; then + sed -i "s/\${MC_COST_OPTIMIZER_ALARM_PORT}/$MC_COST_OPTIMIZER_ALARM_PORT/g" "$OUTPUT_FILE" + echo "✓ MC_COST_OPTIMIZER_ALARM_PORT 대치 완료: $MC_COST_OPTIMIZER_ALARM_PORT" +else + echo "경고: MC_COST_OPTIMIZER_ALARM_PORT 환경변수가 설정되지 않았습니다." +fi + # 컨테이너 이름 치환 (템플릿 내 레거시 이름 정정) sed -i "s/mciam-manager/mc-iam-manager/g" "$OUTPUT_FILE" sed -i "s/mciam-keycloak/mc-iam-manager-kc/g" "$OUTPUT_FILE" diff --git a/conf/docker/conf/mc-iam-manager/1_setup_auto.sh b/conf/docker/conf/mc-iam-manager/1_setup_auto.sh index 05413b5..f3ba3ce 100755 --- a/conf/docker/conf/mc-iam-manager/1_setup_auto.sh +++ b/conf/docker/conf/mc-iam-manager/1_setup_auto.sh @@ -61,6 +61,15 @@ auto_setup() { fi echo "✓ Framework services registered successfully" + # 5-2. iframe 서비스 URL을 브라우저 접근 가능한 외부 주소로 갱신 + echo "Step 5-2: Updating iframe service URLs to public addresses..." + update_public_service_urls + if [ $? -ne 0 ]; then + echo "WARNING: Public service URL update failed (non-fatal, iframe may not render remotely)" + else + echo "✓ Public service URLs updated successfully" + fi + # 6. 프로젝트 동기화 echo "Step 6: Syncing projects..." sync_projects @@ -453,6 +462,58 @@ register_framework_services() { return 0 } +update_public_service_urls() { + echo "Updating framework service URLs to public-accessible addresses..." + + # mc-cost-optimizer-fe: 컨테이너 내부 URL(http://mc-cost-optimizer-fe:7780)을 + # 브라우저가 직접 접근 가능한 nginx HTTPS 프록시 URL로 갱신. + # MCIAM_USE=true 환경에서 /api/getapihosts가 이 값을 iframe src로 반환하기 때문. + local cost_fe_public_url="https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_COST_OPTIMIZER_FE_PROXY_PORT}" + + # mc-cost-optimizer-fe는 upstream api.yaml에 없으므로 먼저 등록 시도(idempotent) + local reg_body + reg_body=$(printf '{"name":"mc-cost-optimizer-fe","version":"v1","baseUrl":"http://mc-cost-optimizer-fe:7780","authType":"none","authUser":"","authPass":"","isActive":true}') + local reg_resp + reg_resp=$(curl -s -w "HTTPSTATUS:%{http_code}" -X POST \ + --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ + --header 'Content-Type: application/json' \ + --data "$reg_body" \ + "$MC_IAM_MANAGER_HOST/api/mcmp-apis") + local reg_code + reg_code=$(echo $reg_resp | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') + if [ "$reg_code" = "201" ]; then + echo " ✓ mc-cost-optimizer-fe registered" + elif [ "$reg_code" = "409" ]; then + echo " ✓ mc-cost-optimizer-fe already registered" + else + echo " ✗ Failed to register mc-cost-optimizer-fe (HTTP $reg_code)" + return 1 + fi + + # baseurl을 외부 공개 URL로 갱신 + local response + response=$(curl -s -w "HTTPSTATUS:%{http_code}" -X PUT \ + --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ + --header 'Content-Type: application/json' \ + --data "{\"base_url\": \"${cost_fe_public_url}\"}" \ + "$MC_IAM_MANAGER_HOST/api/mcmp-apis/name/mc-cost-optimizer-fe") + + local http_code + http_code=$(echo $response | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') + local response_body + response_body=$(echo $response | sed -e 's/HTTPSTATUS\:.*//g') + + if [ "$http_code" = "200" ]; then + echo " ✓ Updated mc-cost-optimizer-fe baseurl: ${cost_fe_public_url}" + else + echo " ✗ Failed to update mc-cost-optimizer-fe (HTTP $http_code): $response_body" + return 1 + fi + + echo "Public service URL update completed" + return 0 +} + init_cloud_resources() { echo "Initializing cloud resources..." response=$(curl -s -X POST \ diff --git a/conf/docker/conf/mc-iam-manager/nginx.template.conf b/conf/docker/conf/mc-iam-manager/nginx.template.conf index 292d935..a2506ee 100644 --- a/conf/docker/conf/mc-iam-manager/nginx.template.conf +++ b/conf/docker/conf/mc-iam-manager/nginx.template.conf @@ -196,6 +196,58 @@ http { } } + # mc-cost-optimizer-be HTTPS proxy (IP 접속 시 Mixed Content 방지) + server { + listen ${MC_COST_OPTIMIZER_BE_PORT} ssl; + server_name ${MC_IAM_MANAGER_PUBLIC_DOMAIN}; + + ssl_certificate /etc/nginx/certs/live/${MC_IAM_MANAGER_PUBLIC_DOMAIN}/fullchain.pem; + ssl_certificate_key /etc/nginx/certs/live/${MC_IAM_MANAGER_PUBLIC_DOMAIN}/privkey.pem; + + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + location / { + resolver 127.0.0.11 valid=10s; + set $upstream_cost_be mc-cost-optimizer-be; + proxy_pass http://$upstream_cost_be:9090; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + } + + # mc-cost-optimizer-alarm HTTPS proxy (IP 접속 시 Mixed Content 방지) + server { + listen ${MC_COST_OPTIMIZER_ALARM_PORT} ssl; + server_name ${MC_IAM_MANAGER_PUBLIC_DOMAIN}; + + ssl_certificate /etc/nginx/certs/live/${MC_IAM_MANAGER_PUBLIC_DOMAIN}/fullchain.pem; + ssl_certificate_key /etc/nginx/certs/live/${MC_IAM_MANAGER_PUBLIC_DOMAIN}/privkey.pem; + + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + location / { + resolver 127.0.0.11 valid=10s; + set $upstream_cost_alarm mc-cost-optimizer-alarm-service; + proxy_pass http://$upstream_cost_alarm:9000; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + } + # mc-cost-optimizer-fe HTTPS proxy (iframe/외부 진입용) server { listen ${MC_COST_OPTIMIZER_FE_PROXY_PORT} ssl; @@ -219,7 +271,7 @@ http { proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-Host $host; proxy_hide_header X-Frame-Options; - add_header X-Frame-Options "SAMEORIGIN" always; + add_header Content-Security-Policy "frame-ancestors https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:3001 https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}" always; proxy_connect_timeout 60s; proxy_send_timeout 60s; diff --git a/conf/docker/docker-compose.yaml b/conf/docker/docker-compose.yaml index 5cfc80e..75eac04 100644 --- a/conf/docker/docker-compose.yaml +++ b/conf/docker/docker-compose.yaml @@ -340,6 +340,8 @@ services: - "${MC_WEB_CONSOLE_FRONT_PORT}:${MC_WEB_CONSOLE_FRONT_PORT}" - "${MC_OBSERVABILITY_GRAFANA_PROXY_PORT}:${MC_OBSERVABILITY_GRAFANA_PROXY_PORT}" - "${MC_COST_OPTIMIZER_FE_PROXY_PORT}:${MC_COST_OPTIMIZER_FE_PROXY_PORT}" + - "${MC_COST_OPTIMIZER_BE_PORT}:${MC_COST_OPTIMIZER_BE_PORT}" + - "${MC_COST_OPTIMIZER_ALARM_PORT}:${MC_COST_OPTIMIZER_ALARM_PORT}" environment: - DOMAIN_NAME=${MC_IAM_MANAGER_PUBLIC_DOMAIN} volumes: @@ -408,10 +410,6 @@ services: - mc-observability-network - mc-infra-manager-network - mc-web-console-network - ports: - - target: 9090 - published: ${MC_COST_OPTIMIZER_BE_PORT} - protocol: tcp depends_on: - mc-cost-optimizer-db volumes: @@ -518,10 +516,6 @@ services: - mc-observability-network - mc-infra-manager-network - mc-web-console-network - ports: - - target: 9000 - published: ${MC_COST_OPTIMIZER_ALARM_PORT} - protocol: tcp depends_on: - mc-cost-optimizer-db volumes: From 667b083a29a7aaeab799d11fa98241b584590994 Mon Sep 17 00:00:00 2001 From: raccoon-mh Date: Sun, 17 May 2026 04:30:51 +0000 Subject: [PATCH 2/9] fix(certbot): switch to webroot authenticator and add nginx reload hook - conf/docker/scripts/certbot-deploy-hook.sh: new deploy hook that runs `docker exec mc-iam-manager-nginx nginx -s reload` after each renewal so the new certificate is applied without container restart - README / README_kr: add "TLS Certificate Auto-Renewal (Mode B)" section documenting the one-time webroot migration command, deploy hook installation, and dry-run verification step Background: the default standalone authenticator requires port 80 to be free, but mc-iam-manager-nginx holds :80 permanently. Auto-renewal would fail silently every run. nginx already serves /.well-known/acme-challenge/ via the certbot/www volume, so webroot renewal works without stopping nginx. --- README.md | 42 ++++++++++++++++++++++ README_kr.md | 42 ++++++++++++++++++++++ conf/docker/scripts/certbot-deploy-hook.sh | 10 ++++++ 3 files changed, 94 insertions(+) create mode 100644 conf/docker/scripts/certbot-deploy-hook.sh diff --git a/README.md b/README.md index 0f6097f..342ea0b 100644 --- a/README.md +++ b/README.md @@ -204,6 +204,48 @@ cd mc-admin-cli/bin ``` +## TLS Certificate Auto-Renewal (Mode B) + +When running in Mode B (Let's Encrypt), certbot renews the certificate automatically via `systemd certbot.timer` (twice daily). The certificate is renewed 30 days before expiry. + +### Webroot setup (required once after installation) + +Mode B uses the **webroot** authenticator so nginx keeps running during renewal. If your installation used the `standalone` authenticator (older setup), switch it once: + +```shell +sudo certbot certonly \ + --webroot \ + -w /conf/docker/container-volume/certbot/www \ + -d \ + --force-renewal +``` + +Verify the renewal config was updated: + +```shell +sudo grep "authenticator" /etc/letsencrypt/renewal/.conf +# Expected: authenticator = webroot +``` + +### Deploy hook — nginx reload after renewal + +After renewal, the new certificate must be loaded into the running nginx container. Install the deploy hook once: + +```shell +sudo cp conf/docker/scripts/certbot-deploy-hook.sh \ + /etc/letsencrypt/renewal-hooks/deploy/reload-nginx-docker.sh +sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx-docker.sh +``` + +### Verify auto-renewal + +```shell +sudo certbot renew --dry-run +# Expected: "all simulated renewals succeeded" +``` + +--- + ## Firewall Port Information The following ports should be registered in the firewall if needed: diff --git a/README_kr.md b/README_kr.md index acd306f..f98833e 100644 --- a/README_kr.md +++ b/README_kr.md @@ -185,6 +185,48 @@ cd mc-admin-cli/bin ``` +## TLS 인증서 자동갱신 (Mode B) + +Mode B(Let's Encrypt) 실행 시 certbot이 `systemd certbot.timer`를 통해 하루 2회 자동갱신을 시도합니다. 만료 30일 전부터 갱신이 시작됩니다. + +### Webroot 방식 전환 (최초 1회 필요) + +Mode B는 갱신 중에도 nginx가 계속 실행될 수 있도록 **webroot** 인증 방식을 사용합니다. 기존 `standalone` 방식으로 설치된 경우 아래 명령으로 한 번 전환해야 합니다: + +```shell +sudo certbot certonly \ + --webroot \ + -w /conf/docker/container-volume/certbot/www \ + -d \ + --force-renewal +``` + +전환 확인: + +```shell +sudo grep "authenticator" /etc/letsencrypt/renewal/.conf +# 기대값: authenticator = webroot +``` + +### Deploy Hook — 갱신 후 nginx 자동 reload + +인증서 갱신 후 nginx 컨테이너에 새 인증서를 즉시 적용하기 위한 deploy hook을 한 번 설치합니다: + +```shell +sudo cp conf/docker/scripts/certbot-deploy-hook.sh \ + /etc/letsencrypt/renewal-hooks/deploy/reload-nginx-docker.sh +sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx-docker.sh +``` + +### 자동갱신 검증 + +```shell +sudo certbot renew --dry-run +# 기대값: "all simulated renewals succeeded" +``` + +--- + ## 방화벽 포트 정보 필요한 경우 다음 포트들을 방화벽에 등록해야 합니다: diff --git a/conf/docker/scripts/certbot-deploy-hook.sh b/conf/docker/scripts/certbot-deploy-hook.sh new file mode 100644 index 0000000..47f0d87 --- /dev/null +++ b/conf/docker/scripts/certbot-deploy-hook.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# certbot deploy hook — reload mc-iam-manager-nginx after certificate renewal. +# +# Install once: +# sudo cp conf/docker/scripts/certbot-deploy-hook.sh \ +# /etc/letsencrypt/renewal-hooks/deploy/reload-nginx-docker.sh +# sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx-docker.sh +docker exec mc-iam-manager-nginx nginx -s reload 2>/dev/null \ + && echo "[certbot-deploy] mc-iam-manager-nginx reloaded successfully" \ + || echo "[certbot-deploy] WARNING: failed to reload mc-iam-manager-nginx (container may not be running)" From 2f99cf7a257f562c13f24cca5d04dc8ecf7fbda6 Mon Sep 17 00:00:00 2001 From: raccoon-mh Date: Sun, 17 May 2026 06:41:00 +0000 Subject: [PATCH 3/9] fix(keycloak): set realm frontendUrl in configure_keycloak_client_uris MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keycloak의 realm Frontend URL이 설정되지 않으면 토큰의 iss 클레임이 내부 호스트명(mc-iam-manager-kc:8080)으로 발급되어 외부 도메인으로 접근 시 kc_id 조회 실패로 workspace/project 조회가 빈 배열을 반환하는 문제가 있었음. configure_keycloak_client_uris 실행 시 realm frontendUrl을 MC_IAM_MANAGER_PUBLIC_HOST로 갱신하여 올바른 iss 클레임이 발급되도록 수정. --- conf/docker/conf/mc-iam-manager/1_setup_auto.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/conf/docker/conf/mc-iam-manager/1_setup_auto.sh b/conf/docker/conf/mc-iam-manager/1_setup_auto.sh index f3ba3ce..2b50c4e 100755 --- a/conf/docker/conf/mc-iam-manager/1_setup_auto.sh +++ b/conf/docker/conf/mc-iam-manager/1_setup_auto.sh @@ -644,6 +644,18 @@ configure_keycloak_client_uris() { KC_ADMIN_URL="${MC_IAM_MANAGER_KEYCLOAK_HOST}/admin/realms/${MC_IAM_MANAGER_KEYCLOAK_REALM}" + # Keycloak realm Frontend URL 설정 (토큰 iss 클레임 base URL) + REALM_HTTP=$(curl -s -o /dev/null -w "%{http_code}" -X PUT \ + "${MC_IAM_MANAGER_KEYCLOAK_HOST}/admin/realms/${MC_IAM_MANAGER_KEYCLOAK_REALM}" \ + -H "Authorization: Bearer ${KC_ADMIN_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{\"attributes\": {\"frontendUrl\": \"${MC_IAM_MANAGER_PUBLIC_HOST}\"}}") + if [ "$REALM_HTTP" = "204" ]; then + echo " ✓ Keycloak realm frontendUrl set to ${MC_IAM_MANAGER_PUBLIC_HOST}" + else + echo " ⚠️ Failed to set realm frontendUrl (HTTP $REALM_HTTP) — tokens may use internal iss" + fi + # mciamClient, mciam-oidc-Client 두 클라이언트 설정 for CLIENT_NAME in "$MC_IAM_MANAGER_KEYCLOAK_CLIENT_NAME" "$MC_IAM_MANAGER_KEYCLOAK_OIDC_CLIENT_NAME"; do [ -z "$CLIENT_NAME" ] && continue From 52e737f8f2168e3ac20a0eb18844dc6866b67ac8 Mon Sep 17 00:00:00 2001 From: raccoon-mh Date: Sun, 17 May 2026 07:42:17 +0000 Subject: [PATCH 4/9] docs(installAll): clarify domain/IP input guide for local and remote VM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dev 모드 도메인 입력 시 세 가지 시나리오를 명확히 안내: - Local PC: Enter 키로 mciam.local 기본값 사용 (/etc/hosts 자동 추가) - Remote VM: VM 공인 IP 입력 (자가서명 인증서에 IP SAN 포함) - 도메인 보유 시: prod 모드 사용 (Let's Encrypt) usage 헬프 메시지 및 Examples도 동일하게 업데이트 --- bin/installAll.sh | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/bin/installAll.sh b/bin/installAll.sh index 91dbf94..2762168 100755 --- a/bin/installAll.sh +++ b/bin/installAll.sh @@ -12,9 +12,10 @@ usage() { echo " -m, --mode IAM mode selection (dev|prod)" echo " dev: Developer mode with self-signed certificate (Mode A)" echo " prod: Production mode with Let's Encrypt certificate (Mode B)" - echo " -d, --domain Public domain for HTTPS" - echo " dev default: mciam.local" - echo " prod: required (e.g. iam.example.com)" + echo " -d, --domain Public domain or IP for HTTPS" + echo " dev (local PC): mciam.local (default, added to /etc/hosts)" + echo " dev (remote VM): VM public IP (e.g. 1.2.3.4)" + echo " prod: real FQDN required (e.g. iam.example.com)" echo " -r, --run Service run mode (log|background|skip)" echo " log: Run with log mode" echo " background: Run in background with monitoring" @@ -22,10 +23,10 @@ usage() { echo " -h, --help Display this help message" echo "" echo "Examples:" - echo " $0 -m dev -r background # Mode A with default domain (mciam.local)" - echo " $0 -m dev -d dev.local -r background # Mode A with custom domain" - echo " $0 -m prod -d iam.example.com -r skip # Mode B with real domain" - echo " $0 # Interactive mode" + echo " $0 -m dev -r background # Local PC: default domain (mciam.local)" + echo " $0 -m dev -d 1.2.3.4 -r background # Remote VM: use public IP" + echo " $0 -m prod -d iam.example.com -r background # Remote VM: use real domain + Let's Encrypt" + echo " $0 # Interactive mode" exit 1 } @@ -213,10 +214,17 @@ if [ -z "$IAM_DOMAIN" ]; then echo "==========================================" if [ "$IAM_MODE" = "dev" ]; then echo "" - echo "Mode A: self-signed certificate will be issued for this domain." - echo "Default is 'mciam.local' (added to /etc/hosts automatically)." + echo "Mode A: self-signed certificate will be issued for this domain/IP." echo "" - echo -n "Enter public domain [mciam.local]: " + echo " [Local PC] Just press Enter to use default 'mciam.local'." + echo " (127.0.0.1 mciam.local added to /etc/hosts automatically)" + echo "" + echo " [Remote VM] Enter the VM's public IP (e.g. 43.202.200.215)." + echo " Self-signed cert will include IP SAN." + echo "" + echo " [With Domain] Use Production Mode (-m prod) for Let's Encrypt cert." + echo "" + echo -n "Enter domain or IP [mciam.local]: " read -r IAM_DOMAIN IAM_DOMAIN="${IAM_DOMAIN:-mciam.local}" else From 7b4d228b45fa1ec1e84feaae857e86255ac2b5d8 Mon Sep 17 00:00:00 2001 From: raccoon-mh Date: Wed, 20 May 2026 07:25:59 +0000 Subject: [PATCH 5/9] feat(iframe): add -fe service separation for iframe proxy URLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 브라우저에서 iframe으로 접근하는 서비스(workflows, datamigrations, swcatalogs)가 내부 Docker hostname URL로 인해 빈 화면으로 표시되는 문제를 해결합니다. mc-cost-optimizer-fe 패턴을 3개 서비스에 동일하게 적용합니다. - conf/api.yaml: mc-cost-optimizer-fe, mc-workflow-manager-fe, mc-data-manager-fe, mc-application-manager-fe 서비스 항목 추가 - conf/docker/conf/mc-web-console/api/conf/api.yaml: 동일 -fe 서비스 추가 - conf/docker/conf/mc-iam-manager/nginx.template.conf: 3개 HTTPS 프록시 server block 추가 (포트 18183, 3400, 18184) - conf/docker/docker-compose.yaml: mc-iam-manager-nginx에 3개 포트 바인딩 및 mc-workflow-manager-network, mc-data-manager-network 연결 추가 - conf/docker/conf/mc-iam-manager/.env.setup: PROXY_PORT 3개 변수 추가 - conf/docker/conf/mc-iam-manager/0_preset_dev.sh,0_preset_prod.sh: 신규 포트 변수 sed 치환 처리 추가 - conf/docker/conf/mc-iam-manager/1_setup_auto.sh: update_public_service_urls()에 -fe 서비스 POST 등록 + PUT 외부URL 갱신 추가 (원본 서비스는 내부 URL 유지, -fe 서비스만 외부 HTTPS URL로 설정) - bin/installAll.sh: certbot 인증서 생성 후 container-volume 소유권 복구 추가 --- bin/installAll.sh | 2 + conf/api.yaml | 20 ++++ conf/docker/conf/mc-iam-manager/.env.setup | 3 + .../conf/mc-iam-manager/0_preset_dev.sh | 3 + .../conf/mc-iam-manager/0_preset_prod.sh | 30 +++++- .../conf/mc-iam-manager/1_setup_auto.sh | 94 +++++++++++++++++++ .../conf/mc-iam-manager/nginx.template.conf | 93 ++++++++++++++++++ .../conf/mc-web-console/api/conf/api.yaml | 15 +++ conf/docker/docker-compose.yaml | 7 +- 9 files changed, 264 insertions(+), 3 deletions(-) diff --git a/bin/installAll.sh b/bin/installAll.sh index 91dbf94..4aa795a 100755 --- a/bin/installAll.sh +++ b/bin/installAll.sh @@ -301,6 +301,8 @@ case $IAM_MODE in ./mcc infra run -f ../conf/docker/docker-compose.cert.yaml if [ $? -eq 0 ]; then echo "✓ Certificate generation completed." + # certbot 컨테이너가 root로 생성한 볼륨 디렉토리의 소유권을 현재 사용자로 회수 + sudo chown -R "$USER:$USER" ../conf/docker/container-volume else echo "❌ Error occurred during certificate generation." exit 1 diff --git a/conf/api.yaml b/conf/api.yaml index daaf566..f980f20 100644 --- a/conf/api.yaml +++ b/conf/api.yaml @@ -55,6 +55,26 @@ services: baseurl: http://mc-data-manager:3300 auth: + mc-cost-optimizer-fe: + version: 0.5.2 + baseurl: http://mc-cost-optimizer-fe:7780 + auth: + + mc-workflow-manager-fe: + version: 0.5.1 + baseurl: http://mc-workflow-manager:18083 + auth: + + mc-data-manager-fe: + version: 0.5.3 + baseurl: http://mc-data-manager:3300 + auth: + + mc-application-manager-fe: + version: 0.5.2 + baseurl: http://mc-application-manager:18084 + auth: + # sample: # baseurl: http://localhost:1323/test # auth: diff --git a/conf/docker/conf/mc-iam-manager/.env.setup b/conf/docker/conf/mc-iam-manager/.env.setup index db3877f..9ebbc93 100644 --- a/conf/docker/conf/mc-iam-manager/.env.setup +++ b/conf/docker/conf/mc-iam-manager/.env.setup @@ -87,3 +87,6 @@ MC_IAM_MANAGER_PUBLIC_KEYCLOAK_HOST=${MC_IAM_MANAGER_PUBLIC_HOST}/auth # === 외부 iframe 프록시 포트 (docker-compose.yaml의 PROXY_PORT 값과 동일하게 유지) === MC_COST_OPTIMIZER_FE_PROXY_PORT=7781 +MC_WORKFLOW_MANAGER_PROXY_PORT=18183 +MC_DATA_MANAGER_PROXY_PORT=3400 +MC_APPLICATION_MANAGER_PROXY_PORT=18184 diff --git a/conf/docker/conf/mc-iam-manager/0_preset_dev.sh b/conf/docker/conf/mc-iam-manager/0_preset_dev.sh index 936d87f..f2f75fe 100755 --- a/conf/docker/conf/mc-iam-manager/0_preset_dev.sh +++ b/conf/docker/conf/mc-iam-manager/0_preset_dev.sh @@ -224,6 +224,9 @@ if [ -n "$MC_IAM_MANAGER_PUBLIC_DOMAIN" ] && [ -n "$MC_IAM_MANAGER_KEYCLOAK_PORT -e "s/\${MC_COST_OPTIMIZER_FE_PROXY_PORT}/$MC_COST_OPTIMIZER_FE_PROXY_PORT/g" \ -e "s/\${MC_COST_OPTIMIZER_BE_PORT}/$MC_COST_OPTIMIZER_BE_PORT/g" \ -e "s/\${MC_COST_OPTIMIZER_ALARM_PORT}/$MC_COST_OPTIMIZER_ALARM_PORT/g" \ + -e "s/\${MC_WORKFLOW_MANAGER_PROXY_PORT}/$MC_WORKFLOW_MANAGER_PROXY_PORT/g" \ + -e "s/\${MC_DATA_MANAGER_PROXY_PORT}/$MC_DATA_MANAGER_PROXY_PORT/g" \ + -e "s/\${MC_APPLICATION_MANAGER_PROXY_PORT}/$MC_APPLICATION_MANAGER_PROXY_PORT/g" \ -e "s/mciam-manager/mc-iam-manager/g" \ -e "s/mciam-keycloak/mc-iam-manager-kc/g" \ "$TEMPLATE_FILE" > "$OUTPUT_FILE" diff --git a/conf/docker/conf/mc-iam-manager/0_preset_prod.sh b/conf/docker/conf/mc-iam-manager/0_preset_prod.sh index 97d6a9a..794c496 100755 --- a/conf/docker/conf/mc-iam-manager/0_preset_prod.sh +++ b/conf/docker/conf/mc-iam-manager/0_preset_prod.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -euo pipefail # 템플릿 파일에서 환경변수를 .env 파일의 값으로 대치하는 스크립트 @@ -29,7 +30,7 @@ fi # 출력 디렉토리 생성 OUTPUT_DIR="$(dirname "$OUTPUT_FILE")" -mkdir -p "$OUTPUT_DIR" +mkdir -p "$OUTPUT_DIR" || { echo "오류: 디렉토리를 생성할 수 없습니다: $OUTPUT_DIR (권한 문제일 수 있습니다)"; exit 1; } echo "nginx 설정 파일을 생성합니다..." echo "템플릿: $TEMPLATE_FILE" @@ -57,7 +58,7 @@ echo " MC_OBSERVABILITY_GRAFANA_PROXY_PORT: $MC_OBSERVABILITY_GRAFANA_PROXY_POR echo " MC_COST_OPTIMIZER_FE_PROXY_PORT: $MC_COST_OPTIMIZER_FE_PROXY_PORT" # 템플릿 파일을 복사하고 환경변수 대치 -cp "$TEMPLATE_FILE" "$OUTPUT_FILE" +cp "$TEMPLATE_FILE" "$OUTPUT_FILE" || { echo "오류: 템플릿 파일 복사 실패: $TEMPLATE_FILE → $OUTPUT_FILE"; exit 1; } if [ -n "$MC_IAM_MANAGER_PORT" ]; then sed -i "s/\${MC_IAM_MANAGER_PORT}/$MC_IAM_MANAGER_PORT/g" "$OUTPUT_FILE" @@ -118,6 +119,31 @@ else echo "경고: MC_COST_OPTIMIZER_ALARM_PORT 환경변수가 설정되지 않았습니다." fi +MC_WORKFLOW_MANAGER_PROXY_PORT=$(grep -m1 "^MC_WORKFLOW_MANAGER_PROXY_PORT=" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'" | xargs) +MC_DATA_MANAGER_PROXY_PORT=$(grep -m1 "^MC_DATA_MANAGER_PROXY_PORT=" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'" | xargs) +MC_APPLICATION_MANAGER_PROXY_PORT=$(grep -m1 "^MC_APPLICATION_MANAGER_PROXY_PORT=" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'" | xargs) + +if [ -n "$MC_WORKFLOW_MANAGER_PROXY_PORT" ]; then + sed -i "s/\${MC_WORKFLOW_MANAGER_PROXY_PORT}/$MC_WORKFLOW_MANAGER_PROXY_PORT/g" "$OUTPUT_FILE" + echo "✓ MC_WORKFLOW_MANAGER_PROXY_PORT 대치 완료: $MC_WORKFLOW_MANAGER_PROXY_PORT" +else + echo "경고: MC_WORKFLOW_MANAGER_PROXY_PORT 환경변수가 설정되지 않았습니다." +fi + +if [ -n "$MC_DATA_MANAGER_PROXY_PORT" ]; then + sed -i "s/\${MC_DATA_MANAGER_PROXY_PORT}/$MC_DATA_MANAGER_PROXY_PORT/g" "$OUTPUT_FILE" + echo "✓ MC_DATA_MANAGER_PROXY_PORT 대치 완료: $MC_DATA_MANAGER_PROXY_PORT" +else + echo "경고: MC_DATA_MANAGER_PROXY_PORT 환경변수가 설정되지 않았습니다." +fi + +if [ -n "$MC_APPLICATION_MANAGER_PROXY_PORT" ]; then + sed -i "s/\${MC_APPLICATION_MANAGER_PROXY_PORT}/$MC_APPLICATION_MANAGER_PROXY_PORT/g" "$OUTPUT_FILE" + echo "✓ MC_APPLICATION_MANAGER_PROXY_PORT 대치 완료: $MC_APPLICATION_MANAGER_PROXY_PORT" +else + echo "경고: MC_APPLICATION_MANAGER_PROXY_PORT 환경변수가 설정되지 않았습니다." +fi + # 컨테이너 이름 치환 (템플릿 내 레거시 이름 정정) sed -i "s/mciam-manager/mc-iam-manager/g" "$OUTPUT_FILE" sed -i "s/mciam-keycloak/mc-iam-manager-kc/g" "$OUTPUT_FILE" diff --git a/conf/docker/conf/mc-iam-manager/1_setup_auto.sh b/conf/docker/conf/mc-iam-manager/1_setup_auto.sh index f3ba3ce..726806d 100755 --- a/conf/docker/conf/mc-iam-manager/1_setup_auto.sh +++ b/conf/docker/conf/mc-iam-manager/1_setup_auto.sh @@ -510,6 +510,100 @@ update_public_service_urls() { return 1 fi + # mc-workflow-manager-fe: iframe 전용 nginx HTTPS 프록시 URL 등록 및 갱신 + # (원본 mc-workflow-manager는 내부 API 호출용으로 내부 URL 유지) + local wf_public_url="https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_WORKFLOW_MANAGER_PROXY_PORT}" + reg_body=$(printf '{"name":"mc-workflow-manager-fe","version":"v0.0.1","baseUrl":"http://mc-workflow-manager:18083","authType":"none","authUser":"","authPass":"","isActive":true}') + reg_resp=$(curl -s -w "HTTPSTATUS:%{http_code}" -X POST \ + --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ + --header 'Content-Type: application/json' \ + --data "$reg_body" \ + "$MC_IAM_MANAGER_HOST/api/mcmp-apis") + reg_code=$(echo $reg_resp | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') + if [ "$reg_code" = "201" ]; then + echo " ✓ mc-workflow-manager-fe registered" + elif [ "$reg_code" = "409" ]; then + echo " ✓ mc-workflow-manager-fe already registered" + else + echo " ✗ Failed to register mc-workflow-manager-fe (HTTP $reg_code)" + return 1 + fi + response=$(curl -s -w "HTTPSTATUS:%{http_code}" -X PUT \ + --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ + --header 'Content-Type: application/json' \ + --data "{\"base_url\": \"${wf_public_url}\"}" \ + "$MC_IAM_MANAGER_HOST/api/mcmp-apis/name/mc-workflow-manager-fe") + http_code=$(echo $response | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') + response_body=$(echo $response | sed -e 's/HTTPSTATUS\:.*//g') + if [ "$http_code" = "200" ]; then + echo " ✓ Updated mc-workflow-manager-fe baseurl: ${wf_public_url}" + else + echo " ✗ Failed to update mc-workflow-manager-fe (HTTP $http_code): $response_body" + return 1 + fi + + # mc-data-manager-fe: iframe 전용 nginx HTTPS 프록시 URL 등록 및 갱신 + local dm_public_url="https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_DATA_MANAGER_PROXY_PORT}" + reg_body=$(printf '{"name":"mc-data-manager-fe","version":"v0.0.1","baseUrl":"http://mc-data-manager:3300","authType":"none","authUser":"","authPass":"","isActive":true}') + reg_resp=$(curl -s -w "HTTPSTATUS:%{http_code}" -X POST \ + --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ + --header 'Content-Type: application/json' \ + --data "$reg_body" \ + "$MC_IAM_MANAGER_HOST/api/mcmp-apis") + reg_code=$(echo $reg_resp | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') + if [ "$reg_code" = "201" ]; then + echo " ✓ mc-data-manager-fe registered" + elif [ "$reg_code" = "409" ]; then + echo " ✓ mc-data-manager-fe already registered" + else + echo " ✗ Failed to register mc-data-manager-fe (HTTP $reg_code)" + return 1 + fi + response=$(curl -s -w "HTTPSTATUS:%{http_code}" -X PUT \ + --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ + --header 'Content-Type: application/json' \ + --data "{\"base_url\": \"${dm_public_url}\"}" \ + "$MC_IAM_MANAGER_HOST/api/mcmp-apis/name/mc-data-manager-fe") + http_code=$(echo $response | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') + response_body=$(echo $response | sed -e 's/HTTPSTATUS\:.*//g') + if [ "$http_code" = "200" ]; then + echo " ✓ Updated mc-data-manager-fe baseurl: ${dm_public_url}" + else + echo " ✗ Failed to update mc-data-manager-fe (HTTP $http_code): $response_body" + return 1 + fi + + # mc-application-manager-fe: iframe 전용 nginx HTTPS 프록시 URL 등록 및 갱신 + local am_public_url="https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_APPLICATION_MANAGER_PROXY_PORT}" + reg_body=$(printf '{"name":"mc-application-manager-fe","version":"v0.0.1","baseUrl":"http://mc-application-manager:18084","authType":"none","authUser":"","authPass":"","isActive":true}') + reg_resp=$(curl -s -w "HTTPSTATUS:%{http_code}" -X POST \ + --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ + --header 'Content-Type: application/json' \ + --data "$reg_body" \ + "$MC_IAM_MANAGER_HOST/api/mcmp-apis") + reg_code=$(echo $reg_resp | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') + if [ "$reg_code" = "201" ]; then + echo " ✓ mc-application-manager-fe registered" + elif [ "$reg_code" = "409" ]; then + echo " ✓ mc-application-manager-fe already registered" + else + echo " ✗ Failed to register mc-application-manager-fe (HTTP $reg_code)" + return 1 + fi + response=$(curl -s -w "HTTPSTATUS:%{http_code}" -X PUT \ + --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ + --header 'Content-Type: application/json' \ + --data "{\"base_url\": \"${am_public_url}\"}" \ + "$MC_IAM_MANAGER_HOST/api/mcmp-apis/name/mc-application-manager-fe") + http_code=$(echo $response | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') + response_body=$(echo $response | sed -e 's/HTTPSTATUS\:.*//g') + if [ "$http_code" = "200" ]; then + echo " ✓ Updated mc-application-manager-fe baseurl: ${am_public_url}" + else + echo " ✗ Failed to update mc-application-manager-fe (HTTP $http_code): $response_body" + return 1 + fi + echo "Public service URL update completed" return 0 } diff --git a/conf/docker/conf/mc-iam-manager/nginx.template.conf b/conf/docker/conf/mc-iam-manager/nginx.template.conf index a2506ee..0be9c64 100644 --- a/conf/docker/conf/mc-iam-manager/nginx.template.conf +++ b/conf/docker/conf/mc-iam-manager/nginx.template.conf @@ -248,6 +248,99 @@ http { } } + # mc-workflow-manager HTTPS proxy (iframe용) + server { + listen ${MC_WORKFLOW_MANAGER_PROXY_PORT} ssl; + server_name ${MC_IAM_MANAGER_PUBLIC_DOMAIN}; + + ssl_certificate /etc/nginx/certs/live/${MC_IAM_MANAGER_PUBLIC_DOMAIN}/fullchain.pem; + ssl_certificate_key /etc/nginx/certs/live/${MC_IAM_MANAGER_PUBLIC_DOMAIN}/privkey.pem; + + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + location / { + resolver 127.0.0.11 valid=10s; + set $upstream_wf mc-workflow-manager; + proxy_pass http://$upstream_wf:18083; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + proxy_set_header X-Forwarded-Host $host; + proxy_hide_header X-Frame-Options; + add_header Content-Security-Policy "frame-ancestors https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:3001 https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}" always; + + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + } + + # mc-data-manager HTTPS proxy (iframe용) + server { + listen ${MC_DATA_MANAGER_PROXY_PORT} ssl; + server_name ${MC_IAM_MANAGER_PUBLIC_DOMAIN}; + + ssl_certificate /etc/nginx/certs/live/${MC_IAM_MANAGER_PUBLIC_DOMAIN}/fullchain.pem; + ssl_certificate_key /etc/nginx/certs/live/${MC_IAM_MANAGER_PUBLIC_DOMAIN}/privkey.pem; + + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + location / { + resolver 127.0.0.11 valid=10s; + set $upstream_dm mc-data-manager; + proxy_pass http://$upstream_dm:3300; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + proxy_set_header X-Forwarded-Host $host; + proxy_hide_header X-Frame-Options; + add_header Content-Security-Policy "frame-ancestors https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:3001 https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}" always; + + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + } + + # mc-application-manager HTTPS proxy (iframe용) + server { + listen ${MC_APPLICATION_MANAGER_PROXY_PORT} ssl; + server_name ${MC_IAM_MANAGER_PUBLIC_DOMAIN}; + + ssl_certificate /etc/nginx/certs/live/${MC_IAM_MANAGER_PUBLIC_DOMAIN}/fullchain.pem; + ssl_certificate_key /etc/nginx/certs/live/${MC_IAM_MANAGER_PUBLIC_DOMAIN}/privkey.pem; + + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + location / { + resolver 127.0.0.11 valid=10s; + set $upstream_am mc-application-manager; + proxy_pass http://$upstream_am:18084; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto https; + proxy_set_header X-Forwarded-Host $host; + proxy_hide_header X-Frame-Options; + add_header Content-Security-Policy "frame-ancestors https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:3001 https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}" always; + + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + } + # mc-cost-optimizer-fe HTTPS proxy (iframe/외부 진입용) server { listen ${MC_COST_OPTIMIZER_FE_PROXY_PORT} ssl; diff --git a/conf/docker/conf/mc-web-console/api/conf/api.yaml b/conf/docker/conf/mc-web-console/api/conf/api.yaml index e71313d..a6fed28 100644 --- a/conf/docker/conf/mc-web-console/api/conf/api.yaml +++ b/conf/docker/conf/mc-web-console/api/conf/api.yaml @@ -60,6 +60,21 @@ services: baseurl: http://mc-data-manager:3300 auth: + mc-workflow-manager-fe: + version: v0.0.1 + baseurl: http://mc-workflow-manager:18083 + auth: + + mc-data-manager-fe: + version: v0.0.1 + baseurl: http://mc-data-manager:3300 + auth: + + mc-application-manager-fe: + version: v0.0.1 + baseurl: http://mc-application-manager:18084 + auth: + # sample: # baseurl: http://localhost:1323/test # auth: diff --git a/conf/docker/docker-compose.yaml b/conf/docker/docker-compose.yaml index 59992cf..0d2b6e7 100644 --- a/conf/docker/docker-compose.yaml +++ b/conf/docker/docker-compose.yaml @@ -353,6 +353,9 @@ services: - "${MC_COST_OPTIMIZER_FE_PROXY_PORT}:${MC_COST_OPTIMIZER_FE_PROXY_PORT}" - "${MC_COST_OPTIMIZER_BE_PORT}:${MC_COST_OPTIMIZER_BE_PORT}" - "${MC_COST_OPTIMIZER_ALARM_PORT}:${MC_COST_OPTIMIZER_ALARM_PORT}" + - "${MC_WORKFLOW_MANAGER_PROXY_PORT}:${MC_WORKFLOW_MANAGER_PROXY_PORT}" + - "${MC_DATA_MANAGER_PROXY_PORT}:${MC_DATA_MANAGER_PROXY_PORT}" + - "${MC_APPLICATION_MANAGER_PROXY_PORT}:${MC_APPLICATION_MANAGER_PROXY_PORT}" environment: - DOMAIN_NAME=${MC_IAM_MANAGER_PUBLIC_DOMAIN} volumes: @@ -365,6 +368,8 @@ services: - mc-iam-manager-network - mc-observability-network - mc-cost-optimizer-network + - mc-workflow-manager-network + - mc-data-manager-network mc-iam-manager-post-initial: image: ubuntu:22.04 @@ -984,7 +989,7 @@ services: published: ${MC_WEB_CONSOLE_DB_HOST_PORT} protocol: tcp healthcheck: - test: [ "CMD-SHELL", "pg_isready -U ${MC_WEB_CONSOLE_POSTGRES_USER}" ] + test: [ "CMD-SHELL", "pg_isready -U ${MC_WEB_CONSOLE_POSTGRES_USER} -d ${MC_WEB_CONSOLE_POSTGRES_DB}" ] <<: *default-health-check command: > sh -c "chown -R 70:70 /var/lib/postgresql/data && From bf92fd6fdcd7a9a85e45cc43cb0cf5bde218ce49 Mon Sep 17 00:00:00 2001 From: raccoon-mh Date: Wed, 20 May 2026 07:38:26 +0000 Subject: [PATCH 6/9] chore(docker): update mc-iam-manager, mc-web-console images to cloudbaristaorg releases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit csescsta/edge 이미지를 cloudbaristaorg 공식 릴리즈로 교체 - csescsta/mc-iam-manager:edge → cloudbaristaorg/mc-iam-manager:0.5.2 - csescsta/mc-web-console-api:edge → cloudbaristaorg/mc-web-console-api:0.5.4 - csescsta/mc-web-console-front:edge → cloudbaristaorg/mc-web-console-front:0.5.3 --- conf/docker/docker-compose.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/conf/docker/docker-compose.yaml b/conf/docker/docker-compose.yaml index 0d2b6e7..42ea699 100644 --- a/conf/docker/docker-compose.yaml +++ b/conf/docker/docker-compose.yaml @@ -242,9 +242,7 @@ services: mc-iam-manager: container_name: mc-iam-manager - # image: mc-iam-manager:latest - #image: cloudbaristaorg/mc-iam-manager:edge - image: csescsta/mc-iam-manager:edge + image: cloudbaristaorg/mc-iam-manager:0.5.2 restart: unless-stopped networks: - mc-iam-manager-network @@ -996,7 +994,7 @@ services: exec docker-entrypoint.sh postgres" mc-web-console-api: - image: csescsta/mc-web-console-api:edge + image: cloudbaristaorg/mc-web-console-api:0.5.4 pull_policy: always container_name: mc-web-console-api platform: linux/amd64 @@ -1036,7 +1034,7 @@ services: <<: *default-health-check mc-web-console-front: - image: csescsta/mc-web-console-front:edge + image: cloudbaristaorg/mc-web-console-front:0.5.3 pull_policy: always container_name: mc-web-console-front platform: linux/amd64 From a08280288e39992b50c9fec2fadc57c09ce4e3c9 Mon Sep 17 00:00:00 2001 From: dogfootman Date: Thu, 21 May 2026 06:55:55 +0000 Subject: [PATCH 7/9] feat(docker): add iframe-fe service entries and standardize env var prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ADMINCLI-TECH-002: api.yaml에 mc-workflow-manager-fe, mc-data-manager-fe, mc-application-manager-fe, mc-cost-optimizer-fe 서비스 항목 추가. .env.setup, conf/mc-iam-manager/.env*에 WORKFLOW/DATA/APPLICATION PROXY_PORT + PUBLIC_HOST 변수 추가. 1_setup_auto.sh 인라인 URL 3곳을 ${MC_*_PUBLIC_HOST} 변수 참조로 교체. ADMINCLI-TECH-001: conf/docker/.env.setup, conf/mc-iam-manager/.env*, conf/mc-data-manager/.env, conf/mc-web-console/.env의 변수명을 MC__* prefix 규칙으로 통일. - USE_TICKET_VALID, PREDEFINED_*ROLE, DEFAULT_WORKSPACE_NAME, AWS_ACCOUNT_ID, IDENTITY_*_ARN_AWS, CSP_ROLE_PREFIX → MC_IAM_MANAGER_* prefix 부여 - MCINFRAMANAGER → MC_INFRA_MANAGER_TUMBLEBUG_URL (legacy 2종 삭제) - MCADMINCLI_APIYAML → MC_ADMIN_CLI_APIYAML - CONSOLE_POSTGRES_* → MC_WEB_CONSOLE_POSTGRES_* - USER_NAME/GROUP_NAME/ENCODING_SECRET_KEY → MC_DATA_MANAGER_* prefix - MC_IAM_MANAGER_PORT 중복 라인 및 MC_IAM_MANAGER_KEYCLOAK_DB_DATABASE_NAME dead var 정리 --- bin/cleanAll.sh | 26 +-- bin/iam_manager_init.sh | 126 +++++++------- bin/installAll.sh | 2 +- conf/docker/.env.setup | 45 ++--- conf/docker/api.yaml | 20 +++ conf/docker/conf/mc-data-manager/.env | 6 +- conf/docker/conf/mc-iam-manager/.env | 37 ++-- conf/docker/conf/mc-iam-manager/.env.setup | 60 +++---- .../conf/mc-iam-manager/0_preset_dev.sh | 102 +++++------ .../conf/mc-iam-manager/0_preset_prod.sh | 94 +++++----- .../conf/mc-iam-manager/1_setup_auto.sh | 162 +++++++++--------- .../conf/mc-iam-manager/1_setup_manual.sh | 26 +-- .../conf/mc-iam-manager/docker-post-init.sh | 12 +- conf/docker/conf/mc-iam-manager/init-db.sh | 10 +- .../conf/mc-iam-manager/nginx.template.conf | 38 ++-- conf/docker/conf/mc-web-console/.env | 12 +- conf/docker/docker-compose.cert.yaml | 14 +- src/cmd/apicall/parse.go | 2 +- 18 files changed, 412 insertions(+), 382 deletions(-) diff --git a/bin/cleanAll.sh b/bin/cleanAll.sh index 4582c24..1a36f5d 100755 --- a/bin/cleanAll.sh +++ b/bin/cleanAll.sh @@ -1,6 +1,6 @@ #!/bin/bash -# 경고 메시지 및 사용자 확인 +# Warning message and user confirmation cat </dev/null) - + if [ "$container_status" = "healthy" ]; then - echo "✅ 정상" + echo "✅ Healthy" elif [ "$container_status" = "starting" ]; then - echo "⏳ 시작 중..." + echo "⏳ Starting..." ALL_HEALTHY=false elif [ "$container_status" = "unhealthy" ]; then - echo "❌ 비정상" + echo "❌ Unhealthy" ALL_HEALTHY=false else - echo "❓ 상태 확인 불가 ($container_status)" + echo "❓ Status unknown ($container_status)" ALL_HEALTHY=false fi done @@ -50,82 +50,82 @@ done echo "" if [ "$ALL_HEALTHY" = false ]; then - echo "❌ 필수 컨테이너가 모두 정상 상태가 아닙니다." - echo "다음 컨테이너들이 정상적으로 구동된 후 다시 시도해주세요:" + echo "❌ Not all required containers are healthy." + echo "Please ensure the following containers are running and healthy, then try again:" # echo " - mc-iam-manager" echo " - mc-iam-manager-db" echo " - mc-iam-manager-kc" echo "" - echo "컨테이너 상태 확인: docker ps" - echo "컨테이너 로그 확인: docker logs [컨테이너명]" + echo "Check container status: docker ps" + echo "Check container logs: docker logs [container-name]" exit 1 fi -echo "✅ 모든 필수 컨테이너가 정상 상태입니다." -echo "초기화를 진행할 수 있습니다..." +echo "✅ All required containers are healthy." +echo "Proceeding with initialization..." echo "" echo "------------------------------------------------" echo " MC-IAM-Manager Initialization Mode Selection" echo "------------------------------------------------" -echo "MC-IAM-Manager 초기화는 두 가지 모드로 진행할 수 있습니다:" +echo "MC-IAM-Manager initialization can be performed in two modes:" echo "" -echo "[전체 초기화 - 자동 모드]" -echo " - 모든 초기화 작업이 자동으로 순차 진행" -echo " - 플랫폼 어드민 초기화" -echo " - 로그인 및 인증 토큰 발급" -echo " - 사전 정의된 역할 생성 (admin, operator, viewer 등)" -echo " - 메뉴 데이터 초기화" -echo " - API 리소스 데이터 초기화" -echo " - 프로젝트 동기화 및 워크스페이스 매핑" -echo " - 빠르고 편리한 일괄 설정" +echo "[Full Initialization - Auto Mode]" +echo " - All initialization tasks run automatically in sequence" +echo " - Platform admin initialization" +echo " - Login and authentication token issuance" +echo " - Predefined role creation (admin, operator, viewer, etc.)" +echo " - Menu data initialization" +echo " - API resource data initialization" +echo " - Project sync and workspace mapping" +echo " - Fast and convenient batch setup" echo "" -echo "[부분 초기화 - 수동 모드]" -echo " - 초기화 가능한 작업 목록을 사용자가 선택" -echo " - 각 단계별로 개별 실행 가능" -echo " - 상세한 진행 상황 확인" -echo " - 특정 기능만 선택적으로 초기화" -echo " - 문제 발생 시 단계별 디버깅 가능" +echo "[Partial Initialization - Manual Mode]" +echo " - User selects tasks from the available initialization list" +echo " - Each step can be executed individually" +echo " - Detailed progress visibility" +echo " - Selectively initialize specific features only" +echo " - Step-by-step debugging when issues occur" echo "" echo "==============================================================" -# 사용자 선택 입력 +# User mode selection input while true; do - echo -n "어떤 초기화 모드를 선택하시겠습니까? (1: 전체 초기화, 2: 부분 초기화): " + echo -n "Which initialization mode would you like? (1: Full initialization, 2: Partial initialization): " read -r choice case $choice in 1) echo "" - echo "전체 초기화-자동 모드를 선택하셨습니다." - echo "모든 초기화 작업이 자동으로 순차 진행됩니다..." + echo "Full initialization - Auto mode selected." + echo "All initialization tasks will run automatically in sequence..." echo "" - + cd "$ORIGINAL_DIR" ./mcc infra run -s mc-iam-manager-post-initial - # # 전체 초기화 스크립트 실행 + # # Run full initialization script # cd ../conf/docker/conf/mc-iam-manager/ || { - # echo "오류: mc-iam-manager 디렉토리를 찾을 수 없습니다." + # echo "Error: mc-iam-manager directory not found." # cd "$ORIGINAL_DIR" # exit 1 # } - + # if [ -f "1_setup_auto.sh" ]; then # chmod +x 1_setup_auto.sh # ./1_setup_auto.sh # if [ $? -eq 0 ]; then # echo "" - # echo "✓ 전체 초기화가 완료되었습니다." - # echo "MC-IAM-Manager가 정상적으로 설정되었습니다." + # echo "✓ Full initialization completed." + # echo "MC-IAM-Manager has been configured successfully." # else # echo "" - # echo "❌ 전체 초기화 중 오류가 발생했습니다." + # echo "❌ An error occurred during full initialization." # cd "$ORIGINAL_DIR" # exit 1 # fi # else - # echo "오류: 1_setup_auto.sh 파일을 찾을 수 없습니다." + # echo "Error: 1_setup_auto.sh file not found." # cd "$ORIGINAL_DIR" # exit 1 # fi @@ -134,32 +134,32 @@ while true; do ;; 2) echo "" - echo "부분 초기화-수동 모드를 선택하셨습니다." - echo "초기화 가능한 작업 목록에서 원하는 항목을 선택하세요..." + echo "Partial initialization - Manual mode selected." + echo "Select the desired tasks from the available initialization list..." echo "" - - # 부분 초기화 스크립트 실행 + + # Run partial initialization script cd ../conf/docker/conf/mc-iam-manager/ || { - echo "오류: mc-iam-manager 디렉토리를 찾을 수 없습니다." + echo "Error: mc-iam-manager directory not found." cd "$ORIGINAL_DIR" exit 1 } - + if [ -f "1_setup_manual.sh" ]; then chmod +x 1_setup_manual.sh ./1_setup_manual.sh if [ $? -eq 0 ]; then echo "" - echo "✓ 부분 초기화가 완료되었습니다." - echo "선택한 초기화 작업이 정상적으로 수행되었습니다." + echo "✓ Partial initialization completed." + echo "The selected initialization tasks completed successfully." else echo "" - echo "❌ 부분 초기화 중 오류가 발생했습니다." + echo "❌ An error occurred during partial initialization." cd "$ORIGINAL_DIR" exit 1 fi else - echo "오류: 1_setup_manual.sh 파일을 찾을 수 없습니다." + echo "Error: 1_setup_manual.sh file not found." cd "$ORIGINAL_DIR" exit 1 fi @@ -167,17 +167,17 @@ while true; do break ;; *) - echo "잘못된 선택입니다. 1 또는 2를 입력해주세요." + echo "Invalid choice. Please enter 1 or 2." ;; esac done -# 모든 초기화 작업 완료 후 원래 위치로 돌아가기 +# Return to the original directory after all initialization tasks cd "$ORIGINAL_DIR" echo "" echo "======================================================" -echo "초기화 작업이 완료되었습니다!" -echo "MC-IAM-Manager가 정상적으로 설정되었습니다." +echo "Initialization completed!" +echo "MC-IAM-Manager has been configured successfully." echo "======================================================" diff --git a/bin/installAll.sh b/bin/installAll.sh index b811046..0eb4df6 100755 --- a/bin/installAll.sh +++ b/bin/installAll.sh @@ -309,7 +309,7 @@ case $IAM_MODE in ./mcc infra run -f ../conf/docker/docker-compose.cert.yaml if [ $? -eq 0 ]; then echo "✓ Certificate generation completed." - # certbot 컨테이너가 root로 생성한 볼륨 디렉토리의 소유권을 현재 사용자로 회수 + # Reclaim ownership of volume directories created by the certbot container (runs as root) sudo chown -R "$USER:$USER" ../conf/docker/container-volume else echo "❌ Error occurred during certificate generation." diff --git a/conf/docker/.env.setup b/conf/docker/.env.setup index 2637ee0..4ee6c02 100644 --- a/conf/docker/.env.setup +++ b/conf/docker/.env.setup @@ -5,7 +5,7 @@ HEALTH_CHECK_RETRIES=3 HEALTH_CHECK_START_PERIOD=60s -# Network Configuration (필수) +# Network Configuration (required) MC_INFRA_CONNECTOR_PORT=1024 MC_INFRA_MANAGER_PORT=1323 MC_IAM_MANAGER_PORT=5000 @@ -15,7 +15,7 @@ MC_WEB_CONSOLE_FRONT_PORT=3001 MC_INFRA_MANAGER_POSTGRES_PORT=5432 MC_INFRA_MANAGER_ETCD_PORT=2379 -# === 외부 노출 포트 (published ports — 단일 진실원) === +# === Published Ports (single source of truth) === MC_INFRA_MANAGER_ETCD_PEER_PORT=2380 MC_INFRA_MANAGER_OPENBAO_PORT=8200 MC_INFRA_MANAGER_POSTGRES_HOST_PORT=6432 @@ -61,7 +61,6 @@ MC_OBSERVABILITY_INSIGHT_SCHEDULER_PORT=9002 ## MCIAMMANAGER ENV SETUP MC_IAM_MANAGER_DOMAIN=mc-iam-manager -MC_IAM_MANAGER_PORT=5000 MC_IAM_MANAGER_HOST=http://${MC_IAM_MANAGER_DOMAIN}:${MC_IAM_MANAGER_PORT} MC_IAM_MANAGER_HOST_FOR_INIT=http://${MC_IAM_MANAGER_DOMAIN}:${MC_IAM_MANAGER_PORT} MC_IAM_MANAGER_CERT_EMAIL=mcmp@cloud-barista.org @@ -74,9 +73,9 @@ DEFAULT_LANGUAGE=ko # [ko|en] Default is ko if not set MODE=standalone # [standalone|docker] both are same. ## Resources Permission MODE -USE_TICKET_VALID=true # [true|false] +MC_IAM_MANAGER_USE_TICKET_VALID=true # [true|false] -MCADMINCLI_APIYAML=https://raw.githubusercontent.com/m-cmp/mc-admin-cli/refs/heads/main/conf/api.yaml +MC_ADMIN_CLI_APIYAML=https://raw.githubusercontent.com/m-cmp/mc-admin-cli/refs/heads/main/conf/api.yaml MC_WEB_CONSOLE_MENUYAML=https://raw.githubusercontent.com/m-cmp/mc-web-console/refs/heads/main/conf/webconsole_menu_resources.yaml MC_WEB_CONSOLE_MENU_PERMISSIONS=https://raw.githubusercontent.com/m-cmp/mc-web-console/refs/heads/main/conf/webconsole_menu_permissions.csv @@ -87,9 +86,9 @@ MC_IAM_MANAGER_PLATFORMADMIN_FIRSTNAME=mcmp MC_IAM_MANAGER_PLATFORMADMIN_LASTNAME=iammanager MC_IAM_MANAGER_PLATFORMADMIN_EMAIL=iammanager@cloud-barista.org -PREDEFINED_ROLE=admin,operator,viewer,billadmin,billviewer -PREDEFINED_PLATFORM_ROLE=admin,operator,viewer,billadmin,billviewer -PREDEFINED_WORKSPACE_ROLE=admin,operator,viewer,billadmin,billviewer +MC_IAM_MANAGER_PREDEFINED_ROLE=admin,operator,viewer,billadmin,billviewer +MC_IAM_MANAGER_PREDEFINED_PLATFORM_ROLE=admin,operator,viewer,billadmin,billviewer +MC_IAM_MANAGER_PREDEFINED_WORKSPACE_ROLE=admin,operator,viewer,billadmin,billviewer MC_IAM_MANAGER_KEYCLOAK_CLIENT_NAME=mciamClient MC_IAM_MANAGER_KEYCLOAK_CLIENT_SECRET=mciamClientSecret @@ -139,34 +138,38 @@ MC_INFRA_MANAGER_TERRARIUM_API_PASSWORD= MC_INFRA_MANAGER_POSTGRES_USER=tumblebug MC_INFRA_MANAGER_POSTGRES_PASSWORD=tumblebug MC_INFRA_MANAGER_POSTGRES_DB=tumblebug -MCINFRAMANAGER=http://mc-infra-manager:1323/tumblebug -MCINFRAMANAGER_APIUSERNAME=default -MCINFRAMANAGER_APIPASSWORD=default +MC_INFRA_MANAGER_TUMBLEBUG_URL=http://mc-infra-manager:1323/tumblebug ## Default Workspace -DEFAULT_WORKSPACE_NAME=ws01 +MC_IAM_MANAGER_DEFAULT_WORKSPACE_NAME=ws01 -TEMPORARY_SECURITY_CREDENTIALS_ENDPOINT_AWS=https://sts.amazonaws.com -AWS_ACCOUNT_ID=notyet -IDENTITY_PROVIDER_ARN_AWS=arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${MC_IAM_MANAGER_KEYCLOAK_DOMAIN}/realms/${MC_IAM_MANAGER_KEYCLOAK_OIDC_CLIENT_NAME} -IDENTITY_ROLE_ARN_AWS=arn:aws:iam::${MC_IAM_MANAGER_KEYCLOAK_DOMAIN}:role/mciam-platformadmin +MC_IAM_MANAGER_AWS_STS_ENDPOINT=https://sts.amazonaws.com +MC_IAM_MANAGER_AWS_ACCOUNT_ID=notyet +MC_IAM_MANAGER_AWS_IDENTITY_PROVIDER_ARN=arn:aws:iam::${MC_IAM_MANAGER_AWS_ACCOUNT_ID}:oidc-provider/${MC_IAM_MANAGER_KEYCLOAK_DOMAIN}/realms/${MC_IAM_MANAGER_KEYCLOAK_OIDC_CLIENT_NAME} +MC_IAM_MANAGER_AWS_IDENTITY_ROLE_ARN=arn:aws:iam::${MC_IAM_MANAGER_KEYCLOAK_DOMAIN}:role/mciam-platformadmin -CSP_ROLE_PREFIX=mciam +MC_IAM_MANAGER_CSP_ROLE_PREFIX=mciam -# === 외부 노출 도메인 (브라우저 ↔ nginx HTTPS) === -# Mode A (도메인 없음): 로컬 자가서명 인증서 사용. 0_preset_dev.sh 로 인증서 생성 후 사용. +# === External Domain (browser ↔ nginx HTTPS) === +# Mode A (no domain): Uses a local self-signed certificate. Generate it with 0_preset_dev.sh before use. MC_IAM_MANAGER_PUBLIC_DOMAIN=mciam.local -# Mode B (운영 / 외부 도메인): 아래 주석 해제 후 FQDN 설정. 0_preset_prod.sh + Let's Encrypt 필요. +# Mode B (production / external domain): Uncomment below and set FQDN. Requires 0_preset_prod.sh + Let's Encrypt. # MC_IAM_MANAGER_PUBLIC_DOMAIN= MC_IAM_MANAGER_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN} MC_IAM_MANAGER_PUBLIC_KEYCLOAK_HOST=${MC_IAM_MANAGER_PUBLIC_HOST}/auth -# === nginx HTTPS reverse proxy 포트 (iframe/외부 진입용 — 직접 노출 포트와 충돌 방지) === +# === nginx HTTPS Reverse Proxy Ports (for iframe/external access — must not conflict with direct published ports) === MC_OBSERVABILITY_GRAFANA_PROXY_PORT=33002 MC_OBSERVABILITY_GRAFANA_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_OBSERVABILITY_GRAFANA_PROXY_PORT} MC_COST_OPTIMIZER_FE_PROXY_PORT=7781 MC_COST_OPTIMIZER_FE_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_COST_OPTIMIZER_FE_PROXY_PORT} +MC_WORKFLOW_MANAGER_PROXY_PORT=18183 +MC_WORKFLOW_MANAGER_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_WORKFLOW_MANAGER_PROXY_PORT} +MC_DATA_MANAGER_PROXY_PORT=3400 +MC_DATA_MANAGER_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_DATA_MANAGER_PROXY_PORT} +MC_APPLICATION_MANAGER_PROXY_PORT=18184 +MC_APPLICATION_MANAGER_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_APPLICATION_MANAGER_PROXY_PORT} # MC-COST-OPTIMIZER diff --git a/conf/docker/api.yaml b/conf/docker/api.yaml index 1bf1545..6b1ded2 100644 --- a/conf/docker/api.yaml +++ b/conf/docker/api.yaml @@ -55,6 +55,26 @@ services: baseurl: http://mc-data-manager:3300 auth: + mc-cost-optimizer-fe: + version: 0.4.0 + baseurl: http://mc-cost-optimizer-fe:7780 + auth: + + mc-workflow-manager-fe: + version: v0.0.1 + baseurl: http://mc-workflow-manager:18083 + auth: + + mc-data-manager-fe: + version: v0.0.1 + baseurl: http://mc-data-manager:3300 + auth: + + mc-application-manager-fe: + version: v0.0.1 + baseurl: http://mc-application-manager:18084 + auth: + # sample: # baseurl: http://localhost:1323/test # auth: diff --git a/conf/docker/conf/mc-data-manager/.env b/conf/docker/conf/mc-data-manager/.env index ca3f88e..b8d9631 100644 --- a/conf/docker/conf/mc-data-manager/.env +++ b/conf/docker/conf/mc-data-manager/.env @@ -1,13 +1,13 @@ UID=1000 GID=1000 -USER_NAME=ubuntu -GROUP_NAME=ubuntu +MC_DATA_MANAGER_USER_NAME=ubuntu +MC_DATA_MANAGER_GROUP_NAME=ubuntu MC_DATA_MANAGER_DATABASE_HOST=mc-data-manager-db MC_DATA_MANAGER_DATABASE_PORT=3306 MC_DATA_MANAGER_DATABASE_USER=mcmp MC_DATA_MANAGER_DATABASE_PASSWORD=mcmp MC_DATA_MANAGER_DATABASE_NAME=mcmp -ENCODING_SECRET_KEY=12345678901234567890123456789012 +MC_DATA_MANAGER_ENCODING_SECRET_KEY=12345678901234567890123456789012 MC_DATA_MANAGER_PORT=3300 MC_DATA_MANAGER_ALLOW_IP_RANGE=0.0.0.0/0 \ No newline at end of file diff --git a/conf/docker/conf/mc-iam-manager/.env b/conf/docker/conf/mc-iam-manager/.env index db00cf8..6f7d541 100644 --- a/conf/docker/conf/mc-iam-manager/.env +++ b/conf/docker/conf/mc-iam-manager/.env @@ -14,9 +14,9 @@ DEFAULT_LANGUAGE=ko # [ko|en] Default is ko if not set MODE=standalone # [standalone|docker] both are same. ## Resources Permission MODE -USE_TICKET_VALID=true # [true|false] +MC_IAM_MANAGER_USE_TICKET_VALID=true # [true|false] -MCADMINCLI_APIYAML=https://raw.githubusercontent.com/m-cmp/mc-admin-cli/refs/heads/main/conf/api.yaml +MC_ADMIN_CLI_APIYAML=https://raw.githubusercontent.com/m-cmp/mc-admin-cli/refs/heads/main/conf/api.yaml MC_WEB_CONSOLE_MENUYAML=https://raw.githubusercontent.com/m-cmp/mc-web-console/refs/heads/main/conf/webconsole_menu_resources.yaml MC_WEB_CONSOLE_MENU_PERMISSIONS=https://raw.githubusercontent.com/m-cmp/mc-web-console/refs/heads/main/conf/webconsole_menu_permissions.csv @@ -27,9 +27,9 @@ MC_IAM_MANAGER_PLATFORMADMIN_FIRSTNAME=mcmp MC_IAM_MANAGER_PLATFORMADMIN_LASTNAME=iammanager MC_IAM_MANAGER_PLATFORMADMIN_EMAIL=iammanager@cloud-barista.org -PREDEFINED_ROLE=admin,operator,viewer,billadmin,billviewer -PREDEFINED_PLATFORM_ROLE=admin,operator,viewer,billadmin,billviewer -PREDEFINED_WORKSPACE_ROLE=admin,operator,viewer,billadmin,billviewer +MC_IAM_MANAGER_PREDEFINED_ROLE=admin,operator,viewer,billadmin,billviewer +MC_IAM_MANAGER_PREDEFINED_PLATFORM_ROLE=admin,operator,viewer,billadmin,billviewer +MC_IAM_MANAGER_PREDEFINED_WORKSPACE_ROLE=admin,operator,viewer,billadmin,billviewer MC_IAM_MANAGER_KEYCLOAK_CLIENT_NAME=mciamClient MC_IAM_MANAGER_KEYCLOAK_CLIENT_SECRET=mciamClientSecret @@ -56,16 +56,14 @@ MC_IAM_MANAGER_DATABASE_URL=postgres://${MC_IAM_MANAGER_DATABASE_USER}:${MC_IAM_ MC_IAM_MANAGER_KEYCLOAK_DOMAIN=mc-iam-manager-kc MC_IAM_MANAGER_KEYCLOAK_PORT=8080 MC_IAM_MANAGER_KEYCLOAK_HOST=http://${MC_IAM_MANAGER_KEYCLOAK_DOMAIN}:${MC_IAM_MANAGER_KEYCLOAK_PORT}/auth -MC_IAM_MANAGER_KEYCLOAK_DB_DATABASE_NAME=mc_iam_keycloak_db + MC_IAM_MANAGER_KEYCLOAK_REALM=mciam MC_IAM_MANAGER_KEYCLOAK_CLIENT_PATH=${MC_IAM_MANAGER_KEYCLOAK_DOMAIN}/realms/${MC_IAM_MANAGER_KEYCLOAK_REALM} MC_IAM_MANAGER_KEYCLOAK_ADMIN=admin MC_IAM_MANAGER_KEYCLOAK_ADMIN_PASSWORD=admin_password ## mc-infra-manager -MCINFRAMANAGER=http://mc-infra-manager:1323/tumblebug -MCINFRAMANAGER_APIUSERNAME=default -MCINFRAMANAGER_APIPASSWORD=default +MC_INFRA_MANAGER_TUMBLEBUG_URL=http://mc-infra-manager:1323/tumblebug MC_INFRA_MANAGER_API_USERNAME=default MC_INFRA_MANAGER_API_PASSWORD=default @@ -74,24 +72,31 @@ MC_INFRA_CONNECTOR_API_USERNAME=default MC_INFRA_CONNECTOR_API_PASSWORD=default ## Default Workspace -DEFAULT_WORKSPACE_NAME=ws01 +MC_IAM_MANAGER_DEFAULT_WORKSPACE_NAME=ws01 -TEMPORARY_SECURITY_CREDENTIALS_ENDPOINT_AWS=https://sts.amazonaws.com -AWS_ACCOUNT_ID=notyet -IDENTITY_PROVIDER_ARN_AWS=arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${MC_IAM_MANAGER_KEYCLOAK_DOMAIN}/realms/${MC_IAM_MANAGER_KEYCLOAK_OIDC_CLIENT_NAME} -IDENTITY_ROLE_ARN_AWS=arn:aws:iam::${MC_IAM_MANAGER_KEYCLOAK_DOMAIN}:role/mciam-platformadmin +MC_IAM_MANAGER_AWS_STS_ENDPOINT=https://sts.amazonaws.com +MC_IAM_MANAGER_AWS_ACCOUNT_ID=notyet +MC_IAM_MANAGER_AWS_IDENTITY_PROVIDER_ARN=arn:aws:iam::${MC_IAM_MANAGER_AWS_ACCOUNT_ID}:oidc-provider/${MC_IAM_MANAGER_KEYCLOAK_DOMAIN}/realms/${MC_IAM_MANAGER_KEYCLOAK_OIDC_CLIENT_NAME} +MC_IAM_MANAGER_AWS_IDENTITY_ROLE_ARN=arn:aws:iam::${MC_IAM_MANAGER_KEYCLOAK_DOMAIN}:role/mciam-platformadmin -CSP_ROLE_PREFIX=mciam +MC_IAM_MANAGER_CSP_ROLE_PREFIX=mciam # === 외부 노출 도메인 (브라우저 ↔ nginx HTTPS) === # Mode A (도메인 없음): 로컬 자가서명 인증서. 0_preset_dev.sh 로 생성. # MC_IAM_MANAGER_PUBLIC_DOMAIN=mciam.local # Mode B (운영): 아래 주석 해제 후 FQDN 설정. 0_preset_prod.sh + Let's Encrypt 필요. # MC_IAM_MANAGER_PUBLIC_DOMAIN= -MC_IAM_MANAGER_PUBLIC_DOMAIN=mciam.local +MC_IAM_MANAGER_PUBLIC_DOMAIN=52.79.163.111 MC_IAM_MANAGER_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN} MC_IAM_MANAGER_PUBLIC_KEYCLOAK_HOST=${MC_IAM_MANAGER_PUBLIC_HOST}/auth # === 외부 iframe 프록시 포트 === MC_COST_OPTIMIZER_FE_PROXY_PORT=7781 +MC_COST_OPTIMIZER_FE_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_COST_OPTIMIZER_FE_PROXY_PORT} +MC_WORKFLOW_MANAGER_PROXY_PORT=18183 +MC_WORKFLOW_MANAGER_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_WORKFLOW_MANAGER_PROXY_PORT} +MC_DATA_MANAGER_PROXY_PORT=3400 +MC_DATA_MANAGER_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_DATA_MANAGER_PROXY_PORT} +MC_APPLICATION_MANAGER_PROXY_PORT=18184 +MC_APPLICATION_MANAGER_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_APPLICATION_MANAGER_PROXY_PORT} diff --git a/conf/docker/conf/mc-iam-manager/.env.setup b/conf/docker/conf/mc-iam-manager/.env.setup index 9ebbc93..dd1e2ed 100644 --- a/conf/docker/conf/mc-iam-manager/.env.setup +++ b/conf/docker/conf/mc-iam-manager/.env.setup @@ -1,9 +1,9 @@ -## MC-IAM-Manager 서비스 환경 변수 -## env_file로 컨테이너 런타임에 주입 (docker compose environment: 블록 보완) -## .env.setup 기반으로 생성 - 운영 환경에서는 비밀번호 등을 반드시 변경하세요 +## MC-IAM-Manager Service Environment Variables +## Injected into container runtime via env_file (supplements docker compose environment: block) +## Generated from .env.setup — be sure to change passwords and secrets in production -# 기본 서비스 설정 -# MC_IAM_MANAGER_DOMAIN: Docker 내부 컨테이너 이름 — 공개 도메인(PUBLIC_DOMAIN)과 다름, 변경 금지 +# Basic service configuration +# MC_IAM_MANAGER_DOMAIN: Internal Docker container name — differs from PUBLIC_DOMAIN, do not change MC_IAM_MANAGER_DOMAIN=mc-iam-manager MC_IAM_MANAGER_PORT=5000 MC_IAM_MANAGER_HOST=http://mc-iam-manager:5000 @@ -12,24 +12,24 @@ MC_IAM_MANAGER_CERT_EMAIL=mcmp@cloud-barista.org DEFAULT_LANGUAGE=ko MODE=standalone -USE_TICKET_VALID=true +MC_IAM_MANAGER_USE_TICKET_VALID=true -MCADMINCLI_APIYAML=https://raw.githubusercontent.com/m-cmp/mc-admin-cli/refs/heads/main/conf/api.yaml +MC_ADMIN_CLI_APIYAML=https://raw.githubusercontent.com/m-cmp/mc-admin-cli/refs/heads/main/conf/api.yaml MC_WEB_CONSOLE_MENUYAML=https://raw.githubusercontent.com/m-cmp/mc-web-console/refs/heads/main/conf/webconsole_menu_resources.yaml MC_WEB_CONSOLE_MENU_PERMISSIONS=https://raw.githubusercontent.com/m-cmp/mc-web-console/refs/heads/main/conf/webconsole_menu_permissions.csv -# 플랫폼 관리자 +# Platform administrator MC_IAM_MANAGER_PLATFORMADMIN_ID=mcmp MC_IAM_MANAGER_PLATFORMADMIN_PASSWORD=mcmp_password MC_IAM_MANAGER_PLATFORMADMIN_FIRSTNAME=mcmp MC_IAM_MANAGER_PLATFORMADMIN_LASTNAME=iammanager MC_IAM_MANAGER_PLATFORMADMIN_EMAIL=iammanager@cloud-barista.org -PREDEFINED_ROLE=admin,operator,viewer,billadmin,billviewer -PREDEFINED_PLATFORM_ROLE=admin,operator,viewer,billadmin,billviewer -PREDEFINED_WORKSPACE_ROLE=admin,operator,viewer,billadmin,billviewer +MC_IAM_MANAGER_PREDEFINED_ROLE=admin,operator,viewer,billadmin,billviewer +MC_IAM_MANAGER_PREDEFINED_PLATFORM_ROLE=admin,operator,viewer,billadmin,billviewer +MC_IAM_MANAGER_PREDEFINED_WORKSPACE_ROLE=admin,operator,viewer,billadmin,billviewer -# Keycloak 클라이언트 +# Keycloak client MC_IAM_MANAGER_KEYCLOAK_CLIENT_NAME=mciamClient MC_IAM_MANAGER_KEYCLOAK_CLIENT_SECRET=mciamClientSecret MC_IAM_MANAGER_KEYCLOAK_OIDC_CLIENT_NAME=mciam-oidc-Client @@ -46,20 +46,18 @@ MC_IAM_MANAGER_DATABASE_RECREATE=false MC_IAM_MANAGER_DATABASE_SSLMODE=disable MC_IAM_MANAGER_DATABASE_URL=postgres://mciamdbadmin:mciamdbpassword@mc-iam-manager-db:5432/mc_iam_manager_db?sslmode=disable -# Keycloak 서버 +# Keycloak server MC_IAM_MANAGER_KEYCLOAK_DOMAIN=mc-iam-manager-kc MC_IAM_MANAGER_KEYCLOAK_PORT=8080 MC_IAM_MANAGER_KEYCLOAK_HOST=http://mc-iam-manager-kc:8080/auth -MC_IAM_MANAGER_KEYCLOAK_DB_DATABASE_NAME=mc_iam_keycloak_db + MC_IAM_MANAGER_KEYCLOAK_REALM=mciam MC_IAM_MANAGER_KEYCLOAK_CLIENT_PATH=mc-iam-manager-kc/realms/mciam MC_IAM_MANAGER_KEYCLOAK_ADMIN=admin MC_IAM_MANAGER_KEYCLOAK_ADMIN_PASSWORD=admin_password -# MC-Infra-Manager 연동 -MCINFRAMANAGER=http://mc-infra-manager:1323/tumblebug -MCINFRAMANAGER_APIUSERNAME=default -MCINFRAMANAGER_APIPASSWORD=default +# MC-Infra-Manager integration +MC_INFRA_MANAGER_TUMBLEBUG_URL=http://mc-infra-manager:1323/tumblebug MC_INFRA_MANAGER_API_USERNAME=default MC_INFRA_MANAGER_API_PASSWORD=default @@ -67,26 +65,30 @@ MC_INFRA_MANAGER_API_PASSWORD=default MC_INFRA_CONNECTOR_API_USERNAME=default MC_INFRA_CONNECTOR_API_PASSWORD=default -DEFAULT_WORKSPACE_NAME=ws01 +MC_IAM_MANAGER_DEFAULT_WORKSPACE_NAME=ws01 -# AWS OIDC (사용 시 실제 값으로 교체) -TEMPORARY_SECURITY_CREDENTIALS_ENDPOINT_AWS=https://sts.amazonaws.com -AWS_ACCOUNT_ID=notyet -IDENTITY_PROVIDER_ARN_AWS=arn:aws:iam::notyet:oidc-provider/mc-iam-manager-kc/realms/mciam-oidc-Client -IDENTITY_ROLE_ARN_AWS=arn:aws:iam::mc-iam-manager-kc:role/mciam-platformadmin +# AWS OIDC (replace with actual values when in use) +MC_IAM_MANAGER_AWS_STS_ENDPOINT=https://sts.amazonaws.com +MC_IAM_MANAGER_AWS_ACCOUNT_ID=notyet +MC_IAM_MANAGER_AWS_IDENTITY_PROVIDER_ARN=arn:aws:iam::notyet:oidc-provider/mc-iam-manager-kc/realms/mciam-oidc-Client +MC_IAM_MANAGER_AWS_IDENTITY_ROLE_ARN=arn:aws:iam::mc-iam-manager-kc:role/mciam-platformadmin -CSP_ROLE_PREFIX=mciam +MC_IAM_MANAGER_CSP_ROLE_PREFIX=mciam -# === 외부 노출 도메인 (브라우저 ↔ nginx HTTPS) === -# Mode A (도메인 없음): 로컬 자가서명 인증서. 0_preset_dev.sh 로 생성. +# === External Domain (browser ↔ nginx HTTPS) === +# Mode A (no domain): Local self-signed certificate. Generate with 0_preset_dev.sh. MC_IAM_MANAGER_PUBLIC_DOMAIN=mciam.local -# Mode B (운영): 아래 주석 해제 후 FQDN 설정. 0_preset_prod.sh + Let's Encrypt 필요. +# Mode B (production): Uncomment below and set FQDN. Requires 0_preset_prod.sh + Let's Encrypt. # MC_IAM_MANAGER_PUBLIC_DOMAIN= MC_IAM_MANAGER_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN} MC_IAM_MANAGER_PUBLIC_KEYCLOAK_HOST=${MC_IAM_MANAGER_PUBLIC_HOST}/auth -# === 외부 iframe 프록시 포트 (docker-compose.yaml의 PROXY_PORT 값과 동일하게 유지) === +# === External iframe Proxy Ports (must match PROXY_PORT values in docker-compose.yaml) === MC_COST_OPTIMIZER_FE_PROXY_PORT=7781 +MC_COST_OPTIMIZER_FE_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_COST_OPTIMIZER_FE_PROXY_PORT} MC_WORKFLOW_MANAGER_PROXY_PORT=18183 +MC_WORKFLOW_MANAGER_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_WORKFLOW_MANAGER_PROXY_PORT} MC_DATA_MANAGER_PROXY_PORT=3400 +MC_DATA_MANAGER_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_DATA_MANAGER_PROXY_PORT} MC_APPLICATION_MANAGER_PROXY_PORT=18184 +MC_APPLICATION_MANAGER_PUBLIC_HOST=https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_APPLICATION_MANAGER_PROXY_PORT} diff --git a/conf/docker/conf/mc-iam-manager/0_preset_dev.sh b/conf/docker/conf/mc-iam-manager/0_preset_dev.sh index f2f75fe..361a0de 100755 --- a/conf/docker/conf/mc-iam-manager/0_preset_dev.sh +++ b/conf/docker/conf/mc-iam-manager/0_preset_dev.sh @@ -1,28 +1,28 @@ #!/bin/bash -# 템플릿 파일에서 환경변수를 .env 파일의 값으로 대치하는 스크립트 +# Script to substitute environment variables in the template file with values from the .env file -# 스크립트 실행 디렉토리 확인 +# Resolve script execution directory SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")" echo "PROJECT_ROOT: $PROJECT_ROOT" -# .env 파일 경로 +# .env file path ENV_FILE="${PROJECT_ROOT}/.env" -# 인증서 파일 생성할 경로 (Let's Encrypt 구조와 동일) -# nginx 볼륨 마운트: ./container-volume/mc-iam-manager/certs:/etc/nginx/certs +# Certificate output path (same structure as Let's Encrypt) +# nginx volume mount: ./container-volume/mc-iam-manager/certs:/etc/nginx/certs CERT_PARENT_DIR="${PROJECT_ROOT}/container-volume/mc-iam-manager" -# --- 3. 필요한 디렉토리 생성 (Let's Encrypt 구조와 동일) --- +# --- 3. Create required directories (same structure as Let's Encrypt) --- echo "Creating necessary directories..." -# dockercontainer-volume 디렉토리 먼저 생성 (sudo 권한으로) +# Create container-volume directory first (with sudo if needed) echo "Creating container-volume directory with proper permissions..." -# 현재 사용자 정보 가져오기 +# Get current user info CURRENT_USER=$(whoami) CURRENT_GROUP=$(id -gn) @@ -51,34 +51,34 @@ done echo "✓ Certificate and nginx directories ready" -# 템플릿 파일 경로 +# Template file path TEMPLATE_FILE="./nginx.template.conf" -# 출력 파일 경로 (개선된 구조) +# Output file path (improved structure) OUTPUT_FILE="${PROJECT_ROOT}/container-volume/mc-iam-manager/nginx/nginx.conf" -# .env 파일 존재 확인 +# Check if .env file exists if [ ! -f "$ENV_FILE" ]; then - echo "오류: .env 파일을 찾을 수 없습니다: $ENV_FILE" + echo "Error: .env file not found: $ENV_FILE" exit 1 fi -# 템플릿 파일 존재 확인 +# Check if template file exists if [ ! -f "$TEMPLATE_FILE" ]; then - echo "오류: nginx 템플릿 파일을 찾을 수 없습니다: $TEMPLATE_FILE" + echo "Error: nginx template file not found: $TEMPLATE_FILE" exit 1 fi -# .env 파일을 환경변수로 로드 -echo "환경변수를 로드합니다..." +# Load .env file as environment variables +echo "Loading environment variables..." -# .env 파일을 직접 소스로 불러오기 +# Source .env file directly source "$ENV_FILE" -# 필수 환경변수 검증 -echo "필수 환경변수를 검증합니다..." +# Validate required environment variables +echo "Validating required environment variables..." -# 검증할 필수 환경변수 목록 +# List of required variables to validate REQUIRED_VARS=( "MC_IAM_MANAGER_PUBLIC_DOMAIN" "MC_IAM_MANAGER_KEYCLOAK_DOMAIN" @@ -89,7 +89,7 @@ REQUIRED_VARS=( "MC_IAM_MANAGER_PORT" ) -# 각 필수 환경변수 검증 +# Validate each required environment variable MISSING_VARS=() for var in "${REQUIRED_VARS[@]}"; do if [ -z "${!var}" ]; then @@ -97,28 +97,28 @@ for var in "${REQUIRED_VARS[@]}"; do fi done -# 누락된 환경변수가 있으면 종료 +# Exit if any required variables are missing if [ ${#MISSING_VARS[@]} -gt 0 ]; then - echo "❌ 오류: 다음 필수 환경변수가 설정되지 않았습니다:" + echo "❌ Error: The following required environment variables are not set:" for var in "${MISSING_VARS[@]}"; do echo " - $var" done echo "" - echo "해결 방법:" - echo "1. .env 파일이 존재하는지 확인: $ENV_FILE" - echo "2. .env 파일에 필수 환경변수들이 설정되어 있는지 확인" - echo "3. .env_sample 파일을 참고하여 누락된 환경변수를 추가" + echo "Resolution:" + echo "1. Verify the .env file exists: $ENV_FILE" + echo "2. Confirm all required environment variables are defined in .env" + echo "3. Refer to .env_sample to add any missing environment variables" exit 1 fi -# MC_IAM_MANAGER_KEYCLOAK_PORT가 설정되지 않은 경우 기본값 설정 +# Set default value if MC_IAM_MANAGER_KEYCLOAK_PORT is not set if [ -z "$MC_IAM_MANAGER_KEYCLOAK_PORT" ]; then MC_IAM_MANAGER_KEYCLOAK_PORT=8080 - echo "MC_IAM_MANAGER_KEYCLOAK_PORT가 설정되지 않아 기본값 8080을 사용합니다." + echo "MC_IAM_MANAGER_KEYCLOAK_PORT is not set; using default value 8080." fi -echo "✅ 모든 필수 환경변수가 정상적으로 로드되었습니다." -echo "읽어온 환경변수:" +echo "✅ All required environment variables loaded successfully." +echo "Loaded environment variables:" echo " PUBLIC_DOMAIN: $MC_IAM_MANAGER_PUBLIC_DOMAIN" echo " KEYCLOAK_DOMAIN: $MC_IAM_MANAGER_KEYCLOAK_DOMAIN" echo " MC_IAM_MANAGER_KEYCLOAK_PORT: $MC_IAM_MANAGER_KEYCLOAK_PORT" @@ -127,17 +127,17 @@ echo " DATABASE_USER: $MC_IAM_MANAGER_DATABASE_USER" echo " DATABASE_HOST: $MC_IAM_MANAGER_DATABASE_HOST" echo " MC_IAM_MANAGER_PORT: $MC_IAM_MANAGER_PORT" -# PUBLIC_DOMAIN 기준으로 인증서 디렉토리 정의 (Let's Encrypt 구조와 동일) +# Define certificate directory based on PUBLIC_DOMAIN (same structure as Let's Encrypt) CERT_DIR="${CERT_PARENT_DIR}/certs/live/${MC_IAM_MANAGER_PUBLIC_DOMAIN}" -# Let's Encrypt 구조와 동일한 certs/live/도메인명 디렉토리 생성 +# Create certs/live/ directory (same structure as Let's Encrypt) echo "Creating certificate directory: ${CERT_DIR}" mkdir -p "${CERT_DIR}" || { echo "Error: Failed to create ${CERT_DIR}"; exit 1; } echo "✓ Certificate directory created successfully" -## 로컬환경(인증서) 설정 -# IP 주소인지 도메인인지 판별 +## Local environment (certificate) settings +# Determine whether PUBLIC_DOMAIN is an IP address or a hostname if [[ "${MC_IAM_MANAGER_PUBLIC_DOMAIN}" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then IS_IP=true SAN_ENTRY="IP:${MC_IAM_MANAGER_PUBLIC_DOMAIN}" @@ -147,7 +147,7 @@ else SAN_ENTRY="DNS:${MC_IAM_MANAGER_PUBLIC_DOMAIN}" fi -# --- 3. hosts 파일에 도메인 추가 (도메인인 경우에만) --- +# --- 3. Add domain to hosts file (only if it is a hostname) --- if [ "$IS_IP" = false ]; then HOSTS_FILE="/etc/hosts" echo "Checking ${MC_IAM_MANAGER_PUBLIC_DOMAIN} in ${HOSTS_FILE}..." @@ -169,10 +169,10 @@ if [ "$IS_IP" = false ]; then fi -# --- 4. Self-Signed Certificate 생성 (SAN 포함) --- +# --- 4. Generate Self-Signed Certificate (with SAN) --- echo "Generating Self-Signed Certificate for ${MC_IAM_MANAGER_PUBLIC_DOMAIN} (SAN: ${SAN_ENTRY})... ${CERT_DIR}" -# 기존 인증서 삭제 (새로 발급하기 위해) +# Remove existing certificate files (to issue a fresh one) if [ -f "${CERT_DIR}/privkey.pem" ]; then echo "Removing existing certificate files..." rm "${CERT_DIR}/privkey.pem" "${CERT_DIR}/fullchain.pem" 2>/dev/null @@ -196,24 +196,24 @@ fi -echo "nginx 설정 파일을 생성합니다..." -echo "템플릿: $TEMPLATE_FILE" -echo "출력: $OUTPUT_FILE" +echo "Generating nginx configuration file..." +echo "Template: $TEMPLATE_FILE" +echo "Output: $OUTPUT_FILE" -# 출력 디렉토리가 필요한 경우에만 생성 (상대 경로나 절대 경로인 경우) +# Create output directory only when needed (for relative or absolute paths) OUTPUT_DIR="$(dirname "$OUTPUT_FILE")" if [ "$OUTPUT_DIR" != "." ] && [ "$OUTPUT_DIR" != "$(pwd)" ]; then echo "Creating output directory: $OUTPUT_DIR" mkdir -p "$OUTPUT_DIR" fi -# 기존 nginx.conf 파일이 디렉토리인 경우 제거 +# Remove output path if it is an existing directory if [ -d "$OUTPUT_FILE" ]; then echo "Removing existing directory: $OUTPUT_FILE" rm -rf "$OUTPUT_FILE" fi -# 환경변수 대치 (한 번에 처리) +# Substitute environment variables (processed in a single pass) if [ -n "$MC_IAM_MANAGER_PUBLIC_DOMAIN" ] && [ -n "$MC_IAM_MANAGER_KEYCLOAK_PORT" ]; then sed -e "s/\${MC_IAM_MANAGER_DOMAIN}/$MC_IAM_MANAGER_DOMAIN/g" \ -e "s/\${MC_IAM_MANAGER_PORT}/$MC_IAM_MANAGER_PORT/g" \ @@ -230,17 +230,17 @@ if [ -n "$MC_IAM_MANAGER_PUBLIC_DOMAIN" ] && [ -n "$MC_IAM_MANAGER_KEYCLOAK_PORT -e "s/mciam-manager/mc-iam-manager/g" \ -e "s/mciam-keycloak/mc-iam-manager-kc/g" \ "$TEMPLATE_FILE" > "$OUTPUT_FILE" - echo "✓ PUBLIC_DOMAIN 대치 완료: $MC_IAM_MANAGER_PUBLIC_DOMAIN" - echo "✓ PORT 대치 완료: $MC_IAM_MANAGER_KEYCLOAK_PORT" - echo "✓ 컨테이너 이름 수정 완료" + echo "✓ PUBLIC_DOMAIN substitution done: $MC_IAM_MANAGER_PUBLIC_DOMAIN" + echo "✓ PORT substitution done: $MC_IAM_MANAGER_KEYCLOAK_PORT" + echo "✓ Container name substitution done" else - echo "경고: MC_IAM_MANAGER_PUBLIC_DOMAIN 또는 MC_IAM_MANAGER_KEYCLOAK_PORT 환경변수가 설정되지 않았습니다." + echo "Warning: MC_IAM_MANAGER_PUBLIC_DOMAIN or MC_IAM_MANAGER_KEYCLOAK_PORT environment variable is not set." cp "$TEMPLATE_FILE" "$OUTPUT_FILE" fi -echo "nginx 설정 파일 생성이 완료되었습니다: $OUTPUT_FILE" +echo "nginx configuration file generated successfully: $OUTPUT_FILE" -# 생성된 파일의 내용 확인 (선택사항) +# Display generated file contents (optional) echo "" -echo "=== 생성된 nginx.conf 파일 내용 ===" +echo "=== Generated nginx.conf contents ===" cat "$OUTPUT_FILE" \ No newline at end of file diff --git a/conf/docker/conf/mc-iam-manager/0_preset_prod.sh b/conf/docker/conf/mc-iam-manager/0_preset_prod.sh index 794c496..f92cfe5 100755 --- a/conf/docker/conf/mc-iam-manager/0_preset_prod.sh +++ b/conf/docker/conf/mc-iam-manager/0_preset_prod.sh @@ -1,45 +1,45 @@ #!/bin/bash set -euo pipefail -# 템플릿 파일에서 환경변수를 .env 파일의 값으로 대치하는 스크립트 +# Script to substitute environment variables in the template file with values from the .env file -# 스크립트 실행 디렉토리 확인 +# Resolve script execution directory SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")" -# .env 파일 경로 +# .env file path ENV_FILE="$PROJECT_ROOT/.env" -# 템플릿 파일 경로 +# Template file path TEMPLATE_FILE="./nginx.template.conf" -# 출력 파일 경로 +# Output file path OUTPUT_FILE="${PROJECT_ROOT}/container-volume/mc-iam-manager/nginx/nginx.conf" -# .env 파일 존재 확인 +# Check if .env file exists if [ ! -f "$ENV_FILE" ]; then - echo "오류: .env 파일을 찾을 수 없습니다: $ENV_FILE" + echo "Error: .env file not found: $ENV_FILE" exit 1 fi -# 템플릿 파일 존재 확인 +# Check if template file exists if [ ! -f "$TEMPLATE_FILE" ]; then - echo "오류: nginx 템플릿 파일을 찾을 수 없습니다: $TEMPLATE_FILE" + echo "Error: nginx template file not found: $TEMPLATE_FILE" exit 1 fi -# 출력 디렉토리 생성 +# Create output directory OUTPUT_DIR="$(dirname "$OUTPUT_FILE")" -mkdir -p "$OUTPUT_DIR" || { echo "오류: 디렉토리를 생성할 수 없습니다: $OUTPUT_DIR (권한 문제일 수 있습니다)"; exit 1; } +mkdir -p "$OUTPUT_DIR" || { echo "Error: Cannot create directory: $OUTPUT_DIR (may be a permission issue)"; exit 1; } -echo "nginx 설정 파일을 생성합니다..." -echo "템플릿: $TEMPLATE_FILE" -echo "출력: $OUTPUT_FILE" +echo "Generating nginx configuration file..." +echo "Template: $TEMPLATE_FILE" +echo "Output: $OUTPUT_FILE" -# .env 파일을 안전하게 로드 -echo "환경변수를 로드합니다..." +# Load .env file safely +echo "Loading environment variables..." -# .env 파일에서 필요한 변수들을 직접 읽어오기 +# Read required variables directly from .env file MC_IAM_MANAGER_PORT=$(grep -m1 "^MC_IAM_MANAGER_PORT=" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'" | xargs) MC_IAM_MANAGER_DOMAIN=$(grep -m1 "^MC_IAM_MANAGER_DOMAIN=" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'" | xargs) MC_IAM_MANAGER_PUBLIC_DOMAIN=$(grep -m1 "^MC_IAM_MANAGER_PUBLIC_DOMAIN=" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'" | xargs) @@ -48,7 +48,7 @@ MC_IAM_MANAGER_KEYCLOAK_PORT=$(grep -m1 "^MC_IAM_MANAGER_KEYCLOAK_PORT=" "$ENV_F MC_OBSERVABILITY_GRAFANA_PROXY_PORT=$(grep -m1 "^MC_OBSERVABILITY_GRAFANA_PROXY_PORT=" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'" | xargs) MC_COST_OPTIMIZER_FE_PROXY_PORT=$(grep -m1 "^MC_COST_OPTIMIZER_FE_PROXY_PORT=" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'" | xargs) -echo "읽어온 환경변수:" +echo "Loaded environment variables:" echo " MC_IAM_MANAGER_DOMAIN: $MC_IAM_MANAGER_DOMAIN" echo " MC_IAM_MANAGER_PORT: $MC_IAM_MANAGER_PORT" echo " MC_IAM_MANAGER_PUBLIC_DOMAIN: $MC_IAM_MANAGER_PUBLIC_DOMAIN" @@ -57,49 +57,49 @@ echo " MC_IAM_MANAGER_KEYCLOAK_PORT: $MC_IAM_MANAGER_KEYCLOAK_PORT" echo " MC_OBSERVABILITY_GRAFANA_PROXY_PORT: $MC_OBSERVABILITY_GRAFANA_PROXY_PORT" echo " MC_COST_OPTIMIZER_FE_PROXY_PORT: $MC_COST_OPTIMIZER_FE_PROXY_PORT" -# 템플릿 파일을 복사하고 환경변수 대치 -cp "$TEMPLATE_FILE" "$OUTPUT_FILE" || { echo "오류: 템플릿 파일 복사 실패: $TEMPLATE_FILE → $OUTPUT_FILE"; exit 1; } +# Copy template file and substitute environment variables +cp "$TEMPLATE_FILE" "$OUTPUT_FILE" || { echo "Error: Failed to copy template file: $TEMPLATE_FILE → $OUTPUT_FILE"; exit 1; } if [ -n "$MC_IAM_MANAGER_PORT" ]; then sed -i "s/\${MC_IAM_MANAGER_PORT}/$MC_IAM_MANAGER_PORT/g" "$OUTPUT_FILE" - echo "✓ MC_IAM_MANAGER_PORT 대치 완료: $MC_IAM_MANAGER_PORT" + echo "✓ MC_IAM_MANAGER_PORT substitution done: $MC_IAM_MANAGER_PORT" else - echo "경고: MC_IAM_MANAGER_PORT 환경변수가 설정되지 않았습니다." + echo "Warning: MC_IAM_MANAGER_PORT environment variable is not set." fi if [ -n "$MC_IAM_MANAGER_PUBLIC_DOMAIN" ]; then sed -i "s/\${MC_IAM_MANAGER_PUBLIC_DOMAIN}/$MC_IAM_MANAGER_PUBLIC_DOMAIN/g" "$OUTPUT_FILE" - echo "✓ MC_IAM_MANAGER_PUBLIC_DOMAIN 대치 완료: $MC_IAM_MANAGER_PUBLIC_DOMAIN" + echo "✓ MC_IAM_MANAGER_PUBLIC_DOMAIN substitution done: $MC_IAM_MANAGER_PUBLIC_DOMAIN" else - echo "경고: MC_IAM_MANAGER_PUBLIC_DOMAIN 환경변수가 설정되지 않았습니다." + echo "Warning: MC_IAM_MANAGER_PUBLIC_DOMAIN environment variable is not set." fi if [ -n "$MC_IAM_MANAGER_KEYCLOAK_DOMAIN" ]; then sed -i "s/\${MC_IAM_MANAGER_KEYCLOAK_DOMAIN}/$MC_IAM_MANAGER_KEYCLOAK_DOMAIN/g" "$OUTPUT_FILE" - echo "✓ MC_IAM_MANAGER_KEYCLOAK_DOMAIN 대치 완료: $MC_IAM_MANAGER_KEYCLOAK_DOMAIN" + echo "✓ MC_IAM_MANAGER_KEYCLOAK_DOMAIN substitution done: $MC_IAM_MANAGER_KEYCLOAK_DOMAIN" else - echo "경고: MC_IAM_MANAGER_KEYCLOAK_DOMAIN 환경변수가 설정되지 않았습니다." + echo "Warning: MC_IAM_MANAGER_KEYCLOAK_DOMAIN environment variable is not set." fi if [ -n "$MC_IAM_MANAGER_KEYCLOAK_PORT" ]; then sed -i "s/\${MC_IAM_MANAGER_KEYCLOAK_PORT}/$MC_IAM_MANAGER_KEYCLOAK_PORT/g" "$OUTPUT_FILE" - echo "✓ MC_IAM_MANAGER_KEYCLOAK_PORT 대치 완료: $MC_IAM_MANAGER_KEYCLOAK_PORT" + echo "✓ MC_IAM_MANAGER_KEYCLOAK_PORT substitution done: $MC_IAM_MANAGER_KEYCLOAK_PORT" else - echo "경고: MC_IAM_MANAGER_KEYCLOAK_PORT 환경변수가 설정되지 않았습니다." + echo "Warning: MC_IAM_MANAGER_KEYCLOAK_PORT environment variable is not set." fi if [ -n "$MC_OBSERVABILITY_GRAFANA_PROXY_PORT" ]; then sed -i "s/\${MC_OBSERVABILITY_GRAFANA_PROXY_PORT}/$MC_OBSERVABILITY_GRAFANA_PROXY_PORT/g" "$OUTPUT_FILE" - echo "✓ MC_OBSERVABILITY_GRAFANA_PROXY_PORT 대치 완료: $MC_OBSERVABILITY_GRAFANA_PROXY_PORT" + echo "✓ MC_OBSERVABILITY_GRAFANA_PROXY_PORT substitution done: $MC_OBSERVABILITY_GRAFANA_PROXY_PORT" else - echo "경고: MC_OBSERVABILITY_GRAFANA_PROXY_PORT 환경변수가 설정되지 않았습니다." + echo "Warning: MC_OBSERVABILITY_GRAFANA_PROXY_PORT environment variable is not set." fi if [ -n "$MC_COST_OPTIMIZER_FE_PROXY_PORT" ]; then sed -i "s/\${MC_COST_OPTIMIZER_FE_PROXY_PORT}/$MC_COST_OPTIMIZER_FE_PROXY_PORT/g" "$OUTPUT_FILE" - echo "✓ MC_COST_OPTIMIZER_FE_PROXY_PORT 대치 완료: $MC_COST_OPTIMIZER_FE_PROXY_PORT" + echo "✓ MC_COST_OPTIMIZER_FE_PROXY_PORT substitution done: $MC_COST_OPTIMIZER_FE_PROXY_PORT" else - echo "경고: MC_COST_OPTIMIZER_FE_PROXY_PORT 환경변수가 설정되지 않았습니다." + echo "Warning: MC_COST_OPTIMIZER_FE_PROXY_PORT environment variable is not set." fi MC_COST_OPTIMIZER_BE_PORT=$(grep -m1 "^MC_COST_OPTIMIZER_BE_PORT=" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'" | xargs) @@ -107,16 +107,16 @@ MC_COST_OPTIMIZER_ALARM_PORT=$(grep -m1 "^MC_COST_OPTIMIZER_ALARM_PORT=" "$ENV_F if [ -n "$MC_COST_OPTIMIZER_BE_PORT" ]; then sed -i "s/\${MC_COST_OPTIMIZER_BE_PORT}/$MC_COST_OPTIMIZER_BE_PORT/g" "$OUTPUT_FILE" - echo "✓ MC_COST_OPTIMIZER_BE_PORT 대치 완료: $MC_COST_OPTIMIZER_BE_PORT" + echo "✓ MC_COST_OPTIMIZER_BE_PORT substitution done: $MC_COST_OPTIMIZER_BE_PORT" else - echo "경고: MC_COST_OPTIMIZER_BE_PORT 환경변수가 설정되지 않았습니다." + echo "Warning: MC_COST_OPTIMIZER_BE_PORT environment variable is not set." fi if [ -n "$MC_COST_OPTIMIZER_ALARM_PORT" ]; then sed -i "s/\${MC_COST_OPTIMIZER_ALARM_PORT}/$MC_COST_OPTIMIZER_ALARM_PORT/g" "$OUTPUT_FILE" - echo "✓ MC_COST_OPTIMIZER_ALARM_PORT 대치 완료: $MC_COST_OPTIMIZER_ALARM_PORT" + echo "✓ MC_COST_OPTIMIZER_ALARM_PORT substitution done: $MC_COST_OPTIMIZER_ALARM_PORT" else - echo "경고: MC_COST_OPTIMIZER_ALARM_PORT 환경변수가 설정되지 않았습니다." + echo "Warning: MC_COST_OPTIMIZER_ALARM_PORT environment variable is not set." fi MC_WORKFLOW_MANAGER_PROXY_PORT=$(grep -m1 "^MC_WORKFLOW_MANAGER_PROXY_PORT=" "$ENV_FILE" | cut -d'=' -f2 | tr -d '"' | tr -d "'" | xargs) @@ -125,33 +125,33 @@ MC_APPLICATION_MANAGER_PROXY_PORT=$(grep -m1 "^MC_APPLICATION_MANAGER_PROXY_PORT if [ -n "$MC_WORKFLOW_MANAGER_PROXY_PORT" ]; then sed -i "s/\${MC_WORKFLOW_MANAGER_PROXY_PORT}/$MC_WORKFLOW_MANAGER_PROXY_PORT/g" "$OUTPUT_FILE" - echo "✓ MC_WORKFLOW_MANAGER_PROXY_PORT 대치 완료: $MC_WORKFLOW_MANAGER_PROXY_PORT" + echo "✓ MC_WORKFLOW_MANAGER_PROXY_PORT substitution done: $MC_WORKFLOW_MANAGER_PROXY_PORT" else - echo "경고: MC_WORKFLOW_MANAGER_PROXY_PORT 환경변수가 설정되지 않았습니다." + echo "Warning: MC_WORKFLOW_MANAGER_PROXY_PORT environment variable is not set." fi if [ -n "$MC_DATA_MANAGER_PROXY_PORT" ]; then sed -i "s/\${MC_DATA_MANAGER_PROXY_PORT}/$MC_DATA_MANAGER_PROXY_PORT/g" "$OUTPUT_FILE" - echo "✓ MC_DATA_MANAGER_PROXY_PORT 대치 완료: $MC_DATA_MANAGER_PROXY_PORT" + echo "✓ MC_DATA_MANAGER_PROXY_PORT substitution done: $MC_DATA_MANAGER_PROXY_PORT" else - echo "경고: MC_DATA_MANAGER_PROXY_PORT 환경변수가 설정되지 않았습니다." + echo "Warning: MC_DATA_MANAGER_PROXY_PORT environment variable is not set." fi if [ -n "$MC_APPLICATION_MANAGER_PROXY_PORT" ]; then sed -i "s/\${MC_APPLICATION_MANAGER_PROXY_PORT}/$MC_APPLICATION_MANAGER_PROXY_PORT/g" "$OUTPUT_FILE" - echo "✓ MC_APPLICATION_MANAGER_PROXY_PORT 대치 완료: $MC_APPLICATION_MANAGER_PROXY_PORT" + echo "✓ MC_APPLICATION_MANAGER_PROXY_PORT substitution done: $MC_APPLICATION_MANAGER_PROXY_PORT" else - echo "경고: MC_APPLICATION_MANAGER_PROXY_PORT 환경변수가 설정되지 않았습니다." + echo "Warning: MC_APPLICATION_MANAGER_PROXY_PORT environment variable is not set." fi -# 컨테이너 이름 치환 (템플릿 내 레거시 이름 정정) +# Substitute container names (correct legacy names in template) sed -i "s/mciam-manager/mc-iam-manager/g" "$OUTPUT_FILE" sed -i "s/mciam-keycloak/mc-iam-manager-kc/g" "$OUTPUT_FILE" -echo "✓ 컨테이너 이름 수정 완료" +echo "✓ Container name substitution done" -echo "nginx 설정 파일 생성이 완료되었습니다: $OUTPUT_FILE" +echo "nginx configuration file generated successfully: $OUTPUT_FILE" -# 생성된 파일의 내용 확인 (선택사항) +# Display generated file contents (optional) echo "" -echo "=== 생성된 nginx.conf 파일 내용 ===" +echo "=== Generated nginx.conf contents ===" cat "$OUTPUT_FILE" diff --git a/conf/docker/conf/mc-iam-manager/1_setup_auto.sh b/conf/docker/conf/mc-iam-manager/1_setup_auto.sh index 726806d..a8379d6 100755 --- a/conf/docker/conf/mc-iam-manager/1_setup_auto.sh +++ b/conf/docker/conf/mc-iam-manager/1_setup_auto.sh @@ -1,13 +1,13 @@ #!/bin/bash -# UID 변수 충돌 방지 - .env.setup 파일 사용 +# Prevent UID variable conflict — use .env.setup file source .env -# 자동화된 설정 함수 +# Automated setup function auto_setup() { echo "=== Starting automated setup process ===" - # 1. 플랫폼 어드민 초기화 + # 1. Platform admin initialization echo "Step 1: Initializing platform admin..." init_platform_admin if [ $? -ne 0 ]; then @@ -16,7 +16,7 @@ auto_setup() { fi echo "✓ Platform admin initialized successfully" - # 2. 로그인 + # 2. Login echo "Step 2: Logging in..." login if [ $? -ne 0 ]; then @@ -25,7 +25,7 @@ auto_setup() { fi echo "✓ Login successful" - # 3. 역할 데이터 초기화 + # 3. Role data initialization echo "Step 3: Initializing predefined roles..." init_predefined_roles if [ $? -ne 0 ]; then @@ -34,7 +34,7 @@ auto_setup() { fi echo "✓ Predefined roles initialized successfully" - # 4. 메뉴 데이터 초기화 + # 4. Menu data initialization echo "Step 4: Initializing menu data..." init_menu if [ $? -ne 0 ]; then @@ -43,7 +43,7 @@ auto_setup() { fi echo "✓ Menu data initialized successfully" - # 5. API 리소스 데이터 초기화 + # 5. API resource data initialization echo "Step 5: Initializing API resources..." init_api_resources if [ $? -ne 0 ]; then @@ -52,7 +52,7 @@ auto_setup() { fi echo "✓ API resources initialized successfully" - # 5-1. 프레임워크 서비스 URL 등록 (sync-projects 전 서비스 레지스트리 선행 등록) + # 5-1. Register framework service URLs (must precede sync-projects in the service registry) echo "Step 5-1: Registering framework service URLs..." register_framework_services if [ $? -ne 0 ]; then @@ -61,7 +61,7 @@ auto_setup() { fi echo "✓ Framework services registered successfully" - # 5-2. iframe 서비스 URL을 브라우저 접근 가능한 외부 주소로 갱신 + # 5-2. Update iframe service URLs to public-accessible addresses echo "Step 5-2: Updating iframe service URLs to public addresses..." update_public_service_urls if [ $? -ne 0 ]; then @@ -70,7 +70,7 @@ auto_setup() { echo "✓ Public service URLs updated successfully" fi - # 6. 프로젝트 동기화 + # 6. Project sync echo "Step 6: Syncing projects..." sync_projects if [ $? -ne 0 ]; then @@ -79,7 +79,7 @@ auto_setup() { fi echo "✓ Projects synced successfully" - # 7. Keycloak client redirect URI 설정 + # 7. Keycloak client redirect URI configuration echo "Step 7: Configuring Keycloak client redirect URIs..." configure_keycloak_client_uris if [ $? -ne 0 ]; then @@ -88,7 +88,7 @@ auto_setup() { echo "✓ Keycloak client redirect URIs configured successfully" fi - # 8. 워크스페이스-프로젝트 매핑 + # 8. Workspace-project mapping echo "Step 8: Mapping workspace to all projects..." map_workspace_projects if [ $? -ne 0 ]; then @@ -114,7 +114,7 @@ init_platform_admin() { echo "Admin Email: $MC_IAM_MANAGER_PLATFORMADMIN_EMAIL" echo "Admin Username: $MC_IAM_MANAGER_PLATFORMADMIN_ID" - # 환경 변수 사용 + # Use environment variables json_data=$(jq -n \ --arg email "$MC_IAM_MANAGER_PLATFORMADMIN_EMAIL" \ --arg password "$MC_IAM_MANAGER_PLATFORMADMIN_PASSWORD" \ @@ -128,34 +128,34 @@ init_platform_admin() { --data "$json_data" \ "$MC_IAM_MANAGER_HOST/api/initial-admin") - # HTTP 상태 코드와 응답 본문 분리 + # Split HTTP status code and response body http_code=$(echo $response | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') response_body=$(echo $response | sed -e 's/HTTPSTATUS\:.*//g') echo "Platform admin init HTTP Status: $http_code" echo "Platform admin init Response Body: $response_body" - # 응답 검증 + # Validate response if [ $? -ne 0 ]; then echo "ERROR: Failed to make request to platform admin API" echo "curl exit code: $?" return 1 fi - # HTTP 상태 코드 확인 + # Check HTTP status code if [ "$http_code" != "200" ] && [ "$http_code" != "201" ]; then echo "ERROR: Platform admin initialization failed with HTTP status $http_code" return 1 fi - # JSON 응답 검증 + # Validate JSON response if ! echo "$response_body" | jq . > /dev/null 2>&1; then echo "ERROR: Invalid JSON response from platform admin API" echo "Raw response: $response_body" return 1 fi - # 성공 여부 확인 (응답에 에러가 없는지 확인) + # Check success (verify no error field in response) if echo "$response_body" | jq -e '.error' > /dev/null 2>&1; then echo "ERROR: Platform admin initialization failed with error in response" echo "Error details:" @@ -171,7 +171,7 @@ login() { echo "=== Starting Login Process ===" echo "Target URL: $MC_IAM_MANAGER_HOST/api/auth/login" - # 환경 변수에서 플랫폼 어드민 정보 사용 + # Use platform admin credentials from environment variables if [ -z "$MC_IAM_MANAGER_PLATFORMADMIN_ID" ] || [ -z "$MC_IAM_MANAGER_PLATFORMADMIN_PASSWORD" ]; then echo "ERROR: Platform admin credentials not found in .env file" echo "Please check MC_IAM_MANAGER_PLATFORMADMIN_ID and MC_IAM_MANAGER_PLATFORMADMIN_PASSWORD in .env" @@ -180,7 +180,7 @@ login() { echo "Using platform admin ID: $MC_IAM_MANAGER_PLATFORMADMIN_ID" - # 로그인 요청 JSON 생성 + # Build login request JSON login_json=$(jq -n \ --arg id "$MC_IAM_MANAGER_PLATFORMADMIN_ID" \ --arg password "$MC_IAM_MANAGER_PLATFORMADMIN_PASSWORD" \ @@ -192,40 +192,40 @@ login() { --data "$login_json" \ "$MC_IAM_MANAGER_HOST/api/auth/login") - # HTTP 상태 코드와 응답 본문 분리 + # Split HTTP status code and response body http_code=$(echo $response | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') response_body=$(echo $response | sed -e 's/HTTPSTATUS\:.*//g') echo "Login HTTP Status: $http_code" echo "Login Response Body: $response_body" - # 응답 검증 + # Validate response if [ $? -ne 0 ]; then echo "ERROR: Failed to make login request" echo "curl exit code: $?" return 1 fi - # HTTP 상태 코드 확인 + # Check HTTP status code if [ "$http_code" != "200" ]; then echo "ERROR: Login failed with HTTP status $http_code" return 1 fi - # 디버깅: jq가 설치되어 있는지 확인 + # Debug: check if jq is installed if ! command -v jq &> /dev/null; then echo "ERROR: jq is not installed. Please install jq first." return 1 fi - # 디버깅: 응답이 유효한 JSON인지 확인 + # Debug: verify response is valid JSON if ! echo "$response_body" | jq . > /dev/null 2>&1; then echo "ERROR: Invalid JSON response" echo "Raw response: $response_body" return 1 fi - # 디버깅: access_token 필드가 있는지 확인 + # Debug: check if access_token field exists in response if ! echo "$response_body" | jq -e '.access_token' > /dev/null 2>&1; then echo "ERROR: access_token field not found in response" echo "Available fields:" @@ -235,7 +235,7 @@ login() { MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN="$(echo "$response_body" | jq -r '.access_token')" - # 디버깅: 토큰이 제대로 추출되었는지 확인 + # Debug: verify token was extracted successfully if [ -z "$MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" ] || [ "$MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" = "null" ]; then echo "ERROR: Failed to extract access token" echo "Extracted token: '$MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN'" @@ -260,7 +260,7 @@ init_predefined_roles() { --data "$json_data" \ "$MC_IAM_MANAGER_HOST/api/roles") - # 응답 검증 + # Validate response if [ $? -ne 0 ]; then echo "ERROR: Failed to create role: $role" return 1 @@ -268,7 +268,7 @@ init_predefined_roles() { echo "Response for role $role: $response" - # 성공 여부 확인 + # Check success if echo "$response" | jq -e '.error' > /dev/null 2>&1; then echo "ERROR: Failed to create role: $role" return 1 @@ -282,7 +282,7 @@ init_menu() { echo "Initializing menu data..." wget -q -O ./menu.yaml "$MC_WEB_CONSOLE_MENUYAML" - # wget 성공 여부 확인 + # Check if wget succeeded if [ $? -ne 0 ]; then echo "ERROR: Failed to download menu.yaml" return 1 @@ -293,7 +293,7 @@ init_menu() { --header 'Content-Type: application/json' \ "$MC_IAM_MANAGER_HOST/api/setup/initial-menus") - # 응답 검증 + # Validate response if [ $? -ne 0 ]; then echo "ERROR: Failed to initialize menu data" return 1 @@ -301,7 +301,7 @@ init_menu() { echo "Menu initialization response: $response" - # 성공 여부 확인 + # Check success if echo "$response" | jq -e '.error' > /dev/null 2>&1; then echo "ERROR: Menu initialization failed" return 1 @@ -330,7 +330,7 @@ init_api_resources() { --header 'Content-Type: application/json' \ "$MC_IAM_MANAGER_HOST/api/setup/sync-mcmp-apis") - # 응답 검증 + # Validate response if [ $? -ne 0 ]; then echo "ERROR: Failed to initialize API resources" return 1 @@ -338,7 +338,7 @@ init_api_resources() { echo "API resources initialization response: $response" - # 성공 여부 확인 + # Check success if echo "$response" | jq -e '.error' > /dev/null 2>&1; then echo "ERROR: API resources initialization failed" return 1 @@ -351,8 +351,8 @@ init_api_resources() { register_framework_services() { echo "Registering framework service URLs to mcmp_api_services..." - # api.yaml의 services 섹션에 정의된 서비스들을 POST /api/mcmp-apis 로 등록 - # sync-mcmp-apis는 serviceActions(권한)만 등록하고 service URL 레지스트리는 미처리하므로 별도 등록 필요 + # Register services defined in the services section of api.yaml via POST /api/mcmp-apis + # sync-mcmp-apis only registers serviceActions (permissions) and does not handle the service URL registry — register separately register_service() { local name="$1" @@ -384,7 +384,7 @@ register_framework_services() { if [ "$http_code" = "201" ]; then echo " ✓ Registered: $name ($base_url)" elif [ "$http_code" = "409" ]; then - # 기존 레코드가 있으면 base_url, version, auth 자격증명 모두 업데이트 + # If a record already exists, update base_url, version, and auth credentials PGPASSWORD="$MC_IAM_MANAGER_DATABASE_PASSWORD" psql \ -h "$MC_IAM_MANAGER_DATABASE_HOST" \ -p "${MC_IAM_MANAGER_DATABASE_PORT:-5432}" \ @@ -401,8 +401,8 @@ register_framework_services() { return 0 } - # api.yaml의 services 섹션에 정의된 모든 framework 등록 - # mc-iam-manager 자신은 service URL registry 등록 대상에서 제외 + # Register all frameworks defined in the services section of api.yaml + # mc-iam-manager itself is excluded from the service URL registry local failed=0 local current_svc="" local current_version="" @@ -410,9 +410,9 @@ register_framework_services() { local current_auth_type="" while IFS= read -r line; do - # 서비스 이름 감지 (2칸 들여쓰기 + 콜론으로 끝나는 라인) + # Detect service name (2-space indent + line ending with colon) if echo "$line" | grep -qE "^ [a-z].*:$"; then - # 직전 서비스 처리 + # Process the previous service if [ -n "$current_svc" ] && [ "$current_svc" != "mc-iam-manager" ]; then auth_user="" auth_pass="" @@ -439,7 +439,7 @@ register_framework_services() { fi done < <(sed -n '/^services:/,/^serviceActions:/p' ./api.yaml | head -n -1) - # 마지막 서비스 처리 + # Process the last service if [ -n "$current_svc" ] && [ "$current_svc" != "mc-iam-manager" ]; then auth_user="" auth_pass="" @@ -465,12 +465,12 @@ register_framework_services() { update_public_service_urls() { echo "Updating framework service URLs to public-accessible addresses..." - # mc-cost-optimizer-fe: 컨테이너 내부 URL(http://mc-cost-optimizer-fe:7780)을 - # 브라우저가 직접 접근 가능한 nginx HTTPS 프록시 URL로 갱신. - # MCIAM_USE=true 환경에서 /api/getapihosts가 이 값을 iframe src로 반환하기 때문. + # mc-cost-optimizer-fe: replace the internal container URL (http://mc-cost-optimizer-fe:7780) + # with the nginx HTTPS proxy URL accessible directly from the browser. + # /api/getapihosts returns this value as the iframe src in MCIAM_USE=true environments. local cost_fe_public_url="https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_COST_OPTIMIZER_FE_PROXY_PORT}" - # mc-cost-optimizer-fe는 upstream api.yaml에 없으므로 먼저 등록 시도(idempotent) + # mc-cost-optimizer-fe is not in the upstream api.yaml, so attempt registration first (idempotent) local reg_body reg_body=$(printf '{"name":"mc-cost-optimizer-fe","version":"v1","baseUrl":"http://mc-cost-optimizer-fe:7780","authType":"none","authUser":"","authPass":"","isActive":true}') local reg_resp @@ -490,7 +490,7 @@ update_public_service_urls() { return 1 fi - # baseurl을 외부 공개 URL로 갱신 + # Update baseurl to the external public URL local response response=$(curl -s -w "HTTPSTATUS:%{http_code}" -X PUT \ --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ @@ -510,9 +510,9 @@ update_public_service_urls() { return 1 fi - # mc-workflow-manager-fe: iframe 전용 nginx HTTPS 프록시 URL 등록 및 갱신 - # (원본 mc-workflow-manager는 내부 API 호출용으로 내부 URL 유지) - local wf_public_url="https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_WORKFLOW_MANAGER_PROXY_PORT}" + # mc-workflow-manager-fe: register and update dedicated iframe nginx HTTPS proxy URL + # (the original mc-workflow-manager retains its internal URL for internal API calls) + local wf_public_url="${MC_WORKFLOW_MANAGER_PUBLIC_HOST}" reg_body=$(printf '{"name":"mc-workflow-manager-fe","version":"v0.0.1","baseUrl":"http://mc-workflow-manager:18083","authType":"none","authUser":"","authPass":"","isActive":true}') reg_resp=$(curl -s -w "HTTPSTATUS:%{http_code}" -X POST \ --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ @@ -542,8 +542,8 @@ update_public_service_urls() { return 1 fi - # mc-data-manager-fe: iframe 전용 nginx HTTPS 프록시 URL 등록 및 갱신 - local dm_public_url="https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_DATA_MANAGER_PROXY_PORT}" + # mc-data-manager-fe: register and update dedicated iframe nginx HTTPS proxy URL + local dm_public_url="${MC_DATA_MANAGER_PUBLIC_HOST}" reg_body=$(printf '{"name":"mc-data-manager-fe","version":"v0.0.1","baseUrl":"http://mc-data-manager:3300","authType":"none","authUser":"","authPass":"","isActive":true}') reg_resp=$(curl -s -w "HTTPSTATUS:%{http_code}" -X POST \ --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ @@ -573,8 +573,8 @@ update_public_service_urls() { return 1 fi - # mc-application-manager-fe: iframe 전용 nginx HTTPS 프록시 URL 등록 및 갱신 - local am_public_url="https://${MC_IAM_MANAGER_PUBLIC_DOMAIN}:${MC_APPLICATION_MANAGER_PROXY_PORT}" + # mc-application-manager-fe: register and update dedicated iframe nginx HTTPS proxy URL + local am_public_url="${MC_APPLICATION_MANAGER_PUBLIC_HOST}" reg_body=$(printf '{"name":"mc-application-manager-fe","version":"v0.0.1","baseUrl":"http://mc-application-manager:18084","authType":"none","authUser":"","authPass":"","isActive":true}') reg_resp=$(curl -s -w "HTTPSTATUS:%{http_code}" -X POST \ --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ @@ -646,7 +646,7 @@ sync_projects() { echo "Target URL: $MC_IAM_MANAGER_HOST/api/setup/sync-projects" echo "Access Token: ${MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN:0:20}..." - # mc-infra-manager 상태 확인 + # Check mc-infra-manager availability echo "Checking mc-infra-manager availability..." infra_response=$(curl -s -w "HTTPSTATUS:%{http_code}" "http://mc-infra-manager:1323/tumblebug/readyz") infra_http_code=$(echo $infra_response | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') @@ -660,41 +660,41 @@ sync_projects() { echo "This may cause project sync to fail" fi - # 프로젝트 동기화 요청 + # Make project sync request echo "Making project sync request..." response=$(curl -s -w "HTTPSTATUS:%{http_code}" -X POST \ --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ --header 'Content-Type: application/json' \ "$MC_IAM_MANAGER_HOST/api/setup/sync-projects") - # HTTP 상태 코드와 응답 본문 분리 + # Split HTTP status code and response body http_code=$(echo $response | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') response_body=$(echo $response | sed -e 's/HTTPSTATUS\:.*//g') echo "Project sync HTTP Status: $http_code" echo "Project sync Response Body: $response_body" - # 응답 검증 + # Validate response if [ $? -ne 0 ]; then echo "ERROR: Failed to make request to project sync API" echo "curl exit code: $?" return 1 fi - # HTTP 상태 코드 확인 + # Check HTTP status code if [ "$http_code" != "200" ]; then echo "ERROR: Project sync failed with HTTP status $http_code" return 1 fi - # JSON 응답 검증 + # Validate JSON response if ! echo "$response_body" | jq . > /dev/null 2>&1; then echo "ERROR: Invalid JSON response from project sync API" echo "Raw response: $response_body" return 1 fi - # 성공 여부 확인 + # Check success if echo "$response_body" | jq -e '.error' > /dev/null 2>&1; then echo "ERROR: Project sync failed with error in response" echo "Error details:" @@ -702,7 +702,7 @@ sync_projects() { return 1 fi - # 성공 시 상세 정보 출력 + # Print detailed info on success echo "✓ Project sync completed successfully" echo "Response details:" echo "$response_body" | jq . @@ -720,7 +720,7 @@ configure_keycloak_client_uris() { PUBLIC_HOST="$MC_IAM_MANAGER_PUBLIC_HOST" echo "Public host: $PUBLIC_HOST" - # Keycloak admin token 발급 + # Obtain Keycloak admin token KC_ADMIN_TOKEN=$(curl -s -X POST \ "${MC_IAM_MANAGER_KEYCLOAK_HOST}/realms/master/protocol/openid-connect/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ @@ -738,11 +738,11 @@ configure_keycloak_client_uris() { KC_ADMIN_URL="${MC_IAM_MANAGER_KEYCLOAK_HOST}/admin/realms/${MC_IAM_MANAGER_KEYCLOAK_REALM}" - # mciamClient, mciam-oidc-Client 두 클라이언트 설정 + # Configure both mciamClient and mciam-oidc-Client for CLIENT_NAME in "$MC_IAM_MANAGER_KEYCLOAK_CLIENT_NAME" "$MC_IAM_MANAGER_KEYCLOAK_OIDC_CLIENT_NAME"; do [ -z "$CLIENT_NAME" ] && continue - # client ID (UUID) 조회 + # Look up client ID (UUID) CLIENT_ID=$(curl -s \ "${KC_ADMIN_URL}/clients?clientId=${CLIENT_NAME}" \ -H "Authorization: Bearer ${KC_ADMIN_TOKEN}" \ @@ -753,7 +753,7 @@ configure_keycloak_client_uris() { continue fi - # 현재 client 설정 조회 후 redirect URI 갱신 + # Fetch current client config, then update redirect URI CURRENT=$(curl -s "${KC_ADMIN_URL}/clients/${CLIENT_ID}" \ -H "Authorization: Bearer ${KC_ADMIN_TOKEN}") @@ -779,14 +779,14 @@ configure_keycloak_client_uris() { map_workspace_projects() { echo "Getting workspace list..." - # 워크스페이스 목록 가져오기 + # Get workspace list workspace_response=$(curl -s -X POST \ --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ --header 'Content-Type: application/json' \ --data '{}' \ "$MC_IAM_MANAGER_HOST/api/workspaces/list") - # 응답 검증 + # Validate response if [ $? -ne 0 ]; then echo "ERROR: Failed to get workspace list" return 1 @@ -794,7 +794,7 @@ map_workspace_projects() { echo "Workspace list response: $workspace_response" - # 첫 번째 워크스페이스 ID 추출 + # Extract first workspace ID workspace_id=$(echo "$workspace_response" | jq -r '.[0].id // empty') if [ -z "$workspace_id" ] || [ "$workspace_id" = "null" ]; then @@ -804,7 +804,7 @@ map_workspace_projects() { echo "Using workspace ID: $workspace_id" - # 프로젝트 목록 가져오기 + # Get project list echo "Getting project list..." project_response=$(curl -s -X POST \ --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ @@ -812,7 +812,7 @@ map_workspace_projects() { --data '{}' \ "$MC_IAM_MANAGER_HOST/api/projects/list") - # 응답 검증 + # Validate response if [ $? -ne 0 ]; then echo "ERROR: Failed to get project list" return 1 @@ -820,7 +820,7 @@ map_workspace_projects() { echo "Project list response: $project_response" - # 모든 프로젝트 ID 추출 (문자열로 변환) + # Extract all project IDs (convert to strings) project_ids=$(echo "$project_response" | jq -r '[.[].id | tostring]') if [ -z "$project_ids" ] || [ "$project_ids" = "[]" ]; then @@ -830,7 +830,7 @@ map_workspace_projects() { echo "Found project IDs: $project_ids" - # 워크스페이스에 모든 프로젝트 매핑 + # Map all projects to workspace json_data=$(jq -n --arg workspace_id "$workspace_id" --argjson project_ids "$project_ids" \ '{workspaceId: $workspace_id, projectIds: $project_ids}') @@ -841,34 +841,34 @@ map_workspace_projects() { --data "$json_data" \ "$MC_IAM_MANAGER_HOST/api/workspaces/assign/projects") - # HTTP 상태 코드와 응답 본문 분리 + # Split HTTP status code and response body http_code=$(echo $response | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') response_body=$(echo $response | sed -e 's/HTTPSTATUS\:.*//g') echo "Workspace-Project mapping HTTP Status: $http_code" echo "Workspace-Project mapping Response Body: $response_body" - # 응답 검증 + # Validate response if [ $? -ne 0 ]; then echo "ERROR: Failed to make request to workspace-project mapping API" echo "curl exit code: $?" return 1 fi - # HTTP 상태 코드 확인 + # Check HTTP status code if [ "$http_code" != "200" ]; then echo "ERROR: Workspace-project mapping failed with HTTP status $http_code" return 1 fi - # JSON 응답 검증 + # Validate JSON response if ! echo "$response_body" | jq . > /dev/null 2>&1; then echo "ERROR: Invalid JSON response from workspace-project mapping API" echo "Raw response: $response_body" return 1 fi - # 성공 여부 확인 + # Check success if echo "$response_body" | jq -e '.error' > /dev/null 2>&1; then echo "ERROR: Workspace-project mapping failed with error in response" echo "Error details:" @@ -899,7 +899,7 @@ map_workspace_projects() { # --data "$json_data" \ # "$MC_IAM_MANAGER_HOST_FOR_INIT/api/roles/assign/platform-role") -# # 응답 검증 +# # Validate response # if [ $? -ne 0 ]; then # echo "ERROR: Failed to sync projects" # return 1 @@ -912,11 +912,11 @@ map_workspace_projects() { # return 0 # } -# 자동 설정 실행 +# Run automated setup echo "Starting automated setup process..." auto_setup -# 자동 설정 완료 후 종료 +# Exit after automated setup completes if [ $? -eq 0 ]; then echo "Setup completed successfully!" exit 0 diff --git a/conf/docker/conf/mc-iam-manager/1_setup_manual.sh b/conf/docker/conf/mc-iam-manager/1_setup_manual.sh index 6aa4701..528f022 100755 --- a/conf/docker/conf/mc-iam-manager/1_setup_manual.sh +++ b/conf/docker/conf/mc-iam-manager/1_setup_manual.sh @@ -5,7 +5,7 @@ source ../../.env init_platform_admin() { echo "Initializing platform admin..." - # 환경 변수 사용 + # Use environment variables json_data=$(jq -n \ --arg email "$MC_IAM_MANAGER_PLATFORMADMIN_EMAIL" \ --arg password "$MC_IAM_MANAGER_PLATFORMADMIN_PASSWORD" \ @@ -30,20 +30,20 @@ login() { echo "Login response: $response" - # 디버깅: jq가 설치되어 있는지 확인 + # Debug: check if jq is installed if ! command -v jq &> /dev/null; then echo "ERROR: jq is not installed. Please install jq first." return 1 fi - # 디버깅: 응답이 유효한 JSON인지 확인 + # Debug: check if response is valid JSON if ! echo "$response" | jq . > /dev/null 2>&1; then echo "ERROR: Invalid JSON response" echo "Raw response: $response" return 1 fi - # 디버깅: access_token 필드가 있는지 확인 + # Debug: check if access_token field exists if ! echo "$response" | jq -e '.access_token' > /dev/null 2>&1; then echo "ERROR: access_token field not found in response" echo "Available fields:" @@ -53,7 +53,7 @@ login() { MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN="$(echo "$response" | jq -r '.access_token')" - # 디버깅: 토큰이 제대로 추출되었는지 확인 + # Debug: verify token was extracted correctly if [ -z "$MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" ] || [ "$MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" = "null" ]; then echo "ERROR: Failed to extract access token" echo "Extracted token: '$MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN'" @@ -141,7 +141,7 @@ sync_projects() { echo "Target URL: $MC_IAM_MANAGER_HOST/api/setup/sync-projects" echo "Access Token: ${MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN:0:20}..." - # mc-infra-manager 상태 확인 + # Check mc-infra-manager availability echo "Checking mc-infra-manager availability..." infra_response=$(curl -s -w "HTTPSTATUS:%{http_code}" "http://mc-infra-manager:1323/tumblebug/readyz") infra_http_code=$(echo $infra_response | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') @@ -155,41 +155,41 @@ sync_projects() { echo "This may cause project sync to fail" fi - # 프로젝트 동기화 요청 + # Make project sync request echo "Making project sync request..." response=$(curl -s -w "HTTPSTATUS:%{http_code}" -X POST \ --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ --header 'Content-Type: application/json' \ "$MC_IAM_MANAGER_HOST/api/setup/sync-projects") - # HTTP 상태 코드와 응답 본문 분리 + # Split HTTP status code and response body http_code=$(echo $response | tr -d '\n' | sed -e 's/.*HTTPSTATUS://') response_body=$(echo $response | sed -e 's/HTTPSTATUS\:.*//g') echo "Project sync HTTP Status: $http_code" echo "Project sync Response Body: $response_body" - # 응답 검증 + # Validate response if [ $? -ne 0 ]; then echo "ERROR: Failed to make request to project sync API" echo "curl exit code: $?" return 1 fi - # HTTP 상태 코드 확인 + # Check HTTP status code if [ "$http_code" != "200" ]; then echo "ERROR: Project sync failed with HTTP status $http_code" return 1 fi - # JSON 응답 검증 + # Validate JSON response if ! echo "$response_body" | jq . > /dev/null 2>&1; then echo "ERROR: Invalid JSON response from project sync API" echo "Raw response: $response_body" return 1 fi - # 성공 여부 확인 + # Check success if echo "$response_body" | jq -e '.error' > /dev/null 2>&1; then echo "ERROR: Project sync failed with error in response" echo "Error details:" @@ -197,7 +197,7 @@ sync_projects() { return 1 fi - # 성공 시 상세 정보 출력 + # Print details on success echo "✓ Project sync completed successfully" echo "Response details:" echo "$response_body" | jq . diff --git a/conf/docker/conf/mc-iam-manager/docker-post-init.sh b/conf/docker/conf/mc-iam-manager/docker-post-init.sh index 897f813..659fdfc 100644 --- a/conf/docker/conf/mc-iam-manager/docker-post-init.sh +++ b/conf/docker/conf/mc-iam-manager/docker-post-init.sh @@ -2,7 +2,7 @@ echo 'All required containers are healthy. Starting initialization...' -# 필요한 도구 설치 +# Install required tools apt-get update && apt-get install -y curl jq wget postgresql-client echo '' @@ -13,7 +13,7 @@ echo ' Health Check' echo '------------------------------------------------' -# # mc-iam-manager API가 완전히 준비될 때까지 대기 (간단한 버전) +# # Wait until mc-iam-manager API is fully ready (simple version) # echo 'Waiting for mc-iam-manager API to be ready...' # max_attempts=2 # attempt=1 @@ -21,7 +21,7 @@ echo '------------------------------------------------' # while [ $attempt -le $max_attempts ]; do # echo "Attempt $attempt/$max_attempts: Checking mc-iam-manager API..." -# # 간단한 API 헬스체크 (컨테이너 이름 사용) +# # Simple API health check (using container name) # if curl -s -f "http://mc-iam-manager:5000/readyz" > /dev/null 2>&1; then # echo '✓ mc-iam-manager API is ready!' # break @@ -43,7 +43,7 @@ echo '' echo '------------------------------------------------' echo ' Debug Info' echo '------------------------------------------------' -# 디버깅: 현재 디렉토리와 파일 목록 확인 +# Debug: check current directory and file list echo 'Current working directory:' pwd echo 'Files in current directory:' @@ -71,7 +71,7 @@ echo '------------------------------------------------' echo '1_setup_auto.sh' echo '------------------------------------------------' -# 초기화 스크립트 실행 +# Run initialization script if [ -f '1_setup_auto.sh' ]; then echo 'Found 1_setup_auto.sh, making it executable...' chmod +x 1_setup_auto.sh @@ -81,7 +81,7 @@ if [ -f '1_setup_auto.sh' ]; then # head -5 1_setup_auto.sh echo 'Executing 1_setup_auto.sh...' - # bash로 실행 (Ubuntu에는 bash가 기본적으로 포함됨) + # Run with bash (included by default on Ubuntu) if bash 1_setup_auto.sh; then echo 'Script executed successfully with bash 1_setup_auto.sh' else diff --git a/conf/docker/conf/mc-iam-manager/init-db.sh b/conf/docker/conf/mc-iam-manager/init-db.sh index 6504cce..c35e254 100755 --- a/conf/docker/conf/mc-iam-manager/init-db.sh +++ b/conf/docker/conf/mc-iam-manager/init-db.sh @@ -1,9 +1,9 @@ #!/bin/bash -# PostgreSQL 초기화 스크립트 +# PostgreSQL initialization script echo "Creating databases for MC IAM Manager and Keycloak..." -# 환경변수에서 값 가져오기 (기본값 설정) +# Read values from environment variables (with defaults) DB_USER=${MC_IAM_MANAGER_DATABASE_USER:-mciamdbadmin} DB_PASSWORD=${MC_IAM_MANAGER_DATABASE_PASSWORD:-mciamdbpassword} IAM_DB_NAME=${MC_IAM_MANAGER_DATABASE_NAME:-mc_iam_manager_db} @@ -16,7 +16,7 @@ echo " IAM_DB_NAME: $IAM_DB_NAME" echo " KEYCLOAK_DB_NAME: $KEYCLOAK_DB_NAME" echo " RECREATE_DB: $RECREATE_DB" -# 사용자 생성 (이미 존재하면 무시) +# Create user (skip if already exists) echo "Creating database user..." psql -U $DB_USER -d $IAM_DB_NAME -c "DO \$\$ BEGIN @@ -26,7 +26,7 @@ BEGIN END \$\$;" -# MC IAM Manager 데이터베이스 확인 및 생성 +# Check and create MC IAM Manager database echo "Checking MC IAM Manager database..." if [ "$RECREATE_DB" = "true" ] || ! psql -U $DB_USER -d $IAM_DB_NAME -lqt | cut -d \| -f 1 | grep -qw "$IAM_DB_NAME"; then echo "Creating MC IAM Manager database..." @@ -37,7 +37,7 @@ else echo "MC IAM Manager database already exists." fi -# Keycloak 데이터베이스 확인 및 생성 +# Check and create Keycloak database echo "Checking Keycloak database..." if [ "$RECREATE_DB" = "true" ] || ! psql -U $DB_USER -d $IAM_DB_NAME -lqt | cut -d \| -f 1 | grep -qw "$KEYCLOAK_DB_NAME"; then echo "Creating Keycloak database..." diff --git a/conf/docker/conf/mc-iam-manager/nginx.template.conf b/conf/docker/conf/mc-iam-manager/nginx.template.conf index 0be9c64..862fa80 100644 --- a/conf/docker/conf/mc-iam-manager/nginx.template.conf +++ b/conf/docker/conf/mc-iam-manager/nginx.template.conf @@ -23,7 +23,7 @@ http { gzip on; - # SSL 설정 + # SSL configuration ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384; ssl_prefer_server_ciphers off; @@ -34,14 +34,14 @@ http { listen 80; server_name ${MC_IAM_MANAGER_PUBLIC_DOMAIN}; - # Nginx 자체 health check (HTTP에서 접근 가능) + # Nginx internal health check (accessible over HTTP) location /nginx-health { access_log off; return 200 "nginx is healthy\n"; add_header Content-Type text/plain; } - # Health check endpoint (HTTP에서 접근 가능) + # Health check endpoint (accessible over HTTP) location /health { proxy_pass http://mc-iam-manager:${MC_IAM_MANAGER_PORT}/readyz; proxy_set_header Host $host; @@ -51,18 +51,18 @@ http { proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; - # Health check용 타임아웃 설정 + # Timeout settings for health check proxy_connect_timeout 10s; proxy_send_timeout 10s; proxy_read_timeout 10s; } - # ACME challenge location for Certbot (HTTP에서만 필요) + # ACME challenge location for Certbot (required over HTTP only) location /.well-known/acme-challenge/ { root /var/www/certbot; } - # HTTP to HTTPS 리다이렉트 (health check 제외) + # HTTP to HTTPS redirect (excluding health check) location / { return 301 https://$server_name$request_uri; } @@ -81,14 +81,14 @@ http { add_header X-Content-Type-Options nosniff always; add_header X-XSS-Protection "1; mode=block" always; - # Nginx 자체 health check + # Nginx internal health check location /nginx-health { access_log off; return 200 "nginx is healthy\n"; add_header Content-Type text/plain; } - # Health check endpoint (HTTPS에서도 접근 가능) + # Health check endpoint (accessible over HTTPS as well) location /health { proxy_pass http://mc-iam-manager:${MC_IAM_MANAGER_PORT}/readyz; proxy_set_header Host $host; @@ -98,7 +98,7 @@ http { proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; - # Health check용 타임아웃 설정 + # Timeout settings for health check proxy_connect_timeout 10s; proxy_send_timeout 10s; proxy_read_timeout 10s; @@ -113,7 +113,7 @@ http { proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; - # 타임아웃 설정 + # Timeout settings proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; @@ -128,11 +128,11 @@ http { proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; - # Keycloak Admin UI를 위한 헤더 설정 + # Header settings for Keycloak Admin UI proxy_hide_header X-Frame-Options; add_header X-Frame-Options "SAMEORIGIN" always; - # 타임아웃 설정 + # Timeout settings proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; @@ -165,7 +165,7 @@ http { } } - # mc-observability-grafana HTTPS proxy (iframe/외부 진입용) + # mc-observability-grafana HTTPS proxy (for iframe/external access) server { listen ${MC_OBSERVABILITY_GRAFANA_PROXY_PORT} ssl; server_name ${MC_IAM_MANAGER_PUBLIC_DOMAIN}; @@ -196,7 +196,7 @@ http { } } - # mc-cost-optimizer-be HTTPS proxy (IP 접속 시 Mixed Content 방지) + # mc-cost-optimizer-be HTTPS proxy (prevents Mixed Content on direct IP access) server { listen ${MC_COST_OPTIMIZER_BE_PORT} ssl; server_name ${MC_IAM_MANAGER_PUBLIC_DOMAIN}; @@ -222,7 +222,7 @@ http { } } - # mc-cost-optimizer-alarm HTTPS proxy (IP 접속 시 Mixed Content 방지) + # mc-cost-optimizer-alarm HTTPS proxy (prevents Mixed Content when accessing via IP) server { listen ${MC_COST_OPTIMIZER_ALARM_PORT} ssl; server_name ${MC_IAM_MANAGER_PUBLIC_DOMAIN}; @@ -248,7 +248,7 @@ http { } } - # mc-workflow-manager HTTPS proxy (iframe용) + # mc-workflow-manager HTTPS proxy (for iframe) server { listen ${MC_WORKFLOW_MANAGER_PROXY_PORT} ssl; server_name ${MC_IAM_MANAGER_PUBLIC_DOMAIN}; @@ -279,7 +279,7 @@ http { } } - # mc-data-manager HTTPS proxy (iframe용) + # mc-data-manager HTTPS proxy (for iframe) server { listen ${MC_DATA_MANAGER_PROXY_PORT} ssl; server_name ${MC_IAM_MANAGER_PUBLIC_DOMAIN}; @@ -310,7 +310,7 @@ http { } } - # mc-application-manager HTTPS proxy (iframe용) + # mc-application-manager HTTPS proxy (for iframe) server { listen ${MC_APPLICATION_MANAGER_PROXY_PORT} ssl; server_name ${MC_IAM_MANAGER_PUBLIC_DOMAIN}; @@ -341,7 +341,7 @@ http { } } - # mc-cost-optimizer-fe HTTPS proxy (iframe/외부 진입용) + # mc-cost-optimizer-fe HTTPS proxy (for iframe/external access) server { listen ${MC_COST_OPTIMIZER_FE_PROXY_PORT} ssl; server_name ${MC_IAM_MANAGER_PUBLIC_DOMAIN}; diff --git a/conf/docker/conf/mc-web-console/.env b/conf/docker/conf/mc-web-console/.env index 7947895..320e09b 100644 --- a/conf/docker/conf/mc-web-console/.env +++ b/conf/docker/conf/mc-web-console/.env @@ -1,14 +1,14 @@ # MC Web Console Environment Variables -# MC Web Console 환경 변수 설정 +# MC Web Console environment variable settings # Console Database Configuration -# 콘솔 데이터베이스 설정 -CONSOLE_POSTGRES_DB=mc_web_console_db -CONSOLE_POSTGRES_USER=mcwebconsole -CONSOLE_POSTGRES_PASSWORD=mcwebconsolepassword +# Console database configuration +MC_WEB_CONSOLE_POSTGRES_DB=mc_web_console_db +MC_WEB_CONSOLE_POSTGRES_USER=mcwebconsole +MC_WEB_CONSOLE_POSTGRES_PASSWORD=mcwebconsolepassword # Health Check Configuration -# 헬스 체크 설정 +# Health check configuration HEALTH_CHECK_INTERVAL=30s HEALTH_CHECK_TIMEOUT=10s HEALTH_CHECK_RETRIES=3 diff --git a/conf/docker/docker-compose.cert.yaml b/conf/docker/docker-compose.cert.yaml index d5d1028..28dc211 100644 --- a/conf/docker/docker-compose.cert.yaml +++ b/conf/docker/docker-compose.cert.yaml @@ -1,19 +1,19 @@ services: - # Certbot (인증서 발급 및 갱신용) - # 이 컨테이너는 필요할 때만 1회성으로 실행됩니다. + # Certbot (for certificate issuance and renewal) + # This container is run once on demand. mcmp-certbot: image: certbot/certbot:latest container_name: mcmp-certbot ports: - - "80:80" # Standalone 모드에서 80번 포트 사용 + - "80:80" # Port 80 is used in standalone mode volumes: - # Certbot 설정 및 발급된 인증서 저장 (읽기/쓰기 권한 필요) + # Stores Certbot config and issued certificates (read/write access required) - ./container-volume/mc-iam-manager/certs:/etc/letsencrypt environment: MC_IAM_MANAGER_PUBLIC_DOMAIN: ${MC_IAM_MANAGER_PUBLIC_DOMAIN} MC_IAM_MANAGER_CERT_EMAIL: ${MC_IAM_MANAGER_CERT_EMAIL} entrypoint: ["certbot"] - #command: ["certonly", "--standalone", "--email", "${MC_IAM_MANAGER_CERT_EMAIL}", "--agree-tos", "--no-eff-email", "-d", "${MC_IAM_MANAGER_PUBLIC_DOMAIN}", "--non-interactive", "--staging"] # <-- 테스트 발급 - command: ["certonly", "--standalone", "--email", "${MC_IAM_MANAGER_CERT_EMAIL}", "--agree-tos", "--no-eff-email", "-d", "${MC_IAM_MANAGER_PUBLIC_DOMAIN}", "--non-interactive"] # <-- 실제 발급 - #command: ["certonly", "--standalone", "--email", "${MC_IAM_MANAGER_CERT_EMAIL}", "--agree-tos", "--no-eff-email", "-d", "${MC_IAM_MANAGER_PUBLIC_DOMAIN}", "--non-interactive", "--force-renewal"] # <-- 강제 재발급 \ No newline at end of file + #command: ["certonly", "--standalone", "--email", "${MC_IAM_MANAGER_CERT_EMAIL}", "--agree-tos", "--no-eff-email", "-d", "${MC_IAM_MANAGER_PUBLIC_DOMAIN}", "--non-interactive", "--staging"] # <-- test issuance + command: ["certonly", "--standalone", "--email", "${MC_IAM_MANAGER_CERT_EMAIL}", "--agree-tos", "--no-eff-email", "-d", "${MC_IAM_MANAGER_PUBLIC_DOMAIN}", "--non-interactive"] # <-- actual issuance + #command: ["certonly", "--standalone", "--email", "${MC_IAM_MANAGER_CERT_EMAIL}", "--agree-tos", "--no-eff-email", "-d", "${MC_IAM_MANAGER_PUBLIC_DOMAIN}", "--non-interactive", "--force-renewal"] # <-- force renewal \ No newline at end of file diff --git a/src/cmd/apicall/parse.go b/src/cmd/apicall/parse.go index 585939f..5d039c2 100644 --- a/src/cmd/apicall/parse.go +++ b/src/cmd/apicall/parse.go @@ -31,7 +31,7 @@ func parseJson() { // swagger.json 파일 읽기 data, err := os.ReadFile(swaggerFile) if err != nil { - log.Fatalf("파일 읽기 오류: %s", err) + log.Fatalf("File read error: %s", err) } json := string(data) From 691b3770f4d750d14c8b22705a0c5b7cf62af5a9 Mon Sep 17 00:00:00 2001 From: dogfootman Date: Thu, 21 May 2026 23:56:45 +0000 Subject: [PATCH 8/9] fix(install): sync missing .env vars from .env.setup on each run Add sync_missing_env_vars() to installAll.sh so that variables present in .env.setup but absent from an existing .env are appended automatically. This prevents docker compose failures (no port specified: :) when MC_WORKFLOW_MANAGER_PROXY_PORT, MC_DATA_MANAGER_PROXY_PORT, or MC_APPLICATION_MANAGER_PROXY_PORT are missing from a stale .env file. - Append-only: never overwrites existing user-set values - Idempotent: safe to run multiple times - Applies to both conf/docker/.env and conf/mc-iam-manager/.env --- bin/installAll.sh | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/bin/installAll.sh b/bin/installAll.sh index 0eb4df6..db7a2f8 100755 --- a/bin/installAll.sh +++ b/bin/installAll.sh @@ -200,9 +200,43 @@ ensure_env_file() { fi } +sync_missing_env_vars() { + local setup_file="$1" + local env_file="$2" + + if [ ! -f "$setup_file" ] || [ ! -f "$env_file" ]; then + return 0 + fi + + local tmpfile + tmpfile=$(mktemp) + + while IFS= read -r line; do + _key="${line%%=*}" + if ! grep -qE "^${_key}=" "$env_file"; then + printf '%s\n' "$line" >> "$tmpfile" + fi + done < <(grep -E '^[A-Z_][A-Z0-9_]*=' "$setup_file") + + if [ -s "$tmpfile" ]; then + local rel="${env_file##*/conf/docker/}" + { + printf '\n' + printf '# === Synced from %s by installAll.sh on %s ===\n' \ + "$(basename "$setup_file")" "$(date -Iseconds)" + cat "$tmpfile" + } >> "$env_file" + echo "✓ Synced $(wc -l < "$tmpfile") missing var(s) into ${rel}" + fi + rm -f "$tmpfile" +} + ensure_env_file "$PROJECT_ROOT_ABS/.env.setup" "$PROJECT_ROOT_ABS/.env" ensure_env_file "$PROJECT_ROOT_ABS/conf/mc-iam-manager/.env.setup" "$PROJECT_ROOT_ABS/conf/mc-iam-manager/.env" +sync_missing_env_vars "$PROJECT_ROOT_ABS/.env.setup" "$PROJECT_ROOT_ABS/.env" +sync_missing_env_vars "$PROJECT_ROOT_ABS/conf/mc-iam-manager/.env.setup" "$PROJECT_ROOT_ABS/conf/mc-iam-manager/.env" + # ============================================================================= # Domain Configuration # ============================================================================= From 4de3894b2df3d04e361688c60eb7303128d9b4ec Mon Sep 17 00:00:00 2001 From: dogfootman Date: Fri, 22 May 2026 01:43:42 +0000 Subject: [PATCH 9/9] fix(setup): align api.yaml env var name with .env convention MCADMINCLI_APIYAML -> MC_ADMIN_CLI_APIYAML in 1_setup_auto.sh and 1_setup_manual.sh to match the variable name defined in .env. --- conf/docker/conf/mc-iam-manager/1_setup_auto.sh | 8 ++++---- conf/docker/conf/mc-iam-manager/1_setup_manual.sh | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/conf/docker/conf/mc-iam-manager/1_setup_auto.sh b/conf/docker/conf/mc-iam-manager/1_setup_auto.sh index a8379d6..17972eb 100755 --- a/conf/docker/conf/mc-iam-manager/1_setup_auto.sh +++ b/conf/docker/conf/mc-iam-manager/1_setup_auto.sh @@ -313,12 +313,12 @@ init_menu() { init_api_resources() { echo "Initializing API resources..." - if [ -n "$MCADMINCLI_APIYAML" ]; then - wget -q -O ./api.yaml "$MCADMINCLI_APIYAML" && echo " Downloaded api.yaml from $MCADMINCLI_APIYAML" || { - echo " WARNING: Failed to download api.yaml from $MCADMINCLI_APIYAML — using local copy" + if [ -n "$MC_ADMIN_CLI_APIYAML" ]; then + wget -q -O ./api.yaml "$MC_ADMIN_CLI_APIYAML" && echo " Downloaded api.yaml from $MC_ADMIN_CLI_APIYAML" || { + echo " WARNING: Failed to download api.yaml from $MC_ADMIN_CLI_APIYAML — using local copy" } else - echo " MCADMINCLI_APIYAML not set — using local api.yaml" + echo " MC_ADMIN_CLI_APIYAML not set — using local api.yaml" fi if [ ! -f ./api.yaml ]; then echo "ERROR: api.yaml not found" diff --git a/conf/docker/conf/mc-iam-manager/1_setup_manual.sh b/conf/docker/conf/mc-iam-manager/1_setup_manual.sh index 528f022..41b4a71 100755 --- a/conf/docker/conf/mc-iam-manager/1_setup_manual.sh +++ b/conf/docker/conf/mc-iam-manager/1_setup_manual.sh @@ -94,7 +94,7 @@ init_menu() { init_api_resources() { echo "Initializing API resources..." - wget -q -O ./api.yaml "$MCADMINCLI_APIYAML" + wget -q -O ./api.yaml "$MC_ADMIN_CLI_APIYAML" response=$(curl -s -X POST \ --header "Authorization: Bearer $MC_IAM_MANAGER_PLATFORMADMIN_ACCESSTOKEN" \ --header 'Content-Type: application/json' \