Add WebApp KubeDiagrams
332
webapp/README.md
Normal file
@@ -0,0 +1,332 @@
|
||||
## Project Structure
|
||||
Web Interface for generating Kubernetes diagrams from manifests, Helm charts, or Helmfile files using Kubediagrams.
|
||||
# KubeDiagrams Web App
|
||||
A modern web interface for generating Kubernetes architecture diagrams from manifests, Helm charts, or Helmfile configurations using [KubeDiagrams](https://github.com/philippemerle/KubeDiagrams).
|
||||
## ✨ Features
|
||||
- **Multiple Input Types**: Support for Kubernetes manifests, Helm charts, and Helmfile configurations
|
||||
- **Flexible Output Formats**: Generate diagrams in PNG, SVG, PDF, DOT, and interactive HTML
|
||||
- **Interactive Viewer**: Explore diagrams with an interactive web viewer
|
||||
- **Built-in Examples**: Pre-loaded examples for quick testing
|
||||
- **History Management**: Keep track of your diagram generations
|
||||
- **Docker Support**: Easy deployment with Docker and Docker Compose
|
||||
- **Access Logging**: Apache Combined Log format compatible with GoAccess
|
||||
---
|
||||
|
||||
## Quick Start
|
||||
### Using Docker Compose (Recommended)
|
||||
1. **Clone the repository**
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd kubediagramswebui
|
||||
```
|
||||
2. **Start the application**
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
3. **Access the application**
|
||||
- Open your browser and navigate to `http://localhost:8080`
|
||||
That's it! The application is now running with both frontend and backend services.
|
||||
### Stopping the application
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
### Server-Side Tools (Required) (Include in requirements.txt)
|
||||
The following command-line tools must be installed and available in your PATH:
|
||||
- **`kube-diagrams/helm-diagrams`** - For generating diagrams from Kubernetes manifests and for generating diagrams from Helm charts ([Installation](https://github.com/philippemerle/KubeDiagrams))
|
||||
- **`helmfile`** - Required only for Helmfile tab functionality ([Installation](https://github.com/helmfile/helmfile))
|
||||
### Docker Deployment
|
||||
- Docker Engine 20.10+
|
||||
- Docker Compose
|
||||
### Manual Deployment
|
||||
- **Backend**: Python 3.8+, pip, venv
|
||||
- **Frontend**: Node.js 18+, npm
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
```
|
||||
webapp/
|
||||
├── backend/ # Python/Flask backend
|
||||
│ ├── routes/ # Flask route handlers
|
||||
│ │ ├── manifest.py # Manifest diagram generation endpoints
|
||||
│ │ ├── helm.py # Helm chart diagram endpoints
|
||||
│ │ ├── helmfile.py # Helmfile diagram endpoints
|
||||
│ │ └── submit.py # Feedback submission endpoint
|
||||
│ ├── services/ # Business logic layer
|
||||
│ │ ├── manifestService.py # Manifest processing service
|
||||
│ │ ├── helmService.py # Helm processing service
|
||||
│ │ ├── helmfileService.py # Helmfile processing service
|
||||
│ │ ├── file_manager.py # File operations manager
|
||||
│ │ └── models.py # Data models
|
||||
│ ├── utils/ # Utility modules
|
||||
│ │ ├── access_logger.py # Request logging
|
||||
│ │ ├── logger.py # General logging
|
||||
│ │ ├── response_builder.py # API response builder
|
||||
│ │ └── validators.py # Input validation
|
||||
│ ├── app.py # Flask application entry point
|
||||
│ ├── config.py # Configuration settings
|
||||
│ ├── constants.py # Global constants
|
||||
│ ├── requirements.txt # Python dependencies
|
||||
│ ├── Dockerfile # Backend Docker image
|
||||
│ └── logs/ # Log files (auto-rotation)
|
||||
│
|
||||
├── frontend/ # React/Vite frontend
|
||||
│ ├── src/
|
||||
│ │ ├── components/ # React components
|
||||
│ │ │ ├── common/ # Reusable UI components
|
||||
│ │ │ ├── options/ # Diagram configuration components
|
||||
│ │ │ └── tabs/ # Main tab components
|
||||
│ │ │ ├── ManifestTab/ # Kubernetes manifest tab
|
||||
│ │ │ ├── HelmTab/ # Helm chart tab
|
||||
│ │ │ ├── HelmFileTab/ # Helmfile tab
|
||||
│ │ │ └── InteractiveViewerTab/ # Interactive viewer
|
||||
│ │ ├── examples/ # Example registry
|
||||
│ │ ├── hooks/ # Custom React hooks
|
||||
│ │ ├── services/ # API client services
|
||||
│ │ ├── utils/ # Utility functions
|
||||
│ │ ├── App.jsx # Main application component
|
||||
│ │ └── main.jsx # Application entry point
|
||||
│ ├── public/
|
||||
│ │ ├── examples/ # Example YAML files
|
||||
│ │ │ ├── manifests/ # Manifest examples
|
||||
│ │ │ └── helmfiles/ # Helmfile examples
|
||||
│ │ └── interactive_viewer/ # Interactive viewer assets
|
||||
│ ├── package.json # NPM dependencies
|
||||
│ ├── vite.config.js # Vite configuration
|
||||
│ ├── apache.conf # Apache reverse proxy config
|
||||
│ └── Dockerfile # Frontend Docker image
|
||||
│
|
||||
└── docker-compose.yml # Docker Compose orchestration
|
||||
```
|
||||
---
|
||||
## Manual Installation (Without Docker)
|
||||
### Backend Setup
|
||||
1. **Navigate to backend directory**
|
||||
```bash
|
||||
cd backend
|
||||
```
|
||||
2. **Create and activate virtual environment**
|
||||
```bash
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate # On Windows: venv\Scripts\activate
|
||||
```
|
||||
3. **Install dependencies**
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
4. **Start the Flask server**
|
||||
```bash
|
||||
python3 app.py
|
||||
```
|
||||
The backend server will be available at `http://localhost:5000`
|
||||
### Frontend Setup
|
||||
1. **Navigate to frontend directory**
|
||||
```bash
|
||||
cd frontend
|
||||
```
|
||||
2. **Install dependencies**
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
or
|
||||
```bash
|
||||
npm ci
|
||||
```
|
||||
3. **Start the development server**
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
The frontend will be available at `http://localhost:5173`
|
||||
|
||||
---
|
||||
## Docker Deployment
|
||||
### Architecture
|
||||
The Docker Compose setup consists of two services:
|
||||
- **Frontend**: Apache2 server serving React static files and acting as reverse proxy to the backend
|
||||
- **Backend**: Python/Flask application with Gunicorn WSGI server running KubeDiagrams
|
||||
### Configuration
|
||||
#### Environment Variables
|
||||
**Backend** (`backend/Dockerfile` or `docker-compose.yml`):
|
||||
- `FLASK_ENV`: Set to `production` for production deployment
|
||||
- `BEHIND_PROXY`: Set to `true` when running behind a reverse proxy (default: `true`)
|
||||
- `PROXY_X_FOR`: Number of trusted proxies (default: `1`)
|
||||
**Frontend** (`docker-compose.yml`):
|
||||
- `BACKEND_URL`: Backend service URL (default: `http://backend:5000`)
|
||||
#### Ports
|
||||
- **Frontend**: Port `8080` (mapped to container port `80`)
|
||||
- **Backend**: Port `5000` (internal only, accessed via frontend proxy)
|
||||
### Building and Running
|
||||
**Build and start services**:
|
||||
```bash
|
||||
docker-compose up --build
|
||||
```
|
||||
**Start in detached mode**:
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
**View logs**:
|
||||
```bash
|
||||
docker-compose logs -f
|
||||
```
|
||||
**Stop services**:
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
### Health Checks
|
||||
The backend includes a health check endpoint at `/api/health` that Docker uses to monitor service health.
|
||||
|
||||
---
|
||||
## Logging
|
||||
The Flask backend generates detailed access logs in **Apache Combined Log format**, compatible with tools like **GoAccess** for analysis.
|
||||
### Log Location
|
||||
- **Docker**: `./backend/logs/access.log` (persisted via volume mount)
|
||||
- **Manual**: `backend/logs/access.log`
|
||||
### Log Format
|
||||
```
|
||||
IP - - [datetime] "METHOD PATH PROTOCOL" STATUS SIZE "REFERER" "USER-AGENT" TIME_MS
|
||||
```
|
||||
### Log Rotation
|
||||
- **Frequency**: Daily at midnight
|
||||
- **Retention**: 30 days
|
||||
- **Format**: `access.log.YYYY-MM-DD`
|
||||
### IP Address Detection
|
||||
When running behind a reverse proxy (Apache, Nginx), the backend correctly identifies client IPs using `X-Forwarded-For` headers.
|
||||
**Debug endpoint**: `GET /api/debug/ip` - Returns IP detection information
|
||||
---
|
||||
## Usage Guide
|
||||
|
||||
### 1. Kubernetes Manifest Tab
|
||||
Generate diagrams from raw Kubernetes YAML manifests.
|
||||
**Steps**:
|
||||
1. Select the "Manifest" tab
|
||||
2. Paste your Kubernetes YAML or load an example
|
||||
3. Configure diagram options (format, orientation, colors, etc.)
|
||||
4. Click "Generate Diagram"
|
||||
5. Download the generated diagram or view it interactively
|
||||
**Supported Resources**: Deployments, StatefulSets, Services, Ingresses, ConfigMaps, Secrets, PVCs, and more.
|
||||
|
||||
### 2. Helm Chart Tab
|
||||
Generate diagrams from Helm chart URLs.
|
||||
**Steps**:
|
||||
1. Select the "Helm" tab
|
||||
2. Enter the Helm chart URL (e.g., `https://charts.bitnami.com/bitnami/wordpress`)
|
||||
3. Optionally provide a values file
|
||||
4. Configure diagram options
|
||||
5. Click "Generate Diagram"
|
||||
**Note**: Supports both public Helm repositories and OCI registries.
|
||||
|
||||
### 3. Helmfile Tab
|
||||
Generate diagrams from Helmfile configurations.
|
||||
**Steps**:
|
||||
1. Select the "Helmfile" tab
|
||||
2. Paste your Helmfile YAML or load an example
|
||||
3. Configure diagram options
|
||||
4. Click "Generate Diagram"
|
||||
**Requirement**: `helmfile` must be installed on the server.
|
||||
|
||||
### 4. Interactive Viewer
|
||||
View diagrams in an interactive HTML viewer with zoom, pan, and search capabilities.
|
||||
**Features**:
|
||||
- Search nodes by name
|
||||
- Highlight nodes on hover
|
||||
- Pan and zoom controls
|
||||
- Responsive design
|
||||
---
|
||||
## ️ Configuration Options
|
||||
### Diagram Options
|
||||
- **Format**: PNG, SVG, PDF, DOT, Interactive HTML
|
||||
- **CLI Arguments**: Optional custom parameters passed to the underlying KubeDiagrams tools
|
||||
- **Without Namespace**: Option to generate diagrams without namespace grouping
|
||||
- **Feedback System**: Rate diagrams (1-5 stars) and provide comments for improvement
|
||||
|
||||
### Available via CLI Arguments
|
||||
The CLI arguments field allows you to pass additional parameters to customize diagram generation. Refer to [KubeDiagrams documentation](https://github.com/cloudogu/kubediagrams) for available options.
|
||||
|
||||
---
|
||||
## Examples
|
||||
The application includes built-in examples for quick testing:
|
||||
### Manifest Examples
|
||||
- **Redis StatefulSet**: Redis cluster with persistent storage
|
||||
- **Microservices**: Multi-service application with ingress
|
||||
- **WordPress**: WordPress with MySQL database
|
||||
- **Cassandra**: Cassandra StatefulSet with headless service
|
||||
### Helmfile Examples
|
||||
- **Monitoring Stack**: Prometheus, Grafana, and AlertManager
|
||||
|
||||
### Adding Custom Examples
|
||||
See `frontend/public/examples/README.md` for instructions on adding new examples.
|
||||
|
||||
---
|
||||
## API Endpoints
|
||||
### Backend API
|
||||
- `POST /api/manifest/generate` - Generate diagram from manifest
|
||||
- `POST /api/helm/generate` - Generate diagram from Helm chart
|
||||
- `POST /api/helmfile/generate` - Generate diagram from Helmfile
|
||||
- `POST /api/submit` - Submit feedback
|
||||
|
||||
---
|
||||
## Troubleshooting
|
||||
### Common Issues
|
||||
**Issue**: "Command not found: kube-diagrams"
|
||||
- **Solution**: Ensure KubeDiagrams is installed and in your PATH
|
||||
**Issue**: Diagram generation fails with Helm charts
|
||||
- **Solution**: Verify `helm-diagrams` is installed and the chart URL is accessible
|
||||
**Issue**: Frontend cannot connect to backend
|
||||
- **Solution**: Check that backend is running and CORS is properly configured
|
||||
**Issue**: IP addresses showing as proxy IP instead of client IP
|
||||
- **Solution**: Verify `BEHIND_PROXY=true` and `PROXY_X_FOR` is set correctly
|
||||
|
||||
### Debug Mode
|
||||
Enable debug mode by setting `DEBUG=True` in `backend/config.py` for more detailed error messages.
|
||||
|
||||
---
|
||||
## Testing
|
||||
### Quick Test
|
||||
1. Start both backend and frontend servers
|
||||
2. Navigate to `http://localhost:8080` (Docker) or `http://localhost:5173` (manual)
|
||||
3. Select the "Manifest" tab
|
||||
4. Load an example (e.g., "Redis StatefulSet")
|
||||
5. Click "Generate Diagram"
|
||||
6. Verify the diagram is generated and can be downloaded
|
||||
---
|
||||
## Development
|
||||
### Frontend Development
|
||||
```bash
|
||||
cd frontend
|
||||
npm run dev # Start development server
|
||||
npm run build # Build for production
|
||||
npm run lint # Run ESLint
|
||||
npm run format # Format code with Prettier
|
||||
```
|
||||
### Backend Development
|
||||
```bash
|
||||
cd backend
|
||||
source venv/bin/activate
|
||||
python3 app.py # Start Flask server in debug mode
|
||||
```
|
||||
### Technologies Used
|
||||
**Backend**:
|
||||
- Flask 3.1.2 - Web framework
|
||||
- Gunicorn 23.0.0 - WSGI server
|
||||
- KubeDiagrams 0.6.0 - Diagram generation
|
||||
- PyYAML 6.0.2 - YAML parsing
|
||||
**Frontend**:
|
||||
- React 19.1.0 - UI framework
|
||||
- Vite 6.3.5 - Build tool
|
||||
- TailwindCSS 4.1.6 - Styling
|
||||
- Lucide React - Icons
|
||||
- Motion - Animations
|
||||
---
|
||||
|
||||
## Contributing
|
||||
Contributions are welcome! Please feel free to submit a Pull Request.
|
||||
|
||||
---
|
||||
## Support
|
||||
For issues and questions, please open an issue on the GitHub repository.
|
||||
|
||||
---
|
||||
## 🙏 Acknowledgments
|
||||
- [Graphviz](https://graphviz.org/) - Graph visualization software
|
||||
36
webapp/backend/.dockerignore
Normal file
@@ -0,0 +1,36 @@
|
||||
# Virtual environment
|
||||
venv/
|
||||
.venv/
|
||||
env/
|
||||
|
||||
# Python cache
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
|
||||
# Logs (will be mounted as volume)
|
||||
logs/*.log
|
||||
logs/*.csv
|
||||
|
||||
# Development files
|
||||
.git
|
||||
.gitignore
|
||||
*.md
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
# Test files
|
||||
test-*.png
|
||||
test-*.svg
|
||||
*.test.py
|
||||
|
||||
# OS files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.bak
|
||||
63
webapp/backend/Dockerfile
Normal file
@@ -0,0 +1,63 @@
|
||||
# =============================================================================
|
||||
# KubeDiagrams Backend - Dockerfile
|
||||
# =============================================================================
|
||||
# Base image from KubeDiagrams project (Philippe Merle)
|
||||
# Includes: Helm, Graphviz, Python, PyYAML, diagrams
|
||||
# =============================================================================
|
||||
|
||||
# --- Stage 1: Get Helm binary ---
|
||||
FROM docker.io/alpine/helm:3 AS helm
|
||||
|
||||
# --- Stage 2: Build backend ---
|
||||
FROM docker.io/python:3.13-alpine AS base
|
||||
|
||||
# Install system dependencies
|
||||
RUN apk update && apk add --no-cache \
|
||||
graphviz \
|
||||
bash \
|
||||
ttf-freefont \
|
||||
curl \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
# Copy Helm from first stage
|
||||
COPY --from=helm /usr/bin/helm /usr/local/bin/helm
|
||||
|
||||
# Install Helmfile from GitHub releases (Alpine/musl version)
|
||||
ARG HELMFILE_VERSION=1.2.3
|
||||
RUN curl -fsSL -o /tmp/helmfile.tar.gz \
|
||||
"https://github.com/helmfile/helmfile/releases/download/v${HELMFILE_VERSION}/helmfile_${HELMFILE_VERSION}_linux_386.tar.gz" && \
|
||||
tar -xzf /tmp/helmfile.tar.gz -C /usr/local/bin helmfile && \
|
||||
chmod +x /usr/local/bin/helmfile && \
|
||||
rm /tmp/helmfile.tar.gz
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Copy requirements first (for Docker layer caching)
|
||||
COPY requirements.txt .
|
||||
|
||||
# Install Python dependencies
|
||||
RUN pip install --no-cache-dir --upgrade pip && \
|
||||
pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy backend application code
|
||||
COPY . .
|
||||
|
||||
# Create logs directory
|
||||
RUN mkdir -p logs && chmod 755 logs
|
||||
|
||||
# Environment variables
|
||||
ENV FLASK_APP=app.py
|
||||
ENV FLASK_ENV=production
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
ENV BEHIND_PROXY=true
|
||||
ENV PROXY_X_FOR=1
|
||||
|
||||
# Expose port
|
||||
EXPOSE 5000
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
||||
CMD curl --fail --silent http://localhost:5000/api/health || exit 1
|
||||
|
||||
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "4", "--timeout", "120", "--access-logfile", "-", "--error-logfile", "-", "app:app"]
|
||||
BIN
webapp/backend/__pycache__/app.cpython-312.pyc
Normal file
BIN
webapp/backend/__pycache__/config.cpython-312.pyc
Normal file
BIN
webapp/backend/__pycache__/constants.cpython-312.pyc
Normal file
112
webapp/backend/app.py
Normal file
@@ -0,0 +1,112 @@
|
||||
"""Flask Application for KubeDiagrams Web UI."""
|
||||
from flask import Flask, g, request, jsonify
|
||||
from flask_cors import CORS
|
||||
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||
from config import Config, setup_logging
|
||||
from routes.manifest import manifest_bp
|
||||
from routes.helm import helm_bp
|
||||
from routes.helmfile import helmfile_bp
|
||||
from routes.submit import submit_bp
|
||||
from utils.access_logger import log_request, get_real_ip, get_all_ip_headers
|
||||
from time import time
|
||||
|
||||
|
||||
def create_app():
|
||||
app = Flask(__name__)
|
||||
|
||||
# Health check endpoint
|
||||
@app.route('/api/health', methods=['GET'])
|
||||
def health_check():
|
||||
"""Health check endpoint for monitoring and testing."""
|
||||
return jsonify({
|
||||
'status': 'healthy',
|
||||
'service': 'kubediagrams-backend',
|
||||
'version': '1.0.0'
|
||||
}), 200
|
||||
|
||||
# Debug endpoint for IP testing
|
||||
@app.route('/api/debug/ip', methods=['GET'])
|
||||
def debug_ip():
|
||||
"""
|
||||
Debug endpoint to check IP detection.
|
||||
Returns all IP-related information for debugging proxy configuration.
|
||||
"""
|
||||
return jsonify({
|
||||
'detected_ip': get_real_ip(),
|
||||
'remote_addr': request.remote_addr,
|
||||
'headers': get_all_ip_headers(),
|
||||
'behind_proxy': Config.BEHIND_PROXY,
|
||||
'proxy_x_for': Config.PROXY_X_FOR
|
||||
}), 200
|
||||
|
||||
# Proxy Configuration
|
||||
# When running behind a reverse proxy (nginx, Apache, HAProxy), the proxy
|
||||
# forwards requests to the application. By default, Flask sees the proxy's IP
|
||||
# instead of the real client IP. ProxyFix corrects this by reading the
|
||||
# X-Forwarded-* headers that the proxy sets.
|
||||
if Config.BEHIND_PROXY:
|
||||
app.wsgi_app = ProxyFix(
|
||||
app.wsgi_app,
|
||||
x_for=Config.PROXY_X_FOR, # Number of proxies setting X-Forwarded-For
|
||||
x_proto=Config.PROXY_X_PROTO, # Number of proxies setting X-Forwarded-Proto
|
||||
x_host=Config.PROXY_X_HOST, # Number of proxies setting X-Forwarded-Host
|
||||
x_prefix=Config.PROXY_X_PREFIX # Number of proxies setting X-Forwarded-Prefix
|
||||
)
|
||||
|
||||
# CORS Configuration
|
||||
if Config.CORS_ENABLED:
|
||||
CORS(app)
|
||||
|
||||
# Logging Configuration
|
||||
setup_logging()
|
||||
|
||||
# Middleware pour logger les requêtes
|
||||
@app.before_request
|
||||
def before_request():
|
||||
"""Save request start time for performance logging."""
|
||||
g.request_start_time = time()
|
||||
|
||||
@app.after_request
|
||||
def after_request(response):
|
||||
"""Log request in Apache Combined Log Format."""
|
||||
# Skip logging for health checks to avoid log spam
|
||||
if request.path == '/api/health':
|
||||
return response
|
||||
|
||||
# Get response size
|
||||
response_size = response.calculate_content_length() or 0
|
||||
|
||||
# Log the request
|
||||
log_request(
|
||||
status_code=response.status_code,
|
||||
response_size=response_size
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
# Blueprints registration
|
||||
app.register_blueprint(manifest_bp)
|
||||
app.register_blueprint(helm_bp)
|
||||
app.register_blueprint(helmfile_bp)
|
||||
app.register_blueprint(submit_bp)
|
||||
|
||||
return app
|
||||
|
||||
|
||||
app = create_app() # App Initialization
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=" * 50)
|
||||
print("Flask Application Configuration")
|
||||
print("=" * 50)
|
||||
print(f"BEHIND_PROXY: {Config.BEHIND_PROXY}")
|
||||
print(f"PROXY_X_FOR: {Config.PROXY_X_FOR}")
|
||||
print(f"PROXY_X_PROTO: {Config.PROXY_X_PROTO}")
|
||||
print(f"PROXY_X_HOST: {Config.PROXY_X_HOST}")
|
||||
print(f"PROXY_X_PREFIX: {Config.PROXY_X_PREFIX}")
|
||||
print(f"DEBUG: {Config.DEBUG}")
|
||||
print(f"PORT: {Config.PORT}")
|
||||
print(f"HOST: {Config.HOST}")
|
||||
print("=" * 50)
|
||||
print("")
|
||||
app.run(port=Config.PORT, debug=Config.DEBUG)
|
||||
95
webapp/backend/config.py
Normal file
@@ -0,0 +1,95 @@
|
||||
"""Configuration Flask application."""
|
||||
import os
|
||||
import logging
|
||||
from logging.handlers import TimedRotatingFileHandler
|
||||
from datetime import datetime, time as dt_time
|
||||
|
||||
class Config:
|
||||
"""Config App and Logger."""
|
||||
|
||||
# Flask
|
||||
DEBUG = True
|
||||
PORT = 5000
|
||||
HOST = 'localhost'
|
||||
|
||||
# CORS
|
||||
CORS_ENABLED = True
|
||||
|
||||
# Proxy Configuration
|
||||
# Set to True when running behind a reverse proxy (nginx, Apache, etc.)
|
||||
# This enables proper forwarding of client IP addresses
|
||||
BEHIND_PROXY = os.environ.get('BEHIND_PROXY', 'false').lower() == 'true'
|
||||
# Number of trusted proxies in front of the application
|
||||
# X-Forwarded-For: client, proxy1, proxy2 -> set to 2 if you have 2 proxies
|
||||
PROXY_X_FOR = int(os.environ.get('PROXY_X_FOR', '1'))
|
||||
PROXY_X_PROTO = int(os.environ.get('PROXY_X_PROTO', '1'))
|
||||
PROXY_X_HOST = int(os.environ.get('PROXY_X_HOST', '1'))
|
||||
PROXY_X_PREFIX = int(os.environ.get('PROXY_X_PREFIX', '1'))
|
||||
|
||||
LOG_DIR = "logs"
|
||||
LOG_FILE = "access.log"
|
||||
LOG_FORMAT = '%(message)s'
|
||||
LOG_LEVEL = logging.INFO
|
||||
LOG_ROTATION = "midnight"
|
||||
LOG_INTERVAL = 1
|
||||
LOG_BACKUP_COUNT = 30
|
||||
LOG_ENCODING = 'utf-8'
|
||||
LOG_SUFFIX = "%Y-%m-%d"
|
||||
LOGGER_NAME = "access_logger"
|
||||
# Disable automatic rotation based on file modification time
|
||||
# This prevents creating files with old dates
|
||||
LOG_USE_UTC = False
|
||||
# Fichiers
|
||||
FEEDBACK_FILE = "feedback.txt"
|
||||
|
||||
@classmethod
|
||||
def get_log_path(cls):
|
||||
"""Return path of the logFile."""
|
||||
return os.path.join(cls.LOG_DIR, cls.LOG_FILE)
|
||||
|
||||
|
||||
def setup_logging():
|
||||
"""Config log system with proper rotation handling."""
|
||||
# Create a logs directory if it doesn't exist
|
||||
os.makedirs(Config.LOG_DIR, exist_ok=True)
|
||||
|
||||
# Create a formatter
|
||||
log_formatter = logging.Formatter(Config.LOG_FORMAT)
|
||||
|
||||
log_path = Config.get_log_path()
|
||||
|
||||
# Create a handler with rotation
|
||||
log_handler = TimedRotatingFileHandler(
|
||||
log_path,
|
||||
when=Config.LOG_ROTATION,
|
||||
interval=Config.LOG_INTERVAL,
|
||||
backupCount=Config.LOG_BACKUP_COUNT,
|
||||
encoding=Config.LOG_ENCODING,
|
||||
utc=Config.LOG_USE_UTC
|
||||
)
|
||||
log_handler.setFormatter(log_formatter)
|
||||
log_handler.suffix = Config.LOG_SUFFIX
|
||||
|
||||
current_time = datetime.now()
|
||||
# Calculate next midnight
|
||||
next_midnight = datetime.combine(
|
||||
current_time.date(),
|
||||
dt_time(0, 0, 0)
|
||||
)
|
||||
if current_time >= next_midnight:
|
||||
# If we're past midnight today, rollover at next midnight
|
||||
from datetime import timedelta
|
||||
next_midnight = next_midnight + timedelta(days=1)
|
||||
|
||||
# Set the rollover time (in seconds since epoch)
|
||||
log_handler.rolloverAt = next_midnight.timestamp()
|
||||
|
||||
# Config logger
|
||||
logger = logging.getLogger(Config.LOGGER_NAME)
|
||||
logger.setLevel(Config.LOG_LEVEL)
|
||||
|
||||
# Remove existing handlers to avoid duplicates
|
||||
logger.handlers.clear()
|
||||
logger.addHandler(log_handler)
|
||||
|
||||
return logger
|
||||
23
webapp/backend/constants.py
Normal file
@@ -0,0 +1,23 @@
|
||||
"""Constantes of the backend"""
|
||||
import re
|
||||
# Different format of mime_types
|
||||
MIME_TYPES = {
|
||||
"png": "image/png",
|
||||
"jpg": "image/jpeg",
|
||||
"jpeg": "image/jpeg",
|
||||
"gif": "image/gif",
|
||||
"svg": "image/svg+xml",
|
||||
"pdf": "application/pdf",
|
||||
"dot": "text/vnd.graphviz",
|
||||
"dot_json": "application/json"
|
||||
}
|
||||
# no binary format
|
||||
TEXT_FORMATS = {"svg", "dot", "dot_json"}
|
||||
# Manifest_detector
|
||||
MANIFEST_RE = re.compile(r'^\s*apiVersion\s*:\s*.+$', re.MULTILINE)
|
||||
KIND_RE = re.compile(r'^\s*kind\s*:\s*.+$', re.MULTILINE)
|
||||
# Max log length
|
||||
MAX_LOG_LENGTH = 999999
|
||||
# file extensions
|
||||
YAML_EXTENSIONS = ['.yaml', '.yml']
|
||||
TGZ_EXTENSIONS = ['.tgz', '.tar.gz']
|
||||
8
webapp/backend/feedback.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
[MANIFEST]
|
||||
Note: 0
|
||||
Commentaire: test
|
||||
|
||||
[HELMFILE]
|
||||
Note: 5
|
||||
Commentaire: ttt
|
||||
|
||||
24
webapp/backend/logs/access.log
Normal file
@@ -0,0 +1,24 @@
|
||||
172.20.0.1 - - [27/Jan/2026:10:12:34 +0000] "POST /api/generate-diagram HTTP/1.1" 200 79665 "http://localhost:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 608.50ms
|
||||
172.20.0.1 - - [27/Jan/2026:10:18:03 +0000] "POST /api/generate-diagram HTTP/1.1" 200 6554 "http://localhost:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 579.44ms
|
||||
172.20.0.1 - - [27/Jan/2026:10:19:27 +0000] "GET /api/debug/ip HTTP/1.1" 200 278 "-" "curl/8.5.0" 0.74ms
|
||||
192.168.1.59 - - [27/Jan/2026:10:20:59 +0000] "POST /api/generate-diagram HTTP/1.1" 200 91057 "http://192.168.1.123:8080/" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Mobile Safari/537.36" 476.36ms
|
||||
192.168.1.123 - - [27/Jan/2026:10:21:23 +0000] "POST /api/generate-helmfile-diagram HTTP/1.1" 200 707287 "http://192.168.1.123:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 10285.02ms
|
||||
10.201.9.161 - - [27/Jan/2026:12:18:52 +0000] "POST /api/generate-helm-diagram HTTP/1.1" 200 201474 "http://10.201.9.161:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 3347.54ms
|
||||
10.201.8.211 - - [27/Jan/2026:12:22:49 +0000] "POST /api/generate-diagram HTTP/1.1" 200 79665 "http://10.201.9.161:8080/" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Mobile Safari/537.36" 451.44ms
|
||||
172.20.0.1 - - [27/Jan/2026:12:24:03 +0000] "POST /api/generate-helmfile-diagram HTTP/1.1" 200 707287 "http://localhost:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 8655.16ms
|
||||
10.201.9.161 - - [27/Jan/2026:12:24:09 +0000] "POST /api/generate-helm-diagram HTTP/1.1" 200 201474 "http://10.201.9.161:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 3420.22ms
|
||||
10.201.8.211 - - [27/Jan/2026:12:24:59 +0000] "POST /api/generate-helm-diagram HTTP/1.1" 200 114224 "http://10.201.9.161:8080/" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Mobile Safari/537.36" 1229.77ms
|
||||
10.201.9.161 - - [27/Jan/2026:12:25:01 +0000] "POST /api/generate-helm-diagram HTTP/1.1" 400 2469 "http://10.201.9.161:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 2978.06ms
|
||||
172.20.0.1 - - [27/Jan/2026:12:25:15 +0000] "POST /api/generate-helm-diagram HTTP/1.1" 200 154735 "http://localhost:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 13762.43ms
|
||||
172.20.0.1 - - [27/Jan/2026:12:51:51 +0000] "POST /api/generate-diagram HTTP/1.1" 200 6413 "http://localhost:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 490.70ms
|
||||
172.20.0.1 - - [27/Jan/2026:12:52:42 +0000] "POST /api/generate-diagram HTTP/1.1" 200 79665 "http://localhost:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 519.98ms
|
||||
172.20.0.1 - - [27/Jan/2026:12:53:53 +0000] "POST /api/generate-helmfile-diagram HTTP/1.1" 200 707287 "http://localhost:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 8321.61ms
|
||||
10.201.9.161 - - [27/Jan/2026:13:22:17 +0000] "POST /api/generate-diagram HTTP/1.1" 200 79665 "http://10.201.9.161:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 561.96ms
|
||||
10.201.9.161 - - [27/Jan/2026:13:24:12 +0000] "POST /api/generate-helmfile-diagram HTTP/1.1" 200 707287 "http://10.201.9.161:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 8609.22ms
|
||||
10.201.8.211 - - [27/Jan/2026:13:42:54 +0000] "POST /api/generate-diagram HTTP/1.1" 200 79665 "http://10.201.9.161:8080/" "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Mobile Safari/537.36" 452.02ms
|
||||
10.201.9.161 - - [27/Jan/2026:13:50:05 +0000] "POST /api/generate-diagram HTTP/1.1" 200 93003 "http://10.201.9.161:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 646.66ms
|
||||
10.201.9.161 - - [27/Jan/2026:13:51:25 +0000] "POST /api/generate-helm-diagram HTTP/1.1" 200 2797664 "http://10.201.9.161:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 15009.67ms
|
||||
10.201.9.161 - - [27/Jan/2026:14:28:46 +0000] "POST /api/generate-diagram HTTP/1.1" 200 92580 "http://10.201.9.161:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 619.55ms
|
||||
10.201.9.161 - - [27/Jan/2026:14:29:00 +0000] "POST /api/generate-diagram HTTP/1.1" 200 92580 "http://10.201.9.161:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 614.89ms
|
||||
10.201.9.161 - - [27/Jan/2026:14:29:22 +0000] "POST /api/generate-diagram HTTP/1.1" 200 83194 "http://10.201.9.161:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 536.01ms
|
||||
10.201.9.161 - - [27/Jan/2026:14:29:36 +0000] "POST /api/generate-diagram HTTP/1.1" 400 1269 "http://10.201.9.161:8080/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:147.0) Gecko/20100101 Firefox/147.0" 521.76ms
|
||||
121
webapp/backend/logs/logs.csv
Normal file
@@ -0,0 +1,121 @@
|
||||
2025-11-28 10:46:59,647 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 10:47:17,174 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=png;chartUrl=oci://ghcr.io/argoproj/argo-helm/argo-cd;extraArgs=
|
||||
2025-11-28 10:47:37,037 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=png;helmfile=;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 10:48:04,593 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n name: wordpress-mysql\n labels:\n app: wordpress\nspec:\n ports:\n - port: 3306\n selector:\n app: wordpress\n tier: mysql\n clusterIP: None\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: mysql-pv-claim\n labels:\n app: wordpress\nspec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 512M # instead of 20Gi\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: wordpress-mysql\n labels:\n app: wordpress\nspec:\n selector:\n matchLabels:\n app: wordpress\n tier: mysql\n strategy:\n type: Recreate\n template:\n metadata:\n labels:\n app: wordpress\n tier: mysql\n spec:\n containers:\n - image: mysql:8.0\n name: mysql\n env:\n - name: MYSQL_ROOT_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n - name: MYSQL_DATABASE\n value: wordpress\n - name: MYSQL_USER\n value: wordpress\n - name: MYSQL_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n ports:\n - containerPort: 3306\n name: mysql\n volumeMounts:\n - name: mysql-persistent-storage\n mountPath: /var/lib/mysql\n volumes:\n - name: mysql-persistent-storage\n persistentVolumeClaim:\n claimName: mysql-pv-claim\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: mysql-pass\n labels:\n app: wordpress\ntype: Opaque\ndata:\n password: WU9VUl9QQVNTV09SRA==\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: wordpress\n labels:\n app: wordpress\nspec:\n ports:\n - port: 80\n selector:\n app: wordpress\n tier: frontend\n type: LoadBalancer\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: wp-pv-claim\n labels:\n app: wordpress\nspec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 512M # instead of 20Gi\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: wordpress\n labels:\n app: wordpress\nspec:\n selector:\n matchLabels:\n app: wordpress\n tier: frontend\n strategy:\n type: Recreate\n template:\n metadata:\n labels:\n app: wordpress\n tier: frontend\n spec:\n containers:\n - image: wordpress:6.2.1-apache\n name: wordpress\n env:\n - name: WORDPRESS_DB_HOST\n value: wordpress-mysql\n - name: WORDPRESS_DB_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n - name: WORDPRESS_DB_USER\n value: wordpress\n ports:\n - containerPort: 80\n name: wordpress\n volumeMounts:\n - name: wordpress-persistent-storage\n mountPath: /var/www/html\n volumes:\n - name: wordpress-persistent-storage\n persistentVolumeClaim:\n claimName: wp-pv-claim\n
|
||||
2025-11-28 10:48:07,055 ; 127.0.0.1 ; /api/generate-diagram ; format=jpg;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n name: wordpress-mysql\n labels:\n app: wordpress\nspec:\n ports:\n - port: 3306\n selector:\n app: wordpress\n tier: mysql\n clusterIP: None\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: mysql-pv-claim\n labels:\n app: wordpress\nspec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 512M # instead of 20Gi\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: wordpress-mysql\n labels:\n app: wordpress\nspec:\n selector:\n matchLabels:\n app: wordpress\n tier: mysql\n strategy:\n type: Recreate\n template:\n metadata:\n labels:\n app: wordpress\n tier: mysql\n spec:\n containers:\n - image: mysql:8.0\n name: mysql\n env:\n - name: MYSQL_ROOT_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n - name: MYSQL_DATABASE\n value: wordpress\n - name: MYSQL_USER\n value: wordpress\n - name: MYSQL_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n ports:\n - containerPort: 3306\n name: mysql\n volumeMounts:\n - name: mysql-persistent-storage\n mountPath: /var/lib/mysql\n volumes:\n - name: mysql-persistent-storage\n persistentVolumeClaim:\n claimName: mysql-pv-claim\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: mysql-pass\n labels:\n app: wordpress\ntype: Opaque\ndata:\n password: WU9VUl9QQVNTV09SRA==\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: wordpress\n labels:\n app: wordpress\nspec:\n ports:\n - port: 80\n selector:\n app: wordpress\n tier: frontend\n type: LoadBalancer\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: wp-pv-claim\n labels:\n app: wordpress\nspec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 512M # instead of 20Gi\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: wordpress\n labels:\n app: wordpress\nspec:\n selector:\n matchLabels:\n app: wordpress\n tier: frontend\n strategy:\n type: Recreate\n template:\n metadata:\n labels:\n app: wordpress\n tier: frontend\n spec:\n containers:\n - image: wordpress:6.2.1-apache\n name: wordpress\n env:\n - name: WORDPRESS_DB_HOST\n value: wordpress-mysql\n - name: WORDPRESS_DB_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n - name: WORDPRESS_DB_USER\n value: wordpress\n ports:\n - containerPort: 80\n name: wordpress\n volumeMounts:\n - name: wordpress-persistent-storage\n mountPath: /var/www/html\n volumes:\n - name: wordpress-persistent-storage\n persistentVolumeClaim:\n claimName: wp-pv-claim\n
|
||||
2025-11-28 10:48:08,985 ; 127.0.0.1 ; /api/generate-diagram ; format=jpeg;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n name: wordpress-mysql\n labels:\n app: wordpress\nspec:\n ports:\n - port: 3306\n selector:\n app: wordpress\n tier: mysql\n clusterIP: None\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: mysql-pv-claim\n labels:\n app: wordpress\nspec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 512M # instead of 20Gi\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: wordpress-mysql\n labels:\n app: wordpress\nspec:\n selector:\n matchLabels:\n app: wordpress\n tier: mysql\n strategy:\n type: Recreate\n template:\n metadata:\n labels:\n app: wordpress\n tier: mysql\n spec:\n containers:\n - image: mysql:8.0\n name: mysql\n env:\n - name: MYSQL_ROOT_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n - name: MYSQL_DATABASE\n value: wordpress\n - name: MYSQL_USER\n value: wordpress\n - name: MYSQL_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n ports:\n - containerPort: 3306\n name: mysql\n volumeMounts:\n - name: mysql-persistent-storage\n mountPath: /var/lib/mysql\n volumes:\n - name: mysql-persistent-storage\n persistentVolumeClaim:\n claimName: mysql-pv-claim\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: mysql-pass\n labels:\n app: wordpress\ntype: Opaque\ndata:\n password: WU9VUl9QQVNTV09SRA==\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: wordpress\n labels:\n app: wordpress\nspec:\n ports:\n - port: 80\n selector:\n app: wordpress\n tier: frontend\n type: LoadBalancer\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: wp-pv-claim\n labels:\n app: wordpress\nspec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 512M # instead of 20Gi\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: wordpress\n labels:\n app: wordpress\nspec:\n selector:\n matchLabels:\n app: wordpress\n tier: frontend\n strategy:\n type: Recreate\n template:\n metadata:\n labels:\n app: wordpress\n tier: frontend\n spec:\n containers:\n - image: wordpress:6.2.1-apache\n name: wordpress\n env:\n - name: WORDPRESS_DB_HOST\n value: wordpress-mysql\n - name: WORDPRESS_DB_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n - name: WORDPRESS_DB_USER\n value: wordpress\n ports:\n - containerPort: 80\n name: wordpress\n volumeMounts:\n - name: wordpress-persistent-storage\n mountPath: /var/www/html\n volumes:\n - name: wordpress-persistent-storage\n persistentVolumeClaim:\n claimName: wp-pv-claim\n
|
||||
2025-11-28 10:48:10,977 ; 127.0.0.1 ; /api/generate-diagram ; format=svg;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n name: wordpress-mysql\n labels:\n app: wordpress\nspec:\n ports:\n - port: 3306\n selector:\n app: wordpress\n tier: mysql\n clusterIP: None\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: mysql-pv-claim\n labels:\n app: wordpress\nspec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 512M # instead of 20Gi\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: wordpress-mysql\n labels:\n app: wordpress\nspec:\n selector:\n matchLabels:\n app: wordpress\n tier: mysql\n strategy:\n type: Recreate\n template:\n metadata:\n labels:\n app: wordpress\n tier: mysql\n spec:\n containers:\n - image: mysql:8.0\n name: mysql\n env:\n - name: MYSQL_ROOT_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n - name: MYSQL_DATABASE\n value: wordpress\n - name: MYSQL_USER\n value: wordpress\n - name: MYSQL_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n ports:\n - containerPort: 3306\n name: mysql\n volumeMounts:\n - name: mysql-persistent-storage\n mountPath: /var/lib/mysql\n volumes:\n - name: mysql-persistent-storage\n persistentVolumeClaim:\n claimName: mysql-pv-claim\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: mysql-pass\n labels:\n app: wordpress\ntype: Opaque\ndata:\n password: WU9VUl9QQVNTV09SRA==\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: wordpress\n labels:\n app: wordpress\nspec:\n ports:\n - port: 80\n selector:\n app: wordpress\n tier: frontend\n type: LoadBalancer\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: wp-pv-claim\n labels:\n app: wordpress\nspec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 512M # instead of 20Gi\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: wordpress\n labels:\n app: wordpress\nspec:\n selector:\n matchLabels:\n app: wordpress\n tier: frontend\n strategy:\n type: Recreate\n template:\n metadata:\n labels:\n app: wordpress\n tier: frontend\n spec:\n containers:\n - image: wordpress:6.2.1-apache\n name: wordpress\n env:\n - name: WORDPRESS_DB_HOST\n value: wordpress-mysql\n - name: WORDPRESS_DB_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n - name: WORDPRESS_DB_USER\n value: wordpress\n ports:\n - containerPort: 80\n name: wordpress\n volumeMounts:\n - name: wordpress-persistent-storage\n mountPath: /var/www/html\n volumes:\n - name: wordpress-persistent-storage\n persistentVolumeClaim:\n claimName: wp-pv-claim\n
|
||||
2025-11-28 10:48:14,483 ; 127.0.0.1 ; /api/generate-diagram ; format=pdf;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n name: wordpress-mysql\n labels:\n app: wordpress\nspec:\n ports:\n - port: 3306\n selector:\n app: wordpress\n tier: mysql\n clusterIP: None\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: mysql-pv-claim\n labels:\n app: wordpress\nspec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 512M # instead of 20Gi\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: wordpress-mysql\n labels:\n app: wordpress\nspec:\n selector:\n matchLabels:\n app: wordpress\n tier: mysql\n strategy:\n type: Recreate\n template:\n metadata:\n labels:\n app: wordpress\n tier: mysql\n spec:\n containers:\n - image: mysql:8.0\n name: mysql\n env:\n - name: MYSQL_ROOT_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n - name: MYSQL_DATABASE\n value: wordpress\n - name: MYSQL_USER\n value: wordpress\n - name: MYSQL_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n ports:\n - containerPort: 3306\n name: mysql\n volumeMounts:\n - name: mysql-persistent-storage\n mountPath: /var/lib/mysql\n volumes:\n - name: mysql-persistent-storage\n persistentVolumeClaim:\n claimName: mysql-pv-claim\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: mysql-pass\n labels:\n app: wordpress\ntype: Opaque\ndata:\n password: WU9VUl9QQVNTV09SRA==\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: wordpress\n labels:\n app: wordpress\nspec:\n ports:\n - port: 80\n selector:\n app: wordpress\n tier: frontend\n type: LoadBalancer\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: wp-pv-claim\n labels:\n app: wordpress\nspec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 512M # instead of 20Gi\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: wordpress\n labels:\n app: wordpress\nspec:\n selector:\n matchLabels:\n app: wordpress\n tier: frontend\n strategy:\n type: Recreate\n template:\n metadata:\n labels:\n app: wordpress\n tier: frontend\n spec:\n containers:\n - image: wordpress:6.2.1-apache\n name: wordpress\n env:\n - name: WORDPRESS_DB_HOST\n value: wordpress-mysql\n - name: WORDPRESS_DB_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n - name: WORDPRESS_DB_USER\n value: wordpress\n ports:\n - containerPort: 80\n name: wordpress\n volumeMounts:\n - name: wordpress-persistent-storage\n mountPath: /var/www/html\n volumes:\n - name: wordpress-persistent-storage\n persistentVolumeClaim:\n claimName: wp-pv-claim\n
|
||||
2025-11-28 10:48:18,374 ; 127.0.0.1 ; /api/generate-diagram ; format=dot;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n name: wordpress-mysql\n labels:\n app: wordpress\nspec:\n ports:\n - port: 3306\n selector:\n app: wordpress\n tier: mysql\n clusterIP: None\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: mysql-pv-claim\n labels:\n app: wordpress\nspec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 512M # instead of 20Gi\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: wordpress-mysql\n labels:\n app: wordpress\nspec:\n selector:\n matchLabels:\n app: wordpress\n tier: mysql\n strategy:\n type: Recreate\n template:\n metadata:\n labels:\n app: wordpress\n tier: mysql\n spec:\n containers:\n - image: mysql:8.0\n name: mysql\n env:\n - name: MYSQL_ROOT_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n - name: MYSQL_DATABASE\n value: wordpress\n - name: MYSQL_USER\n value: wordpress\n - name: MYSQL_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n ports:\n - containerPort: 3306\n name: mysql\n volumeMounts:\n - name: mysql-persistent-storage\n mountPath: /var/lib/mysql\n volumes:\n - name: mysql-persistent-storage\n persistentVolumeClaim:\n claimName: mysql-pv-claim\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: mysql-pass\n labels:\n app: wordpress\ntype: Opaque\ndata:\n password: WU9VUl9QQVNTV09SRA==\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: wordpress\n labels:\n app: wordpress\nspec:\n ports:\n - port: 80\n selector:\n app: wordpress\n tier: frontend\n type: LoadBalancer\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: wp-pv-claim\n labels:\n app: wordpress\nspec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 512M # instead of 20Gi\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: wordpress\n labels:\n app: wordpress\nspec:\n selector:\n matchLabels:\n app: wordpress\n tier: frontend\n strategy:\n type: Recreate\n template:\n metadata:\n labels:\n app: wordpress\n tier: frontend\n spec:\n containers:\n - image: wordpress:6.2.1-apache\n name: wordpress\n env:\n - name: WORDPRESS_DB_HOST\n value: wordpress-mysql\n - name: WORDPRESS_DB_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n - name: WORDPRESS_DB_USER\n value: wordpress\n ports:\n - containerPort: 80\n name: wordpress\n volumeMounts:\n - name: wordpress-persistent-storage\n mountPath: /var/www/html\n volumes:\n - name: wordpress-persistent-storage\n persistentVolumeClaim:\n claimName: wp-pv-claim\n
|
||||
2025-11-28 10:48:25,333 ; 127.0.0.1 ; /api/generate-diagram ; format=dot_json;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n name: wordpress-mysql\n labels:\n app: wordpress\nspec:\n ports:\n - port: 3306\n selector:\n app: wordpress\n tier: mysql\n clusterIP: None\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: mysql-pv-claim\n labels:\n app: wordpress\nspec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 512M # instead of 20Gi\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: wordpress-mysql\n labels:\n app: wordpress\nspec:\n selector:\n matchLabels:\n app: wordpress\n tier: mysql\n strategy:\n type: Recreate\n template:\n metadata:\n labels:\n app: wordpress\n tier: mysql\n spec:\n containers:\n - image: mysql:8.0\n name: mysql\n env:\n - name: MYSQL_ROOT_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n - name: MYSQL_DATABASE\n value: wordpress\n - name: MYSQL_USER\n value: wordpress\n - name: MYSQL_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n ports:\n - containerPort: 3306\n name: mysql\n volumeMounts:\n - name: mysql-persistent-storage\n mountPath: /var/lib/mysql\n volumes:\n - name: mysql-persistent-storage\n persistentVolumeClaim:\n claimName: mysql-pv-claim\n---\napiVersion: v1\nkind: Secret\nmetadata:\n name: mysql-pass\n labels:\n app: wordpress\ntype: Opaque\ndata:\n password: WU9VUl9QQVNTV09SRA==\n---\napiVersion: v1\nkind: Service\nmetadata:\n name: wordpress\n labels:\n app: wordpress\nspec:\n ports:\n - port: 80\n selector:\n app: wordpress\n tier: frontend\n type: LoadBalancer\n---\napiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: wp-pv-claim\n labels:\n app: wordpress\nspec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 512M # instead of 20Gi\n---\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: wordpress\n labels:\n app: wordpress\nspec:\n selector:\n matchLabels:\n app: wordpress\n tier: frontend\n strategy:\n type: Recreate\n template:\n metadata:\n labels:\n app: wordpress\n tier: frontend\n spec:\n containers:\n - image: wordpress:6.2.1-apache\n name: wordpress\n env:\n - name: WORDPRESS_DB_HOST\n value: wordpress-mysql\n - name: WORDPRESS_DB_PASSWORD\n valueFrom:\n secretKeyRef:\n name: mysql-pass\n key: password\n - name: WORDPRESS_DB_USER\n value: wordpress\n ports:\n - containerPort: 80\n name: wordpress\n volumeMounts:\n - name: wordpress-persistent-storage\n mountPath: /var/www/html\n volumes:\n - name: wordpress-persistent-storage\n persistentVolumeClaim:\n claimName: wp-pv-claim\n
|
||||
2025-11-28 10:49:16,214 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=png;helmfile=;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 10:50:49,741 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=png;helmfile=repositories:\n - name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n - name: grafana\n url: https://grafana.github.io/helm-charts\n\nreleases:\n - name: prometheus\n namespace: monitoring\n chart: prometheus-community/prometheus\n version: 15.0.0\n values:\n - server:\n persistentVolume:\n enabled: true\n size: 8Gi\n\n - name: grafana\n namespace: monitoring\n chart: grafana/grafana\n version: 6.50.0\n values:\n - adminPassword: changeme\n persistence:\n enabled: true\n size: 5Gi\n\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 10:51:45,236 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=dot_json;helmfile=repositories:\n - name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n - name: grafana\n url: https://grafana.github.io/helm-charts\n\nreleases:\n - name: prometheus\n namespace: monitoring\n chart: prometheus-community/prometheus\n version: 15.0.0\n values:\n - server:\n persistentVolume:\n enabled: true\n size: 8Gi\n\n - name: grafana\n namespace: monitoring\n chart: grafana/grafana\n version: 6.50.0\n values:\n - adminPassword: changeme\n persistence:\n enabled: true\n size: 5Gi\n\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 10:52:07,872 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=pdf;helmfile=repositories:\n - name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n - name: grafana\n url: https://grafana.github.io/helm-charts\n\nreleases:\n - name: prometheus\n namespace: monitoring\n chart: prometheus-community/prometheus\n version: 15.0.0\n values:\n - server:\n persistentVolume:\n enabled: true\n size: 8Gi\n\n - name: grafana\n namespace: monitoring\n chart: grafana/grafana\n version: 6.50.0\n values:\n - adminPassword: changeme\n persistence:\n enabled: true\n size: 5Gi\n\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 10:53:16,735 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=dot_json;helmfile=repositories:\n - name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n - name: grafana\n url: https://grafana.github.io/helm-charts\n\nreleases:\n - name: prometheus\n namespace: monitoring\n chart: prometheus-community/prometheus\n version: 15.0.0\n values:\n - server:\n persistentVolume:\n enabled: true\n size: 8Gi\n\n - name: grafana\n namespace: monitoring\n chart: grafana/grafana\n version: 6.50.0\n values:\n - adminPassword: changeme\n persistence:\n enabled: true\n size: 5Gi\n\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 10:55:33,948 ; 127.0.0.1 ; /api/generate-diagram ; format=dot_json;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 10:59:52,363 ; 127.0.0.1 ; /api/generate-diagram ; format=dot_json;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n name: redis-service\nspec:\n clusterIP: None\n selector:\n app: redis\n ports:\n - port: 6379\n targetPort: 6379\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: redis\nspec:\n serviceName: redis-service\n replicas: 3\n selector:\n matchLabels:\n app: redis\n template:\n metadata:\n labels:\n app: redis\n spec:\n containers:\n - name: redis\n image: redis:7.0\n ports:\n - containerPort: 6379\n volumeMounts:\n - name: data\n mountPath: /data\n volumeClaimTemplates:\n - metadata:\n name: data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n resources:\n requests:\n storage: 1Gi\n\n
|
||||
2025-11-28 11:09:43,294 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command: \n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd\n
|
||||
2025-11-28 11:09:58,166 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=png;helmfile=repositories:\n- name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n\nreleases:\n- name: prom-norbac-ubuntu\n namespace: prometheus\n chart: prometheus-community/prometheus\n set:\n - name: rbac.create\n value: false\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 11:21:48,531 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:21:54,810 ; 127.0.0.1 ; /api/generate-diagram ; format=jpg;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:21:57,647 ; 127.0.0.1 ; /api/generate-diagram ; format=jpeg;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:21:59,337 ; 127.0.0.1 ; /api/generate-diagram ; format=svg;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:22:03,383 ; 127.0.0.1 ; /api/generate-diagram ; format=pdf;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:22:11,671 ; 127.0.0.1 ; /api/generate-diagram ; format=dot;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:22:14,625 ; 127.0.0.1 ; /api/generate-diagram ; format=dot_json;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:22:25,918 ; 127.0.0.1 ; /api/generate-diagram ; format=svg;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:22:31,130 ; 127.0.0.1 ; /api/generate-diagram ; format=dot_json;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:22:51,772 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=png;chartUrl=https://charts.jetstack.io/cert-manager;extraArgs=
|
||||
2025-11-28 11:22:55,039 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=jpg;chartUrl=https://charts.jetstack.io/cert-manager;extraArgs=
|
||||
2025-11-28 11:22:57,897 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=jpeg;chartUrl=https://charts.jetstack.io/cert-manager;extraArgs=
|
||||
2025-11-28 11:23:00,135 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=svg;chartUrl=https://charts.jetstack.io/cert-manager;extraArgs=
|
||||
2025-11-28 11:23:02,246 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=pdf;chartUrl=https://charts.jetstack.io/cert-manager;extraArgs=
|
||||
2025-11-28 11:23:05,591 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=dot;chartUrl=https://charts.jetstack.io/cert-manager;extraArgs=
|
||||
2025-11-28 11:23:08,547 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=dot_json;chartUrl=https://charts.jetstack.io/cert-manager;extraArgs=
|
||||
2025-11-28 11:23:33,878 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=png;helmfile=repositories:\n - name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n - name: grafana\n url: https://grafana.github.io/helm-charts\n\nreleases:\n - name: prometheus\n namespace: monitoring\n chart: prometheus-community/prometheus\n version: 15.0.0\n values:\n - server:\n persistentVolume:\n enabled: true\n size: 8Gi\n\n - name: grafana\n namespace: monitoring\n chart: grafana/grafana\n version: 6.50.0\n values:\n - adminPassword: changeme\n persistence:\n enabled: true\n size: 5Gi\n\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 11:23:38,138 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=dot_json;helmfile=repositories:\n - name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n - name: grafana\n url: https://grafana.github.io/helm-charts\n\nreleases:\n - name: prometheus\n namespace: monitoring\n chart: prometheus-community/prometheus\n version: 15.0.0\n values:\n - server:\n persistentVolume:\n enabled: true\n size: 8Gi\n\n - name: grafana\n namespace: monitoring\n chart: grafana/grafana\n version: 6.50.0\n values:\n - adminPassword: changeme\n persistence:\n enabled: true\n size: 5Gi\n\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 11:23:41,873 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=dot;helmfile=repositories:\n - name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n - name: grafana\n url: https://grafana.github.io/helm-charts\n\nreleases:\n - name: prometheus\n namespace: monitoring\n chart: prometheus-community/prometheus\n version: 15.0.0\n values:\n - server:\n persistentVolume:\n enabled: true\n size: 8Gi\n\n - name: grafana\n namespace: monitoring\n chart: grafana/grafana\n version: 6.50.0\n values:\n - adminPassword: changeme\n persistence:\n enabled: true\n size: 5Gi\n\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 11:23:45,957 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=pdf;helmfile=repositories:\n - name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n - name: grafana\n url: https://grafana.github.io/helm-charts\n\nreleases:\n - name: prometheus\n namespace: monitoring\n chart: prometheus-community/prometheus\n version: 15.0.0\n values:\n - server:\n persistentVolume:\n enabled: true\n size: 8Gi\n\n - name: grafana\n namespace: monitoring\n chart: grafana/grafana\n version: 6.50.0\n values:\n - adminPassword: changeme\n persistence:\n enabled: true\n size: 5Gi\n\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 11:23:49,736 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=svg;helmfile=repositories:\n - name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n - name: grafana\n url: https://grafana.github.io/helm-charts\n\nreleases:\n - name: prometheus\n namespace: monitoring\n chart: prometheus-community/prometheus\n version: 15.0.0\n values:\n - server:\n persistentVolume:\n enabled: true\n size: 8Gi\n\n - name: grafana\n namespace: monitoring\n chart: grafana/grafana\n version: 6.50.0\n values:\n - adminPassword: changeme\n persistence:\n enabled: true\n size: 5Gi\n\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 11:23:53,516 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=jpeg;helmfile=repositories:\n - name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n - name: grafana\n url: https://grafana.github.io/helm-charts\n\nreleases:\n - name: prometheus\n namespace: monitoring\n chart: prometheus-community/prometheus\n version: 15.0.0\n values:\n - server:\n persistentVolume:\n enabled: true\n size: 8Gi\n\n - name: grafana\n namespace: monitoring\n chart: grafana/grafana\n version: 6.50.0\n values:\n - adminPassword: changeme\n persistence:\n enabled: true\n size: 5Gi\n\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 11:23:58,608 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=jpg;helmfile=repositories:\n - name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n - name: grafana\n url: https://grafana.github.io/helm-charts\n\nreleases:\n - name: prometheus\n namespace: monitoring\n chart: prometheus-community/prometheus\n version: 15.0.0\n values:\n - server:\n persistentVolume:\n enabled: true\n size: 8Gi\n\n - name: grafana\n namespace: monitoring\n chart: grafana/grafana\n version: 6.50.0\n values:\n - adminPassword: changeme\n persistence:\n enabled: true\n size: 5Gi\n\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 11:33:17,932 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:33:28,865 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=True;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:33:39,735 ; 127.0.0.1 ; /api/generate-diagram ; format=svg;extraArgs=;withoutNamespace=True;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:33:51,170 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=png;chartUrl=https://charts.jetstack.io/cert-manager;extraArgs=
|
||||
2025-11-28 11:34:15,179 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=svg;chartUrl=https://charts.jetstack.io/cert-manager;extraArgs=
|
||||
2025-11-28 11:34:40,529 ; 127.0.0.1 ; /api/generate-diagram ; format=jpeg;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:37:44,041 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:37:48,813 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:37:51,380 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:37:52,775 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:38:03,632 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:38:45,637 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=png;chartUrl=https://grafana.github.io/helm-charts/grafana;extraArgs=
|
||||
2025-11-28 11:40:55,865 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=png;chartUrl=https://grafana.github.io/helm-charts/grafana;extraArgs=
|
||||
2025-11-28 11:41:04,816 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=svg;chartUrl=https://grafana.github.io/helm-charts/grafana;extraArgs=
|
||||
2025-11-28 11:41:07,810 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=dot;chartUrl=https://grafana.github.io/helm-charts/grafana;extraArgs=
|
||||
2025-11-28 11:41:10,493 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=dot_json;chartUrl=https://grafana.github.io/helm-charts/grafana;extraArgs=
|
||||
2025-11-28 11:41:23,669 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:41:27,014 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=True;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:41:28,875 ; 127.0.0.1 ; /api/generate-diagram ; format=jpg;extraArgs=;withoutNamespace=True;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:41:31,995 ; 127.0.0.1 ; /api/generate-diagram ; format=svg;extraArgs=;withoutNamespace=True;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:41:34,858 ; 127.0.0.1 ; /api/generate-diagram ; format=pdf;extraArgs=;withoutNamespace=True;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 11:41:37,788 ; 127.0.0.1 ; /api/generate-diagram ; format=dot_json;extraArgs=;withoutNamespace=True;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 12:43:34,942 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 12:47:33,411 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 12:47:37,639 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=True;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 12:47:52,325 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=--without-namespace;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 12:48:02,889 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 12:48:05,278 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=True;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 12:54:15,841 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 12:54:17,956 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=True;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 12:54:20,984 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 12:57:21,847 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:05:52,802 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=png;chartUrl=https://kubernetes.github.io/ingress-nginx/ingress-nginx;extraArgs=
|
||||
2025-11-28 13:17:41,041 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:17:46,245 ; 127.0.0.1 ; /api/generate-diagram ; format=jpg;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:17:48,736 ; 127.0.0.1 ; /api/generate-diagram ; format=jpeg;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:17:51,523 ; 127.0.0.1 ; /api/generate-diagram ; format=svg;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:17:53,849 ; 127.0.0.1 ; /api/generate-diagram ; format=pdf;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:17:56,179 ; 127.0.0.1 ; /api/generate-diagram ; format=dot;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:17:59,449 ; 127.0.0.1 ; /api/generate-diagram ; format=dot_json;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:18:42,089 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:21:19,948 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=png;chartUrl=https://prometheus-community.github.io/helm-charts/prometheus;extraArgs=
|
||||
2025-11-28 13:21:25,710 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=dot_json;chartUrl=https://prometheus-community.github.io/helm-charts/prometheus;extraArgs=
|
||||
2025-11-28 13:23:12,597 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:25:15,031 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:25:36,797 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=png;helmfile=repositories:\n- name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n\nreleases:\n- name: prom-norbac-ubuntu\n namespace: prometheus\n chart: prometheus-community/prometheus\n set:\n - name: rbac.create\n value: false\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 13:28:33,079 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:28:39,944 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=True;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:32:50,201 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:32:51,293 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:32:52,066 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:32:55,939 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:32:56,817 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:32:57,550 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:32:58,191 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:32:58,861 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:32:59,611 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:33:00,258 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:33:05,422 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=png;chartUrl=https://prometheus-community.github.io/helm-charts/prometheus;extraArgs=
|
||||
2025-11-28 13:33:16,300 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=png;helmfile=repositories:\n - name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n - name: grafana\n url: https://grafana.github.io/helm-charts\n\nreleases:\n - name: prometheus\n namespace: monitoring\n chart: prometheus-community/prometheus\n version: 15.0.0\n values:\n - server:\n persistentVolume:\n enabled: true\n size: 8Gi\n\n - name: grafana\n namespace: monitoring\n chart: grafana/grafana\n version: 6.50.0\n values:\n - adminPassword: changeme\n persistence:\n enabled: true\n size: 5Gi\n\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 13:37:25,304 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:37:28,741 ; 127.0.0.1 ; /api/generate-diagram ; format=jpeg;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:37:31,008 ; 127.0.0.1 ; /api/generate-diagram ; format=svg;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:37:35,563 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=jpeg;helmfile=;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 13:37:36,927 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=jpeg;helmfile=;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 13:37:39,362 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=jpeg;helmfile=repositories:\n - name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n - name: grafana\n url: https://grafana.github.io/helm-charts\n\nreleases:\n - name: prometheus\n namespace: monitoring\n chart: prometheus-community/prometheus\n version: 15.0.0\n values:\n - server:\n persistentVolume:\n enabled: true\n size: 8Gi\n\n - name: grafana\n namespace: monitoring\n chart: grafana/grafana\n version: 6.50.0\n values:\n - adminPassword: changeme\n persistence:\n enabled: true\n size: 5Gi\n\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 13:38:17,604 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=jpeg;helmfile=repositories:\n - name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n - name: grafana\n url: https://grafana.github.io/helm-charts\n\nreleases:\n - name: prometheus\n namespace: monitoring\n chart: prometheus-community/prometheus\n version: 15.0.0\n values:\n - server:\n persistentVolume:\n enabled: true\n size: 8Gi\n\n - name: grafana\n namespace: monitoring\n chart: grafana/grafana\n version: 6.50.0\n values:\n - adminPassword: changeme\n persistence:\n enabled: true\n size: 5Gi\n\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 13:49:00,253 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 13:58:25,432 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 14:00:16,585 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=png;chartUrl=https://charts.bitnami.com/bitnami/redis;extraArgs=
|
||||
2025-11-28 14:00:47,887 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 14:00:58,825 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=png;chartUrl=https://kubernetes.github.io/ingress-nginx/ingress-nginx;extraArgs=
|
||||
2025-11-28 14:03:51,098 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=png;chartUrl=oci://ghcr.io/argoproj/argo-helm/argo-cd;extraArgs=
|
||||
2025-11-28 14:04:06,132 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 16:40:40,648 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=png;chartUrl=http://charts.gitlab.io/gitlab;extraArgs=--set certmanager-issuer.email=someone@acme.com
|
||||
2025-11-28 16:42:10,189 ; 127.0.0.1 ; /api/generate-helmfile-diagram ; format=png;helmfile=repositories:\n - name: prometheus-community\n url: https://prometheus-community.github.io/helm-charts\n - name: grafana\n url: https://grafana.github.io/helm-charts\n\nreleases:\n - name: prometheus\n namespace: monitoring\n chart: prometheus-community/prometheus\n version: 15.0.0\n values:\n - server:\n persistentVolume:\n enabled: true\n size: 8Gi\n\n - name: grafana\n namespace: monitoring\n chart: grafana/grafana\n version: 6.50.0\n values:\n - adminPassword: changeme\n persistence:\n enabled: true\n size: 5Gi\n\n;extraArgs=;withoutNamespace=False
|
||||
2025-11-28 16:42:50,574 ; 127.0.0.1 ; /api/generate-helm-diagram ; format=png;chartUrl=https://kubernetes.github.io/dashboard/kubernetes-dashboard;extraArgs=
|
||||
2025-11-28 16:43:07,083 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=False;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
2025-11-28 17:14:26,329 ; 127.0.0.1 ; /api/generate-diagram ; format=png;extraArgs=;withoutNamespace=True;manifest=apiVersion: v1\nkind: Service\nmetadata:\n labels:\n app: cassandra\n name: cassandra\nspec:\n clusterIP: None\n ports:\n - port: 9042\n selector:\n app: cassandra\n---\napiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: cassandra\n labels:\n app: cassandra\nspec:\n serviceName: cassandra\n replicas: 3\n selector:\n matchLabels:\n app: cassandra\n template:\n metadata:\n labels:\n app: cassandra\n spec:\n terminationGracePeriodSeconds: 500\n containers:\n - name: cassandra\n image: gcr.io/google-samples/cassandra:v13\n imagePullPolicy: Always\n ports:\n - containerPort: 7000\n name: intra-node\n - containerPort: 7001\n name: tls-intra-node\n - containerPort: 7199\n name: jmx\n - containerPort: 9042\n name: cql\n resources:\n limits:\n cpu: "500m"\n memory: 1Gi\n requests:\n cpu: "500m"\n memory: 512M #CHANGED: instead of 1Gi\n securityContext:\n capabilities:\n add:\n - IPC_LOCK\n lifecycle:\n preStop:\n exec:\n command:\n - /bin/sh\n - -c\n - nodetool drain\n env:\n - name: MAX_HEAP_SIZE\n value: 512M\n - name: HEAP_NEWSIZE\n value: 100M\n - name: CASSANDRA_SEEDS\n value: "cassandra-0.cassandra.default.svc.cluster.local"\n - name: CASSANDRA_CLUSTER_NAME\n value: "K8Demo"\n - name: CASSANDRA_DC\n value: "DC1-K8Demo"\n - name: CASSANDRA_RACK\n value: "Rack1-K8Demo"\n - name: POD_IP\n valueFrom:\n fieldRef:\n fieldPath: status.podIP\n readinessProbe:\n exec:\n command:\n - /bin/bash\n - -c\n - echo OK #ERROR: if /ready-probe.sh\n initialDelaySeconds: 15\n timeoutSeconds: 5\n # These volume mounts are persistent. They are like inline claims,\n # but not exactly because the names need to match exactly one of\n # the stateful pod volumes.\n volumeMounts:\n - name: cassandra-data\n mountPath: /cassandra_data\n # These are converted to volume claims by the controller\n # and mounted at the paths mentioned above.\n # do not use these in production until ssd GCEPersistentDisk or other ssd pd\n volumeClaimTemplates:\n - metadata:\n name: cassandra-data\n spec:\n accessModes: [ "ReadWriteOnce" ]\n storageClassName: fast\n resources:\n requests:\n storage: 512M #CHANGED: instead of 1Gi\n---\nkind: StorageClass\napiVersion: storage.k8s.io/v1\nmetadata:\n name: fast\nprovisioner: k8s.io/minikube-hostpath\nparameters:\n type: pd-ssd
|
||||
|
Can't render this file because it contains an unexpected character in line 1 and column 1096.
|
9
webapp/backend/logs/test.png
Normal file
21
webapp/backend/requirements.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
blinker==1.9.0
|
||||
cfgv==3.4.0
|
||||
click==8.2.1
|
||||
diagrams==0.24.4
|
||||
distlib==0.4.0
|
||||
filelock==3.19.1
|
||||
Flask==3.1.2
|
||||
flask-cors==6.0.1
|
||||
graphviz==0.20.3
|
||||
gunicorn==23.0.0
|
||||
identify==2.6.14
|
||||
itsdangerous==2.2.0
|
||||
Jinja2==3.1.6
|
||||
KubeDiagrams==0.6.0
|
||||
MarkupSafe==3.0.2
|
||||
nodeenv==1.9.1
|
||||
platformdirs==4.4.0
|
||||
pre_commit==4.3.0
|
||||
PyYAML==6.0.2
|
||||
virtualenv==20.34.0
|
||||
Werkzeug==3.1.3
|
||||
7
webapp/backend/routes/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
||||
"""Routes Package Init File"""
|
||||
from .manifest import manifest_bp
|
||||
from .helm import helm_bp
|
||||
from .helmfile import helmfile_bp
|
||||
from .submit import submit_bp
|
||||
|
||||
__all__ = ['manifest_bp', 'helm_bp', 'helmfile_bp', 'submit_bp']
|
||||
BIN
webapp/backend/routes/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
webapp/backend/routes/__pycache__/helm.cpython-312.pyc
Normal file
BIN
webapp/backend/routes/__pycache__/helmfile.cpython-312.pyc
Normal file
BIN
webapp/backend/routes/__pycache__/manifest.cpython-312.pyc
Normal file
BIN
webapp/backend/routes/__pycache__/submit.cpython-312.pyc
Normal file
BIN
webapp/backend/routes/__pycache__/utils.cpython-312.pyc
Normal file
49
webapp/backend/routes/helm.py
Normal file
@@ -0,0 +1,49 @@
|
||||
"""Routes for generating diagrams from Helm charts."""
|
||||
from flask import Blueprint, request
|
||||
|
||||
from .utils import log_to_csv
|
||||
from services import generate_from_helm
|
||||
from utils import InputValidator, ResponseBuilder
|
||||
|
||||
helm_bp = Blueprint('helm', __name__)
|
||||
|
||||
@helm_bp.route('/api/generate-helm-diagram', methods=['POST'])
|
||||
def generate_helm_diagram():
|
||||
"""Generate a diagram from a Helm chart."""
|
||||
data = request.get_json()
|
||||
chart_url = data.get("chart", "")
|
||||
output_format = (data.get("outputFormat") or "png").lower()
|
||||
extra_args = data.get('extraArgs', '')
|
||||
|
||||
# Log to CSV only
|
||||
client_ip = request.remote_addr
|
||||
route = request.path
|
||||
params = f"format={output_format};chartUrl={chart_url};extraArgs={extra_args}"
|
||||
log_to_csv(client_ip, route, params)
|
||||
|
||||
# Chart URL validation
|
||||
is_valid, error_msg = InputValidator.validate_helm_chart_url(chart_url)
|
||||
if not is_valid:
|
||||
return ResponseBuilder.validation_error("chart", error_msg)
|
||||
|
||||
# Output format validation
|
||||
is_valid, error_msg = InputValidator.validate_output_format(output_format)
|
||||
if not is_valid:
|
||||
return ResponseBuilder.validation_error("outputFormat", error_msg)
|
||||
|
||||
# Extra arguments validation
|
||||
is_valid, error_msg = InputValidator.validate_extra_args(extra_args)
|
||||
if not is_valid:
|
||||
return ResponseBuilder.validation_error("extraArgs", error_msg)
|
||||
|
||||
# Diagram generation through service
|
||||
result = generate_from_helm(
|
||||
chart_url=chart_url,
|
||||
output_format=output_format,
|
||||
extra_args=extra_args
|
||||
)
|
||||
|
||||
# Returning the response
|
||||
return ResponseBuilder.from_diagram_result(result)
|
||||
|
||||
|
||||
57
webapp/backend/routes/helmfile.py
Normal file
@@ -0,0 +1,57 @@
|
||||
"""Route for diagram generation from Helmfiles."""
|
||||
from flask import Blueprint, request
|
||||
|
||||
from routes.utils import log_to_csv
|
||||
from services import generate_from_helmfile
|
||||
from utils import InputValidator, ResponseBuilder
|
||||
from .utils import compact_for_log
|
||||
|
||||
helmfile_bp = Blueprint('helmfile', __name__)
|
||||
|
||||
@helmfile_bp.route('/api/generate-helmfile-diagram', methods=['POST'])
|
||||
def generate_helmfile_diagram():
|
||||
"""Diagram generation from a Helmfile."""
|
||||
data = request.get_json()
|
||||
helmfile_content = data.get("content", "")
|
||||
output_format = (data.get("outputFormat") or "png").lower()
|
||||
extra_args = data.get("extraArgs", "").strip()
|
||||
without_namespace = data.get("withoutNamespace", False)
|
||||
|
||||
# Log to CSV only
|
||||
client_ip = request.remote_addr
|
||||
route = request.path
|
||||
params = f"format={output_format};helmfile={compact_for_log(helmfile_content)};extraArgs={compact_for_log(extra_args)};withoutNamespace={without_namespace}"
|
||||
log_to_csv(client_ip, route, params)
|
||||
|
||||
# Helmfile validation
|
||||
is_valid, error_msg = InputValidator.validate_helmfile(helmfile_content)
|
||||
if not is_valid:
|
||||
return ResponseBuilder.validation_error("content", error_msg)
|
||||
|
||||
# Verify it doesn't look like a Manifest
|
||||
if InputValidator.looks_like_manifest(helmfile_content):
|
||||
return ResponseBuilder.error(
|
||||
"This looks like a Manifest. Please use the Manifest tab for this content."
|
||||
)
|
||||
|
||||
# Output format validation
|
||||
is_valid, error_msg = InputValidator.validate_output_format(output_format)
|
||||
if not is_valid:
|
||||
return ResponseBuilder.validation_error("outputFormat", error_msg)
|
||||
|
||||
# Extra arguments validation
|
||||
is_valid, error_msg = InputValidator.validate_extra_args(extra_args)
|
||||
if not is_valid:
|
||||
return ResponseBuilder.validation_error("extraArgs", error_msg)
|
||||
|
||||
# Diagram generation through service
|
||||
result = generate_from_helmfile(
|
||||
helmfile_content=helmfile_content,
|
||||
output_format=output_format,
|
||||
extra_args=extra_args,
|
||||
without_namespace=without_namespace
|
||||
)
|
||||
|
||||
# Returning the response
|
||||
return ResponseBuilder.from_diagram_result(result)
|
||||
|
||||
62
webapp/backend/routes/manifest.py
Normal file
@@ -0,0 +1,62 @@
|
||||
"""Route for diagram generation from Kubernetes manifests."""
|
||||
from flask import Blueprint, request
|
||||
|
||||
from services import generate_from_manifest
|
||||
from utils import InputValidator, ResponseBuilder
|
||||
from .utils import compact_for_log, log_to_csv
|
||||
|
||||
manifest_bp = Blueprint('manifest', __name__)
|
||||
|
||||
@manifest_bp.route('/api/generate-diagram', methods=['POST'])
|
||||
def generate_diagram():
|
||||
"""Diagram generation from a Kubernetes manifest."""
|
||||
data = request.get_json()
|
||||
manifest_content = data.get('manifest', '')
|
||||
output_format = (data.get('outputFormat') or 'png').lower()
|
||||
extra_args = data.get('extraArgs', '')
|
||||
without_namespace = data.get('withoutNamespace', False)
|
||||
|
||||
# Log to CSV only
|
||||
client_ip = request.remote_addr
|
||||
route = request.path
|
||||
params = (
|
||||
f"format={output_format};"
|
||||
f"extraArgs={compact_for_log(extra_args)};"
|
||||
f"withoutNamespace={without_namespace};"
|
||||
f"manifest={compact_for_log(manifest_content)}"
|
||||
)
|
||||
log_to_csv(client_ip, route, params)
|
||||
|
||||
# Manifest validation
|
||||
is_valid, error_msg = InputValidator.validate_manifest(manifest_content)
|
||||
if not is_valid:
|
||||
return ResponseBuilder.validation_error("manifest", error_msg)
|
||||
|
||||
# Verify it doesn't look like a Helmfile
|
||||
if InputValidator.looks_like_helmfile(manifest_content):
|
||||
return ResponseBuilder.error(
|
||||
"This looks like a Helmfile. Please use the HelmFile tab for this content."
|
||||
)
|
||||
|
||||
# Output format validation
|
||||
is_valid, error_msg = InputValidator.validate_output_format(output_format)
|
||||
if not is_valid:
|
||||
return ResponseBuilder.validation_error("outputFormat", error_msg)
|
||||
|
||||
# Extra arguments validation
|
||||
is_valid, error_msg = InputValidator.validate_extra_args(extra_args)
|
||||
if not is_valid:
|
||||
return ResponseBuilder.validation_error("extraArgs", error_msg)
|
||||
|
||||
# Generate diagram through service
|
||||
result = generate_from_manifest(
|
||||
manifest_content=manifest_content,
|
||||
output_format=output_format,
|
||||
extra_args=extra_args,
|
||||
without_namespace=without_namespace
|
||||
)
|
||||
|
||||
# Returning the response
|
||||
return ResponseBuilder.from_diagram_result(result)
|
||||
|
||||
|
||||
43
webapp/backend/routes/submit.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""Route for submitting user feedback."""
|
||||
from flask import request, Blueprint
|
||||
import logging
|
||||
|
||||
from config import Config
|
||||
from utils import ResponseBuilder, logger
|
||||
from .utils import log_to_csv
|
||||
|
||||
submit_bp = Blueprint('submit', __name__)
|
||||
|
||||
@submit_bp.route('/api/submit-feedback', methods=['POST'])
|
||||
def submit_feedback():
|
||||
"""Submit user feedback."""
|
||||
data = request.get_json()
|
||||
note = data.get("note", "")
|
||||
comment = data.get("comment", "")
|
||||
diagram_type = data.get("diagramType", "unknown")
|
||||
|
||||
# Log to CSV only
|
||||
client_ip = request.remote_addr
|
||||
log_to_csv(client_ip, "Feedback", f"type={diagram_type};note={note}")
|
||||
|
||||
if note or comment:
|
||||
try:
|
||||
with open(Config.FEEDBACK_FILE, "a", encoding="utf-8") as f:
|
||||
f.write(f"[{diagram_type.upper()}]\nNote: {note}\nCommentaire: {comment}\n\n")
|
||||
|
||||
return ResponseBuilder.success(
|
||||
message="Feedback submitted successfully. Thank you!"
|
||||
)
|
||||
except Exception as e:
|
||||
# Log l'erreur dans le CSV
|
||||
csv_logger = logging.getLogger(Config.LOGGER_NAME)
|
||||
csv_logger.error(f"Error writing feedback: {e}")
|
||||
return ResponseBuilder.error(
|
||||
"Failed to save feedback. Please try again.",
|
||||
status_code=500
|
||||
)
|
||||
|
||||
return ResponseBuilder.validation_error(
|
||||
"feedback",
|
||||
"Feedback must contain at least a note or a comment."
|
||||
)
|
||||
37
webapp/backend/routes/utils.py
Normal file
@@ -0,0 +1,37 @@
|
||||
"""Functions utils for routes."""
|
||||
from constants import MAX_LOG_LENGTH
|
||||
|
||||
|
||||
def compact_for_log(value: str, maxlen: int = MAX_LOG_LENGTH) -> str:
|
||||
"""
|
||||
Compress a string for the logs (escape n/ r).
|
||||
|
||||
Args:
|
||||
value: Value to be compressed
|
||||
maxlen: Maximum length
|
||||
|
||||
Returns:
|
||||
str: Compacted String
|
||||
"""
|
||||
if value is None:
|
||||
return ""
|
||||
s = str(value).replace("\n", "\\n").replace("\r", "\\r")
|
||||
if len(s) <= maxlen:
|
||||
return s
|
||||
return s[:maxlen] + f"...<+{len(s)-maxlen} chars>"
|
||||
|
||||
|
||||
def log_to_csv(client_ip: str, route: str, params: str):
|
||||
"""
|
||||
Legacy function kept for backward compatibility.
|
||||
|
||||
Note: Logging is now handled centrally in app.py using Apache Combined Log Format
|
||||
which is compatible with GoAccess and other log analysis tools.
|
||||
|
||||
Args:
|
||||
client_ip: Not used (IP obtained from request)
|
||||
route: Not used (obtained from request)
|
||||
params: Not used (logging is done in after_request)
|
||||
"""
|
||||
# No-op: logging is handled by app.py after_request in Apache Combined Log Format
|
||||
pass
|
||||
15
webapp/backend/services/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
||||
"""Package contains all services for diagram generation."""
|
||||
from .models import DiagramResult
|
||||
from .file_manager import FileManager
|
||||
from .manifestService import generate_from_manifest
|
||||
from .helmService import generate_from_helm
|
||||
from .helmfileService import generate_from_helmfile
|
||||
|
||||
__all__ = [
|
||||
'DiagramResult',
|
||||
'FileManager',
|
||||
'generate_from_manifest',
|
||||
'generate_from_helm',
|
||||
'generate_from_helmfile'
|
||||
]
|
||||
|
||||
BIN
webapp/backend/services/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
webapp/backend/services/__pycache__/file_manager.cpython-312.pyc
Normal file
BIN
webapp/backend/services/__pycache__/helmService.cpython-312.pyc
Normal file
BIN
webapp/backend/services/__pycache__/models.cpython-312.pyc
Normal file
BIN
webapp/backend/services/__pycache__/utils.cpython-312.pyc
Normal file
100
webapp/backend/services/file_manager.py
Normal file
@@ -0,0 +1,100 @@
|
||||
"""Temporary file management."""
|
||||
import os
|
||||
import tempfile
|
||||
from typing import Optional
|
||||
from contextlib import contextmanager
|
||||
class FileManager:
|
||||
"""Temporary file manager."""
|
||||
@staticmethod
|
||||
@contextmanager
|
||||
def create_temp_file(content: str, suffix: str = '.yaml', mode: str = 'w'):
|
||||
"""
|
||||
Create a temporary file with the given content.
|
||||
Args:
|
||||
content: Content to be written in the file
|
||||
suffix: File suffix (extension)
|
||||
mode: File opening mode
|
||||
Yields:
|
||||
str: Temporary file path created
|
||||
"""
|
||||
temp_file = None
|
||||
try:
|
||||
with tempfile.NamedTemporaryFile(mode=mode, delete=False, suffix=suffix) as f:
|
||||
if mode == 'w':
|
||||
f.write(content)
|
||||
else:
|
||||
f.write(content.encode('utf-8'))
|
||||
temp_file = f.name
|
||||
yield temp_file
|
||||
finally:
|
||||
if temp_file and os.path.exists(temp_file):
|
||||
try:
|
||||
os.remove(temp_file)
|
||||
except OSError:
|
||||
pass
|
||||
@staticmethod
|
||||
def cleanup_files(*file_paths: str) -> None:
|
||||
"""
|
||||
Safely deletes the specified files.
|
||||
Args:
|
||||
*file_paths: Paths of the files to be deleted
|
||||
"""
|
||||
for file_path in file_paths:
|
||||
if file_path and os.path.exists(file_path):
|
||||
try:
|
||||
os.remove(file_path)
|
||||
except OSError:
|
||||
pass
|
||||
@staticmethod
|
||||
def get_output_paths(base_path: str, output_format: str) -> tuple[str, str]:
|
||||
"""
|
||||
Generates the output paths for a given format.
|
||||
Args:
|
||||
base_path: Base path (without extension)
|
||||
output_format: Requested output format
|
||||
Returns:
|
||||
tuple: (requested format_path, fallback png_path)
|
||||
"""
|
||||
base_without_ext = os.path.splitext(base_path)[0]
|
||||
requested_output = f"{base_without_ext}.{output_format}"
|
||||
png_output = f"{base_without_ext}.png"
|
||||
return requested_output, png_output
|
||||
@staticmethod
|
||||
def find_output_file(requested_path: str, fallback_path: str) -> Optional[tuple[str, str]]:
|
||||
"""
|
||||
Find the generated output file.
|
||||
Args:
|
||||
requested_path: File path in the requested format
|
||||
fallback_path: Fallback file path (PNG)
|
||||
Returns:
|
||||
tuple: (file_path, format) or None if no file found
|
||||
"""
|
||||
if os.path.exists(requested_path):
|
||||
format_ext = os.path.splitext(requested_path)[1].lstrip('.')
|
||||
return requested_path, format_ext
|
||||
elif os.path.exists(fallback_path):
|
||||
return fallback_path, "png"
|
||||
return None
|
||||
@staticmethod
|
||||
def read_file_content(file_path: str, binary: bool = True) -> bytes | str:
|
||||
"""
|
||||
Reads the contents of a file.
|
||||
Args:
|
||||
file_path: Path of the file to read
|
||||
binary: If True, reads in binary mode
|
||||
Returns:
|
||||
File content (bytes or str)
|
||||
"""
|
||||
mode = "rb" if binary else "r"
|
||||
with open(file_path, mode) as f:
|
||||
return f.read()
|
||||
@staticmethod
|
||||
def get_base_name_from_path(file_path: str) -> str:
|
||||
"""
|
||||
Extract the base name of a file path (without extension).
|
||||
Args:
|
||||
file_path: File path
|
||||
Returns:
|
||||
Base name without extension
|
||||
"""
|
||||
return os.path.splitext(os.path.basename(file_path))[0]
|
||||
137
webapp/backend/services/helmService.py
Normal file
@@ -0,0 +1,137 @@
|
||||
"""Service for generating diagrams from Helm charts."""
|
||||
import subprocess
|
||||
import os
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from constants import MIME_TYPES
|
||||
from .models import DiagramResult
|
||||
from .file_manager import FileManager
|
||||
from .utils import parse_extra_args, has_fatal_error, encode_content
|
||||
|
||||
|
||||
def generate_from_helm(
|
||||
chart_url: str,
|
||||
output_format: str = "png",
|
||||
extra_args: str = ""
|
||||
) -> DiagramResult:
|
||||
"""
|
||||
Generate a diagram from a Helm chart.
|
||||
|
||||
Args:
|
||||
chart_url: Helm chart URL
|
||||
output_format: Output format
|
||||
extra_args: Additional arguments
|
||||
|
||||
Returns:
|
||||
DiagramResult: Result of the generation
|
||||
"""
|
||||
# Extraction du nom de base
|
||||
parsed = urlparse(chart_url)
|
||||
base_name = os.path.basename(parsed.path).replace(".tgz", "").replace(".tar.gz", "")
|
||||
|
||||
# Pour les URLs OCI
|
||||
if chart_url.startswith('oci://'):
|
||||
base_name = chart_url.rstrip('/').split('/')[-1]
|
||||
|
||||
requested_output = os.path.abspath(f"{base_name}.{output_format}")
|
||||
png_output = os.path.abspath(f"{base_name}.png")
|
||||
|
||||
try:
|
||||
# Command uses helm-diagrams instead of helm
|
||||
cmd = ["helm-diagrams", chart_url, "-o", f"{base_name}.{output_format}"]
|
||||
if extra_args.strip():
|
||||
cmd.extend(parse_extra_args(extra_args))
|
||||
|
||||
# Execution
|
||||
proc = subprocess.run(cmd, check=False, capture_output=True, text=True)
|
||||
stdout_output = proc.stdout or ""
|
||||
stderr_output = proc.stderr or ""
|
||||
|
||||
# First we verify if there was an error before file exist
|
||||
has_error = proc.returncode != 0 or has_fatal_error(stdout_output, stderr_output)
|
||||
|
||||
# Second we verify if there was an error in the stderr output
|
||||
if "Error:" in stderr_output or "execution error" in stderr_output.lower():
|
||||
has_error = True
|
||||
|
||||
if has_error:
|
||||
FileManager.cleanup_files(requested_output, png_output)
|
||||
|
||||
# logs for all errors
|
||||
error_details = []
|
||||
if "not found" in stderr_output.lower() or "404" in stderr_output:
|
||||
error_details.append("Chart not found. Please verify the repository URL and chart name.")
|
||||
if "could not download" in stderr_output.lower():
|
||||
error_details.append("Could not download the chart. Check the URL and your network connection.")
|
||||
if "authentication" in stderr_output.lower() or "unauthorized" in stderr_output.lower():
|
||||
error_details.append("Authentication required or access denied.")
|
||||
if "is not a valid chart repository" in stderr_output.lower():
|
||||
error_details.append("The URL is not a valid Helm chart repository.")
|
||||
if "repo not found" in stderr_output.lower():
|
||||
error_details.append("Repository not found. Make sure the URL points to a valid Helm repository.")
|
||||
if "execution error" in stderr_output.lower():
|
||||
error_details.append("Helm chart has configuration errors. Check the stderr output below for details.")
|
||||
if "you must provide" in stderr_output.lower():
|
||||
error_details.append("Missing required configuration values in the chart.")
|
||||
|
||||
main_error = " ".join(error_details) if error_details else "helm-diagrams failed to generate the diagram."
|
||||
|
||||
return DiagramResult(
|
||||
success=False,
|
||||
error=main_error,
|
||||
command=" ".join(cmd),
|
||||
stdout=stdout_output,
|
||||
stderr=stderr_output
|
||||
)
|
||||
|
||||
# Search for the output file
|
||||
output_info = FileManager.find_output_file(requested_output, png_output)
|
||||
if not output_info:
|
||||
return DiagramResult(
|
||||
success=False,
|
||||
error=f"Output file not found (looked for {os.path.basename(requested_output)} and {os.path.basename(png_output)}).",
|
||||
command=" ".join(cmd),
|
||||
stdout=stdout_output,
|
||||
stderr=stderr_output
|
||||
)
|
||||
|
||||
output_file, produced_format = output_info
|
||||
|
||||
note = ""
|
||||
if produced_format == "png" and output_format != "png":
|
||||
note = f"Requested format '{output_format}' is not available from helm-diagrams. Returned PNG instead."
|
||||
|
||||
content = FileManager.read_file_content(output_file, binary=True)
|
||||
encoded = encode_content(content, produced_format)
|
||||
|
||||
# Cleaning
|
||||
FileManager.cleanup_files(requested_output, png_output)
|
||||
|
||||
message = (note + " " if note else "") + "Helm diagram successfully generated."
|
||||
|
||||
return DiagramResult(
|
||||
success=True,
|
||||
diagram=encoded,
|
||||
mime_type=MIME_TYPES.get(produced_format, "application/octet-stream"),
|
||||
filename=f"{base_name}.{produced_format}",
|
||||
message=message.strip(),
|
||||
command=" ".join(cmd),
|
||||
stdout=stdout_output,
|
||||
stderr=stderr_output
|
||||
)
|
||||
|
||||
except ValueError as e:
|
||||
FileManager.cleanup_files(requested_output, png_output)
|
||||
return DiagramResult(
|
||||
success=False,
|
||||
error=str(e),
|
||||
command=" ".join(cmd) if 'cmd' in locals() else None
|
||||
)
|
||||
except Exception as e:
|
||||
FileManager.cleanup_files(requested_output, png_output)
|
||||
return DiagramResult(
|
||||
success=False,
|
||||
error=f"Internal error: {e}",
|
||||
command=" ".join(cmd) if 'cmd' in locals() else None
|
||||
)
|
||||
|
||||
121
webapp/backend/services/helmfileService.py
Normal file
@@ -0,0 +1,121 @@
|
||||
"""Service for generating diagrams from Helmfiles."""
|
||||
import subprocess
|
||||
import os
|
||||
|
||||
from constants import MIME_TYPES
|
||||
from .models import DiagramResult
|
||||
from .file_manager import FileManager
|
||||
from .utils import parse_extra_args, has_fatal_error, encode_content
|
||||
|
||||
|
||||
def generate_from_helmfile(
|
||||
helmfile_content: str,
|
||||
output_format: str = "png",
|
||||
extra_args: str = "",
|
||||
without_namespace: bool = False
|
||||
) -> DiagramResult:
|
||||
"""
|
||||
Generate a diagram from a Helmfile.
|
||||
|
||||
Args:
|
||||
helmfile_content: Contents of the Helmfile
|
||||
output_format: Output format
|
||||
extra_args: Additional arguments
|
||||
without_namespace: Hide namespaces
|
||||
|
||||
Returns:
|
||||
DiagramResult: Result of the generation
|
||||
"""
|
||||
with FileManager.create_temp_file(helmfile_content, suffix=".yaml", mode='wb') as temp_helmfile_path:
|
||||
output_path = temp_helmfile_path + f".{output_format}"
|
||||
|
||||
try:
|
||||
# Command helmfile template
|
||||
template_cmd = ["helmfile", "template", "-f", temp_helmfile_path]
|
||||
|
||||
template_proc = subprocess.Popen(
|
||||
template_cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True
|
||||
)
|
||||
helm_output, helm_err = template_proc.communicate()
|
||||
|
||||
if template_proc.returncode != 0 or has_fatal_error("", helm_err):
|
||||
FileManager.cleanup_files(output_path)
|
||||
return DiagramResult(
|
||||
success=False,
|
||||
error="Helmfile template failed. See command output below.",
|
||||
command=" ".join(template_cmd),
|
||||
stdout="",
|
||||
stderr=helm_err or ""
|
||||
)
|
||||
|
||||
# Command kube-diagrams
|
||||
cmd = ["kube-diagrams", "-", "-o", output_path]
|
||||
if without_namespace:
|
||||
cmd.append("--without-namespace")
|
||||
if extra_args.strip():
|
||||
cmd.extend(parse_extra_args(extra_args))
|
||||
|
||||
kube_proc = subprocess.run(
|
||||
cmd,
|
||||
input=helm_output,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True
|
||||
)
|
||||
|
||||
stdout_output = kube_proc.stdout or ""
|
||||
stderr_output = kube_proc.stderr or ""
|
||||
|
||||
if kube_proc.returncode != 0 or has_fatal_error(stdout_output, stderr_output):
|
||||
FileManager.cleanup_files(output_path)
|
||||
return DiagramResult(
|
||||
success=False,
|
||||
error="kube-diagrams failed",
|
||||
command=f"{' '.join(template_cmd)} | {' '.join(cmd)}",
|
||||
stdout=stdout_output,
|
||||
stderr=stderr_output
|
||||
)
|
||||
|
||||
if not os.path.exists(output_path):
|
||||
return DiagramResult(
|
||||
success=False,
|
||||
error=f"Output file not found: {output_path}",
|
||||
command=f"{' '.join(template_cmd)} | {' '.join(cmd)}",
|
||||
stdout=stdout_output,
|
||||
stderr=stderr_output
|
||||
)
|
||||
|
||||
content = FileManager.read_file_content(output_path, binary=True)
|
||||
encoded = encode_content(content, output_format)
|
||||
|
||||
# Cleaning
|
||||
FileManager.cleanup_files(output_path)
|
||||
|
||||
return DiagramResult(
|
||||
success=True,
|
||||
diagram=encoded,
|
||||
mime_type=MIME_TYPES.get(output_format, "application/octet-stream"),
|
||||
filename=f"helmfile-diagram.{output_format}",
|
||||
message="Helmfile diagram successfully generated.",
|
||||
command=f"{' '.join(template_cmd)} | {' '.join(cmd)}",
|
||||
stdout=stdout_output,
|
||||
stderr=stderr_output
|
||||
)
|
||||
|
||||
except ValueError as e:
|
||||
FileManager.cleanup_files(output_path)
|
||||
return DiagramResult(
|
||||
success=False,
|
||||
error=str(e),
|
||||
command=" ".join(cmd) if 'cmd' in locals() else None
|
||||
)
|
||||
except Exception as e:
|
||||
FileManager.cleanup_files(output_path)
|
||||
return DiagramResult(
|
||||
success=False,
|
||||
error=str(e),
|
||||
command=" ".join(cmd) if 'cmd' in locals() else None
|
||||
)
|
||||
99
webapp/backend/services/manifestService.py
Normal file
@@ -0,0 +1,99 @@
|
||||
"""Service for generating diagrams from Kubernetes manifests."""
|
||||
import subprocess
|
||||
|
||||
from constants import MIME_TYPES
|
||||
from .models import DiagramResult
|
||||
from .file_manager import FileManager
|
||||
from .utils import parse_extra_args, has_fatal_error, encode_content
|
||||
|
||||
|
||||
def generate_from_manifest(
|
||||
manifest_content: str,
|
||||
output_format: str = "png",
|
||||
extra_args: str = "",
|
||||
without_namespace: bool = False
|
||||
) -> DiagramResult:
|
||||
"""
|
||||
Generate a diagram from a Kubernetes manifest.
|
||||
|
||||
Args:
|
||||
manifest_content: Content of the manifest
|
||||
output_format: Output format (png, svg, etc.)
|
||||
extra_args: Additional arguments for kube-diagrams
|
||||
without_namespace: Hide namespaces
|
||||
|
||||
Returns:
|
||||
DiagramResult: Result of the generation
|
||||
"""
|
||||
with FileManager.create_temp_file(manifest_content, suffix='.yaml') as tmp_manifest:
|
||||
base_name = FileManager.get_base_name_from_path(tmp_manifest)
|
||||
requested_output, png_output = FileManager.get_output_paths(tmp_manifest, output_format)
|
||||
|
||||
try:
|
||||
# Command
|
||||
cmd = ["kube-diagrams", tmp_manifest, "-o", requested_output]
|
||||
if without_namespace:
|
||||
cmd.append("--without-namespace")
|
||||
if extra_args.strip():
|
||||
cmd.extend(parse_extra_args(extra_args))
|
||||
|
||||
# Execution
|
||||
proc = subprocess.run(cmd, check=False, capture_output=True, text=True)
|
||||
stdout_output = proc.stdout or ""
|
||||
stderr_output = proc.stderr or ""
|
||||
|
||||
# Error verification
|
||||
if proc.returncode != 0 or has_fatal_error(stdout_output, stderr_output):
|
||||
FileManager.cleanup_files(requested_output, png_output)
|
||||
return DiagramResult(
|
||||
success=False,
|
||||
error="KubeDiagrams failed. See command output below.",
|
||||
command=" ".join(cmd),
|
||||
stdout=stdout_output,
|
||||
stderr=stderr_output
|
||||
)
|
||||
|
||||
# Output file verification
|
||||
output_info = FileManager.find_output_file(requested_output, png_output)
|
||||
if not output_info:
|
||||
return DiagramResult(
|
||||
success=False,
|
||||
error=f"Output file not found (looked for {requested_output} and {png_output}).",
|
||||
command=" ".join(cmd),
|
||||
stdout=stdout_output,
|
||||
stderr=stderr_output
|
||||
)
|
||||
|
||||
output_file, produced_format = output_info
|
||||
content = FileManager.read_file_content(output_file, binary=True)
|
||||
encoded = encode_content(content, produced_format)
|
||||
|
||||
# Cleaning
|
||||
FileManager.cleanup_files(requested_output, png_output)
|
||||
|
||||
return DiagramResult(
|
||||
success=True,
|
||||
diagram=encoded,
|
||||
mime_type=MIME_TYPES.get(produced_format, "application/octet-stream"),
|
||||
filename=f"{base_name}.{produced_format}",
|
||||
message="Diagram successfully generated.",
|
||||
command=" ".join(cmd),
|
||||
stdout=stdout_output,
|
||||
stderr=stderr_output
|
||||
)
|
||||
|
||||
except ValueError as e:
|
||||
FileManager.cleanup_files(requested_output, png_output)
|
||||
return DiagramResult(
|
||||
success=False,
|
||||
error=str(e),
|
||||
command=" ".join(cmd) if 'cmd' in locals() else None
|
||||
)
|
||||
except Exception as e:
|
||||
FileManager.cleanup_files(requested_output, png_output)
|
||||
return DiagramResult(
|
||||
success=False,
|
||||
error=f"Internal error: {e}",
|
||||
command=" ".join(cmd) if 'cmd' in locals() else None
|
||||
)
|
||||
|
||||
43
webapp/backend/services/models.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""Service Data Model"""
|
||||
from typing import Optional
|
||||
class DiagramResult:
|
||||
"""Data model for the diagram result."""
|
||||
def __init__(
|
||||
self,
|
||||
success: bool,
|
||||
diagram: Optional[str] = None,
|
||||
mime_type: Optional[str] = None,
|
||||
filename: Optional[str] = None,
|
||||
message: Optional[str] = None,
|
||||
error: Optional[str] = None,
|
||||
command: Optional[str] = None,
|
||||
stdout: Optional[str] = None,
|
||||
stderr: Optional[str] = None
|
||||
):
|
||||
self.success = success
|
||||
self.diagram = diagram
|
||||
self.mime_type = mime_type
|
||||
self.filename = filename
|
||||
self.message = message
|
||||
self.error = error
|
||||
self.command = command
|
||||
self.stdout = stdout
|
||||
self.stderr = stderr
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
"""Converts the DiagramResult to a dictionary."""
|
||||
result = {
|
||||
"command": self.command,
|
||||
"stdout": self.stdout or "",
|
||||
"stderr": self.stderr or ""
|
||||
}
|
||||
if self.success:
|
||||
result.update({
|
||||
"diagram": self.diagram,
|
||||
"mimeType": self.mime_type,
|
||||
"filename": self.filename,
|
||||
"message": self.message
|
||||
})
|
||||
else:
|
||||
result["error"] = self.error
|
||||
return result
|
||||
57
webapp/backend/services/utils.py
Normal file
@@ -0,0 +1,57 @@
|
||||
"""Utilitaires pour les services de génération de diagrammes."""
|
||||
import base64
|
||||
import shlex
|
||||
|
||||
from constants import TEXT_FORMATS
|
||||
|
||||
|
||||
def has_fatal_error(stdout_txt: str, stderr_txt: str) -> bool:
|
||||
"""
|
||||
Vérifie si la sortie contient une erreur fatale.
|
||||
|
||||
Args:
|
||||
stdout_txt: Sortie standard
|
||||
stderr_txt: Sortie d'erreur
|
||||
|
||||
Returns:
|
||||
bool: True si erreur fatale détectée
|
||||
"""
|
||||
return ("error:" in (stdout_txt or "").lower()) or ("error:" in (stderr_txt or "").lower())
|
||||
|
||||
|
||||
def parse_extra_args(extra_args: str) -> list[str]:
|
||||
"""
|
||||
Parse les arguments supplémentaires.
|
||||
|
||||
Args:
|
||||
extra_args: Arguments supplémentaires en string
|
||||
|
||||
Returns:
|
||||
list[str]: Liste des arguments parsés
|
||||
|
||||
Raises:
|
||||
ValueError: Si les arguments sont invalides
|
||||
"""
|
||||
if not extra_args or not extra_args.strip():
|
||||
return []
|
||||
try:
|
||||
return shlex.split(extra_args.strip())
|
||||
except Exception as e:
|
||||
raise ValueError(f"Invalid extraArgs: {e}")
|
||||
|
||||
|
||||
def encode_content(content: bytes, output_format: str) -> str:
|
||||
"""
|
||||
Encode le contenu en base64 ou UTF-8 selon le format.
|
||||
|
||||
Args:
|
||||
content: Contenu à encoder
|
||||
output_format: Format de sortie
|
||||
|
||||
Returns:
|
||||
str: Contenu encodé
|
||||
"""
|
||||
if output_format in TEXT_FORMATS:
|
||||
return content.decode("utf-8")
|
||||
return base64.b64encode(content).decode("utf-8")
|
||||
|
||||
17
webapp/backend/utils/__init__.py
Normal file
@@ -0,0 +1,17 @@
|
||||
"""Package utils."""
|
||||
from .logger import AppLogger, get_app_logger
|
||||
from .validators import InputValidator, ValidationError
|
||||
from .response_builder import ResponseBuilder
|
||||
from .access_logger import get_real_ip, log_request, log_request_compact
|
||||
|
||||
__all__ = [
|
||||
'AppLogger',
|
||||
'get_app_logger',
|
||||
'InputValidator',
|
||||
'ValidationError',
|
||||
'ResponseBuilder',
|
||||
'get_real_ip',
|
||||
'log_request',
|
||||
'log_request_compact'
|
||||
]
|
||||
|
||||
BIN
webapp/backend/utils/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
webapp/backend/utils/__pycache__/access_logger.cpython-312.pyc
Normal file
BIN
webapp/backend/utils/__pycache__/logger.cpython-312.pyc
Normal file
BIN
webapp/backend/utils/__pycache__/validators.cpython-312.pyc
Normal file
283
webapp/backend/utils/access_logger.py
Normal file
@@ -0,0 +1,283 @@
|
||||
"""access logging for Flask application."""
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from flask import request, g
|
||||
from typing import Optional
|
||||
from config import Config
|
||||
|
||||
|
||||
def is_valid_ip(ip: str) -> bool:
|
||||
"""
|
||||
Check if the IP address is valid and not a placeholder.
|
||||
|
||||
Args:
|
||||
ip: IP address string to validate
|
||||
|
||||
Returns:
|
||||
bool: True if IP is valid, False otherwise
|
||||
"""
|
||||
if not ip:
|
||||
return False
|
||||
|
||||
ip = ip.strip()
|
||||
|
||||
# List of invalid placeholder values (not real IPs)
|
||||
invalid_values = [
|
||||
'',
|
||||
'-',
|
||||
'(null)',
|
||||
'null',
|
||||
'None',
|
||||
'unknown',
|
||||
]
|
||||
|
||||
if ip.lower() in [v.lower() for v in invalid_values]:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def normalize_ip(ip: str) -> str:
|
||||
"""
|
||||
Normalize IP address to IPv4 format when possible.
|
||||
Converts IPv6 localhost (::1) to IPv4 (127.0.0.1).
|
||||
|
||||
Args:
|
||||
ip: IP address string
|
||||
|
||||
Returns:
|
||||
str: Normalized IP address
|
||||
"""
|
||||
if not ip:
|
||||
return '-'
|
||||
|
||||
ip = ip.strip()
|
||||
|
||||
# Convert IPv6 localhost to IPv4
|
||||
if ip == '::1':
|
||||
return '127.0.0.1'
|
||||
|
||||
# Convert IPv6-mapped IPv4 addresses (::ffff:192.168.1.1 -> 192.168.1.1)
|
||||
if ip.startswith('::ffff:'):
|
||||
return ip[7:]
|
||||
|
||||
return ip
|
||||
|
||||
|
||||
def get_real_ip() -> str:
|
||||
"""
|
||||
Get the real IP address of the client, handling proxies and load balancers.
|
||||
|
||||
When using ProxyFix middleware (Config.BEHIND_PROXY=True), request.remote_addr
|
||||
is automatically set to the real client IP from X-Forwarded-For headers.
|
||||
|
||||
For additional safety, we also check common proxy headers manually:
|
||||
1. X-Forwarded-For (most common with reverse proxies)
|
||||
2. X-Real-IP (nginx)
|
||||
3. CF-Connecting-IP (Cloudflare)
|
||||
4. True-Client-IP (Akamai and some CDNs)
|
||||
5. request.remote_addr (fallback / already fixed by ProxyFix)
|
||||
|
||||
Returns:
|
||||
str: The real IP address of the client (normalized to IPv4 when possible)
|
||||
"""
|
||||
# X-Forwarded-For can contain multiple IPs: "client, proxy1, proxy2"
|
||||
# The first one is the original client
|
||||
x_forwarded_for = request.headers.get('X-Forwarded-For')
|
||||
if x_forwarded_for:
|
||||
# Take the first IP in the chain (the original client)
|
||||
ip = x_forwarded_for.split(',')[0].strip()
|
||||
if is_valid_ip(ip):
|
||||
return normalize_ip(ip)
|
||||
|
||||
# X-Real-IP is used by nginx
|
||||
x_real_ip = request.headers.get('X-Real-IP')
|
||||
if x_real_ip and is_valid_ip(x_real_ip):
|
||||
return normalize_ip(x_real_ip.strip())
|
||||
|
||||
# Cloudflare specific header
|
||||
cf_connecting_ip = request.headers.get('CF-Connecting-IP')
|
||||
if cf_connecting_ip and is_valid_ip(cf_connecting_ip):
|
||||
return normalize_ip(cf_connecting_ip.strip())
|
||||
|
||||
# Akamai and some CDNs
|
||||
true_client_ip = request.headers.get('True-Client-IP')
|
||||
if true_client_ip and is_valid_ip(true_client_ip):
|
||||
return normalize_ip(true_client_ip.strip())
|
||||
|
||||
# X-Client-IP (some load balancers)
|
||||
x_client_ip = request.headers.get('X-Client-IP')
|
||||
if x_client_ip and is_valid_ip(x_client_ip):
|
||||
return normalize_ip(x_client_ip.strip())
|
||||
|
||||
# Fallback to remote_addr (will be correct if ProxyFix is enabled)
|
||||
remote_addr = request.remote_addr
|
||||
if remote_addr and is_valid_ip(remote_addr):
|
||||
return normalize_ip(remote_addr)
|
||||
|
||||
# Ultimate fallback
|
||||
return '-'
|
||||
|
||||
|
||||
def get_all_ip_headers() -> dict:
|
||||
"""
|
||||
Get all IP-related headers for debugging purposes.
|
||||
|
||||
Returns:
|
||||
dict: Dictionary of all IP-related headers and their values
|
||||
"""
|
||||
headers = {
|
||||
'remote_addr': request.remote_addr,
|
||||
'X-Forwarded-For': request.headers.get('X-Forwarded-For'),
|
||||
'X-Real-IP': request.headers.get('X-Real-IP'),
|
||||
'CF-Connecting-IP': request.headers.get('CF-Connecting-IP'),
|
||||
'True-Client-IP': request.headers.get('True-Client-IP'),
|
||||
'X-Client-IP': request.headers.get('X-Client-IP'),
|
||||
'X-Forwarded-Proto': request.headers.get('X-Forwarded-Proto'),
|
||||
'X-Forwarded-Host': request.headers.get('X-Forwarded-Host'),
|
||||
}
|
||||
return {k: v for k, v in headers.items() if v is not None}
|
||||
|
||||
|
||||
def get_user_agent() -> str:
|
||||
"""
|
||||
Get the User-Agent header.
|
||||
|
||||
Returns:
|
||||
str: User-Agent string or '-' if not present
|
||||
"""
|
||||
return request.headers.get('User-Agent', '-')
|
||||
|
||||
|
||||
def get_referer() -> str:
|
||||
"""
|
||||
Get the Referer header.
|
||||
|
||||
Returns:
|
||||
str: Referer URL or '-' if not present
|
||||
"""
|
||||
return request.headers.get('Referer', '-')
|
||||
|
||||
|
||||
def format_apache_log(
|
||||
ip: str,
|
||||
method: str,
|
||||
path: str,
|
||||
protocol: str,
|
||||
status_code: int,
|
||||
response_size: int,
|
||||
referer: str,
|
||||
user_agent: str,
|
||||
request_time: Optional[float] = None
|
||||
) -> str:
|
||||
"""
|
||||
Format log entry in Apache Combined Log Format with additional info.
|
||||
|
||||
Apache Combined Log Format:
|
||||
IP - - [datetime] "METHOD PATH PROTOCOL" STATUS SIZE "REFERER" "USER-AGENT"
|
||||
|
||||
We add request time at the end for performance monitoring.
|
||||
|
||||
Args:
|
||||
ip: Client IP address
|
||||
method: HTTP method (GET, POST, etc.)
|
||||
path: Request path
|
||||
protocol: HTTP protocol version
|
||||
status_code: HTTP status code
|
||||
response_size: Response size in bytes
|
||||
referer: Referer header
|
||||
user_agent: User-Agent header
|
||||
request_time: Request processing time in milliseconds (optional)
|
||||
|
||||
Returns:
|
||||
str: Formatted log entry
|
||||
"""
|
||||
# Format datetime in Apache format: [10/Oct/2000:13:55:36 +0000]
|
||||
now = datetime.now()
|
||||
timestamp = now.strftime('[%d/%b/%Y:%H:%M:%S +0000]')
|
||||
|
||||
# Escape quotes in referer and user-agent
|
||||
referer = referer.replace('"', '\\"')
|
||||
user_agent = user_agent.replace('"', '\\"')
|
||||
|
||||
# Format: IP - - [datetime] "METHOD PATH PROTOCOL" STATUS SIZE "REFERER" "USER-AGENT"
|
||||
log_line = (
|
||||
f'{ip} - - {timestamp} '
|
||||
f'"{method} {path} {protocol}" '
|
||||
f'{status_code} {response_size} '
|
||||
f'"{referer}" "{user_agent}"'
|
||||
)
|
||||
|
||||
# Add request time if available
|
||||
if request_time is not None:
|
||||
log_line += f' {request_time:.2f}ms'
|
||||
|
||||
return log_line
|
||||
|
||||
|
||||
def log_request(status_code: int, response_size: int = 0):
|
||||
"""
|
||||
Log an HTTP request in Apache Combined Log Format.
|
||||
|
||||
Args:
|
||||
status_code: HTTP status code
|
||||
response_size: Response size in bytes (default: 0)
|
||||
"""
|
||||
try:
|
||||
ip = get_real_ip()
|
||||
method = request.method
|
||||
path = request.path
|
||||
protocol = request.environ.get('SERVER_PROTOCOL', 'HTTP/1.1')
|
||||
referer = get_referer()
|
||||
user_agent = get_user_agent()
|
||||
|
||||
# Calculate request time if available
|
||||
request_time = None
|
||||
if hasattr(g, 'request_start_time'):
|
||||
from time import time
|
||||
request_time = (time() - g.request_start_time) * 1000 # Convert to ms
|
||||
|
||||
# Format and log
|
||||
log_line = format_apache_log(
|
||||
ip=ip,
|
||||
method=method,
|
||||
path=path,
|
||||
protocol=protocol,
|
||||
status_code=status_code,
|
||||
response_size=response_size,
|
||||
referer=referer,
|
||||
user_agent=user_agent,
|
||||
request_time=request_time
|
||||
)
|
||||
|
||||
logger = logging.getLogger(Config.LOGGER_NAME)
|
||||
logger.info(log_line)
|
||||
|
||||
except Exception as e:
|
||||
# Don't let logging errors break the application
|
||||
error_logger = logging.getLogger('app')
|
||||
error_logger.error(f"Error logging request: {e}")
|
||||
|
||||
|
||||
def log_request_compact(status_code: int, params_summary: str = ""):
|
||||
"""
|
||||
Log an HTTP request with a compact parameter summary (for backward compatibility).
|
||||
This can be used for detailed parameter logging alongside the Apache-style log.
|
||||
|
||||
Args:
|
||||
status_code: HTTP status code
|
||||
params_summary: Compact summary of request parameters
|
||||
"""
|
||||
try:
|
||||
ip = get_real_ip()
|
||||
path = request.path
|
||||
|
||||
# Compact format: IP ; PATH ; PARAMS
|
||||
log_line = f"{ip} ; {path} ; {params_summary}"
|
||||
|
||||
logger = logging.getLogger(Config.LOGGER_NAME)
|
||||
logger.info(log_line)
|
||||
|
||||
except Exception as e:
|
||||
error_logger = logging.getLogger('app')
|
||||
error_logger.error(f"Error logging request: {e}")
|
||||
108
webapp/backend/utils/logger.py
Normal file
@@ -0,0 +1,108 @@
|
||||
"""Configuration for application logging."""
|
||||
import logging
|
||||
import sys
|
||||
from logging.handlers import RotatingFileHandler
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class AppLogger:
|
||||
"""Logging manager for the application."""
|
||||
|
||||
_loggers = {}
|
||||
|
||||
@classmethod
|
||||
def setup_logger(
|
||||
cls,
|
||||
name: str,
|
||||
log_file: str = None,
|
||||
level: int = logging.INFO,
|
||||
max_bytes: int = 10 * 1024 * 1024, # 10MB
|
||||
backup_count: int = 5
|
||||
) -> logging.Logger:
|
||||
"""
|
||||
Configure and return a logger.
|
||||
|
||||
Args:
|
||||
name: Name of the logger
|
||||
log_file: Log File Path (optional)
|
||||
level: Logging level
|
||||
max_bytes: Maximum log file size before rotation
|
||||
backup_count: Number of backup files to keep
|
||||
|
||||
Returns:
|
||||
logging.Logger: Logger configured
|
||||
"""
|
||||
# To not recreate logger if already exist
|
||||
if name in cls._loggers:
|
||||
return cls._loggers[name]
|
||||
|
||||
logger = logging.getLogger(name)
|
||||
logger.setLevel(level)
|
||||
|
||||
# Avoid adding multiple handlers to the same logger
|
||||
if logger.handlers:
|
||||
return logger
|
||||
|
||||
formatter = logging.Formatter(
|
||||
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
datefmt='%Y-%m-%d %H:%M:%S'
|
||||
)
|
||||
|
||||
# Console handler
|
||||
console_handler = logging.StreamHandler(sys.stdout)
|
||||
console_handler.setLevel(level)
|
||||
console_handler.setFormatter(formatter)
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
# Handler file if needed
|
||||
if log_file:
|
||||
# Create directory if needed
|
||||
log_path = Path(log_file)
|
||||
log_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
file_handler = RotatingFileHandler(
|
||||
log_file,
|
||||
maxBytes=max_bytes,
|
||||
backupCount=backup_count,
|
||||
encoding='utf-8'
|
||||
)
|
||||
file_handler.setLevel(level)
|
||||
file_handler.setFormatter(formatter)
|
||||
logger.addHandler(file_handler)
|
||||
|
||||
cls._loggers[name] = logger
|
||||
return logger
|
||||
|
||||
@classmethod
|
||||
def get_logger(cls, name: str) -> logging.Logger:
|
||||
"""
|
||||
Retrieve an existing logger or create a new one.
|
||||
|
||||
Args:
|
||||
name: Name of the logger
|
||||
|
||||
Returns:
|
||||
logging.Logger: Logger
|
||||
"""
|
||||
if name in cls._loggers:
|
||||
return cls._loggers[name]
|
||||
return cls.setup_logger(name)
|
||||
|
||||
|
||||
def get_app_logger(name: str = None) -> logging.Logger:
|
||||
"""
|
||||
Helper function to obtain a logger.
|
||||
|
||||
Args:
|
||||
name: Name of the logger (uses the name of the calling module by default)
|
||||
|
||||
Returns:
|
||||
logging.Logger: Logger configured
|
||||
"""
|
||||
if name is None:
|
||||
import inspect
|
||||
frame = inspect.currentframe().f_back
|
||||
name = frame.f_globals.get('__name__', 'app')
|
||||
|
||||
return AppLogger.get_logger(name)
|
||||
|
||||
172
webapp/backend/utils/response_builder.py
Normal file
@@ -0,0 +1,172 @@
|
||||
"""Http response builder."""
|
||||
from typing import Any, Dict, Optional
|
||||
from flask import jsonify, Response
|
||||
|
||||
|
||||
class ResponseBuilder:
|
||||
"""Http response builder."""
|
||||
|
||||
@staticmethod
|
||||
def success(
|
||||
data: Any = None,
|
||||
message: str = "Success",
|
||||
status_code: int = 200
|
||||
) -> tuple[Response, int]:
|
||||
"""
|
||||
Create a standardized success response.
|
||||
|
||||
Args:
|
||||
data: Data to be returned
|
||||
message: Success message
|
||||
status_code: HTTP status code
|
||||
|
||||
Returns:
|
||||
tuple[Response, int]: Flask response and status code
|
||||
"""
|
||||
response = {
|
||||
"success": True,
|
||||
"message": message
|
||||
}
|
||||
|
||||
if data is not None:
|
||||
if isinstance(data, dict):
|
||||
response.update(data)
|
||||
else:
|
||||
response["data"] = data
|
||||
|
||||
return jsonify(response), status_code
|
||||
|
||||
@staticmethod
|
||||
def error(
|
||||
error: str,
|
||||
details: Optional[Dict[str, Any]] = None,
|
||||
status_code: int = 400
|
||||
) -> tuple[Response, int]:
|
||||
"""
|
||||
Creates a standard error response.
|
||||
|
||||
Args:
|
||||
error: Error message
|
||||
details: Additional details
|
||||
status_code: HTTP status code
|
||||
|
||||
Returns:
|
||||
tuple[Response, int]: Flask response and status code
|
||||
"""
|
||||
response = {
|
||||
"success": False,
|
||||
"error": error
|
||||
}
|
||||
|
||||
if details:
|
||||
response.update(details)
|
||||
|
||||
return jsonify(response), status_code
|
||||
|
||||
@staticmethod
|
||||
def validation_error(
|
||||
field: str,
|
||||
message: str,
|
||||
status_code: int = 400
|
||||
) -> tuple[Response, int]:
|
||||
"""
|
||||
Creates a validation error response.
|
||||
|
||||
Args:
|
||||
field: Field in error
|
||||
message: Error message
|
||||
status_code: HTTP status code
|
||||
|
||||
Returns:
|
||||
tuple[Response, int]: Flask response and status code
|
||||
"""
|
||||
return ResponseBuilder.error(
|
||||
error=message,
|
||||
details={"field": field, "type": "validation_error"},
|
||||
status_code=status_code
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def diagram_success(
|
||||
diagram: str,
|
||||
mime_type: str,
|
||||
filename: str,
|
||||
message: str = "Diagram successfully generated.",
|
||||
command: str = None,
|
||||
stdout: str = "",
|
||||
stderr: str = ""
|
||||
) -> tuple[Response, int]:
|
||||
"""
|
||||
Creates a success response for the diagram generation.
|
||||
|
||||
Args:
|
||||
diagram: Content of the diagram (encoded)
|
||||
mime_type: MIME type of the diagram
|
||||
filename: File name
|
||||
message: Success message
|
||||
command: Command executed
|
||||
stdout: Standard output
|
||||
stderr: Error output
|
||||
|
||||
Returns:
|
||||
tuple[Response, int]: Flask response and status code
|
||||
"""
|
||||
response_data = {
|
||||
"diagram": diagram,
|
||||
"mimeType": mime_type,
|
||||
"filename": filename,
|
||||
"message": message,
|
||||
"command": command,
|
||||
"stdout": stdout or "",
|
||||
"stderr": stderr or ""
|
||||
}
|
||||
|
||||
return ResponseBuilder.success(data=response_data, message=message, status_code=200)
|
||||
|
||||
@staticmethod
|
||||
def diagram_error(
|
||||
error: str,
|
||||
command: str = None,
|
||||
stdout: str = "",
|
||||
stderr: str = "",
|
||||
status_code: int = 400
|
||||
) -> tuple[Response, int]:
|
||||
"""
|
||||
Creates an error response for diagram generation.
|
||||
|
||||
Args:
|
||||
error: Error message
|
||||
command: Command executed
|
||||
stdout: Standard output
|
||||
stderr: Error output
|
||||
status_code: HTTP status code
|
||||
|
||||
Returns:
|
||||
tuple[Response, int]: Flask response and status code
|
||||
"""
|
||||
details = {
|
||||
"command": command,
|
||||
"stdout": stdout or "",
|
||||
"stderr": stderr or ""
|
||||
}
|
||||
|
||||
return ResponseBuilder.error(
|
||||
error=error,
|
||||
details=details,
|
||||
status_code=status_code
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def from_diagram_result(result) -> tuple[Response, int]:
|
||||
"""
|
||||
Create a response from a DiagramResult.
|
||||
|
||||
Args:
|
||||
result: Instance of DiagramResult
|
||||
|
||||
Returns:
|
||||
tuple[Response, int]: Flask response and status code
|
||||
"""
|
||||
status_code = 200 if result.success else 400
|
||||
return jsonify(result.to_dict()), status_code
|
||||
|
||||
183
webapp/backend/utils/validators.py
Normal file
@@ -0,0 +1,183 @@
|
||||
"""Validation of user inputs."""
|
||||
import re
|
||||
from typing import Optional, Tuple
|
||||
from constants import MANIFEST_RE, KIND_RE
|
||||
|
||||
|
||||
class ValidationError(Exception):
|
||||
"""Exception error validation."""
|
||||
pass
|
||||
|
||||
|
||||
class InputValidator:
|
||||
"""Validator for user inputs."""
|
||||
|
||||
SUPPORTED_FORMATS = ['png', 'jpg', 'jpeg', 'gif', 'svg', 'pdf', 'dot', 'dot_json']
|
||||
|
||||
# Valid Pattern for url
|
||||
HELM_URL_PATTERN = re.compile(
|
||||
r'^(https?://|oci://|file://|[a-zA-Z0-9\-_]+/[a-zA-Z0-9\-_]+)'
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def validate_manifest(cls, content: str) -> Tuple[bool, Optional[str]]:
|
||||
"""
|
||||
Validate a Kubernetes manifest content.
|
||||
|
||||
Args:
|
||||
content: Manifest content
|
||||
|
||||
Returns:
|
||||
Tuple[bool, Optional[str]]: (is_valid, error_message)
|
||||
"""
|
||||
if not content or not content.strip():
|
||||
return False, "Manifest content cannot be empty."
|
||||
|
||||
# Verify minimum length
|
||||
if len(content.strip()) < 10:
|
||||
return False, "Manifest content is too short."
|
||||
|
||||
# Verify it looks like a manifest K8s
|
||||
if not cls.looks_like_manifest(content):
|
||||
return False, "Content does not appear to be a valid Kubernetes manifest (missing apiVersion or kind)."
|
||||
|
||||
return True, None
|
||||
|
||||
@classmethod
|
||||
def validate_helmfile(cls, content: str) -> Tuple[bool, Optional[str]]:
|
||||
"""
|
||||
Validate a Helmfile content.
|
||||
|
||||
Args:
|
||||
content: Content of a Helmfile
|
||||
|
||||
Returns:
|
||||
Tuple[bool, Optional[str]]: (is_valid, error_message)
|
||||
"""
|
||||
if not content or not content.strip():
|
||||
return False, "Helmfile content cannot be empty."
|
||||
|
||||
if len(content.strip()) < 10:
|
||||
return False, "Helmfile content is too short."
|
||||
|
||||
# Verify it looks like a Helmfile
|
||||
if not cls.looks_like_helmfile(content):
|
||||
return False, "Content does not appear to be a valid Helmfile (missing typical Helmfile keys)."
|
||||
|
||||
return True, None
|
||||
|
||||
@classmethod
|
||||
def validate_helm_chart_url(cls, url: str) -> Tuple[bool, Optional[str]]:
|
||||
"""
|
||||
Validate a Helm chart URL.
|
||||
|
||||
Args:
|
||||
url: URL of the Helm chart
|
||||
|
||||
Returns:
|
||||
Tuple[bool, Optional[str]]: (est_valide, message_erreur)
|
||||
"""
|
||||
if not url or not url.strip():
|
||||
return False, "Chart URL cannot be empty."
|
||||
|
||||
url = url.strip()
|
||||
|
||||
# Verify the helm url pattern
|
||||
if not cls.HELM_URL_PATTERN.match(url):
|
||||
return False, "Invalid Helm chart URL format. Must start with http://, https://, oci://, file://, or be a chart reference."
|
||||
|
||||
return True, None
|
||||
|
||||
@classmethod
|
||||
def validate_output_format(cls, format_str: str) -> Tuple[bool, Optional[str]]:
|
||||
"""
|
||||
Validate output format.
|
||||
|
||||
Args:
|
||||
format_str: output format
|
||||
|
||||
Returns:
|
||||
Tuple[bool, Optional[str]]: (is_valid, error_message)
|
||||
"""
|
||||
if not format_str:
|
||||
return False, "Output format cannot be empty."
|
||||
|
||||
format_str = format_str.lower().strip()
|
||||
|
||||
if format_str not in cls.SUPPORTED_FORMATS:
|
||||
return False, f"Unsupported output format '{format_str}'. Supported formats: {', '.join(cls.SUPPORTED_FORMATS)}"
|
||||
|
||||
return True, None
|
||||
|
||||
@classmethod
|
||||
def validate_extra_args(cls, args: str) -> Tuple[bool, Optional[str]]:
|
||||
"""
|
||||
Validate extra args.
|
||||
|
||||
Args:
|
||||
args: extra_args
|
||||
|
||||
Returns:
|
||||
Tuple[bool, Optional[str]]: (is_valid, error_message)
|
||||
"""
|
||||
if not args or not args.strip():
|
||||
return True, None # Les args vides sont valides
|
||||
|
||||
dangerous_chars = [';', '&', '|', '`', '$', '(', ')']
|
||||
for char in dangerous_chars:
|
||||
if char in args:
|
||||
return False, f"Extra args contain dangerous character '{char}'"
|
||||
|
||||
return True, None
|
||||
|
||||
@staticmethod
|
||||
def looks_like_manifest(text: str) -> bool:
|
||||
"""
|
||||
Heuristic to detect a Kubernetes manifest.
|
||||
|
||||
Args:
|
||||
text: content that will be checked
|
||||
|
||||
Returns:
|
||||
bool: True if it looks like a manifest
|
||||
"""
|
||||
if not text:
|
||||
return False
|
||||
t = text.strip()
|
||||
return bool(MANIFEST_RE.search(t) and KIND_RE.search(t))
|
||||
|
||||
@staticmethod
|
||||
def looks_like_helmfile(text: str) -> bool:
|
||||
"""
|
||||
Heuristic to detect a HelmFile.
|
||||
|
||||
Args:
|
||||
text: Content that will be checked.
|
||||
|
||||
Returns:
|
||||
bool: True if it looks like a Helmfile
|
||||
"""
|
||||
if not text:
|
||||
return False
|
||||
t = text.lower()
|
||||
helmfile_keys = ["\nreleases:", "\nrepositories:", "\nhelmdefaults:", "\nenvironments:", "\ntemplates:"]
|
||||
return any(key in t for key in helmfile_keys)
|
||||
|
||||
# TODO: Not used yet
|
||||
@classmethod
|
||||
def sanitize_filename(cls, filename: str) -> str:
|
||||
"""
|
||||
Clean a filename to make it safe.
|
||||
|
||||
Args:
|
||||
filename: Filename to clean
|
||||
|
||||
Returns:
|
||||
str: Filename cleaned
|
||||
"""
|
||||
safe_filename = re.sub(r'[^a-zA-Z0-9._-]', '_', filename)
|
||||
# Length limit
|
||||
if len(safe_filename) > 255:
|
||||
safe_filename = safe_filename[:255]
|
||||
return safe_filename
|
||||
|
||||
247
webapp/backend/venv/bin/Activate.ps1
Normal file
@@ -0,0 +1,247 @@
|
||||
<#
|
||||
.Synopsis
|
||||
Activate a Python virtual environment for the current PowerShell session.
|
||||
|
||||
.Description
|
||||
Pushes the python executable for a virtual environment to the front of the
|
||||
$Env:PATH environment variable and sets the prompt to signify that you are
|
||||
in a Python virtual environment. Makes use of the command line switches as
|
||||
well as the `pyvenv.cfg` file values present in the virtual environment.
|
||||
|
||||
.Parameter VenvDir
|
||||
Path to the directory that contains the virtual environment to activate. The
|
||||
default value for this is the parent of the directory that the Activate.ps1
|
||||
script is located within.
|
||||
|
||||
.Parameter Prompt
|
||||
The prompt prefix to display when this virtual environment is activated. By
|
||||
default, this prompt is the name of the virtual environment folder (VenvDir)
|
||||
surrounded by parentheses and followed by a single space (ie. '(.venv) ').
|
||||
|
||||
.Example
|
||||
Activate.ps1
|
||||
Activates the Python virtual environment that contains the Activate.ps1 script.
|
||||
|
||||
.Example
|
||||
Activate.ps1 -Verbose
|
||||
Activates the Python virtual environment that contains the Activate.ps1 script,
|
||||
and shows extra information about the activation as it executes.
|
||||
|
||||
.Example
|
||||
Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv
|
||||
Activates the Python virtual environment located in the specified location.
|
||||
|
||||
.Example
|
||||
Activate.ps1 -Prompt "MyPython"
|
||||
Activates the Python virtual environment that contains the Activate.ps1 script,
|
||||
and prefixes the current prompt with the specified string (surrounded in
|
||||
parentheses) while the virtual environment is active.
|
||||
|
||||
.Notes
|
||||
On Windows, it may be required to enable this Activate.ps1 script by setting the
|
||||
execution policy for the user. You can do this by issuing the following PowerShell
|
||||
command:
|
||||
|
||||
PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
||||
|
||||
For more information on Execution Policies:
|
||||
https://go.microsoft.com/fwlink/?LinkID=135170
|
||||
|
||||
#>
|
||||
Param(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[String]
|
||||
$VenvDir,
|
||||
[Parameter(Mandatory = $false)]
|
||||
[String]
|
||||
$Prompt
|
||||
)
|
||||
|
||||
<# Function declarations --------------------------------------------------- #>
|
||||
|
||||
<#
|
||||
.Synopsis
|
||||
Remove all shell session elements added by the Activate script, including the
|
||||
addition of the virtual environment's Python executable from the beginning of
|
||||
the PATH variable.
|
||||
|
||||
.Parameter NonDestructive
|
||||
If present, do not remove this function from the global namespace for the
|
||||
session.
|
||||
|
||||
#>
|
||||
function global:deactivate ([switch]$NonDestructive) {
|
||||
# Revert to original values
|
||||
|
||||
# The prior prompt:
|
||||
if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) {
|
||||
Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt
|
||||
Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT
|
||||
}
|
||||
|
||||
# The prior PYTHONHOME:
|
||||
if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) {
|
||||
Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME
|
||||
Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME
|
||||
}
|
||||
|
||||
# The prior PATH:
|
||||
if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) {
|
||||
Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH
|
||||
Remove-Item -Path Env:_OLD_VIRTUAL_PATH
|
||||
}
|
||||
|
||||
# Just remove the VIRTUAL_ENV altogether:
|
||||
if (Test-Path -Path Env:VIRTUAL_ENV) {
|
||||
Remove-Item -Path env:VIRTUAL_ENV
|
||||
}
|
||||
|
||||
# Just remove VIRTUAL_ENV_PROMPT altogether.
|
||||
if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) {
|
||||
Remove-Item -Path env:VIRTUAL_ENV_PROMPT
|
||||
}
|
||||
|
||||
# Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether:
|
||||
if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) {
|
||||
Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force
|
||||
}
|
||||
|
||||
# Leave deactivate function in the global namespace if requested:
|
||||
if (-not $NonDestructive) {
|
||||
Remove-Item -Path function:deactivate
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.Description
|
||||
Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the
|
||||
given folder, and returns them in a map.
|
||||
|
||||
For each line in the pyvenv.cfg file, if that line can be parsed into exactly
|
||||
two strings separated by `=` (with any amount of whitespace surrounding the =)
|
||||
then it is considered a `key = value` line. The left hand string is the key,
|
||||
the right hand is the value.
|
||||
|
||||
If the value starts with a `'` or a `"` then the first and last character is
|
||||
stripped from the value before being captured.
|
||||
|
||||
.Parameter ConfigDir
|
||||
Path to the directory that contains the `pyvenv.cfg` file.
|
||||
#>
|
||||
function Get-PyVenvConfig(
|
||||
[String]
|
||||
$ConfigDir
|
||||
) {
|
||||
Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg"
|
||||
|
||||
# Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue).
|
||||
$pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue
|
||||
|
||||
# An empty map will be returned if no config file is found.
|
||||
$pyvenvConfig = @{ }
|
||||
|
||||
if ($pyvenvConfigPath) {
|
||||
|
||||
Write-Verbose "File exists, parse `key = value` lines"
|
||||
$pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath
|
||||
|
||||
$pyvenvConfigContent | ForEach-Object {
|
||||
$keyval = $PSItem -split "\s*=\s*", 2
|
||||
if ($keyval[0] -and $keyval[1]) {
|
||||
$val = $keyval[1]
|
||||
|
||||
# Remove extraneous quotations around a string value.
|
||||
if ("'""".Contains($val.Substring(0, 1))) {
|
||||
$val = $val.Substring(1, $val.Length - 2)
|
||||
}
|
||||
|
||||
$pyvenvConfig[$keyval[0]] = $val
|
||||
Write-Verbose "Adding Key: '$($keyval[0])'='$val'"
|
||||
}
|
||||
}
|
||||
}
|
||||
return $pyvenvConfig
|
||||
}
|
||||
|
||||
|
||||
<# Begin Activate script --------------------------------------------------- #>
|
||||
|
||||
# Determine the containing directory of this script
|
||||
$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
|
||||
$VenvExecDir = Get-Item -Path $VenvExecPath
|
||||
|
||||
Write-Verbose "Activation script is located in path: '$VenvExecPath'"
|
||||
Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)"
|
||||
Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)"
|
||||
|
||||
# Set values required in priority: CmdLine, ConfigFile, Default
|
||||
# First, get the location of the virtual environment, it might not be
|
||||
# VenvExecDir if specified on the command line.
|
||||
if ($VenvDir) {
|
||||
Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values"
|
||||
}
|
||||
else {
|
||||
Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir."
|
||||
$VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/")
|
||||
Write-Verbose "VenvDir=$VenvDir"
|
||||
}
|
||||
|
||||
# Next, read the `pyvenv.cfg` file to determine any required value such
|
||||
# as `prompt`.
|
||||
$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir
|
||||
|
||||
# Next, set the prompt from the command line, or the config file, or
|
||||
# just use the name of the virtual environment folder.
|
||||
if ($Prompt) {
|
||||
Write-Verbose "Prompt specified as argument, using '$Prompt'"
|
||||
}
|
||||
else {
|
||||
Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value"
|
||||
if ($pyvenvCfg -and $pyvenvCfg['prompt']) {
|
||||
Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'"
|
||||
$Prompt = $pyvenvCfg['prompt'];
|
||||
}
|
||||
else {
|
||||
Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)"
|
||||
Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'"
|
||||
$Prompt = Split-Path -Path $venvDir -Leaf
|
||||
}
|
||||
}
|
||||
|
||||
Write-Verbose "Prompt = '$Prompt'"
|
||||
Write-Verbose "VenvDir='$VenvDir'"
|
||||
|
||||
# Deactivate any currently active virtual environment, but leave the
|
||||
# deactivate function in place.
|
||||
deactivate -nondestructive
|
||||
|
||||
# Now set the environment variable VIRTUAL_ENV, used by many tools to determine
|
||||
# that there is an activated venv.
|
||||
$env:VIRTUAL_ENV = $VenvDir
|
||||
|
||||
if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
|
||||
|
||||
Write-Verbose "Setting prompt to '$Prompt'"
|
||||
|
||||
# Set the prompt to include the env name
|
||||
# Make sure _OLD_VIRTUAL_PROMPT is global
|
||||
function global:_OLD_VIRTUAL_PROMPT { "" }
|
||||
Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT
|
||||
New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt
|
||||
|
||||
function global:prompt {
|
||||
Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) "
|
||||
_OLD_VIRTUAL_PROMPT
|
||||
}
|
||||
$env:VIRTUAL_ENV_PROMPT = $Prompt
|
||||
}
|
||||
|
||||
# Clear PYTHONHOME
|
||||
if (Test-Path -Path Env:PYTHONHOME) {
|
||||
Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME
|
||||
Remove-Item -Path Env:PYTHONHOME
|
||||
}
|
||||
|
||||
# Add the venv to the PATH
|
||||
Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH
|
||||
$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH"
|
||||
70
webapp/backend/venv/bin/activate
Normal file
@@ -0,0 +1,70 @@
|
||||
# This file must be used with "source bin/activate" *from bash*
|
||||
# You cannot run it directly
|
||||
|
||||
deactivate () {
|
||||
# reset old environment variables
|
||||
if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
|
||||
PATH="${_OLD_VIRTUAL_PATH:-}"
|
||||
export PATH
|
||||
unset _OLD_VIRTUAL_PATH
|
||||
fi
|
||||
if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
|
||||
PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
|
||||
export PYTHONHOME
|
||||
unset _OLD_VIRTUAL_PYTHONHOME
|
||||
fi
|
||||
|
||||
# Call hash to forget past commands. Without forgetting
|
||||
# past commands the $PATH changes we made may not be respected
|
||||
hash -r 2> /dev/null
|
||||
|
||||
if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
|
||||
PS1="${_OLD_VIRTUAL_PS1:-}"
|
||||
export PS1
|
||||
unset _OLD_VIRTUAL_PS1
|
||||
fi
|
||||
|
||||
unset VIRTUAL_ENV
|
||||
unset VIRTUAL_ENV_PROMPT
|
||||
if [ ! "${1:-}" = "nondestructive" ] ; then
|
||||
# Self destruct!
|
||||
unset -f deactivate
|
||||
fi
|
||||
}
|
||||
|
||||
# unset irrelevant variables
|
||||
deactivate nondestructive
|
||||
|
||||
# on Windows, a path can contain colons and backslashes and has to be converted:
|
||||
if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then
|
||||
# transform D:\path\to\venv to /d/path/to/venv on MSYS
|
||||
# and to /cygdrive/d/path/to/venv on Cygwin
|
||||
export VIRTUAL_ENV=$(cygpath /home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv)
|
||||
else
|
||||
# use the path as-is
|
||||
export VIRTUAL_ENV=/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv
|
||||
fi
|
||||
|
||||
_OLD_VIRTUAL_PATH="$PATH"
|
||||
PATH="$VIRTUAL_ENV/"bin":$PATH"
|
||||
export PATH
|
||||
|
||||
# unset PYTHONHOME if set
|
||||
# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
|
||||
# could use `if (set -u; : $PYTHONHOME) ;` in bash
|
||||
if [ -n "${PYTHONHOME:-}" ] ; then
|
||||
_OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
|
||||
unset PYTHONHOME
|
||||
fi
|
||||
|
||||
if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
|
||||
_OLD_VIRTUAL_PS1="${PS1:-}"
|
||||
PS1='(venv) '"${PS1:-}"
|
||||
export PS1
|
||||
VIRTUAL_ENV_PROMPT='(venv) '
|
||||
export VIRTUAL_ENV_PROMPT
|
||||
fi
|
||||
|
||||
# Call hash to forget past commands. Without forgetting
|
||||
# past commands the $PATH changes we made may not be respected
|
||||
hash -r 2> /dev/null
|
||||
27
webapp/backend/venv/bin/activate.csh
Normal file
@@ -0,0 +1,27 @@
|
||||
# This file must be used with "source bin/activate.csh" *from csh*.
|
||||
# You cannot run it directly.
|
||||
|
||||
# Created by Davide Di Blasi <davidedb@gmail.com>.
|
||||
# Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com>
|
||||
|
||||
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate'
|
||||
|
||||
# Unset irrelevant variables.
|
||||
deactivate nondestructive
|
||||
|
||||
setenv VIRTUAL_ENV /home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv
|
||||
|
||||
set _OLD_VIRTUAL_PATH="$PATH"
|
||||
setenv PATH "$VIRTUAL_ENV/"bin":$PATH"
|
||||
|
||||
|
||||
set _OLD_VIRTUAL_PROMPT="$prompt"
|
||||
|
||||
if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then
|
||||
set prompt = '(venv) '"$prompt"
|
||||
setenv VIRTUAL_ENV_PROMPT '(venv) '
|
||||
endif
|
||||
|
||||
alias pydoc python -m pydoc
|
||||
|
||||
rehash
|
||||
69
webapp/backend/venv/bin/activate.fish
Normal file
@@ -0,0 +1,69 @@
|
||||
# This file must be used with "source <venv>/bin/activate.fish" *from fish*
|
||||
# (https://fishshell.com/). You cannot run it directly.
|
||||
|
||||
function deactivate -d "Exit virtual environment and return to normal shell environment"
|
||||
# reset old environment variables
|
||||
if test -n "$_OLD_VIRTUAL_PATH"
|
||||
set -gx PATH $_OLD_VIRTUAL_PATH
|
||||
set -e _OLD_VIRTUAL_PATH
|
||||
end
|
||||
if test -n "$_OLD_VIRTUAL_PYTHONHOME"
|
||||
set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME
|
||||
set -e _OLD_VIRTUAL_PYTHONHOME
|
||||
end
|
||||
|
||||
if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
|
||||
set -e _OLD_FISH_PROMPT_OVERRIDE
|
||||
# prevents error when using nested fish instances (Issue #93858)
|
||||
if functions -q _old_fish_prompt
|
||||
functions -e fish_prompt
|
||||
functions -c _old_fish_prompt fish_prompt
|
||||
functions -e _old_fish_prompt
|
||||
end
|
||||
end
|
||||
|
||||
set -e VIRTUAL_ENV
|
||||
set -e VIRTUAL_ENV_PROMPT
|
||||
if test "$argv[1]" != "nondestructive"
|
||||
# Self-destruct!
|
||||
functions -e deactivate
|
||||
end
|
||||
end
|
||||
|
||||
# Unset irrelevant variables.
|
||||
deactivate nondestructive
|
||||
|
||||
set -gx VIRTUAL_ENV /home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv
|
||||
|
||||
set -gx _OLD_VIRTUAL_PATH $PATH
|
||||
set -gx PATH "$VIRTUAL_ENV/"bin $PATH
|
||||
|
||||
# Unset PYTHONHOME if set.
|
||||
if set -q PYTHONHOME
|
||||
set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
|
||||
set -e PYTHONHOME
|
||||
end
|
||||
|
||||
if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
|
||||
# fish uses a function instead of an env var to generate the prompt.
|
||||
|
||||
# Save the current fish_prompt function as the function _old_fish_prompt.
|
||||
functions -c fish_prompt _old_fish_prompt
|
||||
|
||||
# With the original prompt function renamed, we can override with our own.
|
||||
function fish_prompt
|
||||
# Save the return status of the last command.
|
||||
set -l old_status $status
|
||||
|
||||
# Output the venv prompt; color taken from the blue of the Python logo.
|
||||
printf "%s%s%s" (set_color 4B8BBE) '(venv) ' (set_color normal)
|
||||
|
||||
# Restore the return status of the previous command.
|
||||
echo "exit $old_status" | .
|
||||
# Output the original/"old" prompt.
|
||||
_old_fish_prompt
|
||||
end
|
||||
|
||||
set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
|
||||
set -gx VIRTUAL_ENV_PROMPT '(venv) '
|
||||
end
|
||||
8
webapp/backend/venv/bin/diagrams
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from diagrams.cli import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
webapp/backend/venv/bin/flask
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from flask.cli import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
webapp/backend/venv/bin/gunicorn
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from gunicorn.app.wsgiapp import run
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(run())
|
||||
136
webapp/backend/venv/bin/helm-diagrams
Executable file
@@ -0,0 +1,136 @@
|
||||
#!/bin/bash
|
||||
|
||||
# helm-diagrams: A script to generate a diagram of an Helm chart
|
||||
# using kube-diagrams from the output of 'helm template <name> <chart>'
|
||||
|
||||
# Check if kube-diagrams is installed
|
||||
if ! command -v kube-diagrams &>/dev/null; then
|
||||
echo "Error: kube-diagrams is not installed. Please install it first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if helm is installed
|
||||
if ! command -v helm &>/dev/null; then
|
||||
echo "Error: helm is not installed. Please install it first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Display help message
|
||||
show_help() {
|
||||
echo "Usage: helm-diagrams <helm-chart-url> [OPTIONS] [FLAGS]"
|
||||
echo ""
|
||||
echo "A script to generate a diagram of an Helm chart using kube-diagrams."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -o, --output <file> Specify the output file for the diagram"
|
||||
echo " -f, --format <format> Specify the output format (e.g., png, svg)"
|
||||
echo " --embed-all-icons Embed all icons into svg or dot_json output diagrams"
|
||||
echo " -c, --config <file> Specify the custom kube-diagrams configuration file"
|
||||
echo " -h, --help Display this help message"
|
||||
echo ""
|
||||
echo "Any flag supported by helm template, e.g.:"
|
||||
echo " -g, --generate-name Generate the name (and omit the NAME parameter)"
|
||||
echo " --include-crds Include CRDs in the templated output"
|
||||
echo " -l, --labels stringToString Labels that would be added to release metadata. Should be divided by comma. (default [])"
|
||||
echo " --name-template string Specify template used to name the release"
|
||||
echo " --set stringArray Set values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)"
|
||||
echo " --set-file stringArray Set values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2)"
|
||||
echo " --set-json stringArray Set JSON values on the command line (can specify multiple or separate values with commas: key1=jsonval1,key2=jsonval2)"
|
||||
echo " --set-literal stringArray Set a literal STRING value on the command line"
|
||||
echo " --set-string stringArray Set STRING values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)"
|
||||
echo " -f, --values strings Specify values in a YAML file or a URL (can specify multiple)"
|
||||
echo " --version string Specify a version constraint for the chart version to use. This constraint can be a specific tag (e.g. 1.1.1) or it may reference a valid range (e.g. ^2.0.0). If this is not specified, the latest version is used"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " helm-diagrams https://charts.jetstack.io/cert-manager -o diagram.png"
|
||||
echo " helm-diagrams https://charts.jetstack.io/cert-manager --set crds.enabled=true -o cert-manager.png"
|
||||
echo " helm-diagrams oci://ghcr.io/argoproj/argo-helm/argo-cd -f svg"
|
||||
echo " helm-diagrams --help"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Initialize variables
|
||||
HELM_CHART_URL=""
|
||||
HELM_ARGS=()
|
||||
KUBE_DIAGRAMS_ARGS=("-" "--without-namespace") # Default to stdin indicator
|
||||
|
||||
# Use the KubeDiagrams custom configuration if exist.
|
||||
KD_CC="KubeDiagrams.yaml"
|
||||
if [ -e $KD_CC ]
|
||||
then
|
||||
KUBE_DIAGRAMS_ARGS+=("--config" "$KD_CC")
|
||||
fi
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-h | --help)
|
||||
show_help
|
||||
;;
|
||||
-o | --output | -f | --format | -c | --config)
|
||||
KUBE_DIAGRAMS_ARGS+=("$1")
|
||||
if [[ -n "$2" ]]; then
|
||||
KUBE_DIAGRAMS_ARGS+=("$2")
|
||||
shift 2
|
||||
else
|
||||
echo "Error: $1 requires a value!"
|
||||
exit 64
|
||||
fi
|
||||
;;
|
||||
--embed-all-icons)
|
||||
KUBE_DIAGRAMS_ARGS+=("$1")
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
if [ -z "${HELM_CHART_URL}" ]; then
|
||||
HELM_CHART_URL=$1
|
||||
repository=$(dirname ${HELM_CHART_URL})
|
||||
name=$(basename ${HELM_CHART_URL})
|
||||
KUBE_DIAGRAMS_ARGS+=("--output" "${name}")
|
||||
else
|
||||
HELM_ARGS+=("$1")
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check if any Helm chart url was specified
|
||||
if [ -z "${HELM_CHART_URL}" ]; then
|
||||
echo "Error: At least one Helm chart URL must be specified!"
|
||||
exit 64
|
||||
fi
|
||||
|
||||
echo Download ${HELM_CHART_URL}...
|
||||
|
||||
if [[ ${repository} == oci* ]]; then
|
||||
# Deal with OCI registries.
|
||||
# Execute helm and pipe to kube-diagrams with arguments
|
||||
helm template ${name} ${HELM_CHART_URL} "${HELM_ARGS[@]}" | kube-diagrams "${KUBE_DIAGRAMS_ARGS[@]}"
|
||||
EXIT_CODE=$?
|
||||
elif [[ ${repository} == http* ]]; then
|
||||
# Deal with HTTP registries.
|
||||
|
||||
# Add a Helm repository.
|
||||
rid=helm-diagrams-repo
|
||||
helm repo add $rid $repository --force-update >/dev/null
|
||||
|
||||
# Execute helm and pipe to kube-diagrams with arguments
|
||||
helm template ${name} $rid/${name} "${HELM_ARGS[@]}" | kube-diagrams "${KUBE_DIAGRAMS_ARGS[@]}"
|
||||
EXIT_CODE=$?
|
||||
|
||||
# Remove the Helm repository.
|
||||
helm repo remove $rid >/dev/null
|
||||
else
|
||||
# Deal with local charts
|
||||
# Execute helm and pipe to kube-diagrams with arguments
|
||||
helm template ${name} ${repository}/${name} "${HELM_ARGS[@]}" | kube-diagrams -o local-$name "${KUBE_DIAGRAMS_ARGS[@]}"
|
||||
EXIT_CODE=$?
|
||||
fi
|
||||
|
||||
if [[ $EXIT_CODE -eq 0 ]]; then
|
||||
echo "Diagram generated successfully"
|
||||
else
|
||||
echo "Error: Failed to generate diagram!"
|
||||
exit 1
|
||||
fi
|
||||
BIN
webapp/backend/venv/bin/icons/apiservice.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
webapp/backend/venv/bin/icons/container.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
BIN
webapp/backend/venv/bin/icons/csidriver.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
webapp/backend/venv/bin/icons/csinode.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
webapp/backend/venv/bin/icons/csisc.png
Normal file
|
After Width: | Height: | Size: 9.7 KiB |
BIN
webapp/backend/venv/bin/icons/eps.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
webapp/backend/venv/bin/icons/ic.png
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
webapp/backend/venv/bin/icons/lease.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
webapp/backend/venv/bin/icons/mwc.png
Normal file
|
After Width: | Height: | Size: 9.7 KiB |
BIN
webapp/backend/venv/bin/icons/pc.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
webapp/backend/venv/bin/icons/pdb.png
Normal file
|
After Width: | Height: | Size: 8.0 KiB |
BIN
webapp/backend/venv/bin/icons/podtemplate.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
BIN
webapp/backend/venv/bin/icons/rc.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
webapp/backend/venv/bin/icons/runtimeclass.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
webapp/backend/venv/bin/icons/vpa.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
BIN
webapp/backend/venv/bin/icons/vwc.png
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
8
webapp/backend/venv/bin/identify-cli
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from identify.cli import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
1477
webapp/backend/venv/bin/kube-diagrams
Executable file
689
webapp/backend/venv/bin/kube-diagrams.yaml
Normal file
@@ -0,0 +1,689 @@
|
||||
# Configuration of kube-diagrams
|
||||
default_namespace: default
|
||||
edges:
|
||||
REFERENCE:
|
||||
color: black
|
||||
REFERENCE-UP:
|
||||
color: black
|
||||
direction: up
|
||||
SELECTOR:
|
||||
color: black
|
||||
style: dashed
|
||||
SELECTOR-UP:
|
||||
color: black
|
||||
style: dashed
|
||||
direction: up
|
||||
CONTROLLED_BY:
|
||||
xlabel: controller
|
||||
color: black
|
||||
style: dotted
|
||||
OWNER:
|
||||
color: black
|
||||
style: dotted
|
||||
COMMUNICATION:
|
||||
color: brown
|
||||
DEPENDENCE:
|
||||
color: darkgrey
|
||||
INVISIBLE:
|
||||
color: transparent
|
||||
style: invisible
|
||||
direction: up
|
||||
clusters:
|
||||
- label: app.kubernetes.io/instance
|
||||
title: "K8s Instance: {}"
|
||||
recommended: true
|
||||
graph_attr:
|
||||
bgcolor: "#E5F5FD"
|
||||
- label: release
|
||||
title: "Release: {}"
|
||||
recommended: false
|
||||
graph_attr:
|
||||
bgcolor: "#E5F5FD"
|
||||
- label: helm.sh/chart
|
||||
title: "Helm Chart: {}"
|
||||
recommended: true
|
||||
graph_attr:
|
||||
bgcolor: "#EBF3E7"
|
||||
- label: chart
|
||||
title: "Chart: {}"
|
||||
recommended: false
|
||||
graph_attr:
|
||||
bgcolor: "#EBF3E7"
|
||||
- label: app.kubernetes.io/name
|
||||
title: "K8s Application: {}"
|
||||
recommended: true
|
||||
graph_attr:
|
||||
bgcolor: "#ECE8F6"
|
||||
- label: app
|
||||
title: "Application: {}"
|
||||
recommended: false
|
||||
graph_attr:
|
||||
bgcolor: "#ECE8F6"
|
||||
- label: tier
|
||||
title: "Tier: {}"
|
||||
recommended: false
|
||||
graph_attr:
|
||||
bgcolor: "#ECE8F6"
|
||||
- label: app.kubernetes.io/component
|
||||
title: "K8s Component: {}"
|
||||
recommended: true
|
||||
graph_attr:
|
||||
bgcolor: "#FDF7E3"
|
||||
- label: component
|
||||
title: "Component: {}"
|
||||
recommended: false
|
||||
graph_attr:
|
||||
bgcolor: "#FDF7E3"
|
||||
- label: service
|
||||
title: "Microservice: {}"
|
||||
recommended: false
|
||||
graph_attr:
|
||||
bgcolor: "#FDF7E3"
|
||||
- label: rbac.authorization.k8s.io/aggregate-to-admin
|
||||
title: "Admin ClusterRole Aggregation"
|
||||
recommended: true
|
||||
graph_attr:
|
||||
bgcolor: transparent
|
||||
- label: rbac.authorization.k8s.io/aggregate-to-edit
|
||||
title: "Edit ClusterRole Aggregation"
|
||||
recommended: true
|
||||
graph_attr:
|
||||
bgcolor: transparent
|
||||
- label: rbac.authorization.k8s.io/aggregate-to-view
|
||||
title: "View ClusterRole Aggregation"
|
||||
recommended: true
|
||||
graph_attr:
|
||||
bgcolor: transparent
|
||||
- annotation: helm.sh/hook
|
||||
title: "{}"
|
||||
recommended: true
|
||||
graph_attr:
|
||||
bgcolor: "#EBF3E7"
|
||||
style: dotted,rounded
|
||||
nodes:
|
||||
APIService/apiregistration.k8s.io/v1:
|
||||
scope: Cluster
|
||||
custom_icon: $KD/icons/apiservice.png
|
||||
edges: |
|
||||
service = query_path(resource, "spec.service")
|
||||
if service is not None:
|
||||
edges.add_edge_to(
|
||||
"spec.service",
|
||||
service['name'],
|
||||
service['namespace'],
|
||||
"Service",
|
||||
"v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
APIService/apiregistration.k8s.io/v1beta1: APIService/apiregistration.k8s.io/v1
|
||||
ClusterRole/rbac.authorization.k8s.io/v1:
|
||||
scope: Cluster
|
||||
diagram_node_classname: diagrams.k8s.rbac.CRole
|
||||
edges: |
|
||||
for idx, clusterRoleSelector in enumerate(query_path(resource, "aggregationRule.clusterRoleSelectors", [])):
|
||||
edges.add_all_resources_matching_labels(
|
||||
"ClusterRole",
|
||||
f"aggregationRule.clusterRoleSelectors[{idx}]",
|
||||
match_labels=clusterRoleSelector.get("matchLabels"),
|
||||
tooltip_data=clusterRoleSelector
|
||||
)
|
||||
edges.add_rules_resource_names()
|
||||
ClusterRole/rbac.authorization.k8s.io/v1beta1: ClusterRole/rbac.authorization.k8s.io/v1
|
||||
ClusterRoleBinding/rbac.authorization.k8s.io/v1:
|
||||
scope: Cluster
|
||||
diagram_node_classname: diagrams.k8s.rbac.CRB
|
||||
edges: |
|
||||
edges.add_role("roleRef")
|
||||
edges.add_subjects()
|
||||
ClusterRoleBinding/rbac.authorization.k8s.io/v1beta1: ClusterRoleBinding/rbac.authorization.k8s.io/v1
|
||||
ConfigMap/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.podconfig.CM
|
||||
# no edges
|
||||
CronJob/batch/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.compute.Cronjob
|
||||
edges: |
|
||||
edges.add_owned_resources()
|
||||
edges.add_service_account("spec.jobTemplate.spec.template.spec")
|
||||
edges.add_all_volume_resources("spec.jobTemplate.spec.template.spec.volumes")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.jobTemplate.spec.template.spec.containers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.jobTemplate.spec.template.spec.initContainers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.jobTemplate.spec.template.spec.ephemeralContainers")
|
||||
edges.add_wait_for_services("spec.jobTemplate.spec.template.spec.initContainers")
|
||||
edges.add_networks("spec.jobTemplate.spec.template.metadata.annotations")
|
||||
edges.add_priority_class("spec.jobTemplate.spec.template.spec.priorityClassName")
|
||||
edges.add_edge_to(
|
||||
"spec.jobTemplate.spec.template.spec.runtimeClassName",
|
||||
".",
|
||||
None,
|
||||
"RuntimeClass",
|
||||
"node.k8s.io/v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
CronJob/batch/v1beta1: CronJob/batch/v1
|
||||
CustomResourceDefinition/apiextensions.k8s.io/v1:
|
||||
scope: Cluster
|
||||
diagram_node_classname: diagrams.k8s.others.CRD
|
||||
# no edges
|
||||
CustomResourceDefinition/apiextensions.k8s.io/v1beta1: CustomResourceDefinition/apiextensions.k8s.io/v1
|
||||
CSIDriver/storage.k8s.io/v1:
|
||||
scope: Cluster
|
||||
custom_icon: $KD/icons/csidriver.png
|
||||
# no edges
|
||||
CSIDriver/storage.k8s.io/v1beta1: CSIDriver/storage.k8s.io/v1
|
||||
CSINode/storage.k8s.io/v1:
|
||||
scope: Cluster
|
||||
custom_icon: $KD/icons/csinode.png
|
||||
edges: |
|
||||
for idx, driver in enumerate(query_path(resource, "spec.drivers", [])):
|
||||
edges.add_edge_to(
|
||||
f"spec.drivers[{idx}]",
|
||||
driver['name'],
|
||||
None,
|
||||
"CSIDriver",
|
||||
"storage.k8s.io/v1",
|
||||
"REFERENCE",
|
||||
data=driver
|
||||
)
|
||||
CSIStorageCapacity/storage.k8s.io/v1:
|
||||
scope: Namescaped
|
||||
custom_icon: $KD/icons/csisc.png
|
||||
edges: |
|
||||
edges.add_edge_to(
|
||||
"storageClassName",
|
||||
".",
|
||||
None,
|
||||
"StorageClass",
|
||||
"storage.k8s.io/v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
DaemonSet/apps/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.compute.DS
|
||||
edges: |
|
||||
edges.add_owned_resources()
|
||||
edges.add_service_account("spec.template.spec")
|
||||
edges.add_all_volume_resources("spec.template.spec.volumes")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.containers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.initContainers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.ephemeralContainers")
|
||||
edges.add_wait_for_services("spec.template.spec.initContainers")
|
||||
edges.add_networks("spec.template.metadata.annotations")
|
||||
edges.add_priority_class("spec.template.spec.priorityClassName")
|
||||
edges.add_edge_to(
|
||||
"spec.template.spec.runtimeClassName",
|
||||
".",
|
||||
None,
|
||||
"RuntimeClass",
|
||||
"node.k8s.io/v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
DaemonSet/apps/v1beta2: DaemonSet/apps/v1
|
||||
DaemonSet/extensions/v1beta1: DaemonSet/apps/v1
|
||||
Deployment/apps/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.compute.Deploy
|
||||
edges: |
|
||||
edges.add_owned_resources()
|
||||
edges.add_service_account("spec.template.spec")
|
||||
edges.add_all_volume_resources("spec.template.spec.volumes")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.containers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.initContainers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.ephemeralContainers")
|
||||
edges.add_wait_for_services("spec.template.spec.initContainers")
|
||||
edges.add_networks("spec.template.metadata.annotations")
|
||||
edges.add_priority_class("spec.template.spec.priorityClassName")
|
||||
edges.add_edge_to(
|
||||
"spec.template.spec.runtimeClassName",
|
||||
".",
|
||||
None,
|
||||
"RuntimeClass",
|
||||
"node.k8s.io/v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
Deployment/extensions/v1beta1: Deployment/apps/v1
|
||||
Deployment/apps/v1beta1: Deployment/apps/v1
|
||||
Deployment/apps/v1beta2: Deployment/apps/v1
|
||||
Endpoints/v1:
|
||||
scope: Namespaced
|
||||
plural: endpoints
|
||||
diagram_node_classname: diagrams.k8s.network.Endpoint
|
||||
edges: |
|
||||
for sidx, subset in enumerate(resource.get("subsets", [])):
|
||||
for aidx, address in enumerate(subset.get("addresses", [])):
|
||||
if "targetRef" in address:
|
||||
target = address["targetRef"]
|
||||
edges.add_edge_to(
|
||||
f"subsets[{sidx}].addresses[{aidx}].targetRef",
|
||||
target["name"],
|
||||
target.get("namespace"),
|
||||
target["kind"],
|
||||
"v1",
|
||||
"REFERENCE",
|
||||
data=target
|
||||
)
|
||||
EndpointSlice/discovery.k8s.io/v1:
|
||||
scope: Namespaced
|
||||
custom_icon: $KD/icons/eps.png
|
||||
edges: |
|
||||
for idx, endpoint in enumerate(resource.get("endpoints", [])):
|
||||
if "targetRef" in endpoint:
|
||||
target = endpoint["targetRef"]
|
||||
edges.add_edge_to(
|
||||
f"endpoints[{idx}].targetRef",
|
||||
target["name"],
|
||||
target["namespace"],
|
||||
target["kind"],
|
||||
"v1",
|
||||
"REFERENCE",
|
||||
data=target
|
||||
)
|
||||
Group/rbac.authorization.k8s.io/v1:
|
||||
scope: Cluster
|
||||
diagram_node_classname: diagrams.k8s.rbac.Group
|
||||
# no edges
|
||||
HorizontalPodAutoscaler/autoscaling/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.clusterconfig.HPA
|
||||
edges: |
|
||||
edges.add_resource("spec.scaleTargetRef")
|
||||
HorizontalPodAutoscaler/autoscaling/v2:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.clusterconfig.HPA
|
||||
edges: |
|
||||
edges.add_resource("spec.scaleTargetRef")
|
||||
HorizontalPodAutoscaler/autoscaling/v2beta1: HorizontalPodAutoscaler/autoscaling/v2
|
||||
HorizontalPodAutoscaler/autoscaling/v2beta2: HorizontalPodAutoscaler/autoscaling/v2
|
||||
Ingress/networking.k8s.io/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.network.Ing
|
||||
edges: |
|
||||
edges.add_service("spec.defaultBackend.service.name")
|
||||
for ridx, rule in enumerate(query_path(resource, "spec.rules", [])):
|
||||
for pidx, path in enumerate(query_path(rule, "http.paths", [])):
|
||||
edges.add_service(f"spec.rules[{ridx}].http.paths[{pidx}].backend.service.name", name=query_path(path, "backend.service.name"))
|
||||
edges.add_edge_to(
|
||||
"spec.ingressClassName",
|
||||
".",
|
||||
None,
|
||||
"IngressClass",
|
||||
"networking.k8s.io/v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
for idx, tls in enumerate(query_path(resource, "spec.tls", [])):
|
||||
edges.add_edge_to(
|
||||
f"spec.tls[{idx}]",
|
||||
tls.get("secretName"),
|
||||
get_namespace(resource),
|
||||
"Secret",
|
||||
"v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
Ingress/networking.k8s.io/v1beta1: Ingress/networking.k8s.io/v1
|
||||
Ingress/extensions/v1beta1: Ingress/networking.k8s.io/v1
|
||||
IngressClass/networking.k8s.io/v1:
|
||||
scope: Cluster
|
||||
custom_icon: $KD/icons/ic.png
|
||||
edges: |
|
||||
# TODO: Following works well with ingress-nginx but was not
|
||||
# been tested with any other ingress implementations.
|
||||
edges.add_all_resources_matching_labels("Pod", "metadata.labels",
|
||||
edge_kind="CONTROLLED_BY")
|
||||
IngressClass/networking.k8s.io/v1beta1: IngressClass/networking.k8s.io/v1
|
||||
Job/batch/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.compute.Job
|
||||
edges: |
|
||||
edges.add_owned_resources()
|
||||
edges.add_service_account("spec.template.spec")
|
||||
edges.add_all_volume_resources("spec.template.spec.volumes")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.containers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.initContainers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.ephemeralContainers")
|
||||
edges.add_wait_for_services("spec.template.spec.initContainers")
|
||||
edges.add_networks("spec.template.metadata.annotations")
|
||||
edges.add_priority_class("spec.template.spec.priorityClassName")
|
||||
edges.add_edge_to(
|
||||
"spec.template.spec.runtimeClassName",
|
||||
".",
|
||||
None,
|
||||
"RuntimeClass",
|
||||
"node.k8s.io/v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
Job/batch/v1beta1: Job/batch/v1
|
||||
Lease/coordination.k8s.io/v1:
|
||||
scope: Namespaced
|
||||
custom_icon: $KD/icons/lease.png
|
||||
# no edges
|
||||
LimitRange/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.clusterconfig.LimitRange
|
||||
# no edges
|
||||
MutatingWebhookConfiguration/admissionregistration.k8s.io/v1:
|
||||
scope: Cluster
|
||||
custom_icon: $KD/icons/mwc.png
|
||||
edges: |
|
||||
edges.add_webhooks()
|
||||
MutatingWebhookConfiguration/admissionregistration.k8s.io/v1beta1: MutatingWebhookConfiguration/admissionregistration.k8s.io/v1
|
||||
Namespace/v1:
|
||||
scope: Cluster
|
||||
diagram_node_classname: diagrams.k8s.group.NS
|
||||
# no edges
|
||||
NetworkAttachmentDefinition/k8s.cni.cncf.io/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.azure.network.NetworkInterfaces
|
||||
# no edges
|
||||
NetworkPolicy/networking.k8s.io/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.network.NetworkPolicy
|
||||
edges: |
|
||||
edges.add_all_workload_resources(
|
||||
"spec.podSelector.matchLabels",
|
||||
default_selector={},
|
||||
edge_kind="SELECTOR-UP"
|
||||
)
|
||||
edges.add_ingress_and_egress_rules()
|
||||
Node/v1:
|
||||
scope: Cluster
|
||||
diagram_node_classname: diagrams.k8s.infra.Node
|
||||
edges: |
|
||||
edges.add_owned_resources()
|
||||
PersistentVolume/v1:
|
||||
scope: Cluster
|
||||
diagram_node_classname: diagrams.k8s.storage.PV
|
||||
edges: |
|
||||
edges.add_edge_to(
|
||||
"spec.storageClassName",
|
||||
".",
|
||||
None,
|
||||
"StorageClass",
|
||||
"storage.k8s.io/v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
PersistentVolumeClaim/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.storage.PVC
|
||||
edges: |
|
||||
if query_path(resource, "spec.storageClassName") != "":
|
||||
edges.add_edge_to(
|
||||
"spec.storageClassName",
|
||||
".",
|
||||
None,
|
||||
"StorageClass",
|
||||
"storage.k8s.io/v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
edges.add_edge_to(
|
||||
"spec.volumeName",
|
||||
".",
|
||||
None,
|
||||
"PersistentVolume",
|
||||
"v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
PriorityClass/scheduling.k8s.io/v1:
|
||||
scope: Cluster
|
||||
custom_icon: $KD/icons/pc.png
|
||||
# no edges
|
||||
PriorityClass/scheduling.k8s.io/v1beta1: PriorityClass/scheduling.k8s.io/v1
|
||||
Pod/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.compute.Pod
|
||||
edges: |
|
||||
edges.add_service_account("spec")
|
||||
edges.add_all_volume_resources("spec.volumes")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.containers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.initContainers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.ephemeralContainers")
|
||||
edges.add_wait_for_services("spec.initContainers")
|
||||
edges.add_edge_to(
|
||||
"spec.nodeName",
|
||||
".",
|
||||
None,
|
||||
"Node",
|
||||
"v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
edges.add_networks("metadata.annotations")
|
||||
edges.add_priority_class("spec.priorityClassName")
|
||||
edges.add_edge_to(
|
||||
"spec.runtimeClassName",
|
||||
".",
|
||||
None,
|
||||
"RuntimeClass",
|
||||
"node.k8s.io/v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
PodDisruptionBudget/policy/v1:
|
||||
scope: Namespaced
|
||||
custom_icon: $KD/icons/pdb.png
|
||||
edges: |
|
||||
edges.add_all_workload_resources(
|
||||
"spec.selector.matchLabels",
|
||||
edge_kind="SELECTOR-UP"
|
||||
)
|
||||
PodDisruptionBudget/policy/v1beta1: PodDisruptionBudget/policy/v1
|
||||
PodSecurityPolicy/policy/v1:
|
||||
scope: Namespaced
|
||||
plural: podsecuritypolicies
|
||||
diagram_node_classname: diagrams.k8s.others.PSP
|
||||
# no edges
|
||||
PodSecurityPolicy/policy/v1beta1: PodSecurityPolicy/policy/v1
|
||||
PodSecurityPolicy/extensions/v1beta1: PodSecurityPolicy/policy/v1
|
||||
PodTemplate/v1:
|
||||
scope: Namespaced
|
||||
custom_icon: $KD/icons/podtemplate.png
|
||||
edges: |
|
||||
edges.add_service_account("template.spec")
|
||||
edges.add_all_volume_resources("template.spec.volumes")
|
||||
edges.add_containers_env_value_from_and_env_from("template.spec.containers")
|
||||
edges.add_containers_env_value_from_and_env_from("template.spec.initContainers")
|
||||
edges.add_containers_env_value_from_and_env_from("template.spec.ephemeralContainers")
|
||||
edges.add_wait_for_services("template.spec.initContainers")
|
||||
edges.add_edge_to(
|
||||
"template.spec.nodeName",
|
||||
".",
|
||||
None,
|
||||
"Node",
|
||||
"v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
edges.add_networks("template.metadata.annotations")
|
||||
edges.add_priority_class("template.spec.priorityClassName")
|
||||
edges.add_edge_to(
|
||||
"template.spec.runtimeClassName",
|
||||
".",
|
||||
None,
|
||||
"RuntimeClass",
|
||||
"node.k8s.io/v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
ReplicaSet/apps/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.compute.RS
|
||||
edges: |
|
||||
edges.add_owned_resources()
|
||||
edges.add_service_account("spec.template.spec")
|
||||
edges.add_all_volume_resources("spec.template.spec.volumes")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.containers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.initContainers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.ephemeralContainers")
|
||||
edges.add_wait_for_services("spec.template.spec.initContainers")
|
||||
edges.add_networks("spec.template.metadata.annotations")
|
||||
edges.add_priority_class("spec.template.spec.priorityClassName")
|
||||
edges.add_edge_to(
|
||||
"spec.template.spec.runtimeClassName",
|
||||
".",
|
||||
None,
|
||||
"RuntimeClass",
|
||||
"node.k8s.io/v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
ReplicationController/v1:
|
||||
scope: Namespaced
|
||||
custom_icon: $KD/icons/rc.png
|
||||
edges: |
|
||||
edges.add_owned_resources()
|
||||
edges.add_service_account("spec.template.spec")
|
||||
edges.add_all_volume_resources("spec.template.spec.volumes")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.containers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.initContainers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.ephemeralContainers")
|
||||
edges.add_wait_for_services("spec.template.spec.initContainers")
|
||||
edges.add_networks("spec.template.metadata.annotations")
|
||||
edges.add_priority_class("spec.template.spec.priorityClassName")
|
||||
edges.add_edge_to(
|
||||
"spec.template.spec.runtimeClassName",
|
||||
".",
|
||||
None,
|
||||
"RuntimeClass",
|
||||
"node.k8s.io/v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
ResourceQuota/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.clusterconfig.Quota
|
||||
# no edges
|
||||
Role/rbac.authorization.k8s.io/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.rbac.Role
|
||||
nodes: |
|
||||
create_node_for_role_rules_resource_names(resource, nodes)
|
||||
edges: |
|
||||
edges.add_rules_resource_names()
|
||||
Role/rbac.authorization.k8s.io/v1beta1: Role/rbac.authorization.k8s.io/v1
|
||||
RoleBinding/rbac.authorization.k8s.io/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.rbac.RB
|
||||
edges: |
|
||||
edges.add_role("roleRef")
|
||||
edges.add_subjects()
|
||||
RoleBinding/rbac.authorization.k8s.io/v1beta1: RoleBinding/rbac.authorization.k8s.io/v1
|
||||
RuntimeClass/node.k8s.io/v1:
|
||||
scope: Cluster
|
||||
custom_icon: $KD/icons/runtimeclass.png
|
||||
Secret/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.podconfig.Secret
|
||||
# no edges
|
||||
Service/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.network.SVC
|
||||
edges: |
|
||||
edges.add_edges_for_service()
|
||||
ServiceAccount/v1:
|
||||
scope: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.rbac.SA
|
||||
# no edges
|
||||
StatefulSet/apps/v1:
|
||||
scoped: Namespaced
|
||||
diagram_node_classname: diagrams.k8s.compute.STS
|
||||
nodes: |
|
||||
namespace = resource["metadata"].get("namespace")
|
||||
for vct in query_path(resource, "spec.volumeClaimTemplates", []):
|
||||
pvc = {
|
||||
"kind": "PersistentVolumeClaim",
|
||||
"apiVersion": "v1",
|
||||
**vct
|
||||
}
|
||||
pvc["metadata"]["name"] = f'{pvc["metadata"]["name"]}-{resource["metadata"]["name"]}'
|
||||
if namespace is not None:
|
||||
pvc["metadata"]["namespace"] = namespace
|
||||
pvc["metadata"]["labels"] = {
|
||||
**query_path(resource, "metadata.labels", {}),
|
||||
**query_path(pvc, "metadata.labels", {})
|
||||
}
|
||||
nodes.append(pvc)
|
||||
edges: |
|
||||
edges.add_owned_resources()
|
||||
edges.add_service_account("spec.template.spec")
|
||||
edges.add_all_volume_resources("spec.template.spec.volumes")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.containers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.initContainers")
|
||||
edges.add_containers_env_value_from_and_env_from("spec.template.spec.ephemeralContainers")
|
||||
edges.add_wait_for_services("spec.template.spec.initContainers")
|
||||
edges.add_networks("spec.template.metadata.annotations")
|
||||
edges.add_priority_class("spec.template.spec.priorityClassName")
|
||||
edges.add_edge_to(
|
||||
"spec.template.spec.runtimeClassName",
|
||||
".",
|
||||
None,
|
||||
"RuntimeClass",
|
||||
"node.k8s.io/v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
edges.add_volume_claim_templates("spec.volumeClaimTemplates")
|
||||
edges.add_service("spec.serviceName")
|
||||
StatefulSet/apps/v1beta1: StatefulSet/apps/v1
|
||||
StatefulSet/apps/v1beta2: StatefulSet/apps/v1
|
||||
StorageClass/storage.k8s.io/v1:
|
||||
scope: Cluster
|
||||
diagram_node_classname: diagrams.k8s.storage.SC
|
||||
edges: |
|
||||
edges.add_edge_to(
|
||||
"provisioner",
|
||||
".",
|
||||
None,
|
||||
"CSIDriver",
|
||||
"storage.k8s.io/v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
StorageClass/storage.k8s.io/v1beta1: StorageClass/storage.k8s.io/v1
|
||||
User/rbac.authorization.k8s.io/v1:
|
||||
scope: Cluster
|
||||
diagram_node_classname: diagrams.k8s.rbac.User
|
||||
# no edges
|
||||
ValidatingWebhookConfiguration/admissionregistration.k8s.io/v1:
|
||||
scope: Cluster
|
||||
custom_icon: $KD/icons/vwc.png
|
||||
edges: |
|
||||
edges.add_webhooks()
|
||||
ValidatingWebhookConfiguration/admissionregistration.k8s.io/v1beta1: ValidatingWebhookConfiguration/admissionregistration.k8s.io/v1
|
||||
VerticalPodAutoscaler/autoscaling.k8s.io/v1:
|
||||
scoped: Namespaced
|
||||
custom_icon: $KD/icons/vpa.png
|
||||
edges: |
|
||||
edges.add_resource("spec.targetRef")
|
||||
VolumeAttachment/storage.k8s.io/v1:
|
||||
scope: Cluster
|
||||
diagram_node_classname: diagrams.k8s.storage.Volume
|
||||
edges: |
|
||||
edges.add_edge_to(
|
||||
"spec.nodeName",
|
||||
".",
|
||||
None,
|
||||
"Node",
|
||||
"v1",
|
||||
"REFERENCE"
|
||||
)
|
||||
cluster-resources:
|
||||
# default namespace
|
||||
- default/default/ServiceAccount/v1
|
||||
- kube-root-ca.crt/default/ConfigMap/v1
|
||||
- kubernetes/default/Service/v1
|
||||
# kube-system namespace
|
||||
- extension-apiserver-authentication-reader/kube-system/Role/rbac.authorization.k8s.io/v1
|
||||
- horizontal-pod-autoscaler/kube-system/ServiceAccount/v1
|
||||
# cluster scope
|
||||
- admin/ClusterRole/rbac.authorization.k8s.io/v1
|
||||
- cluster-admin/ClusterRole/rbac.authorization.k8s.io/v1
|
||||
- edit/ClusterRole/rbac.authorization.k8s.io/v1
|
||||
- generic-garbage-collector/kube-system/ServiceAccount/v1
|
||||
- standard/StorageClass/storage.k8s.io/v1
|
||||
- system:anonymous/User/rbac.authorization.k8s.io/v1
|
||||
- system:auth-delegator/ClusterRole/rbac.authorization.k8s.io/v1
|
||||
- system:authenticated/Group/rbac.authorization.k8s.io/v1
|
||||
- system:coredns/ClusterRole/rbac.authorization.k8s.io/v1
|
||||
- system:discovery/ClusterRole/rbac.authorization.k8s.io/v1
|
||||
- system:node-proxier/ClusterRole/rbac.authorization.k8s.io/v1
|
||||
- system:nodes/Group/rbac.authorization.k8s.io/v1
|
||||
- system:unauthenticated/Group/rbac.authorization.k8s.io/v1
|
||||
- system:persistent-volume-provisioner/ClusterRole/rbac.authorization.k8s.io/v1
|
||||
- system:service-account-issuer-discovery/ClusterRole/rbac.authorization.k8s.io/v1
|
||||
- system:serviceaccounts/Group/rbac.authorization.k8s.io/v1
|
||||
- system:volume-scheduler/ClusterRole/rbac.authorization.k8s.io/v1
|
||||
- system-cluster-critical/PriorityClass/scheduling.k8s.io/v1
|
||||
- system-node-critical/PriorityClass/scheduling.k8s.io/v1
|
||||
- view/ClusterRole/rbac.authorization.k8s.io/v1
|
||||
110
webapp/backend/venv/bin/kubectl-diagrams
Executable file
@@ -0,0 +1,110 @@
|
||||
#!/bin/bash
|
||||
|
||||
# kubectl diagrams: A kubectl plugin to generate a diagram of Kubernetes resources
|
||||
# using kube-diagrams from the output of 'kubectl get <resources> -o yaml'
|
||||
|
||||
# Version
|
||||
VERSION="0.1.0"
|
||||
|
||||
# Check if kube-diagrams is installed
|
||||
if ! command -v kube-diagrams &>/dev/null; then
|
||||
echo "Error: kube-diagrams is not installed. Please install it first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if kubectl is installed
|
||||
if ! command -v kubectl &>/dev/null; then
|
||||
echo "Error: kubectl is not installed. Please install it first."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Display help message
|
||||
show_help() {
|
||||
echo "Usage: kubectl diagrams [OPTIONS] <resource1,resource2,...>"
|
||||
echo ""
|
||||
echo "A kubectl plugin to generate diagrams of Kubernetes resources using kube-diagrams."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -n, --namespace <namespace> Specify the namespace to query resources from"
|
||||
echo " -o, --output <file> Specify the output file for the diagram"
|
||||
echo " -f, --format <format> Specify the output format (e.g., png, svg)"
|
||||
echo " --embed-all-icons Embed all icons into svg or dot_json output diagrams"
|
||||
echo " -c, --config <file> Specify the custom kube-diagrams configuration file"
|
||||
echo " --without-namespace Exclude namespace from the diagram"
|
||||
echo " --version Display the version number"
|
||||
echo " --help Display this help message"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " kubectl diagrams pod,service -n my-namespace -o diagram.png"
|
||||
echo " kubectl diagrams deployment --without-namespace -f svg"
|
||||
echo " kubectl diagrams --version"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Initialize variables
|
||||
KUBE_DIAGRAMS_ARGS=("-") # Default to stdin indicator
|
||||
KUBECTL_ARGS=()
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--version)
|
||||
echo "kubectl diagrams version $VERSION"
|
||||
exit
|
||||
;;
|
||||
--help)
|
||||
show_help
|
||||
;;
|
||||
-n | --namespace)
|
||||
if [[ -n "$2" ]]; then
|
||||
KUBECTL_ARGS+=("-n" "$2")
|
||||
shift 2
|
||||
else
|
||||
echo "Error: --namespace requires a value"
|
||||
exit 64
|
||||
fi
|
||||
;;
|
||||
-o | --output | -f | --format | -c | --config | --without-namespace)
|
||||
KUBE_DIAGRAMS_ARGS+=("$1")
|
||||
if [[ "$1" == "-o" || "$1" == "--output" || "$1" == "-f" || "$1" == "--format" || "$1" == "-c" || "$1" == "--config" ]]; then
|
||||
if [[ -n "$2" ]]; then
|
||||
KUBE_DIAGRAMS_ARGS+=("$2")
|
||||
shift 2
|
||||
else
|
||||
echo "Error: $1 requires a value"
|
||||
exit 64
|
||||
fi
|
||||
else
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
--embed-all-icons)
|
||||
KUBE_DIAGRAMS_ARGS+=("$1")
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
KUBECTL_ARGS+=("$1")
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check if any resources were specified
|
||||
if [[ ${#KUBECTL_ARGS[@]} -eq 0 ]]; then
|
||||
echo "Error: At least one resource kind must be specified (e.g., pod, service, deployment)"
|
||||
exit 64
|
||||
fi
|
||||
|
||||
# Add default output format for kubectl
|
||||
KUBECTL_ARGS+=("-o" "yaml")
|
||||
|
||||
# Execute kubectl and pipe to kube-diagrams with arguments
|
||||
kubectl get "${KUBECTL_ARGS[@]}" | kube-diagrams "${KUBE_DIAGRAMS_ARGS[@]}"
|
||||
EXIT_CODE=$?
|
||||
|
||||
if [[ $EXIT_CODE -eq 0 ]]; then
|
||||
echo "Diagram generated successfully"
|
||||
else
|
||||
echo "Error: Failed to generate diagram"
|
||||
exit 1
|
||||
fi
|
||||
8
webapp/backend/venv/bin/nodeenv
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from nodeenv import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
webapp/backend/venv/bin/normalizer
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from charset_normalizer.cli import cli_detect
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(cli_detect())
|
||||
8
webapp/backend/venv/bin/pip
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pip._internal.cli.main import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
webapp/backend/venv/bin/pip-compile
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from piptools.scripts.compile import cli
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(cli())
|
||||
8
webapp/backend/venv/bin/pip-sync
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from piptools.scripts.sync import cli
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(cli())
|
||||
8
webapp/backend/venv/bin/pip3
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pip._internal.cli.main import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
webapp/backend/venv/bin/pip3.12
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pip._internal.cli.main import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
webapp/backend/venv/bin/pre-commit
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from pre_commit.main import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
8
webapp/backend/venv/bin/pyproject-build
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from build.__main__ import entrypoint
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(entrypoint())
|
||||
1
webapp/backend/venv/bin/python
Symbolic link
@@ -0,0 +1 @@
|
||||
python3
|
||||
1
webapp/backend/venv/bin/python3
Symbolic link
@@ -0,0 +1 @@
|
||||
/usr/bin/python3
|
||||
1
webapp/backend/venv/bin/python3.12
Symbolic link
@@ -0,0 +1 @@
|
||||
python3
|
||||
8
webapp/backend/venv/bin/virtualenv
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from virtualenv.__main__ import run_with_catch
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(run_with_catch())
|
||||
8
webapp/backend/venv/bin/wheel
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/home/spirals/Documents/Workspace/Inria/kubediagramswebui/backend/venv/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import sys
|
||||
from wheel._commands import main
|
||||
if __name__ == '__main__':
|
||||
sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1 @@
|
||||
pip
|
||||
@@ -0,0 +1,28 @@
|
||||
Copyright 2010 Pallets
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,92 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: MarkupSafe
|
||||
Version: 3.0.2
|
||||
Summary: Safely add untrusted strings to HTML/XML markup.
|
||||
Maintainer-email: Pallets <contact@palletsprojects.com>
|
||||
License: Copyright 2010 Pallets
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Project-URL: Donate, https://palletsprojects.com/donate
|
||||
Project-URL: Documentation, https://markupsafe.palletsprojects.com/
|
||||
Project-URL: Changes, https://markupsafe.palletsprojects.com/changes/
|
||||
Project-URL: Source, https://github.com/pallets/markupsafe/
|
||||
Project-URL: Chat, https://discord.gg/pallets
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Environment :: Web Environment
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
|
||||
Classifier: Topic :: Text Processing :: Markup :: HTML
|
||||
Classifier: Typing :: Typed
|
||||
Requires-Python: >=3.9
|
||||
Description-Content-Type: text/markdown
|
||||
License-File: LICENSE.txt
|
||||
|
||||
# MarkupSafe
|
||||
|
||||
MarkupSafe implements a text object that escapes characters so it is
|
||||
safe to use in HTML and XML. Characters that have special meanings are
|
||||
replaced so that they display as the actual characters. This mitigates
|
||||
injection attacks, meaning untrusted user input can safely be displayed
|
||||
on a page.
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
```pycon
|
||||
>>> from markupsafe import Markup, escape
|
||||
|
||||
>>> # escape replaces special characters and wraps in Markup
|
||||
>>> escape("<script>alert(document.cookie);</script>")
|
||||
Markup('<script>alert(document.cookie);</script>')
|
||||
|
||||
>>> # wrap in Markup to mark text "safe" and prevent escaping
|
||||
>>> Markup("<strong>Hello</strong>")
|
||||
Markup('<strong>hello</strong>')
|
||||
|
||||
>>> escape(Markup("<strong>Hello</strong>"))
|
||||
Markup('<strong>hello</strong>')
|
||||
|
||||
>>> # Markup is a str subclass
|
||||
>>> # methods and operators escape their arguments
|
||||
>>> template = Markup("Hello <em>{name}</em>")
|
||||
>>> template.format(name='"World"')
|
||||
Markup('Hello <em>"World"</em>')
|
||||
```
|
||||
|
||||
## Donate
|
||||
|
||||
The Pallets organization develops and supports MarkupSafe and other
|
||||
popular packages. In order to grow the community of contributors and
|
||||
users, and allow the maintainers to devote more time to the projects,
|
||||
[please donate today][].
|
||||
|
||||
[please donate today]: https://palletsprojects.com/donate
|
||||
@@ -0,0 +1,15 @@
|
||||
MarkupSafe-3.0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
MarkupSafe-3.0.2.dist-info/LICENSE.txt,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475
|
||||
MarkupSafe-3.0.2.dist-info/METADATA,sha256=aAwbZhSmXdfFuMM-rEHpeiHRkBOGESyVLJIuwzHP-nw,3975
|
||||
MarkupSafe-3.0.2.dist-info/RECORD,,
|
||||
MarkupSafe-3.0.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
MarkupSafe-3.0.2.dist-info/WHEEL,sha256=OVgtqZzfzIXXtylXP90gxCZ6CKBCwKYyHM8PpMEjN1M,151
|
||||
MarkupSafe-3.0.2.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11
|
||||
markupsafe/__init__.py,sha256=sr-U6_27DfaSrj5jnHYxWN-pvhM27sjlDplMDPZKm7k,13214
|
||||
markupsafe/__pycache__/__init__.cpython-312.pyc,,
|
||||
markupsafe/__pycache__/_native.cpython-312.pyc,,
|
||||
markupsafe/_native.py,sha256=hSLs8Jmz5aqayuengJJ3kdT5PwNpBWpKrmQSdipndC8,210
|
||||
markupsafe/_speedups.c,sha256=O7XulmTo-epI6n2FtMVOrJXl8EAaIwD2iNYmBI5SEoQ,4149
|
||||
markupsafe/_speedups.cpython-312-x86_64-linux-gnu.so,sha256=t1DBZlpsjFA30BOOvXfXfT1wvO_4cS16VbHz1-49q5U,43432
|
||||
markupsafe/_speedups.pyi,sha256=ENd1bYe7gbBUf2ywyYWOGUpnXOHNJ-cgTNqetlW8h5k,41
|
||||
markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
@@ -0,0 +1,6 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: setuptools (75.2.0)
|
||||
Root-Is-Purelib: false
|
||||
Tag: cp312-cp312-manylinux_2_17_x86_64
|
||||
Tag: cp312-cp312-manylinux2014_x86_64
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
markupsafe
|
||||
@@ -0,0 +1 @@
|
||||
pip
|
||||