mirror of
https://github.com/PegaProx/project-pegaprox.git
synced 2026-08-12 15:27:47 +08:00
Features: - Network View in Corporate Layout sidebar (bridges, SDN, per-node VM mapping) - Custom bind address for reverse proxy on different host (#212) - OIDC JWT verification toggle for broken JWKS environments - Corporate Layout light mode improvements - Language picker dropdown for Corporate Layout (#236) - Community plugin: proxmox-ha (#226) - Spanish translations update (#234) Fixes: - Cross-cluster replication storage mapping (#192) - Site recovery stuck plans + race conditions (#238) - Container/local disk migration with multiple storages - Guest agent log spam when QEMU agent disabled (#237) - BG image upload behind reverse proxy (#210) - Topology diagram layout stability - PBS cluster filtering (#142) - Datastore usage mismatch sidebar vs tab (#201) - Node shell letter-spacing in Corporate Layout - Chevron icon rotation in Corporate node cards Security: - SQL injection whitelist for cluster field updates - File upload path traversal + null byte hardening - Cluster credentials endpoint access control - Error message leak prevention (14 endpoints) - Permission template fixes (5 undefined permissions)
60 lines
2.1 KiB
Python
60 lines
2.1 KiB
Python
"""
|
|
Hello World Plugin - Example plugin for PegaProx
|
|
Demonstrates how to build a plugin with routes, auth, and PegaProx API access.
|
|
|
|
All plugin routes are automatically protected by authentication (plugins.view permission).
|
|
Plugins can access PegaProx internals: cluster_managers, get_db(), request, etc.
|
|
"""
|
|
import logging
|
|
from flask import request
|
|
from pegaprox.api.plugins import register_plugin_route
|
|
from pegaprox.globals import cluster_managers
|
|
from pegaprox.core.db import get_db
|
|
|
|
PLUGIN_NAME = "Hello World"
|
|
|
|
|
|
def _get_status():
|
|
"""Example route: returns plugin status + connected cluster count"""
|
|
# access cluster managers (same API as core PegaProx)
|
|
connected = sum(1 for m in cluster_managers.values() if m.is_connected)
|
|
total = len(cluster_managers)
|
|
|
|
# access request context (user info from auth)
|
|
user = getattr(request, 'session', {}).get('user', 'unknown')
|
|
|
|
return {
|
|
'plugin': 'hello_world',
|
|
'status': 'running',
|
|
'message': 'Hello from the plugin system!',
|
|
'authenticated_user': user,
|
|
'clusters': {'connected': connected, 'total': total}
|
|
}
|
|
|
|
|
|
def _get_info():
|
|
"""Example route: returns plugin metadata"""
|
|
return {
|
|
'name': PLUGIN_NAME,
|
|
'version': '1.0.0',
|
|
'author': 'PegaProx Team',
|
|
'description': 'Example plugin demonstrating the PegaProx plugin API',
|
|
'available_routes': ['status', 'info'],
|
|
'api_docs': {
|
|
'status': 'GET /api/plugins/hello_world/api/status — Plugin status + cluster info',
|
|
'info': 'GET /api/plugins/hello_world/api/info — Plugin metadata'
|
|
}
|
|
}
|
|
|
|
|
|
def register(app):
|
|
"""Called by PegaProx when the plugin is enabled.
|
|
Use register_plugin_route(plugin_id, path, handler) to add API routes.
|
|
All routes are auto-prefixed: /api/plugins/{plugin_id}/api/{path}
|
|
Authentication is handled automatically (plugins.view permission required).
|
|
"""
|
|
register_plugin_route('hello_world', 'status', _get_status)
|
|
register_plugin_route('hello_world', 'info', _get_info)
|
|
|
|
logging.info("[PLUGINS] Hello World plugin registered")
|