Files
openshift-resource-governance/scripts/webhook-deploy.py

181 lines
5.9 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Webhook for automatic deployment after GitHub Actions
This script can be run as a service to detect changes on Docker Hub
"""
import os
import json
import subprocess
import logging
from flask import Flask, request, jsonify
from datetime import datetime
# Logging configuration
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = Flask(__name__)
# Configuration
IMAGE_NAME = os.getenv('IMAGE_NAME', 'resource-governance')
REGISTRY = os.getenv('REGISTRY', 'andersonid')
NAMESPACE = os.getenv('NAMESPACE', 'resource-governance')
SCRIPT_PATH = os.getenv('AUTO_DEPLOY_SCRIPT', './scripts/auto-deploy.sh')
@app.route('/webhook/dockerhub', methods=['POST'])
def dockerhub_webhook():
"""Webhook to receive Docker Hub notifications"""
try:
data = request.get_json()
# Check if it's a push notification
if data.get('push_data', {}).get('tag') == 'latest':
logger.info(f"Received push notification for {REGISTRY}/{IMAGE_NAME}:latest")
# Execute automatic deployment
result = run_auto_deploy('latest')
return jsonify({
'status': 'success',
'message': 'Automatic deployment started',
'result': result
}), 200
else:
logger.info(f"Push ignored - tag: {data.get('push_data', {}).get('tag')}")
return jsonify({'status': 'ignored', 'message': 'Tag is not latest'}), 200
except Exception as e:
logger.error(f"Webhook error: {e}")
return jsonify({'status': 'error', 'message': str(e)}), 500
@app.route('/webhook/github', methods=['POST'])
def github_webhook():
"""Webhook to receive GitHub notifications"""
try:
# Check if it's a push to main
if request.headers.get('X-GitHub-Event') == 'push':
data = request.get_json()
if data.get('ref') == 'refs/heads/main':
logger.info("Received push notification for main branch")
# Execute automatic deployment
result = run_auto_deploy('latest')
return jsonify({
'status': 'success',
'message': 'Automatic deployment started',
'result': result
}), 200
else:
logger.info(f"Push ignored - branch: {data.get('ref')}")
return jsonify({'status': 'ignored', 'message': 'Branch is not main'}), 200
else:
logger.info(f"Event ignored: {request.headers.get('X-GitHub-Event')}")
return jsonify({'status': 'ignored', 'message': 'Event is not push'}), 200
except Exception as e:
logger.error(f"Webhook error: {e}")
return jsonify({'status': 'error', 'message': str(e)}), 500
@app.route('/deploy/<tag>', methods=['POST'])
def manual_deploy(tag):
"""Manual deployment with specific tag"""
try:
logger.info(f"Manual deployment requested for tag: {tag}")
result = run_auto_deploy(tag)
return jsonify({
'status': 'success',
'message': f'Manual deployment started for tag: {tag}',
'result': result
}), 200
except Exception as e:
logger.error(f"Manual deployment error: {e}")
return jsonify({'status': 'error', 'message': str(e)}), 500
def run_auto_deploy(tag):
"""Execute automatic deployment script"""
try:
logger.info(f"Executing automatic deployment for tag: {tag}")
# Execute deployment script
result = subprocess.run(
[SCRIPT_PATH, tag],
capture_output=True,
text=True,
timeout=600 # 10 minutes timeout
)
if result.returncode == 0:
logger.info("Automatic deployment completed successfully")
return {
'success': True,
'stdout': result.stdout,
'stderr': result.stderr
}
else:
logger.error(f"Automatic deployment failed: {result.stderr}")
return {
'success': False,
'stdout': result.stdout,
'stderr': result.stderr
}
except subprocess.TimeoutExpired:
logger.error("Automatic deployment timeout")
return {
'success': False,
'error': 'Timeout'
}
except Exception as e:
logger.error(f"Error executing automatic deployment: {e}")
return {
'success': False,
'error': str(e)
}
@app.route('/health', methods=['GET'])
def health():
"""Health check"""
return jsonify({
'status': 'healthy',
'timestamp': datetime.now().isoformat(),
'image': f'{REGISTRY}/{IMAGE_NAME}',
'namespace': NAMESPACE
}), 200
@app.route('/status', methods=['GET'])
def status():
"""Service status"""
try:
# Check if logged into OpenShift
result = subprocess.run(['oc', 'whoami'], capture_output=True, text=True)
return jsonify({
'status': 'running',
'timestamp': datetime.now().isoformat(),
'openshift_user': result.stdout.strip() if result.returncode == 0 else 'Not logged in',
'image': f'{REGISTRY}/{IMAGE_NAME}',
'namespace': NAMESPACE,
'script_path': SCRIPT_PATH
}), 200
except Exception as e:
return jsonify({
'status': 'error',
'message': str(e)
}), 500
if __name__ == '__main__':
port = int(os.getenv('PORT', 8080))
debug = os.getenv('DEBUG', 'false').lower() == 'true'
logger.info(f"Starting webhook server on port {port}")
logger.info(f"Configuration: IMAGE_NAME={IMAGE_NAME}, REGISTRY={REGISTRY}, NAMESPACE={NAMESPACE}")
app.run(host='0.0.0.0', port=port, debug=debug)