duzo fixow i optymalizacji
This commit is contained in:
142
app.py
142
app.py
@@ -1,4 +1,4 @@
|
||||
from flask import Flask, render_template, request, redirect, url_for, flash, session, Response
|
||||
from flask import Flask, render_template, request, redirect, url_for, flash, session, Response, jsonify
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from werkzeug.security import generate_password_hash, check_password_hash
|
||||
import os, paramiko, threading, time, io, tempfile, csv
|
||||
@@ -159,7 +159,11 @@ def ensure_local_defaults(content, user_id):
|
||||
return final_content
|
||||
|
||||
def format_host(host):
|
||||
if not host:
|
||||
return "Unknown Host"
|
||||
|
||||
resolved_name = None
|
||||
|
||||
# Priorytet dla Linux Daemon
|
||||
if host.use_daemon and host.type == 'linux' and host.daemon_url:
|
||||
resolved_name = host.resolved_daemon or host.hostname
|
||||
@@ -175,12 +179,8 @@ def format_host(host):
|
||||
except (socket.herror, socket.gaierror):
|
||||
pass # Jeśli nie można rozwiązać, pozostaw IP
|
||||
|
||||
return f"{resolved_name} ({host.raw_ip})"
|
||||
return f"{resolved_name} ({host.raw_ip})" if resolved_name else f"Unknown ({host.raw_ip})"
|
||||
|
||||
# Automatyczne dodanie wartości systemowych
|
||||
variables["hostname"] = socket.gethostname() # Nazwa hosta
|
||||
variables["resolved_hostname"] = socket.getfqdn() # Pełna nazwa hosta
|
||||
return variables
|
||||
|
||||
|
||||
def wrap_content_with_comments(content):
|
||||
@@ -679,48 +679,54 @@ def clear_server():
|
||||
def clear_single_server(host_id):
|
||||
if 'user_id' not in session:
|
||||
return redirect(url_for('login'))
|
||||
|
||||
host = db.session.get(Host, host_id)
|
||||
if not host or host.user_id != session['user_id']:
|
||||
flash('Host not found or unauthorized', 'danger')
|
||||
return redirect(url_for('clear_servers'))
|
||||
return redirect(url_for('clear_server'))
|
||||
|
||||
default_content = ensure_local_defaults("", session['user_id'])
|
||||
|
||||
default_content = ensure_local_defaults("")
|
||||
try:
|
||||
host_name = format_host(host)
|
||||
|
||||
if host.use_daemon and host.type == 'linux':
|
||||
import requests
|
||||
url = host.daemon_url.rstrip('/') + '/hosts'
|
||||
headers = {"Authorization": host.daemon_token}
|
||||
# Zakładamy, że demon potrafi zastąpić /etc/hosts treścią "default_content"
|
||||
resp = requests.post(url, json={"hosts": default_content},
|
||||
headers=headers, verify=False, timeout=10)
|
||||
resp = requests.post(url, json={"hosts": default_content}, headers=headers, verify=False, timeout=10)
|
||||
if resp.status_code != 200:
|
||||
raise Exception(f"Daemon update error: {resp.status_code} - {resp.text}")
|
||||
|
||||
elif host.type == 'mikrotik':
|
||||
clear_mikrotik(host)
|
||||
else:
|
||||
# standard linux
|
||||
clear_linux(host, default_content)
|
||||
|
||||
flash(f'Cleared host: {host.hostname}', 'success')
|
||||
flash(f'Cleared host: {host_name}', 'success')
|
||||
except Exception as e:
|
||||
flash(f'Error clearing host {host.hostname}: {str(e)}', 'danger')
|
||||
flash(f'Error clearing host {host_name}: {str(e)}', 'danger')
|
||||
|
||||
return redirect(url_for('clear_server'))
|
||||
|
||||
return redirect(url_for('clear_all_server'))
|
||||
|
||||
@app.route('/clear-all-server', methods=['GET', 'POST'])
|
||||
def clear_all_server():
|
||||
if 'user_id' not in session:
|
||||
return redirect(url_for('login'))
|
||||
|
||||
hosts = Host.query.filter_by(user_id=session['user_id']).all()
|
||||
|
||||
if request.method == 'POST':
|
||||
linux_clear = request.form.get('linux')
|
||||
mikrotik_clear = request.form.get('mikrotik')
|
||||
default_content = ensure_local_defaults("")
|
||||
default_content = ensure_local_defaults("", session['user_id'])
|
||||
|
||||
for h in hosts:
|
||||
try:
|
||||
host_name = format_host(h) if h else "Unknown Host"
|
||||
print(f"DEBUG: Czyszczenie hosta {host_name}")
|
||||
|
||||
if h.type == 'linux' and linux_clear:
|
||||
if h.use_daemon:
|
||||
import requests
|
||||
@@ -732,18 +738,18 @@ def clear_all_server():
|
||||
raise Exception(f"Daemon update error: {resp.status_code} - {resp.text}")
|
||||
else:
|
||||
clear_linux(h, default_content)
|
||||
flash(f'Cleared Linux host: {h.hostname}', 'success')
|
||||
flash(f'Cleared Linux host: {host_name}', 'success')
|
||||
|
||||
elif h.type == 'mikrotik' and mikrotik_clear:
|
||||
clear_mikrotik(h)
|
||||
flash(f'Cleared Mikrotik host: {h.hostname}', 'success')
|
||||
flash(f'Cleared Mikrotik host: {host_name}', 'success')
|
||||
|
||||
except Exception as e:
|
||||
flash(f'Error clearing host {h.hostname}: {str(e)}', 'danger')
|
||||
flash(f'Error clearing host {host_name}: {str(e)}', 'danger')
|
||||
|
||||
return redirect(url_for('clear_all_server'))
|
||||
|
||||
return render_template('clear_servers.html', hosts=hosts)
|
||||
return render_template('clear_servers.html', hosts=hosts, format_host=format_host)
|
||||
|
||||
# -------------------
|
||||
# ZARZĄDZANIE PLIKAMI HOSTS (WIELOKROTNE PLIKI)
|
||||
@@ -1246,35 +1252,24 @@ def deploy_user(user_id):
|
||||
if not h.auto_deploy_enabled:
|
||||
continue
|
||||
|
||||
# Pobranie pliku hosts wybranego dla serwera
|
||||
if h.preferred_hostfile_id:
|
||||
chosen_file = HostFile.query.filter_by(id=h.preferred_hostfile_id, user_id=user_id).first()
|
||||
if not chosen_file:
|
||||
chosen_file = default_file
|
||||
else:
|
||||
chosen_file = default_file
|
||||
|
||||
# Wstępna zawartość - pobrany plik hosts
|
||||
chosen_file = HostFile.query.filter_by(id=h.preferred_hostfile_id, user_id=user_id).first() if h.preferred_hostfile_id else default_file
|
||||
final_content = chosen_file.content.strip()
|
||||
|
||||
# Jeśli disable_local_default jest włączone → usuwamy local-defaults, ale reszta pozostaje
|
||||
if h.disable_local_default:
|
||||
final_content = remove_local_defaults(final_content, user_id)
|
||||
else:
|
||||
# Dodaj regex, jeśli nie jest wyłączony
|
||||
if not h.disable_regex_deploy and regex_lines.strip():
|
||||
final_content = regex_lines + "\n" + final_content
|
||||
|
||||
final_content = ensure_local_defaults(final_content, user_id)
|
||||
|
||||
try:
|
||||
# 🖥 Wgrywanie na Mikrotik
|
||||
host_name = format_host(h) if h else "Unknown Host"
|
||||
|
||||
if h.type == 'mikrotik':
|
||||
wrapped_content = wrap_mikrotik_content(final_content)
|
||||
deploy_mikrotik(h, wrapped_content)
|
||||
log_details = f'[MIKROTIK] Updated {format_host(h)} for user {user_id}'
|
||||
log_details = f'[MIKROTIK] Updated {host_name} for user {user_id}'
|
||||
|
||||
# 🖥 Wgrywanie na Linux Daemon
|
||||
elif h.use_daemon and h.type == 'linux':
|
||||
import requests
|
||||
wrapped_content = wrap_content_with_comments(final_content)
|
||||
@@ -1283,9 +1278,8 @@ def deploy_user(user_id):
|
||||
resp = requests.post(url, json={"hosts": wrapped_content}, headers=headers, timeout=10, verify=False)
|
||||
if resp.status_code != 200:
|
||||
raise Exception(f"Daemon POST error: {resp.status_code} - {resp.text}")
|
||||
log_details = f'[LINUX/DAEMON] Updated {format_host(h)} for user {user_id}'
|
||||
log_details = f'[LINUX/DAEMON] Updated {host_name} for user {user_id}'
|
||||
|
||||
# 🖥 Wgrywanie na standardowy Linux przez SSH
|
||||
else:
|
||||
ssh = open_ssh_connection(h)
|
||||
wrapped_content = wrap_content_with_comments(final_content)
|
||||
@@ -1297,14 +1291,13 @@ def deploy_user(user_id):
|
||||
sftp.close()
|
||||
ssh.close()
|
||||
os.remove(tmp_file_path)
|
||||
log_details = f'[LINUX] Updated {format_host(h)} for user {user_id}'
|
||||
log_details = f'[LINUX] Updated {host_name} for user {user_id}'
|
||||
|
||||
# Logowanie wdrożenia
|
||||
db.session.add(DeployLog(details=log_details, user_id=user_id))
|
||||
db.session.commit()
|
||||
|
||||
except Exception as e:
|
||||
error_log = f'Failed to update {format_host(h)}: {str(e)} for user {user_id}'
|
||||
error_log = f'Failed to update {host_name}: {str(e)} for user {user_id}'
|
||||
db.session.add(DeployLog(details=error_log, user_id=user_id))
|
||||
db.session.commit()
|
||||
|
||||
@@ -1751,7 +1744,9 @@ def local_defaults():
|
||||
ip_address = request.form.get('ip_address', '').strip()
|
||||
|
||||
if hostname and ip_address:
|
||||
new_entry = LocalDefaultEntry(user_id=user_id, hostname=hostname, ip_address=ip_address or None, entry=entry_content)
|
||||
entry_content = f"{ip_address} {hostname}"
|
||||
|
||||
new_entry = LocalDefaultEntry(user_id=user_id, hostname=hostname, ip_address=ip_address, entry=entry_content)
|
||||
db.session.add(new_entry)
|
||||
db.session.commit()
|
||||
flash('Dodano nowy wpis.', 'success')
|
||||
@@ -1764,19 +1759,66 @@ def local_defaults():
|
||||
return render_template('local_defaults.html', entries=entries)
|
||||
|
||||
@app.route('/local-defaults/delete/<int:entry_id>', methods=['POST'])
|
||||
def delete_local_default(entry_id):
|
||||
@app.route('/local-defaults/delete', methods=['POST'])
|
||||
def delete_local_default(entry_id=None):
|
||||
if 'user_id' not in session:
|
||||
return redirect(url_for('login'))
|
||||
return jsonify({'status': 'error', 'message': 'Unauthorized'}), 403
|
||||
|
||||
entry = LocalDefaultEntry.query.get(entry_id)
|
||||
if not entry or entry.user_id != session['user_id']:
|
||||
flash('Wpis nie istnieje lub brak uprawnień.', 'danger')
|
||||
if request.is_json:
|
||||
data = request.get_json()
|
||||
entry_ids = data.get('entry_ids', [])
|
||||
|
||||
if not entry_ids:
|
||||
return jsonify({'status': 'error', 'message': 'Brak wpisów do usunięcia'}), 400
|
||||
|
||||
entries_to_delete = LocalDefaultEntry.query.filter(
|
||||
LocalDefaultEntry.id.in_(entry_ids),
|
||||
LocalDefaultEntry.user_id == session['user_id']
|
||||
).all()
|
||||
|
||||
if not entries_to_delete:
|
||||
return jsonify({'status': 'error', 'message': 'Nie znaleziono wpisów do usunięcia'}), 404
|
||||
|
||||
for entry in entries_to_delete:
|
||||
db.session.delete(entry)
|
||||
|
||||
db.session.commit()
|
||||
return jsonify({'status': 'success', 'message': 'Wpisy usunięte pomyślnie'})
|
||||
|
||||
else:
|
||||
# Obsługa usuwania pojedynczego wpisu
|
||||
entry = LocalDefaultEntry.query.get(entry_id)
|
||||
if not entry or entry.user_id != session['user_id']:
|
||||
flash('Wpis nie istnieje lub brak uprawnień.', 'danger')
|
||||
return redirect(url_for('local_defaults'))
|
||||
|
||||
db.session.delete(entry)
|
||||
db.session.commit()
|
||||
flash('Wpis został usunięty.', 'info')
|
||||
return redirect(url_for('local_defaults'))
|
||||
|
||||
db.session.delete(entry)
|
||||
db.session.commit()
|
||||
flash('Wpis został usunięty.', 'info')
|
||||
return redirect(url_for('local_defaults'))
|
||||
|
||||
@app.route('/local-defaults/update/<int:entry_id>', methods=['POST'])
|
||||
def update_local_default(entry_id):
|
||||
if 'user_id' not in session:
|
||||
return jsonify({'status': 'error', 'message': 'Unauthorized'}), 403
|
||||
|
||||
entry = db.session.get(LocalDefaultEntry, entry_id)
|
||||
if not entry or entry.user_id != session['user_id']:
|
||||
return jsonify({'status': 'error', 'message': 'Entry not found'}), 404
|
||||
|
||||
data = request.get_json()
|
||||
new_ip = data.get('ip_address', '').strip()
|
||||
new_hostname = data.get('hostname', '').strip()
|
||||
|
||||
if new_ip and new_hostname:
|
||||
entry.ip_address = new_ip
|
||||
entry.hostname = new_hostname
|
||||
entry.entry = f"{new_ip} {new_hostname}"
|
||||
db.session.commit()
|
||||
return jsonify({'status': 'success', 'message': 'Updated successfully', 'ip_address': new_ip, 'hostname': new_hostname})
|
||||
else:
|
||||
return jsonify({'status': 'error', 'message': 'IP and hostname are required'}), 400
|
||||
|
||||
scheduler = BackgroundScheduler(timezone=get_localzone())
|
||||
scheduler.add_job(func=scheduled_deployments, trigger="interval", minutes=1, next_run_time=datetime.now())
|
||||
|
Reference in New Issue
Block a user