mirror of
https://github.com/MengMengCode/CLICD.git
synced 2026-08-06 05:52:19 +08:00
修复防火墙至不支持的方法 等待Claude修复
This commit is contained in:
@@ -1445,6 +1445,7 @@ function clicd_firewallUpdate($params)
|
|||||||
$input = clicd_json_input();
|
$input = clicd_json_input();
|
||||||
$enabled = clicd_param_value($input, 'enabled', 'true');
|
$enabled = clicd_param_value($input, 'enabled', 'true');
|
||||||
$enabled = filter_var($enabled, FILTER_VALIDATE_BOOLEAN);
|
$enabled = filter_var($enabled, FILTER_VALIDATE_BOOLEAN);
|
||||||
|
$defaultAction = strtoupper(trim((string)clicd_param_value($input, 'default_action', '')));
|
||||||
$rules = clicd_param_value($input, 'rules', '[]');
|
$rules = clicd_param_value($input, 'rules', '[]');
|
||||||
|
|
||||||
if (is_string($rules)) {
|
if (is_string($rules)) {
|
||||||
@@ -1461,6 +1462,9 @@ function clicd_firewallUpdate($params)
|
|||||||
'enabled' => $enabled,
|
'enabled' => $enabled,
|
||||||
'rules' => $rules,
|
'rules' => $rules,
|
||||||
];
|
];
|
||||||
|
if (in_array($defaultAction, ['ACCEPT', 'DROP'], true)) {
|
||||||
|
$payload['default_action'] = $defaultAction;
|
||||||
|
}
|
||||||
|
|
||||||
$container = [];
|
$container = [];
|
||||||
$containerId = clicd_container_api_id($params, $container);
|
$containerId = clicd_container_api_id($params, $container);
|
||||||
@@ -1526,6 +1530,7 @@ function clicd_firewall_ajax($params)
|
|||||||
// update
|
// update
|
||||||
$enabled = clicd_param_value($input, 'enabled', 'true');
|
$enabled = clicd_param_value($input, 'enabled', 'true');
|
||||||
$enabled = filter_var($enabled, FILTER_VALIDATE_BOOLEAN);
|
$enabled = filter_var($enabled, FILTER_VALIDATE_BOOLEAN);
|
||||||
|
$defaultAction = strtoupper(trim((string)clicd_param_value($input, 'default_action', '')));
|
||||||
$rules = clicd_param_value($input, 'rules', '[]');
|
$rules = clicd_param_value($input, 'rules', '[]');
|
||||||
|
|
||||||
if (is_string($rules)) {
|
if (is_string($rules)) {
|
||||||
@@ -1542,6 +1547,9 @@ function clicd_firewall_ajax($params)
|
|||||||
'enabled' => $enabled,
|
'enabled' => $enabled,
|
||||||
'rules' => $rules,
|
'rules' => $rules,
|
||||||
];
|
];
|
||||||
|
if (in_array($defaultAction, ['ACCEPT', 'DROP'], true)) {
|
||||||
|
$payload['default_action'] = $defaultAction;
|
||||||
|
}
|
||||||
|
|
||||||
$call = clicd_request_debug($params, '/api/v1/containers/' . rawurlencode($containerId) . '/firewall', $payload, 'PUT', 30);
|
$call = clicd_request_debug($params, '/api/v1/containers/' . rawurlencode($containerId) . '/firewall', $payload, 'PUT', 30);
|
||||||
$debug[] = $call['debug'];
|
$debug[] = $call['debug'];
|
||||||
|
|||||||
+461
-125
@@ -1,52 +1,370 @@
|
|||||||
<style>
|
<style>
|
||||||
.clicd-fw-panel{font-size:14px;color:#1f2937}
|
.clicd-fw-panel {
|
||||||
.clicd-fw-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin-bottom:16px}
|
font-size: 14px;
|
||||||
.clicd-fw-card{border:1px solid #e5e7eb;border-radius:6px;padding:12px;background:#fff}
|
color: #1f2937
|
||||||
.clicd-fw-label{color:#6b7280;font-size:12px;margin-bottom:4px}
|
}
|
||||||
.clicd-fw-value{font-size:18px;font-weight:600;word-break:break-all}
|
|
||||||
.clicd-fw-section{border:1px solid #e5e7eb;border-radius:6px;background:#fff;padding:12px;margin-top:8px}
|
.clicd-fw-grid {
|
||||||
.clicd-fw-title{font-weight:600;margin:18px 0 8px}
|
display: grid;
|
||||||
.clicd-fw-muted{color:#6b7280}
|
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||||
.clicd-fw-toggle-row{display:flex;align-items:center;gap:12px;margin-bottom:12px}
|
gap: 12px;
|
||||||
.clicd-fw-toggle{position:relative;display:inline-flex;width:48px;height:26px;cursor:pointer}
|
margin-bottom: 16px
|
||||||
.clicd-fw-toggle input{opacity:0;width:0;height:0}
|
}
|
||||||
.clicd-fw-toggle-slider{position:absolute;inset:0;background:#d1d5db;border-radius:26px;transition:.25s}
|
|
||||||
.clicd-fw-toggle-slider:before{content:"";position:absolute;width:22px;height:22px;border-radius:50%;background:#fff;top:2px;left:2px;transition:.25s}.clicd-fw-toggle .clicd-fw-toggle-slider:before{width:16px;height:16px;top:2px;left:2px}
|
.clicd-fw-card {
|
||||||
.clicd-fw-toggle input:checked+.clicd-fw-toggle-slider{background:#10b981}
|
border: 1px solid #e5e7eb;
|
||||||
.clicd-fw-toggle input:checked+.clicd-fw-toggle-slider:before{transform:translateX(22px)}
|
border-radius: 6px;
|
||||||
.clicd-fw-toggle-label{font-size:14px;font-weight:500}
|
padding: 12px;
|
||||||
.clicd-fw-status{font-size:13px;color:#6b7280}
|
background: #fff
|
||||||
.clicd-fw-rule-form{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:10px;align-items:end}
|
}
|
||||||
.clicd-fw-field label{display:block;color:#6b7280;font-size:12px;margin-bottom:4px}
|
|
||||||
.clicd-fw-input,.clicd-fw-select{width:100%;height:34px;border:1px solid #d1d5db;border-radius:4px;padding:6px 8px;box-sizing:border-box}
|
.clicd-fw-label {
|
||||||
.clicd-fw-input:focus,.clicd-fw-select:focus{border-color:#2563eb;outline:none}
|
color: #6b7280;
|
||||||
.clicd-fw-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:end}
|
font-size: 12px;
|
||||||
.clicd-fw-btn{height:34px;border:1px solid #2563eb;background:#2563eb;color:#fff;border-radius:4px;padding:0 12px;cursor:pointer;font-size:13px}
|
margin-bottom: 4px
|
||||||
.clicd-fw-btn[disabled]{opacity:.6;cursor:not-allowed}
|
}
|
||||||
.clicd-fw-btn-secondary{border-color:#d1d5db;background:#fff;color:#374151}
|
|
||||||
.clicd-fw-btn-danger{border-color:#dc2626;background:#dc2626;color:#fff}
|
.clicd-fw-value {
|
||||||
.clicd-fw-btn-sm{height:30px;padding:0 10px;font-size:12px}
|
font-size: 18px;
|
||||||
.clicd-fw-rules{display:flex;flex-direction:column;gap:10px;margin-top:8px}
|
font-weight: 600;
|
||||||
.clicd-fw-rule{border:1px solid #e5e7eb;border-radius:6px;background:#fff;padding:12px}
|
word-break: break-all
|
||||||
.clicd-fw-rule-header{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px;flex-wrap:wrap}
|
}
|
||||||
.clicd-fw-rule-direction{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:4px;font-size:12px;font-weight:600}
|
|
||||||
.clicd-fw-direction-in{background:#dbeafe;color:#1d4ed8}
|
.clicd-fw-section {
|
||||||
.clicd-fw-direction-out{background:#fef3c7;color:#92400e}
|
border: 1px solid #e5e7eb;
|
||||||
.clicd-fw-rule-action{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:4px;font-size:12px;font-weight:600}
|
border-radius: 6px;
|
||||||
.clicd-fw-action-ACCEPT{background:#d1fae5;color:#065f46}
|
background: #fff;
|
||||||
.clicd-fw-action-DROP{background:#fee2e2;color:#991b1b}
|
padding: 12px;
|
||||||
.clicd-fw-rule-desc{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:8px}
|
margin-top: 8px
|
||||||
.clicd-fw-rule-detail{font-size:13px;color:#374151;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
}
|
||||||
.clicd-fw-rule-detail .sep{color:#d1d5db}
|
|
||||||
.clicd-fw-rule-edit-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px;margin-top:8px;padding-top:8px;border-top:1px solid #e5e7eb}
|
.clicd-fw-title {
|
||||||
.clicd-fw-message{border:1px solid #bfdbfe;background:#eff6ff;color:#1d4ed8;border-radius:6px;padding:10px 12px;margin-bottom:12px;display:none}
|
font-weight: 600;
|
||||||
.clicd-fw-message.error{border-color:#fecaca;background:#fef2f2;color:#b91c1c}
|
margin: 18px 0 8px
|
||||||
.clicd-fw-debug{margin-top:12px;border:1px dashed #d1d5db;border-radius:6px;background:#f9fafb;padding:10px;color:#374151;white-space:pre-wrap;font-size:12px;display:none}
|
}
|
||||||
.clicd-fw-modal-mask{position:fixed;inset:0;background:rgba(15,23,42,.42);display:none;align-items:center;justify-content:center;z-index:9999;padding:16px}
|
|
||||||
.clicd-fw-modal{width:min(420px,100%);background:#fff;border-radius:6px;border:1px solid #e5e7eb;box-shadow:0 18px 48px rgba(15,23,42,.22);padding:16px}
|
.clicd-fw-muted {
|
||||||
.clicd-fw-modal-title{font-size:16px;font-weight:700;color:#111827;margin-bottom:8px}
|
color: #6b7280
|
||||||
.clicd-fw-modal-body{font-size:14px;color:#4b5563;line-height:1.6;margin-bottom:14px}
|
}
|
||||||
.clicd-fw-modal-actions{display:flex;justify-content:flex-end;gap:8px}
|
|
||||||
|
.clicd-fw-toggle-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-toggle {
|
||||||
|
position: relative;
|
||||||
|
display: inline-flex;
|
||||||
|
width: 48px;
|
||||||
|
height: 26px;
|
||||||
|
cursor: pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-toggle input {
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-toggle-slider {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: #d1d5db;
|
||||||
|
border-radius: 26px;
|
||||||
|
transition: .25s
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-toggle-slider:before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: #fff;
|
||||||
|
top: 2px;
|
||||||
|
left: 2px;
|
||||||
|
transition: .25s
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-toggle .clicd-fw-toggle-slider:before {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
top: 2px;
|
||||||
|
left: 2px
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-toggle input:checked+.clicd-fw-toggle-slider {
|
||||||
|
background: #10b981
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-toggle input:checked+.clicd-fw-toggle-slider:before {
|
||||||
|
transform: translateX(22px)
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-toggle-label {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-status {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #6b7280
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-rule-form {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
|
||||||
|
gap: 10px;
|
||||||
|
align-items: end
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-field label {
|
||||||
|
display: block;
|
||||||
|
color: #6b7280;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-bottom: 4px
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-input,
|
||||||
|
.clicd-fw-select {
|
||||||
|
width: 100%;
|
||||||
|
height: 34px;
|
||||||
|
border: 1px solid #d1d5db;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
box-sizing: border-box
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-input:focus,
|
||||||
|
.clicd-fw-select:focus {
|
||||||
|
border-color: #2563eb;
|
||||||
|
outline: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: end
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-btn {
|
||||||
|
height: 34px;
|
||||||
|
border: 1px solid #2563eb;
|
||||||
|
background: #2563eb;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 13px
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-btn[disabled] {
|
||||||
|
opacity: .6;
|
||||||
|
cursor: not-allowed
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-btn-secondary {
|
||||||
|
border-color: #d1d5db;
|
||||||
|
background: #fff;
|
||||||
|
color: #374151
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-btn-danger {
|
||||||
|
border-color: #dc2626;
|
||||||
|
background: #dc2626;
|
||||||
|
color: #fff
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-btn-sm {
|
||||||
|
height: 30px;
|
||||||
|
padding: 0 10px;
|
||||||
|
font-size: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-rules {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 8px
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-rule {
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: #fff;
|
||||||
|
padding: 12px
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-rule-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
flex-wrap: wrap
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-rule-direction {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-direction-in {
|
||||||
|
background: #dbeafe;
|
||||||
|
color: #1d4ed8
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-direction-out {
|
||||||
|
background: #fef3c7;
|
||||||
|
color: #92400e
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-rule-action {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-action-ACCEPT {
|
||||||
|
background: #d1fae5;
|
||||||
|
color: #065f46
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-action-DROP {
|
||||||
|
background: #fee2e2;
|
||||||
|
color: #991b1b
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-rule-desc {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-bottom: 8px
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-rule-detail {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #374151;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-rule-detail .sep {
|
||||||
|
color: #d1d5db
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-rule-edit-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
||||||
|
gap: 8px;
|
||||||
|
margin-top: 8px;
|
||||||
|
padding-top: 8px;
|
||||||
|
border-top: 1px solid #e5e7eb
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-message {
|
||||||
|
border: 1px solid #bfdbfe;
|
||||||
|
background: #eff6ff;
|
||||||
|
color: #1d4ed8;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-message.error {
|
||||||
|
border-color: #fecaca;
|
||||||
|
background: #fef2f2;
|
||||||
|
color: #b91c1c
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-debug {
|
||||||
|
margin-top: 12px;
|
||||||
|
border: 1px dashed #d1d5db;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: #f9fafb;
|
||||||
|
padding: 10px;
|
||||||
|
color: #374151;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
font-size: 12px;
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-modal-mask {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
background: rgba(15, 23, 42, .42);
|
||||||
|
display: none;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 9999;
|
||||||
|
padding: 16px
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-modal {
|
||||||
|
width: min(420px, 100%);
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
box-shadow: 0 18px 48px rgba(15, 23, 42, .22);
|
||||||
|
padding: 16px
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-modal-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #111827;
|
||||||
|
margin-bottom: 8px
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-modal-body {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #4b5563;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 14px
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-modal-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 8px
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-default-action-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 10px
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-default-action-row label {
|
||||||
|
color: #6b7280;
|
||||||
|
font-size: 12px;
|
||||||
|
white-space: nowrap
|
||||||
|
}
|
||||||
|
|
||||||
|
.clicd-fw-default-action-row select {
|
||||||
|
height: 30px;
|
||||||
|
border: 1px solid #d1d5db;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0 8px;
|
||||||
|
font-size: 13px
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class="clicd-fw-panel" id="clicd-fw-panel" data-service-id="{$service_id}" data-area-key="{$area_key}">
|
<div class="clicd-fw-panel" id="clicd-fw-panel" data-service-id="{$service_id}" data-area-key="{$area_key}">
|
||||||
@@ -72,11 +390,26 @@
|
|||||||
<span class="clicd-fw-toggle-label">启用防火墙</span>
|
<span class="clicd-fw-toggle-label">启用防火墙</span>
|
||||||
<span class="clicd-fw-status" id="clicd-fw-status-text">加载中...</span>
|
<span class="clicd-fw-status" id="clicd-fw-status-text">加载中...</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="clicd-fw-default-action-row">
|
||||||
|
<label>默认策略</label>
|
||||||
|
<select id="clicd-fw-default-action">
|
||||||
|
<option value="DROP">DROP(拒绝未匹配流量)</option>
|
||||||
|
<option value="ACCEPT">ACCEPT(放行未匹配流量)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="clicd-fw-title">添加规则</div>
|
<div class="clicd-fw-title">添加规则</div>
|
||||||
<div class="clicd-fw-section" id="clicd-fw-add-section">
|
<div class="clicd-fw-section" id="clicd-fw-add-section">
|
||||||
<div class="clicd-fw-rule-form">
|
<div class="clicd-fw-rule-form">
|
||||||
|
<div class="clicd-fw-field">
|
||||||
|
<label>网络</label>
|
||||||
|
<select class="clicd-fw-select" id="clicd-fw-add-network">
|
||||||
|
<option value="ipv4">IPv4</option>
|
||||||
|
<option value="ipv6">IPv6</option>
|
||||||
|
<option value="all">全部</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
<div class="clicd-fw-field">
|
<div class="clicd-fw-field">
|
||||||
<label>方向</label>
|
<label>方向</label>
|
||||||
<select class="clicd-fw-select" id="clicd-fw-add-direction">
|
<select class="clicd-fw-select" id="clicd-fw-add-direction">
|
||||||
@@ -128,7 +461,8 @@
|
|||||||
<div class="clicd-fw-modal-title">确认删除</div>
|
<div class="clicd-fw-modal-title">确认删除</div>
|
||||||
<div class="clicd-fw-modal-body" id="clicd-fw-delete-text">确认删除该规则?</div>
|
<div class="clicd-fw-modal-body" id="clicd-fw-delete-text">确认删除该规则?</div>
|
||||||
<div class="clicd-fw-modal-actions">
|
<div class="clicd-fw-modal-actions">
|
||||||
<button class="clicd-fw-btn clicd-fw-btn-secondary" type="button" id="clicd-fw-delete-cancel">取消</button>
|
<button class="clicd-fw-btn clicd-fw-btn-secondary" type="button"
|
||||||
|
id="clicd-fw-delete-cancel">取消</button>
|
||||||
<button class="clicd-fw-btn clicd-fw-btn-danger" type="button" id="clicd-fw-delete-confirm">删除</button>
|
<button class="clicd-fw-btn clicd-fw-btn-danger" type="button" id="clicd-fw-delete-confirm">删除</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -136,7 +470,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
(function(){
|
(function () {
|
||||||
var panel = document.getElementById('clicd-fw-panel');
|
var panel = document.getElementById('clicd-fw-panel');
|
||||||
if (!panel || panel.getAttribute('data-bound') === '1') return;
|
if (!panel || panel.getAttribute('data-bound') === '1') return;
|
||||||
panel.setAttribute('data-bound', '1');
|
panel.setAttribute('data-bound', '1');
|
||||||
@@ -145,6 +479,7 @@
|
|||||||
var debugBox = document.getElementById('clicd-fw-debug');
|
var debugBox = document.getElementById('clicd-fw-debug');
|
||||||
var rulesContainer = document.getElementById('clicd-fw-rules');
|
var rulesContainer = document.getElementById('clicd-fw-rules');
|
||||||
var enabledCheckbox = document.getElementById('clicd-fw-enabled');
|
var enabledCheckbox = document.getElementById('clicd-fw-enabled');
|
||||||
|
var defaultActionSelect = document.getElementById('clicd-fw-default-action');
|
||||||
var statusText = document.getElementById('clicd-fw-status-text');
|
var statusText = document.getElementById('clicd-fw-status-text');
|
||||||
var deleteModal = document.getElementById('clicd-fw-delete-modal');
|
var deleteModal = document.getElementById('clicd-fw-delete-modal');
|
||||||
var deleteText = document.getElementById('clicd-fw-delete-text');
|
var deleteText = document.getElementById('clicd-fw-delete-text');
|
||||||
@@ -168,8 +503,12 @@
|
|||||||
return "{$MODULE_CUSTOM_API}";
|
return "{$MODULE_CUSTOM_API}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function serviceId() {
|
||||||
|
return panel.getAttribute('data-service-id') || '';
|
||||||
|
}
|
||||||
|
|
||||||
function setBusy(busy) {
|
function setBusy(busy) {
|
||||||
panel.querySelectorAll('button, input, select').forEach(function(el){ el.disabled = !!busy; });
|
panel.querySelectorAll('button, input, select').forEach(function (el) { el.disabled = !!busy; });
|
||||||
}
|
}
|
||||||
|
|
||||||
function escapeHtml(value) {
|
function escapeHtml(value) {
|
||||||
@@ -181,20 +520,10 @@
|
|||||||
.replace(/'/g, ''');
|
.replace(/'/g, ''');
|
||||||
}
|
}
|
||||||
|
|
||||||
function portDisplay(port) {
|
function portDisplay(port) { return port || '所有'; }
|
||||||
return port || '所有';
|
function sourceIpDisplay(ip) { return ip || '任意'; }
|
||||||
}
|
function networkLabel(net) {
|
||||||
|
return net === 'ipv6' ? 'IPv6' : net === 'all' ? 'ALL' : 'IPv4';
|
||||||
function sourceIpDisplay(ip) {
|
|
||||||
return ip || '任意';
|
|
||||||
}
|
|
||||||
|
|
||||||
function directionLabel(dir) {
|
|
||||||
return dir === 'in' ? '入站' : '出站';
|
|
||||||
}
|
|
||||||
|
|
||||||
function actionLabel(action) {
|
|
||||||
return action === 'ACCEPT' ? '放行' : '拒绝';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderRules(rules) {
|
function renderRules(rules) {
|
||||||
@@ -203,10 +532,11 @@
|
|||||||
rulesContainer.innerHTML = '<div class="clicd-fw-section clicd-fw-muted">暂无防火墙规则</div>';
|
rulesContainer.innerHTML = '<div class="clicd-fw-section clicd-fw-muted">暂无防火墙规则</div>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rulesContainer.innerHTML = currentRules.map(function(rule, idx) {
|
rulesContainer.innerHTML = currentRules.map(function (rule, idx) {
|
||||||
var dir = (rule.direction || 'in').toLowerCase();
|
var dir = (rule.direction || 'in').toLowerCase();
|
||||||
var proto = (rule.protocol || 'tcp').toLowerCase();
|
var proto = (rule.protocol || 'tcp').toLowerCase();
|
||||||
var action = (rule.action || 'ACCEPT').toUpperCase();
|
var action = (rule.action || 'ACCEPT').toUpperCase();
|
||||||
|
var network = (rule.network || 'ipv4').toLowerCase();
|
||||||
var port = escapeHtml(portDisplay(rule.port));
|
var port = escapeHtml(portDisplay(rule.port));
|
||||||
var srcIp = escapeHtml(sourceIpDisplay(rule.source_ip));
|
var srcIp = escapeHtml(sourceIpDisplay(rule.source_ip));
|
||||||
var desc = escapeHtml(rule.description || '');
|
var desc = escapeHtml(rule.description || '');
|
||||||
@@ -219,8 +549,9 @@
|
|||||||
'<div class="clicd-fw-rule-header">' +
|
'<div class="clicd-fw-rule-header">' +
|
||||||
'<div style="display:flex;align-items:center;gap:6px;flex-wrap:wrap">' +
|
'<div style="display:flex;align-items:center;gap:6px;flex-wrap:wrap">' +
|
||||||
'<span class="clicd-fw-rule-direction ' + dirClass + '">' + (dir === 'in' ? '↑ 入站' : '↓ 出站') + '</span>' +
|
'<span class="clicd-fw-rule-direction ' + dirClass + '">' + (dir === 'in' ? '↑ 入站' : '↓ 出站') + '</span>' +
|
||||||
'<span class="clicd-fw-rule-action ' + actionClass + '">' + actionLabel(action) + '</span>' +
|
'<span class="clicd-fw-rule-action ' + actionClass + '">' + (action === 'ACCEPT' ? '放行' : '拒绝') + '</span>' +
|
||||||
'<span style="font-size:13px;color:#6b7280">' + proto.toUpperCase() + '</span>' +
|
'<span style="font-size:13px;color:#6b7280">' + proto.toUpperCase() + '</span>' +
|
||||||
|
'<span style="font-size:12px;background:#f3f4f6;color:#374151;padding:2px 6px;border-radius:4px">' + networkLabel(network) + '</span>' +
|
||||||
'<span style="font-size:13px;color:#374151">' +
|
'<span style="font-size:13px;color:#374151">' +
|
||||||
(port !== '所有' ? '端口: ' + port : '') +
|
(port !== '所有' ? '端口: ' + port : '') +
|
||||||
(srcIp !== '任意' && port !== '所有' ? ' | ' : '') +
|
(srcIp !== '任意' && port !== '所有' ? ' | ' : '') +
|
||||||
@@ -231,7 +562,6 @@
|
|||||||
'<label class="clicd-fw-toggle" style="width:36px;height:20px">' +
|
'<label class="clicd-fw-toggle" style="width:36px;height:20px">' +
|
||||||
'<input type="checkbox" class="clicd-fw-rule-enabled" ' + enabledChecked + '>' +
|
'<input type="checkbox" class="clicd-fw-rule-enabled" ' + enabledChecked + '>' +
|
||||||
'<span class="clicd-fw-toggle-slider" style="border-radius:20px"></span>' +
|
'<span class="clicd-fw-toggle-slider" style="border-radius:20px"></span>' +
|
||||||
|
|
||||||
'</label>' +
|
'</label>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
@@ -239,6 +569,11 @@
|
|||||||
'<span style="font-size:13px;color:#374151;flex:1">' + (desc || '<span style="color:#9ca3af">无说明</span>') + '</span>' +
|
'<span style="font-size:13px;color:#374151;flex:1">' + (desc || '<span style="color:#9ca3af">无说明</span>') + '</span>' +
|
||||||
'</div>' +
|
'</div>' +
|
||||||
'<div class="clicd-fw-rule-edit-row">' +
|
'<div class="clicd-fw-rule-edit-row">' +
|
||||||
|
'<div class="clicd-fw-field"><label>网络</label><select class="clicd-fw-select clicd-fw-edit-field" data-field="network">' +
|
||||||
|
'<option value="ipv4"' + (network === 'ipv4' ? ' selected' : '') + '>IPv4</option>' +
|
||||||
|
'<option value="ipv6"' + (network === 'ipv6' ? ' selected' : '') + '>IPv6</option>' +
|
||||||
|
'<option value="all"' + (network === 'all' ? ' selected' : '') + '>全部</option>' +
|
||||||
|
'</select></div>' +
|
||||||
'<div class="clicd-fw-field"><label>方向</label><select class="clicd-fw-select clicd-fw-edit-field" data-field="direction">' +
|
'<div class="clicd-fw-field"><label>方向</label><select class="clicd-fw-select clicd-fw-edit-field" data-field="direction">' +
|
||||||
'<option value="in"' + (dir === 'in' ? ' selected' : '') + '>入站</option>' +
|
'<option value="in"' + (dir === 'in' ? ' selected' : '') + '>入站</option>' +
|
||||||
'<option value="out"' + (dir === 'out' ? ' selected' : '') + '>出站</option>' +
|
'<option value="out"' + (dir === 'out' ? ' selected' : '') + '>出站</option>' +
|
||||||
@@ -262,9 +597,8 @@
|
|||||||
'</div>';
|
'</div>';
|
||||||
}).join('');
|
}).join('');
|
||||||
|
|
||||||
// Bind toggle events for rule enabled/disabled
|
rulesContainer.querySelectorAll('.clicd-fw-rule-enabled').forEach(function (toggle, idx) {
|
||||||
rulesContainer.querySelectorAll('.clicd-fw-rule-enabled').forEach(function(toggle, idx) {
|
toggle.addEventListener('change', function () {
|
||||||
toggle.addEventListener('change', function() {
|
|
||||||
var rule = currentRules[idx];
|
var rule = currentRules[idx];
|
||||||
if (!rule) return;
|
if (!rule) return;
|
||||||
rule.enabled = toggle.checked;
|
rule.enabled = toggle.checked;
|
||||||
@@ -273,17 +607,12 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRuleFromItem(item) {
|
|
||||||
var idx = parseInt(item.getAttribute('data-rule-index'), 10);
|
|
||||||
if (isNaN(idx) || !currentRules[idx]) return null;
|
|
||||||
return { index: idx, rule: currentRules[idx] };
|
|
||||||
}
|
|
||||||
|
|
||||||
function getEditField(item, name) {
|
function getEditField(item, name) {
|
||||||
return item.querySelector('[data-field="' + name + '"]');
|
return item.querySelector('[data-field="' + name + '"]');
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateRuleFromFields(item, idx) {
|
function updateRuleFromFields(item, idx) {
|
||||||
|
currentRules[idx].network = getEditField(item, 'network') ? getEditField(item, 'network').value : 'ipv4';
|
||||||
currentRules[idx].direction = getEditField(item, 'direction') ? getEditField(item, 'direction').value : 'in';
|
currentRules[idx].direction = getEditField(item, 'direction') ? getEditField(item, 'direction').value : 'in';
|
||||||
currentRules[idx].protocol = getEditField(item, 'protocol') ? getEditField(item, 'protocol').value : 'tcp';
|
currentRules[idx].protocol = getEditField(item, 'protocol') ? getEditField(item, 'protocol').value : 'tcp';
|
||||||
currentRules[idx].port = getEditField(item, 'port') ? getEditField(item, 'port').value : '';
|
currentRules[idx].port = getEditField(item, 'port') ? getEditField(item, 'port').value : '';
|
||||||
@@ -294,6 +623,8 @@
|
|||||||
|
|
||||||
function getAddRulePayload() {
|
function getAddRulePayload() {
|
||||||
return {
|
return {
|
||||||
|
id: '',
|
||||||
|
network: document.getElementById('clicd-fw-add-network').value,
|
||||||
direction: document.getElementById('clicd-fw-add-direction').value,
|
direction: document.getElementById('clicd-fw-add-direction').value,
|
||||||
protocol: document.getElementById('clicd-fw-add-protocol').value,
|
protocol: document.getElementById('clicd-fw-add-protocol').value,
|
||||||
port: document.getElementById('clicd-fw-add-port').value,
|
port: document.getElementById('clicd-fw-add-port').value,
|
||||||
@@ -305,17 +636,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function clearAddForm() {
|
function clearAddForm() {
|
||||||
|
document.getElementById('clicd-fw-add-network').value = 'ipv4';
|
||||||
document.getElementById('clicd-fw-add-port').value = '';
|
document.getElementById('clicd-fw-add-port').value = '';
|
||||||
document.getElementById('clicd-fw-add-source-ip').value = '';
|
document.getElementById('clicd-fw-add-source-ip').value = '';
|
||||||
document.getElementById('clicd-fw-add-action').value = 'ACCEPT';
|
document.getElementById('clicd-fw-add-action').value = 'ACCEPT';
|
||||||
document.getElementById('clicd-fw-add-desc').value = '';
|
document.getElementById('clicd-fw-add-desc').value = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── FIX: 发 JSON body,走 firewallajax 路由 ──
|
||||||
function saveFirewall() {
|
function saveFirewall() {
|
||||||
var enabled = enabledCheckbox.checked;
|
var enabled = enabledCheckbox.checked;
|
||||||
var rules = currentRules.map(function(r) {
|
var defaultAction = defaultActionSelect.value;
|
||||||
|
var rules = currentRules.map(function (r) {
|
||||||
return {
|
return {
|
||||||
id: r.id || '',
|
id: r.id || '',
|
||||||
|
network: r.network || 'ipv4',
|
||||||
direction: r.direction || 'in',
|
direction: r.direction || 'in',
|
||||||
protocol: r.protocol || 'tcp',
|
protocol: r.protocol || 'tcp',
|
||||||
port: r.port || '',
|
port: r.port || '',
|
||||||
@@ -327,29 +662,30 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
var body = new URLSearchParams();
|
|
||||||
body.set('id', panel.getAttribute('data-service-id') || '');
|
|
||||||
body.set('func', 'firewallUpdate');
|
|
||||||
body.set('enabled', enabled ? 'true' : 'false');
|
|
||||||
body.set('rules', JSON.stringify(rules));
|
|
||||||
|
|
||||||
fetch(endpoint(), {
|
fetch(endpoint(), {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
'Content-Type': 'application/json; charset=UTF-8',
|
||||||
'Authorization': 'JWT {$Think.get.jwt}'
|
'Authorization': 'JWT {$Think.get.jwt}'
|
||||||
},
|
},
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
body: body.toString()
|
body: JSON.stringify({
|
||||||
|
id: serviceId(),
|
||||||
|
func: 'firewallajax',
|
||||||
|
action: 'update',
|
||||||
|
enabled: enabled,
|
||||||
|
default_action: defaultAction,
|
||||||
|
rules: rules
|
||||||
})
|
})
|
||||||
.then(function(res){ return res.text(); })
|
})
|
||||||
.then(function(text){
|
.then(function (res) { return res.text(); })
|
||||||
|
.then(function (text) {
|
||||||
var data;
|
var data;
|
||||||
try { data = JSON.parse(text); } catch(e) { data = {status:'error', msg:'非 JSON 响应: ' + text}; }
|
try { data = JSON.parse(text); } catch (e) { data = { status: 'error', msg: '非 JSON 响应: ' + text }; }
|
||||||
showDebug((data.data && data.data.debug) || data.debug || data);
|
showDebug((data.data && data.data.debug) || data.debug || data);
|
||||||
if (data.status === 200 || data.status === 'success') {
|
if (data.status === 200 || data.status === 'success') {
|
||||||
showMessage('success', data.msg || '防火墙设置已更新');
|
showMessage('success', data.msg || '防火墙设置已更新');
|
||||||
if (data.data && data.data.rules) {
|
if (data.data && Array.isArray(data.data.rules)) {
|
||||||
currentRules = data.data.rules;
|
currentRules = data.data.rules;
|
||||||
renderRules(currentRules);
|
renderRules(currentRules);
|
||||||
}
|
}
|
||||||
@@ -358,38 +694,42 @@
|
|||||||
showMessage('error', data.msg || '更新失败');
|
showMessage('error', data.msg || '更新失败');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function(e){
|
.catch(function (e) {
|
||||||
showMessage('error', e.message || '请求失败');
|
showMessage('error', e.message || '请求失败');
|
||||||
showDebug({error: String(e)});
|
showDebug({ error: String(e) });
|
||||||
})
|
})
|
||||||
.finally(function(){
|
.finally(function () {
|
||||||
setBusy(false);
|
setBusy(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── FIX: 发 JSON body,走 firewallajax 路由 ──
|
||||||
function loadFirewall() {
|
function loadFirewall() {
|
||||||
setBusy(true);
|
setBusy(true);
|
||||||
var body = new URLSearchParams();
|
|
||||||
body.set('id', panel.getAttribute('data-service-id') || '');
|
|
||||||
body.set('func', 'firewallList');
|
|
||||||
|
|
||||||
fetch(endpoint(), {
|
fetch(endpoint(), {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
'Content-Type': 'application/json; charset=UTF-8',
|
||||||
'Authorization': 'JWT {$Think.get.jwt}'
|
'Authorization': 'JWT {$Think.get.jwt}'
|
||||||
},
|
},
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
body: body.toString()
|
body: JSON.stringify({
|
||||||
|
id: serviceId(),
|
||||||
|
func: 'firewallajax',
|
||||||
|
action: 'list'
|
||||||
})
|
})
|
||||||
.then(function(res){ return res.text(); })
|
})
|
||||||
.then(function(text){
|
.then(function (res) { return res.text(); })
|
||||||
|
.then(function (text) {
|
||||||
var data;
|
var data;
|
||||||
try { data = JSON.parse(text); } catch(e) { data = {status:'error', msg:'非 JSON 响应: ' + text}; }
|
try { data = JSON.parse(text); } catch (e) { data = { status: 'error', msg: '非 JSON 响应: ' + text }; }
|
||||||
showDebug((data.data && data.data.debug) || data.debug || data);
|
showDebug((data.data && data.data.debug) || data.debug || data);
|
||||||
if (data.status === 200 || data.status === 'success') {
|
if (data.status === 200 || data.status === 'success') {
|
||||||
if (data.data) {
|
if (data.data) {
|
||||||
enabledCheckbox.checked = data.data.enabled === true || data.data.enabled === 'true' || data.data.enabled === 1;
|
enabledCheckbox.checked = data.data.enabled === true || data.data.enabled === 'true' || data.data.enabled === 1;
|
||||||
|
if (data.data.default_action && defaultActionSelect) {
|
||||||
|
defaultActionSelect.value = data.data.default_action;
|
||||||
|
}
|
||||||
currentRules = Array.isArray(data.data.rules) ? data.data.rules : [];
|
currentRules = Array.isArray(data.data.rules) ? data.data.rules : [];
|
||||||
renderRules(currentRules);
|
renderRules(currentRules);
|
||||||
updateStatusText();
|
updateStatusText();
|
||||||
@@ -399,26 +739,26 @@
|
|||||||
rulesContainer.innerHTML = '<div class="clicd-fw-section clicd-fw-muted">加载失败</div>';
|
rulesContainer.innerHTML = '<div class="clicd-fw-section clicd-fw-muted">加载失败</div>';
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function(e){
|
.catch(function (e) {
|
||||||
showMessage('error', e.message || '请求失败');
|
showMessage('error', e.message || '请求失败');
|
||||||
showDebug({error: String(e)});
|
showDebug({ error: String(e) });
|
||||||
rulesContainer.innerHTML = '<div class="clicd-fw-section clicd-fw-muted">加载失败</div>';
|
rulesContainer.innerHTML = '<div class="clicd-fw-section clicd-fw-muted">加载失败</div>';
|
||||||
})
|
})
|
||||||
.finally(function(){
|
.finally(function () {
|
||||||
setBusy(false);
|
setBusy(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateStatusText() {
|
function updateStatusText() {
|
||||||
if (enabledCheckbox.checked) {
|
if (enabledCheckbox.checked) {
|
||||||
statusText.textContent = '已启用 - 默认拒绝所有流量,仅放行规则中定义的流量';
|
statusText.textContent = '已启用 - 默认' + (defaultActionSelect.value === 'DROP' ? '拒绝' : '放行') + '未匹配流量';
|
||||||
} else {
|
} else {
|
||||||
statusText.textContent = '已禁用 - 所有流量不受限制';
|
statusText.textContent = '已禁用 - 所有流量不受限制';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function openDeleteModal(rule, desc) {
|
function openDeleteModal(idx, desc) {
|
||||||
pendingDeleteRule = rule;
|
pendingDeleteRule = idx;
|
||||||
if (deleteText) {
|
if (deleteText) {
|
||||||
deleteText.textContent = '确认删除规则: ' + (desc || '未命名规则') + ' ?';
|
deleteText.textContent = '确认删除规则: ' + (desc || '未命名规则') + ' ?';
|
||||||
}
|
}
|
||||||
@@ -434,24 +774,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event delegation
|
panel.addEventListener('click', function (event) {
|
||||||
panel.addEventListener('click', function(event) {
|
|
||||||
var button = event.target.closest('[data-clicd-fw-action]');
|
var button = event.target.closest('[data-clicd-fw-action]');
|
||||||
if (!button) return;
|
if (!button) return;
|
||||||
var action = button.getAttribute('data-clicd-fw-action');
|
var action = button.getAttribute('data-clicd-fw-action');
|
||||||
|
|
||||||
if (action === 'add-rule') {
|
if (action === 'add-rule') {
|
||||||
var payload = getAddRulePayload();
|
currentRules.push(getAddRulePayload());
|
||||||
currentRules.push({
|
|
||||||
id: '',
|
|
||||||
direction: payload.direction,
|
|
||||||
protocol: payload.protocol,
|
|
||||||
port: payload.port,
|
|
||||||
source_ip: payload.source_ip,
|
|
||||||
action: payload.action,
|
|
||||||
description: payload.description,
|
|
||||||
enabled: true
|
|
||||||
});
|
|
||||||
renderRules(currentRules);
|
renderRules(currentRules);
|
||||||
clearAddForm();
|
clearAddForm();
|
||||||
saveFirewall();
|
saveFirewall();
|
||||||
@@ -476,7 +805,13 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
enabledCheckbox.addEventListener('change', function() {
|
enabledCheckbox.addEventListener('change', function () {
|
||||||
|
updateStatusText();
|
||||||
|
saveFirewall();
|
||||||
|
});
|
||||||
|
|
||||||
|
defaultActionSelect.addEventListener('change', function () {
|
||||||
|
updateStatusText();
|
||||||
saveFirewall();
|
saveFirewall();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -484,22 +819,23 @@
|
|||||||
deleteCancel.addEventListener('click', closeDeleteModal);
|
deleteCancel.addEventListener('click', closeDeleteModal);
|
||||||
}
|
}
|
||||||
if (deleteModal) {
|
if (deleteModal) {
|
||||||
deleteModal.addEventListener('click', function(event){
|
deleteModal.addEventListener('click', function (event) {
|
||||||
if (event.target === deleteModal) closeDeleteModal();
|
if (event.target === deleteModal) closeDeleteModal();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (deleteConfirm) {
|
if (deleteConfirm) {
|
||||||
deleteConfirm.addEventListener('click', function(){
|
deleteConfirm.addEventListener('click', function () {
|
||||||
if (pendingDeleteRule === null) return;
|
if (pendingDeleteRule === null) return;
|
||||||
var idx = pendingDeleteRule;
|
var idx = pendingDeleteRule;
|
||||||
closeDeleteModal();
|
closeDeleteModal();
|
||||||
if (idx >= 0 && idx < currentRules.length) {
|
if (idx >= 0 && idx < currentRules.length) {
|
||||||
currentRules.splice(idx, 1);
|
currentRules.splice(idx, 1);
|
||||||
|
renderRules(currentRules);
|
||||||
saveFirewall();
|
saveFirewall();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadFirewall();
|
loadFirewall();
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
Reference in New Issue
Block a user