diff --git a/README.md b/README.md index 420eb0c..4b45416 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,95 @@ A high-performance API Gateway and distributed platform built in Go. Provides a - **🔐 Authentication** - Wallet signatures, API keys, JWT tokens - **💾 Storage** - IPFS-based decentralized file storage with encryption - **⚡ Cache** - Distributed cache with Olric (in-memory key-value) -- **🗄️ Database** - RQLite distributed SQL with Raft consensus +- **🗄️ Database** - RQLite distributed SQL with Raft consensus + Per-namespace SQLite databases - **📡 Pub/Sub** - Real-time messaging via LibP2P and WebSocket - **⚙️ Serverless** - WebAssembly function execution with host functions - **🌐 HTTP Gateway** - Unified REST API with automatic HTTPS (Let's Encrypt) - **📦 Client SDK** - Type-safe Go SDK for all services +- **🚀 App Deployments** - Deploy React, Next.js, Go, Node.js apps with automatic domains +- **🗄️ SQLite Databases** - Per-namespace isolated databases with IPFS backups + +## Application Deployments + +Deploy full-stack applications with automatic domain assignment and namespace isolation. + +### Deploy a React App + +```bash +# Build your app +cd my-react-app +npm run build + +# Deploy to Orama Network +orama deploy static ./dist --name my-app + +# Your app is now live at: https://my-app.orama.network +``` + +### Deploy Next.js with SSR + +```bash +cd my-nextjs-app +npm run build +orama deploy nextjs . --name my-nextjs --ssr + +# Live at: https://my-nextjs.orama.network +``` + +### Deploy Go Backend + +```bash +# Build for Linux +GOOS=linux GOARCH=amd64 go build -o api main.go + +# Deploy +orama deploy go ./api --name my-api + +# API live at: https://my-api.orama.network +``` + +### Create SQLite Database + +```bash +# Create database +orama db create my-database + +# Create schema +orama db query my-database "CREATE TABLE users (id INT, name TEXT)" + +# Insert data +orama db query my-database "INSERT INTO users VALUES (1, 'Alice')" + +# Query data +orama db query my-database "SELECT * FROM users" + +# Backup to IPFS +orama db backup my-database +``` + +### Full-Stack Example + +Deploy a complete app with React frontend, Go backend, and SQLite database: + +```bash +# 1. Create database +orama db create myapp-db +orama db query myapp-db "CREATE TABLE users (id INT PRIMARY KEY, name TEXT)" + +# 2. Deploy Go backend (connects to database) +GOOS=linux GOARCH=amd64 go build -o api main.go +orama deploy go ./api --name myapp-api + +# 3. Deploy React frontend (calls backend API) +cd frontend && npm run build +orama deploy static ./dist --name myapp + +# Access: +# Frontend: https://myapp.orama.network +# Backend: https://myapp-api.orama.network +``` + +**📖 Full Guide**: See [Deployment Guide](docs/DEPLOYMENT_GUIDE.md) for complete documentation, examples, and best practices. ## Quick Start @@ -108,36 +192,63 @@ make build ## CLI Commands +### Authentication + +```bash +orama auth login # Authenticate with wallet +orama auth status # Check authentication +orama auth logout # Clear credentials +``` + +### Application Deployments + +```bash +# Deploy applications +orama deploy static --name myapp # React, Vue, static sites +orama deploy nextjs --name myapp --ssr # Next.js with SSR +orama deploy go --name myapp # Go binaries +orama deploy nodejs --name myapp # Node.js apps + +# Manage deployments +orama deployments list # List all deployments +orama deployments get # Get deployment details +orama deployments logs --follow # View logs +orama deployments delete # Delete deployment +orama deployments rollback --version 1 # Rollback to version +``` + +### SQLite Databases + +```bash +orama db create # Create database +orama db query "SELECT * FROM t" # Execute SQL query +orama db list # List all databases +orama db backup # Backup to IPFS +orama db backups # List backups +``` + ### Network Status ```bash -./bin/orama health # Cluster health check -./bin/orama peers # List connected peers -./bin/orama status # Network status +orama health # Cluster health check +orama peers # List connected peers +orama status # Network status ``` -### Database Operations +### RQLite Operations ```bash -./bin/orama query "SELECT * FROM users" -./bin/orama query "CREATE TABLE users (id INTEGER PRIMARY KEY)" -./bin/orama transaction --file ops.json +orama query "SELECT * FROM users" +orama query "CREATE TABLE users (id INTEGER PRIMARY KEY)" +orama transaction --file ops.json ``` ### Pub/Sub ```bash -./bin/orama pubsub publish -./bin/orama pubsub subscribe 30s -./bin/orama pubsub topics -``` - -### Authentication - -```bash -./bin/orama auth login -./bin/orama auth status -./bin/orama auth logout +orama pubsub publish +orama pubsub subscribe 30s +orama pubsub topics ``` ## Serverless Functions (WASM) @@ -331,10 +442,12 @@ See `openapi/gateway.yaml` for complete API specification. ## Documentation +- **[Deployment Guide](docs/DEPLOYMENT_GUIDE.md)** - Deploy React, Next.js, Go apps and manage databases - **[Architecture Guide](docs/ARCHITECTURE.md)** - System architecture and design patterns - **[Client SDK](docs/CLIENT_SDK.md)** - Go SDK documentation and examples - **[Gateway API](docs/GATEWAY_API.md)** - Complete HTTP API reference - **[Security Deployment](docs/SECURITY_DEPLOYMENT_GUIDE.md)** - Production security hardening +- **[Testing Plan](docs/TESTING_PLAN.md)** - Comprehensive testing strategy and implementation ## Resources diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 35ea99f..4518577 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -76,6 +76,16 @@ func main() { case "auth": cli.HandleAuthCommand(args) + // Deployment commands + case "deploy": + cli.HandleDeployCommand(args) + case "deployments": + cli.HandleDeploymentsCommand(args) + + // Database commands + case "db": + cli.HandleDBCommand(args) + // Help case "help", "--help", "-h": showHelp() @@ -132,19 +142,51 @@ func showHelp() { fmt.Printf(" auth status - Show detailed auth info\n") fmt.Printf(" auth help - Show auth command help\n\n") + fmt.Printf("📦 Deployments:\n") + fmt.Printf(" deploy static - Deploy a static site (React, Vue, etc.)\n") + fmt.Printf(" deploy nextjs - Deploy a Next.js application\n") + fmt.Printf(" deploy go - Deploy a Go backend\n") + fmt.Printf(" deploy nodejs - Deploy a Node.js backend\n") + fmt.Printf(" deployments list - List all deployments\n") + fmt.Printf(" deployments get - Get deployment details\n") + fmt.Printf(" deployments logs - View deployment logs\n") + fmt.Printf(" deployments delete - Delete a deployment\n") + fmt.Printf(" deployments rollback - Rollback to previous version\n\n") + + fmt.Printf("🗄️ Databases:\n") + fmt.Printf(" db create - Create a SQLite database\n") + fmt.Printf(" db query \"\" - Execute SQL query\n") + fmt.Printf(" db list - List all databases\n") + fmt.Printf(" db backup - Backup database to IPFS\n") + fmt.Printf(" db backups - List database backups\n\n") + fmt.Printf("Global Flags:\n") fmt.Printf(" -f, --format - Output format: table, json (default: table)\n") fmt.Printf(" -t, --timeout - Operation timeout (default: 30s)\n") fmt.Printf(" --help, -h - Show this help message\n\n") fmt.Printf("Examples:\n") + fmt.Printf(" # Deploy a React app\n") + fmt.Printf(" cd my-react-app && npm run build\n") + fmt.Printf(" orama deploy static ./dist --name my-app\n\n") + + fmt.Printf(" # Deploy a Next.js app with SSR\n") + fmt.Printf(" cd my-nextjs-app && npm run build\n") + fmt.Printf(" orama deploy nextjs . --name my-nextjs --ssr\n\n") + + fmt.Printf(" # Create and use a database\n") + fmt.Printf(" orama db create my-db\n") + fmt.Printf(" orama db query my-db \"CREATE TABLE users (id INT, name TEXT)\"\n") + fmt.Printf(" orama db query my-db \"INSERT INTO users VALUES (1, 'Alice')\"\n\n") + + fmt.Printf(" # Manage deployments\n") + fmt.Printf(" orama deployments list\n") + fmt.Printf(" orama deployments get my-app\n") + fmt.Printf(" orama deployments logs my-app --follow\n\n") + fmt.Printf(" # First node (creates new cluster)\n") fmt.Printf(" sudo orama install --vps-ip 203.0.113.1 --domain node-1.orama.network\n\n") - fmt.Printf(" # Join existing cluster\n") - fmt.Printf(" sudo orama install --vps-ip 203.0.113.2 --domain node-2.orama.network \\\n") - fmt.Printf(" --peers /ip4/203.0.113.1/tcp/4001/p2p/12D3KooW... --cluster-secret \n\n") - fmt.Printf(" # Service management\n") fmt.Printf(" orama status\n") fmt.Printf(" orama logs node --follow\n") diff --git a/docs/DEPLOYMENT_GUIDE.md b/docs/DEPLOYMENT_GUIDE.md new file mode 100644 index 0000000..b627772 --- /dev/null +++ b/docs/DEPLOYMENT_GUIDE.md @@ -0,0 +1,897 @@ +# Orama Network Deployment Guide + +Complete guide for deploying applications and managing databases on Orama Network. + +## Table of Contents + +- [Overview](#overview) +- [Authentication](#authentication) +- [Deploying Static Sites (React, Vue, etc.)](#deploying-static-sites) +- [Deploying Next.js Applications](#deploying-nextjs-applications) +- [Deploying Go Backends](#deploying-go-backends) +- [Deploying Node.js Backends](#deploying-nodejs-backends) +- [Managing SQLite Databases](#managing-sqlite-databases) +- [How Domains Work](#how-domains-work) +- [Full-Stack Application Example](#full-stack-application-example) +- [Managing Deployments](#managing-deployments) +- [Troubleshooting](#troubleshooting) + +--- + +## Overview + +Orama Network provides a decentralized platform for deploying web applications and managing databases. Each deployment: + +- **Gets a unique domain** automatically (e.g., `myapp.orama.network`) +- **Isolated per namespace** - your data and apps are completely separate from others +- **Served from IPFS** (static) or **runs as a process** (dynamic apps) +- **Fully managed** - automatic health checks, restarts, and logging + +### Supported Deployment Types + +| Type | Description | Use Case | Domain Example | +|------|-------------|----------|----------------| +| **Static** | HTML/CSS/JS files served from IPFS | React, Vue, Angular, plain HTML | `myapp.orama.network` | +| **Next.js** | Next.js with SSR support | Full-stack Next.js apps | `myapp.orama.network` | +| **Go** | Compiled Go binaries | REST APIs, microservices | `api.orama.network` | +| **Node.js** | Node.js applications | Express APIs, TypeScript backends | `backend.orama.network` | + +--- + +## Authentication + +Before deploying, authenticate with your wallet: + +```bash +# Authenticate +orama auth login + +# Check authentication status +orama auth whoami +``` + +Your API key is stored securely and used for all deployment operations. + +--- + +## Deploying Static Sites + +Deploy static sites built with React, Vue, Angular, or any static site generator. + +### React/Vite Example + +```bash +# 1. Build your React app +cd my-react-app +npm run build + +# 2. Deploy the build directory +orama deploy static ./dist --name my-react-app --domain repoanalyzer.ai + +# Output: +# 📦 Creating tarball from ./dist... +# ☁️ Uploading to Orama Network... +# +# ✅ Deployment successful! +# +# Name: my-react-app +# Type: static +# Status: active +# Version: 1 +# Content CID: QmXxxx... +# +# URLs: +# • https://my-react-app.orama.network +``` + +### What Happens Behind the Scenes + +1. **Tarball Creation**: CLI automatically creates a `.tar.gz` from your directory +2. **IPFS Upload**: Files are uploaded to IPFS and pinned across the network +3. **DNS Record**: A DNS record is created pointing `my-react-app.orama.network` to the gateway +4. **Instant Serving**: Your app is immediately accessible via the URL + +### Features + +- ✅ **SPA Routing**: Unknown routes automatically serve `/index.html` (perfect for React Router) +- ✅ **Correct Content-Types**: Automatically detects and serves `.html`, `.css`, `.js`, `.json`, `.png`, etc. +- ✅ **Caching**: `Cache-Control: public, max-age=3600` headers for optimal performance +- ✅ **Zero Downtime Updates**: Use `--update` flag to update without downtime + +### Updating a Deployment + +```bash +# Make changes to your app +# Rebuild +npm run build + +# Update deployment +orama deploy static ./dist --name my-react-app --update + +# Version increments automatically (1 → 2) +``` + +--- + +## Deploying Next.js Applications + +Deploy Next.js apps with full SSR (Server-Side Rendering) support. + +### Next.js with SSR + +```bash +# 1. Build your Next.js app +cd my-nextjs-app +npm run build + +# 2. Deploy with SSR enabled +orama deploy nextjs . --name my-nextjs --ssr + +# Output: +# 📦 Creating tarball from . +# ☁️ Uploading to Orama Network... +# +# ✅ Deployment successful! +# +# Name: my-nextjs +# Type: nextjs +# Status: active +# Version: 1 +# Port: 10100 +# +# URLs: +# • https://my-nextjs.orama.network +# +# ⚠️ Note: SSR deployment may take a minute to start. Check status with: orama deployments get my-nextjs +``` + +### What Happens Behind the Scenes + +1. **Tarball Upload**: Your `.next` build directory, `package.json`, and `public` are uploaded +2. **Home Node Assignment**: A node is chosen to host your app based on capacity +3. **Port Allocation**: A unique port (10100-19999) is assigned +4. **Systemd Service**: A systemd service is created to run `node server.js` +5. **Health Checks**: Gateway monitors your app every 30 seconds +6. **Reverse Proxy**: Gateway proxies requests from your domain to the local port + +### Static Next.js Export (No SSR) + +If you export Next.js to static HTML: + +```bash +# next.config.js +module.exports = { + output: 'export' +} + +# Build and deploy as static +npm run build +orama deploy static ./out --name my-nextjs-static +``` + +--- + +## Deploying Go Backends + +Deploy compiled Go binaries for high-performance APIs. + +### Go REST API Example + +```bash +# 1. Build your Go binary for Linux (if on Mac/Windows) +cd my-go-api +GOOS=linux GOARCH=amd64 go build -o api main.go + +# 2. Deploy the binary +orama deploy go ./api --name my-api + +# Output: +# 📦 Creating tarball from ./api... +# ☁️ Uploading to Orama Network... +# +# ✅ Deployment successful! +# +# Name: my-api +# Type: go +# Status: active +# Version: 1 +# Port: 10101 +# +# URLs: +# • https://my-api.orama.network +``` + +### Example Go API Code + +```go +// main.go +package main + +import ( + "encoding/json" + "log" + "net/http" + "os" +) + +func main() { + port := os.Getenv("PORT") + if port == "" { + port = "8080" + } + + http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { + json.NewEncoder(w).Encode(map[string]string{"status": "healthy"}) + }) + + http.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) { + users := []map[string]interface{}{ + {"id": 1, "name": "Alice"}, + {"id": 2, "name": "Bob"}, + } + json.NewEncoder(w).Encode(users) + }) + + log.Printf("Starting server on port %s", port) + log.Fatal(http.ListenAndServe(":"+port, nil)) +} +``` + +### Important Notes + +- **Environment Variables**: The `PORT` environment variable is automatically set to your allocated port +- **Health Endpoint**: Recommended to implement `/health` for monitoring +- **Binary Requirements**: Must be Linux-compatible (GOOS=linux GOARCH=amd64) +- **Systemd Managed**: Runs as a systemd service with auto-restart on failure + +--- + +## Deploying Node.js Backends + +Deploy Node.js/Express/TypeScript backends. + +### Express API Example + +```bash +# 1. Build your Node.js app (if using TypeScript) +cd my-node-api +npm run build + +# 2. Deploy (must include node_modules or use a bundler) +orama deploy nodejs ./dist --name my-node-api + +# Output: +# 📦 Creating tarball from ./dist... +# ☁️ Uploading to Orama Network... +# +# ✅ Deployment successful! +# +# Name: my-node-api +# Type: nodejs +# Status: active +# Version: 1 +# Port: 10102 +# +# URLs: +# • https://my-node-api.orama.network +``` + +### Example Node.js API + +```javascript +// server.js +const express = require('express'); +const app = express(); +const port = process.env.PORT || 8080; + +app.get('/health', (req, res) => { + res.json({ status: 'healthy' }); +}); + +app.get('/api/data', (req, res) => { + res.json({ message: 'Hello from Orama Network!' }); +}); + +app.listen(port, () => { + console.log(`Server running on port ${port}`); +}); +``` + +--- + +## Managing SQLite Databases + +Each namespace gets its own isolated SQLite databases. + +### Creating a Database + +```bash +# Create a new database +orama db create my-database + +# Output: +# ✅ Database created: my-database +# Home Node: node-abc123 +# File Path: /home/debros/.orama/data/sqlite/your-namespace/my-database.db +``` + +### Executing Queries + +```bash +# Create a table +orama db query my-database "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)" + +# Insert data +orama db query my-database "INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com')" + +# Query data +orama db query my-database "SELECT * FROM users" + +# Output: +# 📊 Query Result +# Rows: 1 +# +# id | name | email +# ----------------+-----------------+------------------------- +# 1 | Alice | alice@example.com +``` + +### Listing Databases + +```bash +orama db list + +# Output: +# NAME SIZE HOME NODE CREATED +# my-database 12.3 KB node-abc123 2024-01-22 10:30 +# prod-database 1.2 MB node-abc123 2024-01-20 09:15 +# +# Total: 2 +``` + +### Backing Up to IPFS + +```bash +# Create a backup +orama db backup my-database + +# Output: +# ✅ Backup created +# CID: QmYxxx... +# Size: 12.3 KB + +# List backups +orama db backups my-database + +# Output: +# VERSION CID SIZE DATE +# 1 QmYxxx... 12.3 KB 2024-01-22 10:45 +# 2 QmZxxx... 15.1 KB 2024-01-22 14:20 +``` + +### Database Features + +- ✅ **WAL Mode**: Write-Ahead Logging for better concurrency +- ✅ **Namespace Isolation**: Complete separation between namespaces +- ✅ **Automatic Backups**: Scheduled backups to IPFS every 6 hours +- ✅ **ACID Transactions**: Full SQLite transactional support +- ✅ **Concurrent Reads**: Multiple readers can query simultaneously + +--- + +## How Domains Work + +### Domain Assignment + +When you deploy an application, it automatically gets a domain: + +``` +Format: {deployment-name}.orama.network +Example: my-react-app.orama.network +``` + +### Node-Specific Domains (Optional) + +For direct access to a specific node: + +``` +Format: {deployment-name}.{node-id}.orama.network +Example: my-react-app.node-7prvNa.orama.network +``` + +### DNS Resolution Flow + +1. **Client**: Browser requests `my-react-app.orama.network` +2. **DNS**: CoreDNS server queries RQLite for DNS record +3. **Record**: Returns IP address of a gateway node +4. **Gateway**: Receives request with `Host: my-react-app.orama.network` header +5. **Routing**: Domain routing middleware looks up deployment by domain +6. **Response**: + - **Static**: Serves content from IPFS + - **Dynamic**: Reverse proxies to the app's local port + +### Custom Domains (Future Feature) + +Support for custom domains (e.g., `www.myapp.com`) with TXT record verification. + +--- + +## Full-Stack Application Example + +Deploy a complete full-stack application with React frontend, Go backend, and SQLite database. + +### Architecture + +``` +┌─────────────────────────────────────────────┐ +│ React Frontend (Static) │ +│ Domain: myapp.orama.network │ +│ Deployed to IPFS │ +└─────────────────┬───────────────────────────┘ + │ + │ API Calls + ▼ +┌─────────────────────────────────────────────┐ +│ Go Backend (Dynamic) │ +│ Domain: myapp-api.orama.network │ +│ Port: 10100 │ +│ Systemd Service │ +└─────────────────┬───────────────────────────┘ + │ + │ SQL Queries + ▼ +┌─────────────────────────────────────────────┐ +│ SQLite Database │ +│ Name: myapp-db │ +│ File: ~/.orama/data/sqlite/ns/myapp-db.db│ +└─────────────────────────────────────────────┘ +``` + +### Step 1: Create the Database + +```bash +# Create database +orama db create myapp-db + +# Create schema +orama db query myapp-db "CREATE TABLE users ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + email TEXT UNIQUE NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +)" + +# Insert test data +orama db query myapp-db "INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com')" +``` + +### Step 2: Deploy Go Backend + +**Backend Code** (`main.go`): + +```go +package main + +import ( + "database/sql" + "encoding/json" + "log" + "net/http" + "os" + + _ "github.com/mattn/go-sqlite3" +) + +type User struct { + ID int `json:"id"` + Name string `json:"name"` + Email string `json:"email"` + CreatedAt string `json:"created_at"` +} + +var db *sql.DB + +func main() { + // DATABASE_NAME env var is automatically set by Orama + dbPath := os.Getenv("DATABASE_PATH") + if dbPath == "" { + dbPath = "/home/debros/.orama/data/sqlite/" + os.Getenv("NAMESPACE") + "/myapp-db.db" + } + + var err error + db, err = sql.Open("sqlite3", dbPath) + if err != nil { + log.Fatal(err) + } + defer db.Close() + + port := os.Getenv("PORT") + if port == "" { + port = "8080" + } + + // CORS middleware + http.HandleFunc("/", corsMiddleware(routes)) + + log.Printf("Starting server on port %s", port) + log.Fatal(http.ListenAndServe(":"+port, nil)) +} + +func routes(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/health": + json.NewEncoder(w).Encode(map[string]string{"status": "healthy"}) + case "/api/users": + if r.Method == "GET" { + getUsers(w, r) + } else if r.Method == "POST" { + createUser(w, r) + } + default: + http.NotFound(w, r) + } +} + +func getUsers(w http.ResponseWriter, r *http.Request) { + rows, err := db.Query("SELECT id, name, email, created_at FROM users ORDER BY id") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer rows.Close() + + var users []User + for rows.Next() { + var u User + rows.Scan(&u.ID, &u.Name, &u.Email, &u.CreatedAt) + users = append(users, u) + } + + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode(users) +} + +func createUser(w http.ResponseWriter, r *http.Request) { + var u User + if err := json.NewDecoder(r.Body).Decode(&u); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + result, err := db.Exec("INSERT INTO users (name, email) VALUES (?, ?)", u.Name, u.Email) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + id, _ := result.LastInsertId() + u.ID = int(id) + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) + json.NewEncoder(w).Encode(u) +} + +func corsMiddleware(next http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") + + if r.Method == "OPTIONS" { + w.WriteHeader(http.StatusOK) + return + } + + next(w, r) + } +} +``` + +**Deploy Backend**: + +```bash +# Build for Linux +GOOS=linux GOARCH=amd64 go build -o api main.go + +# Deploy +orama deploy go ./api --name myapp-api +``` + +### Step 3: Deploy React Frontend + +**Frontend Code** (`src/App.jsx`): + +```jsx +import { useEffect, useState } from 'react'; + +function App() { + const [users, setUsers] = useState([]); + const [name, setName] = useState(''); + const [email, setEmail] = useState(''); + + const API_URL = 'https://myapp-api.orama.network'; + + useEffect(() => { + fetchUsers(); + }, []); + + const fetchUsers = async () => { + const response = await fetch(`${API_URL}/api/users`); + const data = await response.json(); + setUsers(data); + }; + + const addUser = async (e) => { + e.preventDefault(); + await fetch(`${API_URL}/api/users`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name, email }), + }); + setName(''); + setEmail(''); + fetchUsers(); + }; + + return ( +
+

