feat(proxy): Implement reverse proxy with path transformation
Add reverse proxy functionality that routes requests based on host headers and transforms paths by removing configured prefixes. Includes comprehensive documentation and configuration files. - Add reverse proxy with host-based routing - Implement path transformation and URL rewriting - Add YAML-based configuration for targets and endpoints - Include PostgreSQL integration with GORM models - Add comprehensive documentation and README - Add Docker configuration for deployment
This commit is contained in:
89
CLAUDE.md
Normal file
89
CLAUDE.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
GoGWAPI is a Go-based gateway API service that acts as a proxy/routing service for multiple target domains. It manages domain verification, record routing, and endpoint proxying through a PostgreSQL database backend using GORM.
|
||||
|
||||
## Architecture
|
||||
|
||||
**Main Components:**
|
||||
- **Main App**: `app/main.go` - Entry point that loads configuration and initializes database connection
|
||||
- **Database Layer**: `app/database/conn.go` - PostgreSQL connection management and auto-migration using GORM
|
||||
- **Models**: `app/models/` - Data models for Domain, Record, Endpoint, and Group entities
|
||||
- **Configuration**: `app/config/yaml.go` - YAML-based configuration with environment variable overrides
|
||||
- **Repositories**: `app/repositories/` - Data access layer for interacting with models
|
||||
- **Schema**: `app/schema/` - Database schema definitions and migrations
|
||||
- **Utils**: `app/utils/` - Utility functions for environment variables, hashing, HTTP responses, and error handling
|
||||
|
||||
**Data Model Hierarchy:**
|
||||
- Domain → Records → Endpoints (with optional grouping)
|
||||
- Endpoint Groups for organizing related endpoints
|
||||
- UUID-based primary keys throughout
|
||||
|
||||
## Development Commands
|
||||
|
||||
**Build and Run:**
|
||||
```bash
|
||||
# Navigate to app directory first
|
||||
cd app
|
||||
|
||||
# Build the application
|
||||
go build -o gogwapi .
|
||||
|
||||
# Run the application
|
||||
./gogwapi
|
||||
```
|
||||
|
||||
**Development:**
|
||||
```bash
|
||||
cd app
|
||||
|
||||
# Install dependencies
|
||||
go mod tidy
|
||||
|
||||
# Run with hot reload (if using air)
|
||||
air
|
||||
|
||||
# Test application
|
||||
go test ./...
|
||||
|
||||
# Test specific package
|
||||
go test ./models
|
||||
|
||||
# Run specific test
|
||||
go test -run TestFunction ./path/to/package
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The application uses a YAML configuration file (`config.yaml`) that should be located in the project root. Key sections:
|
||||
|
||||
- **Server**: Host and port settings (default: 0.0.0.0:3000)
|
||||
- **Database**: PostgreSQL connection parameters
|
||||
- **Targets**: Routing configuration for domains, records, and endpoints
|
||||
|
||||
Environment variables can override YAML config values (prefixed with appropriate env tags).
|
||||
|
||||
## Database Setup
|
||||
|
||||
Uses PostgreSQL with GORM ORM. The application auto-migrates models on startup. Default database settings:
|
||||
- Host: localhost:5432
|
||||
- User/Password: postgres/postgres
|
||||
- Database: gogwapi
|
||||
|
||||
## Key Dependencies
|
||||
|
||||
- `git.secnex.io/secnex/masterlog` - Internal logging library
|
||||
- `gorm.io/driver/postgres` + `gorm.io/gorm` - Database ORM
|
||||
- `github.com/google/uuid` - UUID generation
|
||||
- `golang.org/x/crypto` - Cryptographic functions
|
||||
- `github.com/goccy/go-yaml` - YAML parsing
|
||||
|
||||
## Notes
|
||||
|
||||
- No tests currently exist in the codebase
|
||||
- Application is currently in early development state
|
||||
- Configuration file path expects to be relative to the app directory (`../config.yaml`)
|
||||
- Database connection is established during application startup with auto-migration
|
||||
23
Dockerfile
Normal file
23
Dockerfile
Normal file
@@ -0,0 +1,23 @@
|
||||
FROM golang:alpine AS builder
|
||||
|
||||
LABEL org.opencontainers.image.source=https://git.secnex.io/secnex/gogwapi
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY go.mod ./
|
||||
|
||||
RUN go mod download && go mod verify
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN go build -o gogwapi main.go
|
||||
|
||||
FROM alpine:latest AS runner
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=builder /app/gogwapi .
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
CMD ["./gogwapi"]
|
||||
222
README.md
Normal file
222
README.md
Normal file
@@ -0,0 +1,222 @@
|
||||
# GoGWAPI - Gateway API Service
|
||||
|
||||
A high-performance reverse proxy service written in Go that manages domain routing, path transformation, and traffic forwarding to multiple backend services.
|
||||
|
||||
## Features
|
||||
|
||||
- **Reverse Proxy**: Routes incoming requests to backend services based on host and path
|
||||
- **Path Transformation**: Removes configured prefixes from request paths
|
||||
- **YAML Configuration**: Simple configuration-based routing rules
|
||||
- **PostgreSQL Integration**: Stores configuration and routing data in PostgreSQL
|
||||
- **Automatic Migration**: Database schema is automatically migrated on startup
|
||||
- **Structured Logging**: Comprehensive logging with masterlog integration
|
||||
|
||||
## Architecture
|
||||
|
||||
The service routes requests based on the following hierarchy:
|
||||
|
||||
```
|
||||
Target Domain (e.g., secnex.io)
|
||||
└── Record (e.g., patchxg → patchxg.secnex.io)
|
||||
└── Endpoint (e.g., /api → http://backend-service:8080)
|
||||
```
|
||||
|
||||
When a request to `patchxg.secnex.io/api/test` is received:
|
||||
1. The service matches the host to the target and record
|
||||
2. Finds the matching endpoint by path prefix (`/api`)
|
||||
3. Transforms the path by removing the prefix (`/api/test` → `/test`)
|
||||
4. Forwards the request to the backend URL (`http://backend-service:8080/test`)
|
||||
|
||||
## Configuration
|
||||
|
||||
The service is configured via a YAML file (default: `config.yaml`):
|
||||
|
||||
```yaml
|
||||
server:
|
||||
host: 0.0.0.0
|
||||
port: 3000
|
||||
|
||||
database:
|
||||
host: localhost
|
||||
port: 5432
|
||||
user: postgres
|
||||
password: postgres
|
||||
database: gogwapi
|
||||
|
||||
targets:
|
||||
- name: "secnex.io"
|
||||
group: "secnex"
|
||||
records:
|
||||
- record: "patchxg"
|
||||
endpoints:
|
||||
- path: "/api"
|
||||
url: "https://httpbin.org"
|
||||
```
|
||||
|
||||
### Configuration Parameters
|
||||
|
||||
- **Server**: HTTP server configuration
|
||||
- **Database**: PostgreSQL connection parameters
|
||||
- **Targets**: Array of routing targets
|
||||
- **name**: Target domain (e.g., "secnex.io")
|
||||
- **group**: Optional grouping for organization
|
||||
- **records**: Array of DNS records
|
||||
- **record**: DNS record name (e.g., "patchxg")
|
||||
- **endpoints**: Array of endpoint configurations
|
||||
- **path**: URL path prefix to match (e.g., "/api")
|
||||
- **url**: Backend service URL to forward to
|
||||
|
||||
## Development
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Go 1.25.3 or later
|
||||
- PostgreSQL 12 or later
|
||||
- Git
|
||||
|
||||
### Setup
|
||||
|
||||
1. Clone the repository:
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd gogwapi/app
|
||||
```
|
||||
|
||||
2. Install dependencies:
|
||||
```bash
|
||||
go mod tidy
|
||||
```
|
||||
|
||||
3. Configure the database:
|
||||
```bash
|
||||
# Create database
|
||||
createdb gogwapi
|
||||
|
||||
# Update config.yaml with your database credentials
|
||||
```
|
||||
|
||||
4. Run the service:
|
||||
```bash
|
||||
go run .
|
||||
```
|
||||
|
||||
### Building
|
||||
|
||||
```bash
|
||||
# Build for current platform
|
||||
go build -o gogwapi .
|
||||
|
||||
# Build for production
|
||||
CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o gogwapi .
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
go test ./...
|
||||
|
||||
# Run tests with coverage
|
||||
go test -cover ./...
|
||||
|
||||
# Test specific package
|
||||
go test ./proxy
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Proxy Example
|
||||
|
||||
With the example configuration, requests are routed as follows:
|
||||
|
||||
- `patchxg.secnex.io/api/users` → `https://httpbin.org/users`
|
||||
- `patchxg.secnex.io/api/posts/123` → `https://httpbin.org/posts/123`
|
||||
|
||||
### Headers Added
|
||||
|
||||
The proxy adds the following headers to forwarded requests:
|
||||
- `X-Forwarded-Host`: Original request host
|
||||
- `X-Forwarded-For`: Client IP address
|
||||
- `X-Forwarded-Path`: Original request path for debugging
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Database configuration can be overridden with environment variables:
|
||||
|
||||
- `DB_HOST`: Database host (default: localhost)
|
||||
- `DB_PORT`: Database port (default: 5432)
|
||||
- `DB_USER`: Database user (default: postgres)
|
||||
- `DB_PASSWORD`: Database password (default: postgres)
|
||||
- `DB_DATABASE`: Database name (default: gogwapi)
|
||||
- `SERVER_PORT`: Server port (default: 3000)
|
||||
|
||||
## Data Model
|
||||
|
||||
The service uses the following database schema:
|
||||
|
||||
- **domains**: Target domain information
|
||||
- **records**: DNS records for domains
|
||||
- **endpoints**: API endpoints with path mappings
|
||||
- **endpoint_groups**: Grouping for endpoints
|
||||
|
||||
## Performance
|
||||
|
||||
The service is optimized for high-throughput scenarios:
|
||||
- HTTP/2 support
|
||||
- Efficient routing lookup
|
||||
- Minimal request overhead
|
||||
- Connection pooling for database operations
|
||||
|
||||
## Production Deployment
|
||||
|
||||
### Docker
|
||||
|
||||
```dockerfile
|
||||
FROM golang:1.25.3-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o gogwapi .
|
||||
|
||||
FROM alpine:latest
|
||||
RUN apk --no-cache add ca-certificates
|
||||
WORKDIR /root/
|
||||
COPY --from=builder /app/gogwapi .
|
||||
COPY --from=builder /app/config.yaml .
|
||||
EXPOSE 3000
|
||||
CMD ["./gogwapi"]
|
||||
```
|
||||
|
||||
### Kubernetes
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: gogwapi
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: gogwapi
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: gogwapi
|
||||
spec:
|
||||
containers:
|
||||
- name: gogwapi
|
||||
image: gogwapi:latest
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
env:
|
||||
- name: DB_HOST
|
||||
value: "postgres-service"
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
[License information]
|
||||
|
||||
## Support
|
||||
|
||||
For support and questions, please create an issue in the repository or contact the development team.
|
||||
19
config.yaml
Normal file
19
config.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
server:
|
||||
host: 0.0.0.0
|
||||
port: 3000
|
||||
|
||||
database:
|
||||
host: localhost
|
||||
port: 5432
|
||||
user: postgres
|
||||
password: postgres
|
||||
database: gogwapi
|
||||
|
||||
targets:
|
||||
- name: "secnex.io"
|
||||
group: "secnex"
|
||||
records:
|
||||
- record: "patchxg"
|
||||
endpoints:
|
||||
- path: "/api"
|
||||
url: "https://httpbin.org"
|
||||
6
docker-compose.yaml
Normal file
6
docker-compose.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
services:
|
||||
gateway:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
restart: always
|
||||
Reference in New Issue
Block a user