feat: 按照需求初步接入品高云

x-20250106
chengmingrui 2025-01-23 18:03:32 +08:00
parent a9cf567b08
commit 94b3ccffeb
17 changed files with 2627 additions and 5 deletions

33
.npmrc Normal file
View File

@ -0,0 +1,33 @@
; Force npm to always require authentication when accessing the registry, even for GET requests.
; always-auth = false
; The location of npm's cache directory. See npm-cache (https://docs.npmjs.com/cli/cache)
; Default: Windows: %AppData%\npm-cache, Posix: ~/.npm
; cache =
; What level of logs to report. On failure, all logs are written to npm-debug.log in the current working directory.
; Any logs of a higher level than the setting are shown. The default is "warn", which shows warn and error output.
; Default: "warn"
; Values: "silent", "error", "warn", "http", "info", "verbose", "silly"
; loglevel =
; The config file to read for global config options.
; Default: {prefix}/etc/npmrc
; globalconfig =
; The location to install global items. If set on the command line, then it forces non-global commands to run in the specified folder.
; Default: see npm-folders (https://docs.npmjs.com/files/folders)
; prefix =
; The base URL of the npm package registry.
; Default: https://registry.npmjs.org/
registry = http://58.210.154.140:13011/repository/bocloud-npm/
auto-install-peers = true
strict-peer-dependencies = false
shamefully-hoist = true
always-auth = true
_auth = Ym9jbG91ZDpjbXBAdjU4Nw==
; If set to false, then ignore npm-shrinkwrap.json files when installing.
; Default: true
; shrinkwrap =

View File

@ -0,0 +1,194 @@
/**
* Created by HaijunZhang on 2019/4/28.
*/
<template>
<common-wrapper code="storage" :add-data="addData" ref="common" :elements="elements" :get-params="getParams" :item-data="retention" :disabled="disabled" v-if="isLoadData">
<basic-form :model="addData.configs" ref="addForm" label-position="left">
<el-divider></el-divider>
<h5>配置信息</h5>
<el-row :gutter="20">
<el-col :span="10">
<basic-form-item label="磁盘类别:" prop="diskType" validate = "required">
<el-select v-model="addData.configs.diskType" placeholder="请先选择磁盘类别" @change="sizeChange">
<el-option v-for="item in categoryData" :label="item.name" :value="item.value" :key="item.value"></el-option>
</el-select>
</basic-form-item>
</el-col>
<el-col :span="10">
<basic-form-item label="大小:" >
<el-input-number :min="minSize" :max="maxSize" v-model="currentElement.insAmount" placeholder="请输入大小"></el-input-number>
</basic-form-item>
</el-col>
<el-col :span="10" v-if="addData.configs.diskType == 'io1'">
<basic-form-item label="IOPS" prop="iops" validate="required">
<el-input-number size="medium" v-model="addData.configs.iops" :min="100" :max="64000"> </el-input-number>
<span class="info">IOPS和磁盘最大比率为 50:1</span>
</basic-form-item>
</el-col>
</el-row>
<el-divider></el-divider>
<h5>云配置信息</h5>
<el-row :gutter="20">
<el-col :span="10">
<basic-form-item label="名称:" validate="required" prop="name">
<el-input v-model="addData.configs.name" placeholder="请输入名称"></el-input>
</basic-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="10">
<basic-form-item label="描述:" prop="remark">
<el-input type="textarea" v-model="addData.configs.remark" placeholder="请输入描述"></el-input>
</basic-form-item>
</el-col>
</el-row>
</basic-form>
<div slot="preview-card">
<basic-form-item label="磁盘容量:">{{currentElement.insAmount}}GB</basic-form-item>
</div>
</common-wrapper>
</template>
<script>
import CommonWrapper from 'views/resource-apply/components/PublicCommonWrapper.vue';
import { add, element } from '../data/publicInit'
import { getSystemConfigs } from 'services/system/index'
import { cloneDeep } from 'lodash-es'
import { getShoppingCartDetail } from 'services/system/shop_cart'
export default {
components: { CommonWrapper },
props: {
type: {
type: String
},
itemData: {
type: [Object, Boolean]
},
disabled: {
type: Boolean
}
},
data () {
return {
elements: [{
...element,
name: '云硬盘',
serviceCode: 'bingocloudos.standard.volume',
insAmount: 20,
main: true
}
],
addData: {
...add,
location: {
...add.location,
vendorType: this.type,
diskCategory: ''
},
service: 'bingocloudos.standard.volume',
configs: {
diskType: 'gp2',
iops: 100
}
},
categoryData: [
{ name: '通用型 SSD', value: 'gp2', size: 1 },
{ name: '预配置 IOPS SSD', value: 'io1', size: 4 },
{ name: 'Cold HDD', value: 'sc1', size: 125 },
{ name: '吞吐优化 HDD', value: 'st1', size: 125 },
{ name: '磁介质', value: 'standard', size: 1 }
],
minSize: 20,
maxSize: 100000,
serverList: [],
retention: false,
isLoadData: false
}
},
computed: {
currentElement () {
return this.elements[0]
}
},
created () {
getSystemConfigs({ codes: 'DefaultDiskSize' }).then(data => {
if (data.success) {
this.maxSize = Number(data.data.DefaultDiskSize)
}
})
if (this.itemData) {
this.retention = this.itemData
this.addData = cloneDeep(this.retention)
this.handleShowData()
} else if (this.$route.query.id) {
getShoppingCartDetail(this.$route.query.id).then(data => {
if (data.success) {
this.retention = JSON.parse(data.data.inventory)
this.addData = cloneDeep(this.retention)
this.handleShowData()
}
})
} else {
this.addData = {
...add,
location: {
...add.location,
vendorType: this.type,
diskCategory: ''
},
service: 'bingocloudos.standard.volume',
configs: {
diskType: 'gp2',
iops: 100
}
}
}
this.isLoadData = true
},
watch: {
'addData.location.vendorType' () {
this.$emit('type', this.addData.location.vendorType)
}
},
methods: {
sizeChange() {
const obj = this.categoryData.find(item => item.value == this.addData.configs.diskType)
this.minSize = obj.size
this.currentElement.insAmount = obj.size
if (this.addData.configs.diskType == 'io1') {
this.addData.configs.iops = 100
}
},
getPostData () {
let data = false
data = this.$refs.common.handlePostData()
return data
},
//
handleShowData() {
const { elements } = this.retention
const [first, ...others] = elements
this.elements = [
{
...element,
...first,
insAmount: this.addData.configs.size
}
]
},
getParams () {
let data = false;
this.$refs.addForm.validate(valid => {
if (valid) {
this.addData.configs.size = this.currentElement.insAmount
data = true
}
})
return data;
}
}
}
</script>
<style scoped lang="scss">
</style>

View File

@ -9,6 +9,7 @@
<tce :type="type" v-if="type == 'TCE'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></tce> <tce :type="type" v-if="type == 'TCE'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></tce>
<ali :type="type" v-if="type == 'ALIYUN'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></ali> <ali :type="type" v-if="type == 'ALIYUN'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></ali>
<aws :type="type" v-if="type == 'AWS'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></aws> <aws :type="type" v-if="type == 'AWS'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></aws>
<bingoCloudOS :type="type" v-if="type == 'BINGOCLOUDOS'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></bingoCloudOS>
</div> </div>
</template> </template>
@ -19,6 +20,7 @@ import tencent from './tencent.vue'
import tce from './tce.vue' import tce from './tce.vue'
import op from './op.vue' import op from './op.vue'
import aws from './aws.vue' import aws from './aws.vue'
import bingoCloudOS from './bingoCloudOS.vue'
export default { export default {
props: { props: {
itemData: { itemData: {
@ -28,7 +30,7 @@ export default {
type: Boolean type: Boolean
} }
}, },
components: { ali, op, huawei, tencent, aws, tce }, components: { ali, op, huawei, tencent, aws, bingoCloudOS, tce },
data () { data () {
return { return {
type: '' type: ''

View File

@ -0,0 +1,160 @@
<template>
<div>
<el-dialog :title="addData.title" :visible.sync="addData.dialog" width="50%" v-if="addData.dialog" append-to-body>
<div>
<el-form ref="data" :model="addData.data" :status-icon="true" label-width="120px">
<basic-form-item label="卷类型" prop="catalog" validate="required">
<el-select v-model="addData.data.catalog" @change="setCatelog" :disabled="addData.title === '编辑磁盘' && addData.data.catalog === 'root'">
<el-option label="根" value="root" v-if="addData.title === '编辑磁盘'"></el-option>
<el-option label="EBS" value="EBS"></el-option>
</el-select>
</basic-form-item>
<basic-form-item label="设备:" prop="device" validate="required">
<el-select v-model="addData.data.device" :disabled="addData.title === '编辑磁盘' && addData.data.catalog === 'root'">
<el-option label="/dev/xvda" value="/dev/xvda" v-if="addData.data.catalog === 'root'"></el-option>
<template v-if="addData.data.catalog === 'EBS'">
<!--<el-option label="/dev/sdb" value="/dev/sdb"></el-option>
<el-option label="/dev/sdc" value="/dev/sdc"></el-option>
<el-option label="/dev/sdd" value="/dev/sdd"></el-option>
<el-option label="/dev/sde" value="/dev/sde"></el-option>
<el-option label="/dev/sdf" value="/dev/sdf"></el-option>
<el-option label="/dev/sdg" value="/dev/sdg"></el-option>
<el-option label="/dev/sdh" value="/dev/sdh"></el-option>
<el-option label="/dev/sdi" value="/dev/sdi"></el-option>
<el-option label="/dev/sdj" value="/dev/sdj"></el-option>
<el-option label="/dev/sdk" value="/dev/sdk"></el-option>
<el-option label="/dev/sdl" value="/dev/sdl"></el-option>-->
<el-option v-for="(item, index) in addData.deviceList" :key="`device-${index}`" :label="item.name" :value="item.value"> </el-option>
</template>
</el-select>
</basic-form-item>
<basic-form-item label="类别:" prop="category" validate="required">
<el-select v-model="addData.data.category" placeholder="请先选择磁盘类别" @change="sizeChange">
<template v-if="addData.data.catalog === 'root'">
<el-option v-for="item in categoryData" :label="item.name" :value="item.value" :key="item.value"></el-option>
</template>
<template v-if="addData.data.catalog === 'EBS'">
<el-option v-for="item in categoryDatas" :label="item.name" :value="item.value" :key="item.value"></el-option>
</template>
</el-select>
</basic-form-item>
<basic-form-item label="大小GB" prop="size" validate="required">
<el-input-number size="medium" v-model="addData.data.size" :min="addData.data.size" :max="32768" v-if="addData.data.catalog === 'root'"> </el-input-number>
<el-input-number size="medium" v-model="addData.data.size" :min="0" :max="32768" v-if="addData.data.catalog === 'EBS'"> </el-input-number>
</basic-form-item>
</el-form>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="ghost" @click="back"> </el-button>
<el-button type="primary" @click="ok"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
props: {
addData: {
type: Object,
default: function() {
return {
data: {
labelIds: []
},
dialog: false
}
}
},
networkList: {
type: Array
},
xvda: {
type: Boolean
}
},
data() {
return {
categoryDatas: [
{
name: '通用型 SSD',
value: 'gp2',
size: 1
},
{
name: '预配置 IOPS SSD',
value: 'io1',
size: 4
},
{
name: 'Cold HDD',
value: 'sc1',
size: 500
},
{
name: '吞吐优化 HDD',
value: 'st1',
size: 500
},
{
name: '磁介质',
value: 'standard',
size: 1
}
],
categoryData: [
{
name: '通用型 SSD',
value: 'gp2',
size: 1
},
{
name: '预配置 IOPS SSD',
value: 'io1',
size: 4
},
{
name: '磁介质',
value: 'standard',
size: 1
}
],
sizeData: {
gp2: 20,
io1: 40,
sc1: 500,
st1: 500,
standard: 1
},
regionList: [],
minSize: 20
}
},
methods: {
setCatelog() {},
back() {
if (this.addData.title == '编辑磁盘' && this.xvda) this.$emit('back')
this.addData.dialog = false
},
sizeChange() {
this.minSize = this.sizeData[this.addData.data.category]
this.addData.data.size = this.sizeData[this.addData.data.category]
},
ok() {
this.$refs.data.validate(valid => {
if (valid) {
this.$emit('ok', this.addData)
this.addData.dialog = false
}
})
}
}
}
</script>
<style scoped>
.mine-text {
font-size: 10px;
color: #b4b4b4;
}
</style>

View File

@ -0,0 +1,273 @@
<template>
<div>
<div>
<template v-for="(item, index) in tagList">
<el-tag class="m-l-xs" :key="index" v-if="item.catalog === 'root'" :disable-transitions="false" @click.stop="modify(item, index)" @close.stop="handleClose(item, index)">
{{ item.device }}
</el-tag>
<el-tag class="m-l-xs" :key="index" v-else closable :disable-transitions="false" @click.stop="modify(item, index)" @close.stop="handleClose(item, index)">
{{ item.device }}
</el-tag>
</template>
<el-button size="mini" @click="add" type="primary" class="m-l-md">添加</el-button>
<span class="mine-text m-l-md" v-if="!tagList.length"></span>
</div>
<add :add-data="addData" v-if="addData.dialog" @ok="addOk" :now-list="tagList"></add>
</div>
</template>
<script>
import add from './add.vue'
export default {
components: {
add
},
props: {
networkList: {
type: Array
},
diskId: {
type: [String, Number]
},
type: {
type: String
},
imageData: {
type: Array
},
source: {
type: String
},
parentData: {
type: Object
}
},
watch: {
diskId: {
handler(newVal, oldVal) {
this.tagList = []
const result = this.imageData.filter((item) => Number(item.id) === Number(newVal))
if (result.length !== 0) {
const rows = result[0]
if (rows.blockDeviceMappings) {
JSON.parse(rows.blockDeviceMappings).forEach((item, index) => {
const newItem = {
device: item.deviceName
}
if (item.ebs) {
newItem.size = item.ebs.volumeSize ? item.ebs.volumeSize : 40
newItem.category = item.ebs.volumeTypeAsString
}
if (item.deviceName === rows.rootDeviceName) {
newItem.catalog = 'root'
} else {
newItem.catalog = 'EBS'
}
this.tagList.push(newItem)
if (rows.osCategory === 'windows') {
this.deviceList = this.deviceListWin
} else {
this.deviceList = this.deviceListLinux
}
})
} else {
}
}
}
}
},
created() {
if (this.parentData && this.parentData.diskDevices) {
this.tagList = this.parentData.diskDevices
}
},
data() {
return {
tagList: [],
deviceList: [],
deviceListLinux: [
{
name: '/dev/sdb',
value: '/dev/sdb'
},
{
name: '/dev/sdc',
value: '/dev/sdc'
},
{
name: '/dev/sdd',
value: '/dev/sdd'
},
{
name: '/dev/sde',
value: '/dev/sde'
},
{
name: '/dev/sdf',
value: '/dev/sdf'
},
{
name: '/dev/sdg',
value: '/dev/sdg'
},
{
name: '/dev/sdh',
value: '/dev/sdh'
},
{
name: '/dev/sdi',
value: '/dev/sdi'
},
{
name: '/dev/sdj',
value: '/dev/sdj'
},
{
name: '/dev/sdk',
value: '/dev/sdk'
},
{
name: '/dev/sdl',
value: '/dev/sdl'
}
],
deviceListWin: [
{
name: 'xvdb',
value: 'xvdb'
},
{
name: 'xvdc',
value: 'xvdc'
},
{
name: 'xvdd',
value: 'xvdd'
},
{
name: 'xvde',
value: 'xvde'
},
{
name: 'xvdf',
value: 'xvdf'
},
{
name: 'xvdg',
value: 'xvdg'
},
{
name: 'xvdh',
value: 'xvdh'
},
{
name: 'xvdi',
value: 'xvdi'
},
{
name: 'xvdj',
value: 'xvdj'
},
{
name: 'xvdk',
value: 'xvdk'
},
{
name: 'xvdl',
value: 'xvdl'
}
],
devices: [],
addData: {
dialog: false,
data: {}
},
modifyData: {
dialog: false,
data: {}
},
nowList: []
}
},
methods: {
handleClose(data, index) {
this.tagList.splice(index, 1)
},
getDevices() {
let list = this.deviceList
if (this.tagList.length == 0) {
this.$message.error('请先选择系统盘!')
return []
}
if (this.tagList.length > 1) {
this.tagList.forEach((item, index) => {
if (item.catalog === 'EBS') {
list = list.filter((row) => row.value !== item.device)
}
})
return list
} else {
if (this.tagList[0].catalog === 'root') {
return list
}
}
},
add() {
const list = this.getDevices()
if (list.length) {
this.addData = {
dialog: true,
title: '新增磁盘',
deviceList: list,
data: {
device: '',
size: 0,
catalog: 'EBS',
category: ''
}
}
}
},
modify(data, index) {
const list = this.getDevices()
const arr = [
{
name: data.device,
value: data.device
}
]
const ss = data.catalog === 'EBS' ? list.concat(arr) : []
this.addData = {
dialog: true,
index: index,
title: '编辑磁盘',
deviceList: ss,
data: {
catalog: data.catalog,
device: data.device,
size: data.size,
category: data.category ? data.category : 'gp2',
deleteWithInstance: data.deleteWithInstance
}
}
},
addOk(data) {
if (data.index >= 0) {
this.tagList[data.index] = data.data
} else {
this.tagList.push(data.data)
}
},
ok() {
return this.tagList
}
}
}
</script>
<style scoped>
.mine-text {
font-size: 10px;
color: #b4b4b4;
}
</style>

View File

@ -0,0 +1,84 @@
<template>
<div>
<el-dialog :title="addData.title" :visible.sync="addData.dialog" width="40%" v-if="addData.dialog" append-to-body>
<div>
<el-form ref="data" :model="addData.data" :status-icon="true" label-width="120px">
<!-- <basic-form-item label="deviceIndex" prop="deviceIndex" validate = "required">
<el-input v-model="addData.data.deviceIndex"></el-input>
</basic-form-item> -->
<basic-form-item label="网络接口:" prop="networkInterfaceUuid" validate="required">
<el-select v-model="addData.data.networkInterfaceUuid">
<el-option v-for="item in list" :disabled="nowList.indexOf(item.networkInterfaceUuid) > -1" :label="item.name + '(类型:' + item.interfaceType + ')'" :value="item.networkInterfaceUuid" :key="item.value"></el-option>
</el-select>
</basic-form-item>
</el-form>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="ghost" @click="addData.dialog = false"> </el-button>
<el-button type="primary" @click="ok"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
/* global $ */
import { getNics } from 'services/platform/bingoCloudOS'
export default {
props: {
addData: {
type: Object,
default: function() {
return {
data: {
labelIds: []
},
dialog: false
}
}
},
subnetId: {
type: [String, Number]
},
vendorId: {
type: [String, Number]
},
nowList: {
type: Array
}
},
data() {
return {
list: []
}
},
methods: {
getNics() {
getNics({
simple: true,
params: JSON.stringify([{ param: { vendorId: this.vendorId, subnetId: this.subnetId, deviceIndex: -1 }, sign: 'EQ' }])
}).then(data => {
if (data.success) {
this.list = data.data.rows
}
})
},
ok() {
this.$refs.data.validate(valid => {
if (valid) {
this.list.forEach(item => {
if (item.networkInterfaceUuid == this.addData.data.networkInterfaceUuid) this.addData.data.name = item.name
})
this.$emit('ok', this.addData)
this.addData.dialog = false
}
})
}
},
created() {
this.getNics()
}
}
</script>
<style></style>

View File

@ -0,0 +1,86 @@
<template>
<div>
<div v-if="addData.subnetId">
<el-tag class="m-l-xs" :key="index" v-for="(item, index) in tagList" closable :disable-transitions="false" @click.stop="modify(item, index)" @close.stop="handleClose(index)">
{{ item.name }}
</el-tag>
<el-button size="mini" @click="add" type="primary" class="m-l-md">添加</el-button>
</div>
<div v-else></div>
<add :add-data="addObj" v-if="addObj.dialog" @ok="addOk" :subnet-id="addData.subnetId" :vendor-id="addData.vendorId" :now-list="nowList"></add>
</div>
</template>
<script>
import add from './add.vue'
export default {
components: { add },
props: {
addData: {
type: Object
}
},
data() {
return {
tagList: [],
addObj: {
dialog: false,
data: {}
},
modifyData: {
dialog: false,
data: {}
},
nowList: []
}
},
methods: {
handleClose(index) {
this.nowList.splice(index, 1)
this.tagList.splice(index, 1)
},
add() {
this.addObj = {
dialog: true,
title: '新增网络接口',
data: {
deviceIndex: this.tagList.length
}
}
},
modify(data, index) {
this.addObj = {
dialog: true,
index: index,
title: '编辑网络接口',
data: {
deviceIndex: data.deviceIndex,
networkInterfaceUuid: data.networkInterfaceUuid
}
}
},
addOk(data) {
if (data.index >= 0) {
this.tagList[data.index] = data.data
this.nowList[data.index].networkInterfaceUuid = data.data.networkInterfaceUuid
} else {
this.tagList.push(data.data)
this.nowList.push(data.data.networkInterfaceUuid)
}
},
ok() {
return this.tagList
}
},
watch: {
subnetId: {
handler(newVal) {
this.tagList = []
},
deep: true
}
}
}
</script>
<style scoped></style>

View File

@ -0,0 +1,110 @@
<template>
<div>
<basic-form-item label="系统规格:" validate="required">
<div v-if="addData.configs.flavorId">
已选规格{{addData.configs.cpu}}C/{{addData.configs.memory}}G
</div>
<el-form :inline="true" class="m-t-xs">
<el-form-item>
<el-input placeholder="名称" v-model="searchData.name"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleSearchSpec"></el-button>
</el-form-item>
</el-form>
<el-table :data="list" highlight-current-row tooltip-effect="dark" stripe border fit>
<el-table-column label="名称">
<template slot-scope="scope">
<el-radio :label="scope.row.id" v-model="addData.configs.flavorId" @change="checkConfig">
{{ scope.row.name }}
</el-radio>
</template>
</el-table-column>
<el-table-column label="规格uuid" prop="flavorUuid"> </el-table-column>
<el-table-column label="cpu" prop="cpu"> </el-table-column>
<el-table-column label="内存(GB)" prop="memory"> </el-table-column>
</el-table>
<div class="pagination-container">
<el-pagination @size-change="handleSizeChange1" @current-change="getList" :current-page.sync="params.page" :page-sizes="[5, 10, 20, 30, 50]" :page-size="params.rows" layout="total, sizes, prev, pager, next, jumper" :total="total"> </el-pagination>
</div>
</basic-form-item>
</div>
</template>
<script>
/* global $ */
import { getFlavor } from 'services/platform/index'
export default {
props: {
addData: {
type: Object,
default: function () {
return {
data: {
},
dialog: false
}
}
}
},
data () {
return {
searchData: {
name: ''
},
params: {
page: 1,
rows: 5
},
list: [],
total: 0
}
},
methods: {
checkConfig (id) {
const obj = this.list.find(item => item.id == id)
this.$set(this.addData.configs, 'cpu', obj.cpu)
this.$set(this.addData.configs, 'memory', obj.memory)
},
handleSizeChange1(val) {
this.params.rows = val
this.getList()
},
//
getList() {
getFlavor(this.params).then((data) => {
if (data.success) {
this.list = data.data.rows
this.total = data.data.total
if (!this.addData.configs.flavorId && this.list.length) {
this.$set(this.addData.configs, 'flavorId', this.list[0].id)
this.checkConfig(this.addData.configs.flavorId)
}
}
})
},
//
handleSearchSpec() {
this.params.page = 1
this.params.params = this.$tools.handleSearchParam({
vendorId: this.addData.location.vendorId,
regionId: this.addData.location.region,
'name:LK': this.searchData.name
})
this.getList()
}
},
watch: {
'addData.location.region' () {
this.handleSearchSpec()
}
},
created () {
this.handleSearchSpec()
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,190 @@
<template>
<el-col :span="24">
<basic-form-item label="镜像:" validate="required">
<el-form :inline="true">
<el-form-item>
<el-input v-model="searchData.name" placeholder="名称"></el-input>
</el-form-item>
<el-form-item>
<el-select v-model="searchData.type">
<el-option v-for="(item, index) in typeList" :key="index" :label="item.name" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="searchData.osType" clearable>
<el-option v-for="(item, index) in osTypeList" :key="index" :label="item.name" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="searchData.architecture" clearable>
<el-option v-for="(item, index) in architectureList" :key="index" :label="item.name" :value="item.value"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="hendleSearch"></el-button>
</el-form-item>
<el-table :data="imageList" highlight-current-row tooltip-effect="dark" stripe border fit>
<template slot="empty">
请选择地域
</template>
<el-table-column label="镜像名称">
<template slot-scope="scope">
<el-radio :label="scope.row.id" v-model="addData.imageId">
{{ scope.row.name }}
</el-radio>
</template>
</el-table-column>
<el-table-column label="镜像ID" prop="imageUuid" show-overflow-tooltip> </el-table-column>
<el-table-column prop="status" label="状态" show-overflow-tooltip>
<template slot-scope="scope">
<status-icon :type="scope.row.status | vmStatusColor">{{ scope.row.status | openstackServer }}</status-icon>
</template>
</el-table-column>
<el-table-column prop="regionName" label="可用域" show-overflow-tooltip></el-table-column>
</el-table>
<div class="pagination-container">
<el-pagination @size-change="handleChange" @current-change="getImageData" :current-page.sync="params.page" :page-sizes="[5, 10, 20, 30, 50]" :page-size="params.rows" layout="total, sizes, prev, pager, next, jumper" :total="total"> </el-pagination>
</div>
</el-form>
</basic-form-item>
<basic-form-item label="虚拟磁盘:">
<DataDisk ref="disk" :image-data="imageList" :disk-id="addData.imageId" :parent-data="addData"></DataDisk>
</basic-form-item>
</el-col>
</template>
<script>
import { getImage } from 'services/platform/index'
import DataDisk from './addDisk/index.vue'
export default {
components: { DataDisk },
props: {
addData: {
type: Object
},
imageData: {
type: Object,
default: () => {
return {
rows: []
}
}
},
location: {
type: Object
},
itemData: {
type: [Object, Boolean]
}
},
created () {
this.hendleSearch()
},
data() {
return {
searchData: {
type: 'PUBLIC',
osType: '',
architecture: ''
},
typeList: [
{
name: '公共镜像',
value: 'PUBLIC'
},
{
name: '私有镜像',
value: 'PRIVATE'
}
],
architectureList: [
{
name: 'i386',
value: 'i386'
},
{
name: 'x86_64',
value: 'x86_64'
}
],
osTypeList: [
{
name: 'kernel',
value: 'kernel'
},
{
name: 'machine',
value: 'machine '
}
],
imageList: [],
params: {
page: 1,
rows: 5
},
total: 0
}
},
methods: {
handleChange(val) {
this.params.rows = val
this.getImageData()
},
hendleSearch() {
if (!this.location.region) return this.$message.error('请选择地域')
this.params.params = this.$tools.handleSearchParam({
vendorId: this.location.vendorId,
imageType: this.searchData.type,
regionId: this.location.region,
architecture: this.searchData.architecture,
osType: this.searchData.osType,
status: 'ACTIVE',
applyList: true,
'name:lk': this.searchData.name
})
this.getImageData()
},
getImageData() {
getImage(this.params).then(data => {
if (data.success) {
this.imageList = data.data.rows
this.total = data.data.total
this.$set(this.imageData, 'rows', data.data.rows)
if (this.itemData && (this.itemData.location.vendorId != this.location.vendorId)) {
this.$set(this.addData, 'imageId', '')
}
}
})
}
},
watch: {
'location.vendorId': {
handler(newVal) {
this.hendleSearch()
},
deep: true
}
}
}
</script>
<style>
.powerLine {
background-color: #d4d4d4;
padding: 5px;
margin-bottom: 10px;
border-color: #cbcbcb;
position: relative;
}
.powerLine .powerLineLeft {
font-weight: bold;
}
.powerLine .powerLineRight {
position: absolute;
right: 10px;
top: 5px;
cursor: pointer;
}
</style>

View File

@ -0,0 +1,382 @@
/**
* Created by HaijunZhang on 2019/4/28.
*/
<template>
<common-wrapper code="compute" :show-count="!vmData.hasEip" :add-data="addData" @vendorId="getList" @backZone="getSubnet" ref="common" :elements="elements" :get-params="getParams" :modify-element="modifyElement" :item-data="retention" :disabled="disabled">
<el-divider></el-divider>
<h5>配置信息</h5>
<el-col :span="15" v-if="addData.location.region">
<flavor :add-data="addData"></flavor>
</el-col>
<images v-if="addData.location.vendorId" :add-data="addData.configs" :vendor-id="addData.location.vendorId" :location="addData.location" vendorType="bingoCloudOS" :item-data="retention" ref="image"></images>
<div style="clear:both"></div>
<basic-form :model="vmData" ref="addForm" label-position="left" :disabled="disabled">
<el-divider></el-divider>
<h5>网络信息</h5>
<el-col :span="4">
<basic-form-item prop="terminationProtected" label="启动终止保护:">
<el-checkbox v-model="vmData.terminationProtected"></el-checkbox>
</basic-form-item>
</el-col>
<el-col :span="4">
<basic-form-item prop="hasIpv6" label="设置IPV6">
<el-checkbox v-model="vmData.hasIpv6" @change="changeHasIpv6"></el-checkbox>
</basic-form-item>
</el-col>
<el-col :span="4">
<basic-form-item prop="hasEip" label="设置EIP">
<el-checkbox v-model="vmData.hasEip" @change="changeHasEip"></el-checkbox>
</basic-form-item>
</el-col>
<el-col :span="12" v-if="vmData.hasEip">
<basic-form-item label="弹性IP" prop="eipId" validate="required">
<el-select v-model="vmData.eipId" filterable clearable @change="changeE">
<el-option v-for="(item, index) in eipList" :key="index" :label="item.name" :value="item.id"> {{ item.name }}({{ item.publicIp }}) </el-option>
</el-select>
</basic-form-item>
</el-col>
<el-col :span="24">
<el-col :span="12">
<basic-form-item label="所属网络:" prop="networkId" validate="required" required-message="">
<el-select v-model="vmData.networkId" @change="changeVPC">
<el-option v-for="item in vpcData" :label="`${item.name}(${item.vpcId})`" :value="item.id" :key="item.vpcId"></el-option>
</el-select>
</basic-form-item>
</el-col>
<el-col :span="12">
<basic-form-item label="所属子网:" prop="subnetId" validate="required" required-message="">
<el-select v-model="vmData.subnetId" filterable placeholder="请先选择交换机">
<el-option v-for="(item, index) in subnets" :label="item.name" :value="item.id" :key="index">{{ item.name }}({{ item.subnetId }} - {{ item.cidr }})</el-option>
</el-select>
</basic-form-item>
</el-col>
<el-col :span="12" v-if="addData.emption.count == 1">
<el-col :span="24">
<el-col :span="6">
<basic-form-item label="手动指定IP: ">
<el-checkbox v-model="vmData.manualIp"></el-checkbox>
</basic-form-item>
</el-col>
<el-col :span="18" v-if="vmData.manualIp">
<basic-form-item label="IP" prop="managerIp" validate="required,ip" required-message="ip">
<el-input v-model="vmData.managerIp" placeholder="请输入192.168.1.1类型格式"></el-input>
</basic-form-item>
</el-col>
</el-col>
</el-col>
<el-col :span="12">
<basic-form-item label="安全组:" prop="groups" :rules="[{ required: true, message: '请选择安全组', trigger: 'blur' }]">
<el-select v-model="vmData.groups" multiple>
<el-option v-for="(item, index) in groupsData" :key="index" :label="`${item.name}(${item.value})`" :value="item.value"></el-option>
</el-select>
</basic-form-item>
</el-col>
</el-col>
<div style="clear:both"></div>
<el-divider></el-divider>
<h5>云主机信息</h5>
<el-col :span="12">
<basic-form-item label="虚机名称:" validate="required" prop="name">
<el-input v-model="vmData.name" placeholder="请输入虚拟机名"></el-input>
<div class="tip">设置虚拟机名称前缀</div>
</basic-form-item>
</el-col>
<el-col :span="12">
<basic-form-item label="密钥:" prop="keypairId" validate="required" required-message="">
<el-select v-model="vmData.keypairId">
<el-option v-for="item in keypairList" :key="item.id" :label="item.name" :value="item.id"></el-option>
</el-select>
</basic-form-item>
</el-col>
</basic-form>
</common-wrapper>
</template>
<script>
import CommonWrapper from 'views/resource-apply/components/PublicCommonWrapper.vue';
import { add } from '../../data/publicInit'
import { getKey, getGroup, getVpc, getSubnet, getListEip } from 'services/platform/index'
import images from './image.vue'
import { cloneDeep } from 'lodash-es'
import { getShoppingCartDetail } from 'services/system/shop_cart'
import flavor from './flavor.vue'
export default {
components: { CommonWrapper, images, flavor },
props: {
type: {
type: String
},
itemData: {
type: [Object, Boolean]
},
disabled: {
type: Boolean
}
},
data () {
return {
elements: [{
name: '云主机',
serviceCode: 'bingocloudos.standard.server',
main: true,
cpu: 0,
memory: 0
}
],
addData: {
...cloneDeep(add),
location: {
...add.location,
vendorType: this.type,
diskCategory: ''
},
service: 'bingocloudos.standard.server',
configs: {
resourceLabel: [],
imageId: '',
imageType: 'PUBLIC',
imageName: ''
}
},
vmData: {
networkId: '',
subnetId: '',
groups: [],
terminationProtected: false,
hasIpv6: false,
hasEip: false,
keypairId: ''
},
vpcData: [],
subnets: [],
groupsData: [],
eipList: [],
keypairList: [],
retention: false
}
},
computed: {
currentElement () {
return this.elements[0]
}
},
created () {
if (this.itemData) {
this.retention = this.itemData
this.handleShowData()
} else if (this.$route.query.id) {
getShoppingCartDetail(this.$route.query.id).then(data => {
if (data.success) {
this.retention = JSON.parse(data.data.inventory)
this.handleShowData()
}
})
} else {
this.addData = {
...add,
location: {
...add.location,
vendorType: this.type,
diskCategory: ''
},
service: 'bingocloudos.standard.server',
configs: {
resourceLabel: [],
imageId: '',
imageType: 'PUBLIC',
imageName: ''
}
}
}
},
methods: {
handleShowData () {
this.addData = cloneDeep(this.retention)
const { name, hasIpv6, networkId, subnetId, groups, manualIp, managerIp, terminationProtected, hasEip, keypairId, eipId } = this.addData.configs
this.vmData = {
name: name,
networkId: networkId,
subnetId: subnetId,
groups: groups,
manualIp: manualIp,
managerIp: managerIp,
terminationProtected: terminationProtected,
hasIpv6: hasIpv6,
hasEip: hasEip,
keypairId: keypairId,
eipId
}
this.getVPCList()
if (hasEip) this.getListEips()
},
changeHasIpv6(val) {
this.getVPCList()
if (val) {
this.vmData.networkId = ''
this.vmData.subnetId = ''
}
},
changeHasEip(val) {
this.getVPCList()
if (val) {
this.vmData.networkId = ''
this.vmData.subnetId = ''
this.getListEips()
}
},
getListEips() {
getListEip({
vendorId: this.addData.location.vendorId,
regionId: this.addData.location.region
}).then((data) => {
if (data.success) {
this.eipList = data.data
}
})
},
getPostData () {
let data = false
data = this.$refs.common.handlePostData()
return data
},
getVPCList() {
if (this.retention && this.retention.location.region == this.addData.location.region) {
this.subnets = []
this.groupsData = []
} else {
this.$set(this.vmData, 'networkId', '')
this.$set(this.vmData, 'subnetId', '')
this.$set(this.vmData, 'groups', [])
this.subnets = []
this.groupsData = []
}
this.groupsData = []
const params = {
page: 1,
rows: 9999
}
params.params = this.$tools.handleSearchParam({
vendorId: this.addData.location.vendorId,
regionId: this.addData.location.region,
hasIpv6: this.vmData.hasIpv6
})
getVpc(params).then((data) => {
if (data.success) {
this.vpcData = data.data.rows
if (this.vmData.networkId) {
this.changeVPC()
}
}
})
},
changeVPC() {
this.getSubnet()
this.getGroupData()
},
//
getSubnet() {
const params = JSON.stringify([
{
param: {
networkId: this.vmData.networkId,
zone: this.addData.location.az,
vendorId: this.addData.location.vendorId,
regionId: this.addData.location.region,
hasIpv6: this.vmData.hasIpv6
},
sign: 'EQ'
}
])
getSubnet({
page: 1,
rows: 999999,
params
}).then((data) => {
if (data.success) {
this.subnets = data.data.rows
}
})
},
getGroupData() {
getGroup({
simple: true,
params: JSON.stringify([
{
param: {
vendorId: this.addData.location.vendorId,
vpcId: this.vmData.networkId
},
sign: 'EQ'
}
])
}).then((data) => {
if (data.success) {
this.groupsData = data.data.rows
}
})
},
getList () {
this.getVPCList(true)
this.getKeypair()
},
getKeypair() {
getKey({
simple: true,
params: JSON.stringify([{ param: { vendorId: this.addData.location.vendorId, regionId: this.addData.location.region }, sign: 'EQ' }])
}).then(data => {
if (data.success) {
this.keypairList = data.data.rows
}
})
},
getParams () {
let data = false;
this.$refs.addForm.validate(valid => {
if (valid) {
this.vmData.diskDevices = this.$refs.image.$refs.disk.ok()
let flag = false
this.vmData.diskDevices.forEach((item, index) => {
if (index == 0) item.deleteWithInstance = 'true'
else item.deleteWithInstance = 'false'
if (!item.size) flag = true
})
if (this.vmData.diskDevices.length == 0) return this.$message.error('请添加磁盘')
if (flag) return this.$message.error('磁盘数据不完善')
const { ...other } = this.vmData;
const result = {
...other,
regionId: this.addData.location.region,
zoneId: this.addData.location.az
};
if (this.vmData.hasEip) this.addData.emption.count = 1
data = result;
}
});
return data;
},
modifyElement () {
this.currentElement.cpu = this.addData.configs.cpu
this.currentElement.memory = this.addData.configs.memory
this.vmData.diskDevices.forEach(item => {
this.elements.push({
serviceCode: 'bingocloudos.standard.volume',
insAmount: item.size
})
})
}
},
watch: {
'addData.location.vendorType' () {
this.$emit('type', this.addData.location.vendorType)
}
}
}
</script>
<style scoped lang="scss">
@import '../../index.scss';
.remark_title{
font-size: 12px;
color: #979797;
}
</style>

View File

@ -6,6 +6,7 @@
<vc :type="type" v-if="type == 'VMWARE'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></vc> <vc :type="type" v-if="type == 'VMWARE'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></vc>
<op :type="type" v-else-if="type == 'OPENSTACK'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></op> <op :type="type" v-else-if="type == 'OPENSTACK'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></op>
<aws :type="type" v-else-if="type == 'AWS'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></aws> <aws :type="type" v-else-if="type == 'AWS'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></aws>
<bingoCloudOS :type="type" v-else-if="type == 'BINGOCLOUDOS'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></bingoCloudOS>
<ali :type="type" v-else-if="type == 'ALIYUN'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></ali> <ali :type="type" v-else-if="type == 'ALIYUN'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></ali>
<huawei :type="type" v-else-if="type == 'HUAWEI'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></huawei> <huawei :type="type" v-else-if="type == 'HUAWEI'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></huawei>
<tencent :type="type" v-else-if="type == 'TENCENT'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></tencent> <tencent :type="type" v-else-if="type == 'TENCENT'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></tencent>
@ -21,6 +22,7 @@ import huawei from './huawei/index.vue'
import tencent from './tencent/index.vue' import tencent from './tencent/index.vue'
import tce from './tce/index.vue' import tce from './tce/index.vue'
import aws from './aws/index.vue' import aws from './aws/index.vue'
import bingoCloudOS from './bingoCloudOS/index.vue'
export default { export default {
props: { props: {
itemData: { itemData: {
@ -30,7 +32,7 @@ export default {
type: Boolean type: Boolean
} }
}, },
components: { vc, ali, op, huawei, tencent, aws, tce }, components: { vc, ali, op, huawei, tencent, aws, bingoCloudOS, tce },
data () { data () {
return { return {
type: '' type: ''

View File

@ -0,0 +1,140 @@
/**
* Created by HaijunZhang on 2019/4/28.
*/
<template>
<common-wrapper code="network" :add-data="addData" ref="common" :elements="elements" :get-params="getParams" :item-data="retention" :disabled="disabled" v-if="isLoadData">
<basic-form :model="addData.configs" ref="addForm" label-position="left">
<h5>云配置信息</h5>
<el-row :gutter="20">
<el-col :span="24">
</el-col>
<el-col :span="10">
<basic-form-item label="名称:" validate="required" prop="name">
<el-input v-model="addData.configs.name" placeholder="请输入名称"></el-input>
</basic-form-item>
</el-col>
<el-col :span="24">
<basic-form-item label=" ">
<p style="font-size:12px">
通过选择从其中分配公有 IP 地址的公有 IPv4 地址池来分配弹性 IP 地址您可以为运行中的实例免费关联一个弹性 IP (EIP)地址如果将更多 EIP 与该实例关联则将按比例向与该实例相关联的每个额外 EIP 收费额外 EIP 只能在 Amazon VPC 中使用为确保有效使用弹性 IP 地址当这些 IP
地址未与运行中的实例相关联或者关联到已停止的实例或未连接的网络接口时我们会按小时收取少量费用
</p>
</basic-form-item>
</el-col>
</el-row>
</basic-form>
</common-wrapper>
</template>
<script>
import CommonWrapper from 'views/resource-apply/components/PublicCommonWrapper.vue';
import { add, element } from '../data/publicInit'
import { cloneDeep } from 'lodash-es'
import { getShoppingCartDetail } from 'services/system/shop_cart'
export default {
components: { CommonWrapper },
props: {
type: {
type: String
},
itemData: {
type: [Object, Boolean]
},
disabled: {
type: Boolean
}
},
data () {
return {
elements: [{
...element,
name: 'EIP',
serviceCode: 'network.bingoCloudOS.eip',
main: true
}
],
addData: {
...cloneDeep(add),
location: {
...add.location,
vendorType: this.type
},
service: 'network.bingoCloudOS.eip',
configs: {
bandwidth: 1
}
},
retention: false,
isLoadData: false
}
},
computed: {
currentElement () {
return this.elements[0]
}
},
created () {
if (this.itemData) {
this.retention = this.itemData
this.addData = cloneDeep(this.retention)
const { elements } = this.retention
const [first, ...others] = elements
this.elements = [
{
...element,
...first
}
]
} else if (this.$route.query.id) {
getShoppingCartDetail(this.$route.query.id).then(data => {
if (data.success) {
this.retention = JSON.parse(data.data.inventory)
this.addData = cloneDeep(this.retention)
const { elements } = this.retention
const [first, ...others] = elements
this.elements = [
{
...element,
...first
}
]
}
})
} else {
this.addData = {
...add,
location: {
...add.location,
vendorType: this.type
},
service: 'network.bingoCloudOS.eip',
configs: {
bandwidth: 1
}
}
}
this.isLoadData = true
},
methods: {
getPostData () {
let data = false
data = this.$refs.common.handlePostData()
return data
},
getParams () {
let data = false;
this.$refs.addForm.validate(valid => {
if (valid) {
this.addData.configs.regionId = this.addData.location.region
data = true
}
})
return data;
}
}
}
</script>
<style scoped lang="scss">
</style>

View File

@ -5,6 +5,7 @@
<div> <div>
<ali :type="type" v-if="type == 'ALIYUN'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></ali> <ali :type="type" v-if="type == 'ALIYUN'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></ali>
<huawei :type="type" v-else-if="type == 'HUAWEI'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></huawei> <huawei :type="type" v-else-if="type == 'HUAWEI'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></huawei>
<bingoCloudOS :type="type" v-else-if="type == 'BINGOCLOUDOS'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></bingoCloudOS>
<aws :type="type" v-else-if="type == 'AWS'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></aws> <aws :type="type" v-else-if="type == 'AWS'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></aws>
<tencent :type="type" v-else-if="type == 'TENCENT'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></tencent> <tencent :type="type" v-else-if="type == 'TENCENT'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></tencent>
<tce :type="type" v-else-if="type == 'TCE'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></tce> <tce :type="type" v-else-if="type == 'TCE'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></tce>
@ -19,6 +20,7 @@ import huawei from './huawei.vue'
import tencent from './tencent.vue' import tencent from './tencent.vue'
import tce from './tce.vue' import tce from './tce.vue'
import aws from './aws.vue' import aws from './aws.vue'
import bingoCloudOS from './bingoCloudOS.vue'
export default { export default {
props: { props: {
itemData: { itemData: {
@ -28,7 +30,7 @@ export default {
type: Boolean type: Boolean
} }
}, },
components: { ali, op, huawei, tencent, aws, tce }, components: { ali, op, huawei, tencent, aws, bingoCloudOS, tce },
data () { data () {
return { return {
type: '' type: ''

View File

@ -0,0 +1,806 @@
/**
* Created by HaijunZhang on 2019/4/28.
*/
<template>
<common-wrapper code="network" :add-data="addData" ref="common" @vendorId="handleSearch" :elements="elements" :get-params="getParams" :item-data="retention" :disabled="disabled">
<basic-form :model="addData.configs" ref="addForm" label-position="left">
<el-divider></el-divider>
<h5>配置信息</h5>
<el-row>
<el-col :span="12">
<basic-form-item validate="required" label="负载均衡器类型:">
<el-radio-group v-model="addData.configs.loadBalancerType" @change="selectType">
<el-radio label="application">应用程序负载均衡器</el-radio>
<el-radio label="network">网络负载均衡器</el-radio>
</el-radio-group>
</basic-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<basic-form-item label="名称:" prop="name" validate="required,awsName" require-message="a-zA-Z0-9">
<el-input v-model="addData.configs.name" placeholder="仅允许a-z、A-Z、0-9和连字符"></el-input>
</basic-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<basic-form-item validate="required" label="模式:">
<el-radio-group v-model="addData.configs.scheme" @change="changeClassification">
<el-radio label="internet-facing">面向Internet</el-radio>
<el-radio label="internal">内部</el-radio>
</el-radio-group>
</basic-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<basic-form-item label="IP地址类型" validate="required" require-message="IP">
<el-select v-model="addData.configs.ipAddressType" @change="changeIpAddressType" v-if="addData.configs.scheme === 'internet-facing'" placeholder="请选择IP地址类型">
<el-option value="ipv4" label="ipv4"></el-option>
<el-option value="dualstack" label="dualstack"></el-option>
</el-select>
<el-select v-model="addData.configs.ipAddressType" v-if="addData.configs.scheme === 'internal'" disabled>
<el-option value="ipv4" label="ipv4" disabled></el-option>
</el-select>
</basic-form-item>
</el-col>
</el-row>
<el-row style="margin-top: 20px">
<el-col :span="24">
<basic-form-item label="侦听器: " validate="required">
<basic-table :data="dataList2" v-if="addData.configs.loadBalancerType === 'application'">
<el-table-column label="负载均衡器协议" prop="protocol">
<template slot-scope="scope">
<el-select style="width: 50%" v-model="scope.row.protocol" @change="changeData1(scope.row.protocol, scope.$index)">
<el-option value="HTTP" label="HTTP"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="负载均衡器端口" prop="port">
<template slot-scope="scope">
<el-input style="width: 50%" v-model="scope.row.port"></el-input>
</template>
</el-table-column>
<el-table-column width="200" label="操作">
<template slot-scope="scope">
<el-button type="text" @click.native.prevent="deleteRow(scope.$index, dataList2)"><i class="el-icon-delete"></i> 删除 </el-button>
</template>
</el-table-column>
<div slot="pagination"></div>
</basic-table>
<basic-table :data="dataList" v-if="addData.configs.loadBalancerType === 'network'">
<el-table-column label="负载均衡器协议" prop="protocol">
<template slot-scope="scope">
<el-select style="width: 50%" v-model="scope.row.protocol" @change="changeData2(scope.row.protocol, scope.$index)">
<el-option value="TCP" label="TCP"></el-option>
<el-option value="TCP_UDP" label="TCP_UDP"></el-option>
<el-option value="UDP" label="UDP"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column label="负载均衡器端口" prop="port">
<template slot-scope="scope">
<el-input style="width: 50%" v-model="scope.row.port"></el-input>
</template>
</el-table-column>
<el-table-column width="200" label="操作">
<template slot-scope="scope">
<el-button type="text" @click.native.prevent="deleteRow(scope.$index, dataList)"><i class="el-icon-delete"></i> 删除 </el-button>
</template>
</el-table-column>
<div slot="pagination"></div>
</basic-table>
<el-button style="margin-top: 10px" type="primary" @click="addRow"></el-button>
</basic-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<basic-form-item label="VPC" validate="required">
<el-select @change="handleSubNets" v-model="vpcModel" value-key="vpcId" clearable>
<el-option v-for="(item, index) in vpcList" :key="index" :label="item.vpcValue" :value="item"></el-option>
</el-select>
</basic-form-item>
</el-col>
</el-row>
<el-row style="margin-top: 10px">
<el-col :span="24">
<basic-form-item label="可用区:" validate="required">
<el-row v-if="showNorth1a">
<el-col :span="3">
<el-checkbox v-model="northA_checked">cn-north-1a</el-checkbox>
</el-col>
<el-col :span="21">
<el-row>
<el-select v-model="subNetValueA" style="width: 50%" @change="changePrivateAddressA" value-key="id" :disabled="!northA_checked">
<el-option v-for="(item, index) in cnNorth1AList" :key="index" :label="item.subNetValueA" :value="item"> </el-option>
</el-select>
</el-row>
</el-col>
<el-col :span="24">
<el-row v-if="northA_checked" style="margin-top: 20px">
<el-col :span="2">IPv4地址</el-col>
<el-col :span="1">
<el-tooltip class="item" effect="dark" content="Virtual Private Cloud (VPC) 是品高云内您自己的逻辑隔离区域中的虚拟网络。请选择您为目标实例选择的同一 VPC。" placement="top">
<i class="el-icon-info"></i>
</el-tooltip>
</el-col>
<el-col :span="8" v-if="addData.configs.scheme === 'internet-facing' && addData.configs.loadBalancerType === 'network'">
<el-select v-model="Ipv4_addressA" @change="hanldeElastic">
<el-option label="由AWS分配" value="BINGOCLOUDOS"></el-option>
<el-option label="选择弹性IP" value="IP"></el-option>
</el-select>
<el-select v-model="Ipv4_Elastic_Val_A" v-if="Ipv4_addressA == 'IP'" style="margin-top: 10px">
<el-option v-for="(item, index) in elasticList" :key="index" :label="item.publicIp + '(' + item.elasticIpUuid + ')'" :value="item.id"></el-option>
</el-select>
</el-col>
<el-col :span="8" v-if="addData.configs.scheme === 'internet-facing' && addData.configs.loadBalancerType === 'application'">
<el-row>
<span>由AWS分配</span>
</el-row>
</el-col>
<el-col :span="8" v-if="addData.configs.scheme === 'internal' && addData.configs.loadBalancerType === 'network'">
<el-row>
<span>从CIDR分配{{ cidr }}</span>
</el-row>
</el-col>
<el-col v-if="addData.configs.scheme === 'internal' && addData.configs.loadBalancerType === 'application'" :span="21"> CIDR{{ cidr }} </el-col>
<el-col v-if="showIpv6 && addData.configs.loadBalancerType === 'application' && addData.configs.scheme === 'internet-facing' && addData.configs.ipAddressType == 'dualstack'">
<el-col :span="2">IPv6地址</el-col>
<el-col :span="1" style="margin-left: -40px">
<el-tooltip class="item" effect="dark" content="节点的 IPv6 地址从子网 CIDR 分配。" placement="top">
<i class="el-icon-info"></i>
</el-tooltip>
</el-col>
<el-col v-if="ipv6_cidr && addData.configs.loadBalancerType === 'application'" :span="8">{{ ipv6_cidr }}</el-col>
<el-col v-else :span="8"></el-col>
</el-col>
<el-col v-if="showIpv6 && addData.configs.loadBalancerType === 'network' && addData.configs.scheme === 'internet-facing' && addData.configs.ipAddressType == 'dualstack'">
<el-col :span="2">IPv6地址</el-col>
<el-col :span="1" style="margin-left: -40px">
<el-tooltip class="item" effect="dark" content="节点的 IPv6 地址从子网 CIDR 分配。" placement="top">
<i class="el-icon-info"></i>
</el-tooltip>
</el-col>
<el-col v-if="ipv6_cidr" :span="8">
<el-select v-model="north1A_CIDR_value">
<el-option :label="'从CIDR分配' + ipv6_cidr" value="assign"></el-option>
<el-option :label="'从CIDR输入 IP' + ipv6_cidr" value="input"></el-option>
</el-select>
<basic-form-item v-if="addData.configs.ipAddressType == 'dualstack' && north1A_CIDR_value == 'input'" maxlength="64">
<el-input v-model="private_Ipv6_input_A" placeholder="IPv6地址"></el-input>
</basic-form-item>
</el-col>
<el-col v-if="ipv6_cidr && addData.configs.loadBalancerType === 'application'" :span="8">{{ ipv6_cidr }}</el-col>
<el-col v-if="!ipv6_cidr" :span="8"></el-col>
</el-col>
</el-row>
<el-row v-if="classificationStatus && northA_checked && addData.configs.loadBalancerType === 'network'" style="margin: 10px 0 0 -28px">
<el-col :span="3">私有IPv4地址</el-col>
<el-col :span="8" style="margin-left: -40px">
<el-select v-model="north1A_CIDR_value">
<el-option :label="'从CIDR分配' + cidr" value="assign"></el-option>
<el-option :label="'从CIDR输入' + cidr" value="input"></el-option>
</el-select>
<basic-form-item v-if="addData.configs.ipAddressType == 'ipv4' && north1A_CIDR_value == 'input'" maxlength="64">
<el-input v-model="private_Ipv4_input_A" placeholder="私有IPv4地址"></el-input>
</basic-form-item>
</el-col>
</el-row>
</el-col>
</el-row>
<el-row v-if="showNorth1B" :style="showNorth1a ? 'margin-top: 20px;' : ''">
<el-col :span="3">
<el-checkbox v-model="northB_checked">cn-north-1b</el-checkbox>
</el-col>
<el-col :span="21">
<el-row>
<el-select v-model="subNetValueB" style="width: 50%" @change="changePrivateAddressB" value-key="id" :disabled="!northB_checked">
<el-option v-for="(item, index) in cnNorth1BList" :key="index" :label="item.subNetValueB" :value="item"></el-option>
</el-select>
</el-row>
</el-col>
<el-col :span="24">
<el-row v-if="northB_checked" style="margin-top: 20px">
<el-col :span="2">IPv4地址</el-col>
<el-col :span="1">
<el-tooltip class="item" effect="dark" content="对于面向 Internet 的负载均衡器,节点的 IPv4 地址由 品高云 分配,您也可以选择您的其中一个弹性 IP 地址。对于内部负载均衡器IPv4 地址从子网 CIDR 分配。" placement="top">
<i class="el-icon-info"></i>
</el-tooltip>
</el-col>
<el-col :span="8" v-if="addData.configs.scheme === 'internet-facing' && addData.configs.loadBalancerType === 'network'">
<el-select v-model="Ipv4_addressB" @change="hanldeElastic">
<el-option label="由品高云分配" value="BINGOCLOUDOS"></el-option>
<el-option label="选择弹性IP" value="IP"></el-option>
</el-select>
<el-select v-model="Ipv4_Elastic_Val_B" v-if="Ipv4_addressB == 'IP'" style="margin-top: 10px">
<el-option v-for="(item, index) in elasticList" :key="index" :label="item.publicIp + '(' + item.elasticIpUuid + ')'" :value="item.id"></el-option>
</el-select>
</el-col>
<el-col :span="8" v-if="addData.configs.scheme === 'internet-facing' && addData.configs.loadBalancerType === 'application'">
<el-row>
<span>由AWS分配</span>
</el-row>
</el-col>
<el-col :span="8" v-if="addData.configs.scheme === 'internal' && addData.configs.loadBalancerType === 'network'">
<el-row>
<span>从CIDR分配{{ cidrB }}</span>
</el-row>
</el-col>
<el-col v-if="addData.configs.scheme === 'internal' && addData.configs.loadBalancerType === 'application'" :span="21"> CIDR{{ cidrB }} </el-col>
<el-col v-if="showIpv6 && addData.configs.scheme === 'internet-facing' && addData.configs.ipAddressType == 'dualstack'">
<el-col :span="2">IPv6地址</el-col>
<el-col :span="1" style="margin-left: -40px">
<el-tooltip class="item" effect="dark" content="节点的 IPv6 地址从子网 CIDR 分配。" placement="top">
<i class="el-icon-info"></i>
</el-tooltip>
</el-col>
<el-col v-if="ipv6_cidrB && addData.configs.loadBalancerType === 'network'" :span="8">
<el-select v-model="north1B_CIDR_value">
<el-option :label="'从CIDR分配' + ipv6_cidrB" value="assign"></el-option>
<el-option :label="'从CIDR输入 IP' + ipv6_cidrB" value="input"></el-option>
</el-select>
<basic-form-item v-if="addData.configs.ipAddressType == 'dualstack' && north1B_CIDR_value == 'input'" maxlength="64">
<el-input v-model="private_Ipv6_input_B" placeholder="IPv6地址"></el-input>
</basic-form-item>
</el-col>
<el-col v-if="ipv6_cidrB && addData.configs.loadBalancerType === 'application'" :span="8">{{ ipv6_cidrB }}</el-col>
<el-col v-if="!ipv6_cidrB" :span="8"></el-col>
</el-col>
</el-row>
<el-row v-if="classificationStatus && northB_checked && addData.configs.loadBalancerType === 'network'" style="margin: 10px 0 0 -28px">
<el-col :span="3">私有IPv4地址</el-col>
<el-col :span="8" style="margin-left: -40px">
<el-select v-model="north1B_CIDR_value">
<el-option :label="'从CIDR分配' + cidrB" value="assign"></el-option>
<el-option :label="'从CIDR输入' + cidrB" value="input"></el-option>
</el-select>
<basic-form-item v-if="addData.configs.ipAddressType == 'ipv4' && north1B_CIDR_value == 'input'" maxlength="64">
<el-input v-model="private_Ipv4_input_B" placeholder="私有IPv4地址"></el-input>
</basic-form-item>
</el-col>
</el-row>
</el-col>
</el-row>
</basic-form-item>
</el-col>
</el-row>
<el-row class="top_margin_border">
<!-- <el-form :inline="true" v-if="addData.configs.loadBalancerType === 'application'">
<el-form-item label="筛选条件:">
<el-select v-model="safeOptions" @change="changeSafeGroup">
<el-option label="VPC 安全组" value="vpc"></el-option>
<el-option label="EC2 安全组" value="ec2"></el-option>
</el-select>
</el-form-item>
</el-form> -->
</el-row>
<basic-form-item label-width="140px" label="安全组: " validate="required" v-if="addData.configs.loadBalancerType === 'application'">
<basic-table :data="safeTableData" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column prop="groupUuid" label="安全组ID"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
<el-table-column prop="remark" label="描述"></el-table-column>
<div slot="pagination"></div>
</basic-table>
</basic-form-item>
</basic-form>
</common-wrapper>
</template>
<script>
import CommonWrapper from 'views/resource-apply/components/PublicCommonWrapper.vue';
import { add, element } from '../data/publicInit'
import { cloneDeep } from 'lodash-es'
import { getShoppingCartDetail } from 'services/system/shop_cart'
import { getTargetgroups, getTargets, getVpcData, getSubNetsList, getSafeTableData, getElasticIp } from 'services/platform/bingoCloudOS'
export default {
components: { CommonWrapper },
props: {
type: {
type: String
},
itemData: {
type: [Object, Boolean]
},
disabled: {
type: Boolean
}
},
data () {
return {
elements: [{
...element,
name: '负载均衡',
serviceCode: 'network.bingoCloudOS.slb',
main: true
}
],
addData: {
...cloneDeep(add),
location: {
...add.location,
vendorType: this.type
},
service: 'network.bingoCloudOS.slb',
configs: {
name: '',
loadBalancerType: 'network',
scheme: 'internet-facing',
ipAddressType: 'ipv4',
availabilityZones: []
}
},
retention: false,
//
detailTableData: [],
tableData: [],
params: {
page: 1,
rows: 9999
},
paramd: {
page: 1,
rows: 9999
},
publicParams: {
page: 1,
rows: 9999
},
safeTableParams: {
page: 1,
rows: 10
},
private_Ipv4_input_A: '',
private_Ipv4_input_B: '',
private_Ipv6_input_A: '',
private_Ipv6_input_B: '',
regionId: 'cn-north-1',
tempStore: '',
listeners: [],
CheckPort: '',
runStatePath: '/',
runStateProtocol: 'HTTP',
aimClassification: 'instance',
aimGroupName: '',
protocolVersion: 'HTTP1',
aimPort: 80,
aimProtocol: 'HTTP',
protocol: '',
classificationSelection: '',
safeOptions: '',
regionList: '',
north1A_CIDR_value: 'assign',
north1B_CIDR_value: 'assign',
vpcList: [],
vpcValue: '',
vpcId: '',
assignSafeRadio: 3, //
input: '',
classification: '',
classificationStatus: false,
dataList: [{ protocol: 'TCP', port: 80 }],
dataList2: [{ protocol: 'HTTP', port: 80 }],
northA_checked: false, // cn-north-1a
northB_checked: false, // cn-north-1b
showNorth1a: true,
showNorth1B: true, // cn-north-1b
cnNorth1AList: [],
cnNorth1BList: [],
subNetValueA: '',
subNetValueB: '',
Ipv4_addressA: 'BINGOCLOUDOS',
Ipv4_addressB: 'BINGOCLOUDOS',
elasticList: [],
Ipv4_Elastic_Val_A: '',
Ipv4_Elastic_Val_B: '',
zone: '',
north1A_CIDR: '',
north1B_CIDR: '',
subNetList: [],
cidr: '',
cidrB: '',
showIpv6: false,
ipv6_cidr: '',
ipv6_cidrB: '',
safeTableData: [], //
vpcModel: ''
}
},
computed: {
currentElement () {
return this.elements[0]
}
},
created () {
if (this.itemData) {
this.retention = this.itemData
this.addData = cloneDeep(this.retention)
const { elements } = this.retention
const [first, ...others] = elements
this.elements = [
{
...element,
...first
}
]
} else if (this.$route.query.id) {
getShoppingCartDetail(this.$route.query.id).then(data => {
if (data.success) {
this.retention = JSON.parse(data.data.inventory)
this.addData = cloneDeep(this.retention)
const { elements } = this.retention
const [first, ...others] = elements
this.elements = [
{
...element,
...first
}
]
}
})
}
},
watch: {
'addData.location.vendorType' () {
this.$emit('type', this.addData.location.vendorType)
},
northB_checked(newVal, oldVal) {
if (this.cnNorth1BList.length && newVal) {
this.addData.configs.availabilityZones[1] = { sId: this.cnNorth1BList[0].id }
} else {
this.addData.configs.availabilityZones.pop()
}
}
},
methods: {
getPostData () {
let data = false
data = this.$refs.common.handlePostData()
return data
},
getParams () {
let data = false;
this.$refs.addForm.validate(valid => {
if (valid) {
if (this.dataList.length) {
for (let i = 0; i < this.dataList.length; i++) {
if (this.dataList[i].protocol == '选择协议' || this.dataList[i].port == '') {
return this.$message.error('请填写侦听器相关信息')
}
}
} else {
return this.$message.error('至少添加一个侦听器')
}
if (this.addData.configs.availabilityZones.length <= 1 || this.northA_checked == false || this.northB_checked == false) {
return this.$message.error('当前vpc不可用,必须指定至少两个子网')
}
if (this.Ipv4_addressA == 'IP' && this.Ipv4_addressB == 'IP' && this.Ipv4_Elastic_Val_A == this.Ipv4_Elastic_Val_B) return this.$message.error('弹性IP地址不可相同')
if (this.addData.configs.loadBalancerType === 'network') {
this.addData.configs.availabilityZones[0].loadBalancerAddresses = []
this.addData.configs.availabilityZones[1].loadBalancerAddresses = []
if (this.addData.configs.scheme === 'internet-facing' || (this.addData.configs.scheme === 'internal' && this.north1A_CIDR_value != 'input' && this.north1B_CIDR_value != 'input')) {
this.addData.configs.availabilityZones[0].loadBalancerAddresses[0] = { eipId: this.Ipv4_Elastic_Val_A }
this.addData.configs.availabilityZones[1].loadBalancerAddresses[0] = { eipId: this.Ipv4_Elastic_Val_B }
}
if (this.north1A_CIDR_value == 'input' && this.north1B_CIDR_value == 'input') {
this.addData.configs.availabilityZones[0].loadBalancerAddresses[0] = { privateIPv4Address: this.private_Ipv4_input_A }
this.addData.configs.availabilityZones[1].loadBalancerAddresses[0] = { privateIPv4Address: this.private_Ipv4_input_B }
if (this.private_Ipv4_input_A && this.private_Ipv4_input_B && this.private_Ipv4_input_A == this.private_Ipv4_input_B) {
return this.$message.error('输入的私有IPv4地址不能相同')
}
}
if ((this.north1A_CIDR_value == 'input' && this.north1B_CIDR_value != 'input') || (this.north1A_CIDR_value != 'input' && this.north1B_CIDR_value == 'input')) {
return this.$message.error('输入的私有Ipv4或Ipv6地址需同时存在')
}
if (this.addData.configs.ipAddressType == 'dualstack') {
if (this.ipv6_cidr == null) {
return this.$message.error('所选的子网必须具有IP地址类型所需的CIDR块')
}
if (this.north1A_CIDR_value == 'input' && this.north1B_CIDR_value == 'input') {
this.addData.configs.availabilityZones[0].loadBalancerAddresses[0] = { iPv6Address: this.private_Ipv6_input_A }
this.addData.configs.availabilityZones[1].loadBalancerAddresses[0] = { iPv6Address: this.private_Ipv6_input_B }
}
}
this.dataList.forEach((item, index) => {
if (index + 1 < this.dataList.length) {
if (item.port == this.dataList[index + 1].port) return this.$message.error('端口号不能相同')
}
})
data = {
balancer: this.addData.configs,
listeners: this.dataList,
targetGroup: { id: this.tempStore }
}
} else {
const safeGroup = []
this.securityGroups.forEach(item => {
safeGroup.push({ id: item.id })
})
if (safeGroup.length == 0) {
return this.$message.error('至少选择一个安全组')
}
const newBalancer = JSON.parse(JSON.stringify(this.addData.configs))
newBalancer.securityGroups = safeGroup
data = {
balancer: newBalancer,
listeners: this.dataList2,
targetGroup: { id: this.tempStore }
}
}
}
})
return data;
},
selectType() {
if (this.addData.configs.loadBalancerType === 'application') {
this.listeners = this.dataList
}
if (this.addData.configs.loadBalancerType === 'network') {
this.listeners = this.dataList
}
this.getData()
},
handleDetailSearch() {
const params = [{ param: { tgId: this.tempStore[0] }, sign: 'EQ' }]
this.paramd.params = JSON.stringify(params)
this.getDetailData()
},
getDetailData() {
getTargets(this.paramd).then(data => {
if (data.success) {
this.detailTableData = data.data.rows
this.totald = data.data.total
}
})
},
handleSearch() {
this.getData()
this.getVpcList()
this.hanldeElastic()
this.params.params = this.$tools.handleSearchParam({
vendorId: this.addData.location.vendorId,
regionId: this.addData.location.region
})
},
getData() {
const targetGroupsParams = JSON.parse(JSON.stringify(this.publicParams))
if (this.addData.configs.loadBalancerType === 'application') {
targetGroupsParams.params = JSON.stringify([
{
param: {
vendorId: this.addData.location.vendorId,
loadBalancerUuids: '[]',
vpcUuid: this.vpcId,
regionId: this.addData.location.region
},
sign: 'EQ'
},
{
param: {
protocol: '"HTTP"'
},
sign: 'IN'
}
])
} else {
const protocolData = JSON.parse(JSON.stringify(this.dataList))
const isTCP = protocolData.every(item => {
return item.protocol == 'TCP'
})
const isUDP = protocolData.every(item => {
return item.protocol == 'UDP'
})
for (let i = 0; i < protocolData.length; i++) {
if (isTCP) {
this.protocol = '"TCP"'
} else {
this.protocol = '"TCP_UDP"'
}
if (isUDP) {
this.protocol = '"UDP"'
}
}
targetGroupsParams.params = JSON.stringify([
{
param: {
vendorId: this.addData.location.vendorId,
loadBalancerUuids: '[]',
vpcUuid: this.vpcId,
regionId: this.addData.location.region
},
sign: 'EQ'
},
{
param: {
protocol: this.protocol
},
sign: 'IN'
}
])
}
getTargetgroups(targetGroupsParams).then(data => {
if (data.success) {
this.tableData = data.data.rows
if (this.tableData.length) {
this.tempStore = this.tableData[0].id
} else {
this.tempStore = ''
}
this.total = data.data.total
}
})
},
changeData1(name, index) {
switch (name) {
case 'HTTP':
this.dataList2[index].port = 80
break
// case 'HTTPS':
// this.dataList2[index].port = 443
// break
}
},
changeData2(name, index) {
switch (name) {
case 'TCP':
this.dataList[index].port = 80
break
case 'TCP_UDP':
this.dataList[index].port = 53
break
case 'UDP':
this.dataList[index].port = 53
}
this.getData()
},
deleteRow(index, rows) {
rows.splice(index, 1)
this.getData()
},
addRow() {
if (this.addData.configs.loadBalancerType === 'network') {
this.dataList.push({ protocol: '选择协议', port: '' })
}
if (this.addData.configs.loadBalancerType === 'application') {
this.dataList2.push({ protocol: 'HTTP', port: 80 })
}
},
changeClassification() {
if (this.addData.configs.scheme === 'internal') {
this.addData.configs.ipAddressType = 'ipv4'
this.classificationStatus = true
} else {
this.addData.configs.ipAddressType = 'ipv4'
this.classificationStatus = false
}
},
goBack() {
sessionStorage.setItem('platformId', this.serverId)
this.$router.back(-1)
},
getVpcList() {
const params = JSON.stringify([{ param: { regionId: this.addData.location.region, vendorId: this.addData.location.vendorId }, sign: 'EQ' }])
const vpcParams = JSON.parse(JSON.stringify(this.publicParams))
vpcParams.params = params
getVpcData(vpcParams).then(data => {
this.vpcList = data.data.rows
this.vpcList.forEach((item, index) => {
item.vpcValue = `${item.vpcId} (${item.cidr}) | ${item.name}`
})
this.vpcModel = this.vpcList[0]
if (this.vpcList.length > 0) {
this.handleSubNets()
this.getSafeTableList()
this.getData()
}
})
},
handleSubNets() {
this.vpcId = this.vpcModel.vpcId
this.Ipv4_addressA = 'BINGOCLOUDOS'
this.Ipv4_addressB = 'BINGOCLOUDOS'
this.getData()
this.northA_checked = this.northB_checked = false
const params = JSON.stringify([{ param: { networkId: this.vpcModel.id, vendorId: this.addData.location.vendorId }, sign: 'EQ' }])
const subNetsParams = JSON.parse(JSON.stringify(this.publicParams))
subNetsParams.params = params
getSubNetsList(subNetsParams).then(data => {
this.subNetList = data.data.rows
if (this.addData.location.region == 'cn-north-1') {
this.cnNorth1AList = this.subNetList.filter(item => item.zone == 'cn-north-1a')
} else {
this.cnNorth1AList = this.subNetList.filter(item => item.zone == 'cn-northwest-1a')
}
if (this.cnNorth1AList.length) {
this.addData.configs.availabilityZones[0] = { sId: this.cnNorth1AList[0].id }
this.cidr = this.cnNorth1AList[0].cidr
this.ipv6_cidr = this.cnNorth1AList[0].ipv6Cidr
this.showNorth1a = true
} else {
this.showNorth1a = false
}
this.cnNorth1BList = this.subNetList.filter(item1 => item1.zone == 'cn-north-1b')
if (this.cnNorth1BList.length) {
this.ipv6_cidrB = this.cnNorth1BList[0].ipv6Cidr
this.cidrB = this.cnNorth1BList[0].cidr
this.showNorth1B = true
} else {
this.showNorth1B = false
}
this.subNetList.forEach((item, index) => {
this.zone = item.zone
if ((item.zone == 'cn-north-1a' || item.zone == 'cn-northwest-1a') && (this.addData.configs.scheme === 'internet-facing' || this.addData.configs.scheme === 'internal')) {
item.subNetValueA = `${item.subnetUuid} (${item.name})`
this.subNetValueA = this.cnNorth1AList[0]
} else {
item.subNetValueB = `${item.subnetUuid} (${item.name})`
this.subNetValueB = this.cnNorth1BList[0]
}
})
})
},
// cn-north-1a
changePrivateAddressA(e) {
this.addData.configs.availabilityZones[0] = { sId: e.id }
this.ipv6_cidr = e.ipv6Cidr
this.cidr = e.cidr
},
// cn-north-1b
changePrivateAddressB(e) {
this.addData.configs.availabilityZones[1] = { sId: e.id }
this.ipv6_cidrB = e.ipv6Cidr
this.cidrB = e.cidr
},
changeIpAddressType(e) {
if (e === 'ipv4') {
this.showIpv6 = false
} else {
this.showIpv6 = true
}
},
getSafeTableList() {
this.safeTableParams.params = JSON.stringify([{ param: { vpcId: this.vpcModel.id, vendorId: this.addData.location.vendorId }, sign: 'EQ' }])
getSafeTableData(this.safeTableParams).then(data => {
this.safeTableData = data.data.rows
})
},
handleSelectionChange(row) {
this.securityGroups = row
},
// ip
hanldeElastic() {
if (this.Ipv4_addressA == 'IP' || this.Ipv4_addressB == 'IP') {
const params = JSON.stringify([
{ param: { regionId: this.addData.location.region, vendorId: this.addData.location.vendorId }, sign: 'EQ' },
{
param: {
associationId: ''
},
sign: 'NUL'
}
])
const subNetsParams = JSON.parse(JSON.stringify(this.publicParams))
subNetsParams.params = params
getElasticIp(subNetsParams).then(data => {
this.elasticList = data.data.rows
if (this.elasticList.length && this.Ipv4_addressA == 'IP') {
this.Ipv4_Elastic_Val_A = this.elasticList[0].id
}
if (this.elasticList.length && this.Ipv4_addressB == 'IP') {
this.Ipv4_Elastic_Val_B = this.elasticList[0].id
}
})
} else {
this.elasticList = []
}
}
}
}
</script>
<style scoped lang="scss">
</style>

View File

@ -5,12 +5,14 @@
<div> <div>
<ali :type="type" v-if="type == 'ALIYUN'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></ali> <ali :type="type" v-if="type == 'ALIYUN'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></ali>
<aws :type="type" v-else-if="type == 'AWS'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></aws> <aws :type="type" v-else-if="type == 'AWS'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></aws>
<bingoCloudOS :type="type" v-else-if="type == 'BINGOCLOUDOS'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></bingoCloudOS>
</div> </div>
</template> </template>
<script> <script>
import ali from './ali.vue' import ali from './ali.vue'
import aws from './aws.vue' import aws from './aws.vue'
import bingoCloudOS from './bingoCloudOS.vue'
export default { export default {
props: { props: {
itemData: { itemData: {
@ -20,7 +22,7 @@ export default {
type: Boolean type: Boolean
} }
}, },
components: { ali, aws }, components: { ali, aws, bingoCloudOS },
data () { data () {
return { return {
type: '' type: ''

View File

@ -0,0 +1,154 @@
/**
* Created by HaijunZhang on 2019/4/28.
*/
<template>
<common-wrapper code="network" :add-data="addData" ref="common" :elements="elements" :get-params="getParams" :item-data="retention" :disabled="disabled" v-if="isLoadData">
<basic-form :model="addData.configs" ref="addForm" label-position="left">
<el-divider></el-divider>
<h5>配置信息</h5>
<el-row :gutter="20">
<el-col :span="12">
<basic-form-item label="cidr: " prop="cidr" validate="required,cidr">
<el-input v-model="addData.configs.cidr"></el-input>
</basic-form-item>
</el-col>
<el-col :span="13">
<basic-form-item label="IPV6 CIDR" prop="providedIpv6Cidr" validate="required" label-width="120px">
<el-radio-group v-model="addData.configs.providedIpv6Cidr">
<el-radio label="0">无IPV6 CIDR</el-radio>
<el-radio label="1">Amazon</el-radio>
</el-radio-group>
</basic-form-item>
</el-col>
</el-row>
<el-divider></el-divider>
<h5>云配置信息</h5>
<el-row :gutter="20">
<el-col :span="10">
<basic-form-item label="名称:" validate="required" prop="name">
<el-input v-model="addData.configs.name" placeholder="请输入名称"></el-input>
</basic-form-item>
</el-col>
</el-row>
</basic-form>
</common-wrapper>
</template>
<script>
import CommonWrapper from 'views/resource-apply/components/PublicCommonWrapper.vue';
import { add, element } from '../data/publicInit'
import { cloneDeep } from 'lodash-es'
import { getShoppingCartDetail } from 'services/system/shop_cart'
export default {
components: { CommonWrapper },
props: {
type: {
type: String
},
itemData: {
type: [Object, Boolean]
},
disabled: {
type: Boolean
}
},
data () {
return {
elements: [{
...element,
name: 'VPC',
serviceCode: 'bingocloudos.standard.vpc',
main: true
}
],
addData: {
...cloneDeep(add),
location: {
...add.location,
vendorType: this.type
},
service: 'bingocloudos.standard.vpc',
configs: {
providedIpv6Cidr: '0',
cidr: ''
}
},
retention: false,
isLoadData: false
}
},
computed: {
currentElement () {
return this.elements[0]
}
},
created () {
if (this.itemData) {
this.retention = this.itemData
this.addData = cloneDeep(this.retention)
const { elements } = this.retention
const [first, ...others] = elements
this.elements = [
{
...element,
...first
}
]
} else if (this.$route.query.id) {
getShoppingCartDetail(this.$route.query.id).then(data => {
if (data.success) {
this.retention = JSON.parse(data.data.inventory)
this.addData = cloneDeep(this.retention)
const { elements } = this.retention
const [first, ...others] = elements
this.elements = [
{
...element,
...first
}
]
}
})
} else {
this.addData = {
...add,
location: {
...add.location,
vendorType: this.type
},
service: 'bingocloudos.standard.vpc',
configs: {
providedIpv6Cidr: '0',
cidr: ''
}
}
}
this.isLoadData = true
},
watch: {
'addData.location.vendorType' () {
this.$emit('type', this.addData.location.vendorType)
}
},
methods: {
getPostData () {
let data = false
data = this.$refs.common.handlePostData()
return data
},
getParams () {
let data = false;
this.$refs.addForm.validate(valid => {
if (valid) {
data = true
}
})
return data;
}
}
}
</script>
<style scoped lang="scss">
</style>

View File

@ -5,6 +5,7 @@
<div> <div>
<op :type="type" v-if="type == 'OPENSTACK'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></op> <op :type="type" v-if="type == 'OPENSTACK'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></op>
<aws :type="type" v-if="type == 'AWS'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></aws> <aws :type="type" v-if="type == 'AWS'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></aws>
<bingoCloudOS :type="type" v-if="type == 'AWS'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></bingoCloudOS>
<ali :type="type" v-if="type == 'ALIYUN'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></ali> <ali :type="type" v-if="type == 'ALIYUN'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></ali>
<huawei :type="type" v-if="type == 'HUAWEI'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></huawei> <huawei :type="type" v-if="type == 'HUAWEI'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></huawei>
<tencent :type="type" v-if="type == 'TENCENT'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></tencent> <tencent :type="type" v-if="type == 'TENCENT'" @type="setType" :item-data="itemData" :disabled="disabled" ref="node"></tencent>
@ -19,6 +20,7 @@ import op from './op.vue'
import tencent from './tencent.vue' import tencent from './tencent.vue'
import tce from './tce.vue' import tce from './tce.vue'
import aws from './aws.vue' import aws from './aws.vue'
import bingoCloudOS from './bingoCloudOS.vue'
export default { export default {
props: { props: {
itemData: { itemData: {
@ -28,7 +30,7 @@ export default {
type: Boolean type: Boolean
} }
}, },
components: { ali, op, huawei, tencent, aws, tce }, components: { ali, op, huawei, tencent, aws, bingoCloudOS, tce },
data () { data () {
return { return {
type: '' type: ''