187 lines
5.4 KiB
Markdown
187 lines
5.4 KiB
Markdown
# CFTunnels - Cloudflare Tunnels Management API
|
|
|
|
> **Note**: All pull requests should be raised against the `test` branch.
|
|
|
|
A Spring Boot REST API for managing Cloudflare Tunnels with ingress mappings and an approval workflow.
|
|
|
|
## Overview
|
|
|
|
CFTunnels provides a programmatic way to manage Cloudflare Tunnel configurations, allowing teams to:
|
|
|
|
- View and manage Cloudflare Tunnels
|
|
- Add, modify, and delete ingress mappings
|
|
- Request mapping changes through an approval workflow
|
|
- Track tunnel configurations locally
|
|
|
|
## Features
|
|
|
|
- **Tunnel Management**: Create, update, and delete Cloudflare tunnels
|
|
- **Ingress Mappings**: Add custom ingress rules to tunnel configurations
|
|
- **Approval Workflow**: Request/approve/reject mapping changes
|
|
- **Security**: OIDC-based authentication with role-based access
|
|
- **API Documentation**: OpenAPI/Swagger documentation
|
|
|
|
## Technology Stack
|
|
|
|
- Java 17
|
|
- Spring Boot 3.x
|
|
- Spring Data JPA
|
|
- Spring Security with OIDC
|
|
- H2 Database (configurable for PostgreSQL)
|
|
- Cloudflare API v4
|
|
|
|
## Prerequisites
|
|
|
|
- Java 17 or higher
|
|
- Cloudflare account with API key
|
|
- OIDC provider (e.g., Google, Okta, Auth0)
|
|
|
|
## Configuration
|
|
|
|
Copy `.env.example` to `.env` and configure:
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
### Required Environment Variables
|
|
|
|
| Variable | Description |
|
|
|---------|-------------|
|
|
| `CLOUDFLARE_ACCOUNT_ID` | Cloudflare Account ID |
|
|
| `CLOUDFLARE_API_KEY` | Cloudflare API Key |
|
|
| `CLOUDFLARE_EMAIL` | Cloudflare account email |
|
|
| `SPRING_PROFILES_ACTIVE` | Environment (local, dev, prod) |
|
|
|
|
### Security Configuration
|
|
|
|
OIDC settings in `application.properties`:
|
|
|
|
```properties
|
|
spring.security.oauth2.client.registration.<provider>.client-id=your-client-id
|
|
spring.security.oauth2.client.registration.<provider>.client-secret=your-client-secret
|
|
spring.security.oauth2.client.provider.<provider>.issuer-uri=https://your-oidc-provider
|
|
```
|
|
|
|
## Running Locally
|
|
|
|
### Using Gradle
|
|
|
|
```bash
|
|
./gradlew bootRun
|
|
```
|
|
|
|
### Using Docker
|
|
|
|
```bash
|
|
docker-compose up --build
|
|
```
|
|
|
|
The API will be available at `http://localhost:8080`
|
|
|
|
## API Documentation
|
|
|
|
Once running, access:
|
|
|
|
- **Swagger UI**: `http://localhost:8080/swagger-ui.html`
|
|
- **OpenAPI JSON**: `http://localhost:8080/v3/api-docs`
|
|
|
|
## API Endpoints
|
|
|
|
### Base URL: `/cloudflare`
|
|
|
|
| Method | Endpoint | Description | Required Role |
|
|
|--------|----------|-------------|---------------|
|
|
| GET | `/whoami` | Get current user info | USER |
|
|
| GET | `/tunnels` | List all Cloudflare tunnels | USER |
|
|
| GET | `/configured/tunnels` | List locally configured tunnels | USER |
|
|
| GET | `/requests` | List all mapping requests | USER |
|
|
| GET | `/tunnels/{tunnelId}/mappings` | Get tunnel configuration | DEVELOPER |
|
|
| POST | `/tunnels/{tunnelId}/mappings` | Add ingress mapping | ADMIN |
|
|
| DELETE | `/tunnels/{tunnelId}/mappings` | Delete ingress mapping | DEVELOPER |
|
|
| POST | `/tunnels/configure/{tunnelId}/requests` | Create mapping request | DEVELOPER |
|
|
| PUT | `/requests/{requestId}/approve` | Approve mapping request | APPROVER |
|
|
| PUT | `/requests/{requestId}/reject` | Reject mapping request | APPROVER |
|
|
| PUT | `/tunnels/configure/{tunnelId}` | Configure tunnel for environment | ADMIN |
|
|
|
|
## Role-Based Access
|
|
|
|
| Role | Permissions |
|
|
|------|-------------|
|
|
| USER | View tunnels and requests |
|
|
| DEVELOPER | Create/modify/delete mappings, create requests |
|
|
| APPROVER | Approve/reject requests |
|
|
| ADMIN | Full access including tunnel configuration |
|
|
|
|
## Example Usage
|
|
|
|
### List all tunnels
|
|
|
|
```bash
|
|
curl -H "Authorization: Bearer $TOKEN" \
|
|
http://localhost:8080/cloudflare/tunnels
|
|
```
|
|
|
|
### Add an ingress mapping
|
|
|
|
```bash
|
|
curl -X POST \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"hostname": "api.example.com",
|
|
"service": "http://localhost:8080",
|
|
"originRequest": {"noTLSVerify": true}
|
|
}' \
|
|
http://localhost:8080/cloudflare/tunnels/{tunnelId}/mappings
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
CFTunnels/
|
|
├── src/main/java/com/hithomelabs/CFTunnels/
|
|
│ ├── CfTunnelsApplication.java # Main application
|
|
│ ├── Config/ # Configuration classes
|
|
│ ├── Controllers/ # REST controllers
|
|
│ │ └── TunnelController.java # Main API controller
|
|
│ ├── Entity/ # JPA entities
|
|
│ │ ├── Mapping.java # Ingress mapping
|
|
│ │ ├── Protocol.java # Protocol enum
|
|
│ │ ├── Request.java # Mapping request
|
|
│ │ ├── Tunnel.java # Tunnel entity
|
|
│ │ └── User.java # User entity
|
|
│ ├── Models/ # DTOs
|
|
│ ├── Repositories/ # JPA repositories
|
|
│ └── Services/ # Business logic
|
|
│ ├── CloudflareAPIService.java # Cloudflare API
|
|
│ └── MappingRequestService.java # Request workflow
|
|
└── src/main/resources/
|
|
├── application.properties # Main config
|
|
└── schema.sql # Database schema
|
|
```
|
|
|
|
## Testing
|
|
|
|
Run tests with:
|
|
|
|
```bash
|
|
./gradlew test
|
|
```
|
|
|
|
Run integration tests:
|
|
|
|
```bash
|
|
./gradlew integrationTest
|
|
```
|
|
|
|
## License
|
|
|
|
Private - All rights reserved
|
|
|
|
## References
|
|
|
|
- [Cloudflare Tunnel Documentation](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/)
|
|
- [Cloudflare API v4](https://api.cloudflare.com/)
|
|
- [Spring Boot Documentation](https://docs.spring.io/spring-boot/docs/current/reference/)
|