|
@@ -34,6 +34,16 @@
|
|
|
overflow-y: auto;
|
|
|
}
|
|
|
|
|
|
+ .upstreamEntry.inactive{
|
|
|
+ background-color: #f3f3f3 !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .upstreamEntry{
|
|
|
+ cursor: pointer;
|
|
|
+ border-radius: 0.4em !important;
|
|
|
+ border: 1px solid rgb(233, 233, 233) !important;
|
|
|
+ }
|
|
|
+
|
|
|
@media (max-width: 499px) {
|
|
|
.upstreamActions{
|
|
|
position: relative;
|
|
@@ -66,7 +76,7 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="ui message">
|
|
|
- <i class="ui blue info circle icon"></i> Round-robin load balancing algorithm will be used for upstreams with same priority. Lower priority origin server will be used as fallback when all the higher priority server are offline.
|
|
|
+ <i class="ui blue info circle icon"></i> Round-robin load balancing algorithm will be used for upstreams with same weight. Set weight to 0 for fallback only.
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="ui tab basic segment" data-tab="newupstream">
|
|
@@ -137,29 +147,56 @@
|
|
|
return;
|
|
|
}else{
|
|
|
$("#upstreamTable").html("");
|
|
|
- if (data != undefined){
|
|
|
- console.log(data);
|
|
|
+
|
|
|
+ if (data.ActiveOrigins.length == 0){
|
|
|
+ //There is no upstream for this proxy rule
|
|
|
+ $("#upstreamTable").append(`<tr>
|
|
|
+ <td colspan="2"><b><i class="ui yellow exclamation triangle icon"></i> No Active Upstream Origin</b><br>
|
|
|
+ This HTTP proxy rule will always return Error 521 when requested. To fix this, add or enable a upstream origin to this proxy endpoint.
|
|
|
+ <div class="ui divider"></div>
|
|
|
+ </td>
|
|
|
+ </tr>`);
|
|
|
+ }
|
|
|
+
|
|
|
+ data.ActiveOrigins.forEach(upstream => {
|
|
|
+ renderUpstreamEntryToTable(upstream, true);
|
|
|
+ });
|
|
|
+
|
|
|
+ data.InactiveOrigins.forEach(upstream => {
|
|
|
+ renderUpstreamEntryToTable(upstream, false);
|
|
|
+ });
|
|
|
+
|
|
|
+ let totalUpstreams = data.ActiveOrigins.length + data.InactiveOrigins.length;
|
|
|
+ if (totalUpstreams == 1){
|
|
|
+ $(".lowPriorityButton").addClass('disabled');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (parent && parent.document.getElementById("httpProxyList") != null){
|
|
|
+ //Also update the parent display
|
|
|
+ let element = $(parent.document.getElementById("httpProxyList")).find(".upstreamList.editing");
|
|
|
+ let upstreams = "";
|
|
|
data.ActiveOrigins.forEach(upstream => {
|
|
|
- renderUpstreamEntryToTable(upstream, true);
|
|
|
- });
|
|
|
+ //Check if the upstreams require TLS connections
|
|
|
+ let tlsIcon = "";
|
|
|
+ if (upstream.RequireTLS){
|
|
|
+ tlsIcon = `<i class="green lock icon" title="TLS Mode"></i>`;
|
|
|
+ if (upstream.SkipCertValidations){
|
|
|
+ tlsIcon = `<i class="yellow lock icon" title="TLS/SSL mode without verification"></i>`
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- data.InactiveOrigins.forEach(upstream => {
|
|
|
- renderUpstreamEntryToTable(upstream, false);
|
|
|
+ let upstreamLink = `${upstream.RequireTLS?"https://":"http://"}${upstream.OriginIpOrDomain}`;
|
|
|
+
|
|
|
+ upstreams += `<a href="${upstreamLink}" target="_blank">${upstream.OriginIpOrDomain} ${tlsIcon}</a><br>`;
|
|
|
});
|
|
|
|
|
|
- if (data.ActiveOrigins.length == 1){
|
|
|
- $(".lowPriorityButton").addClass('disabled');
|
|
|
+ if (data.ActiveOrigins.length == 0){
|
|
|
+ upstreams = `<i class="ui yellow exclamation triangle icon"></i> No Active Upstream Origin<br>`
|
|
|
}
|
|
|
-
|
|
|
- $(".ui.checkbox").checkbox();
|
|
|
- }else{
|
|
|
- //Assume no origins
|
|
|
- $("#inlineEditTable").html(`<tr>
|
|
|
- <td colspan="2"><i class="ui red circle times icon"></i> Invalid Upstream Settings</td>
|
|
|
- </tr>`);
|
|
|
+ $(element).html(upstreams);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+ $(".ui.checkbox").checkbox();
|
|
|
}
|
|
|
}
|
|
|
})
|
|
@@ -176,15 +213,15 @@
|
|
|
}
|
|
|
|
|
|
//Priority Arrows
|
|
|
- let upArrowClass = "";
|
|
|
- if (upstream.Priority == 0 ){
|
|
|
- //Cannot go any higher
|
|
|
- upArrowClass = "disabled";
|
|
|
+ let downArrowClass = "";
|
|
|
+ if (upstream.Weight == 0 ){
|
|
|
+ //Cannot go any lower
|
|
|
+ downArrowClass = "disabled";
|
|
|
}
|
|
|
let url = `${upstream.RequireTLS?"https://":"http://"}${upstream.OriginIpOrDomain}`
|
|
|
let payload = encodeURIComponent(JSON.stringify(upstream));
|
|
|
let domUID = newUID();
|
|
|
- $("#upstreamTable").append(`<div class="ui upstreamEntry ${isActive?"":"disabled"} segment" data-domid="${domUID}" data-payload="${payload}" data-priority="${upstream.Priority}">
|
|
|
+ $("#upstreamTable").append(`<div class="ui upstreamEntry ${isActive?"":"inactive"} basic segment" data-domid="${domUID}" data-payload="${payload}" data-priority="${upstream.Priority}">
|
|
|
<h4 class="ui header">
|
|
|
<div class="ui toggle checkbox" style="display:inline-block;">
|
|
|
<input type="checkbox" class="enableState" name="enabled" style="margin-top: 0.4em;" onchange="saveUpstreamUpdate('${domUID}');" ${isActive?"checked":""}>
|
|
@@ -192,7 +229,7 @@
|
|
|
</div>
|
|
|
<div class="content">
|
|
|
<a href="${url}" target="_blank" class="upstreamLink">${upstream.OriginIpOrDomain} ${tlsIcon}</a>
|
|
|
- <div class="sub header">Priority: ${upstream.Priority}</div>
|
|
|
+ <div class="sub header">${isActive?"Active":"Inactive"} | Weight: ${upstream.Weight}x</div>
|
|
|
</div>
|
|
|
</h4>
|
|
|
<div class="advanceOptions" style="display:none;">
|
|
@@ -222,12 +259,12 @@
|
|
|
</div>
|
|
|
<div class="upstreamActions">
|
|
|
<!-- Change Priority -->
|
|
|
- <button class="ui basic circular icon button ${upArrowClass} highPriorityButton" title="Higher Priority"><i class="ui arrow up icon"></i></button>
|
|
|
- <button class="ui basic circular icon button lowPriorityButton" title="Lower Priority"><i class="ui arrow down icon"></i></button>
|
|
|
+ <button class="ui basic circular icon button highPriorityButton" title="Increase Weight"><i class="ui arrow up icon"></i></button>
|
|
|
+ <button class="ui basic circular icon button lowPriorityButton ${downArrowClass}" title="Reduce Weight"><i class="ui arrow down icon"></i></button>
|
|
|
<button class="ui basic circular icon editbtn button" onclick="handleUpstreamOriginEdit('${domUID}');" title="Edit Upstream Destination"><i class="ui grey edit icon"></i></button>
|
|
|
- <button style="display:none;" class="ui basic circular icon savebtn button" onclick="saveUpstreamUpdate('${domUID}');" title="Save New Destination"><i class="ui green save icon"></i></button>
|
|
|
+ <button style="display:none;" class="ui basic circular icon trashbtn button" onclick="removeUpstream('${domUID}');" title="Remove Upstream"><i class="ui red trash icon"></i></button>
|
|
|
+ <button style="display:none;" class="ui basic circular icon savebtn button" onclick="saveUpstreamUpdate('${domUID}');" title="Save Changes"><i class="ui green save icon"></i></button>
|
|
|
<button style="display:none;" class="ui basic circular icon cancelbtn button" onclick="initOriginList();" title="Cancel"><i class="ui grey times icon"></i></button>
|
|
|
- <button style="display:none;" class="ui basic circular icon trashbtn button" title="Remove Upstream"><i class="ui red trash icon"></i></button>
|
|
|
</div>
|
|
|
</div>`);
|
|
|
}
|
|
@@ -400,6 +437,35 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ //Handle removal of an upstream
|
|
|
+ function removeUpstream(domid){
|
|
|
+ let targetDOM = $(`.upstreamEntry[data-domid=${domid}]`);
|
|
|
+ let originalSettings = $(targetDOM).attr("data-payload");
|
|
|
+ originalSettings = JSON.parse(decodeURIComponent(originalSettings));
|
|
|
+ let UpstreamKey = originalSettings.OriginIpOrDomain;
|
|
|
+ if (!confirm("Confirm removing " + UpstreamKey + " from upstream?")){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //Remove the upstream
|
|
|
+ $.ajax({
|
|
|
+ url: "/api/proxy/upstream/remove",
|
|
|
+ method: "POST",
|
|
|
+ data: {
|
|
|
+ ep: editingEndpoint.ep,
|
|
|
+ origin: originalSettings.OriginIpOrDomain, //Original ip or domain as key
|
|
|
+ },
|
|
|
+ success: function(data){
|
|
|
+ if (data.error != undefined){
|
|
|
+ parent.msgbox(data.error, false);
|
|
|
+
|
|
|
+ }else{
|
|
|
+ parent.msgbox("Upstream deleted");
|
|
|
+ initOriginList();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
if (window.location.hash.length > 1){
|
|
|
let payloadHash = window.location.hash.substr(1);
|
|
|
try{
|