349 lines
8.9 KiB
Markdown
349 lines
8.9 KiB
Markdown
# Tanzu Deployer UI - Angular Frontend
|
||
|
||
A modern, dark-themed Angular 19.1 frontend for deploying applications to Tanzu/Cloud Foundry environments.
|
||
|
||
## Features
|
||
|
||
- ✅ **Modern Dark Theme**: Sleek GitHub-inspired dark UI with blue/purple gradients
|
||
- ✅ **Simple Form Interface**: Easy-to-use deployment form with all Tanzu configuration fields
|
||
- ✅ **Modern File Upload**: Beautiful drag-and-drop style file upload buttons with SVG icons
|
||
- ✅ **Chunked File Upload**: Handles large JAR files using Base64-encoded chunks (compatible with Java proxy)
|
||
- ✅ **Real-time Progress**: Visual progress bar showing upload and deployment status
|
||
- ✅ **Live Logs**: Collapsible terminal-style output window displaying deployment logs
|
||
- ✅ **Responsive Design**: Works seamlessly on desktop, tablet, and mobile devices
|
||
- ✅ **Secure**: Password fields are masked, follows Angular security best practices
|
||
- ✅ **Configurable**: Environment-based configuration for all settings
|
||
- ✅ **Production Ready**: Includes nginx configuration and Helm chart for K8s deployment
|
||
|
||
## Configuration
|
||
|
||
All application settings are managed via environment files:
|
||
|
||
**`src/environments/environment.ts`** (Development):
|
||
```typescript
|
||
export const environment = {
|
||
production: false,
|
||
apiBase: '/api/cf', // API endpoint base URL
|
||
chunkSize: 1048576, // Chunk size in bytes (1MB)
|
||
enableSslValidation: false, // Show/hide SSL validation checkbox
|
||
pollInterval: 5000, // Poll interval in milliseconds
|
||
maxPollAttempts: 120, // Max polling attempts (10 minutes)
|
||
defaultLogsExpanded: true, // Logs expanded by default
|
||
showDebugInfo: false // Show debug information
|
||
};
|
||
```
|
||
|
||
**`src/environments/environment.prod.ts`** (Production):
|
||
- Same structure as development
|
||
- Used when building with `--configuration production`
|
||
|
||
### Customizing Configuration
|
||
|
||
To customize the application behavior:
|
||
|
||
1. Edit `src/environments/environment.ts` for development
|
||
2. Edit `src/environments/environment.prod.ts` for production
|
||
3. Rebuild the application
|
||
|
||
**Common Customizations:**
|
||
|
||
- **Enable SSL Validation Checkbox**: Set `enableSslValidation: true`
|
||
- **Change Chunk Size**: Set `chunkSize: 2097152` (2MB)
|
||
- **Increase Poll Time**: Set `maxPollAttempts: 240` (20 minutes)
|
||
- **Change API Endpoint**: Set `apiBase: 'https://api.example.com/cf'`
|
||
|
||
## Quick Start
|
||
|
||
### Local Development
|
||
|
||
1. **Install dependencies:**
|
||
```bash
|
||
npm install
|
||
```
|
||
|
||
2. **Start development server:**
|
||
```bash
|
||
npm start
|
||
```
|
||
|
||
3. **Open browser:**
|
||
Navigate to `http://localhost:4200`
|
||
|
||
### Build for Production
|
||
|
||
```bash
|
||
npm run build:prod
|
||
```
|
||
|
||
Built files will be in `dist/cf-deployer-ui/browser/`
|
||
|
||
## Docker Deployment
|
||
|
||
### Build Docker Image
|
||
|
||
```bash
|
||
docker build -t cf-deployer-ui:latest .
|
||
```
|
||
|
||
### Run Docker Container
|
||
|
||
```bash
|
||
docker run -d \
|
||
-p 8080:80 \
|
||
-e BACKEND_URL=http://cf-deployer-backend:8080 \
|
||
--name cf-deployer-ui \
|
||
cf-deployer-ui:latest
|
||
```
|
||
|
||
**Environment Variables:**
|
||
- `BACKEND_URL`: URL of the CF Deployer backend API (default: `http://localhost:8080`)
|
||
|
||
## Kubernetes Deployment
|
||
|
||
### Prerequisites
|
||
|
||
- Kubernetes cluster
|
||
- Helm 3.x installed
|
||
- Docker image pushed to registry
|
||
|
||
### Deploy with Helm
|
||
|
||
1. **Update values.yaml:**
|
||
```yaml
|
||
image:
|
||
repository: your-registry/cf-deployer-ui
|
||
tag: "1.0.0"
|
||
|
||
backend:
|
||
url: "http://cf-deployer-backend:8080"
|
||
|
||
ingress:
|
||
enabled: true
|
||
hosts:
|
||
- host: cf-deployer.example.com
|
||
paths:
|
||
- path: /
|
||
pathType: Prefix
|
||
```
|
||
|
||
2. **Install the chart:**
|
||
```bash
|
||
helm install cf-deployer-ui ./helm
|
||
```
|
||
|
||
3. **Upgrade the chart:**
|
||
```bash
|
||
helm upgrade cf-deployer-ui ./helm
|
||
```
|
||
|
||
4. **Uninstall:**
|
||
```bash
|
||
helm uninstall cf-deployer-ui
|
||
```
|
||
|
||
### Helm Configuration Options
|
||
|
||
| Parameter | Description | Default |
|
||
|-----------|-------------|---------|
|
||
| `replicaCount` | Number of replicas | `2` |
|
||
| `image.repository` | Docker image repository | `cf-deployer-ui` |
|
||
| `image.tag` | Docker image tag | `latest` |
|
||
| `service.type` | Kubernetes service type | `ClusterIP` |
|
||
| `service.port` | Service port | `80` |
|
||
| `backend.url` | Backend API URL | `http://cf-deployer-backend:8080` |
|
||
| `ingress.enabled` | Enable ingress | `false` |
|
||
| `resources.limits.cpu` | CPU limit | `500m` |
|
||
| `resources.limits.memory` | Memory limit | `512Mi` |
|
||
|
||
## Usage
|
||
|
||
### Deployment Flow
|
||
|
||
1. **Fill in Cloud Foundry Details:**
|
||
- API Endpoint (e.g., `https://api.cf.example.com`)
|
||
- Username and Password
|
||
- Organization and Space
|
||
- Application Name
|
||
- Skip SSL Validation (if needed)
|
||
|
||
2. **Select Files:**
|
||
- JAR File: Your application JAR
|
||
- Manifest File: Cloud Foundry manifest.yml
|
||
|
||
3. **Deploy:**
|
||
- Click "Deploy to Cloud Foundry"
|
||
- Watch progress bar and logs
|
||
- Wait for completion
|
||
|
||
### Screenshots
|
||
|
||
**Main Form:**
|
||
- Clean, responsive form with all required fields
|
||
- File upload with size display
|
||
- SSL validation checkbox
|
||
|
||
**Progress Tracking:**
|
||
- Visual progress bar (0-100%)
|
||
- Current step indicator
|
||
- Status badges (IN_PROGRESS, COMPLETED, FAILED)
|
||
|
||
**Logs Output:**
|
||
- Collapsible terminal-style output
|
||
- Timestamped log entries
|
||
- Auto-scroll to latest logs
|
||
|
||
## Architecture
|
||
|
||
### How It Works
|
||
|
||
The frontend mimics the behavior of `deploy-chunked-simple.sh`:
|
||
|
||
1. **Initialize Upload Session:**
|
||
```
|
||
POST /api/cf/upload/init
|
||
→ Returns uploadSessionId
|
||
```
|
||
|
||
2. **Upload Files in Chunks:**
|
||
- Splits files into 1MB chunks
|
||
- Base64 encodes each chunk (for Java proxy compatibility)
|
||
- Uploads via:
|
||
```
|
||
POST /api/cf/upload/chunk?uploadSessionId=...&fileType=...&chunkIndex=...&totalChunks=...&fileName=...
|
||
Headers: Content-Type: text/plain, X-Chunk-Encoding: base64
|
||
Body: Base64 chunk data
|
||
```
|
||
|
||
3. **Finalize Upload:**
|
||
```
|
||
POST /api/cf/upload/finalize?uploadSessionId=...&async=true
|
||
```
|
||
|
||
4. **Poll Deployment Status:**
|
||
```
|
||
GET /api/cf/deployment/status/{uploadSessionId}
|
||
(Every 5 seconds until COMPLETED or FAILED)
|
||
```
|
||
|
||
### Why Base64 Encoding?
|
||
|
||
The frontend sends chunks as Base64-encoded text because:
|
||
- It goes through a Java proxy that reads `@RequestBody String`
|
||
- Binary data gets corrupted when read as String
|
||
- Base64 ensures safe text transport through the proxy
|
||
- Backend automatically decodes Base64 back to binary
|
||
|
||
## Project Structure
|
||
|
||
```
|
||
frontend/
|
||
├── src/
|
||
│ ├── app/
|
||
│ │ ├── app.component.ts # Main component with form logic
|
||
│ │ ├── app.component.html # Template with form UI
|
||
│ │ ├── app.component.css # Component styles
|
||
│ │ └── deploy.service.ts # API service
|
||
│ ├── index.html # Main HTML file
|
||
│ ├── main.ts # Bootstrap file
|
||
│ └── styles.css # Global styles
|
||
├── helm/ # Helm chart
|
||
│ ├── Chart.yaml
|
||
│ ├── values.yaml
|
||
│ └── templates/
|
||
│ ├── deployment.yaml
|
||
│ ├── service.yaml
|
||
│ ├── ingress.yaml
|
||
│ └── _helpers.tpl
|
||
├── nginx.conf # nginx configuration
|
||
├── Dockerfile # Multi-stage Docker build
|
||
├── angular.json # Angular CLI configuration
|
||
├── package.json # NPM dependencies
|
||
└── tsconfig.json # TypeScript configuration
|
||
```
|
||
|
||
## Development
|
||
|
||
### Prerequisites
|
||
|
||
- Node.js 20.x or higher
|
||
- npm 10.x or higher
|
||
- Angular CLI 19.x
|
||
|
||
### Install Angular CLI
|
||
|
||
```bash
|
||
npm install -g @angular/cli@19
|
||
```
|
||
|
||
### Code Structure
|
||
|
||
**app.component.ts:**
|
||
- Handles form state and validation
|
||
- Manages file uploads and chunking
|
||
- Polls deployment status
|
||
- Updates progress and logs
|
||
|
||
**deploy.service.ts:**
|
||
- Encapsulates all HTTP API calls
|
||
- Returns RxJS Observables converted to Promises
|
||
- Handles Base64 encoding headers
|
||
|
||
**Styling:**
|
||
- Responsive grid layout
|
||
- Mobile-first design
|
||
- Terminal-style logs with custom scrollbar
|
||
- Gradient progress bar
|
||
|
||
## Troubleshooting
|
||
|
||
### CORS Errors
|
||
|
||
If you see CORS errors in the browser console:
|
||
|
||
1. **Development:** Configure proxy in `angular.json`:
|
||
```json
|
||
{
|
||
"serve": {
|
||
"options": {
|
||
"proxyConfig": "proxy.conf.json"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
Create `proxy.conf.json`:
|
||
```json
|
||
{
|
||
"/api": {
|
||
"target": "http://localhost:8080",
|
||
"secure": false
|
||
}
|
||
}
|
||
```
|
||
|
||
2. **Production:** nginx handles proxying (already configured)
|
||
|
||
### File Upload Fails
|
||
|
||
- Check that backend is running and accessible
|
||
- Verify `BACKEND_URL` environment variable
|
||
- Check browser console for error messages
|
||
- Enable DEBUG_MODE in backend to see detailed logs
|
||
|
||
### Deployment Timeout
|
||
|
||
- Default timeout is 10 minutes (120 attempts × 5 seconds)
|
||
- Increase `maxAttempts` in `pollDeploymentStatus()` if needed
|
||
- Check backend logs for actual deployment status
|
||
|
||
## Browser Support
|
||
|
||
- Chrome/Edge (latest)
|
||
- Firefox (latest)
|
||
- Safari (latest)
|
||
- Mobile browsers (iOS Safari, Chrome Android)
|
||
|
||
## License
|
||
|
||
MIT License - see main project README
|