CFTunnels/README.md
Dave the Dev 047433fe60
Some checks failed
Promote image with tag test to prod / tag (push) Successful in 6s
Promote image with tag test to prod / build_tag_push (push) Successful in 34s
Daily cloudflare API integration test / cloudflare-api-test (push) Failing after 1m7s
Hithomelabs/CFTunnels#115: Add PR target branch note to README
2026-04-15 18:44:51 +00:00

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/)