updated player deployment for digiserver
This commit is contained in:
@@ -3,6 +3,7 @@ from flask import Blueprint, request, jsonify, current_app
|
||||
from functools import wraps
|
||||
from datetime import datetime, timedelta
|
||||
import secrets
|
||||
import hashlib
|
||||
import bcrypt
|
||||
from typing import Optional, Dict, List
|
||||
|
||||
@@ -860,6 +861,133 @@ def receive_edited_media():
|
||||
return jsonify({'error': 'Internal server error'}), 500
|
||||
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
# SSH/Deployment Endpoints - For player provisioning and code deployment
|
||||
# ──────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
@api_bp.route('/deploy/test-ssh', methods=['POST'])
|
||||
@rate_limit(max_requests=30, window=60)
|
||||
def test_ssh_connection():
|
||||
"""Test SSH connection to a remote host.
|
||||
|
||||
Request JSON:
|
||||
hostname: Target hostname or IP (required)
|
||||
username: SSH username (required)
|
||||
password: SSH password (required)
|
||||
port: SSH port (default: 22)
|
||||
|
||||
Returns:
|
||||
JSON with connection test result
|
||||
"""
|
||||
try:
|
||||
from app.utils.ssh_deploy import test_ssh_connection as test_ssh
|
||||
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
return jsonify({'error': 'No data provided'}), 400
|
||||
|
||||
hostname = data.get('hostname', '').strip()
|
||||
username = data.get('username', '').strip()
|
||||
password = data.get('password', '').strip()
|
||||
port = data.get('port', 22)
|
||||
|
||||
# Validation
|
||||
if not hostname or not username or not password:
|
||||
return jsonify({'error': 'hostname, username, and password are required'}), 400
|
||||
|
||||
# Test connection
|
||||
result = test_ssh(hostname, username, password, port)
|
||||
|
||||
log_action('info', f'SSH test for {username}@{hostname}: {result["message"]}')
|
||||
|
||||
return jsonify(result), 200 if result['success'] else 400
|
||||
|
||||
except Exception as e:
|
||||
log_action('error', f'Error testing SSH connection: {str(e)}')
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e),
|
||||
'message': f'SSH test error: {str(e)}'
|
||||
}), 500
|
||||
|
||||
|
||||
@api_bp.route('/deploy/player', methods=['POST'])
|
||||
@rate_limit(max_requests=20, window=60)
|
||||
def deploy_player():
|
||||
"""Deploy player code to a remote host via SSH.
|
||||
|
||||
Request JSON:
|
||||
hostname: Target hostname or IP (required)
|
||||
username: SSH username (required)
|
||||
password: SSH password (required)
|
||||
player_name: Name for the player instance (required)
|
||||
port: SSH port (default: 22)
|
||||
deploy_path: Deployment path on remote host (default: /home/[user]/kiwy-signage)
|
||||
repo_url: Git repository URL (default: official Kiwy-Signage repo)
|
||||
|
||||
Returns:
|
||||
JSON with deployment status and step details
|
||||
"""
|
||||
try:
|
||||
from app.utils.ssh_deploy import deploy_player_to_host
|
||||
|
||||
data = request.get_json()
|
||||
if not data:
|
||||
return jsonify({'error': 'No data provided'}), 400
|
||||
|
||||
hostname = data.get('hostname', '').strip()
|
||||
username = data.get('username', '').strip()
|
||||
password = data.get('password', '').strip()
|
||||
player_name = data.get('player_name', '').strip()
|
||||
port = data.get('port', 22)
|
||||
deploy_path = data.get('deploy_path', None) # Will default to /home/[user]/kiwy-signage
|
||||
repo_url = data.get('repo_url', 'https://gitea.moto-adv.com/ske087/Kiwy-Signage.git').strip()
|
||||
|
||||
# Validation
|
||||
if not hostname or not username or not password:
|
||||
return jsonify({'error': 'hostname, username, and password are required'}), 400
|
||||
|
||||
if not player_name:
|
||||
return jsonify({'error': 'player_name is required'}), 400
|
||||
|
||||
# Get server URL for player configuration
|
||||
# Use X-Forwarded-Proto and X-Forwarded-Host for proxy, fall back to request host
|
||||
scheme = request.headers.get('X-Forwarded-Proto', request.scheme)
|
||||
host = request.headers.get('X-Forwarded-Host', request.host)
|
||||
server_url = f"{scheme}://{host}/digiserver"
|
||||
|
||||
# Get or generate API key for the player
|
||||
# For now, use a hash of player_name and hostname as a simple key
|
||||
import hashlib
|
||||
api_key = hashlib.sha256(f'{player_name}:{hostname}'.encode()).hexdigest()[:32]
|
||||
|
||||
# Execute deployment
|
||||
result = deploy_player_to_host(
|
||||
hostname=hostname,
|
||||
username=username,
|
||||
password=password,
|
||||
player_name=player_name,
|
||||
repo_url=repo_url,
|
||||
deploy_path=deploy_path, # Will use /home/[user]/kiwy-signage if None
|
||||
port=port,
|
||||
server_url=server_url,
|
||||
server_api_key=api_key
|
||||
)
|
||||
|
||||
log_action('info', f'Player deployment for {player_name} on {hostname}: success={result["success"]}')
|
||||
|
||||
return jsonify(result), 200 if result['success'] else 400
|
||||
|
||||
except Exception as e:
|
||||
log_action('error', f'Error deploying player: {str(e)}')
|
||||
return jsonify({
|
||||
'success': False,
|
||||
'error': str(e),
|
||||
'message': f'Deployment error: {str(e)}',
|
||||
'steps': []
|
||||
}), 500
|
||||
|
||||
|
||||
@api_bp.errorhandler(404)
|
||||
def api_not_found(error):
|
||||
"""Handle 404 errors in API."""
|
||||
|
||||
Reference in New Issue
Block a user