diff --git a/.gitignore b/.gitignore index b24ff5c..100bb2d 100644 --- a/.gitignore +++ b/.gitignore @@ -40,8 +40,9 @@ dist/ .terraform.lock.hcl # Private deployment (OKE/K8s — not for public distribution) -deploy/terraform-oke/ -deploy/k8s/ +infra/terraform-oke/ +infra/k8s/ -# Project internal docs -LESSONS_LEARNED.md +# Cache +.pytest_cache/ +**/.pytest_cache/ diff --git a/README.md b/README.md index 76a0adc..bd9e3cc 100644 --- a/README.md +++ b/README.md @@ -504,26 +504,35 @@ Allow group to read buckets in compartment ``` oci-cis-agent/ ├── backend/ -│ ├── app.py # FastAPI application (~10500 lines) -│ ├── cis_reports.py # Oracle CIS Benchmark checker (6660 lines, report engine) -│ ├── mcp_cis_server.py # MCP server with 12 granular CIS tools (~700 lines) -│ ├── gen_tf_reference.py # OCI Terraform provider resource catalog generator -│ ├── Dockerfile # Python 3.12 + OCI CLI + Terraform 1.14.7 + Chromium -│ └── requirements.txt # Dependencies -├── frontend-react/ -│ ├── src/ # React 19 SPA (TypeScript, 46 source files, ~19500 lines) -│ │ ├── pages/ # 20 page components (Chat, Terraform, Explorer, Terminal, OCI Services, Reports, Config, Admin) -│ │ ├── api/ # API client + endpoint modules -│ │ ├── stores/ # Zustand stores (app, auth, terminal — state persistence across navigation) -│ │ ├── hooks/ # Custom hooks (theme, polling) -│ │ └── i18n/ # Internationalization (pt/en/es, 850+ keys) -│ └── dist/ # Built SPA served at / +│ ├── app.py # FastAPI application (~10500 lines) +│ ├── cis_reports.py # Oracle CIS Benchmark checker (6660 lines) +│ ├── mcp_cis_server.py # MCP server with 12 granular CIS tools +│ ├── gen_tf_reference.py # OCI Terraform provider resource catalog generator +│ ├── Dockerfile # Backend image (Python 3.12 + OCI CLI + Terraform + Chromium) +│ ├── requirements.txt +│ └── tests/ # 86 baseline tests (pytest) +├── frontend/ +│ ├── src/ # React 19 SPA (TypeScript, 46 files, ~19500 lines) +│ │ ├── pages/ # 20 page components +│ │ ├── api/ # API client + endpoint modules +│ │ ├── stores/ # Zustand stores (app, auth, terminal) +│ │ ├── hooks/ # Custom hooks (theme, polling) +│ │ └── i18n/ # Internationalization (pt/en/es, 850+ keys) +│ └── dist/ # Built SPA +├── infra/ +│ ├── docker/ +│ │ ├── Dockerfile.single # Single container (nginx + backend + supervisord) +│ │ └── Dockerfile.frontend +│ ├── terraform-vm/ # OCI VM deployment (ARM Free Tier, LB+WAF+SSL) +│ ├── scripts/ +│ │ ├── push-images.sh # Build + push to OCIR +│ │ └── ocir-login.py # Encrypted OCIR credentials helper +│ └── ... +├── distribution/ # Public release package (setup.sh + README + terraform) ├── nginx/ -│ └── default.conf # Reverse proxy (React SPA + API /api/) -├── docker-compose.yml # Orchestration -├── logo.svg # Project logo (Oracle AI Robot) -├── .env.example # Environment template -├── .gitignore +│ └── default.conf +├── docker-compose.yml +├── .env.example └── README.md ``` @@ -884,7 +893,7 @@ python -m pytest tests/ -v ### Build & Push OCIR Image ```bash -OCIR_REGION=us-ashburn-1 OCIR_NAMESPACE=idi1o0a010nx ./deploy/scripts/push-images.sh +OCIR_REGION=us-ashburn-1 OCIR_NAMESPACE=idi1o0a010nx ./infra/scripts/push-images.sh ``` ### Rebuild After Changes diff --git a/deploy/scripts/push-images.sh b/deploy/scripts/push-images.sh deleted file mode 100755 index b6ef5d5..0000000 --- a/deploy/scripts/push-images.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" - -OCIR_REGION="${OCIR_REGION:?Set OCIR_REGION (e.g., us-ashburn-1)}" -OCIR_NAMESPACE="${OCIR_NAMESPACE:?Set OCIR_NAMESPACE}" -OCIR_REPO_PREFIX="${OCIR_REPO_PREFIX:-oci-cis-agent}" -IMAGE_TAG="${IMAGE_TAG:-latest}" - -UNIFIED="${OCIR_REGION}.ocir.io/${OCIR_NAMESPACE}/${OCIR_REPO_PREFIX}:${IMAGE_TAG}" -BACKEND="${OCIR_REGION}.ocir.io/${OCIR_NAMESPACE}/${OCIR_REPO_PREFIX}-backend:${IMAGE_TAG}" -FRONTEND="${OCIR_REGION}.ocir.io/${OCIR_NAMESPACE}/${OCIR_REPO_PREFIX}-frontend:${IMAGE_TAG}" - -echo "========================================" -echo "OCI CIS Agent — Build & Push to OCIR" -echo "========================================" -echo "Unified: $UNIFIED" -echo "Backend: $BACKEND" -echo "Frontend: $FRONTEND" -echo "" - -# 1. Build frontend React SPA -echo ">>> Building frontend..." -cd "$PROJECT_ROOT/frontend-react" -npm ci --silent -npm run build -echo "Frontend build OK." - -# 2. Ensure buildx builder exists -docker buildx inspect multiarch >/dev/null 2>&1 || \ - docker buildx create --name multiarch --use -docker buildx use multiarch - -# 3. Login to OCIR -echo ">>> Logging in to OCIR..." -docker login "${OCIR_REGION}.ocir.io" - -# 4. Build + push UNIFIED image (single container — nginx + backend) -echo ">>> Building & pushing unified image (amd64 + arm64)..." -cd "$PROJECT_ROOT" -docker buildx build \ - --platform linux/amd64,linux/arm64 \ - -t "$UNIFIED" \ - --push \ - -f deploy/Dockerfile . -echo "Unified image pushed." - -# 5. Build + push backend (multi-arch) — for docker-compose deployments -echo ">>> Building & pushing backend (amd64 + arm64)..." -docker buildx build \ - --platform linux/amd64,linux/arm64 \ - -t "$BACKEND" \ - --push \ - -f backend/Dockerfile backend/ -echo "Backend image pushed." - -# 6. Build + push frontend (multi-arch) — for docker-compose deployments -echo ">>> Building & pushing frontend (amd64 + arm64)..." -docker buildx build \ - --platform linux/amd64,linux/arm64 \ - -t "$FRONTEND" \ - --push \ - -f deploy/Dockerfile.frontend . -echo "Frontend image pushed." - -echo "" -echo "========================================" -echo "All 3 images pushed!" -echo "Unified: $UNIFIED (single container)" -echo "Backend: $BACKEND (docker-compose)" -echo "Frontend: $FRONTEND (docker-compose)" -echo "========================================" diff --git a/docker-compose.yml b/docker-compose.yml index e4de6a6..3277beb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -38,7 +38,7 @@ services: environment: - TZ=${TZ:-America/Sao_Paulo} volumes: - - ./frontend-react/dist:/usr/share/nginx/html/app:ro + - ./frontend/dist:/usr/share/nginx/html/app:ro - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro ports: - "${PORT:-8080}:80" diff --git a/frontend-react/.gitignore b/frontend/.gitignore similarity index 100% rename from frontend-react/.gitignore rename to frontend/.gitignore diff --git a/frontend-react/README.md b/frontend/README.md similarity index 100% rename from frontend-react/README.md rename to frontend/README.md diff --git a/frontend-react/eslint.config.js b/frontend/eslint.config.js similarity index 100% rename from frontend-react/eslint.config.js rename to frontend/eslint.config.js diff --git a/frontend-react/index.html b/frontend/index.html similarity index 100% rename from frontend-react/index.html rename to frontend/index.html diff --git a/frontend-react/package-lock.json b/frontend/package-lock.json similarity index 100% rename from frontend-react/package-lock.json rename to frontend/package-lock.json diff --git a/frontend-react/package.json b/frontend/package.json similarity index 100% rename from frontend-react/package.json rename to frontend/package.json diff --git a/frontend-react/postcss.config.js b/frontend/postcss.config.js similarity index 100% rename from frontend-react/postcss.config.js rename to frontend/postcss.config.js diff --git a/frontend-react/public/logo.svg b/frontend/public/logo.svg similarity index 100% rename from frontend-react/public/logo.svg rename to frontend/public/logo.svg diff --git a/frontend-react/src/App.tsx b/frontend/src/App.tsx similarity index 100% rename from frontend-react/src/App.tsx rename to frontend/src/App.tsx diff --git a/frontend-react/src/api/client.ts b/frontend/src/api/client.ts similarity index 100% rename from frontend-react/src/api/client.ts rename to frontend/src/api/client.ts diff --git a/frontend-react/src/api/endpoints/adb.ts b/frontend/src/api/endpoints/adb.ts similarity index 100% rename from frontend-react/src/api/endpoints/adb.ts rename to frontend/src/api/endpoints/adb.ts diff --git a/frontend-react/src/api/endpoints/admin.ts b/frontend/src/api/endpoints/admin.ts similarity index 100% rename from frontend-react/src/api/endpoints/admin.ts rename to frontend/src/api/endpoints/admin.ts diff --git a/frontend-react/src/api/endpoints/auth.ts b/frontend/src/api/endpoints/auth.ts similarity index 100% rename from frontend-react/src/api/endpoints/auth.ts rename to frontend/src/api/endpoints/auth.ts diff --git a/frontend-react/src/api/endpoints/chat.ts b/frontend/src/api/endpoints/chat.ts similarity index 100% rename from frontend-react/src/api/endpoints/chat.ts rename to frontend/src/api/endpoints/chat.ts diff --git a/frontend-react/src/api/endpoints/embeddings.ts b/frontend/src/api/endpoints/embeddings.ts similarity index 100% rename from frontend-react/src/api/endpoints/embeddings.ts rename to frontend/src/api/endpoints/embeddings.ts diff --git a/frontend-react/src/api/endpoints/explorer.ts b/frontend/src/api/endpoints/explorer.ts similarity index 100% rename from frontend-react/src/api/endpoints/explorer.ts rename to frontend/src/api/endpoints/explorer.ts diff --git a/frontend-react/src/api/endpoints/genai.ts b/frontend/src/api/endpoints/genai.ts similarity index 100% rename from frontend-react/src/api/endpoints/genai.ts rename to frontend/src/api/endpoints/genai.ts diff --git a/frontend-react/src/api/endpoints/mcp.ts b/frontend/src/api/endpoints/mcp.ts similarity index 100% rename from frontend-react/src/api/endpoints/mcp.ts rename to frontend/src/api/endpoints/mcp.ts diff --git a/frontend-react/src/api/endpoints/oci.ts b/frontend/src/api/endpoints/oci.ts similarity index 100% rename from frontend-react/src/api/endpoints/oci.ts rename to frontend/src/api/endpoints/oci.ts diff --git a/frontend-react/src/api/endpoints/reports.ts b/frontend/src/api/endpoints/reports.ts similarity index 100% rename from frontend-react/src/api/endpoints/reports.ts rename to frontend/src/api/endpoints/reports.ts diff --git a/frontend-react/src/api/endpoints/terraform.ts b/frontend/src/api/endpoints/terraform.ts similarity index 100% rename from frontend-react/src/api/endpoints/terraform.ts rename to frontend/src/api/endpoints/terraform.ts diff --git a/frontend-react/src/components/layout/AppShell.tsx b/frontend/src/components/layout/AppShell.tsx similarity index 100% rename from frontend-react/src/components/layout/AppShell.tsx rename to frontend/src/components/layout/AppShell.tsx diff --git a/frontend-react/src/components/layout/Sidebar.tsx b/frontend/src/components/layout/Sidebar.tsx similarity index 100% rename from frontend-react/src/components/layout/Sidebar.tsx rename to frontend/src/components/layout/Sidebar.tsx diff --git a/frontend-react/src/hooks/usePolling.ts b/frontend/src/hooks/usePolling.ts similarity index 100% rename from frontend-react/src/hooks/usePolling.ts rename to frontend/src/hooks/usePolling.ts diff --git a/frontend-react/src/hooks/useTheme.ts b/frontend/src/hooks/useTheme.ts similarity index 100% rename from frontend-react/src/hooks/useTheme.ts rename to frontend/src/hooks/useTheme.ts diff --git a/frontend-react/src/i18n/en.ts b/frontend/src/i18n/en.ts similarity index 100% rename from frontend-react/src/i18n/en.ts rename to frontend/src/i18n/en.ts diff --git a/frontend-react/src/i18n/es.ts b/frontend/src/i18n/es.ts similarity index 100% rename from frontend-react/src/i18n/es.ts rename to frontend/src/i18n/es.ts diff --git a/frontend-react/src/i18n/index.ts b/frontend/src/i18n/index.ts similarity index 100% rename from frontend-react/src/i18n/index.ts rename to frontend/src/i18n/index.ts diff --git a/frontend-react/src/i18n/pt.ts b/frontend/src/i18n/pt.ts similarity index 100% rename from frontend-react/src/i18n/pt.ts rename to frontend/src/i18n/pt.ts diff --git a/frontend-react/src/index.css b/frontend/src/index.css similarity index 100% rename from frontend-react/src/index.css rename to frontend/src/index.css diff --git a/frontend-react/src/main.tsx b/frontend/src/main.tsx similarity index 100% rename from frontend-react/src/main.tsx rename to frontend/src/main.tsx diff --git a/frontend-react/src/pages/ChatPage.tsx b/frontend/src/pages/ChatPage.tsx similarity index 100% rename from frontend-react/src/pages/ChatPage.tsx rename to frontend/src/pages/ChatPage.tsx diff --git a/frontend-react/src/pages/ExplorerPage.tsx b/frontend/src/pages/ExplorerPage.tsx similarity index 100% rename from frontend-react/src/pages/ExplorerPage.tsx rename to frontend/src/pages/ExplorerPage.tsx diff --git a/frontend-react/src/pages/LoginPage.tsx b/frontend/src/pages/LoginPage.tsx similarity index 100% rename from frontend-react/src/pages/LoginPage.tsx rename to frontend/src/pages/LoginPage.tsx diff --git a/frontend-react/src/pages/OciServicesPage.tsx b/frontend/src/pages/OciServicesPage.tsx similarity index 100% rename from frontend-react/src/pages/OciServicesPage.tsx rename to frontend/src/pages/OciServicesPage.tsx diff --git a/frontend-react/src/pages/PromptGeneratorPage.tsx b/frontend/src/pages/PromptGeneratorPage.tsx similarity index 100% rename from frontend-react/src/pages/PromptGeneratorPage.tsx rename to frontend/src/pages/PromptGeneratorPage.tsx diff --git a/frontend-react/src/pages/ReportsPage.tsx b/frontend/src/pages/ReportsPage.tsx similarity index 100% rename from frontend-react/src/pages/ReportsPage.tsx rename to frontend/src/pages/ReportsPage.tsx diff --git a/frontend-react/src/pages/TerminalPage.tsx b/frontend/src/pages/TerminalPage.tsx similarity index 100% rename from frontend-react/src/pages/TerminalPage.tsx rename to frontend/src/pages/TerminalPage.tsx diff --git a/frontend-react/src/pages/TerraformPage.tsx b/frontend/src/pages/TerraformPage.tsx similarity index 100% rename from frontend-react/src/pages/TerraformPage.tsx rename to frontend/src/pages/TerraformPage.tsx diff --git a/frontend-react/src/pages/WorkspacesPage.tsx b/frontend/src/pages/WorkspacesPage.tsx similarity index 100% rename from frontend-react/src/pages/WorkspacesPage.tsx rename to frontend/src/pages/WorkspacesPage.tsx diff --git a/frontend-react/src/pages/admin/AuditPage.tsx b/frontend/src/pages/admin/AuditPage.tsx similarity index 100% rename from frontend-react/src/pages/admin/AuditPage.tsx rename to frontend/src/pages/admin/AuditPage.tsx diff --git a/frontend-react/src/pages/admin/MySettingsPage.tsx b/frontend/src/pages/admin/MySettingsPage.tsx similarity index 100% rename from frontend-react/src/pages/admin/MySettingsPage.tsx rename to frontend/src/pages/admin/MySettingsPage.tsx diff --git a/frontend-react/src/pages/admin/OracleIamPage.tsx b/frontend/src/pages/admin/OracleIamPage.tsx similarity index 100% rename from frontend-react/src/pages/admin/OracleIamPage.tsx rename to frontend/src/pages/admin/OracleIamPage.tsx diff --git a/frontend-react/src/pages/admin/UsersPage.tsx b/frontend/src/pages/admin/UsersPage.tsx similarity index 100% rename from frontend-react/src/pages/admin/UsersPage.tsx rename to frontend/src/pages/admin/UsersPage.tsx diff --git a/frontend-react/src/pages/config/AdbConfigPage.tsx b/frontend/src/pages/config/AdbConfigPage.tsx similarity index 100% rename from frontend-react/src/pages/config/AdbConfigPage.tsx rename to frontend/src/pages/config/AdbConfigPage.tsx diff --git a/frontend-react/src/pages/config/EmbConsultPage.tsx b/frontend/src/pages/config/EmbConsultPage.tsx similarity index 100% rename from frontend-react/src/pages/config/EmbConsultPage.tsx rename to frontend/src/pages/config/EmbConsultPage.tsx diff --git a/frontend-react/src/pages/config/EmbeddingsPage.tsx b/frontend/src/pages/config/EmbeddingsPage.tsx similarity index 100% rename from frontend-react/src/pages/config/EmbeddingsPage.tsx rename to frontend/src/pages/config/EmbeddingsPage.tsx diff --git a/frontend-react/src/pages/config/GenAiConfigPage.tsx b/frontend/src/pages/config/GenAiConfigPage.tsx similarity index 100% rename from frontend-react/src/pages/config/GenAiConfigPage.tsx rename to frontend/src/pages/config/GenAiConfigPage.tsx diff --git a/frontend-react/src/pages/config/McpServersPage.tsx b/frontend/src/pages/config/McpServersPage.tsx similarity index 100% rename from frontend-react/src/pages/config/McpServersPage.tsx rename to frontend/src/pages/config/McpServersPage.tsx diff --git a/frontend-react/src/pages/config/OciConfigPage.tsx b/frontend/src/pages/config/OciConfigPage.tsx similarity index 100% rename from frontend-react/src/pages/config/OciConfigPage.tsx rename to frontend/src/pages/config/OciConfigPage.tsx diff --git a/frontend-react/src/stores/app.ts b/frontend/src/stores/app.ts similarity index 100% rename from frontend-react/src/stores/app.ts rename to frontend/src/stores/app.ts diff --git a/frontend-react/src/stores/auth.ts b/frontend/src/stores/auth.ts similarity index 100% rename from frontend-react/src/stores/auth.ts rename to frontend/src/stores/auth.ts diff --git a/frontend-react/src/stores/terminal.ts b/frontend/src/stores/terminal.ts similarity index 100% rename from frontend-react/src/stores/terminal.ts rename to frontend/src/stores/terminal.ts diff --git a/frontend-react/tsconfig.app.json b/frontend/tsconfig.app.json similarity index 100% rename from frontend-react/tsconfig.app.json rename to frontend/tsconfig.app.json diff --git a/frontend-react/tsconfig.json b/frontend/tsconfig.json similarity index 100% rename from frontend-react/tsconfig.json rename to frontend/tsconfig.json diff --git a/frontend-react/tsconfig.node.json b/frontend/tsconfig.node.json similarity index 100% rename from frontend-react/tsconfig.node.json rename to frontend/tsconfig.node.json diff --git a/frontend-react/vite.config.ts b/frontend/vite.config.ts similarity index 100% rename from frontend-react/vite.config.ts rename to frontend/vite.config.ts diff --git a/deploy/Dockerfile.frontend b/infra/docker/Dockerfile.frontend similarity index 75% rename from deploy/Dockerfile.frontend rename to infra/docker/Dockerfile.frontend index 32d4950..ee81b12 100644 --- a/deploy/Dockerfile.frontend +++ b/infra/docker/Dockerfile.frontend @@ -1,6 +1,6 @@ FROM nginx:alpine RUN rm -rf /usr/share/nginx/html/* -COPY frontend-react/dist /usr/share/nginx/html/app +COPY frontend/dist /usr/share/nginx/html/app COPY nginx/default.conf /etc/nginx/conf.d/default.conf EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] diff --git a/deploy/Dockerfile b/infra/docker/Dockerfile.single similarity index 98% rename from deploy/Dockerfile rename to infra/docker/Dockerfile.single index 26a78b5..a87af37 100644 --- a/deploy/Dockerfile +++ b/infra/docker/Dockerfile.single @@ -26,7 +26,7 @@ COPY backend/gen_tf_reference.py . # ── Frontend (pre-built React SPA) ───────────────────────────────────────── RUN rm -rf /usr/share/nginx/html/* -COPY frontend-react/dist /usr/share/nginx/html/app +COPY frontend/dist /usr/share/nginx/html/app # ── Nginx config (proxy to localhost instead of backend hostname) ─────────── RUN printf 'map $uri $empty {\n default "";\n}\n\nserver {\n listen 8080;\n server_name _;\n client_max_body_size 50M;\n absolute_redirect off;\n\n location / {\n root /usr/share/nginx/html/app;\n try_files $uri $uri/ /index.html;\n add_header Cache-Control "no-cache, no-store, must-revalidate" always;\n add_header X-Frame-Options "DENY" always;\n add_header X-Content-Type-Options "nosniff" always;\n add_header X-XSS-Protection "1; mode=block" always;\n add_header Referrer-Policy "strict-origin-when-cross-origin" always;\n add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;\n }\n\n location /api/ {\n proxy_pass http://127.0.0.1:8000/api/;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n proxy_read_timeout 900s;\n proxy_send_timeout 900s;\n proxy_connect_timeout 60s;\n add_header X-Frame-Options "SAMEORIGIN" always;\n add_header X-Content-Type-Options "nosniff" always;\n }\n}\n' > /etc/nginx/sites-available/default diff --git a/deploy/scripts/ocir-login.py b/infra/scripts/ocir-login.py similarity index 100% rename from deploy/scripts/ocir-login.py rename to infra/scripts/ocir-login.py diff --git a/infra/scripts/push-images.sh b/infra/scripts/push-images.sh new file mode 100755 index 0000000..5092429 --- /dev/null +++ b/infra/scripts/push-images.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" + +OCIR_REGION="${OCIR_REGION:?Set OCIR_REGION (e.g., us-ashburn-1)}" +OCIR_NAMESPACE="${OCIR_NAMESPACE:?Set OCIR_NAMESPACE}" +OCIR_REPO_PREFIX="${OCIR_REPO_PREFIX:-oci-cis-agent}" +IMAGE_TAG="${IMAGE_TAG:-latest}" + +UNIFIED="${OCIR_REGION}.ocir.io/${OCIR_NAMESPACE}/${OCIR_REPO_PREFIX}:${IMAGE_TAG}" + +echo "========================================" +echo "OCI CIS Agent — Build & Push to OCIR" +echo "========================================" +echo "Image: $UNIFIED" +echo "" + +# 1. Build frontend React SPA +echo ">>> Building frontend..." +cd "$PROJECT_ROOT/frontend" +npm ci --silent +npm run build +echo "Frontend build OK." + +# 2. Ensure buildx builder exists +docker buildx inspect multiarch >/dev/null 2>&1 || \ + docker buildx create --name multiarch --use +docker buildx use multiarch + +# 3. Login to OCIR +echo ">>> Logging in to OCIR..." +docker login "${OCIR_REGION}.ocir.io" + +# 4. Build + push single container image (multi-arch) +echo ">>> Building & pushing image (amd64 + arm64)..." +cd "$PROJECT_ROOT" +docker buildx build \ + --platform linux/amd64,linux/arm64 \ + -t "$UNIFIED" \ + --push \ + -f infra/docker/Dockerfile.single . +echo "Image pushed." + +echo "" +echo "========================================" +echo "Done! $UNIFIED" +echo "========================================" diff --git a/deploy/terraform-vm/compute.tf b/infra/terraform-vm/compute.tf similarity index 100% rename from deploy/terraform-vm/compute.tf rename to infra/terraform-vm/compute.tf diff --git a/deploy/terraform-vm/dns.tf b/infra/terraform-vm/dns.tf similarity index 100% rename from deploy/terraform-vm/dns.tf rename to infra/terraform-vm/dns.tf diff --git a/deploy/terraform-vm/lb.tf b/infra/terraform-vm/lb.tf similarity index 100% rename from deploy/terraform-vm/lb.tf rename to infra/terraform-vm/lb.tf diff --git a/deploy/terraform-vm/network.tf b/infra/terraform-vm/network.tf similarity index 100% rename from deploy/terraform-vm/network.tf rename to infra/terraform-vm/network.tf diff --git a/deploy/terraform-vm/outputs.tf b/infra/terraform-vm/outputs.tf similarity index 100% rename from deploy/terraform-vm/outputs.tf rename to infra/terraform-vm/outputs.tf diff --git a/deploy/terraform-vm/provider.tf b/infra/terraform-vm/provider.tf similarity index 100% rename from deploy/terraform-vm/provider.tf rename to infra/terraform-vm/provider.tf diff --git a/deploy/terraform-vm/storage.tf b/infra/terraform-vm/storage.tf similarity index 100% rename from deploy/terraform-vm/storage.tf rename to infra/terraform-vm/storage.tf diff --git a/deploy/terraform-vm/templates/cloud-init.sh.tpl b/infra/terraform-vm/templates/cloud-init.sh.tpl similarity index 100% rename from deploy/terraform-vm/templates/cloud-init.sh.tpl rename to infra/terraform-vm/templates/cloud-init.sh.tpl diff --git a/deploy/terraform-vm/terraform.tfvars.example b/infra/terraform-vm/terraform.tfvars.example similarity index 100% rename from deploy/terraform-vm/terraform.tfvars.example rename to infra/terraform-vm/terraform.tfvars.example diff --git a/deploy/terraform-vm/variables.tf b/infra/terraform-vm/variables.tf similarity index 100% rename from deploy/terraform-vm/variables.tf rename to infra/terraform-vm/variables.tf diff --git a/deploy/terraform-vm/waf.tf b/infra/terraform-vm/waf.tf similarity index 100% rename from deploy/terraform-vm/waf.tf rename to infra/terraform-vm/waf.tf