Orama Network Full-Stack App

+ +

Add User

+
+ setName(e.target.value)} + placeholder="Name" + required + /> + setEmail(e.target.value)} + placeholder="Email" + type="email" + required + /> + +
+ +

Users

+
    + {users.map((user) => ( +
  • + {user.name} - {user.email} +
  • + ))} +
+
+ ); +} + +export default App; +``` + +**Deploy Frontend**: + +```bash +# Build +npm run build + +# Deploy +orama deploy static ./dist --name myapp +``` + +### Step 4: Access Your App + +Open your browser to: +- **Frontend**: `https://myapp.orama.network` +- **Backend API**: `https://myapp-api.orama.network/api/users` + +### Full-Stack Summary + +✅ **Frontend**: React app served from IPFS +✅ **Backend**: Go API running on allocated port +✅ **Database**: SQLite database with ACID transactions +✅ **Domains**: Automatic DNS for both services +✅ **Isolated**: All resources namespaced and secure + +--- + +## Managing Deployments + +### List All Deployments + +```bash +orama deployments list + +# Output: +# NAME TYPE STATUS VERSION CREATED +# my-react-app static active 1 2024-01-22 10:30 +# myapp-api go active 1 2024-01-22 10:45 +# my-nextjs nextjs active 2 2024-01-22 11:00 +# +# Total: 3 +``` + +### Get Deployment Details + +```bash +orama deployments get my-react-app + +# Output: +# Deployment: my-react-app +# +# ID: dep-abc123 +# Type: static +# Status: active +# Version: 1 +# Namespace: your-namespace +# Content CID: QmXxxx... +# Memory Limit: 256 MB +# CPU Limit: 50% +# Restart Policy: always +# +# URLs: +# • https://my-react-app.orama.network +# +# Created: 2024-01-22T10:30:00Z +# Updated: 2024-01-22T10:30:00Z +``` + +### View Logs + +```bash +# View last 100 lines +orama deployments logs my-nextjs + +# Follow logs in real-time +orama deployments logs my-nextjs --follow +``` + +### Rollback to Previous Version + +```bash +# Rollback to version 1 +orama deployments rollback my-nextjs --version 1 + +# Output: +# ⚠️ Rolling back 'my-nextjs' to version 1. Continue? (y/N): y +# +# ✅ Rollback successful! +# +# Deployment: my-nextjs +# Current Version: 1 +# Rolled Back From: 2 +# Rolled Back To: 1 +# Status: active +``` + +### Delete Deployment + +```bash +orama deployments delete my-old-app + +# Output: +# ⚠️ Are you sure you want to delete deployment 'my-old-app'? (y/N): y +# +# ✅ Deployment 'my-old-app' deleted successfully +``` + +--- + +## Troubleshooting + +### Deployment Issues + +**Problem**: Deployment status is "failed" + +```bash +# Check deployment details +orama deployments get my-app + +# View logs for errors +orama deployments logs my-app + +# Common issues: +# - Binary not compiled for Linux (GOOS=linux GOARCH=amd64) +# - Missing dependencies (node_modules not included) +# - Port already in use (shouldn't happen, but check logs) +# - Health check failing (ensure /health endpoint exists) +``` + +**Problem**: Can't access deployment URL + +```bash +# 1. Check deployment status +orama deployments get my-app + +# 2. Verify DNS (may take up to 10 seconds to propagate) +dig my-app.orama.network + +# 3. For local development, add to /etc/hosts +echo "127.0.0.1 my-app.orama.network" | sudo tee -a /etc/hosts + +# 4. Test with Host header +curl -H "Host: my-app.orama.network" http://localhost:6001/ +``` + +### Database Issues + +**Problem**: Database not found + +```bash +# List all databases +orama db list + +# Ensure database name matches exactly (case-sensitive) +# Databases are namespace-isolated +``` + +**Problem**: SQL query fails + +```bash +# Check table exists +orama db query my-db "SELECT name FROM sqlite_master WHERE type='table'" + +# Check syntax +orama db query my-db ".schema users" +``` + +### Authentication Issues + +```bash +# Re-authenticate +orama auth logout +orama auth login + +# Check token validity +orama auth status +``` + +### Need Help? + +- **Documentation**: Check `/docs` directory +- **Logs**: Gateway logs at `~/.orama/logs/gateway.log` +- **Issues**: Report bugs at GitHub repository +- **Community**: Join our Discord/Telegram + +--- + +## Best Practices + +### Security + +1. **Never commit sensitive data**: Use environment variables for secrets +2. **Validate inputs**: Always sanitize user input in your backend +3. **HTTPS only**: All deployments automatically use HTTPS in production +4. **CORS**: Configure CORS appropriately for your API + +### Performance + +1. **Optimize builds**: Minimize bundle sizes (React, Next.js) +2. **Use caching**: Leverage browser caching for static assets +3. **Database indexes**: Add indexes to frequently queried columns +4. **Health checks**: Implement `/health` endpoint for monitoring + +### Deployment Workflow + +1. **Test locally first**: Ensure your app works before deploying +2. **Use version control**: Track changes in Git +3. **Incremental updates**: Use `--update` flag instead of delete + redeploy +4. **Backup databases**: Regular backups via `orama db backup` +5. **Monitor logs**: Check logs after deployment for errors + +--- + +## Next Steps + +- **Explore the API**: See `/docs/GATEWAY_API.md` for HTTP API details +- **Advanced Features**: Custom domains, load balancing, autoscaling (coming soon) +- **Production Deployment**: Install nodes with `orama install` for production clusters +- **Client SDK**: Use the Go/JS SDK for programmatic deployments + +--- + +**Orama Network** - Decentralized Application Platform + +Deploy anywhere. Access everywhere. Own everything. diff --git a/docs/GATEWAY_API.md b/docs/GATEWAY_API.md deleted file mode 100644 index 54f6bc7..0000000 --- a/docs/GATEWAY_API.md +++ /dev/null @@ -1,734 +0,0 @@ -# Gateway API Documentation - -## Overview - -The Orama Network Gateway provides a unified HTTP/HTTPS API for all network services. It handles authentication, routing, and service coordination. - -**Base URL:** `https://api.orama.network` (production) or `http://localhost:6001` (development) - -## Authentication - -All API requests (except `/health` and `/v1/auth/*`) require authentication. - -### Authentication Methods - -1. **API Key** (Recommended for server-to-server) -2. **JWT Token** (Recommended for user sessions) -3. **Wallet Signature** (For blockchain integration) - -### Using API Keys - -Include your API key in the `Authorization` header: - -```bash -curl -H "Authorization: Bearer your-api-key-here" \ - https://api.orama.network/v1/status -``` - -Or in the `X-API-Key` header: - -```bash -curl -H "X-API-Key: your-api-key-here" \ - https://api.orama.network/v1/status -``` - -### Using JWT Tokens - -```bash -curl -H "Authorization: Bearer your-jwt-token-here" \ - https://api.orama.network/v1/status -``` - -## Base Endpoints - -### Health Check - -```http -GET /health -``` - -**Response:** -```json -{ - "status": "ok", - "timestamp": "2024-01-20T10:30:00Z" -} -``` - -### Status - -```http -GET /v1/status -``` - -**Response:** -```json -{ - "version": "0.80.0", - "uptime": "24h30m15s", - "services": { - "rqlite": "healthy", - "ipfs": "healthy", - "olric": "healthy" - } -} -``` - -### Version - -```http -GET /v1/version -``` - -**Response:** -```json -{ - "version": "0.80.0", - "commit": "abc123...", - "built": "2024-01-20T00:00:00Z" -} -``` - -## Authentication API - -### Get Challenge (Wallet Auth) - -Generate a nonce for wallet signature. - -```http -POST /v1/auth/challenge -Content-Type: application/json - -{ - "wallet": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", - "purpose": "login", - "namespace": "default" -} -``` - -**Response:** -```json -{ - "wallet": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", - "namespace": "default", - "nonce": "a1b2c3d4e5f6...", - "purpose": "login", - "expires_at": "2024-01-20T10:35:00Z" -} -``` - -### Verify Signature - -Verify wallet signature and issue JWT + API key. - -```http -POST /v1/auth/verify -Content-Type: application/json - -{ - "wallet": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", - "signature": "0x...", - "nonce": "a1b2c3d4e5f6...", - "namespace": "default" -} -``` - -**Response:** -```json -{ - "jwt_token": "eyJhbGciOiJIUzI1NiIs...", - "refresh_token": "refresh_abc123...", - "api_key": "api_xyz789...", - "expires_in": 900, - "namespace": "default" -} -``` - -### Refresh Token - -Refresh an expired JWT token. - -```http -POST /v1/auth/refresh -Content-Type: application/json - -{ - "refresh_token": "refresh_abc123..." -} -``` - -**Response:** -```json -{ - "jwt_token": "eyJhbGciOiJIUzI1NiIs...", - "expires_in": 900 -} -``` - -### Logout - -Revoke refresh tokens. - -```http -POST /v1/auth/logout -Authorization: Bearer your-jwt-token - -{ - "all": false -} -``` - -**Response:** -```json -{ - "message": "logged out successfully" -} -``` - -### Whoami - -Get current authentication info. - -```http -GET /v1/auth/whoami -Authorization: Bearer your-api-key -``` - -**Response:** -```json -{ - "authenticated": true, - "method": "api_key", - "api_key": "api_xyz789...", - "namespace": "default" -} -``` - -## Storage API (IPFS) - -### Upload File - -```http -POST /v1/storage/upload -Authorization: Bearer your-api-key -Content-Type: multipart/form-data - -file: -``` - -Or with JSON: - -```http -POST /v1/storage/upload -Authorization: Bearer your-api-key -Content-Type: application/json - -{ - "data": "base64-encoded-data", - "filename": "document.pdf", - "pin": true, - "encrypt": false -} -``` - -**Response:** -```json -{ - "cid": "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG", - "size": 1024, - "filename": "document.pdf" -} -``` - -### Get File - -```http -GET /v1/storage/get/:cid -Authorization: Bearer your-api-key -``` - -**Response:** Binary file data or JSON (if `Accept: application/json`) - -### Pin File - -```http -POST /v1/storage/pin -Authorization: Bearer your-api-key -Content-Type: application/json - -{ - "cid": "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG", - "replication_factor": 3 -} -``` - -**Response:** -```json -{ - "cid": "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG", - "status": "pinned" -} -``` - -### Unpin File - -```http -DELETE /v1/storage/unpin/:cid -Authorization: Bearer your-api-key -``` - -**Response:** -```json -{ - "message": "unpinned successfully" -} -``` - -### Get Pin Status - -```http -GET /v1/storage/status/:cid -Authorization: Bearer your-api-key -``` - -**Response:** -```json -{ - "cid": "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG", - "status": "pinned", - "replicas": 3, - "peers": ["12D3KooW...", "12D3KooW..."] -} -``` - -## Cache API (Olric) - -### Set Value - -```http -PUT /v1/cache/put -Authorization: Bearer your-api-key -Content-Type: application/json - -{ - "key": "user:123", - "value": {"name": "Alice", "email": "alice@example.com"}, - "ttl": 300 -} -``` - -**Response:** -```json -{ - "message": "value set successfully" -} -``` - -### Get Value - -```http -GET /v1/cache/get?key=user:123 -Authorization: Bearer your-api-key -``` - -**Response:** -```json -{ - "key": "user:123", - "value": {"name": "Alice", "email": "alice@example.com"} -} -``` - -### Get Multiple Values - -```http -POST /v1/cache/mget -Authorization: Bearer your-api-key -Content-Type: application/json - -{ - "keys": ["user:1", "user:2", "user:3"] -} -``` - -**Response:** -```json -{ - "results": { - "user:1": {"name": "Alice"}, - "user:2": {"name": "Bob"}, - "user:3": null - } -} -``` - -### Delete Value - -```http -DELETE /v1/cache/delete?key=user:123 -Authorization: Bearer your-api-key -``` - -**Response:** -```json -{ - "message": "deleted successfully" -} -``` - -### Scan Keys - -```http -GET /v1/cache/scan?pattern=user:*&limit=100 -Authorization: Bearer your-api-key -``` - -**Response:** -```json -{ - "keys": ["user:1", "user:2", "user:3"], - "count": 3 -} -``` - -## Database API (RQLite) - -### Execute SQL - -```http -POST /v1/rqlite/exec -Authorization: Bearer your-api-key -Content-Type: application/json - -{ - "sql": "INSERT INTO users (name, email) VALUES (?, ?)", - "args": ["Alice", "alice@example.com"] -} -``` - -**Response:** -```json -{ - "last_insert_id": 123, - "rows_affected": 1 -} -``` - -### Query SQL - -```http -POST /v1/rqlite/query -Authorization: Bearer your-api-key -Content-Type: application/json - -{ - "sql": "SELECT * FROM users WHERE id = ?", - "args": [123] -} -``` - -**Response:** -```json -{ - "columns": ["id", "name", "email"], - "rows": [ - [123, "Alice", "alice@example.com"] - ] -} -``` - -### Get Schema - -```http -GET /v1/rqlite/schema -Authorization: Bearer your-api-key -``` - -**Response:** -```json -{ - "tables": [ - { - "name": "users", - "schema": "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)" - } - ] -} -``` - -## Pub/Sub API - -### Publish Message - -```http -POST /v1/pubsub/publish -Authorization: Bearer your-api-key -Content-Type: application/json - -{ - "topic": "chat", - "data": "SGVsbG8sIFdvcmxkIQ==", - "namespace": "default" -} -``` - -**Response:** -```json -{ - "message": "published successfully" -} -``` - -### List Topics - -```http -GET /v1/pubsub/topics -Authorization: Bearer your-api-key -``` - -**Response:** -```json -{ - "topics": ["chat", "notifications", "events"] -} -``` - -### Subscribe (WebSocket) - -```http -GET /v1/pubsub/ws?topic=chat -Authorization: Bearer your-api-key -Upgrade: websocket -``` - -**WebSocket Messages:** - -Incoming (from server): -```json -{ - "type": "message", - "topic": "chat", - "data": "SGVsbG8sIFdvcmxkIQ==", - "timestamp": "2024-01-20T10:30:00Z" -} -``` - -Outgoing (to server): -```json -{ - "type": "publish", - "topic": "chat", - "data": "SGVsbG8sIFdvcmxkIQ==" -} -``` - -### Presence - -```http -GET /v1/pubsub/presence?topic=chat -Authorization: Bearer your-api-key -``` - -**Response:** -```json -{ - "topic": "chat", - "members": [ - {"id": "user-123", "joined_at": "2024-01-20T10:00:00Z"}, - {"id": "user-456", "joined_at": "2024-01-20T10:15:00Z"} - ] -} -``` - -## Serverless API (WASM) - -### Deploy Function - -```http -POST /v1/functions -Authorization: Bearer your-api-key -Content-Type: multipart/form-data - -name: hello-world -namespace: default -description: Hello world function -wasm: -memory_limit: 64 -timeout: 30 -``` - -**Response:** -```json -{ - "id": "fn_abc123", - "name": "hello-world", - "namespace": "default", - "wasm_cid": "QmXxx...", - "version": 1, - "created_at": "2024-01-20T10:30:00Z" -} -``` - -### Invoke Function - -```http -POST /v1/functions/hello-world/invoke -Authorization: Bearer your-api-key -Content-Type: application/json - -{ - "name": "Alice" -} -``` - -**Response:** -```json -{ - "result": "Hello, Alice!", - "execution_time_ms": 15, - "memory_used_mb": 2.5 -} -``` - -### List Functions - -```http -GET /v1/functions?namespace=default -Authorization: Bearer your-api-key -``` - -**Response:** -```json -{ - "functions": [ - { - "name": "hello-world", - "description": "Hello world function", - "version": 1, - "created_at": "2024-01-20T10:30:00Z" - } - ] -} -``` - -### Delete Function - -```http -DELETE /v1/functions/hello-world?namespace=default -Authorization: Bearer your-api-key -``` - -**Response:** -```json -{ - "message": "function deleted successfully" -} -``` - -### Get Function Logs - -```http -GET /v1/functions/hello-world/logs?limit=100 -Authorization: Bearer your-api-key -``` - -**Response:** -```json -{ - "logs": [ - { - "timestamp": "2024-01-20T10:30:00Z", - "level": "info", - "message": "Function invoked", - "invocation_id": "inv_xyz789" - } - ] -} -``` - -## Error Responses - -All errors follow a consistent format: - -```json -{ - "code": "NOT_FOUND", - "message": "user with ID '123' not found", - "details": { - "resource": "user", - "id": "123" - }, - "trace_id": "trace-abc123" -} -``` - -### Common Error Codes - -| Code | HTTP Status | Description | -|------|-------------|-------------| -| `VALIDATION_ERROR` | 400 | Invalid input | -| `UNAUTHORIZED` | 401 | Authentication required | -| `FORBIDDEN` | 403 | Permission denied | -| `NOT_FOUND` | 404 | Resource not found | -| `CONFLICT` | 409 | Resource already exists | -| `TIMEOUT` | 408 | Operation timeout | -| `RATE_LIMIT_EXCEEDED` | 429 | Too many requests | -| `SERVICE_UNAVAILABLE` | 503 | Service unavailable | -| `INTERNAL` | 500 | Internal server error | - -## Rate Limiting - -The API implements rate limiting per API key: - -- **Default:** 100 requests per minute -- **Burst:** 200 requests - -Rate limit headers: -``` -X-RateLimit-Limit: 100 -X-RateLimit-Remaining: 95 -X-RateLimit-Reset: 1611144000 -``` - -When rate limited: -```json -{ - "code": "RATE_LIMIT_EXCEEDED", - "message": "rate limit exceeded", - "details": { - "limit": 100, - "retry_after": 60 - } -} -``` - -## Pagination - -List endpoints support pagination: - -```http -GET /v1/functions?limit=10&offset=20 -``` - -Response includes pagination metadata: -```json -{ - "data": [...], - "pagination": { - "total": 100, - "limit": 10, - "offset": 20, - "has_more": true - } -} -``` - -## Webhooks (Future) - -Coming soon: webhook support for event notifications. - -## Support - -- API Issues: https://github.com/DeBrosOfficial/network/issues -- OpenAPI Spec: `openapi/gateway.yaml` -- SDK Documentation: `docs/CLIENT_SDK.md` diff --git a/docs/SECURITY_DEPLOYMENT_GUIDE.md b/docs/SECURITY_DEPLOYMENT_GUIDE.md deleted file mode 100644 index f51cd03..0000000 --- a/docs/SECURITY_DEPLOYMENT_GUIDE.md +++ /dev/null @@ -1,476 +0,0 @@ -# Orama Network - Security Deployment Guide - -**Date:** January 18, 2026 -**Status:** Production-Ready -**Audit Completed By:** Claude Code Security Audit - ---- - -## Executive Summary - -This document outlines the security hardening measures applied to the 4-node Orama Network production cluster. All critical vulnerabilities identified in the security audit have been addressed. - -**Security Status:** ✅ SECURED FOR PRODUCTION - ---- - -## Server Inventory - -| Server ID | IP Address | Domain | OS | Role | -|-----------|------------|--------|-----|------| -| VPS 1 | 51.83.128.181 | node-kv4la8.debros.network | Ubuntu 22.04 | Gateway + Cluster Node | -| VPS 2 | 194.61.28.7 | node-7prvNa.debros.network | Ubuntu 24.04 | Gateway + Cluster Node | -| VPS 3 | 83.171.248.66 | node-xn23dq.debros.network | Ubuntu 24.04 | Gateway + Cluster Node | -| VPS 4 | 62.72.44.87 | node-nns4n5.debros.network | Ubuntu 24.04 | Gateway + Cluster Node | - ---- - -## Services Running on Each Server - -| Service | Port(s) | Purpose | Public Access | -|---------|---------|---------|---------------| -| **orama-node** | 80, 443, 7001 | API Gateway | Yes (80, 443 only) | -| **rqlited** | 5001, 7002 | Distributed SQLite DB | Cluster only | -| **ipfs** | 4101, 4501, 8080 | Content-addressed storage | Cluster only | -| **ipfs-cluster** | 9094, 9098 | IPFS cluster management | Cluster only | -| **olric-server** | 3320, 3322 | Distributed cache | Cluster only | -| **anon** (Anyone proxy) | 9001, 9050, 9051 | Anonymity proxy | Cluster only | -| **libp2p** | 4001 | P2P networking | Yes (public P2P) | -| **SSH** | 22 | Remote access | Yes | - ---- - -## Security Measures Implemented - -### 1. Firewall Configuration (UFW) - -**Status:** ✅ Enabled on all 4 servers - -#### Public Ports (Open to Internet) -- **22/tcp** - SSH (with hardening) -- **80/tcp** - HTTP (redirects to HTTPS) -- **443/tcp** - HTTPS (Let's Encrypt production certificates) -- **4001/tcp** - libp2p swarm (P2P networking) - -#### Cluster-Only Ports (Restricted to 4 Server IPs) -All the following ports are ONLY accessible from the 4 cluster IPs: -- **5001/tcp** - rqlite HTTP API -- **7001/tcp** - SNI Gateway -- **7002/tcp** - rqlite Raft consensus -- **9094/tcp** - IPFS Cluster API -- **9098/tcp** - IPFS Cluster communication -- **3322/tcp** - Olric distributed cache -- **4101/tcp** - IPFS swarm (cluster internal) - -#### Firewall Rules Example -```bash -sudo ufw default deny incoming -sudo ufw default allow outgoing -sudo ufw allow 22/tcp comment "SSH" -sudo ufw allow 80/tcp comment "HTTP" -sudo ufw allow 443/tcp comment "HTTPS" -sudo ufw allow 4001/tcp comment "libp2p swarm" - -# Cluster-only access for sensitive services -sudo ufw allow from 51.83.128.181 to any port 5001 proto tcp -sudo ufw allow from 194.61.28.7 to any port 5001 proto tcp -sudo ufw allow from 83.171.248.66 to any port 5001 proto tcp -sudo ufw allow from 62.72.44.87 to any port 5001 proto tcp -# (repeat for ports 7001, 7002, 9094, 9098, 3322, 4101) - -sudo ufw enable -``` - -### 2. SSH Hardening - -**Location:** `/etc/ssh/sshd_config.d/99-hardening.conf` - -**Configuration:** -```bash -PermitRootLogin yes # Root login allowed with SSH keys -PasswordAuthentication yes # Password auth enabled (you have keys configured) -PubkeyAuthentication yes # SSH key authentication enabled -PermitEmptyPasswords no # No empty passwords -X11Forwarding no # X11 disabled for security -MaxAuthTries 3 # Max 3 login attempts -ClientAliveInterval 300 # Keep-alive every 5 minutes -ClientAliveCountMax 2 # Disconnect after 2 failed keep-alives -``` - -**Your SSH Keys Added:** -- ✅ `ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPcGZPX2iHXWO8tuyyDkHPS5eByPOktkw3+ugcw79yQO` -- ✅ `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDgCWmycaBN3aAZJcM2w4+Xi2zrTwN78W8oAiQywvMEkubqNNWHF6I3...` - -Both keys are installed on all 4 servers in: -- VPS 1: `/home/ubuntu/.ssh/authorized_keys` -- VPS 2, 3, 4: `/root/.ssh/authorized_keys` - -### 3. Fail2ban Protection - -**Status:** ✅ Installed and running on all 4 servers - -**Purpose:** Automatically bans IPs after failed SSH login attempts - -**Check Status:** -```bash -sudo systemctl status fail2ban -``` - -### 4. Security Updates - -**Status:** ✅ All security updates applied (as of Jan 18, 2026) - -**Update Command:** -```bash -sudo apt update && sudo apt upgrade -y -``` - -### 5. Let's Encrypt TLS Certificates - -**Status:** ✅ Production certificates (NOT staging) - -**Configuration:** -- **Provider:** Let's Encrypt (ACME v2 Production) -- **Auto-renewal:** Enabled via autocert -- **Cache Directory:** `/home/debros/.orama/tls-cache/` -- **Domains:** - - node-kv4la8.debros.network (VPS 1) - - node-7prvNa.debros.network (VPS 2) - - node-xn23dq.debros.network (VPS 3) - - node-nns4n5.debros.network (VPS 4) - -**Certificate Files:** -- Account key: `/home/debros/.orama/tls-cache/acme_account+key` -- Certificates auto-managed by autocert - -**Verification:** -```bash -curl -I https://node-kv4la8.debros.network -# Should return valid SSL certificate -``` - ---- - -## Cluster Configuration - -### RQLite Cluster - -**Nodes:** -- 51.83.128.181:7002 (Leader) -- 194.61.28.7:7002 -- 83.171.248.66:7002 -- 62.72.44.87:7002 - -**Test Cluster Health:** -```bash -ssh ubuntu@51.83.128.181 -curl -s http://localhost:5001/status | jq '.store.nodes' -``` - -**Expected Output:** -```json -[ - {"id":"194.61.28.7:7002","addr":"194.61.28.7:7002","suffrage":"Voter"}, - {"id":"51.83.128.181:7002","addr":"51.83.128.181:7002","suffrage":"Voter"}, - {"id":"62.72.44.87:7002","addr":"62.72.44.87:7002","suffrage":"Voter"}, - {"id":"83.171.248.66:7002","addr":"83.171.248.66:7002","suffrage":"Voter"} -] -``` - -### IPFS Cluster - -**Test Cluster Health:** -```bash -ssh ubuntu@51.83.128.181 -curl -s http://localhost:9094/id | jq '.cluster_peers' -``` - -**Expected:** All 4 peer IDs listed - -### Olric Cache Cluster - -**Port:** 3320 (localhost), 3322 (cluster communication) - -**Test:** -```bash -ssh ubuntu@51.83.128.181 -ss -tulpn | grep olric -``` - ---- - -## Access Credentials - -### SSH Access - -**VPS 1:** -```bash -ssh ubuntu@51.83.128.181 -# OR using your SSH key: -ssh -i ~/.ssh/ssh-sotiris/id_ed25519 ubuntu@51.83.128.181 -``` - -**VPS 2, 3, 4:** -```bash -ssh root@194.61.28.7 -ssh root@83.171.248.66 -ssh root@62.72.44.87 -``` - -**Important:** Password authentication is still enabled, but your SSH keys are configured for passwordless access. - ---- - -## Testing & Verification - -### 1. Test External Port Access (From Your Machine) - -```bash -# These should be BLOCKED (timeout or connection refused): -nc -zv 51.83.128.181 5001 # rqlite API - should be blocked -nc -zv 51.83.128.181 7002 # rqlite Raft - should be blocked -nc -zv 51.83.128.181 9094 # IPFS cluster - should be blocked - -# These should be OPEN: -nc -zv 51.83.128.181 22 # SSH - should succeed -nc -zv 51.83.128.181 80 # HTTP - should succeed -nc -zv 51.83.128.181 443 # HTTPS - should succeed -nc -zv 51.83.128.181 4001 # libp2p - should succeed -``` - -### 2. Test Domain Access - -```bash -curl -I https://node-kv4la8.debros.network -curl -I https://node-7prvNa.debros.network -curl -I https://node-xn23dq.debros.network -curl -I https://node-nns4n5.debros.network -``` - -All should return `HTTP/1.1 200 OK` or similar with valid SSL certificates. - -### 3. Test Cluster Communication (From VPS 1) - -```bash -ssh ubuntu@51.83.128.181 -# Test rqlite cluster -curl -s http://localhost:5001/status | jq -r '.store.nodes[].id' - -# Test IPFS cluster -curl -s http://localhost:9094/id | jq -r '.cluster_peers[]' - -# Check all services running -ps aux | grep -E "(orama-node|rqlited|ipfs|olric)" | grep -v grep -``` - ---- - -## Maintenance & Operations - -### Firewall Management - -**View current rules:** -```bash -sudo ufw status numbered -``` - -**Add a new allowed IP for cluster services:** -```bash -sudo ufw allow from NEW_IP_ADDRESS to any port 5001 proto tcp -sudo ufw allow from NEW_IP_ADDRESS to any port 7002 proto tcp -# etc. -``` - -**Delete a rule:** -```bash -sudo ufw status numbered # Get rule number -sudo ufw delete [NUMBER] -``` - -### SSH Management - -**Test SSH config without applying:** -```bash -sudo sshd -t -``` - -**Reload SSH after config changes:** -```bash -sudo systemctl reload ssh -``` - -**View SSH login attempts:** -```bash -sudo journalctl -u ssh | tail -50 -``` - -### Fail2ban Management - -**Check banned IPs:** -```bash -sudo fail2ban-client status sshd -``` - -**Unban an IP:** -```bash -sudo fail2ban-client set sshd unbanip IP_ADDRESS -``` - -### Security Updates - -**Check for updates:** -```bash -apt list --upgradable -``` - -**Apply updates:** -```bash -sudo apt update && sudo apt upgrade -y -``` - -**Reboot if kernel updated:** -```bash -sudo reboot -``` - ---- - -## Security Improvements Completed - -### Before Security Audit: -- ❌ No firewall enabled -- ❌ rqlite database exposed to internet (port 5001, 7002) -- ❌ IPFS cluster management exposed (port 9094, 9098) -- ❌ Olric cache exposed (port 3322) -- ❌ Root login enabled without restrictions (VPS 2, 3, 4) -- ❌ No fail2ban on 3 out of 4 servers -- ❌ 19-39 security updates pending - -### After Security Hardening: -- ✅ UFW firewall enabled on all servers -- ✅ Sensitive ports restricted to cluster IPs only -- ✅ SSH hardened with key authentication -- ✅ Fail2ban protecting all servers -- ✅ All security updates applied -- ✅ Let's Encrypt production certificates verified -- ✅ Cluster communication tested and working -- ✅ External access verified (HTTP/HTTPS only) - ---- - -## Recommended Next Steps (Optional) - -These were not implemented per your request but are recommended for future consideration: - -1. **VPN/Private Networking** - Use WireGuard or Tailscale for encrypted cluster communication instead of firewall rules -2. **Automated Security Updates** - Enable unattended-upgrades for automatic security patches -3. **Monitoring & Alerting** - Set up Prometheus/Grafana for service monitoring -4. **Regular Security Audits** - Run `lynis` or `rkhunter` monthly for security checks - ---- - -## Important Notes - -### Let's Encrypt Configuration - -The Orama Network gateway uses **autocert** from Go's `golang.org/x/crypto/acme/autocert` package. The configuration is in: - -**File:** `/home/debros/.orama/configs/node.yaml` - -**Relevant settings:** -```yaml -http_gateway: - https: - enabled: true - domain: "node-kv4la8.debros.network" - auto_cert: true - cache_dir: "/home/debros/.orama/tls-cache" - http_port: 80 - https_port: 443 - email: "admin@node-kv4la8.debros.network" -``` - -**Important:** There is NO `letsencrypt_staging` flag set, which means it defaults to **production Let's Encrypt**. This is correct for production deployment. - -### Firewall Persistence - -UFW rules are persistent across reboots. The firewall will automatically start on boot. - -### SSH Key Access - -Both of your SSH keys are configured on all servers. You can access: -- VPS 1: `ssh -i ~/.ssh/ssh-sotiris/id_ed25519 ubuntu@51.83.128.181` -- VPS 2-4: `ssh -i ~/.ssh/ssh-sotiris/id_ed25519 root@IP_ADDRESS` - -Password authentication is still enabled as a fallback, but keys are recommended. - ---- - -## Emergency Access - -If you get locked out: - -1. **VPS Provider Console:** All major VPS providers offer web-based console access -2. **Password Access:** Password auth is still enabled on all servers -3. **SSH Keys:** Two keys configured for redundancy - -**Disable firewall temporarily (emergency only):** -```bash -sudo ufw disable -# Fix the issue -sudo ufw enable -``` - ---- - -## Verification Checklist - -Use this checklist to verify the security hardening: - -- [ ] All 4 servers have UFW firewall enabled -- [ ] SSH is hardened (MaxAuthTries 3, X11Forwarding no) -- [ ] Your SSH keys work on all servers -- [ ] Fail2ban is running on all servers -- [ ] Security updates are current -- [ ] rqlite port 5001 is NOT accessible from internet -- [ ] rqlite port 7002 is NOT accessible from internet -- [ ] IPFS cluster ports 9094, 9098 are NOT accessible from internet -- [ ] Domains are accessible via HTTPS with valid certificates -- [ ] RQLite cluster shows all 4 nodes -- [ ] IPFS cluster shows all 4 peers -- [ ] All services are running (5 processes per server) - ---- - -## Contact & Support - -For issues or questions about this deployment: - -- **Security Audit Date:** January 18, 2026 -- **Configuration Files:** `/home/debros/.orama/configs/` -- **Firewall Rules:** `/etc/ufw/` -- **SSH Config:** `/etc/ssh/sshd_config.d/99-hardening.conf` -- **TLS Certs:** `/home/debros/.orama/tls-cache/` - ---- - -## Changelog - -### January 18, 2026 - Production Security Hardening - -**Changes:** -1. Added UFW firewall rules on all 4 VPS servers -2. Restricted sensitive ports (5001, 7002, 9094, 9098, 3322, 4101) to cluster IPs only -3. Hardened SSH configuration -4. Added your 2 SSH keys to all servers -5. Installed fail2ban on VPS 1, 2, 3 (VPS 4 already had it) -6. Applied all pending security updates (23-39 packages per server) -7. Verified Let's Encrypt is using production (not staging) -8. Tested all services: rqlite, IPFS, libp2p, Olric clusters -9. Verified all 4 domains are accessible via HTTPS - -**Result:** Production-ready secure deployment ✅ - ---- - -**END OF DEPLOYMENT GUIDE** diff --git a/docs/TESTING_PLAN.md b/docs/TESTING_PLAN.md deleted file mode 100644 index 1abdc3c..0000000 --- a/docs/TESTING_PLAN.md +++ /dev/null @@ -1,760 +0,0 @@ -# Comprehensive Testing Plan - -This document outlines the complete testing strategy for the namespace isolation and custom deployment system. - -## Table of Contents - -1. [Unit Tests](#unit-tests) -2. [Integration Tests](#integration-tests) -3. [End-to-End Tests](#end-to-end-tests) -4. [CLI Tests](#cli-tests) -5. [Performance Tests](#performance-tests) -6. [Security Tests](#security-tests) -7. [Chaos/Failure Tests](#chaos-failure-tests) - ---- - -## 1. Unit Tests - -### 1.1 Port Allocator Tests - -**File**: `pkg/deployments/port_allocator_test.go` - -**Test Cases**: -- ✅ Allocate first port (should be 10100) -- ✅ Allocate sequential ports -- ✅ Find gaps in allocation -- ✅ Handle port exhaustion (all 10000 ports used) -- ✅ Concurrent allocation with race detector -- ✅ Conflict retry with exponential backoff - -**Command**: -```bash -go test ./pkg/deployments -run TestPortAllocator -v -``` - -### 1.2 Home Node Manager Tests - -**File**: `pkg/deployments/home_node_test.go` - -**Test Cases**: -- ✅ Assign namespace to node with lowest load -- ✅ Reuse existing home node for namespace -- ✅ Weight calculation (deployments, ports, memory, CPU) -- ✅ Handle no nodes available -- ✅ Node failure detection and reassignment - -**Command**: -```bash -go test ./pkg/deployments -run TestHomeNodeManager -v -``` - -### 1.3 Health Checker Tests - -**File**: `pkg/deployments/health/checker_test.go` (needs to be created) - -**Test Cases**: -- Check static deployment (always healthy) -- Check dynamic deployment with health endpoint -- Mark as failed after 3 consecutive failures -- Record health check history -- Parallel health checking - -**Command**: -```bash -go test ./pkg/deployments/health -v -``` - -### 1.4 Process Manager Tests - -**File**: `pkg/deployments/process/manager_test.go` (needs to be created) - -**Test Cases**: -- Create systemd service file -- Start deployment process -- Stop deployment process -- Restart deployment -- Read logs from journalctl - -**Command**: -```bash -go test ./pkg/deployments/process -v -``` - -### 1.5 Deployment Service Tests - -**File**: `pkg/gateway/handlers/deployments/service_test.go` (needs to be created) - -**Test Cases**: -- Create deployment -- Get deployment by ID -- List deployments for namespace -- Update deployment -- Delete deployment -- Record deployment history - -**Command**: -```bash -go test ./pkg/gateway/handlers/deployments -v -``` - ---- - -## 2. Integration Tests - -### 2.1 Static Deployment Integration Test - -**File**: `tests/integration/static_deployment_test.go` (needs to be created) - -**Setup**: -- Start test RQLite instance -- Start test IPFS node -- Start test gateway - -**Test Flow**: -1. Upload static content tarball -2. Verify deployment created in database -3. Verify content uploaded to IPFS -4. Verify DNS record created -5. Test HTTP request to deployment domain -6. Verify content served correctly - -**Command**: -```bash -go test ./tests/integration -run TestStaticDeployment -v -``` - -### 2.2 Next.js SSR Deployment Integration Test - -**File**: `tests/integration/nextjs_deployment_test.go` (needs to be created) - -**Test Flow**: -1. Upload Next.js build -2. Verify systemd service created -3. Verify process started -4. Wait for health check to pass -5. Test HTTP request to deployment -6. Verify SSR response - -**Command**: -```bash -go test ./tests/integration -run TestNextJSDeployment -v -``` - -### 2.3 SQLite Database Integration Test - -**File**: `tests/integration/sqlite_test.go` (needs to be created) - -**Test Flow**: -1. Create SQLite database -2. Verify database file created on disk -3. Execute CREATE TABLE query -4. Execute INSERT query -5. Execute SELECT query -6. Backup database to IPFS -7. Verify backup CID recorded - -**Command**: -```bash -go test ./tests/integration -run TestSQLiteDatabase -v -``` - -### 2.4 Custom Domain Integration Test - -**File**: `tests/integration/custom_domain_test.go` (needs to be created) - -**Test Flow**: -1. Add custom domain to deployment -2. Verify TXT record verification token generated -3. Mock DNS TXT record lookup -4. Verify domain -5. Verify DNS A record created -6. Test HTTP request to custom domain - -**Command**: -```bash -go test ./tests/integration -run TestCustomDomain -v -``` - -### 2.5 Update and Rollback Integration Test - -**File**: `tests/integration/update_rollback_test.go` (needs to be created) - -**Test Flow**: -1. Deploy initial version -2. Update deployment with new content -3. Verify version incremented -4. Verify new content served -5. Rollback to previous version -6. Verify old content served -7. Verify history recorded correctly - -**Command**: -```bash -go test ./tests/integration -run TestUpdateRollback -v -``` - ---- - -## 3. End-to-End Tests - -### 3.1 Full Static Deployment E2E Test - -**File**: `tests/e2e/static_deployment_test.go` (needs to be created) - -**Prerequisites**: -- Running RQLite cluster -- Running IPFS cluster -- Running gateway instances -- CoreDNS configured - -**Test Flow**: -1. Create test React app -2. Build app (`npm run build`) -3. Deploy via CLI: `orama deploy static ./dist --name e2e-static` -4. Wait for deployment to be active -5. Resolve deployment domain via DNS -6. Make HTTPS request to deployment -7. Verify all static assets load correctly -8. Test SPA routing (fallback to index.html) -9. Update deployment -10. Verify zero-downtime update -11. Delete deployment -12. Verify cleanup - -**Command**: -```bash -go test ./tests/e2e -run TestStaticDeploymentE2E -v -timeout 10m -``` - -### 3.2 Full Next.js SSR Deployment E2E Test - -**File**: `tests/e2e/nextjs_deployment_test.go` (needs to be created) - -**Test Flow**: -1. Create test Next.js app with API routes -2. Build app (`npm run build`) -3. Deploy via CLI: `orama deploy nextjs . --name e2e-nextjs --ssr` -4. Wait for process to start and pass health check -5. Test static route -6. Test API route -7. Test SSR page -8. Update deployment with graceful restart -9. Verify health check before cutting over -10. Rollback if health check fails -11. Monitor logs during deployment -12. Delete deployment - -**Command**: -```bash -go test ./tests/e2e -run TestNextJSDeploymentE2E -v -timeout 15m -``` - -### 3.3 Full SQLite Database E2E Test - -**File**: `tests/e2e/sqlite_test.go` (needs to be created) - -**Test Flow**: -1. Create database via CLI: `orama db create e2e-testdb` -2. Create schema: `orama db query e2e-testdb "CREATE TABLE ..."` -3. Insert data: `orama db query e2e-testdb "INSERT ..."` -4. Query data: `orama db query e2e-testdb "SELECT ..."` -5. Verify results match expected -6. Backup database: `orama db backup e2e-testdb` -7. List backups: `orama db backups e2e-testdb` -8. Verify backup CID in IPFS -9. Restore from backup (if implemented) -10. Verify data integrity - -**Command**: -```bash -go test ./tests/e2e -run TestSQLiteDatabaseE2E -v -timeout 10m -``` - -### 3.4 DNS Resolution E2E Test - -**File**: `tests/e2e/dns_test.go` (needs to be created) - -**Test Flow**: -1. Create deployment -2. Query all 4 nameservers for deployment domain -3. Verify all return same IP -4. Add custom domain -5. Verify TXT record -6. Verify A record created -7. Query external DNS resolver -8. Verify domain resolves correctly - -**Command**: -```bash -go test ./tests/e2e -run TestDNSResolutionE2E -v -timeout 5m -``` - ---- - -## 4. CLI Tests - -### 4.1 Deploy Command Tests - -**File**: `tests/cli/deploy_test.go` (needs to be created) - -**Test Cases**: -- Deploy static site -- Deploy Next.js with --ssr flag -- Deploy Node.js backend -- Deploy Go backend -- Handle missing arguments -- Handle invalid paths -- Handle network errors gracefully - -**Command**: -```bash -go test ./tests/cli -run TestDeployCommand -v -``` - -### 4.2 Deployments Management Tests - -**File**: `tests/cli/deployments_test.go` (needs to be created) - -**Test Cases**: -- List all deployments -- Get specific deployment -- Delete deployment with confirmation -- Rollback to version -- View logs with --follow -- Filter deployments by status - -**Command**: -```bash -go test ./tests/cli -run TestDeploymentsCommands -v -``` - -### 4.3 Database Command Tests - -**File**: `tests/cli/db_test.go` (needs to be created) - -**Test Cases**: -- Create database -- Execute query (SELECT, INSERT, UPDATE, DELETE) -- List databases -- Backup database -- List backups -- Handle SQL syntax errors -- Handle connection errors - -**Command**: -```bash -go test ./tests/cli -run TestDatabaseCommands -v -``` - -### 4.4 Domain Command Tests - -**File**: `tests/cli/domain_test.go` (needs to be created) - -**Test Cases**: -- Add custom domain -- Verify domain -- List domains -- Remove domain -- Handle verification failures - -**Command**: -```bash -go test ./tests/cli -run TestDomainCommands -v -``` - ---- - -## 5. Performance Tests - -### 5.1 Concurrent Deployment Test - -**Objective**: Verify system handles multiple concurrent deployments - -**Test**: -```bash -# Deploy 50 static sites concurrently -for i in {1..50}; do - orama deploy static ./test-site --name test-$i & -done -wait - -# Verify all succeeded -orama deployments list | grep -c "active" -# Should output: 50 -``` - -### 5.2 Port Allocation Performance Test - -**Objective**: Measure port allocation speed under high contention - -**Test**: -```go -func BenchmarkPortAllocation(b *testing.B) { - // Setup - db := setupTestDB() - allocator := deployments.NewPortAllocator(db, logger) - - b.RunParallel(func(pb *testing.PB) { - for pb.Next() { - _, err := allocator.AllocatePort(ctx, "test-node", uuid.New().String()) - if err != nil { - b.Fatal(err) - } - } - }) -} -``` - -**Command**: -```bash -go test -bench=BenchmarkPortAllocation -benchtime=10s ./pkg/deployments -``` - -### 5.3 DNS Query Performance Test - -**Objective**: Measure CoreDNS query latency with RQLite backend - -**Test**: -```bash -# Warm up -for i in {1..1000}; do - dig @localhost test.orama.network > /dev/null -done - -# Benchmark -ab -n 10000 -c 100 http://localhost:53/dns-query?name=test.orama.network - -# Expected: <50ms p95 latency -``` - -### 5.4 Health Check Performance Test - -**Objective**: Verify health checker handles 1000 deployments - -**Test**: -- Create 1000 test deployments -- Start health checker -- Measure time to complete one check cycle -- Expected: <60 seconds for all 1000 checks - ---- - -## 6. Security Tests - -### 6.1 Namespace Isolation Test - -**Objective**: Verify users cannot access other namespaces' resources - -**Test**: -```bash -# User A deploys -export ORAMA_TOKEN="user-a-token" -orama deploy static ./site --name myapp - -# User B attempts to access User A's deployment -export ORAMA_TOKEN="user-b-token" -orama deployments get myapp -# Expected: 404 Not Found or 403 Forbidden - -# User B attempts to access User A's database -orama db query user-a-db "SELECT * FROM users" -# Expected: 404 Not Found or 403 Forbidden -``` - -### 6.2 SQL Injection Test - -**Objective**: Verify SQLite handler sanitizes inputs - -**Test**: -```bash -# Attempt SQL injection in database name -orama db create "test'; DROP TABLE users; --" -# Expected: Validation error - -# Attempt SQL injection in query -orama db query testdb "SELECT * FROM users WHERE id = '1' OR '1'='1'" -# Expected: Query executes safely (parameterized) -``` - -### 6.3 Path Traversal Test - -**Objective**: Verify deployment paths are sanitized - -**Test**: -```bash -# Attempt path traversal in deployment name -orama deploy static ./site --name "../../etc/passwd" -# Expected: Validation error - -# Attempt path traversal in SQLite database name -orama db create "../../../etc/shadow" -# Expected: Validation error -``` - -### 6.4 Resource Exhaustion Test - -**Objective**: Verify resource limits are enforced - -**Test**: -```bash -# Deploy 10001 sites (exceeds default limit) -for i in {1..10001}; do - orama deploy static ./site --name test-$i -done -# Expected: Last deployment rejected with quota error - -# Create huge SQLite database -orama db query bigdb "CREATE TABLE huge (data TEXT)" -orama db query bigdb "INSERT INTO huge VALUES ('$(head -c 10G 80%) - -### Phase 2: Integration Tests (Days 2-3) -- Run integration tests in isolated environment -- Fix any integration issues -- Verify database state consistency - -### Phase 3: E2E Tests (Days 4-5) -- Run E2E tests in staging environment -- Test with real DNS, IPFS, RQLite -- Fix any environment-specific issues - -### Phase 4: Performance Tests (Day 6) -- Run load tests -- Measure latency and throughput -- Optimize bottlenecks - -### Phase 5: Security Tests (Day 7) -- Run security test suite -- Fix any vulnerabilities -- Document security model - -### Phase 6: Chaos Tests (Day 8) -- Run failure scenario tests -- Verify recovery procedures -- Document failure modes - -### Phase 7: Production Validation (Day 9-10) -- Deploy to production with feature flag OFF -- Run smoke tests in production -- Enable feature flag for 10% of traffic -- Monitor for 24 hours -- Gradually increase to 100% - ---- - -## Test Environment Setup - -### Local Development - -```bash -# Start test dependencies -docker-compose -f tests/docker-compose.test.yml up -d - -# Run unit tests -make test-unit - -# Run integration tests -make test-integration - -# Run all tests -make test-all -``` - -### CI/CD Pipeline - -```yaml -# .github/workflows/test.yml -name: Test - -on: [push, pull_request] - -jobs: - unit-tests: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-go@v2 - - run: go test ./pkg/... -v -race -coverprofile=coverage.out - - integration-tests: - runs-on: ubuntu-latest - services: - rqlite: - image: rqlite/rqlite - ipfs: - image: ipfs/go-ipfs - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-go@v2 - - run: go test ./tests/integration/... -v -timeout 15m - - e2e-tests: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - run: ./scripts/setup-test-env.sh - - run: go test ./tests/e2e/... -v -timeout 30m -``` - ---- - -## Success Criteria - -### Unit Tests -- ✅ All tests pass -- ✅ Code coverage >80% -- ✅ No race conditions detected - -### Integration Tests -- ✅ All happy path scenarios pass -- ✅ Error scenarios handled gracefully -- ✅ Database state remains consistent - -### E2E Tests -- ✅ Full workflows complete successfully -- ✅ DNS resolution works across all nameservers -- ✅ Deployments accessible via HTTPS - -### Performance Tests -- ✅ Port allocation: <10ms per allocation -- ✅ DNS queries: <50ms p95 latency -- ✅ Deployment creation: <30s for static, <2min for dynamic -- ✅ Health checks: Complete 1000 deployments in <60s - -### Security Tests -- ✅ Namespace isolation enforced -- ✅ No SQL injection vulnerabilities -- ✅ No path traversal vulnerabilities -- ✅ Resource limits enforced - -### Chaos Tests -- ✅ Node failure: Recovery within 5 minutes -- ✅ Service failure: Graceful degradation -- ✅ Concurrent updates: No race conditions - ---- - -## Ongoing Testing - -After production deployment: - -1. **Synthetic Monitoring**: Create test deployments every hour and verify they work -2. **Canary Deployments**: Test new versions with 1% of traffic before full rollout -3. **Load Testing**: Weekly load tests to ensure performance doesn't degrade -4. **Security Scanning**: Automated vulnerability scans -5. **Chaos Engineering**: Monthly chaos tests in staging - ---- - -## Test Automation Commands - -```bash -# Run all tests -make test-all - -# Run unit tests only -make test-unit - -# Run integration tests only -make test-integration - -# Run E2E tests only -make test-e2e - -# Run performance tests -make test-performance - -# Run security tests -make test-security - -# Run chaos tests -make test-chaos - -# Generate coverage report -make test-coverage - -# Run tests with race detector -make test-race -``` diff --git a/pkg/cli/deployment_commands.go b/pkg/cli/deployment_commands.go new file mode 100644 index 0000000..93c6168 --- /dev/null +++ b/pkg/cli/deployment_commands.go @@ -0,0 +1,54 @@ +package cli + +import ( + "fmt" + "os" + + "github.com/DeBrosOfficial/network/pkg/cli/db" + "github.com/DeBrosOfficial/network/pkg/cli/deployments" +) + +// HandleDeployCommand handles deploy commands +func HandleDeployCommand(args []string) { + deployCmd := deployments.DeployCmd + deployCmd.SetArgs(args) + + if err := deployCmd.Execute(); err != nil { + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) + } +} + +// HandleDeploymentsCommand handles deployments management commands +func HandleDeploymentsCommand(args []string) { + // Create root command for deployments management + deploymentsCmd := deployments.DeployCmd + deploymentsCmd.Use = "deployments" + deploymentsCmd.Short = "Manage deployments" + deploymentsCmd.Long = "List, get, delete, rollback, and view logs for deployments" + + // Add management subcommands + deploymentsCmd.AddCommand(deployments.ListCmd) + deploymentsCmd.AddCommand(deployments.GetCmd) + deploymentsCmd.AddCommand(deployments.DeleteCmd) + deploymentsCmd.AddCommand(deployments.RollbackCmd) + deploymentsCmd.AddCommand(deployments.LogsCmd) + + deploymentsCmd.SetArgs(args) + + if err := deploymentsCmd.Execute(); err != nil { + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) + } +} + +// HandleDBCommand handles database commands +func HandleDBCommand(args []string) { + dbCmd := db.DBCmd + dbCmd.SetArgs(args) + + if err := dbCmd.Execute(); err != nil { + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) + } +}