feat: execution failure reports, auto-printer for WMT, UTC timezone fix for all timestamps
This commit is contained in:
@@ -3,7 +3,7 @@ Web routes for Ansible management interface
|
||||
"""
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify
|
||||
from app.services.ansible_service import AnsibleService
|
||||
from app.models import Device, AnsibleExecution, PlaybookExecution
|
||||
from app.models import Device, AnsibleExecution, PlaybookExecution, ExecutionFailureReport
|
||||
from config.database_config import get_db
|
||||
import logging
|
||||
|
||||
@@ -89,13 +89,18 @@ def playbooks():
|
||||
'builtin': True
|
||||
},
|
||||
{
|
||||
'name': 'restart_service',
|
||||
'name': 'restart_service',
|
||||
'description': 'Restart monitoring services on devices',
|
||||
'builtin': True
|
||||
}
|
||||
},
|
||||
{
|
||||
'name': 'distribute_ssh_keys',
|
||||
'description': 'Push server public key to devices using password auth',
|
||||
'builtin': True
|
||||
},
|
||||
]
|
||||
|
||||
return render_template('ansible/playbooks.html',
|
||||
return render_template('ansible/playbooks.html',
|
||||
playbooks=playbooks,
|
||||
builtin_playbooks=builtin_playbooks)
|
||||
except Exception as e:
|
||||
@@ -123,17 +128,20 @@ def execute():
|
||||
})
|
||||
seen.add(h['hostname'])
|
||||
|
||||
settings = ansible_service.load_settings()
|
||||
return render_template('ansible/execute.html',
|
||||
inventory=inventory_data,
|
||||
all_inv_hosts=all_inv_hosts,
|
||||
preselect_playbook=preselect)
|
||||
preselect_playbook=preselect,
|
||||
use_password_auth=settings.get('use_password_auth', False))
|
||||
except Exception as e:
|
||||
logging.error(f"Error loading execute form: {e}")
|
||||
flash(f'Error loading form: {e}', 'error')
|
||||
return render_template('ansible/execute.html',
|
||||
inventory={'groups': {}},
|
||||
all_inv_hosts=[],
|
||||
preselect_playbook='')
|
||||
preselect_playbook='',
|
||||
use_password_auth=False)
|
||||
|
||||
elif request.method == 'POST':
|
||||
# Execute playbook
|
||||
@@ -182,17 +190,24 @@ def execute():
|
||||
ansible_service.create_restart_service_playbook()
|
||||
elif playbook_name == 'system_health':
|
||||
ansible_service.create_system_health_playbook()
|
||||
|
||||
elif playbook_name == 'distribute_ssh_keys':
|
||||
ansible_service.create_distribute_ssh_keys_playbook()
|
||||
|
||||
# Add controller IP for callbacks
|
||||
extra_vars['ansible_controller_ip'] = request.host
|
||||
|
||||
# Force password auth for key distribution, or honour the form toggle
|
||||
force_password = (playbook_name == 'distribute_ssh_keys') or \
|
||||
bool(request.form.get('force_password_auth'))
|
||||
|
||||
# Use async execution (returns immediately with execution_id)
|
||||
result = ansible_service.execute_playbook_async(
|
||||
playbook_name=playbook_name,
|
||||
limit_hosts=selected_hosts,
|
||||
extra_vars=extra_vars,
|
||||
priority=priority,
|
||||
max_retries=max_retries
|
||||
max_retries=max_retries,
|
||||
force_password_auth=force_password,
|
||||
)
|
||||
|
||||
if result['success']:
|
||||
@@ -256,6 +271,11 @@ def execution_details(execution_id):
|
||||
flash(f'Error loading execution details: {e}', 'error')
|
||||
return redirect(url_for('ansible_web.executions'))
|
||||
|
||||
@ansible_web_bp.route('/executions/<execution_id>/live-popup')
|
||||
def execution_live_popup(execution_id):
|
||||
"""Standalone popup window for live execution output"""
|
||||
return render_template('ansible/live_popup.html', execution_id=execution_id)
|
||||
|
||||
@ansible_web_bp.route('/ssh/setup')
|
||||
def ssh_setup():
|
||||
"""SSH key setup interface"""
|
||||
@@ -288,10 +308,14 @@ def save_ssh_settings():
|
||||
try:
|
||||
fallback_password = request.form.get('ssh_fallback_password', '').strip()
|
||||
if not fallback_password:
|
||||
flash('Fallback password cannot be empty.', 'error')
|
||||
flash('Password cannot be empty.', 'error')
|
||||
return redirect(url_for('ansible_web.ssh_setup'))
|
||||
|
||||
ansible_service.save_settings({'ssh_fallback_password': fallback_password})
|
||||
use_password_auth = request.form.get('use_password_auth') == 'on'
|
||||
ansible_service.save_settings({
|
||||
'ssh_fallback_password': fallback_password,
|
||||
'use_password_auth': use_password_auth,
|
||||
})
|
||||
flash('SSH settings saved successfully.', 'success')
|
||||
except Exception as e:
|
||||
logging.error(f"Error saving SSH settings: {e}")
|
||||
@@ -596,4 +620,20 @@ def delete_playbook():
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error deleting playbook: {e}")
|
||||
return jsonify({'error': str(e)}), 500
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
@ansible_web_bp.route('/failure-reports')
|
||||
def failure_reports():
|
||||
"""View all saved execution failure reports."""
|
||||
try:
|
||||
with get_db().get_session() as session:
|
||||
reports = session.query(ExecutionFailureReport)\
|
||||
.order_by(ExecutionFailureReport.saved_at.desc())\
|
||||
.all()
|
||||
reports_data = [r.to_dict() for r in reports]
|
||||
return render_template('ansible/failure_reports.html', reports=reports_data)
|
||||
except Exception as e:
|
||||
logging.error(f"Error loading failure reports: {e}")
|
||||
flash(f'Error loading failure reports: {e}', 'error')
|
||||
return render_template('ansible/failure_reports.html', reports=[])
|
||||
Reference in New Issue
Block a user