diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml deleted file mode 100644 index 7378c8b..0000000 --- a/.gitea/workflows/build.yml +++ /dev/null @@ -1,190 +0,0 @@ -name: Build Docker Image - -on: - push: - branches: [main] - tags: - - 'v*' - workflow_dispatch: - -env: - REGISTRY: gitea0213.kro.kr - IMAGE_NAME: ${{ github.repository }} - DOCKER_HOST: tcp://172.17.0.1:2375 - -jobs: - build-and-push: - runs-on: ubuntu-24.04-arm - permissions: - contents: write - packages: write - - outputs: - image-tag: ${{ steps.meta.outputs.tags }} - image-digest: ${{ steps.build.outputs.digest }} - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Log in to Gitea Container Registry - run: | - echo "${{ secrets.GITEAREGISTRY }}" | docker login ${{ env.REGISTRY }} --username bluemayne --password-stdin - - - name: Lowercase repository name - id: lowercase - run: | - echo "repo=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT - - - name: Extract metadata (tags, labels) - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ steps.lowercase.outputs.repo }} - tags: | - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=sha,prefix={{branch}}-sha-,format=long - type=raw,value=latest,enable={{is_default_branch}} - - - name: Build and push Docker image - id: build - run: | - TAGS="${{ steps.meta.outputs.tags }}" - - # Build the image - docker build \ - -t $(echo "$TAGS" | head -n 1) \ - -f ./deploy/docker/Dockerfile \ - ./services/backend - - # Tag all versions - FIRST_TAG=$(echo "$TAGS" | head -n 1) - echo "$TAGS" | while read tag; do - if [ "$tag" != "$FIRST_TAG" ]; then - docker tag "$FIRST_TAG" "$tag" - fi - done - - # Push all tags - echo "$TAGS" | while read tag; do - docker push "$tag" - done - - # Get digest - DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$FIRST_TAG" | cut -d'@' -f2) - echo "digest=$DIGEST" >> $GITHUB_OUTPUT - - - name: Extract SHA tag - id: extract-tag - run: | - # Extract the SHA-based tag from the tags list - TAGS="${{ steps.meta.outputs.tags }}" - echo "All tags:" - echo "$TAGS" - echo "---" - - # Get commit SHA (full 40 characters) - COMMIT_SHA="${{ github.sha }}" - - # Get current branch name - BRANCH_NAME="${{ github.ref_name }}" - echo "Branch: $BRANCH_NAME" - - # Method 1: Extract the full SHA tag from docker/metadata-action output - # docker/metadata-action creates: -sha- - SHA_TAG=$(echo "$TAGS" | grep -oE "${BRANCH_NAME}-sha-[a-f0-9]{40}" | head -n 1) - - # Method 2: If not found, try to extract any branch-sha- tag (fallback) - if [ -z "$SHA_TAG" ]; then - SHA_TAG=$(echo "$TAGS" | grep -oE "${BRANCH_NAME}-sha-[a-f0-9]+" | head -n 1) - if [ -n "$SHA_TAG" ]; then - echo "⚠️ Found SHA tag (may not be full 40 chars): $SHA_TAG" - fi - fi - - # Method 3: Fallback to commit SHA directly (construct the tag) - if [ -z "$SHA_TAG" ]; then - SHA_TAG="${BRANCH_NAME}-sha-$COMMIT_SHA" - echo "⚠️ Could not extract from tags, using commit SHA: $SHA_TAG" - fi - - if [ -z "$SHA_TAG" ]; then - echo "❌ ERROR: Failed to extract SHA tag" - exit 1 - fi - - echo "sha-tag=$SHA_TAG" >> $GITHUB_OUTPUT - echo "✅ Extracted SHA tag: $SHA_TAG" - - - name: Update kustomization with new image tag - env: - GITEA_TOKEN: ${{ secrets.GITEAREGISTRYTOKEN }} - run: | - git config --global user.name "gitea-actions[bot]" - git config --global user.email "gitea-actions[bot]@users.noreply.gitea.com" - - # Validate that SHA_TAG is not empty - SHA_TAG="${{ steps.extract-tag.outputs.sha-tag }}" - if [ -z "$SHA_TAG" ]; then - echo "❌ ERROR: SHA_TAG is empty, cannot update kustomization" - exit 1 - fi - - # For mas, we only have prod overlay (main branch) - BRANCH_NAME="${{ github.ref_name }}" - if [ "$BRANCH_NAME" = "main" ]; then - OVERLAY="prod" - else - echo "⚠️ Unknown branch: $BRANCH_NAME, skipping kustomization update" - exit 0 - fi - - KUSTOMIZATION_FILE="deploy/k8s/overlays/$OVERLAY/kustomization.yaml" - - # Check if kustomization file has images section - if grep -q "images:" "$KUSTOMIZATION_FILE"; then - echo "📝 Updating $KUSTOMIZATION_FILE with tag: $SHA_TAG" - - # Update kustomization.yaml with new image tag - # Handle both cases: newTag: (with value) and newTag: (empty) - sed -i.bak "s|newTag:.*|newTag: $SHA_TAG|" "$KUSTOMIZATION_FILE" - - # Verify the update was successful - if grep -q "newTag: $SHA_TAG" "$KUSTOMIZATION_FILE"; then - echo "✅ Successfully updated kustomization.yaml" - rm -f "$KUSTOMIZATION_FILE.bak" - else - echo "❌ ERROR: Failed to update kustomization.yaml" - cat "$KUSTOMIZATION_FILE" - exit 1 - fi - - # Commit and push if there are changes - if git diff --quiet; then - echo "No changes to commit" - else - git add "$KUSTOMIZATION_FILE" - git commit -m "Update $OVERLAY image to $SHA_TAG" - git push - echo "✅ Kustomization updated with new image tag: $SHA_TAG" - fi - else - echo "ℹ️ $OVERLAY overlay uses base image (latest tag), skipping kustomization update" - echo " Image built with tag: $SHA_TAG" - fi - - - name: Display image information - run: | - echo "✅ Image built and pushed successfully!" - echo "📦 Image tags:" - echo "${{ steps.meta.outputs.tags }}" - echo "🔖 SHA tag: ${{ steps.extract-tag.outputs.sha-tag }}" - echo "🔖 Digest: ${{ steps.build.outputs.digest }}" - echo "" - echo "🚀 Kustomization updated with new image tag" - echo " ArgoCD will automatically detect and deploy this new image" - echo " Monitor deployment at your ArgoCD dashboard" - diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c009f4c..923f513 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,13 +15,9 @@ jobs: build-and-push: runs-on: ubuntu-24.04-arm permissions: - contents: write + contents: read packages: write - outputs: - image-tag: ${{ steps.meta.outputs.tags }} - image-digest: ${{ steps.build.outputs.digest }} - steps: - name: Checkout code uses: actions/checkout@v4 @@ -48,96 +44,24 @@ jobs: images: ${{ env.REGISTRY }}/${{ steps.lowercase.outputs.repo }} tags: | type=ref,event=branch - type=ref,event=pr type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=sha,prefix={{branch}}-sha-,format=long type=raw,value=latest,enable={{is_default_branch}} - name: Build and push Docker image id: build uses: docker/build-push-action@v5 with: - context: ./services/backend - file: ./deploy/docker/Dockerfile + context: ./langgraph + file: ./Dockerfile push: true + platforms: linux/arm64 tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} - platforms: linux/arm64 cache-from: type=gha cache-to: type=gha,mode=max - - name: Extract SHA tag - id: extract-tag - run: | - TAGS="${{ steps.meta.outputs.tags }}" - echo "All tags:" - echo "$TAGS" - echo "---" - - COMMIT_SHA="${{ github.sha }}" - BRANCH_NAME="${{ github.ref_name }}" - echo "Branch: $BRANCH_NAME" - - SHA_TAG=$(echo "$TAGS" | grep -oE "${BRANCH_NAME}-sha-[a-f0-9]{40}" | head -n 1) - - if [ -z "$SHA_TAG" ]; then - SHA_TAG=$(echo "$TAGS" | grep -oE "${BRANCH_NAME}-sha-[a-f0-9]+" | head -n 1) - fi - - if [ -z "$SHA_TAG" ]; then - SHA_TAG="${BRANCH_NAME}-sha-$COMMIT_SHA" - fi - - if [ -z "$SHA_TAG" ]; then - echo "ERROR: Failed to extract SHA tag" - exit 1 - fi - - echo "sha-tag=$SHA_TAG" >> $GITHUB_OUTPUT - echo "Extracted SHA tag: $SHA_TAG" - - - name: Update kustomization with new image tag - run: | - git config --global user.name "github-actions[bot]" - git config --global user.email "github-actions[bot]@users.noreply.github.com" - - SHA_TAG="${{ steps.extract-tag.outputs.sha-tag }}" - if [ -z "$SHA_TAG" ]; then - echo "ERROR: SHA_TAG is empty" - exit 1 - fi - - BRANCH_NAME="${{ github.ref_name }}" - if [ "$BRANCH_NAME" = "main" ]; then - OVERLAY="prod" - else - echo "Unknown branch: $BRANCH_NAME, skipping" - exit 0 - fi - - KUSTOMIZATION_FILE="deploy/k8s/overlays/$OVERLAY/kustomization.yaml" - - if grep -q "images:" "$KUSTOMIZATION_FILE"; then - echo "Updating $KUSTOMIZATION_FILE with tag: $SHA_TAG" - sed -i "s|newTag:.*|newTag: $SHA_TAG|" "$KUSTOMIZATION_FILE" - - if git diff --quiet; then - echo "No changes to commit" - else - git add "$KUSTOMIZATION_FILE" - git commit -m "Update $OVERLAY image to $SHA_TAG" - git push - echo "Kustomization updated with new image tag: $SHA_TAG" - fi - else - echo "$OVERLAY overlay uses base image, skipping kustomization update" - fi - - name: Display image information run: | echo "Image built and pushed successfully!" echo "Image tags:" echo "${{ steps.meta.outputs.tags }}" - echo "SHA tag: ${{ steps.extract-tag.outputs.sha-tag }}" - echo "Digest: ${{ steps.build.outputs.digest }}" diff --git a/deploy/docker/Dockerfile b/Dockerfile similarity index 100% rename from deploy/docker/Dockerfile rename to Dockerfile diff --git a/README.md b/README.md deleted file mode 100644 index 0ae85e9..0000000 --- a/README.md +++ /dev/null @@ -1,337 +0,0 @@ -# MAS (Multi-Agent System) - -**K8s 인프라 분석 & 의사결정 시스템** - 클러스터를 분석하고 도구 도입 여부를 결정해주는 AI 시스템 - -## 🎯 What is this? - -MAS는 Kubernetes 클러스터 상태를 분석하고, **도구 도입 추천/비추천을 결정**해주는 AI 에이전트 시스템입니다. - -**사용 시나리오:** -1. "Tekton 도입 여부를 결정해줘" → 클러스터 분석 → **도입 추천/비추천 결정** -2. 한국어로 이유, 대안, 구현 가이드 제공 -3. 기술적 세부사항 없이 **명확한 결론** 제시 - -## 🤖 Agents - -### Planning Agent (Claude 4.5) -- 도구 요구사항 분석 -- 필요한 K8s 리소스 파악 -- 확인이 필요한 클러스터 정보 정의 - -### Research Agent (Groq Llama 3.3) -- kubectl 명령어로 클러스터 상태 분석 -- 기존 도구 확인 (ArgoCD, Gitea, Prometheus 등) -- 리소스 사용률 및 버전 확인 - -### Decision Agent (Claude 4.5) -- **도입 추천/비추천 결정** (한국어) -- 명확한 이유 제시 -- 대안 제시 (비추천인 경우) -- 간단한 구현 가이드 (추천인 경우) - -### Tech stack -- **Backend**: LangGraph + LangChain + FastAPI -- **UI**: Chainlit (chat-style UI) -- **Database**: PostgreSQL (CNPG) -- **Cache**: Redis -- **LLMs**: Claude API (Orchestrator, Planning, Prompt Gen) + Groq Llama 3.3 (Research) -- **Deploy**: Kubernetes + ArgoCD - ---- - -## 🚀 Local development - -### 1. Run with Docker Compose - -```bash -cd deploy/docker - -# Copy or create .env and fill in your API keys -# (ANTHROPIC_API_KEY, GROQ_API_KEY, etc.) - -# Start the full stack -docker compose up -d - -# Tail logs -docker compose logs -f mas -``` - -Open: `http://localhost:8000` - -### 2. Run backend directly (Python) - -```bash -cd services/backend - -# Create venv -python -m venv venv -source venv/bin/activate # Windows: venv\Scripts\activate - -# Install dependencies -pip install -r requirements.txt - -# Environment variables -cp .env.example .env -# Edit .env and set your API keys - -# Run Chainlit app -chainlit run chainlit_app.py -``` - ---- - -## ☸️ Kubernetes deployment - -### 1. Create namespace and secrets - -```bash -kubectl create namespace mas - -kubectl create secret generic mas-api-keys \ - --from-literal=anthropic-api-key=YOUR_CLAUDE_KEY \ - --from-literal=openai-api-key=YOUR_OPENAI_KEY \ - --from-literal=google-api-key=YOUR_GEMINI_KEY \ - -n mas -``` - -### 2. Deploy via ArgoCD - -```bash -# Create ArgoCD Application -kubectl apply -f deploy/argocd/mas.yaml - -# Sync and check status -argocd app sync mas -argocd app get mas -``` - -### 3. Deploy from your server (example) - -```bash -# SSH into your k3s master -ssh oracle-master - -# Apply ArgoCD Application -sudo kubectl apply -f /path/to/deploy/argocd/mas.yaml - -# Check status -sudo kubectl get pods -n mas -sudo kubectl logs -f deployment/mas -n mas -``` - -Ingress example (if configured): `https://mas.mayne.vcn` - ---- - -## 🎨 UI customization - -### Chainlit theme & behavior - -You can customize the UI via `services/backend/.chainlit`: - -```toml -[UI] -name = "MAS" -show_readme_as_default = true -default_collapse_content = true -``` - -### Agent prompts - -System prompts for each agent live in `services/backend/agents.py`. -You can tune: -- how the **Orchestrator** routes tasks -- coding style of backend/frontend agents -- SRE troubleshooting behavior - ---- - -## 📊 Observability - -### Prometheus ServiceMonitor (example) - -```yaml -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: mas - namespace: mas -spec: - selector: - matchLabels: - app: mas - endpoints: - - port: http - path: /metrics -``` - -### Grafana dashboards - -Recommended panels: -- LangGraph workflow metrics -- Per-agent latency & error rate -- Token usage and cost estimates -- Backend API latency & 5xx rate - ---- - -## 🔧 Advanced features - -### 1. MCP (Model Context Protocol) with Claude - -Using Claude Code as Orchestrator, MAS can access: -- Filesystem (read/write project files) -- Git (status, commit, push, PR) -- SSH (run remote commands on your servers) -- PostgreSQL (schema inspection, migrations, queries) -- Kubernetes (kubectl via MCP tool) - -This allows fully automated workflows like: -- “Create a new service, add deployment manifests, and deploy to k3s.” -- “Debug failing pods and propose a fix, then open a PR.” - -### 2. Multi-agent collaboration (LangGraph) - -Typical workflow: - -```text -User request - ↓ -Claude Orchestrator - ↓ decides which agent(s) to call -Backend Dev → Frontend Dev → SRE - ↓ -Claude Orchestrator (review & summary) - ↓ -Final answer to user -``` - -Examples: -- Full‑stack feature (API + UI + monitoring) -- Infra rollout (Harbor, Tekton, CNPG, MetalLB) with validation - ---- - -## 📝 Usage examples - -### Example 1: Tekton 도입 여부 결정 - -```text -User: "Tekton 도입 여부를 결정해줘" - -🎼 Orchestrator → 조율 - -📋 Planning Agent: - → Tekton 요구사항: Namespace, CRDs, Controllers - → 필요 리소스: 2 CPU, 4GB RAM - → 확인 필요: 기존 CI/CD 도구, K8s 버전 - -🔍 Research Agent: - → kubectl get nodes: v1.33.6, 3 nodes ✓ - → kubectl get pods -A: ArgoCD 운영 중 발견 - → Gitea Actions 사용 가능 확인 - -💡 Decision Agent: - ❌ Tekton 도입 비추천 - - 이유: - - ArgoCD + Gitea Actions로 충분 - - 추가 리소스 소비 불필요 - - 학습 곡선 및 유지보수 부담 - - 대안: - - Gitea Actions 활용 (이미 설치됨) - - ArgoCD로 배포 자동화 유지 - -✨ Output: 명확한 한국어 보고서 -``` - -### Example 2: Harbor 필요성 분석 - -```text -User: "Harbor가 필요한지 분석해줘" - -→ Planning: Harbor 요구사항 분석 -→ Research: 기존 registry 확인 (Gitea Container Registry 발견) -→ Decision: - ❌ Harbor 도입 비추천 - 이유: Gitea Container Registry로 충분 - -✨ 사용자 친화적 한국어 결론 -``` - -### Example 3: Prometheus 설치 여부 - -```text -User: "Prometheus를 설치해야 할까?" - -→ Planning: Monitoring stack 요구사항 -→ Research: 이미 Prometheus 운영 중 발견! -→ Decision: - ✅ 이미 설치되어 있음 - 현재 상태: monitoring namespace에서 정상 작동 중 - -✨ 중복 설치 방지 -``` - ---- - -## 🔧 Workflow - -``` -User Input: "X 도입 여부를 결정해줘" - ↓ -Orchestrator (조율) - ↓ -Planning Agent (도구 요구사항 분석) - ↓ -Research Agent (클러스터 상태 분석) - ↓ -Decision Agent (한국어 의사결정 보고서) - ↓ -Output: ✅ 추천 또는 ❌ 비추천 (이유 포함) -``` - -## 📊 출력 예시 - -```markdown -# Tekton 도입 분석 결과 - -## 📊 현재 클러스터 상태 -- Kubernetes 버전: v1.33.6 -- 노드: 3개 (1 control-plane, 2 workers) -- 기존 CI/CD: ArgoCD, Gitea Actions -- 운영 애플리케이션: 15개 - -## 💡 권장사항: Tekton 도입 비추천 - -### ❌ 비추천 이유 -1. ArgoCD + Gitea Actions 조합으로 충분 -2. 추가 리소스 소비 (2 CPU, 4GB RAM) -3. 학습 곡선 및 운영 부담 증가 - -### 🔄 권장 대안 -- Gitea Actions로 빌드 파이프라인 구성 -- ArgoCD로 GitOps 배포 유지 -- 필요시 GitHub Actions 연동 - -## 🎯 결론 -현재 인프라로 충분하며, Tekton 도입은 불필요합니다. -``` - -## 🤝 Contributing - -Contributions are welcome: -- Improve Planning Agent prompts for better folder structures -- Enhance Research Agent kubectl commands -- Add more infrastructure tools (Harbor, Tekton, CNPG, MetalLB, etc.) -- Better Markdown template for Prompt Generator - -Feel free to open issues or PRs in your Git repository. - ---- - -## 📄 License - -MIT - diff --git a/deploy/argocd/application-prod.yaml b/deploy/argocd/application-prod.yaml deleted file mode 100644 index ec67961..0000000 --- a/deploy/argocd/application-prod.yaml +++ /dev/null @@ -1,31 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: mas-prod - namespace: argocd - finalizers: - - resources-finalizer.argocd.argoproj.io -spec: - project: default - source: - repoURL: https://github.com/Mayne0213/mas.git - targetRevision: main - path: deploy/k8s/overlays/prod - destination: - server: https://kubernetes.default.svc - namespace: mas - syncPolicy: - automated: - prune: true - selfHeal: true - allowEmpty: false - syncOptions: - - CreateNamespace=true - retry: - limit: 5 - backoff: - duration: 5s - factor: 2 - maxDuration: 3m - revisionHistoryLimit: 10 - diff --git a/deploy/argocd/application.yaml b/deploy/argocd/application.yaml deleted file mode 100644 index ca39d28..0000000 --- a/deploy/argocd/application.yaml +++ /dev/null @@ -1,37 +0,0 @@ -apiVersion: argoproj.io/v1alpha1 -kind: Application -metadata: - name: mas - namespace: argocd - finalizers: - - resources-finalizer.argocd.argoproj.io -spec: - project: default - - source: - repoURL: https://github.com/Mayne0213/mas.git - targetRevision: main - path: deploy/argocd - - destination: - server: https://kubernetes.default.svc - namespace: argocd - - syncPolicy: - automated: - prune: true - selfHeal: true - allowEmpty: false - - syncOptions: - - CreateNamespace=true - - retry: - limit: 5 - backoff: - duration: 5s - factor: 2 - maxDuration: 3m - - revisionHistoryLimit: 10 - diff --git a/deploy/argocd/kustomization.yaml b/deploy/argocd/kustomization.yaml deleted file mode 100644 index 12d7dfc..0000000 --- a/deploy/argocd/kustomization.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -resources: - # App of Apps Application (self-managing) - - application.yaml - - # Application deployments - - application-prod.yaml - diff --git a/deploy/k8s/base/deployment.yaml b/deploy/k8s/base/deployment.yaml deleted file mode 100644 index 6b7f465..0000000 --- a/deploy/k8s/base/deployment.yaml +++ /dev/null @@ -1,66 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: mas - namespace: mas - labels: - app: mas -spec: - replicas: 1 - selector: - matchLabels: - app: mas - template: - metadata: - labels: - app: mas - spec: - hostPID: true # 호스트 프로세스 네임스페이스 접근 - serviceAccountName: mas - containers: - - name: mas - image: ghcr.io/mayne0213/mas:latest - imagePullPolicy: Always - securityContext: - privileged: true # nsenter 사용을 위한 권한 - ports: - - containerPort: 8000 - name: http - env: - - name: ANTHROPIC_API_KEY - valueFrom: - secretKeyRef: - name: mas-api-keys - key: anthropic-api-key - # Chainlit uses asyncpg directly (not SQLAlchemy) - - name: CHAINLIT_DATABASE_URL - value: "postgresql://bluemayne:$(POSTGRES_PASSWORD)@postgresql-rw.postgresql.svc.cluster.local:5432/mas" - # SQLAlchemy format (if needed) - - name: DATABASE_URL - value: "postgresql://bluemayne:$(POSTGRES_PASSWORD)@postgresql-rw.postgresql.svc.cluster.local:5432/mas" - - name: POSTGRES_HOST - value: "postgresql-rw.postgresql.svc.cluster.local" - - name: POSTGRES_PORT - value: "5432" - - name: POSTGRES_USER - value: "bluemayne" - - name: POSTGRES_PASSWORD - valueFrom: - secretKeyRef: - name: postgresql-password - key: password - - name: GITEA_TOKEN - valueFrom: - secretKeyRef: - name: mas-api-keys - key: gitea-token - optional: true - - name: REDIS_URL - value: "redis://redis:6379/0" - resources: - requests: - memory: "256Mi" - cpu: "100m" - limits: - memory: "1Gi" - diff --git a/deploy/k8s/base/kustomization.yaml b/deploy/k8s/base/kustomization.yaml deleted file mode 100644 index d982379..0000000 --- a/deploy/k8s/base/kustomization.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -resources: - - deployment.yaml - - service.yaml - - serviceaccount.yaml - -commonLabels: - app.kubernetes.io/name: mas - app.kubernetes.io/component: platform - -images: - - name: github.com/Mayne0213/mas - newTag: latest - diff --git a/deploy/k8s/base/service.yaml b/deploy/k8s/base/service.yaml deleted file mode 100644 index 2dc580c..0000000 --- a/deploy/k8s/base/service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: mas - namespace: mas - labels: - app: mas -spec: - type: ClusterIP - ports: - - port: 8000 - targetPort: 8000 - protocol: TCP - name: http - selector: - app: mas - diff --git a/deploy/k8s/base/serviceaccount.yaml b/deploy/k8s/base/serviceaccount.yaml deleted file mode 100644 index bbe65dc..0000000 --- a/deploy/k8s/base/serviceaccount.yaml +++ /dev/null @@ -1,50 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: mas - namespace: mas ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: mas-viewer -rules: - - apiGroups: ["", "apps", "batch", "networking.k8s.io"] - resources: ["*"] - verbs: ["get", "list", "watch"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: mas-writer -rules: - - apiGroups: ["", "apps", "batch", "networking.k8s.io"] - resources: ["*"] - verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: mas-viewer-binding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: mas-viewer -subjects: - - kind: ServiceAccount - name: mas - namespace: mas ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: mas-writer-binding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: mas-writer -subjects: - - kind: ServiceAccount - name: mas - namespace: mas - diff --git a/deploy/k8s/overlays/prod/externalsecret.yaml b/deploy/k8s/overlays/prod/externalsecret.yaml deleted file mode 100644 index ea31b97..0000000 --- a/deploy/k8s/overlays/prod/externalsecret.yaml +++ /dev/null @@ -1,58 +0,0 @@ -apiVersion: external-secrets.io/v1 -kind: ExternalSecret -metadata: - name: mas-api-keys -spec: - refreshInterval: 1h - secretStoreRef: - kind: ClusterSecretStore - name: vault-backend - target: - name: mas-api-keys - creationPolicy: Owner - data: - - secretKey: anthropic-api-key - remoteRef: - key: mas/api-keys - property: ANTHROPIC_API_KEY ---- -apiVersion: external-secrets.io/v1 -kind: ExternalSecret -metadata: - name: postgresql-password -spec: - refreshInterval: 1h - secretStoreRef: - kind: ClusterSecretStore - name: vault-backend - target: - name: postgresql-password - creationPolicy: Owner - data: - - secretKey: password - remoteRef: - key: databases/postgresql - property: PASSWORD - - secretKey: postgres-password - remoteRef: - key: databases/postgresql - property: POSTGRES_PASSWORD ---- -apiVersion: external-secrets.io/v1 -kind: ExternalSecret -metadata: - name: postgresql-root-password -spec: - refreshInterval: 1h - secretStoreRef: - kind: ClusterSecretStore - name: vault-backend - target: - name: postgresql-root-password - creationPolicy: Owner - data: - - secretKey: password - remoteRef: - key: databases/postgresql - property: POSTGRES_PASSWORD - diff --git a/deploy/k8s/overlays/prod/ingress.yaml b/deploy/k8s/overlays/prod/ingress.yaml deleted file mode 100644 index 5fdae5e..0000000 --- a/deploy/k8s/overlays/prod/ingress.yaml +++ /dev/null @@ -1,35 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: mas-ingress - annotations: - cert-manager.io/cluster-issuer: "letsencrypt-prod" - traefik.ingress.kubernetes.io/router.middlewares: authelia-authelia-auth@kubernetescrd -spec: - ingressClassName: traefik - tls: - - hosts: - - mas0213.kro.kr - - www.mas0213.kro.kr - secretName: mas-tls - rules: - - host: mas0213.kro.kr - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: mas - port: - number: 8000 - - host: www.mas0213.kro.kr - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: mas - port: - number: 8000 diff --git a/deploy/k8s/overlays/prod/kustomization.yaml b/deploy/k8s/overlays/prod/kustomization.yaml deleted file mode 100644 index 32cfc0c..0000000 --- a/deploy/k8s/overlays/prod/kustomization.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -namespace: mas - -resources: - - ../../base - - resourcequota.yaml - - externalsecret.yaml - - ingress.yaml - -commonLabels: - environment: production - -# 이미지 태그 설정 (ArgoCD Image Updater가 자동으로 업데이트) -images: - - name: ghcr.io/mayne0213/mas - newName: ghcr.io/mayne0213/mas - newTag: main-sha-f9e224d1babebeb86275a65872bb9980b8ebff5f - diff --git a/deploy/k8s/overlays/prod/namespace.yaml b/deploy/k8s/overlays/prod/namespace.yaml deleted file mode 100644 index af1e786..0000000 --- a/deploy/k8s/overlays/prod/namespace.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: mas - labels: - name: mas - environment: production - diff --git a/deploy/k8s/overlays/prod/resourcequota.yaml b/deploy/k8s/overlays/prod/resourcequota.yaml deleted file mode 100644 index fad5f00..0000000 --- a/deploy/k8s/overlays/prod/resourcequota.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: ResourceQuota -metadata: - name: mas-quota -spec: - hard: - requests.cpu: "4" - requests.memory: 8Gi - # limits.cpu: "8" # Removed to prevent quota enforcement (we removed CPU limits cluster-wide) - limits.memory: 16Gi - persistentvolumeclaims: "5" - diff --git a/deploy/k8s/overlays/prod/serviceaccount.yaml b/deploy/k8s/overlays/prod/serviceaccount.yaml deleted file mode 100644 index eb67ecf..0000000 --- a/deploy/k8s/overlays/prod/serviceaccount.yaml +++ /dev/null @@ -1,127 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: mas - namespace: mas ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: mas-viewer -rules: - # Read-only access to most resources - - apiGroups: [""] - resources: - - pods - - pods/log - - services - - endpoints - - namespaces - - nodes - - persistentvolumeclaims - - configmaps - verbs: ["get", "list", "watch"] - - - apiGroups: ["apps"] - resources: - - deployments - - statefulsets - - daemonsets - - replicasets - verbs: ["get", "list", "watch"] - - - apiGroups: ["batch"] - resources: - - jobs - - cronjobs - verbs: ["get", "list", "watch"] - - - apiGroups: ["networking.k8s.io"] - resources: - - ingresses - verbs: ["get", "list", "watch"] - - - apiGroups: ["argoproj.io"] - resources: - - applications - verbs: ["get", "list", "watch"] - - # Describe resources - - apiGroups: [""] - resources: - - pods/status - - services/status - verbs: ["get"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: mas-viewer-binding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: mas-viewer -subjects: - - kind: ServiceAccount - name: mas - namespace: mas ---- -# YAML Manager용 write 권한 (Groq 에이전트) -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: mas-writer -rules: - # Write access for YAML Manager - - apiGroups: [""] - resources: - - pods - - services - - configmaps - - secrets - verbs: ["create", "update", "patch", "delete"] - - - apiGroups: ["apps"] - resources: - - deployments - - statefulsets - - daemonsets - - replicasets - verbs: ["create", "update", "patch", "delete"] - - - apiGroups: ["networking.k8s.io"] - resources: - - ingresses - verbs: ["create", "update", "patch", "delete"] - - - apiGroups: ["batch"] - resources: - - jobs - - cronjobs - verbs: ["create", "update", "patch", "delete"] - - # Namespace management - - apiGroups: [""] - resources: - - namespaces - verbs: ["create", "update", "patch"] - - # ArgoCD Application management - - apiGroups: ["argoproj.io"] - resources: - - applications - verbs: ["create", "update", "patch", "delete"] ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: mas-writer-binding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: mas-writer -subjects: - - kind: ServiceAccount - name: mas - namespace: mas - diff --git a/services/backend/agents/__init__.py b/langgraph/agents/__init__.py similarity index 100% rename from services/backend/agents/__init__.py rename to langgraph/agents/__init__.py diff --git a/services/backend/agents/decision_agent.py b/langgraph/agents/decision_agent.py similarity index 100% rename from services/backend/agents/decision_agent.py rename to langgraph/agents/decision_agent.py diff --git a/services/backend/agents/orchestrator.py b/langgraph/agents/orchestrator.py similarity index 100% rename from services/backend/agents/orchestrator.py rename to langgraph/agents/orchestrator.py diff --git a/services/backend/agents/planning_agent.py b/langgraph/agents/planning_agent.py similarity index 100% rename from services/backend/agents/planning_agent.py rename to langgraph/agents/planning_agent.py diff --git a/services/backend/agents/prompt_generator_agent.py b/langgraph/agents/prompt_generator_agent.py similarity index 100% rename from services/backend/agents/prompt_generator_agent.py rename to langgraph/agents/prompt_generator_agent.py diff --git a/services/backend/agents/research_agent.py b/langgraph/agents/research_agent.py similarity index 100% rename from services/backend/agents/research_agent.py rename to langgraph/agents/research_agent.py diff --git a/services/backend/agents/state.py b/langgraph/agents/state.py similarity index 100% rename from services/backend/agents/state.py rename to langgraph/agents/state.py diff --git a/services/backend/chainlit.md b/langgraph/chainlit.md similarity index 100% rename from services/backend/chainlit.md rename to langgraph/chainlit.md diff --git a/services/backend/chainlit_app.py b/langgraph/chainlit_app.py similarity index 100% rename from services/backend/chainlit_app.py rename to langgraph/chainlit_app.py diff --git a/services/backend/requirements.txt b/langgraph/requirements.txt similarity index 100% rename from services/backend/requirements.txt rename to langgraph/requirements.txt diff --git a/services/backend/tools/__init__.py b/langgraph/tools/__init__.py similarity index 100% rename from services/backend/tools/__init__.py rename to langgraph/tools/__init__.py diff --git a/services/backend/tools/bash_tool.py b/langgraph/tools/bash_tool.py similarity index 100% rename from services/backend/tools/bash_tool.py rename to langgraph/tools/bash_tool.py diff --git a/services/backend/workflow.py b/langgraph/workflow.py similarity index 100% rename from services/backend/workflow.py rename to langgraph/workflow.py