Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
authorMHSanaei <ho3ein.sanaei@gmail.com>2024-03-13 11:45:59 +0300
committerMHSanaei <ho3ein.sanaei@gmail.com>2024-03-13 11:45:59 +0300
commit1e2be1042923e42a7da5c421615c78b944bdd59a (patch)
tree9b99344c74302835ad4ea9acb49fa9875faf7e50 /web
parent569c9428fb7924fb693605385f745e4bf524dc20 (diff)
BurstObservatory & Observatory
Co-Authored-By: Alireza Ahmadi <alireza7@gmail.com>
Diffstat (limited to 'web')
-rw-r--r--web/html/xui/form/client.html2
-rw-r--r--web/html/xui/xray.html386
2 files changed, 255 insertions, 133 deletions
diff --git a/web/html/xui/form/client.html b/web/html/xui/form/client.html
index b170338c..7bac2185 100644
--- a/web/html/xui/form/client.html
+++ b/web/html/xui/form/client.html
@@ -75,7 +75,7 @@
</template>
<a-input-number v-model="client.limitIp" min="0"></a-input-number>
</a-form-item>
- <a-form-item v-if="app.ipLimitEnable && client.email && isEdit">
+ <a-form-item v-if="client.limitIp > 0 && client.email && isEdit">
<template slot="label">
<a-tooltip>
<template slot="title">
diff --git a/web/html/xui/xray.html b/web/html/xui/xray.html
index 83553656..12b76fc4 100644
--- a/web/html/xui/xray.html
+++ b/web/html/xui/xray.html
@@ -75,7 +75,7 @@
<a-space direction="vertical">
<a-card hoverable style="margin-bottom: .5rem;">
<a-row style="display: flex; flex-wrap: wrap; align-items: center;">
- <a-col :xs="24" :sm="10" style="padding: 4px;">
+ <a-col :xs="24" :sm="8" style="padding: 4px;">
<a-space direction="horizontal">
<a-button type="primary" :disabled="saveBtnDisable" @click="updateXraySetting">{{ i18n "pages.xray.save" }}</a-button>
<a-button type="danger" :disabled="!saveBtnDisable" @click="restartXray">{{ i18n "pages.xray.restart" }}</a-button>
@@ -89,7 +89,7 @@
</a-popover>
</a-space>
</a-col>
- <a-col :xs="24" :sm="14">
+ <a-col :xs="24" :sm="16">
<template>
<div>
<a-back-top :target="() => document.getElementById('content-layout')" visibility-height="200">
@@ -103,13 +103,10 @@
</a-col>
</a-row>
</a-card>
- <a-tabs class="ant-card-dark-box-nohover" default-active-key="tpl-1"
- @change="(activeKey) => { if(activeKey == 'tpl-advanced') this.changeCode(); }"
+ <a-tabs class="ant-card-dark-box-nohover" default-active-key="1"
+ @change="(activeKey) => { this.changePage(activeKey); }"
:class="themeSwitcher.currentTheme">
- <a-tab-pane key="tpl-1" tab='{{ i18n "pages.xray.basicTemplate"}}'>
- <a-space direction="horizontal" style="padding: 20px 20px">
- <a-button type="danger" @click="resetXrayConfigToDefault">{{ i18n "pages.settings.resetDefaultConfig" }}</a-button>
- </a-space>
+ <a-tab-pane key="tpl-basic" tab='{{ i18n "pages.xray.basicTemplate"}}' style="padding-top: 20px;">
<a-collapse>
<a-collapse-panel header='{{ i18n "pages.xray.generalConfigs"}}'>
<a-row :xs="24" :sm="24" :lg="12">
@@ -284,11 +281,14 @@
</template>
<a-button v-else type="primary" icon="cloud" style="margin: 15px 20px;" @click="showWarp()">WARP</a-button>
</a-collapse-panel>
+ <a-collapse-panel header='{{ i18n "pages.settings.resetDefaultConfig"}}'>
+ <a-space direction="horizontal" style="padding: 0 20px">
+ <a-button type="danger" @click="resetXrayConfigToDefault">{{ i18n "pages.settings.resetDefaultConfig" }}</a-button>
+ </a-space>
+ </a-collapse-panel>
</a-collapse>
</a-tab-pane>
- <a-tab-pane key="tpl-2" tab='{{ i18n "pages.xray.Routings"}}' style="padding-top: 20px;">
- <a-alert type="warning" style="margin-bottom: 10px; width: fit-content"
- message='{{ i18n "pages.xray.RoutingsDesc"}}' show-icon></a-alert>
+ <a-tab-pane key="tpl-routing" tab='{{ i18n "pages.xray.Routings"}}' style="padding-top: 20px;">
<a-button type="primary" icon="plus" @click="addRule">{{ i18n "pages.xray.rules.add" }}</a-button>
<a-table-sortable :columns="isMobile ? rulesMobileColumns : rulesColumns" bordered
:row-key="r => r.key"
@@ -410,7 +410,7 @@
</template>
</a-table-sortable>
</a-tab-pane>
- <a-tab-pane key="tpl-3" tab='{{ i18n "pages.xray.Outbounds"}}' style="padding-top: 20px;" force-render="true">
+ <a-tab-pane key="tpl-outbound" tab='{{ i18n "pages.xray.Outbounds"}}' style="padding-top: 20px;" force-render="true">
<a-row>
<a-col :xs="12" :sm="12" :lg="12">
<a-button type="primary" icon="plus" @click="addOutbound()" style="margin-bottom: 10px;">{{ i18n
@@ -478,7 +478,7 @@
</template>
</a-table>
</a-tab-pane>
- <a-tab-pane key="tpl-4" tab='{{ i18n "pages.xray.outbound.reverse"}}' style="padding-top: 20px;" force-render="true">
+ <a-tab-pane key="tpl-reverse" tab='{{ i18n "pages.xray.outbound.reverse"}}' style="padding-top: 20px;" force-render="true">
<a-button type="primary" icon="plus" @click="addReverse()" style="margin-bottom: 10px;">{{ i18n "pages.xray.outbound.addReverse" }}</a-button>
<a-table :columns="reverseColumns" bordered v-if="reverseData.length>0"
:row-key="r => r.key"
@@ -506,9 +506,7 @@
</template>
</a-table>
</a-tab-pane>
- <a-tab-pane key="tpl-5" tab='{{ i18n "pages.xray.Balancers"}}' style="padding-top: 20px;" force-render="true">
- <a-alert type="warning" style="margin-bottom: 10px; width: fit-content"
- message='{{ i18n "pages.xray.balancer.balancerDesc" }}' show-icon></a-alert>
+ <a-tab-pane key="tpl-balancer" tab='{{ i18n "pages.xray.Balancers"}}' style="padding-top: 20px;" force-render="true">
<a-button type="primary" icon="plus" @click="addBalancer()" style="margin-bottom: 10px;">{{ i18n "pages.xray.balancer.addBalancer"}}</a-button>
<a-table :columns="balancerColumns" bordered v-if="balancersData.length>0"
:row-key="r => r.key"
@@ -544,8 +542,19 @@
<a-tag class="info-large-tag" style="margin:1;" v-for="sel in balancer.selector">[[ sel ]]</a-tag>
</template>
</a-table>
+ <a-radio-group
+ v-model="obsSettings"
+ v-if="observatoryEnable || burstObservatoryEnable"
+ @change="changeObsCode"
+ button-style="solid"
+ style="margin: 10px 0;"
+ :size="isMobile ? 'small' : ''">
+ <a-radio-button value="observatory" v-if="observatoryEnable">Observatory</a-radio-button>
+ <a-radio-button value="burstObservatory" v-if="burstObservatoryEnable">Burst Observatory</a-radio-button>
+ </a-radio-group>
+ <textarea style="position:absolute; left: -800px;" id="obsSetting"></textarea>
</a-tab-pane>
- <a-tab-pane key="tpl-6" tab='DNS' style="padding-top: 20px;" force-render="true">
+ <a-tab-pane key="tpl-dns" tab='DNS' style="padding-top: 20px;" force-render="true">
<setting-list-item type="switch" title='{{ i18n "pages.xray.dns.enable" }}' desc='{{ i18n "pages.xray.dns.enableDesc" }}' v-model="enableDNS"></setting-list-item>
<template v-if="enableDNS">
<setting-list-item type="text" title='{{ i18n "pages.xray.dns.tag" }}' desc='{{ i18n "pages.xray.dns.tagDesc" }}' v-model="dnsTag"></setting-list-item>
@@ -696,6 +705,13 @@
{ title: '{{ i18n "pages.xray.outbound.domain"}}', dataIndex: 'domain', align: 'center', width: 50 },
];
+ const balancerColumns = [
+ { title: "#", align: 'center', width: 20, scopedSlots: { customRender: 'action' } },
+ { title: '{{ i18n "pages.xray.balancer.tag"}}', dataIndex: 'tag', align: 'center', width: 50 },
+ { title: '{{ i18n "pages.xray.balancer.balancerStrategy"}}', align: 'center', width: 50, scopedSlots: { customRender: 'strategy' }},
+ { title: '{{ i18n "pages.xray.balancer.balancerSelectors"}}', align: 'center', width: 100, scopedSlots: { customRender: 'selector' }},
+ ];
+
const dnsColumns = [
{ title: "#", align: 'center', width: 20, scopedSlots: { customRender: 'action' } },
{ title: '{{ i18n "pages.xray.outbound.address"}}', align: 'center', width: 50, scopedSlots: { customRender: 'address' } },
@@ -708,13 +724,6 @@
{ title: '{{ i18n "pages.xray.fakedns.poolSize"}}', dataIndex: 'poolSize', align: 'center', width: 50 },
];
- const balancerColumns = [
- { title: "#", align: 'center', width: 20, scopedSlots: { customRender: 'action' } },
- { title: '{{ i18n "pages.xray.balancer.tag"}}', dataIndex: 'tag', align: 'center', width: 50 },
- { title: '{{ i18n "pages.xray.balancer.balancerStrategy"}}', align: 'center', width: 50, scopedSlots: { customRender: 'strategy' }},
- { title: '{{ i18n "pages.xray.balancer.balancerSelectors"}}', align: 'center', width: 100, scopedSlots: { customRender: 'selector' }},
- ];
-
const app = new Vue({
delimiters: ['[[', ']]'],
el: '#app',
@@ -733,6 +742,7 @@
showAlert: false,
isMobile: window.innerWidth <= 768,
advSettings: 'xraySetting',
+ obsSettings: '',
cm: null,
cmOptions: {
lineNumbers: true,
@@ -827,6 +837,22 @@
],
"queryStrategy": "UseIP"
},
+ },
+ defaultObservatory: {
+ subjectSelector: [],
+ probeURL: "http://www.google.com/gen_204",
+ probeInterval: "10m",
+ enableConcurrency: true
+ },
+ defaultBurstObservatory: {
+ subjectSelector: [],
+ pingConfig: {
+ destination: "http://www.google.com/gen_204",
+ interval: "30m",
+ connectivity: "http://connectivitycheck.platform.hicloud.com/generate_204",
+ timeout: "10s",
+ sampling: 2
+ }
}
},
methods: {
@@ -927,6 +953,10 @@
this.saveBtnDisable = true;
}
},
+ changePage(pageKey) {
+ if(pageKey == 'tpl-advanced') this.changeCode();
+ if(pageKey == 'tpl-balancer') this.changeObsCode();
+ },
syncRulesWithOutbound(tag, setting) {
const newTemplateSettings = this.templateSettings;
const haveRules = newTemplateSettings.routing.rules.some((r) => r?.outboundTag === tag);
@@ -1009,6 +1039,23 @@
}
});
},
+ changeObsCode() {
+ if (this.obsSettings == ''){
+ return
+ }
+ if(this.cm != null) {
+ this.cm.toTextArea();
+ }
+ textAreaObj = document.getElementById('obsSetting');
+ textAreaObj.value = this[this.obsSettings];
+ this.cm = CodeMirror.fromTextArea(textAreaObj, this.cmOptions);
+ this.cm.on('change',editor => {
+ value = editor.getValue();
+ if(this.isJsonString(value)){
+ this[this.obsSettings] = value;
+ }
+ });
+ },
isJsonString(str) {
try {
JSON.parse(str);
@@ -1087,6 +1134,91 @@
outbounds.splice(0, 0, outbounds.splice(index, 1)[0]);
this.outboundSettings = JSON.stringify(outbounds);
},
+ addReverse(){
+ reverseModal.show({
+ title: '{{ i18n "pages.xray.outbound.addReverse"}}',
+ okText: '{{ i18n "pages.xray.outbound.addReverse" }}',
+ confirm: (reverse, rules) => {
+ reverseModal.loading();
+ if(reverse.tag.length > 0){
+ newTemplateSettings = this.templateSettings;
+ if(newTemplateSettings.reverse == undefined) newTemplateSettings.reverse = {};
+ if(newTemplateSettings.reverse[reverse.type+'s'] == undefined) newTemplateSettings.reverse[reverse.type+'s'] = [];
+ newTemplateSettings.reverse[reverse.type+'s'].push({ tag: reverse.tag, domain: reverse.domain });
+ this.templateSettings = newTemplateSettings;
+
+ // Add related rules
+ this.templateSettings.routing.rules.push(...rules);
+ this.routingRuleSettings = JSON.stringify(this.templateSettings.routing.rules);
+ }
+ reverseModal.close();
+ },
+ isEdit: false
+ });
+ },
+ editReverse(index){
+ if(this.reverseData[index].type == "bridge") {
+ oldRules = this.templateSettings.routing.rules.filter(r => r.inboundTag && r.inboundTag[0] == this.reverseData[index].tag);
+ } else {
+ oldRules = this.templateSettings.routing.rules.filter(r => r.outboundTag && r.outboundTag == this.reverseData[index].tag);
+ }
+ reverseModal.show({
+ title: '{{ i18n "pages.xray.outbound.editReverse"}} ' + (index+1),
+ reverse: this.reverseData[index],
+ rules: oldRules,
+ confirm: (reverse, rules) => {
+ reverseModal.loading();
+ if(reverse.tag.length > 0){
+ oldData = this.reverseData[index];
+ newTemplateSettings = this.templateSettings;
+ oldReverseIndex = newTemplateSettings.reverse[oldData.type+'s'].findIndex(rs => rs.tag == oldData.tag);
+ oldRuleIndex0 = oldRules.length>0 ? newTemplateSettings.routing.rules.findIndex(r => JSON.stringify(r) == JSON.stringify(oldRules[0])) : -1;
+ oldRuleIndex1 = oldRules.length==2 ? newTemplateSettings.routing.rules.findIndex(r => JSON.stringify(r) == JSON.stringify(oldRules[1])) : -1;
+ if(oldData.type == reverse.type){
+ newTemplateSettings.reverse[oldData.type + 's'][oldReverseIndex] = { tag: reverse.tag, domain: reverse.domain };
+ } else {
+ newTemplateSettings.reverse[oldData.type+'s'].splice(oldReverseIndex,1);
+ // delete empty object
+ if(newTemplateSettings.reverse[oldData.type+'s'].length == 0) Reflect.deleteProperty(newTemplateSettings.reverse, oldData.type+'s');
+ // add other type of reverse if it is not exist
+ if(!newTemplateSettings.reverse[reverse.type+'s']) newTemplateSettings.reverse[reverse.type+'s'] = [];
+ newTemplateSettings.reverse[reverse.type+'s'].push({ tag: reverse.tag, domain: reverse.domain });
+ }
+ this.templateSettings = newTemplateSettings;
+
+ // Adjust Rules
+ newRules = this.templateSettings.routing.rules;
+ oldRuleIndex0 != -1 ? newRules[oldRuleIndex0] = rules[0] : newRules.push(rules[0]);
+ oldRuleIndex1 != -1 ? newRules[oldRuleIndex1] = rules[1] : newRules.push(rules[1]);
+ this.routingRuleSettings = JSON.stringify(newRules);
+ }
+ reverseModal.close();
+ },
+ isEdit: true
+ });
+ },
+ deleteReverse(index){
+ oldData = this.reverseData[index];
+ newTemplateSettings = this.templateSettings;
+ reverseTypeObj = newTemplateSettings.reverse[oldData.type+'s'];
+ realIndex = reverseTypeObj.findIndex(r => r.tag==oldData.tag && r.domain==oldData.domain);
+ newTemplateSettings.reverse[oldData.type+'s'].splice(realIndex,1);
+
+ // delete empty objects
+ if(reverseTypeObj.length == 0) Reflect.deleteProperty(newTemplateSettings.reverse, oldData.type+'s');
+ if(Object.keys(newTemplateSettings.reverse).length === 0) Reflect.deleteProperty(newTemplateSettings, 'reverse');
+
+ // delete related routing rules
+ newRules = newTemplateSettings.routing.rules;
+ if(oldData.type == "bridge"){
+ newRules = newTemplateSettings.routing.rules.filter(r => !( r.inboundTag && r.inboundTag.length == 1 && r.inboundTag[0] == oldData.tag));
+ } else if(oldData.type == "portal"){
+ newRules = newTemplateSettings.routing.rules.filter(r => r.outboundTag != oldData.tag);
+ }
+ newTemplateSettings.routing.rules = newRules;
+
+ this.templateSettings = newTemplateSettings;
+ },
async refreshOutboundTraffic() {
if (!this.refreshing) {
this.refreshing = true;
@@ -1133,14 +1265,27 @@
'tag': balancer.tag,
'selector': balancer.selector
};
- if (balancer.strategy === 'roundRobin' || balancer.strategy === 'leastload' || balancer.strategy === 'leastping') {
+ if (balancer.strategy && balancer.strategy != 'random') {
tmpBalancer.strategy = {
'type': balancer.strategy
};
+ if (balancer.strategy == 'leastPing'){
+ if (!newTemplateSettings.observatory)
+ newTemplateSettings.observatory = this.defaultObservatory;
+ if (!newTemplateSettings.observatory.subjectSelector.includes(balancer.tag))
+ newTemplateSettings.observatory.subjectSelector.push(balancer.tag);
+ }
+ if (balancer.strategy == 'leastLoad'){
+ if (!newTemplateSettings.burstObservatory)
+ newTemplateSettings.burstObservatory = this.defaultBurstObservatory;
+ if (!newTemplateSettings.burstObservatory.subjectSelector.includes(balancer.tag))
+ newTemplateSettings.burstObservatory.subjectSelector.push(balancer.tag);
+ }
}
newTemplateSettings.routing.balancers.push(tmpBalancer);
this.templateSettings = newTemplateSettings;
balancerModal.close();
+ this.changeObsCode();
},
isEdit: false
});
@@ -1160,10 +1305,31 @@
'tag': balancer.tag,
'selector': balancer.selector
};
- if (balancer.strategy === 'roundRobin' || balancer.strategy === 'leastload' || balancer.strategy === 'leastping') {
+
+ // Remove old tag
+ if (newTemplateSettings.observatory){
+ newTemplateSettings.observatory.subjectSelector = newTemplateSettings.observatory.subjectSelector.filter(s => s != oldTag);
+ }
+ if (newTemplateSettings.burstObservatory){
+ newTemplateSettings.burstObservatory.subjectSelector = newTemplateSettings.burstObservatory.subjectSelector.filter(s => s != oldTag);
+ }
+
+ if (balancer.strategy && balancer.strategy != 'random') {
tmpBalancer.strategy = {
'type': balancer.strategy
};
+ if (balancer.strategy == 'leastPing'){
+ if (!newTemplateSettings.observatory)
+ newTemplateSettings.observatory = this.defaultObservatory;
+ if (!newTemplateSettings.observatory.subjectSelector.includes(balancer.tag))
+ newTemplateSettings.observatory.subjectSelector.push(balancer.tag);
+ }
+ if (balancer.strategy == 'leastLoad'){
+ if (!newTemplateSettings.burstObservatory)
+ newTemplateSettings.burstObservatory = this.defaultBurstObservatory;
+ if (!newTemplateSettings.burstObservatory.subjectSelector.includes(balancer.tag))
+ newTemplateSettings.burstObservatory.subjectSelector.push(balancer.tag);
+ }
}
newTemplateSettings.routing.balancers[index] = tmpBalancer;
@@ -1177,6 +1343,7 @@
}
this.templateSettings = newTemplateSettings;
balancerModal.close();
+ this.changeObsCode();
},
isEdit: true
});
@@ -1191,6 +1358,14 @@
let realIndex = newTemplateSettings.routing.balancers.findIndex((b) => b.tag === removedBalancer.tag);
newTemplateSettings.routing.balancers.splice(realIndex, 1);
+ // Remove tag from observatory
+ if (newTemplateSettings.observatory){
+ newTemplateSettings.observatory.subjectSelector = newTemplateSettings.observatory.subjectSelector.filter(s => s != removedBalancer.tag);
+ }
+ if (newTemplateSettings.burstObservatory){
+ newTemplateSettings.burstObservatory.subjectSelector = newTemplateSettings.burstObservatory.subjectSelector.filter(s => s != removedBalancer.tag);
+ }
+
// Remove related routing rules
newTemplateSettings.routing.rules.forEach((rule) => {
if (rule.balancerTag === removedBalancer.tag) {
@@ -1203,91 +1378,7 @@
delete newTemplateSettings.routing.balancers;
}
this.templateSettings = newTemplateSettings;
- },
- addReverse(){
- reverseModal.show({
- title: '{{ i18n "pages.xray.outbound.addReverse"}}',
- okText: '{{ i18n "pages.xray.outbound.addReverse" }}',
- confirm: (reverse, rules) => {
- reverseModal.loading();
- if(reverse.tag.length > 0){
- newTemplateSettings = this.templateSettings;
- if(newTemplateSettings.reverse == undefined) newTemplateSettings.reverse = {};
- if(newTemplateSettings.reverse[reverse.type+'s'] == undefined) newTemplateSettings.reverse[reverse.type+'s'] = [];
- newTemplateSettings.reverse[reverse.type+'s'].push({ tag: reverse.tag, domain: reverse.domain });
- this.templateSettings = newTemplateSettings;
-
- // Add related rules
- this.templateSettings.routing.rules.push(...rules);
- this.routingRuleSettings = JSON.stringify(this.templateSettings.routing.rules);
- }
- reverseModal.close();
- },
- isEdit: false
- });
- },
- editReverse(index){
- if(this.reverseData[index].type == "bridge") {
- oldRules = this.templateSettings.routing.rules.filter(r => r.inboundTag && r.inboundTag[0] == this.reverseData[index].tag);
- } else {
- oldRules = this.templateSettings.routing.rules.filter(r => r.outboundTag && r.outboundTag == this.reverseData[index].tag);
- }
- reverseModal.show({
- title: '{{ i18n "pages.xray.outbound.editReverse"}} ' + (index+1),
- reverse: this.reverseData[index],
- rules: oldRules,
- confirm: (reverse, rules) => {
- reverseModal.loading();
- if(reverse.tag.length > 0){
- oldData = this.reverseData[index];
- newTemplateSettings = this.templateSettings;
- oldReverseIndex = newTemplateSettings.reverse[oldData.type+'s'].findIndex(rs => rs.tag == oldData.tag);
- oldRuleIndex0 = oldRules.length>0 ? newTemplateSettings.routing.rules.findIndex(r => JSON.stringify(r) == JSON.stringify(oldRules[0])) : -1;
- oldRuleIndex1 = oldRules.length==2 ? newTemplateSettings.routing.rules.findIndex(r => JSON.stringify(r) == JSON.stringify(oldRules[1])) : -1;
- if(oldData.type == reverse.type){
- newTemplateSettings.reverse[oldData.type + 's'][oldReverseIndex] = { tag: reverse.tag, domain: reverse.domain };
- } else {
- newTemplateSettings.reverse[oldData.type+'s'].splice(oldReverseIndex,1);
- // delete empty object
- if(newTemplateSettings.reverse[oldData.type+'s'].length == 0) Reflect.deleteProperty(newTemplateSettings.reverse, oldData.type+'s');
- // add other type of reverse if it is not exist
- if(!newTemplateSettings.reverse[reverse.type+'s']) newTemplateSettings.reverse[reverse.type+'s'] = [];
- newTemplateSettings.reverse[reverse.type+'s'].push({ tag: reverse.tag, domain: reverse.domain });
- }
- this.templateSettings = newTemplateSettings;
-
- // Adjust Rules
- newRules = this.templateSettings.routing.rules;
- oldRuleIndex0 != -1 ? newRules[oldRuleIndex0] = rules[0] : newRules.push(rules[0]);
- oldRuleIndex1 != -1 ? newRules[oldRuleIndex1] = rules[1] : newRules.push(rules[1]);
- this.routingRuleSettings = JSON.stringify(newRules);
- }
- reverseModal.close();
- },
- isEdit: true
- });
- },
- deleteReverse(index){
- oldData = this.reverseData[index];
- newTemplateSettings = this.templateSettings;
- reverseTypeObj = newTemplateSettings.reverse[oldData.type+'s'];
- realIndex = reverseTypeObj.findIndex(r => r.tag==oldData.tag && r.domain==oldData.domain);
- newTemplateSettings.reverse[oldData.type+'s'].splice(realIndex,1);
-
- // delete empty objects
- if(reverseTypeObj.length == 0) Reflect.deleteProperty(newTemplateSettings.reverse, oldData.type+'s');
- if(Object.keys(newTemplateSettings.reverse).length === 0) Reflect.deleteProperty(newTemplateSettings, 'reverse');
-
- // delete related routing rules
- newRules = newTemplateSettings.routing.rules;
- if(oldData.type == "bridge"){
- newRules = newTemplateSettings.routing.rules.filter(r => !( r.inboundTag && r.inboundTag.length == 1 && r.inboundTag[0] == oldData.tag));
- } else if(oldData.type == "portal"){
- newRules = newTemplateSettings.routing.rules.filter(r => r.outboundTag != oldData.tag);
- }
- newTemplateSettings.routing.rules = newRules;
-
- this.templateSettings = newTemplateSettings;
+ this.changeObsCode()
},
addDNSServer(){
dnsModal.show({
@@ -1479,27 +1570,6 @@
return data;
},
},
- balancersData: {
- get: function () {
- data = []
- if (this.templateSettings != null && this.templateSettings.routing != null && this.templateSettings.routing.balancers != null) {
- this.templateSettings.routing.balancers.forEach((o, index) => {
- let strategy = "random"
- if (o.strategy && (o.strategy.type == "roundRobin" || o.strategy.type == "leastload" || o.strategy.type == "leastping")) {
- strategy = o.strategy.type;
- }
-
- data.push({
- 'key': index,
- 'tag': o.tag ? o.tag : "",
- 'strategy': strategy,
- 'selector': o.selector ? o.selector : []
- });
- });
- }
- return data;
- }
- },
routingRuleSettings: {
get: function () { return this.templateSettings ? JSON.stringify(this.templateSettings.routing.rules, null, 2) : null; },
set: function (newValue) {
@@ -1529,6 +1599,58 @@
return data;
}
},
+ balancersData: {
+ get: function () {
+ data = []
+ if (this.templateSettings != null && this.templateSettings.routing != null && this.templateSettings.routing.balancers != null) {
+ this.templateSettings.routing.balancers.forEach((o, index) => {
+ data.push({
+ 'key': index,
+ 'tag': o.tag ? o.tag : "",
+ 'strategy': o.strategy?.type ?? "random",
+ 'selector': o.selector ? o.selector : []
+ });
+ });
+ }
+ return data;
+ }
+ },
+ observatory: {
+ get: function () {
+ return this.templateSettings?.observatory ? JSON.stringify(this.templateSettings.observatory, null, 2) : null;
+ },
+ set: function (newValue) {
+ newTemplateSettings = this.templateSettings;
+ newTemplateSettings.observatory = JSON.parse(newValue);
+ this.templateSettings = newTemplateSettings;
+ },
+ },
+ burstObservatory: {
+ get: function () {
+ return this.templateSettings?.burstObservatory ? JSON.stringify(this.templateSettings.burstObservatory, null, 2) : null;
+ },
+ set: function (newValue) {
+ newTemplateSettings = this.templateSettings;
+ newTemplateSettings.burstObservatory = JSON.parse(newValue);
+ this.templateSettings = newTemplateSettings;
+ },
+ },
+ observatoryEnable: {
+ get: function () { return this.templateSettings != null && this.templateSettings.observatory },
+ set: function (v) {
+ newTemplateSettings = this.templateSettings;
+ newTemplateSettings.observatory = v ? this.defaultObservatory : undefined;
+ this.templateSettings = newTemplateSettings;
+ }
+ },
+ burstObservatoryEnable: {
+ get: function () { return this.templateSettings != null && this.templateSettings.burstObservatory },
+ set: function (v) {
+ newTemplateSettings = this.templateSettings;
+ newTemplateSettings.burstObservatory = v ? this.defaultBurstObservatory : undefined;
+ this.templateSettings = newTemplateSettings;
+ }
+ },
freedomStrategy: {
get: function () {
if (!this.templateSettings) return "AsIs";