mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
vpc: ilb and other views and buttons
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
parent
1b5c926ea0
commit
058394b78e
@ -119,13 +119,13 @@ export default {
|
|||||||
columns: ['name', 'state', 'displaytext', 'cidr', 'account', 'zonename'],
|
columns: ['name', 'state', 'displaytext', 'cidr', 'account', 'zonename'],
|
||||||
details: ['name', 'id', 'displaytext', 'cidr', 'networkdomain', 'ispersistent', 'redundantvpcrouter', 'restartrequired', 'zonename', 'account', 'domain'],
|
details: ['name', 'id', 'displaytext', 'cidr', 'networkdomain', 'ispersistent', 'redundantvpcrouter', 'restartrequired', 'zonename', 'account', 'domain'],
|
||||||
related: [{
|
related: [{
|
||||||
name: 'publicip',
|
|
||||||
title: 'Public IP Addresses',
|
|
||||||
param: 'vpcid'
|
|
||||||
}, {
|
|
||||||
name: 'privategw',
|
name: 'privategw',
|
||||||
title: 'Private Gateways',
|
title: 'Private Gateways',
|
||||||
param: 'vpcid'
|
param: 'vpcid'
|
||||||
|
}, {
|
||||||
|
name: 'publicip',
|
||||||
|
title: 'Public IP Addresses',
|
||||||
|
param: 'vpcid'
|
||||||
}, {
|
}, {
|
||||||
name: 's2svpn',
|
name: 's2svpn',
|
||||||
title: 'Site-to-Site VPN Gateways',
|
title: 'Site-to-Site VPN Gateways',
|
||||||
@ -151,7 +151,10 @@ export default {
|
|||||||
name: 'details',
|
name: 'details',
|
||||||
component: () => import('@/components/view/DetailsTab.vue')
|
component: () => import('@/components/view/DetailsTab.vue')
|
||||||
}, {
|
}, {
|
||||||
name: 'Tiers',
|
name: 'Router',
|
||||||
|
component: () => import('@/views/network/VpcRouterTab.vue')
|
||||||
|
}, {
|
||||||
|
name: 'Network',
|
||||||
component: () => import('@/views/network/VpcTiersTab.vue')
|
component: () => import('@/views/network/VpcTiersTab.vue')
|
||||||
}],
|
}],
|
||||||
actions: [
|
actions: [
|
||||||
@ -293,7 +296,49 @@ export default {
|
|||||||
permission: ['listPrivateGateways'],
|
permission: ['listPrivateGateways'],
|
||||||
columns: ['ipaddress', 'state', 'gateway', 'netmask', 'account', 'domain'],
|
columns: ['ipaddress', 'state', 'gateway', 'netmask', 'account', 'domain'],
|
||||||
details: ['ipaddress', 'gateway', 'netmask', 'vlan', 'sourcenatsupported', 'aclid', 'account', 'domain', 'zone'],
|
details: ['ipaddress', 'gateway', 'netmask', 'vlan', 'sourcenatsupported', 'aclid', 'account', 'domain', 'zone'],
|
||||||
|
tabs: [{
|
||||||
|
name: 'details',
|
||||||
|
component: () => import('@/components/view/DetailsTab.vue')
|
||||||
|
}, {
|
||||||
|
name: 'Static Routes',
|
||||||
|
component: () => import('@/views/network/StaticRoutesTab.vue'),
|
||||||
|
show: () => true
|
||||||
|
}],
|
||||||
actions: [
|
actions: [
|
||||||
|
{
|
||||||
|
api: 'createPrivateGateway',
|
||||||
|
icon: 'plus',
|
||||||
|
label: 'Add Private Gateway',
|
||||||
|
listView: true,
|
||||||
|
args: ['physicalnetworkid', 'vlan', 'ipaddress', 'gateway', 'netmask', 'sourcenatsupported', 'aclid'],
|
||||||
|
mapping: {
|
||||||
|
aclid: {
|
||||||
|
api: 'listNetworkACLLists'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
api: 'replaceNetworkACLList',
|
||||||
|
icon: 'swap',
|
||||||
|
label: 'Replace ACL List',
|
||||||
|
dataView: true,
|
||||||
|
args: ['aclid', 'gatewayid'],
|
||||||
|
mapping: {
|
||||||
|
aclid: {
|
||||||
|
api: 'listNetworkACLLists',
|
||||||
|
params: (record) => { return { vpcid: record.vpcid } }
|
||||||
|
},
|
||||||
|
gatewayid: {
|
||||||
|
value: (record) => { return record.id }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
api: 'deletePrivateGateway',
|
||||||
|
icon: 'delete',
|
||||||
|
label: 'Delete Private Gateway',
|
||||||
|
dataView: true
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -305,6 +350,19 @@ export default {
|
|||||||
columns: ['publicip', 'account', 'domain'],
|
columns: ['publicip', 'account', 'domain'],
|
||||||
details: ['publicip', 'account', 'domain'],
|
details: ['publicip', 'account', 'domain'],
|
||||||
actions: [
|
actions: [
|
||||||
|
{
|
||||||
|
api: 'createVpnGateway',
|
||||||
|
icon: 'plus',
|
||||||
|
label: 'Create VPN Gateway',
|
||||||
|
listView: true,
|
||||||
|
args: ['vpcid']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
api: 'deleteVpnGateway',
|
||||||
|
icon: 'delete',
|
||||||
|
label: 'Delete VPN Gateway',
|
||||||
|
dataView: true
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -316,6 +374,33 @@ export default {
|
|||||||
columns: ['publicip', 'state', 'gateway', 'ipsecpsk', 'ikepolicy', 'esppolicy'],
|
columns: ['publicip', 'state', 'gateway', 'ipsecpsk', 'ikepolicy', 'esppolicy'],
|
||||||
details: ['publicip', 'gateway', 'passive', 'cidrlist', 'ipsecpsk', 'ikepolicy', 'esppolicy', 'ikelifetime', 'esplifetime', 'dpd', 'forceencap', 'created'],
|
details: ['publicip', 'gateway', 'passive', 'cidrlist', 'ipsecpsk', 'ikepolicy', 'esppolicy', 'ikelifetime', 'esplifetime', 'dpd', 'forceencap', 'created'],
|
||||||
actions: [
|
actions: [
|
||||||
|
{
|
||||||
|
api: 'createVpnConnection',
|
||||||
|
icon: 'plus',
|
||||||
|
label: 'Create VPN Connection',
|
||||||
|
listView: true,
|
||||||
|
args: ['s2scustomergatewayid', 's2svpngatewayid', 'passive'],
|
||||||
|
mapping: {
|
||||||
|
s2scustomergatewayid: {
|
||||||
|
api: 'listVpnCustomerGateways'
|
||||||
|
},
|
||||||
|
s2svpngatewayid: {
|
||||||
|
api: 'listVpnGateways'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
api: 'resetVpnConnection',
|
||||||
|
icon: 'reload',
|
||||||
|
label: 'Reset VPN Connection',
|
||||||
|
dataView: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
api: 'deleteVpnConnection',
|
||||||
|
icon: 'delete',
|
||||||
|
label: 'Delete VPN Connection',
|
||||||
|
dataView: true
|
||||||
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -357,6 +442,44 @@ export default {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'ilb',
|
||||||
|
title: 'Internal LB',
|
||||||
|
icon: 'share-alt',
|
||||||
|
hidden: true,
|
||||||
|
permission: ['listLoadBalancers'],
|
||||||
|
columns: ['name', 'sourceipaddress', 'loadbalancerrule', 'algorithm', 'account', 'domain'],
|
||||||
|
columns: ['name', 'sourceipaddress', 'loadbalancerrule', 'algorithm', 'account', 'domain'],
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
api: 'createLoadBalancer',
|
||||||
|
icon: 'plus',
|
||||||
|
label: 'Add Internal LB',
|
||||||
|
listView: true,
|
||||||
|
args: ['name', 'description', 'sourceipaddress', 'sourceport', 'instanceport', 'algorithm', 'networkid', 'sourceipaddressnetworkid', 'scheme'],
|
||||||
|
mapping: {
|
||||||
|
algorithm: {
|
||||||
|
options: ['source', 'roundrobin', 'leastconn']
|
||||||
|
},
|
||||||
|
scheme: {
|
||||||
|
value: (record) => { return 'Internal' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
api: 'assignToLoadBalancerRule',
|
||||||
|
icon: 'plus',
|
||||||
|
label: 'Assign VMs',
|
||||||
|
dataView: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
api: 'deleteLoadBalancer',
|
||||||
|
icon: 'delete',
|
||||||
|
label: 'Delete LB',
|
||||||
|
dataView: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'vpnuser',
|
name: 'vpnuser',
|
||||||
title: 'VPN Users',
|
title: 'VPN Users',
|
||||||
|
|||||||
@ -147,7 +147,7 @@
|
|||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<a-select-option v-for="(opt, optIndex) in field.opts" :key="optIndex">
|
<a-select-option v-for="(opt, optIndex) in field.opts" :key="optIndex">
|
||||||
{{ opt.name || opt.description || opt.traffictype }}
|
{{ opt.name || opt.description || opt.traffictype || opt.publicip }}
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
83
ui/src/views/network/StaticRoutesTab.vue
Normal file
83
ui/src/views/network/StaticRoutesTab.vue
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
// 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">
|
||||||
|
Static Routes Stub
|
||||||
|
<a-button type="dashed" icon="plus" style="width: 100%" @click="handleOpenModal">Add: button to add static route</a-button>
|
||||||
|
<div v-for="(route, index) in routes" :key="index">
|
||||||
|
{{ route }}
|
||||||
|
</div>
|
||||||
|
</a-spin>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { api } from '@/api'
|
||||||
|
import Status from '@/components/widgets/Status'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'StaticRoutesTab',
|
||||||
|
components: {
|
||||||
|
Status
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
resource: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
routes: [],
|
||||||
|
fetchLoading: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
loading (newData, oldData) {
|
||||||
|
if (!newData && this.resource.id) {
|
||||||
|
this.fetchData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetchData () {
|
||||||
|
this.fetchLoading = true
|
||||||
|
api('listStaticRoutes', { gatewayid: this.resource.id }).then(json => {
|
||||||
|
this.routes = json.liststaticroutesresponse.staticroute
|
||||||
|
}).catch(error => {
|
||||||
|
this.$notification.error({
|
||||||
|
message: 'Request Failed',
|
||||||
|
description: error.response.headers['x-description']
|
||||||
|
})
|
||||||
|
}).finally(() => {
|
||||||
|
this.fetchLoading = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
98
ui/src/views/network/VpcRouterTab.vue
Normal file
98
ui/src/views/network/VpcRouterTab.vue
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
// 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-tabs :animated="false" tabPosition="left">
|
||||||
|
<a-tab-pane tab="Private Gateways" key="pgw" v-if="'listPrivateGateways' in $store.getters.apis">
|
||||||
|
<a-button type="dashed" icon="plus" style="width: 100%">Add Private Gateway</a-button>
|
||||||
|
</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%">Acquire New IP</a-button>
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane tab="S2S VPN Gateway" key="vpngw" v-if="'listVpnGateways' in $store.getters.apis">
|
||||||
|
<a-button type="dashed" icon="plus" style="width: 100%">Create Site-to-Site VPN Gateway</a-button>
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane tab="S2S VPN Connection" key="vpnc" v-if="'listVpnConnections' in $store.getters.apis">
|
||||||
|
<a-button type="dashed" icon="plus" style="width: 100%">Create Site-to-Site VPN Connection</a-button>
|
||||||
|
</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%">Add Network ACL List</a-button>
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane tab="Virtual Routers" key="vr" v-if="'listRouters' in $store.getters.apis">
|
||||||
|
{{ routers }}
|
||||||
|
</a-tab-pane>
|
||||||
|
</a-tabs>
|
||||||
|
</a-spin>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { api } from '@/api'
|
||||||
|
import Status from '@/components/widgets/Status'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'VpcRouterTab',
|
||||||
|
components: {
|
||||||
|
Status
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
resource: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
routers: [],
|
||||||
|
fetchLoading: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.fetchData()
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
loading (newData, oldData) {
|
||||||
|
if (!newData && this.resource.id) {
|
||||||
|
this.fetchData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fetchData () {
|
||||||
|
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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@ -17,12 +17,53 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a-spin :spinning="fetchLoading">
|
<a-spin :spinning="fetchLoading">
|
||||||
<div v-for="(network, index) in networks" :key="index">
|
<a-button type="dashed" icon="plus" style="width: 100%">Add Network</a-button>
|
||||||
|
<a-list class="list">
|
||||||
|
<a-list-item v-for="network in networks" :key="network.id" class="list__item">
|
||||||
|
<div class="list__item-outer-container">
|
||||||
|
<div class="list__item-container">
|
||||||
|
<div class="list__col">
|
||||||
|
<div class="list__label">
|
||||||
<router-link :to="{ path: '/guestnetwork/' + network.id }">{{ network.name }}</router-link>
|
<router-link :to="{ path: '/guestnetwork/' + network.id }">{{ network.name }}</router-link>
|
||||||
{{ network.cidr }}
|
|
||||||
<router-link :to="{ path: '/vm/?vpcid=' + resource.id + '&networkid=' + network.id }">View VMs</router-link>
|
|
||||||
<router-link :to="{ path: '/publicip/?isstaticnat=true' + '&associatednetworkid=' + network.id }">View SNATs</router-link>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div>CIDR: {{ network.cidr }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="list__col">
|
||||||
|
<a-button icon="share-alt">
|
||||||
|
<router-link :to="{ path: '/ilb?networkid=' + network.id }"> Internal LB</router-link>
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
<div class="list__col">
|
||||||
|
<a-button icon="share-alt">
|
||||||
|
<router-link :to="{ path: '/publicip?forloadbalancing=true' + '&associatednetworkid=' + network.id }"> Public LB IP</router-link>
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
<div class="list__col">
|
||||||
|
<a-button icon="environment">
|
||||||
|
<router-link :to="{ path: '/publicip?isstaticnat=true' + '&associatednetworkid=' + network.id }"> Static NATS</router-link>
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
<div class="list__col">
|
||||||
|
<a-button icon="desktop">
|
||||||
|
<router-link :to="{ path: '/vm/?vpcid=' + resource.id + '&networkid=' + network.id }"> VMs</router-link>
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div slot="actions">
|
||||||
|
<a-popconfirm
|
||||||
|
:title="`${$t('label.delete')}?`"
|
||||||
|
@confirm="handleDelete(item)"
|
||||||
|
okText="Yes"
|
||||||
|
cancelText="No"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
|
<a-button icon="delete" type="danger" shape="round"></a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
</div>
|
||||||
|
</a-list-item>
|
||||||
|
</a-list>
|
||||||
|
|
||||||
</a-spin>
|
</a-spin>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -80,5 +121,39 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
.list {
|
||||||
|
|
||||||
|
&__label {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__col {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
@media (min-width: 480px) {
|
||||||
|
&:not(:last-child) {
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
margin-right: -8px;
|
||||||
|
|
||||||
|
&-outer-container {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
@media (min-width: 480px) {
|
||||||
|
flex-direction: row;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user