mirror of https://github.com/apache/cloudstack.git
1390 lines
45 KiB
Vue
1390 lines
45 KiB
Vue
// 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>
|
|
<div>
|
|
<a-spin :spinning="fetchLoading">
|
|
<a-tabs
|
|
:tabPosition="device === 'mobile' ? 'top' : 'left'"
|
|
:animated="false"
|
|
@change="onTabChange">
|
|
<a-tab-pane
|
|
v-for="item in hardcodedNsps"
|
|
:key="item.title">
|
|
<span slot="tab">
|
|
{{ $t(item.title) }}
|
|
<status :text="item.title in nsps ? nsps[item.title].state : $t('label.disabled')" style="margin-bottom: 6px; margin-left: 6px" />
|
|
</span>
|
|
<provider-item
|
|
v-if="tabKey===item.title"
|
|
:loading="loading"
|
|
:itemNsp="item"
|
|
:nsp="nsps[item.title]"
|
|
:resourceId="resource.id"
|
|
:zoneId="resource.zoneid"
|
|
:tabKey="tabKey"/>
|
|
</a-tab-pane>
|
|
</a-tabs>
|
|
</a-spin>
|
|
<div v-if="showFormAction">
|
|
<keep-alive v-if="currentAction.component">
|
|
<a-modal
|
|
:title="$t(currentAction.label)"
|
|
:visible="showFormAction"
|
|
:closable="true"
|
|
:maskClosable="false"
|
|
:cancelText="$t('label.cancel')"
|
|
style="top: 20px;"
|
|
@cancel="onCloseAction"
|
|
:confirmLoading="actionLoading"
|
|
:footer="null"
|
|
centered>
|
|
<component
|
|
:is="currentAction.component"
|
|
:resource="nsp"
|
|
:action="currentAction" />
|
|
</a-modal>
|
|
</keep-alive>
|
|
<a-modal
|
|
v-else
|
|
:title="$t(currentAction.label)"
|
|
:visible="showFormAction"
|
|
:confirmLoading="actionLoading"
|
|
:maskClosable="false"
|
|
:okText="$t('label.ok')"
|
|
:cancelText="$t('label.cancel')"
|
|
style="top: 20px;"
|
|
@ok="handleSubmit"
|
|
@cancel="onCloseAction"
|
|
centered
|
|
>
|
|
<a-form
|
|
:form="form"
|
|
layout="vertical">
|
|
<a-form-item
|
|
v-for="(field, index) in currentAction.fieldParams"
|
|
:key="index"
|
|
:label="$t('label.' + field.name)">
|
|
<span v-if="field.name==='password'">
|
|
<a-input-password
|
|
:autoFocus="index===0"
|
|
v-decorator="[field.name, {
|
|
rules: [
|
|
{
|
|
required: field.required,
|
|
message: $t('message.error.required.input')
|
|
}
|
|
]
|
|
}]"
|
|
:placeholder="field.description" />
|
|
</span>
|
|
<span v-else-if="field.type==='boolean'">
|
|
<a-switch
|
|
:autoFocus="index===0"
|
|
v-decorator="[field.name, {
|
|
rules: [{
|
|
required: field.required,
|
|
message: $t('message.error.required.input')
|
|
}]
|
|
}]"
|
|
:placeholder="field.description"
|
|
/>
|
|
</span>
|
|
<span v-else-if="field.type==='uuid'">
|
|
<a-select
|
|
:autoFocus="index===0"
|
|
v-decorator="[field.name, {
|
|
rules: [{
|
|
required: field.required,
|
|
message: $t('message.error.select')
|
|
}]
|
|
}]"
|
|
:loading="field.loading"
|
|
:placeholder="field.description">
|
|
<a-select-option
|
|
v-for="(opt, idx) in field.opts"
|
|
:key="idx">{{ opt.name || opt.description }}</a-select-option>
|
|
</a-select>
|
|
</span>
|
|
<span v-else>
|
|
<a-input
|
|
:autoFocus="index===0"
|
|
v-decorator="[field.name, {
|
|
rules: [
|
|
{
|
|
required: field.required,
|
|
message: $t('message.error.required.input')
|
|
}
|
|
]
|
|
}]"
|
|
:placeholder="field.description" />
|
|
</span>
|
|
</a-form-item>
|
|
</a-form>
|
|
</a-modal>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import store from '@/store'
|
|
import { api } from '@/api'
|
|
import { mixinDevice } from '@/utils/mixin.js'
|
|
import Status from '@/components/widgets/Status'
|
|
import ProviderItem from '@/views/infra/network/providers/ProviderItem'
|
|
|
|
export default {
|
|
name: 'ServiceProvidersTab',
|
|
components: {
|
|
Status,
|
|
ProviderItem
|
|
},
|
|
mixins: [mixinDevice],
|
|
props: {
|
|
resource: {
|
|
type: Object,
|
|
required: true
|
|
},
|
|
loading: {
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
},
|
|
data () {
|
|
return {
|
|
nsps: {},
|
|
nsp: {},
|
|
fetchLoading: false,
|
|
actionLoading: false,
|
|
showFormAction: false,
|
|
currentAction: {},
|
|
tabKey: 'BaremetalDhcpProvider'
|
|
}
|
|
},
|
|
computed: {
|
|
hardcodedNsps () {
|
|
return [
|
|
{
|
|
title: 'BaremetalDhcpProvider',
|
|
actions: [
|
|
{
|
|
api: 'addBaremetalDhcp',
|
|
listView: true,
|
|
icon: 'plus',
|
|
label: 'label.add.baremetal.dhcp.device',
|
|
args: ['url', 'username', 'password'],
|
|
mapping: {
|
|
dhcpservertype: {
|
|
value: (record) => { return 'DHCPD' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return (record && record.id && record.state === 'Enabled') },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return (record && record.id && record.state === 'Disabled') },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'deleteNetworkServiceProvider',
|
|
listView: true,
|
|
icon: 'poweroff',
|
|
label: 'label.shutdown.provider',
|
|
confirm: 'message.confirm.delete.provider',
|
|
show: (record) => { return record && record.id }
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'servicelist'],
|
|
lists: [
|
|
{
|
|
title: 'label.baremetal.dhcp.devices',
|
|
api: 'listBaremetalDhcp',
|
|
mapping: {
|
|
physicalnetworkid: {
|
|
value: (record) => { return record.physicalnetworkid }
|
|
}
|
|
},
|
|
columns: ['url']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
title: 'BaremetalPxeProvider',
|
|
actions: [
|
|
{
|
|
api: 'addBaremetalPxeKickStartServer',
|
|
listView: true,
|
|
icon: 'plus',
|
|
label: 'label.baremetal.pxe.device',
|
|
args: ['url', 'username', 'password', 'tftpdir'],
|
|
mapping: {
|
|
pxeservertype: {
|
|
value: (record) => { return 'KICK_START' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return (record && record.id && record.state === 'Enabled') },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return (record && record.id && record.state === 'Disabled') },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'deleteNetworkServiceProvider',
|
|
listView: true,
|
|
icon: 'poweroff',
|
|
label: 'label.shutdown.provider',
|
|
confirm: 'message.confirm.delete.provider',
|
|
show: (record) => { return record && record.id }
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'servicelist'],
|
|
lists: [
|
|
{
|
|
title: 'label.baremetal.pxe.devices',
|
|
api: 'listBaremetalPxeServers',
|
|
mapping: {
|
|
physicalnetworkid: {
|
|
value: (record) => { return record.physicalnetworkid }
|
|
}
|
|
},
|
|
columns: ['url']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
title: 'BigSwitchBcf',
|
|
actions: [
|
|
{
|
|
api: 'addBigSwitchBcfDevice',
|
|
listView: true,
|
|
icon: 'plus',
|
|
label: 'label.add.bigswitchbcf.device',
|
|
args: ['hostname', 'username', 'password', 'nat']
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Enabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Disabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'deleteNetworkServiceProvider',
|
|
listView: true,
|
|
icon: 'poweroff',
|
|
label: 'label.shutdown.provider',
|
|
confirm: 'message.confirm.delete.provider',
|
|
show: (record) => { return record && record.id }
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'servicelist'],
|
|
lists: [
|
|
{
|
|
title: 'label.devices',
|
|
api: 'listBigSwitchBcfDevices',
|
|
mapping: {
|
|
physicalnetworkid: {
|
|
value: (record) => { return record.physicalnetworkid }
|
|
}
|
|
},
|
|
columns: ['hostname', 'action']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
title: 'BrocadeVcs',
|
|
actions: [
|
|
{
|
|
api: 'addBrocadeVcsDevice',
|
|
listView: true,
|
|
icon: 'plus',
|
|
label: 'label.add.bigswitchbcf.device',
|
|
args: ['hostname', 'username', 'password']
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Enabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Disabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'deleteNetworkServiceProvider',
|
|
listView: true,
|
|
icon: 'poweroff',
|
|
label: 'label.shutdown.provider',
|
|
confirm: 'message.confirm.delete.provider',
|
|
show: (record) => { return record && record.id }
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'servicelist'],
|
|
lists: [
|
|
{
|
|
title: 'label.devices',
|
|
api: 'listBrocadeVcsDevices',
|
|
mapping: {
|
|
physicalnetworkid: {
|
|
value: (record) => { return record.physicalnetworkid }
|
|
}
|
|
},
|
|
columns: ['hostname', 'action']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
title: 'CiscoVnmc',
|
|
actions: [
|
|
{
|
|
api: 'addCiscoVnmcResource',
|
|
listView: true,
|
|
icon: 'plus',
|
|
label: 'label.add.vnmc.device',
|
|
args: ['hostname', 'username', 'password']
|
|
},
|
|
{
|
|
api: 'addCiscoAsa1000vResource',
|
|
listView: true,
|
|
icon: 'plus-circle',
|
|
label: 'label.add.ciscoasa1000v',
|
|
args: ['hostname', 'insideportprofile', 'clusterid'],
|
|
mapping: {
|
|
zoneid: {
|
|
params: (record) => { return record.zoneid }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Enabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Disabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'deleteNetworkServiceProvider',
|
|
listView: true,
|
|
icon: 'poweroff',
|
|
label: 'label.shutdown.provider',
|
|
confirm: 'message.confirm.delete.provider',
|
|
show: (record) => { return record && record.id }
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'servicelist'],
|
|
lists: [
|
|
{
|
|
title: 'label.list.ciscovnmc',
|
|
api: 'listCiscoVnmcResources',
|
|
mapping: {
|
|
physicalnetworkid: {
|
|
value: (record) => { return record.physicalnetworkid }
|
|
}
|
|
},
|
|
columns: ['resource', 'provider']
|
|
},
|
|
{
|
|
title: 'label.list.ciscoasa1000v',
|
|
api: 'listCiscoAsa1000vResources',
|
|
mapping: {
|
|
physicalnetworkid: {
|
|
value: (record) => { return record.physicalnetworkid }
|
|
}
|
|
},
|
|
columns: ['hostname', 'insideportprofile', 'action']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
title: 'ConfigDrive',
|
|
actions: [
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Enabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Disabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'servicelist', 'physicalnetworkid']
|
|
},
|
|
{
|
|
title: 'F5BigIp',
|
|
actions: [
|
|
{
|
|
api: 'addF5LoadBalancer',
|
|
listView: true,
|
|
icon: 'plus',
|
|
label: 'label.add.f5.device',
|
|
component: () => import('@/views/infra/network/providers/AddF5LoadBalancer.vue')
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Enabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Disabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'deleteNetworkServiceProvider',
|
|
listView: true,
|
|
icon: 'poweroff',
|
|
label: 'label.shutdown.provider',
|
|
confirm: 'message.confirm.delete.provider',
|
|
show: (record) => { return record && record.id }
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'servicelist'],
|
|
lists: [
|
|
{
|
|
title: 'label.devices',
|
|
api: 'listF5LoadBalancers',
|
|
mapping: {
|
|
physicalnetworkid: {
|
|
value: (record) => { return record.physicalnetworkid }
|
|
}
|
|
},
|
|
columns: ['ipaddress', 'lbdevicestate', 'action']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
title: 'GloboDns',
|
|
actions: [
|
|
{
|
|
api: 'addGloboDnsHost',
|
|
listView: true,
|
|
icon: 'plus',
|
|
label: 'label.globo.dns.configuration',
|
|
args: ['url', 'username', 'password']
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Enabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Disabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'deleteNetworkServiceProvider',
|
|
listView: true,
|
|
icon: 'poweroff',
|
|
label: 'label.shutdown.provider',
|
|
confirm: 'message.confirm.delete.provider',
|
|
show: (record) => { return record && record.id }
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'servicelist']
|
|
},
|
|
{
|
|
title: 'InternalLbVm',
|
|
actions: [
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Enabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Disabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'physicalnetworkid', 'destinationphysicalnetworkid', 'servicelist'],
|
|
lists: [
|
|
{
|
|
title: 'label.instances',
|
|
api: 'listInternalLoadBalancerVMs',
|
|
mapping: {
|
|
zoneid: {
|
|
value: (record) => { return record.zoneid }
|
|
}
|
|
},
|
|
columns: ['name', 'zonename', 'type', 'state']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
title: 'JuniperSRX',
|
|
actions: [
|
|
{
|
|
api: 'addSrxFirewall',
|
|
listView: true,
|
|
icon: 'plus',
|
|
label: 'label.add.srx.device',
|
|
component: () => import('@/views/infra/network/providers/AddSrxFirewall.vue')
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Enabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Disabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'deleteNetworkServiceProvider',
|
|
listView: true,
|
|
icon: 'poweroff',
|
|
label: 'label.shutdown.provider',
|
|
confirm: 'message.confirm.delete.provider',
|
|
show: (record) => { return record && record.id }
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'servicelist'],
|
|
lists: [
|
|
{
|
|
title: 'label.devices',
|
|
api: 'listSrxFirewalls',
|
|
mapping: {
|
|
physicalnetworkid: {
|
|
value: (record) => { return record.physicalnetworkid }
|
|
}
|
|
},
|
|
columns: ['ipaddress', 'fwdevicestate', 'action']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
title: 'Netscaler',
|
|
actions: [
|
|
{
|
|
api: 'addNetscalerLoadBalancer',
|
|
icon: 'plus',
|
|
listView: true,
|
|
label: 'label.add.netscaler.device',
|
|
component: () => import('@/views/infra/network/providers/AddNetscalerLoadBalancer.vue')
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Enabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Disabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'deleteNetworkServiceProvider',
|
|
listView: true,
|
|
icon: 'poweroff',
|
|
label: 'label.shutdown.provider',
|
|
confirm: 'message.confirm.delete.provider',
|
|
show: (record) => { return record && record.id }
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'servicelist'],
|
|
lists: [
|
|
{
|
|
title: 'label.devices',
|
|
api: 'listNetscalerLoadBalancers',
|
|
mapping: {
|
|
physicalnetworkid: {
|
|
value: (record) => { return record.physicalnetworkid }
|
|
}
|
|
},
|
|
columns: ['ipaddress', 'lbdevicestate', 'action']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
title: 'NiciraNvp',
|
|
actions: [
|
|
{
|
|
api: 'addNiciraNvpDevice',
|
|
icon: 'plus',
|
|
listView: true,
|
|
label: 'label.add.niciranvp.device',
|
|
component: () => import('@/views/infra/network/providers/AddNiciraNvpDevice.vue')
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Enabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Disabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'deleteNetworkServiceProvider',
|
|
listView: true,
|
|
icon: 'poweroff',
|
|
label: 'label.shutdown.provider',
|
|
confirm: 'message.confirm.delete.provider',
|
|
show: (record) => { return record && record.id }
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'servicelist'],
|
|
lists: [
|
|
{
|
|
title: 'label.devices',
|
|
api: 'listNiciraNvpDevices',
|
|
mapping: {
|
|
physicalnetworkid: {
|
|
value: (record) => { return record.physicalnetworkid }
|
|
}
|
|
},
|
|
columns: ['hostname', 'transportzoneuuid', 'l3gatewayserviceuuid', 'l2gatewayserviceuuid', 'action']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
title: 'Opendaylight',
|
|
actions: [
|
|
{
|
|
api: 'addOpenDaylightController',
|
|
listView: true,
|
|
icon: 'plus',
|
|
label: 'label.add.opendaylight.device',
|
|
args: ['url', 'username', 'password']
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Enabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Disabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'deleteNetworkServiceProvider',
|
|
listView: true,
|
|
icon: 'poweroff',
|
|
label: 'label.shutdown.provider',
|
|
confirm: 'message.confirm.delete.provider',
|
|
show: (record) => { return record && record.id }
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'servicelist'],
|
|
lists: [
|
|
{
|
|
title: 'label.opendaylight.controllers',
|
|
api: 'listOpenDaylightControllers',
|
|
mapping: {
|
|
physicalnetworkid: {
|
|
value: (record) => { return record.physicalnetworkid }
|
|
}
|
|
},
|
|
columns: ['name', 'url', 'username', 'action']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
title: 'Ovs',
|
|
details: ['name', 'state', 'id', 'servicelist'],
|
|
lists: [
|
|
{
|
|
title: 'listOvsElements',
|
|
api: 'listOvsElements',
|
|
mapping: {
|
|
nspid: {
|
|
value: (record) => { return record.id }
|
|
}
|
|
},
|
|
columns: ['account', 'domain', 'enabled', 'project', 'action']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
title: 'PaloAlto',
|
|
actions: [
|
|
{
|
|
api: 'addPaloAltoFirewall',
|
|
listView: true,
|
|
icon: 'plus',
|
|
label: 'label.add.pa.device',
|
|
component: () => import('@/views/infra/network/providers/AddPaloAltoFirewall.vue')
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return (record && record.id && record.state === 'Enabled') },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return (record && record.id && record.state === 'Disabled') },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'deleteNetworkServiceProvider',
|
|
listView: true,
|
|
icon: 'poweroff',
|
|
label: 'label.shutdown.provider',
|
|
confirm: 'message.confirm.delete.provider',
|
|
show: (record) => { return record && record.id }
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'servicelist'],
|
|
lists: [
|
|
{
|
|
title: 'label.devices',
|
|
api: 'listPaloAltoFirewalls',
|
|
mapping: {
|
|
physicalnetworkid: {
|
|
value: (record) => { return record.physicalnetworkid }
|
|
}
|
|
},
|
|
columns: ['ipaddress', 'fwdevicestate', 'type', 'action']
|
|
}
|
|
]
|
|
},
|
|
// {
|
|
// title: 'SecurityGroupProvider',
|
|
// details: ['name', 'state', 'id', 'servicelist'],
|
|
// },
|
|
{
|
|
title: 'VirtualRouter',
|
|
actions: [
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Enabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Disabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'servicelist'],
|
|
lists: [
|
|
{
|
|
title: 'label.instances',
|
|
api: 'listRouters',
|
|
mapping: {
|
|
listAll: {
|
|
value: (record) => { return true }
|
|
},
|
|
zoneid: {
|
|
value: (record) => { return record.zoneid }
|
|
},
|
|
forvpc: {
|
|
value: (record) => { return false }
|
|
}
|
|
},
|
|
columns: ['name', 'state', 'hostname', 'zonename']
|
|
}
|
|
]
|
|
},
|
|
{
|
|
title: 'VpcVirtualRouter',
|
|
actions: [
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'stop',
|
|
listView: true,
|
|
label: 'label.disable.provider',
|
|
confirm: 'message.confirm.disable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Enabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Disabled' }
|
|
}
|
|
}
|
|
},
|
|
{
|
|
api: 'updateNetworkServiceProvider',
|
|
icon: 'play-circle',
|
|
listView: true,
|
|
label: 'label.enable.provider',
|
|
confirm: 'message.confirm.enable.provider',
|
|
show: (record) => { return record && record.id && record.state === 'Disabled' },
|
|
mapping: {
|
|
state: {
|
|
value: (record) => { return 'Enabled' }
|
|
}
|
|
}
|
|
}
|
|
],
|
|
details: ['name', 'state', 'id', 'servicelist'],
|
|
lists: [
|
|
{
|
|
title: 'label.instances',
|
|
api: 'listRouters',
|
|
mapping: {
|
|
forvpc: {
|
|
value: (record) => { return true }
|
|
},
|
|
zoneid: {
|
|
value: (record) => { return record.zoneid }
|
|
},
|
|
listAll: {
|
|
value: () => { return true }
|
|
}
|
|
},
|
|
columns: ['name', 'state', 'hostname', 'zonename']
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
},
|
|
beforeCreate () {
|
|
this.form = this.$form.createForm(this)
|
|
},
|
|
created () {
|
|
this.fetchData()
|
|
},
|
|
watch: {
|
|
loading (newData, oldData) {
|
|
if (!newData && this.resource.id) {
|
|
this.fetchData()
|
|
}
|
|
}
|
|
},
|
|
inject: ['parentPollActionCompletion'],
|
|
provide () {
|
|
return {
|
|
provideSetNsp: this.setNsp,
|
|
provideExecuteAction: this.executeAction,
|
|
provideCloseAction: this.onCloseAction,
|
|
provideReload: this.fetchData
|
|
}
|
|
},
|
|
methods: {
|
|
fetchData () {
|
|
if (!this.resource || !('id' in this.resource)) {
|
|
return
|
|
}
|
|
this.fetchServiceProvider()
|
|
},
|
|
fetchServiceProvider (name) {
|
|
this.fetchLoading = true
|
|
api('listNetworkServiceProviders', { physicalnetworkid: this.resource.id, name: name }).then(json => {
|
|
const sps = json.listnetworkserviceprovidersresponse.networkserviceprovider || []
|
|
if (sps.length > 0) {
|
|
for (const sp of sps) {
|
|
this.nsps[sp.name] = sp
|
|
}
|
|
}
|
|
}).catch(error => {
|
|
this.$notifyError(error)
|
|
}).finally(() => {
|
|
this.fetchLoading = false
|
|
})
|
|
},
|
|
onTabChange (tabKey) {
|
|
this.tabKey = tabKey
|
|
},
|
|
setNsp (nsp) {
|
|
this.nsp = nsp
|
|
},
|
|
async handleSubmit () {
|
|
if (this.currentAction.confirm) {
|
|
await this.executeConfirmAction()
|
|
return
|
|
}
|
|
|
|
await this.form.validateFields(async (err, values) => {
|
|
if (err) {
|
|
return
|
|
}
|
|
const params = {}
|
|
params.physicalnetworkid = this.nsp.physicalnetworkid
|
|
for (const key in values) {
|
|
const input = values[key]
|
|
for (const param of this.currentAction.fieldParams) {
|
|
if (param.name !== key) {
|
|
continue
|
|
}
|
|
if (param.type === 'uuid') {
|
|
params[key] = param.opts[input].id
|
|
} else if (param.type === 'list') {
|
|
params[key] = input.map(e => { return param.opts[e].id }).reduce((str, name) => { return str + ',' + name })
|
|
} else {
|
|
params[key] = input
|
|
}
|
|
}
|
|
}
|
|
if (this.currentAction.mapping) {
|
|
for (const key in this.currentAction.mapping) {
|
|
if (!this.currentAction.mapping[key].value) {
|
|
continue
|
|
}
|
|
params[key] = this.currentAction.mapping[key].value(this.resource, params)
|
|
}
|
|
}
|
|
this.actionLoading = true
|
|
|
|
try {
|
|
if (!this.nsp.id) {
|
|
const serviceParams = {}
|
|
serviceParams.name = this.nsp.name
|
|
serviceParams.physicalnetworkid = this.nsp.physicalnetworkid
|
|
const networkServiceProvider = await this.addNetworkServiceProvider(serviceParams)
|
|
this.nsp = { ...this.nsp, ...networkServiceProvider }
|
|
}
|
|
params.id = this.nsp.id
|
|
const hasJobId = await this.executeApi(this.currentAction.api, params, this.currentAction.method)
|
|
if (!hasJobId) {
|
|
await this.$message.success('Success')
|
|
await this.fetchData()
|
|
}
|
|
this.actionLoading = false
|
|
this.onCloseAction()
|
|
} catch (error) {
|
|
this.actionLoading = false
|
|
this.$notification.error({
|
|
message: this.$t('message.request.failed'),
|
|
description: error
|
|
})
|
|
}
|
|
})
|
|
},
|
|
onCloseAction () {
|
|
this.currentAction = {}
|
|
this.showFormAction = false
|
|
},
|
|
addNetworkServiceProvider (args) {
|
|
return new Promise((resolve, reject) => {
|
|
let message = ''
|
|
api('addNetworkServiceProvider', args).then(async json => {
|
|
const jobId = json.addnetworkserviceproviderresponse.jobid
|
|
if (jobId) {
|
|
const result = await this.pollJob(jobId)
|
|
if (result.jobstatus === 2) {
|
|
message = result.jobresult.errortext
|
|
reject(message)
|
|
return
|
|
}
|
|
resolve(result.jobresult.networkserviceprovider)
|
|
}
|
|
}).catch(error => {
|
|
message = (error.response && error.response.headers && error.response.headers['x-description']) || error.message
|
|
reject(message)
|
|
})
|
|
})
|
|
},
|
|
async pollJob (jobId) {
|
|
return new Promise(resolve => {
|
|
const asyncJobInterval = setInterval(() => {
|
|
api('queryAsyncJobResult', { jobId }).then(async json => {
|
|
const result = json.queryasyncjobresultresponse
|
|
if (result.jobstatus === 0) {
|
|
return
|
|
}
|
|
|
|
clearInterval(asyncJobInterval)
|
|
resolve(result)
|
|
})
|
|
}, 1000)
|
|
})
|
|
},
|
|
executeAction (action) {
|
|
this.currentAction = action
|
|
if (this.currentAction.confirm) {
|
|
this.$confirm({
|
|
title: this.$t('label.confirmation'),
|
|
content: this.$t(action.confirm),
|
|
onOk: this.handleSubmit
|
|
})
|
|
} else {
|
|
this.showFormAction = true
|
|
if (!action.component) {
|
|
const apiParams = store.getters.apis[action.api].params || []
|
|
this.currentAction.fieldParams = action.args.map(arg => {
|
|
const field = apiParams.filter(param => param.name === arg)[0]
|
|
if (field.type === 'uuid') {
|
|
this.listFieldOpts(field)
|
|
}
|
|
return field
|
|
}) || []
|
|
if (this.currentAction.api === 'addCiscoVnmcResource') {
|
|
this.currentAction.method = 'POST'
|
|
}
|
|
}
|
|
}
|
|
},
|
|
listFieldOpts (field) {
|
|
const paramName = field.name
|
|
const params = { listall: true }
|
|
const possibleName = 'list' + paramName.replace('ids', '').replace('id', '').toLowerCase() + 's'
|
|
let possibleApi
|
|
for (const api in store.getters.apis) {
|
|
if (api.toLowerCase().startsWith(possibleName)) {
|
|
possibleApi = api
|
|
break
|
|
}
|
|
}
|
|
if (this.currentAction.mapping) {
|
|
Object.keys(this.currentAction.mapping).forEach(key => {
|
|
if (this.currentAction.mapping[key].params) {
|
|
params[key] = this.currentAction.mapping[key].params(this.resource)
|
|
}
|
|
})
|
|
}
|
|
if (!possibleApi) {
|
|
return
|
|
}
|
|
field.loading = true
|
|
field.opts = []
|
|
api(possibleApi, params).then(json => {
|
|
field.loading = false
|
|
for (const obj in json) {
|
|
if (obj.includes('response')) {
|
|
for (const res in json[obj]) {
|
|
if (res === 'count') {
|
|
continue
|
|
}
|
|
field.opts = json[obj][res]
|
|
this.$forceUpdate()
|
|
break
|
|
}
|
|
break
|
|
}
|
|
}
|
|
}).catch(error => {
|
|
console.log(error.stack)
|
|
field.loading = false
|
|
})
|
|
},
|
|
async executeConfirmAction () {
|
|
const params = {}
|
|
params.id = this.nsp.id
|
|
if (this.currentAction.mapping) {
|
|
for (const key in this.currentAction.mapping) {
|
|
if (!this.currentAction.mapping[key].value) {
|
|
continue
|
|
}
|
|
params[key] = this.currentAction.mapping[key].value(this.resource, params)
|
|
}
|
|
}
|
|
this.actionLoading = true
|
|
|
|
try {
|
|
const hasJobId = await this.executeApi(this.currentAction.api, params)
|
|
if (!hasJobId) {
|
|
await this.fetchData()
|
|
}
|
|
this.actionLoading = false
|
|
this.onCloseAction()
|
|
} catch (message) {
|
|
this.actionLoading = false
|
|
this.$notification.error({
|
|
message: this.$t('message.request.failed'),
|
|
description: message
|
|
})
|
|
}
|
|
},
|
|
executeApi (apiName, args, method) {
|
|
return new Promise((resolve, reject) => {
|
|
let hasJobId = false
|
|
let message = ''
|
|
const promise = (method === 'POST') ? api(apiName, {}, method, args) : api(apiName, args)
|
|
promise.then(json => {
|
|
for (const obj in json) {
|
|
if (obj.includes('response') || obj.includes(apiName)) {
|
|
for (const res in json[obj]) {
|
|
if (res === 'jobid') {
|
|
this.$store.dispatch('AddAsyncJob', {
|
|
title: this.$t(this.currentAction.label),
|
|
jobid: json[obj][res],
|
|
description: this.$t(this.nsp.name),
|
|
status: 'progress'
|
|
})
|
|
this.parentPollActionCompletion(json[obj][res], this.currentAction)
|
|
hasJobId = true
|
|
break
|
|
}
|
|
}
|
|
break
|
|
}
|
|
}
|
|
|
|
resolve(hasJobId)
|
|
}).catch(error => {
|
|
message = (error.response && error.response.headers && error.response.headers['x-description']) || error.message
|
|
reject(message)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|