Files
portfolio/services/nextjs/app/api/argocd/route.ts
Mayne0213 822afb3215 CHORE(app): add ArgoCD SSL configuration
- Enable SSL for ArgoCD API
- Configure TLS settings
2025-11-25 12:30:24 +09:00

135 lines
3.6 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
// 클러스터 내부에서 실행되는 경우 클러스터 내부 서비스 URL 사용
// 외부에서 실행되는 경우 환경 변수로 설정 가능
const ARGOCD_SERVER_URL = process.env.ARGOCD_SERVER_URL || 'https://argocd-server.argocd.svc.cluster.local';
const ARGOCD_TOKEN = process.env.ARGOCD_TOKEN || '';
const ARGOCD_CA_CERT = process.env.ARGOCD_CA_CERT || '';
// Node.js 환경에서 커스텀 fetch 함수 생성 (인증서 지원)
async function fetchWithCert(url: string, options: RequestInit = {}): Promise<Response> {
// 브라우저 환경에서는 기본 fetch 사용
if (typeof window !== 'undefined') {
return fetch(url, options);
}
// Node.js 환경에서 인증서가 있으면 커스텀 agent 사용
if (ARGOCD_CA_CERT) {
const https = require('https');
const { Agent } = https;
const agent = new Agent({
ca: ARGOCD_CA_CERT,
rejectUnauthorized: true,
});
// Node.js의 fetch에 agent 전달
const nodeOptions: any = {
...options,
agent,
};
return fetch(url, nodeOptions);
}
return fetch(url, options);
}
interface ArgoCDApplication {
metadata: {
name: string;
namespace: string;
};
spec: {
source: {
repoURL: string;
path?: string;
targetRevision: string;
};
destination: {
server: string;
namespace: string;
};
};
status: {
health: {
status: string;
};
sync: {
status: string;
};
resources?: Array<{
kind: string;
name: string;
namespace: string;
status: string;
health?: {
status: string;
};
}>;
};
}
// GET /api/argocd - Get all ArgoCD applications
export async function GET(request: NextRequest) {
try {
if (!ARGOCD_TOKEN) {
return NextResponse.json(
{ error: 'ArgoCD token not configured' },
{ status: 500 }
);
}
// ArgoCD API v1 - Get applications
const response = await fetchWithCert(`${ARGOCD_SERVER_URL}/api/v1/applications`, {
headers: {
'Authorization': `Bearer ${ARGOCD_TOKEN}`,
'Content-Type': 'application/json',
},
cache: 'no-store',
});
if (!response.ok) {
const errorText = await response.text();
console.error('ArgoCD API error:', response.status, errorText);
return NextResponse.json(
{ error: `ArgoCD API error: ${response.status}` },
{ status: response.status }
);
}
const data = await response.json();
// Read-only로 필터링 (필요한 정보만 반환)
const applications = (data.items || []).map((app: ArgoCDApplication) => ({
name: app.metadata.name,
namespace: app.metadata.namespace,
repoURL: app.spec.source.repoURL,
path: app.spec.source.path || '',
targetRevision: app.spec.source.targetRevision,
destination: app.spec.destination,
health: app.status.health?.status || 'Unknown',
sync: app.status.sync?.status || 'Unknown',
resources: app.status.resources?.map((resource) => ({
kind: resource.kind,
name: resource.name,
namespace: resource.namespace,
status: resource.status,
health: resource.health?.status || 'Unknown',
})) || [],
}));
return NextResponse.json({
applications,
timestamp: new Date().toISOString(),
});
} catch (error) {
console.error('Error fetching ArgoCD applications:', error);
return NextResponse.json(
{ error: 'Failed to fetch ArgoCD applications' },
{ status: 500 }
);
}
}