You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ro...@apache.org on 2020/01/21 11:04:34 UTC
[cloudstack-primate] branch master updated: network: Static NAT
enable form (#119)
This is an automated email from the ASF dual-hosted git repository.
rohit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack-primate.git
The following commit(s) were added to refs/heads/master by this push:
new 0cb23ed network: Static NAT enable form (#119)
0cb23ed is described below
commit 0cb23ed5a8c1c9c517d2136d5bf12890c529fd8b
Author: Ritchie Vincent <rf...@gmail.com>
AuthorDate: Tue Jan 21 11:04:25 2020 +0000
network: Static NAT enable form (#119)
Add static NAT form for public IP
---
src/components/view/ResourceView.vue | 1 +
src/config/section/network.js | 8 +-
src/views/network/EnableStaticNat.vue | 277 ++++++++++++++++++++++++++++++++++
3 files changed, 280 insertions(+), 6 deletions(-)
diff --git a/src/components/view/ResourceView.vue b/src/components/view/ResourceView.vue
index a1c4bf7..2dc572e 100644
--- a/src/components/view/ResourceView.vue
+++ b/src/components/view/ResourceView.vue
@@ -110,6 +110,7 @@ export default {
},
showHideTab (tab) {
if ('networkServiceFilter' in tab) {
+ if (this.resource.virtualmachineid && tab.name !== 'Firewall') return false
return this.networkService && this.networkService.service &&
tab.networkServiceFilter(this.networkService.service)
} else if ('show' in tab) {
diff --git a/src/config/section/network.js b/src/config/section/network.js
index a2a429a..e1f57cc 100644
--- a/src/config/section/network.js
+++ b/src/config/section/network.js
@@ -260,12 +260,8 @@ export default {
label: 'Enable Static NAT',
dataView: true,
show: (record) => { return !record.virtualmachineid && !record.issourcenat },
- args: ['ipaddressid', 'virtualmachineid', 'vmguestip'],
- mapping: {
- ipaddressid: {
- value: (record) => { return record.id }
- }
- }
+ popup: true,
+ component: () => import('@/views/network/EnableStaticNat.vue')
},
{
api: 'disableStaticNat',
diff --git a/src/views/network/EnableStaticNat.vue b/src/views/network/EnableStaticNat.vue
new file mode 100644
index 0000000..30cbb62
--- /dev/null
+++ b/src/views/network/EnableStaticNat.vue
@@ -0,0 +1,277 @@
+// 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-list class="list" :loading="loading">
+ <div slot="header" class="list__header">
+ <a-input-search
+ placeholder="Search"
+ v-model="searchQuery"
+ @search="fetchData" />
+ </div>
+
+ <a-list-item
+ v-for="vm in vmsList"
+ :key="vm.id"
+ class="list__item"
+ :class="{ 'list__item--selected' : selectedVm && selectedVm.id === vm.id }">
+
+ <div class="list__outer-container">
+ <div class="list__container" @click="() => handleSelectItem(vm)">
+ <div class="list__row">
+ <div class="list__title">{{ $t('name') }}</div>
+ <div>{{ vm.name }}</div>
+ </div>
+ <div class="list__row">
+ <div class="list__title">{{ $t('instancename') }}</div>
+ <div>{{ vm.instancename }}</div>
+ </div>
+ <div class="list__row">
+ <div class="list__title">{{ $t('displayname') }}</div>
+ <div>{{ vm.displayname }}</div>
+ </div>
+ <div class="list__row">
+ <div class="list__title">{{ $t('account') }}</div>
+ <div>{{ vm.account }}</div>
+ </div>
+ <div class="list__row">
+ <div class="list__title">{{ $t('zonenamelabel') }}</div>
+ <div>{{ vm.zonename }}</div>
+ </div>
+ <div class="list__row">
+ <div class="list__title">{{ $t('state') }}</div>
+ <div>{{ vm.state }}</div>
+ </div>
+ <a-radio
+ class="list__radio"
+ :checked="selectedVm && selectedVm.id === vm.id"
+ @change="fetchNics"></a-radio>
+ </div>
+
+ <a-select
+ v-if="nicsList.length && selectedVm && selectedVm.id === vm.id"
+ class="nic-select"
+ :defaultValue="selectedNic.ipaddress">
+ <a-select-option
+ @click="selectedNic = item"
+ v-for="item in nicsList"
+ :key="item.id">
+ {{ item.ipaddress }}
+ </a-select-option>
+ </a-select>
+ </div>
+
+ </a-list-item>
+
+ <div slot="footer" class="list__footer">
+ <a-button @click="handleClose">{{ $t('cancel') }}</a-button>
+ <a-button @click="handleSubmit" type="primary" :disabled="!selectedVm || !selectedNic">{{ $t('ok') }}</a-button>
+ </div>
+
+ </a-list>
+</template>
+
+<script>
+import { api } from '@/api'
+
+export default {
+ props: {
+ resource: {
+ type: Object,
+ required: true
+ }
+ },
+ inject: ['parentFetchData'],
+ data () {
+ return {
+ loading: false,
+ vmsList: [],
+ selectedVm: null,
+ nicsList: [],
+ searchQuery: null,
+ selectedNic: null
+ }
+ },
+ mounted () {
+ this.fetchData()
+ },
+ methods: {
+ fetchData () {
+ this.loading = true
+ api('listVirtualMachines', {
+ page: 1,
+ pageSize: 500,
+ listAll: true,
+ networkid: this.resource.associatednetworkid,
+ account: this.resource.account,
+ domainid: this.resource.domainid,
+ keyword: this.searchQuery
+ }).then(response => {
+ this.vmsList = response.listvirtualmachinesresponse.virtualmachine
+ this.loading = false
+ }).catch(error => {
+ this.$notification.error({
+ message: `Error ${error.response.status}`,
+ description: error.response.data.errorresponse.errortext
+ })
+ this.loading = false
+ })
+ },
+ fetchNics () {
+ this.loading = true
+ this.nicsList = []
+ api('listNics', {
+ virtualmachineid: this.selectedVm.id,
+ networkid: this.resource.associatednetworkid
+ }).then(response => {
+ this.nicsList = response.listnicsresponse.nic
+
+ let secondaryIps = this.nicsList.map(item => item.secondaryip)
+
+ if (secondaryIps[0]) {
+ secondaryIps = secondaryIps[0]
+ this.nicsList = [...this.nicsList, ...secondaryIps]
+ }
+
+ this.selectedNic = this.nicsList[0]
+ this.loading = false
+ }).catch(error => {
+ this.$notification.error({
+ message: `Error ${error.response.status}`,
+ description: error.response.data.errorresponse.errortext
+ })
+ this.loading = false
+ })
+ },
+ handleSelectItem (vm) {
+ this.selectedVm = vm
+ this.fetchNics()
+ },
+ handleSubmit () {
+ this.loading = true
+ api('enableStaticNat', {
+ ipaddressid: this.resource.id,
+ virtualmachineid: this.selectedVm.id,
+ vmguestip: this.selectedNic.ipaddress
+ }).then(() => {
+ this.parentFetchData()
+ this.loading = false
+ this.handleClose()
+ }).catch(error => {
+ this.$notification.error({
+ message: `Error ${error.response.status}`,
+ description: error.response.data.errorresponse.errortext
+ })
+ this.loading = false
+ this.handleClose()
+ })
+ },
+ handleClose () {
+ this.$parent.$parent.close()
+ }
+ }
+}
+</script>
+
+<style scoped lang="scss">
+
+ .list {
+ max-height: 95vh;
+ width: 95vw;
+ overflow-y: scroll;
+ margin: -24px;
+
+ @media (min-width: 1000px) {
+ max-height: 70vh;
+ width: 60vw;
+ }
+
+ &__header,
+ &__footer {
+ padding-right: 20px;
+ padding-left: 20px;
+ }
+
+ &__footer {
+ display: flex;
+ justify-content: flex-end;
+
+ button {
+ &:not(:last-child) {
+ margin-right: 10px;
+ }
+ }
+ }
+
+ &__item {
+ padding-right: 20px;
+ padding-left: 20px;
+
+ &--selected {
+ background-color: #e6f7ff;
+ }
+
+ }
+
+ &__title {
+ font-weight: bold;
+ }
+
+ &__outer-container {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ }
+
+ &__container {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ cursor: pointer;
+
+ @media (min-width: 760px) {
+ flex-direction: row;
+ align-items: center;
+ }
+
+ }
+
+ &__row {
+ margin-bottom: 10px;
+
+ @media (min-width: 760px) {
+ margin-right: 20px;
+ margin-bottom: 0;
+ }
+ }
+
+ &__radio {
+
+ @media (min-width: 760px) {
+ margin-left: auto;
+ }
+
+ }
+
+ }
+
+ .nic-select {
+ margin-top: 10px;
+ margin-right: auto;
+ min-width: 150px;
+ }
+</style>