mirror of https://github.com/Aidaho12/haproxy-wi
v8.2.1: Refactor JS and Python models, remove unused functions, and improve form validation
Updated JavaScript to refine option selection logic and remove redundant functions (`showCompare`, `showCompareConfigs`). Enhanced Python models with validators to enforce non-empty inputs for critical fields (`port`, `maxconn`, etc.). Optimized configuration diff logic for better performance and readability. Added file lock checks before database migrations.master
parent
44ddae6dd1
commit
f749f7366e
|
@ -5,6 +5,7 @@ from flask_apscheduler import APScheduler
|
|||
|
||||
from app.modules.common.common import set_correct_owner
|
||||
from app.modules.roxywi import logger
|
||||
from app.modules.common.lock_utils import acquire_file_lock
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config.from_object('app.config.Configuration')
|
||||
|
@ -33,9 +34,10 @@ from app.modules.db.db_model import create_tables
|
|||
from app.create_db import default_values
|
||||
from app.modules.db.migration_manager import migrate
|
||||
|
||||
create_tables()
|
||||
default_values()
|
||||
migrate()
|
||||
if not acquire_file_lock():
|
||||
create_tables()
|
||||
default_values()
|
||||
migrate()
|
||||
|
||||
set_correct_owner('/var/lib/roxy-wi')
|
||||
|
||||
|
|
|
@ -359,13 +359,10 @@ def diff_config(old_cfg, cfg) -> str:
|
|||
:param cfg: Path to the new configuration file to compare.
|
||||
:return: Unified diff output showing the differences between `old_cfg` and `cfg`.
|
||||
"""
|
||||
diff = ""
|
||||
cmd = f"/bin/diff -ub {old_cfg} {cfg}"
|
||||
output, stderr = server_mod.subprocess_execute(cmd)
|
||||
|
||||
for line in output:
|
||||
diff += line + "\n"
|
||||
return diff
|
||||
output = '\n'.join(output)
|
||||
return output
|
||||
|
||||
|
||||
def _classify_line(line: str) -> str:
|
||||
|
@ -429,12 +426,9 @@ def compare_config(service: str, left: str, right: str) -> str:
|
|||
:param right: The name of the right configuration file.
|
||||
:return: The rendered template with the diff output and the user language for Flask.
|
||||
"""
|
||||
lang = roxywi_common.get_user_lang_for_flask()
|
||||
config_dir = config_common.get_config_dir(service)
|
||||
cmd = f'diff -pub {config_dir}{left} {config_dir}{right}'
|
||||
output, stderr = server_mod.subprocess_execute(cmd)
|
||||
|
||||
return render_template('ajax/compare.html', stdout=output, lang=lang)
|
||||
output = diff_config(f'{config_dir}{left}', f'{config_dir}{right}')
|
||||
return output
|
||||
|
||||
|
||||
def show_config(server_ip: str, service: str, config_file_name: str, configver: str, claims: dict, edit_section: str) -> str:
|
||||
|
|
|
@ -388,6 +388,20 @@ class HaproxyBackendServer(BaseModel):
|
|||
send_proxy: Optional[bool] = 0
|
||||
backup: Optional[bool] = 0
|
||||
|
||||
@model_validator(mode='before')
|
||||
@classmethod
|
||||
def int_cannot_be_empty(cls, values):
|
||||
if 'port' in values:
|
||||
if values['port'] == '':
|
||||
raise ValueError('Port cannot be empty')
|
||||
if 'port_check' in values:
|
||||
if values['port_check'] == '':
|
||||
raise ValueError('Port check cannot be empty')
|
||||
if 'maxconn' in values:
|
||||
if values['maxconn'] == '':
|
||||
raise ValueError('Maxconn cannot be empty')
|
||||
return values
|
||||
|
||||
|
||||
class HaproxyCookie(BaseModel):
|
||||
dynamic: str
|
||||
|
@ -559,6 +573,21 @@ class NginxBackendServer(BaseModel):
|
|||
fail_timeout: int
|
||||
|
||||
|
||||
@model_validator(mode='before')
|
||||
@classmethod
|
||||
def int_cannot_be_empty(cls, values):
|
||||
if 'port' in values:
|
||||
if values['port'] == '':
|
||||
raise ValueError('Port cannot be empty')
|
||||
if 'max_fails' in values:
|
||||
if values['max_fails'] == '':
|
||||
raise ValueError('max_fails cannot be empty')
|
||||
if 'fail_timeout' in values:
|
||||
if values['fail_timeout'] == '':
|
||||
raise ValueError('fail_timeout cannot be empty')
|
||||
return values
|
||||
|
||||
|
||||
class NginxUpstreamRequest(BaseModel):
|
||||
name: EscapedString
|
||||
balance: Optional[Literal['ip_hash', 'least_conn', 'random', 'round_robin']]
|
||||
|
@ -619,6 +648,7 @@ class NginxLocationRequest(BaseModel):
|
|||
class NginxProxyPassRequest(BaseModel):
|
||||
locations: List[NginxLocationRequest]
|
||||
name: Union[IPvAnyAddress, DomainName]
|
||||
name_aliases: List[Union[IPvAnyAddress, DomainName]] = None
|
||||
port: Annotated[int, Gt(1), Le(65535)]
|
||||
type: Literal['proxy_pass'] = 'proxy_pass'
|
||||
scheme: Literal['http', 'https'] = 'http'
|
||||
|
|
|
@ -98,15 +98,15 @@ function showStats() {
|
|||
});
|
||||
}
|
||||
function openStats() {
|
||||
let serv = $("#serv").val();
|
||||
let service_url = cur_url[4];
|
||||
let serv = $("#serv option:selected").val();
|
||||
let service_url = $('#service').val();
|
||||
let url = "/stats/"+service_url+"/"+serv
|
||||
let win = window.open(url, '_blank');
|
||||
win.focus();
|
||||
}
|
||||
function openVersions() {
|
||||
let serv = $("#serv").val();
|
||||
let service_url = cur_url[4];
|
||||
let serv = $("#serv option:selected").val();
|
||||
let service_url = $('#service').val();
|
||||
let url = "/config/versions/"+service_url+"/"+serv
|
||||
let win = window.open(url,"_self");
|
||||
win.focus();
|
||||
|
@ -230,43 +230,6 @@ function showMap() {
|
|||
}
|
||||
});
|
||||
}
|
||||
function showCompare() {
|
||||
$.ajax({
|
||||
url: "/config/compare/" + $("#service").val() + "/" + $("#serv").val() + "/show",
|
||||
data: {
|
||||
left: $('#left').val(),
|
||||
right: $("#right").val(),
|
||||
},
|
||||
type: "POST",
|
||||
success: function (data) {
|
||||
if (data.indexOf('error:') != '-1') {
|
||||
toastr.error(data);
|
||||
} else {
|
||||
toastr.clear();
|
||||
$("#ajax").html(data);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function showCompareConfigs() {
|
||||
clearAllAjaxFields();
|
||||
$('#ajax-config_file_name').empty();
|
||||
$.ajax({
|
||||
url: "/config/compare/" + $("#service").val() + "/" + $("#serv").val() + "/files",
|
||||
type: "GET",
|
||||
success: function (data) {
|
||||
if (data.indexOf('error:') != '-1') {
|
||||
toastr.error(data);
|
||||
} else {
|
||||
toastr.clear();
|
||||
$("#ajax-compare").html(data);
|
||||
$("input[type=submit], button").button();
|
||||
$("select").selectmenu();
|
||||
window.history.pushState("Show compare config", "Show compare config", '/config/compare/' + $("#service").val() + '/' + $("#serv").val());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function showConfig() {
|
||||
let edit_section = '';
|
||||
let edit_section_uri = '';
|
||||
|
|
Loading…
Reference in New Issue