# CF Deployer - Cloud Foundry Deployment Service

A Spring Boot application that provides a REST API for deploying Java applications to Cloud Foundry/Tanzu environments.

## Prerequisites

- Java 21
- Gradle 8.14

## Build and Run

### Build the application
```bash
./gradlew clean build
```

### Run the application
```bash
./gradlew bootRun
```

Or run the JAR directly:
```bash
java -jar build/libs/cf-uploader-1.0.0.jar
```

The application will start on `http://localhost:8080`

## API Endpoints

### 1. Deploy Application to Cloud Foundry

**Endpoint:** `POST /api/cf/deploy`

**Content-Type:** `multipart/form-data`

**Request Parts:**
- `request` (JSON string): Deployment configuration
- `jarFile` (file): The Java application JAR file
- `manifest` (file): Cloud Foundry manifest.yml file

#### Sample cURL Request

```bash
curl -X POST http://localhost:8080/api/cf/deploy \
  -F 'request={
    "apiEndpoint": "https://api.cf.example.com",
    "username": "your-username",
    "password": "your-password",
    "organization": "your-org",
    "space": "your-space",
    "appName": "my-app",
    "skipSslValidation": false
  }' \
  -F 'jarFile=@/path/to/your/application.jar' \
  -F 'manifest=@/path/to/manifest.yml'
```

#### Sample Request with Skip SSL Validation

```bash
curl -X POST http://localhost:8080/api/cf/deploy \
  -F 'request={
    "apiEndpoint": "https://api.sys.tanzu.example.com",
    "username": "admin",
    "password": "admin123",
    "organization": "development",
    "space": "dev",
    "appName": "sample-app",
    "skipSslValidation": true
  }' \
  -F 'jarFile=@./sample-app.jar' \
  -F 'manifest=@./manifest.yml'
```

---

### 2. List Applications

**Endpoint:** `POST /api/cf/apps`

**Content-Type:** `application/json`

Lists all applications in the specified organization and space.

#### Sample cURL Request

```bash
curl -X POST http://localhost:8080/api/cf/apps \
  -H "Content-Type: application/json" \
  -d '{
    "apiEndpoint": "https://api.cf.example.com",
    "username": "your-username",
    "password": "your-password",
    "organization": "your-org",
    "space": "your-space",
    "appName": "",
    "skipSslValidation": false
  }'
```

---

### 3. List Routes

**Endpoint:** `POST /api/cf/routes`

**Content-Type:** `application/json`

Lists all routes in the specified organization and space.

#### Sample cURL Request

```bash
curl -X POST http://localhost:8080/api/cf/routes \
  -H "Content-Type: application/json" \
  -d '{
    "apiEndpoint": "https://api.cf.example.com",
    "username": "your-username",
    "password": "your-password",
    "organization": "your-org",
    "space": "your-space",
    "appName": "",
    "skipSslValidation": false
  }'
```

---

### 4. Get Application Details

**Endpoint:** `POST /api/cf/app/{appName}`

**Content-Type:** `application/json`

Gets detailed information about a specific application.

#### Sample cURL Request

```bash
curl -X POST http://localhost:8080/api/cf/app/my-app \
  -H "Content-Type: application/json" \
  -d '{
    "apiEndpoint": "https://api.cf.example.com",
    "username": "your-username",
    "password": "your-password",
    "organization": "your-org",
    "space": "your-space",
    "appName": "",
    "skipSslValidation": false
  }'
```

---

### 5. Get Application Logs

**Endpoint:** `POST /api/cf/logs/{appName}?recent=true`

**Content-Type:** `application/json`

**Query Parameters:**
- `recent` (optional, default: `true`): If true, gets recent logs; if false, tails logs

Gets logs for a specific application.

#### Sample cURL Request (Recent Logs)

```bash
curl -X POST "http://localhost:8080/api/cf/logs/my-app?recent=true" \
  -H "Content-Type: application/json" \
  -d '{
    "apiEndpoint": "https://api.cf.example.com",
    "username": "your-username",
    "password": "your-password",
    "organization": "your-org",
    "space": "your-space",
    "appName": "",
    "skipSslValidation": false
  }'
```

---

### Sample Manifest File (manifest.yml)

```yaml
---
applications:
- name: sample-app
  memory: 1G
  instances: 2
  path: sample-app.jar
  buildpacks:
  - java_buildpack
  env:
    SPRING_PROFILES_ACTIVE: production
```

## Common Request Parameters

All endpoints require the following CF credentials and target information:

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `apiEndpoint` | String | Yes | Cloud Foundry API endpoint URL |
| `username` | String | Yes | CF username |
| `password` | String | Yes | CF password |
| `organization` | String | Yes | Target CF organization |
| `space` | String | Yes | Target CF space |
| `appName` | String | No* | Application name (required only for `/deploy` endpoint) |
| `skipSslValidation` | Boolean | Yes | Skip SSL certificate validation |

**Note:** Even though `appName` is not used by utility endpoints (`/apps`, `/routes`, `/app/{appName}`, `/logs/{appName}`), it must still be included in the JSON request body (can be empty string). The organization and space determine which apps/routes are listed or queried.

## Response Format

### Success Response

```json
{
  "success": true,
  "message": "Application deployed successfully",
  "deploymentId": "123e4567-e89b-12d3-a456-426614174000",
  "output": "CF CLI output logs...",
  "error": null
}
```

### Error Response

```json
{
  "success": false,
  "message": "Application deployment failed",
  "deploymentId": "123e4567-e89b-12d3-a456-426614174000",
  "output": "CF CLI output logs...",
  "error": "Error details..."
}
```

## Configuration

Application settings can be configured in `src/main/resources/application.properties`:

```properties
# Server port
server.port=8080

# Max file size (default: 500MB)
spring.servlet.multipart.max-file-size=500MB
spring.servlet.multipart.max-request-size=500MB

# CF CLI timeout in seconds (default: 600)
cf.cli.timeout=600

# Optional: Custom CF CLI path (if not using bundled binaries)
cf.cli.path=
```

## Features

- **Application Deployment**: Deploy JAR files to Cloud Foundry with manifest support
- **Application Management**: List apps, view details, and access logs
- **Route Management**: List all routes in your CF space
- **Automatic CF CLI Management**: Bundled CF CLI binaries for Linux, macOS, and Windows
- **Secure Password Handling**: Passwords are masked in all log output
- **Comprehensive Logging**: Detailed DEBUG-level logging for troubleshooting deployments
- **Configurable Timeouts**: Adjustable timeout for long-running deployments (default: 600s)
- **Large File Support**: Multipart file upload support up to 500MB
- **Automatic Cleanup**: Temporary files are automatically cleaned up after operations
- **Error Handling**: Comprehensive exception handling with detailed error messages

## Error Handling

The API handles various error scenarios:
- **400 Bad Request**: Invalid request parameters or file validation errors
- **413 Payload Too Large**: Files exceed 500MB limit
- **500 Internal Server Error**: Deployment failures or unexpected errors

## Development

### Project Structure

```
src/main/java/com/cfdeployer/
├── controller/          # REST controllers
├── service/            # Business logic
├── model/              # DTOs
└── exception/          # Exception handlers

src/main/resources/
├── application.properties
└── cf-cli/             # CF CLI binaries (auto-downloaded)
```

### Build with Custom CF CLI Version

Edit `build.gradle` to change the CF CLI version:

```groovy
def cfCliVersion = '8.7.10'  // Change this version
```

## License

This project is licensed under the MIT License.
