mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 11:52:28 +01:00
network: IP Address and Router Tabs (#152)
Guest network - IP Address and Router Tabs Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com> Co-authored-by: Rohit Yadav <rohit@apache.org>
This commit is contained in:
parent
4cd63a763e
commit
ae50e11888
@ -15,6 +15,8 @@
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
import store from '@/store'
|
||||
|
||||
export default {
|
||||
name: 'network',
|
||||
title: 'Network',
|
||||
@ -29,14 +31,6 @@ export default {
|
||||
columns: ['name', 'state', 'type', 'cidr', 'ip6cidr', 'broadcasturi', 'account', 'zonename'],
|
||||
details: ['name', 'id', 'description', 'type', 'traffictype', 'vpcid', 'vlan', 'broadcasturi', 'cidr', 'ip6cidr', 'netmask', 'gateway', 'ispersistent', 'restartrequired', 'reservediprange', 'redundantrouter', 'networkdomain', 'zonename', 'account', 'domain'],
|
||||
related: [{
|
||||
name: 'publicip',
|
||||
title: 'IP Addresses',
|
||||
param: 'associatednetworkid'
|
||||
}, {
|
||||
name: 'router',
|
||||
title: 'Routers',
|
||||
param: 'networkid'
|
||||
}, {
|
||||
name: 'vm',
|
||||
title: 'Instances',
|
||||
param: 'networkid'
|
||||
@ -47,7 +41,15 @@ export default {
|
||||
}, {
|
||||
name: 'Egress Rules',
|
||||
component: () => import('@/views/network/EgressConfigure.vue'),
|
||||
show: () => true
|
||||
show: (record) => { return record.type === 'Isolated' && 'listEgressFirewallRules' in store.getters.apis }
|
||||
}, {
|
||||
name: 'Public IP Addresses',
|
||||
component: () => import('@/views/network/IpAddressesTab.vue'),
|
||||
show: (record) => { return record.type === 'Isolated' && 'listPublicIpAddresses' in store.getters.apis }
|
||||
}, {
|
||||
name: 'Virtual Routers',
|
||||
component: () => import('@/views/network/RoutersTab.vue'),
|
||||
show: (record) => { return (record.type === 'Isolated' || record.type === 'Shared') && 'listRouters' in store.getters.apis }
|
||||
}],
|
||||
actions: [
|
||||
{
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
"Accounts": "Accounts",
|
||||
"Affinity Groups": "Affinity Groups",
|
||||
"Alerts": "Alerts",
|
||||
"allocated": "Allocated",
|
||||
"cancel": "Cancel",
|
||||
"CPU Sockets": "CPU Sockets",
|
||||
"Cloudian Storage": "Cloudian Storage",
|
||||
|
||||
232
ui/src/views/network/IpAddressesTab.vue
Normal file
232
ui/src/views/network/IpAddressesTab.vue
Normal file
@ -0,0 +1,232 @@
|
||||
// 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.
|
||||
|
||||
<template>
|
||||
<a-spin :spinning="fetchLoading">
|
||||
<a-button type="dashed" icon="plus" style="width: 100%; margin-bottom: 15px" @click="acquireIpAddress">
|
||||
{{ $t("label.acquire.new.ip") }}
|
||||
</a-button>
|
||||
<a-table
|
||||
size="small"
|
||||
style="overflow-y: auto"
|
||||
:columns="columns"
|
||||
:dataSource="ips"
|
||||
:rowKey="item => item.id"
|
||||
:pagination="false" >
|
||||
<template slot="ipaddress" slot-scope="text, record">
|
||||
<router-link :to="{ path: '/publicip/' + record.id }" >{{ text }} </router-link>
|
||||
<a-tag v-if="record.issourcenat === true">source-nat</a-tag>
|
||||
</template>
|
||||
|
||||
<template slot="state" slot-scope="text, record">
|
||||
<status :text="record.state" displayText />
|
||||
</template>
|
||||
|
||||
<template slot="virtualmachineid" slot-scope="text, record">
|
||||
<a-icon type="desktop" v-if="record.virtualmachineid" />
|
||||
<router-link :to="{ path: '/vm/' + record.virtualmachineid }" > {{ record.virtualmachinename || record.virtualmachineid }} </router-link>
|
||||
</template>
|
||||
|
||||
<template slot="action" slot-scope="text, record">
|
||||
<a-button
|
||||
v-if="record.issourcenat !== true"
|
||||
type="danger"
|
||||
icon="delete"
|
||||
shape="circle"
|
||||
@click="releaseIpAddress(record)" />
|
||||
</template>
|
||||
</a-table>
|
||||
<a-divider/>
|
||||
<a-pagination
|
||||
class="row-element pagination"
|
||||
size="small"
|
||||
:current="page"
|
||||
:pageSize="pageSize"
|
||||
:total="totalIps"
|
||||
:showTotal="total => `Total ${total} items`"
|
||||
:pageSizeOptions="['10', '20', '40', '80', '100']"
|
||||
@change="changePage"
|
||||
@showSizeChange="changePageSize"
|
||||
showSizeChanger/>
|
||||
</a-spin>
|
||||
</template>
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import Status from '@/components/widgets/Status'
|
||||
|
||||
export default {
|
||||
name: 'IpAddressesTab',
|
||||
components: {
|
||||
Status
|
||||
},
|
||||
props: {
|
||||
resource: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
totalIps: 0,
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
columns: [
|
||||
{
|
||||
title: this.$t('ipaddress'),
|
||||
dataIndex: 'ipaddress',
|
||||
scopedSlots: { customRender: 'ipaddress' }
|
||||
},
|
||||
{
|
||||
title: this.$t('state'),
|
||||
dataIndex: 'state',
|
||||
scopedSlots: { customRender: 'state' }
|
||||
},
|
||||
{
|
||||
title: this.$t('vm'),
|
||||
dataIndex: 'virtualmachineid',
|
||||
scopedSlots: { customRender: 'virtualmachineid' }
|
||||
},
|
||||
{
|
||||
title: this.$t('Network'),
|
||||
dataIndex: 'associatednetworkname'
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
scopedSlots: { customRender: 'action' }
|
||||
}
|
||||
],
|
||||
fetchLoading: false,
|
||||
ips: [],
|
||||
regions: [],
|
||||
clicked: '',
|
||||
action: {
|
||||
acquire: 'Please confirm that you want to acquire new IP',
|
||||
release: 'Please confirm that you want to release this IP'
|
||||
},
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.fetchData()
|
||||
},
|
||||
watch: {
|
||||
resource: function (newItem, oldItem) {
|
||||
if (!newItem || !newItem.id) {
|
||||
return
|
||||
}
|
||||
this.fetchData()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetchData () {
|
||||
const params = {
|
||||
listall: true,
|
||||
page: this.page,
|
||||
pagesize: this.pageSize
|
||||
}
|
||||
if (this.$route.path.startsWith('/vpc')) {
|
||||
params.vpcid = this.resource.id
|
||||
params.forvirtualnetwork = true
|
||||
} else {
|
||||
params.associatednetworkid = this.resource.id
|
||||
}
|
||||
this.fetchLoading = true
|
||||
api('listPublicIpAddresses', params).then(json => {
|
||||
this.totalIps = json.listpublicipaddressesresponse.count || 0
|
||||
this.ips = json.listpublicipaddressesresponse.publicipaddress || []
|
||||
}).finally(() => {
|
||||
this.fetchLoading = false
|
||||
})
|
||||
},
|
||||
changePage (page, pageSize) {
|
||||
this.page = page
|
||||
this.pageSize = pageSize
|
||||
this.fetchData()
|
||||
},
|
||||
changePageSize (currentPage, pageSize) {
|
||||
this.page = currentPage
|
||||
this.pageSize = pageSize
|
||||
this.fetchData()
|
||||
},
|
||||
acquireIpAddress () {
|
||||
const params = {}
|
||||
if (this.$route.path.startsWith('/vpc')) {
|
||||
params.vpcid = this.resource.id
|
||||
} else {
|
||||
params.networkid = this.resource.id
|
||||
}
|
||||
this.fetchLoading = true
|
||||
api('associateIpAddress', params).then(response => {
|
||||
this.$pollJob({
|
||||
jobId: response.associateipaddressresponse.jobid,
|
||||
successMessage: `Successfully acquired IP for ${this.resource.name}`,
|
||||
successMethod: () => {
|
||||
this.fetchData()
|
||||
},
|
||||
errorMessage: 'Failed to acquire IP',
|
||||
errorMethod: () => {
|
||||
this.fetchData()
|
||||
},
|
||||
loadingMessage: `Acquiring IP for ${this.resource.name} is in progress`,
|
||||
catchMessage: 'Error encountered while fetching async job result'
|
||||
})
|
||||
}).catch(error => {
|
||||
this.fetchLoading = false
|
||||
this.$notification.error({
|
||||
message: `Error ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext,
|
||||
duration: 0
|
||||
})
|
||||
})
|
||||
},
|
||||
releaseIpAddress (ip) {
|
||||
this.fetchLoading = true
|
||||
api('disassociateIpAddress', {
|
||||
id: ip.id
|
||||
}).then(response => {
|
||||
this.$pollJob({
|
||||
jobId: response.disassociateipaddressresponse.jobid,
|
||||
successMessage: 'Successfully released IP',
|
||||
successMethod: () => {
|
||||
this.fetchData()
|
||||
},
|
||||
errorMessage: 'Failed to release IP',
|
||||
errorMethod: () => {
|
||||
this.fetchData()
|
||||
},
|
||||
loadingMessage: `Releasing IP for ${this.resource.name} is in progress`,
|
||||
catchMessage: 'Error encountered while fetching async job result'
|
||||
})
|
||||
}).catch(error => {
|
||||
this.fetchLoading = false
|
||||
this.$notification.error({
|
||||
message: `Error ${error.response.status}`,
|
||||
description: error.response.data.errorresponse.errortext,
|
||||
duration: 0
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
151
ui/src/views/network/RoutersTab.vue
Normal file
151
ui/src/views/network/RoutersTab.vue
Normal file
@ -0,0 +1,151 @@
|
||||
// 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.
|
||||
|
||||
<template>
|
||||
<a-table
|
||||
size="small"
|
||||
style="overflow-y: auto"
|
||||
:columns="columns"
|
||||
:dataSource="routers"
|
||||
:rowKey="item => item.id"
|
||||
:pagination="false"
|
||||
:loading="fetchLoading"
|
||||
>
|
||||
<template slot="name" slot-scope="text,item">
|
||||
<router-link :to="{ path: '/router/' + item.id }" >{{ text }}</router-link>
|
||||
</template>
|
||||
<template slot="status" slot-scope="text, item">
|
||||
<status class="status" :text="item.state" displayText />
|
||||
</template>
|
||||
<template slot="requiresupgrade" slot-scope="text, item">
|
||||
{{ item.requiresupgrade ? $t('Yes') : $t('No') }}
|
||||
</template>
|
||||
<template slot="isredundantrouter" slot-scope="text, record">
|
||||
{{ record.isredundantrouter ? record.redundantstate : record.isredundantrouter }}
|
||||
</template>
|
||||
<template slot="hostname" slot-scope="text, record">
|
||||
<router-link :to="{ path: '/host/' + record.hostid }" >{{ record.hostname || record.hostid }}</router-link>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import Status from '@/components/widgets/Status'
|
||||
|
||||
export default {
|
||||
name: 'RoutersTab',
|
||||
components: {
|
||||
Status
|
||||
},
|
||||
props: {
|
||||
resource: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
fetchLoading: false,
|
||||
routers: [],
|
||||
columns: [
|
||||
{
|
||||
title: this.$t('name'),
|
||||
dataIndex: 'name',
|
||||
scopedSlots: { customRender: 'name' }
|
||||
},
|
||||
{
|
||||
title: this.$t('status'),
|
||||
dataIndex: 'state',
|
||||
scopedSlots: { customRender: 'status' }
|
||||
},
|
||||
{
|
||||
title: this.$t('ip'),
|
||||
dataIndex: 'publicip'
|
||||
},
|
||||
{
|
||||
title: this.$t('version'),
|
||||
dataIndex: 'version'
|
||||
},
|
||||
{
|
||||
title: this.$t('requiresupgrade'),
|
||||
dataIndex: 'requiresupgrade',
|
||||
scopedSlots: { customRender: 'requiresupgrade' }
|
||||
},
|
||||
{
|
||||
title: this.$t('isredundantrouter'),
|
||||
dataIndex: 'isredundantrouter',
|
||||
scopedSlots: { customRender: 'isredundantrouter' }
|
||||
},
|
||||
{
|
||||
title: this.$t('hostname'),
|
||||
dataIndex: 'hostname',
|
||||
scopedSlots: { customRender: 'hostname' }
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.fetchData()
|
||||
},
|
||||
watch: {
|
||||
resource: function (newItem, oldItem) {
|
||||
if (!newItem || !newItem.id) {
|
||||
return
|
||||
}
|
||||
this.fetchData()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetchData () {
|
||||
var params = {
|
||||
listAll: true
|
||||
}
|
||||
if (this.$route.fullPath.startsWith('/vpc')) {
|
||||
params.vpcid = this.resource.id
|
||||
} else {
|
||||
params.networkid = this.resource.id
|
||||
}
|
||||
this.fetchLoading = true
|
||||
api('listRouters', params).then(json => {
|
||||
this.routers = json.listroutersresponse.router || []
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
message: 'Request Failed',
|
||||
description: error.response.headers['x-description'],
|
||||
duration: 0
|
||||
})
|
||||
}).finally(() => {
|
||||
this.fetchLoading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.status {
|
||||
margin-top: -5px;
|
||||
|
||||
&--end {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -28,6 +28,56 @@
|
||||
<a-tab-pane :tab="$t('networks')" key="tier">
|
||||
<VpcTiersTab :resource="resource" :loading="loading" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="Public IP Addresses" key="ip" v-if="'listPublicIpAddresses' in $store.getters.apis">
|
||||
<IpAddressesTab :resource="resource" :loading="loading" />
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="Network ACL Lists" key="acl" v-if="'listNetworkACLLists' in $store.getters.apis">
|
||||
<a-button
|
||||
type="dashed"
|
||||
icon="plus"
|
||||
style="width: 100%"
|
||||
@click="() => handleOpenModals('networkAcl')">
|
||||
Add Network ACL List
|
||||
</a-button>
|
||||
<a-table
|
||||
class="table"
|
||||
size="small"
|
||||
:columns="networkAclsColumns"
|
||||
:dataSource="networkAcls"
|
||||
:rowKey="item => item.id"
|
||||
:pagination="false"
|
||||
>
|
||||
<template slot="name" slot-scope="text, item">
|
||||
<router-link :to="{ path: '/acllist/' + item.id }">
|
||||
{{ text }}
|
||||
</router-link>
|
||||
</template>
|
||||
</a-table>
|
||||
<a-pagination
|
||||
class="row-element pagination"
|
||||
size="small"
|
||||
:current="page"
|
||||
:pageSize="pageSize"
|
||||
:total="itemCounts.networkAcls"
|
||||
:showTotal="total => `Total ${total} items`"
|
||||
:pageSizeOptions="['10', '20', '40', '80', '100']"
|
||||
@change="changePage"
|
||||
@showSizeChange="changePageSize"
|
||||
showSizeChanger/>
|
||||
<a-modal
|
||||
v-model="modals.networkAcl"
|
||||
:title="$t('label.add.acl.list')"
|
||||
@ok="handleNetworkAclFormSubmit">
|
||||
<a-form @submit.prevent="handleNetworkAclFormSubmit" :form="networkAclForm">
|
||||
<a-form-item :label="$t('label.add.list.name')">
|
||||
<a-input v-decorator="['name', {rules: [{ required: true, message: 'Required' }]}]"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('description')">
|
||||
<a-input v-decorator="['description', {rules: [{ required: true, message: 'Required' }]}]"></a-input>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="Private Gateways" key="pgw" v-if="'listPrivateGateways' in $store.getters.apis">
|
||||
<a-button
|
||||
type="dashed"
|
||||
@ -110,49 +160,6 @@
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="Public IP Addresses" key="ip" v-if="'listPublicIpAddresses' in $store.getters.apis">
|
||||
<a-button type="dashed" icon="plus" style="width: 100%" @click="handleAcquireNewIp">Acquire New IP</a-button>
|
||||
<a-table
|
||||
class="table"
|
||||
size="small"
|
||||
:columns="publicIpAddressesColumns"
|
||||
:dataSource="publicIpAddresses"
|
||||
:rowKey="item => item.id"
|
||||
:pagination="false"
|
||||
>
|
||||
<template slot="ipaddress" slot-scope="text, item">
|
||||
<router-link :to="{ path: '/publicip/' + item.id }">
|
||||
{{ text }}
|
||||
<a-tag v-if="item.issourcenat">source-nat</a-tag>
|
||||
<a-tag v-if="item.isstaticnat">static-nat</a-tag>
|
||||
</router-link>
|
||||
</template>
|
||||
<template slot="state" slot-scope="text, item">
|
||||
<status :text="item.state" displayText></status>
|
||||
</template>
|
||||
<template slot="vm" slot-scope="text, item">
|
||||
<router-link :to="{ path: '/vm/' + item.virtualmachineid }">
|
||||
{{ item.virtualmachinedisplayname || item.virtualmachinename }}
|
||||
</router-link>
|
||||
</template>
|
||||
<template slot="network" slot-scope="text, item">
|
||||
<router-link :to="{ path: '/guestnetwork/' + item.associatednetworkid }">
|
||||
{{ item.associatednetworkname }}
|
||||
</router-link>
|
||||
</template>
|
||||
</a-table>
|
||||
<a-pagination
|
||||
class="row-element pagination"
|
||||
size="small"
|
||||
:current="page"
|
||||
:pageSize="pageSize"
|
||||
:total="itemCounts.publicIpAddresses"
|
||||
:showTotal="total => `Total ${total} items`"
|
||||
:pageSizeOptions="['10', '20', '40', '80', '100']"
|
||||
@change="changePage"
|
||||
@showSizeChange="changePageSize"
|
||||
showSizeChanger/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="VPN Gateway" key="vpngw" v-if="'listVpnGateways' in $store.getters.apis">
|
||||
<a-button
|
||||
v-if="vpnGateways.length === 0"
|
||||
@ -229,94 +236,8 @@
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="Network ACL Lists" key="acl" v-if="'listNetworkACLLists' in $store.getters.apis">
|
||||
<a-button
|
||||
type="dashed"
|
||||
icon="plus"
|
||||
style="width: 100%"
|
||||
@click="() => handleOpenModals('networkAcl')">
|
||||
Add Network ACL List
|
||||
</a-button>
|
||||
<a-table
|
||||
class="table"
|
||||
size="small"
|
||||
:columns="networkAclsColumns"
|
||||
:dataSource="networkAcls"
|
||||
:rowKey="item => item.id"
|
||||
:pagination="false"
|
||||
>
|
||||
<template slot="name" slot-scope="text, item">
|
||||
<router-link :to="{ path: '/acllist/' + item.id }">
|
||||
{{ text }}
|
||||
</router-link>
|
||||
</template>
|
||||
</a-table>
|
||||
<a-pagination
|
||||
class="row-element pagination"
|
||||
size="small"
|
||||
:current="page"
|
||||
:pageSize="pageSize"
|
||||
:total="itemCounts.networkAcls"
|
||||
:showTotal="total => `Total ${total} items`"
|
||||
:pageSizeOptions="['10', '20', '40', '80', '100']"
|
||||
@change="changePage"
|
||||
@showSizeChange="changePageSize"
|
||||
showSizeChanger/>
|
||||
<a-modal
|
||||
v-model="modals.networkAcl"
|
||||
:title="$t('label.add.acl.list')"
|
||||
@ok="handleNetworkAclFormSubmit">
|
||||
<a-form @submit.prevent="handleNetworkAclFormSubmit" :form="networkAclForm">
|
||||
<a-form-item :label="$t('label.add.list.name')">
|
||||
<a-input v-decorator="['name', {rules: [{ required: true, message: 'Required' }]}]"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('description')">
|
||||
<a-input v-decorator="['description', {rules: [{ required: true, message: 'Required' }]}]"></a-input>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="Virtual Routers" key="vr" v-if="'listRouters' in $store.getters.apis">
|
||||
<a-list>
|
||||
<a-list-item v-for="item in routers" :key="item.id">
|
||||
<div class="list__item">
|
||||
<div class="list__row">
|
||||
<div class="list__col">
|
||||
<div class="list__label">{{ $t('name') }}</div>
|
||||
<div>
|
||||
<router-link :to="{ path: '/router/' + item.id }">
|
||||
{{ item.name }}
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list__col">
|
||||
<div class="list__label">{{ $t('state') }}</div>
|
||||
<div><status :text="item.state" displayText></status></div>
|
||||
</div>
|
||||
<div class="list__col">
|
||||
<div class="list__label">{{ $t('publicip') }}</div>
|
||||
<div>{{ item.publicip }}</div>
|
||||
</div>
|
||||
<div class="list__col">
|
||||
<div class="list__label">{{ $t('redundantrouter') }}</div>
|
||||
<div>{{ item.isredundantrouter }}</div>
|
||||
</div>
|
||||
<div class="list__col">
|
||||
<div class="list__label">{{ $t('redundantstate') }}</div>
|
||||
<div>{{ item.redundantstate }}</div>
|
||||
</div>
|
||||
<div class="list__col">
|
||||
<div class="list__label">{{ $t('hostname') }}</div>
|
||||
<div>
|
||||
<router-link :to="{ path: '/host/' + item.hostid }">
|
||||
{{ item.hostname }}
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-list-item>
|
||||
</a-list>
|
||||
<RoutersTab :resource="resource" :loading="loading" />
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-spin>
|
||||
@ -324,16 +245,20 @@
|
||||
|
||||
<script>
|
||||
import { api } from '@/api'
|
||||
import { mixinDevice } from '@/utils/mixin.js'
|
||||
import DetailsTab from '@/components/view/DetailsTab'
|
||||
import Status from '@/components/widgets/Status'
|
||||
import IpAddressesTab from './IpAddressesTab'
|
||||
import RoutersTab from './RoutersTab'
|
||||
import VpcTiersTab from './VpcTiersTab'
|
||||
import { mixinDevice } from '@/utils/mixin.js'
|
||||
|
||||
export default {
|
||||
name: 'VpcTab',
|
||||
components: {
|
||||
DetailsTab,
|
||||
Status,
|
||||
IpAddressesTab,
|
||||
RoutersTab,
|
||||
VpcTiersTab
|
||||
},
|
||||
mixins: [mixinDevice],
|
||||
@ -349,10 +274,8 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
routers: [],
|
||||
fetchLoading: false,
|
||||
privateGateways: [],
|
||||
publicIpAddresses: [],
|
||||
vpnGateways: [],
|
||||
vpnConnections: [],
|
||||
networkAcls: [],
|
||||
@ -415,28 +338,6 @@ export default {
|
||||
dataIndex: 'ipsecpsk'
|
||||
}
|
||||
],
|
||||
publicIpAddressesColumns: [
|
||||
{
|
||||
title: this.$t('ip'),
|
||||
dataIndex: 'ipaddress',
|
||||
scopedSlots: { customRender: 'ipaddress' }
|
||||
},
|
||||
{
|
||||
title: this.$t('state'),
|
||||
dataIndex: 'state',
|
||||
scopedSlots: { customRender: 'state' }
|
||||
},
|
||||
{
|
||||
title: this.$t('vm'),
|
||||
dataIndex: 'vm',
|
||||
scopedSlots: { customRender: 'vm' }
|
||||
},
|
||||
{
|
||||
title: this.$t('network'),
|
||||
dataIndex: 'network',
|
||||
scopedSlots: { customRender: 'network' }
|
||||
}
|
||||
],
|
||||
networkAclsColumns: [
|
||||
{
|
||||
title: this.$t('name'),
|
||||
@ -450,7 +351,6 @@ export default {
|
||||
],
|
||||
itemCounts: {
|
||||
privateGateways: 0,
|
||||
publicIpAddresses: 0,
|
||||
vpnConnections: 0,
|
||||
networkAcls: 0
|
||||
},
|
||||
@ -486,9 +386,6 @@ export default {
|
||||
case 'pgw':
|
||||
this.fetchPrivateGateways()
|
||||
break
|
||||
case 'ip':
|
||||
this.fetchPublicIpAddresses()
|
||||
break
|
||||
case 'vpngw':
|
||||
this.fetchVpnGateways()
|
||||
break
|
||||
@ -498,24 +395,8 @@ export default {
|
||||
case 'acl':
|
||||
this.fetchAclList()
|
||||
break
|
||||
case 'vr':
|
||||
this.fetchRouters()
|
||||
break
|
||||
}
|
||||
},
|
||||
fetchRouters () {
|
||||
this.fetchLoading = true
|
||||
api('listRouters', { vpcid: this.resource.id, listAll: true }).then(json => {
|
||||
this.routers = json.listroutersresponse.router
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
message: 'Request Failed',
|
||||
description: error.response.headers['x-description']
|
||||
})
|
||||
}).finally(() => {
|
||||
this.fetchLoading = false
|
||||
})
|
||||
},
|
||||
fetchPrivateGateways () {
|
||||
this.fetchLoading = true
|
||||
api('listPrivateGateways', {
|
||||
@ -535,26 +416,6 @@ export default {
|
||||
this.fetchLoading = false
|
||||
})
|
||||
},
|
||||
fetchPublicIpAddresses () {
|
||||
this.fetchLoading = true
|
||||
api('listPublicIpAddresses', {
|
||||
vpcid: this.resource.id,
|
||||
listAll: true,
|
||||
page: this.page,
|
||||
pagesize: this.pageSize,
|
||||
forvirtualnetwork: true
|
||||
}).then(json => {
|
||||
this.publicIpAddresses = json.listpublicipaddressesresponse.publicipaddress
|
||||
this.itemCounts.publicIpAddresses = json.listpublicipaddressesresponse.count
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
message: 'Request Failed',
|
||||
description: error.response.headers['x-description']
|
||||
})
|
||||
}).finally(() => {
|
||||
this.fetchLoading = false
|
||||
})
|
||||
},
|
||||
fetchVpnGateways () {
|
||||
this.fetchLoading = true
|
||||
api('listVpnGateways', {
|
||||
@ -726,39 +587,6 @@ export default {
|
||||
})
|
||||
})
|
||||
},
|
||||
handleAcquireNewIp () {
|
||||
this.fetchLoading = true
|
||||
api('associateIpAddress', { vpcid: this.resource.id }).then(response => {
|
||||
this.$store.dispatch('AddAsyncJob', {
|
||||
title: `Successfully acquired new IP`,
|
||||
jobid: response.associateipaddressresponse.jobid,
|
||||
status: 'progress'
|
||||
})
|
||||
this.$pollJob({
|
||||
jobId: response.associateipaddressresponse.jobid,
|
||||
successMethod: () => {
|
||||
this.fetchPublicIpAddresses()
|
||||
},
|
||||
errorMessage: 'Failed to acquire new IP',
|
||||
errorMethod: () => {
|
||||
this.fetchPublicIpAddresses()
|
||||
},
|
||||
loadingMessage: `Acquiring new IP...`,
|
||||
catchMessage: 'Error encountered while fetching async job result',
|
||||
catchMethod: () => {
|
||||
this.fetchPublicIpAddresses()
|
||||
}
|
||||
})
|
||||
}).catch(error => {
|
||||
this.$notification.error({
|
||||
message: 'Request Failed',
|
||||
description: error.response.headers['x-description']
|
||||
})
|
||||
}).finally(() => {
|
||||
this.fetchLoading = false
|
||||
this.fetchPublicIpAddresses()
|
||||
})
|
||||
},
|
||||
handleVpnConnectionFormSubmit () {
|
||||
this.fetchLoading = true
|
||||
this.modals.vpnConnection = false
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user