vpc: ilb and other views and buttons

Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
Rohit Yadav 2020-01-28 14:25:27 +05:30
parent 1b5c926ea0
commit 058394b78e
5 changed files with 391 additions and 12 deletions

View File

@ -119,13 +119,13 @@ export default {
columns: ['name', 'state', 'displaytext', 'cidr', 'account', 'zonename'],
details: ['name', 'id', 'displaytext', 'cidr', 'networkdomain', 'ispersistent', 'redundantvpcrouter', 'restartrequired', 'zonename', 'account', 'domain'],
related: [{
name: 'publicip',
title: 'Public IP Addresses',
param: 'vpcid'
}, {
name: 'privategw',
title: 'Private Gateways',
param: 'vpcid'
}, {
name: 'publicip',
title: 'Public IP Addresses',
param: 'vpcid'
}, {
name: 's2svpn',
title: 'Site-to-Site VPN Gateways',
@ -151,7 +151,10 @@ export default {
name: 'details',
component: () => import('@/components/view/DetailsTab.vue')
}, {
name: 'Tiers',
name: 'Router',
component: () => import('@/views/network/VpcRouterTab.vue')
}, {
name: 'Network',
component: () => import('@/views/network/VpcTiersTab.vue')
}],
actions: [
@ -293,7 +296,49 @@ export default {
permission: ['listPrivateGateways'],
columns: ['ipaddress', 'state', 'gateway', 'netmask', 'account', 'domain'],
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: [
{
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'],
details: ['publicip', 'account', 'domain'],
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'],
details: ['publicip', 'gateway', 'passive', 'cidrlist', 'ipsecpsk', 'ikepolicy', 'esppolicy', 'ikelifetime', 'esplifetime', 'dpd', 'forceencap', 'created'],
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',
title: 'VPN Users',

View File

@ -147,7 +147,7 @@
}"
>
<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>
</span>

View 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>

View 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>

View File

@ -17,12 +17,53 @@
<template>
<a-spin :spinning="fetchLoading">
<div v-for="(network, index) in networks" :key="index">
<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>
<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>
</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>
</template>
@ -80,5 +121,39 @@ export default {
</script>
<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>