diff --git a/src/config/section/network.js b/src/config/section/network.js
index 150aa461d..0ddfc3d19 100644
--- a/src/config/section/network.js
+++ b/src/config/section/network.js
@@ -44,6 +44,10 @@ export default {
name: 'egress.rules',
component: () => import('@/views/network/EgressRulesTab.vue'),
show: (record) => { return record.type === 'Isolated' && !('vpcid' in record) && 'listEgressFirewallRules' in store.getters.apis }
+ }, {
+ name: 'lb.config',
+ component: () => import('@/views/network/LbConfigTab.vue'),
+ show: (record) => { return record.type === 'Isolated' && !('vpcid' in record) && 'listEgressFirewallRules' in store.getters.apis }
}, {
name: 'public.ip.addresses',
component: () => import('@/views/network/IpAddressesTab.vue'),
diff --git a/src/locales/en.json b/src/locales/en.json
index fa54ea1c4..8d3f77b31 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -632,6 +632,7 @@
"label.crosszones": "Cross Zones",
"label.currency": "Currency",
"label.current": "isCurrent",
+"label.currentsslcert": "Current SSL Certificate",
"label.currentpassword": "Current Password",
"label.custom": "Custom",
"label.custom.disk.offering": "Custom Disk Offering",
@@ -1212,6 +1213,11 @@
"label.lb.algorithm.roundrobin": "Round-robin",
"label.lb.algorithm.source": "Source",
"label.lb.cookie": "LbCookie",
+"label.lb.config": "LB Configs",
+"label.lb.configuration": "Configuration",
+"label.lb.config.name": "Lb Config name",
+"label.lb.config.default.value": "Default value",
+"label.lb.config.value": "Value",
"label.lb.protocol.http": "HTTP",
"label.lb.protocol.ssl": "SSL",
"label.lb.protocol.tcp.proxy": "TCP-proxy",
@@ -1966,6 +1972,7 @@
"label.ssh.key.pairs": "SSH Key Pairs",
"label.sshkeypair": "New SSH Key Pair",
"label.sshkeypairs": "SSH keypairs",
+"label.ssl": "SSL",
"label.sslcertificates": "SSL Certificates",
"label.standard.us.keyboard": "Standard (US) keyboard",
"label.start": "Start",
@@ -2443,6 +2450,7 @@
"message.add.ip.range.direct.network": "Add an IP range to direct network in zone ",
"message.add.ip.range.to.pod": "
Add an IP range to pod:
",
"message.add.iprange.processing": "Adding IP Range...",
+"message.add.lbconfig.processing": "Adding new load balancer config",
"message.add.load.balancer": "Add a load balancer to zone",
"message.add.load.balancer.under.ip": "The load balancer rule has been added under IP:",
"message.add.network": "Add a new network for zone: ",
@@ -2832,6 +2840,7 @@
"message.failed.to.add": "Failed to add",
"message.failed.to.assign.vms": "Failed to assign VMs",
"message.failed.to.remove": "Failed to remove",
+"message.failed.to.remove.lbconfig": "Failed to remove load balancer config",
"message.generate.keys": "Please confirm that you would like to generate new keys for this user.",
"message.gslb.delete.confirm": "Please confirm you want to delete this GSLB",
"message.gslb.lb.remove.confirm": "Please confirm you want to remove load balancing from GSLB",
@@ -2993,6 +3002,8 @@
"message.remove.instance.failed": "Failed to remove instance",
"message.remove.instance.processing": "Removing...",
"message.remove.iprange.processing": "Removing IP Range...",
+"message.remove.lbconfig.processing": "Removing load balancer config",
+"message.remove.lbconfig.failed": "Failed to remove Load Balancer Config",
"message.remove.ldap": "Are you sure you want to delete the LDAP configuration?",
"message.remove.nic.processing": "Removing NIC...",
"message.remove.port.forward.failed": "Removing Port Forwarding rule failed",
@@ -3085,6 +3096,7 @@
"message.success.create.keypair": "Successfully created SSH key pair",
"message.success.create.kubernetes.cluter": "Successfully created Kubernetes cluster",
"message.success.create.l2.network": "Successfully created L2 network",
+"message.success.create.lbconfig": "Successfully created load balancer config",
"message.success.create.snapshot.from.vmsnapshot": "Successfully created Snapshot from VM snapshot",
"message.success.create.user": "Successfully created user",
"message.success.create.volume": "Successfully created volume",
@@ -3113,6 +3125,7 @@
"message.success.remove.instance.rule": "Successfully removed instance from rule",
"message.success.remove.ip": "Successfully removed IP",
"message.success.remove.iprange": "Successfully removed IP Range",
+"message.success.remove.lbconfig": "Successfully removed load balancer config",
"message.success.remove.nic": "Successfully removed",
"message.success.remove.port.forward": "Successfully removed Port Forwarding rule",
"message.success.remove.rule": "Successfully deleted rule",
diff --git a/src/views/network/LbConfigTab.vue b/src/views/network/LbConfigTab.vue
new file mode 100644
index 000000000..d64c31f27
--- /dev/null
+++ b/src/views/network/LbConfigTab.vue
@@ -0,0 +1,366 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+
+
+
+
+
+
+
diff --git a/src/views/network/LoadBalancing.vue b/src/views/network/LoadBalancing.vue
index 9e6949b88..962999777 100644
--- a/src/views/network/LoadBalancing.vue
+++ b/src/views/network/LoadBalancing.vue
@@ -50,8 +50,15 @@
{{ $t('label.tcp.proxy') }}
{{ $t('label.tcp') }}
{{ $t('label.udp') }}
+ {{ $t('label.ssl') }}
+
@@ -372,6 +390,125 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ handleDeleteInstanceFromRule(instance, record, ip)" />
+
@@ -394,6 +531,7 @@ export default {
data () {
return {
loading: true,
+ visible: true,
lbRules: [],
newTagsForm: this.$form.createForm(this),
tagsModalVisible: false,
@@ -426,14 +564,43 @@ export default {
publicport: '',
protocol: 'tcp',
virtualmachineid: [],
- vmguestip: []
+ vmguestip: [],
+ sslcert: ''
+ },
+ sslcerts: {
+ loading: false,
+ data: []
},
+ selectedSsl: {
+ name: '',
+ id: null
+ },
+ addSslCertModalVisible: false,
+ showAssignedSsl: false,
addVmModalVisible: false,
addVmModalLoading: false,
addVmModalNicLoading: false,
+ addLbConfigVisible: false,
+ addLbConfigModalLoading: false,
+ currentAccountId: null,
+ assignedSslCert: 'None',
+ buttonVisible: false,
+ deleteSslButtonVisible: true,
+ addSslButtonVisible: true,
+ lbConfig: {
+ scope: 'LoadBalancerRule',
+ name: '',
+ description: null,
+ defaultvalue: null,
+ value: null,
+ forced: 'true'
+ },
vms: [],
nics: [],
+ lbConfigs: [],
+ savedLbConfigs: [],
totalCount: 0,
+ totalCountLbConfig: 0,
page: 1,
pageSize: 10,
columns: [
@@ -465,6 +632,14 @@ export default {
title: this.$t('label.action.configure.stickiness'),
scopedSlots: { customRender: 'stickiness' }
},
+ {
+ title: this.$t('label.lb.configuration'),
+ scopedSlots: { customRender: 'configuration' }
+ },
+ {
+ title: this.$t('label.sslcertificates'),
+ scopedSlots: { customRender: 'sslcert' }
+ },
{
title: this.$t('label.add.vms'),
scopedSlots: { customRender: 'add' }
@@ -474,6 +649,28 @@ export default {
scopedSlots: { customRender: 'actions' }
}
],
+ lbconfigColumns: [
+ {
+ title: this.$t('label.lb.config.name'),
+ dataIndex: 'name'
+ },
+ {
+ title: this.$t('label.description'),
+ dataIndex: 'description'
+ },
+ {
+ title: this.$t('label.lb.config.default.value'),
+ dataIndex: 'defaultvalue'
+ },
+ {
+ title: this.$t('label.lb.config.value'),
+ dataIndex: 'value'
+ },
+ {
+ title: this.$t('label.action'),
+ scopedSlots: { customRender: 'actions' }
+ }
+ ],
tiers: {
loading: false,
data: []
@@ -581,6 +778,139 @@ export default {
this.loading = false
})
},
+ fetchSslCerts () {
+ this.sslcerts.loading = true
+ this.sslcerts.data = []
+ // Firt get the account id
+ api('listAccounts', {
+ name: this.resource.account,
+ domainid: this.resource.domainid
+ }).then(json => {
+ const accounts = json.listaccountsresponse.account || []
+ if (accounts.length > 0) {
+ // Now fetch all the ssl certs for this account
+ this.currentAccountId = accounts[0].id
+ api('listSslCerts', {
+ accountid: this.currentAccountId
+ }).then(json => {
+ if (json.listsslcertsresponse.sslcert && json.listsslcertsresponse.sslcert.length > 0) {
+ this.selectedSsl.name = json.listsslcertsresponse.sslcert[0].name
+ this.selectedSsl.id = json.listsslcertsresponse.sslcert[0].id
+ json.listsslcertsresponse.sslcert.forEach(entry => this.sslcerts.data.push(entry))
+ }
+ }).catch(error => {
+ this.$notifyError(error)
+ })
+ }
+ }).catch(error => {
+ this.$notifyError(error)
+ }).finally(() => {
+ this.sslcerts.loading = false
+ })
+ if (this.selectedRule !== null) {
+ this.getCurrentlyAssignedSslCert()
+ }
+ },
+ getCurrentlyAssignedSslCert () {
+ api('listSslCerts', {
+ accountid: this.currentAccountId,
+ lbruleid: this.selectedRule.id
+ }).then(json => {
+ if (json.listsslcertsresponse.sslcert && json.listsslcertsresponse.sslcert.length > 0) {
+ this.assignedSslCert = json.listsslcertsresponse.sslcert[0].name
+ this.deleteSslButtonVisible = true
+ } else {
+ this.assignedSslCert = 'None'
+ this.deleteSslButtonVisible = false
+ }
+ }).catch(error => {
+ this.$notifyError(error)
+ })
+ },
+ selectssl (e) {
+ this.selectedSsl.id = e
+ },
+ handleAddSslCert (data) {
+ this.addSslCert(data, this.selectedSsl.id)
+ },
+ addSslTolbRule () {
+ this.visible = false
+ this.addSslCert(this.selectedRule.id, this.selectedSsl.id)
+ },
+ addSslCert (lbRuleId, certId) {
+ this.disableSslAddDeleteButtons()
+ api('assignCertToLoadBalancer', {
+ lbruleid: lbRuleId,
+ certid: certId,
+ forced: true
+ }).then(response => {
+ this.$pollJob({
+ jobId: response.assigncerttoloadbalancerresponse.jobid,
+ successMessage: `Successfully assigned Ssl certificate`,
+ successMethod: () => {
+ if (this.selectedRule !== null) {
+ this.getCurrentlyAssignedSslCert()
+ }
+ this.enableSslAddDeleteButtons()
+ },
+ errorMessage: 'Failed to assign ssl certificate',
+ errorMethod: () => {
+ },
+ loadingMessage: `Assigning ssl certificate...`,
+ catchMessage: 'Error encountered while fetching async job result addSslTolbRule',
+ catchMethod: (e) => {
+ this.closeModal()
+ }
+ })
+ }).catch(error => {
+ this.$notifyError(error)
+ }).finally(() => {
+ })
+ },
+ removeSslFromLbRule () {
+ this.disableSslAddDeleteButtons()
+ api('removeCertFromLoadBalancer', {
+ lbruleid: this.selectedRule.id
+ }).then(response => {
+ this.$pollJob({
+ jobId: response.removecertfromloadbalancerresponse.jobid,
+ successMessage: `Successfully removed Ssl certificate`,
+ successMethod: () => {
+ this.visible = true
+ this.getCurrentlyAssignedSslCert()
+ this.enableSslAddDeleteButtons()
+ },
+ errorMessage: 'Failed to remove ssl certificate',
+ errorMethod: () => {
+ this.visible = true
+ },
+ loadingMessage: `Removing ssl certificate...`,
+ catchMessage: 'Error encountered while fetching async job result',
+ catchMethod: () => {
+ this.closeModal()
+ }
+ })
+ }).catch(error => {
+ this.$notifyError(error)
+ }).finally(() => {
+ })
+ },
+ populateValues () {
+ for (let i = 0; i < this.lbConfigs.length; i++) {
+ if (this.lbConfig.name === this.lbConfigs[i].name) {
+ this.lbConfig.description = this.lbConfigs[i].description
+ this.lbConfig.defaultvalue = this.lbConfigs[i].defaultvalue
+ }
+ }
+ },
+ enableSslAddDeleteButtons () {
+ this.deleteSslButtonVisible = true
+ this.addSslButtonVisible = true
+ },
+ disableSslAddDeleteButtons () {
+ this.addSslButtonVisible = false
+ this.deleteSslButtonVisible = false
+ },
fetchLBRuleInstances () {
for (const rule of this.lbRules) {
this.loading = true
@@ -859,6 +1189,32 @@ export default {
handleStickinessMethodSelectChange (e) {
this.stickinessPolicyMethod = e
},
+ handleDeleteLoadBalancerConfig (rule) {
+ this.addLbConfigModalLoading = true
+ api('deleteLoadBalancerConfig', {
+ id: rule.id
+ }).then(response => {
+ this.$pollJob({
+ jobId: response.deleteloadbalancerconfigresponse.jobid,
+ successMessage: `Successfully removed load balancer config`,
+ successMethod: () => {
+ this.fetchSavedLbConfigs()
+ },
+ errorMessage: 'Failed to remove load balancer config',
+ errorMethod: () => {
+ this.fetchSavedLbConfigs()
+ },
+ loadingMessage: `Removing load balancer config...`,
+ catchMessage: 'Error encountered while fetching async job result',
+ catchMethod: () => {
+ this.fetchSavedLbConfigs()
+ }
+ })
+ }).catch(error => {
+ this.$notifyError(error)
+ this.fetchSavedLbConfigs()
+ })
+ },
handleDeleteInstanceFromRule (instance, rule, ip) {
this.loading = true
api('removeFromLoadBalancerRule', {
@@ -966,6 +1322,83 @@ export default {
this.loading = false
})
},
+ handleOpenAddConfiguration () {
+ api('listLoadBalancerConfigs', {
+ listAll: true,
+ scope: 'LoadBalancerRule',
+ loadbalancerid: this.selectedRule.id
+ }).then(response => {
+ this.lbConfigs = response.listloadbalancerconfigsresponse.loadbalancerconfig
+ this.addLbConfigVisible = true
+ const tempLbConfig = response.listloadbalancerconfigsresponse.loadbalancerconfig[0]
+ this.lbConfig.name = tempLbConfig.name
+ this.lbConfig.description = tempLbConfig.description
+ this.lbConfig.defaultvalue = tempLbConfig.defaultvalue
+ }).catch(error => {
+ this.$notifyError(error)
+ this.closeModal()
+ })
+ this.fetchSavedLbConfigs()
+ },
+ handleAddNewLbConfig () {
+ if (!this.lbConfig.value) {
+ this.$refs.lbconfigValue.classList.add('error')
+ return
+ } else {
+ this.$refs.lbconfigValue.classList.remove('error')
+ }
+ this.addLbConfigModalLoading = true
+ api('createLoadBalancerConfig', {
+ scope: 'LoadBalancerRule',
+ name: this.lbConfig.name,
+ value: this.lbConfig.value,
+ forced: 'true',
+ loadbalancerid: this.selectedRule.id
+ }).then(response => {
+ this.$pollJob({
+ jobId: response.createloadbalancerconfigresponse.jobid,
+ successMessage: this.$t('message.success.create.lbconfig'),
+ successMethod: () => {
+ this.fetchSavedLbConfigs()
+ },
+ errorMessage: this.$t('message.failed.to.remove.lbconfig'),
+ errorMethod: () => {
+ this.fetchSavedLbConfigs()
+ },
+ loadingMessage: this.$t('message.add.lbconfig.processing'),
+ catchMessage: this.$t('error.fetching.async.job.result'),
+ catchMethod: () => {
+ this.fetchSavedLbConfigs()
+ }
+ })
+ this.addLbConfigModalLoading = true
+ }).catch(error => {
+ this.$notifyError(error)
+ this.fetchSavedLbConfigs()
+ })
+ this.lbConfig.value = null
+ },
+ fetchSavedLbConfigs () {
+ api('listLoadBalancerConfigs', {
+ scope: 'LoadBalancerRule',
+ loadbalancerid: this.selectedRule.id
+ }).then(response => {
+ this.savedLbConfigs = response.listloadbalancerconfigsresponse.loadbalancerconfig
+ this.totalCountLbConfig = response.listloadbalancerconfigsresponse.count || 0
+ }).catch(error => {
+ this.$notifyError(error)
+ this.loading = false
+ })
+ this.addLbConfigModalLoading = false
+ },
+ handleOpenAddSslCertModal () {
+ this.addSslCertModalVisible = true
+ if (this.selectedRule) {
+ this.showAssignedSsl = true
+ this.buttonVisible = true
+ }
+ this.fetchSslCerts()
+ },
handleOpenAddVMModal () {
if (!this.selectedRule) {
if (!this.newRule.name) {
@@ -1045,7 +1478,6 @@ export default {
},
handleAssignToLBRule (data) {
const vmIDIpMap = {}
-
let count = 0
let innerCount = 0
this.newRule.vmguestip.forEach(ip => {
@@ -1074,6 +1506,9 @@ export default {
successMethod: () => {
this.parentFetchData()
this.parentToggleLoading()
+ if (this.selectedSsl.id !== null) {
+ this.handleAddSslCert(data)
+ }
this.fetchData()
this.closeModal()
},
@@ -1137,6 +1572,11 @@ export default {
this.editRuleModalLoading = false
this.addVmModalLoading = false
this.addVmModalNicLoading = false
+ this.addLbConfigVisible = false
+ this.addSslCertModalVisible = false
+ this.showAssignedSsl = false
+ this.buttonVisible = false
+ this.savedLbConfigs = []
this.vms = []
this.nics = []
this.addVmModalVisible = false