| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147 |
- <template>
- <div>
- <page-header :title="$t('network.text_570')" :tabs="cloudEnvOptions" :current-tab.sync="cloudEnv" />
- <page-body need-margin-bottom>
- <a-form class="mt-3" :form="form.fc" @submit.prevent="handleSubmit" v-bind="formItemLayout" hideRequiredMark>
- <a-form-item :label="$t('network.text_205', [$t('dictionary.project')])" class="mt-3" v-bind="formItemLayout">
- <domain-project :fc="form.fc" :decorators="{ project: decorators.project, domain: decorators.domain }" @update:domain="handleDomainChange" />
- </a-form-item>
- <area-selects
- class="mb-0"
- ref="areaSelects"
- :wrapperCol="formItemLayout.wrapperCol"
- :labelCol="formItemLayout.labelCol"
- :names="areaselectsName"
- :providerParams="providerParams"
- :cloudregionParams="cloudregionParams"
- :isRequired="true"
- filterBrandResource="network_manage"
- @change="handleRegionChange" />
- <a-form-item :label="$t('network.text_21')" v-bind="formItemLayout">
- <a-input v-decorator="decorators.name" :placeholder="$t('validator.resourceName')" />
- </a-form-item>
- <a-form-item :label="$t('common.description')" v-bind="formItemLayout">
- <a-textarea :auto-size="{ minRows: 1, maxRows: 3 }" v-decorator="decorators.description" :placeholder="$t('common_367')" />
- </a-form-item>
- <a-form-item label="VPC" v-bind="formItemLayout">
- <base-select
- v-decorator="decorators.vpc"
- resource="vpcs"
- :params="vpcParams"
- :isDefaultSelect="true"
- :needParams="true"
- @change="vpcChange"
- :item.sync="curVpc"
- :labelFormat="vpcLabelFormat"
- :select-props="{ placeholder: $t('common_226') }" />
- </a-form-item>
- <a-form-item :label="$t('network.text_571')" v-bind="formItemLayout" v-if="show || isShowWire">
- <base-select
- resource="wires"
- v-decorator="decorators.wire"
- :selectProps="{ 'placeholder': $t('network.text_572') }"
- :isDefaultSelect="true"
- :item.sync="curWire"
- :labelFormat="wireLabelFormat"
- :params="wireParams" />
- </a-form-item>
- <a-form-item :label="$t('network.text_24')" :extra="$t('network.text_573')" v-bind="formItemLayout" v-if="!show && !isShowWire">
- <a-select v-decorator="decorators.zone" :placeholder="$t('network.text_287')" :filterOption="filterOption" show-search>
- <a-select-option v-for="item in zoneList" :key="item.id" :value="item.id">{{item.name}}</a-select-option>
- </a-select>
- </a-form-item>
- <a-form-item :label="$t('network.text_574')" v-bind="formItemLayout" v-if="show">
- <a-radio-group v-decorator="decorators.server_type">
- <a-radio-button
- v-for="item of serverTypeOpts"
- :disabled="item.disabled"
- :key="item.key"
- :value="item.key">{{ item.label }}</a-radio-button>
- </a-radio-group>
- </a-form-item>
- <!-- 网段 -->
- <a-form-item :label="$t('network.text_575')" v-bind="formItemLayout" required v-if="show">
- <template slot="extra">
- <div>{{$t('network.text_576')}}</div>
- <div>{{$t('network.text_577')}}</div>
- </template>
- <ip-subnets :decorator="decorators.ipSubnets" @clear-error="clearIpSubnetsError" />
- <div v-if="ipSubnetsHelp" class="error-tips">{{ ipSubnetsHelp }}</div>
- </a-form-item>
- <!-- 输入 网段 -->
- <a-form-item :label="$t('network.text_575')" :extra="$t('network.prefix_in_cidr_range.prompt', [curVpcCidrText])" v-bind="formItemLayout" v-if="!show && !isGroupGuestIpPrefix">
- <a-row :gutter="8">
- <a-col :span="12" v-if="curVpc && curVpc.cidr_block">
- <a-form-item class="mb-0">
- <a-input v-decorator="decorators.guest_ip_prefix(0)" :placeholder="$t('network.ipv4.prefix.prompt')" />
- </a-form-item>
- </a-col>
- <a-col :span="12" v-if="curVpc && curVpc.cidr_block6">
- <a-form-item class="mb-0">
- <a-input v-decorator="decorators.guest_ip6_prefix(0)" :placeholder="$t('network.ipv6.prefix.prompt')" />
- </a-form-item>
- </a-col>
- </a-row>
- <div v-if="guestIpPrefixHelp" class="error-tips">{{ guestIpPrefixHelp }}</div>
- </a-form-item>
- <a-form-item :label="$t('network.text_575')" v-bind="formItemLayout" :validate-status="guestIpPrefixValidateStatus" :help="guestIpPrefixHelp" required v-if="isGroupGuestIpPrefix">
- <template slot="extra">
- <div>{{$t('network.text_578')}}</div>
- <div>{{$t('network.text_580')}}</div>
- </template>
- <!-- 网段 -->
- <a-row :gutter="8" v-for="(item, i) in guestIpPrefix" :key="item.key">
- <a-col :span="11">
- <a-form-item>
- <a-input v-decorator="decorators.guest_ip_prefix(i)" :placeholder="$t('network.ipv4.subnet.input.prompt')" />
- </a-form-item>
- </a-col>
- <a-col :span="11">
- <a-form-item>
- <a-input v-decorator="decorators.guest_ip6_prefix(i)" :placeholder="$t('network.ipv6.subnet.input.prompt')" />
- </a-form-item>
- </a-col>
- <a-col :span="2">
- <a-button shape="circle" icon="minus" size="small" v-if="guestIpPrefix.length > 1" @click="decrease(i)" class="mt-2 ml-2" />
- </a-col>
- </a-row>
- <div class="d-flex align-items-center" v-if="remain > 0">
- <a-button type="primary" shape="circle" icon="plus" size="small" @click="addGuestIpPrefix" />
- <a-button type="link" @click="addGuestIpPrefix">{{$t('network.text_582')}}</a-button>
- <span class="count-tips">{{$t('network.text_169')}}<span class="remain-num">{{ remain }}</span>{{$t('network.text_170')}}</span>
- </div>
- </a-form-item>
- <a-form-item :label="$t('common_498')" v-if="isShowIsAutoAlloc">
- <a-switch v-decorator="decorators.is_auto_alloc" />
- <template slot="extra">{{$t('common_500')}}</template>
- </a-form-item>
- <a-form-item :label="$t('common.text00012')" class="mb-0">
- <tag
- v-decorator="decorators.__meta__" />
- </a-form-item>
- <a-collapse :bordered="false" v-if="isShowAdvanceOptions">
- <a-collapse-panel :header="$t('network.text_94')" key="1" forceRender>
- <a-form-item :label="$t('network.text_743')" v-bind="formItemLayout" v-if="hasBgpType">
- <a-input v-decorator="decorators.bgp_type" />
- <span slot="extra">{{$t('network.text_744')}}</span>
- </a-form-item>
- <a-form-item v-bind="formItemLayout">
- <span slot="label">{{$t('network.text_583')}}</span>
- <a-radio-group v-decorator="decorators.alloc_policy">
- <a-radio-button
- v-for="item of allocPolicyoptions"
- :key="item.key"
- :value="item.key">{{ item.label }}</a-radio-button>
- </a-radio-group>
- <span slot="extra" v-if="form.fc.getFieldValue('alloc_policy') === 'none'">{{$t('network.text_584')}}</span>
- </a-form-item>
- <a-form-item :label="$t('network.dns_server')" v-bind="formItemLayout">
- <a-input :placeholder="$t('validator.IPs')" v-decorator="decorators.guest_dns" />
- </a-form-item>
- <a-form-item v-bind="formItemLayout">
- <span slot="label">{{$t('network.text_586')}}</span>
- <template slot="extra">
- <div>{{$t('network.text_587')}}</div>
- <div>{{$t('network.text_588')}}</div>
- <div>{{$t('network.text_589')}}</div>
- <div>{{$t('network.text_590')}}</div>
- </template>
- <a-input :placeholder="$t('validator.domain')" v-decorator="decorators.guest_domain" />
- </a-form-item>
- <a-form-item :label="$t('network.ntp_server')" v-bind="formItemLayout">
- <a-input :placeholder="$t('validator.IPs_or_domains')" v-decorator="decorators.guest_ntp" />
- </a-form-item>
- <a-form-item label="dhcp_relay" v-if="show">
- <a-input class="w-50" v-decorator="decorators.guest_dhcp" :placeholder="$t('validator.IPs')" />
- </a-form-item>
- </a-collapse-panel>
- </a-collapse>
- <page-footer>
- <template v-slot:right>
- <a-button type="primary" html-type="submit" class="ml-3" :loading="submiting">{{$t('network.text_30')}}</a-button>
- <a-button class="ml-3" @click="() => $router.back()">{{$t('common.cancel')}}</a-button>
- </template>
- </page-footer>
- </a-form>
- </page-body>
- </div>
- </template>
- <script>
- import * as R from 'ramda'
- import { mapGetters } from 'vuex'
- import validateForm, { isRequired, REGEXP } from '@/utils/validate'
- import { Manager } from '@/utils/manager'
- import { uuid } from '@/utils/utils'
- import { typeClouds, getCloudEnvOptions } from '@/utils/common/hypervisor'
- import DomainProject from '@/sections/DomainProject'
- import AreaSelects from '@/sections/AreaSelects'
- import i18n from '@/locales'
- import { HYPERVISORS_MAP } from '@/constants'
- import Tag from '@/sections/Tag'
- import IpSubnets from './components/IpSubnets'
- const { networkSegment, networkSegment6 } = REGEXP
- const masks = {
- azure: { min: 8, max: 29 },
- qcloud: { min: 16, max: 28 },
- aliyun: { min: 17, max: 29 },
- aws: { min: 16, max: 28 },
- ucloud: { min: 16, max: 29 },
- huawei: { min: 16, max: 29 },
- onecloud: undefined,
- vmware: undefined,
- baremetal: undefined,
- openstack: undefined,
- zstack: undefined,
- dstack: undefined,
- }
- function validateGateway (rule, value, callback) {
- if (!value) {
- return callback()
- }
- // 只需要查看是否是以 0 结尾
- const ipItems = value.split('.')
- const msg = i18n.t('network.text_591')
- if (ipItems[ipItems.length - 1] === '0') {
- return callback(msg)
- }
- return callback()
- }
- function validateGateway6 (rule, value, callback) {
- if (!value) {
- return callback()
- }
- // 只需要查看是否是以 0 结尾
- const ipItems = value.split(':')
- const msg = i18n.t('network.text_591')
- if (ipItems[ipItems.length - 1] === '0') {
- return callback(msg)
- }
- return callback()
- }
- export default {
- name: 'NetworkCreate',
- components: {
- IpSubnets,
- DomainProject,
- AreaSelects,
- Tag,
- },
- data () {
- const cloudEnvOptions = getCloudEnvOptions('network_manage_brands', true)
- const queryType = this.$route.query.type
- let cloudEnv = queryType === 'idc' ? 'onpremise' : this.$route.query.type
- let routerQuery = this.$route.query.type
- if (!cloudEnvOptions.find(val => val.key === cloudEnv)) {
- cloudEnv = cloudEnvOptions[0].key
- routerQuery = cloudEnv === 'onpremise' ? 'idc' : cloudEnv
- }
- const prefixKey = uuid()
- return {
- submiting: false,
- cloudEnvOptions,
- cloudEnv,
- routerQuery,
- form: {
- fc: this.$form.createForm(this, { onValuesChange: this.handleValuesChange }),
- fd: {
- guest_ip_prefix: [],
- guest_ip6_prefix: [],
- },
- },
- ipSubnetsValidateStatus: '',
- guestIpPrefixValidateStatus: '',
- ipSubnetsHelp: '',
- guestIpPrefixHelp: '',
- formItemLayout: {
- wrapperCol: {
- md: { span: 18 },
- xl: { span: 20 },
- xxl: { span: 22 },
- },
- labelCol: {
- md: { span: 6 },
- xl: { span: 4 },
- xxl: { span: 2 },
- },
- },
- decorators: {
- domain: [
- 'domain',
- {
- rules: [
- { validator: isRequired(), message: i18n.t('rules.domain'), trigger: 'change' },
- ],
- },
- ],
- project: [
- 'project',
- {
- rules: [
- { validator: isRequired(), message: i18n.t('rules.project'), trigger: 'change' },
- ],
- },
- ],
- name: [
- 'name',
- {
- initialValue: '',
- validateFirst: true,
- rules: [
- { required: true, message: this.$t('network.text_116') },
- { validator: this.$validate('resourceName') },
- ],
- },
- ],
- description: ['description'],
- vpc: [
- 'vpc',
- {
- rules: [
- { required: true, message: this.$t('network.text_274') },
- ],
- },
- ],
- wire: [
- 'wire',
- {
- rules: [
- { required: true, message: this.$t('network.text_572') },
- ],
- },
- ],
- zone: [
- 'zone',
- {
- rules: [
- { required: true, message: this.$t('network.text_287') },
- ],
- },
- ],
- server_type: [
- 'server_type',
- {
- initialValue: '',
- rules: [
- { required: true, message: this.$t('network.text_592') },
- ],
- },
- ],
- alloc_policy: [
- 'alloc_policy',
- {
- initialValue: 'none',
- },
- ],
- guest_dns: [
- 'guest_dns',
- {
- initialValue: '',
- validateTrigger: ['change', 'blur'],
- rules: [
- { validator: this.$validate('IPs', false) },
- ],
- },
- ],
- guest_domain: [
- 'guest_domain',
- {
- initialValue: '',
- rules: [
- { validator: this.$validate('domain', false) },
- ],
- },
- ],
- guest_ntp: [
- 'guest_ntp',
- {
- initialValue: '',
- validateTrigger: ['change', 'blur'],
- rules: [
- { validator: this.$validate('IPs_or_domains', false) },
- ],
- },
- ],
- ipSubnets: {
- startip: i => [
- `startip[${i}]`,
- {
- initialValue: '',
- validateFirst: true,
- rules: [
- // { required: true, message: this.$t('network.text_593') },
- { validator: this.validateIpv4 },
- ],
- },
- ],
- endip: i => [
- `endip[${i}]`,
- {
- initialValue: '',
- validateFirst: true,
- rules: [
- // { required: true, message: this.$t('network.text_594') },
- { validator: this.validateIpv4 },
- ],
- },
- ],
- netmask: i => [
- `netmask[${i}]`,
- {
- initialValue: '24',
- rules: [
- { required: true, message: this.$t('network.text_595') },
- ],
- },
- ],
- gateway: i => [
- `gateway[${i}]`,
- {
- initialValue: '',
- validateTrigger: ['change', 'blur'],
- validateFirst: true,
- rules: [
- { validator: this.validateIpv4 },
- { validator: validateGateway },
- ],
- },
- ],
- startip6: i => [
- `startip6[${i}]`,
- {
- initialValue: '',
- validateFirst: true,
- rules: [
- { validator: this.validateIpv6 },
- ],
- },
- ],
- endip6: i => [
- `endip6[${i}]`,
- {
- initialValue: '',
- validateFirst: true,
- rules: [
- { validator: this.validateIpv6 },
- ],
- },
- ],
- netmask6: i => [
- `netmask6[${i}]`,
- {
- initialValue: '64',
- rules: [
- { required: true, message: this.$t('network.text_595') },
- ],
- },
- ],
- gateway6: i => [
- `gateway6[${i}]`,
- {
- initialValue: '',
- validateTrigger: ['change', 'blur'],
- validateFirst: true,
- rules: [
- { validator: this.validateIpv6 },
- { validator: validateGateway6 },
- ],
- },
- ],
- vlan: i => [
- `vlan[${i}]`,
- {
- initialValue: '',
- },
- ],
- },
- guest_ip_prefix: i => [
- `guest_ip_prefix[${i}]`,
- {
- initialValue: '',
- validateFirst: true,
- rules: [
- { validator: this.validatePublicIpPrefix },
- ],
- },
- ],
- guest_ip6_prefix: i => [
- `guest_ip6_prefix[${i}]`,
- {
- initialValue: '',
- validateFirst: true,
- rules: [
- { validator: this.validatePublicIpPrefix6 },
- ],
- },
- ],
- guest_dhcp: [
- 'guest_dhcp',
- {
- validateFirst: true,
- rules: [
- { validator: this.$validate('IPs', false) },
- ],
- },
- ],
- is_auto_alloc: ['is_auto_alloc', {
- valuePropName: 'checked',
- }],
- bgp_type: [
- 'bgp_type',
- ],
- __meta__: [
- '__meta__',
- {
- rules: [
- { validator: validateForm('tagName') },
- ],
- },
- ],
- },
- allocPolicyoptions: [
- { label: this.$t('network.text_600'), key: 'none' },
- { label: this.$t('network.text_601'), key: 'stepdown' },
- { label: this.$t('network.text_602'), key: 'stepup' },
- { label: this.$t('network.text_603'), key: 'random' },
- ],
- isShowWire: true,
- isGroupGuestIpPrefix: false,
- show: true,
- regionProvider: '',
- regionId: '',
- guestIpPrefix: [{ key: prefixKey }],
- guestIp6Prefix: [{ key: prefixKey }],
- zoneList: [],
- project_domain: '',
- vpcId: '',
- curVpc: null,
- curWire: null,
- }
- },
- computed: {
- ...mapGetters(['isAdminMode', 'scope', 'userInfo']),
- // 是否显示加入自动分配地址池
- isShowIsAutoAlloc () {
- const { vpc, server_type } = this.form.fd
- if (this.cloudEnv === 'onpremise' && vpc === 'default') {
- return ['guest', undefined].includes(server_type)
- }
- return true
- },
- // 是否显示高级配置
- isShowAdvanceOptions () {
- return this.cloudEnv === 'onpremise'
- },
- remain () {
- const remain = 6 - this.guestIpPrefix.length
- return Math.max(remain, 0)
- },
- vpcParams () {
- const params = {
- limit: 0,
- usable_vpc: true,
- scope: this.scope,
- cloudregion_id: this.regionId,
- }
- if (this.cloudEnv === 'private') {
- params.show_emulated = true
- }
- if (this.isAdminMode) {
- params.project_domain = this.project_domain
- delete params.scope
- }
- if (!this.regionId) return {}
- return params
- },
- cloudregionParams () {
- const params = {
- scope: this.scope,
- limit: 0,
- is_on_premise: true,
- // usable_vpc: true,
- show_emulated: true,
- usable: false,
- }
- if (this.cloudEnv === 'private') {
- params.is_private = true
- delete params.is_public
- delete params.is_on_premise
- } else if (this.cloudEnv === 'public') {
- params.is_public = true
- delete params.is_private
- delete params.is_on_premise
- } else {
- params.is_on_premise = true
- delete params.is_private
- delete params.is_public
- }
- if (this.isAdminMode) {
- params.project_domain = this.project_domain
- delete params.scope
- }
- return params
- },
- wireParams () {
- const params = {
- scope: this.scope,
- vpcId: this.vpcId,
- }
- if (this.isAdminMode) {
- params.project_domain = this.project_domain
- delete params.scope
- }
- return params
- },
- zoneParams () {
- const params = {
- scope: this.scope,
- show_emulated: true,
- 'filter.0': 'status.equals(enable)',
- order: 'asc',
- order_by: 'external_id',
- }
- if (this.isAdminMode) {
- params.project_domain = this.project_domain
- delete params.scope
- }
- return params
- },
- areaselectsName () {
- if (this.cloudEnv === 'private' || this.cloudEnv === 'onpremise') {
- return ['cloudregion']
- }
- return ['provider', 'cloudregion']
- },
- providerParams () {
- return {
- cloud_env: 'public',
- usable: false,
- usable_vpc: true,
- project_domain: this.form.fd.domain?.key,
- filter: 'provider.notequals("Google")',
- }
- },
- curVpcCidrText () {
- const cidrs = []
- if (this.curVpc?.cidr_block) {
- cidrs.push(this.curVpc.cidr_block)
- }
- if (this.curVpc?.cidr_block6) {
- cidrs.push(this.curVpc.cidr_block6)
- }
- return cidrs.join(', ')
- },
- hasBgpType () {
- return this.form.fd.server_type === 'eip' || this.form.fd.server_type === 'guest' || this.form.fd.server_type === 'baremetal' || this.form.fd.server_type === 'hostlocal'
- },
- serverTypeOpts () {
- const opts = [
- { label: this.$t('network.text_226'), key: 'guest', disabled: false },
- { label: this.$t('network.text_598'), key: 'baremetal', disabled: false },
- // { label: this.$t('network.text_599'), key: 'container' },
- { label: 'PXE', key: 'pxe', disabled: false },
- { label: 'IPMI', key: 'ipmi', disabled: false },
- { label: this.$t('network.text_221'), key: 'eip', disabled: false },
- { label: this.$t('network.server_type.hostlocal.text'), key: 'hostlocal', disabled: false },
- ]
- const isHostLocalWire = this.curWire?.id === '__host_local__'
- for (let i = 0; i < opts.length; i++) {
- if (opts[i].key === 'hostlocal') {
- if (isHostLocalWire) {
- opts[i].disabled = false
- } else {
- opts[i].disabled = true
- }
- } else {
- if (isHostLocalWire) {
- opts[i].disabled = true
- } else {
- opts[i].disabled = false
- }
- }
- }
- return opts
- },
- },
- provide () {
- return {
- form: this.form,
- }
- },
- watch: {
- cloudEnv (newValue) {
- this.$refs.areaSelects.fetchs(this.areaselectsName)
- if (newValue === 'private') {
- this.show = false
- this.isGroupGuestIpPrefix = false
- } else if (newValue === 'public') {
- this.show = false
- this.isGroupGuestIpPrefix = false
- } else {
- this.show = true
- this.isGroupGuestIpPrefix = true
- }
- },
- 'form.fd.guest_ip_prefix': {
- handler (newValue) {
- if (newValue.filter(item => item).length > 0) {
- this.guestIpPrefixHelp = ''
- }
- },
- },
- 'form.fd.guest_ip6_prefix': {
- handler (newValue) {
- if (newValue.filter(item => item).length > 0) {
- this.guestIpPrefixHelp = ''
- }
- },
- },
- 'form.fd.vpc': {
- handler (newValue) {
- if (newValue === 'default') {
- this.$nextTick(() => {
- if (this.curWire?.id === '__host_local__') { // 如果当前选择的网线是主机本地网线,则设置服务器类型为主机本地
- this.form.fc.setFieldsValue({
- server_type: 'hostlocal',
- })
- } else { // 如果当前选择的网线不是主机本地网线,则设置服务器类型为虚拟机
- this.form.fc.setFieldsValue({
- server_type: 'guest',
- })
- }
- })
- }
- },
- },
- 'form.fd.wire': {
- handler (newValue) {
- console.log('newValue', newValue)
- if (newValue === '__host_local__') {
- this.$nextTick(() => {
- this.form.fc.setFieldsValue({
- server_type: 'hostlocal',
- })
- })
- } else {
- this.$nextTick(() => {
- this.form.fc.setFieldsValue({
- server_type: 'guest',
- })
- })
- }
- },
- },
- },
- created () {
- this.initState()
- },
- methods: {
- validateIpv4 (rule, value, callback) {
- if (!value) {
- callback()
- } else if (!REGEXP.IPv4.regexp.test(value)) {
- callback(new Error(this.$t('common.tips.input', ['IPv4'])))
- }
- callback()
- },
- validateIpv6 (rule, value, callback) {
- if (!value) {
- callback()
- } else if (!REGEXP.IPv6.regexp.test(value)) {
- callback(new Error(this.$t('common.tips.input', ['IPv6'])))
- }
- callback()
- },
- validateDhcpRelay (rule, value, callback) {
- if (!value) {
- callback()
- } else if (!REGEXP.IPv4s.regexp.test(value)) {
- callback(new Error(this.$t('common.tips.input', ['IPv4'])))
- }
- callback()
- },
- validateDhcpRelay6 (rule, value, callback) {
- if (!value) {
- callback()
- } else if (!REGEXP.IPv6s.regexp.test(value)) {
- callback(new Error(this.$t('common.tips.input', ['IPv6'])))
- }
- callback()
- },
- initState () {
- if (this.cloudEnv === 'private') {
- this.show = false
- this.isGroupGuestIpPrefix = false
- } else if (this.cloudEnv === 'public') {
- this.show = false
- this.isGroupGuestIpPrefix = false
- } else {
- this.show = true
- this.isGroupGuestIpPrefix = true
- }
- },
- handleValuesChange (props, values) {
- this.form.fd = {
- ...this.form.fd,
- ...values,
- }
- },
- wireLabelFormat (item) {
- if (item) {
- const { name, zone } = item
- return (
- <div class='d-flex'>
- <span class='text-truncate flex-fill mr-2' title={ name }>{ name }</span>
- <span style="color: #8492a6; font-size: 13px">可用区:{zone}</span>
- </div>
- )
- }
- return null
- },
- handleDomainChange (val) {
- this.project_domain = val.key
- },
- addGuestIpPrefix () {
- this.clearGuestIpPrefixError()
- const key = uuid()
- this.guestIpPrefix.push({
- key,
- })
- this.guestIp6Prefix.push({
- key,
- })
- },
- decrease (index) {
- this.guestIpPrefix.splice(index, 1)
- this.guestIp6Prefix.splice(index, 1)
- },
- handleRegionChange (data) {
- const hasCloudRegion = R.has('cloudregion')(data)
- if (hasCloudRegion && !R.isEmpty(data.cloudregion)) {
- this.fetchZone(data.cloudregion.id)
- } else {
- this.zoneList = []
- this.form.fc.resetFields(['zone'])
- return
- }
- const { provider } = data.cloudregion.value
- this.regionProvider = provider
- this.regionId = data.cloudregion.id
- if (provider === typeClouds.providerMap.ZStack.key || provider === typeClouds.providerMap.CNware.key) {
- this.isShowWire = true
- } else {
- this.isShowWire = false
- }
- },
- vpcChange (vpcId) {
- this.vpcId = vpcId
- this.show = false
- if (this.cloudEnv === 'onpremise') {
- if (vpcId !== 'default') { // vpc network
- this.isGroupGuestIpPrefix = true
- this.show = false
- } else { // classic network
- this.isGroupGuestIpPrefix = false
- this.show = true
- this.form.fc.setFieldsValue({
- server_type: 'guest',
- })
- }
- }
- if (this.cloudEnv === 'private' && this.curVpc?.brand === 'Cloudpods' && this.curVpc?.external_id === 'default') {
- this.isShowWire = true
- this.isGroupGuestIpPrefix = true
- } else {
- this.isShowWire = false
- this.isGroupGuestIpPrefix = false
- }
- },
- vpcLabelFormat (item) {
- if (this.cloudEnv === 'public' || this.regionProvider === HYPERVISORS_MAP.hcso.provider || this.regionProvider === HYPERVISORS_MAP.hcs.provider) {
- if (item.manager) {
- if (item.cidr_block || item.cidr_block6) {
- return (<div>{ item.name }<span v-if="item.cidr_block">({ item.cidr_block })</span><span v-if="item.cidr_block6">({ item.cidr_block6 })</span><span class="ml-2 text-color-secondary">{ this.$t('common.cloudprovider_1var', [item.manager]) }</span></div>)
- }
- return (<div>{ item.name }<span class="ml-2 text-color-secondary">{ this.$t('common.cloudprovider_1var', [item.manager]) }</span></div>)
- }
- } else if (this.cloudEnv === 'onpremise') {
- if (item.cidr_block || item.cidr_block6) {
- const cidrs = []
- if (item.cidr_block) {
- cidrs.push(item.cidr_block)
- }
- if (item.cidr_block6) {
- cidrs.push(item.cidr_block6)
- }
- return (<div>{ item.name } ({ cidrs.join(', ') })</div>)
- }
- if (item.id === 'default') return (<div>{ item.name }<span v-if="item.cidr_block">({this.$t('common.text00047')})</span></div>)
- }
- return (<div>{ item.name }</div>)
- },
- validatePublicIpPrefix (rule, value, callback) {
- if (value) {
- if (!networkSegment.regexp.test(value)) {
- callback(new Error(networkSegment.message))
- }
- const maskNum = (value && value.split('/').length > 1) ? value.split('/')[1] : null
- const publicWire = this.form.fc.getFieldValue('cloudregion')
- if (maskNum && publicWire && publicWire.provider) {
- const provider = publicWire.provider.toLowerCase()
- if (masks[provider]) {
- const min = masks[provider].min
- const max = masks[provider].max
- if (masks[provider] && (maskNum < min || maskNum > max)) {
- callback(new Error(this.$t('network.ipaddr.mask.error', [min, max])))
- }
- }
- }
- }
- callback()
- },
- validatePublicIpPrefix6 (rule, value, callback) {
- if (value) {
- if (!networkSegment6.regexp.test(value)) {
- callback(new Error(networkSegment6.message))
- return
- }
- const maskNum = (value && value.split('/').length > 1) ? value.split('/')[1] : null
- const min = 64
- const max = 124
- if (maskNum < min || maskNum > max) {
- callback(new Error(this.$t('network.ipaddr.mask.error', [min, max])))
- return
- }
- }
- callback()
- },
- fetchZone (regionId) {
- new this.$Manager('cloudregions')
- .getSpecific({ id: regionId, spec: 'zones', params: this.zoneParams })
- .then(({ data: { data = [] } }) => {
- this.form.fc.resetFields(['zone'])
- this.zoneList = data
- })
- },
- genData (values) {
- const guest_dhcp = values.guest_dhcp
- if (this.cloudEnv === 'onpremise') {
- const data = []
- if (this.isGroupGuestIpPrefix) {
- R.forEachObjIndexed((value, key) => {
- const obj = {
- alloc_policy: values.alloc_policy,
- guest_dns: values.guest_dns,
- guest_domain: values.guest_domain,
- guest_ntp: values.guest_ntp,
- guest_ip_prefix: value,
- guest_ip6_prefix: values.guest_ip6_prefix && values.guest_ip6_prefix[key],
- name: values.name,
- description: values.description,
- vpc: values.vpc,
- zone: values.zone,
- project_id: values.project?.key,
- is_auto_alloc: values.is_auto_alloc,
- guest_dhcp,
- __meta__: values.__meta__,
- }
- data.push(obj)
- }, values.guest_ip_prefix)
- } else if (this.show) {
- R.forEachObjIndexed((value, key) => {
- const obj = {
- bgp_type: values.bgp_type,
- alloc_policy: values.alloc_policy,
- guest_dns: values.guest_dns,
- guest_domain: values.guest_domain,
- guest_ntp: values.guest_ntp,
- guest_ip_start: values.startip[key],
- guest_ip_end: values.endip[key],
- guest_ip_mask: values.netmask[key],
- guest_gateway: values.gateway[key],
- guest_ip6_start: values.startip6 && values.startip6[key],
- guest_ip6_end: values.endip6 && values.endip6[key],
- guest_ip6_mask: values.netmask6 && values.netmask6[key],
- guest_gateway6: values.gateway6 && values.gateway6[key],
- vlan_id: values.vlan[key] === '' ? '1' : values.vlan[key],
- name: values.name,
- description: values.description,
- project_id: values.project?.key,
- server_type: values.server_type,
- wire_id: values.wire,
- is_auto_alloc: values.is_auto_alloc,
- guest_dhcp,
- __meta__: values.__meta__,
- }
- data.push(obj)
- }, values.startip)
- } else {
- var ipPrefix = null
- var ip6Prefix = null
- if (values.guest_ip_prefix) {
- ipPrefix = values.guest_ip_prefix[0]
- if (values.guest_ip6_prefix) {
- ip6Prefix = values.guest_ip6_prefix[0]
- }
- } else if (values.guest_ip6_prefix) {
- ip6Prefix = values.guest_ip6_prefix[0]
- }
- const obj = {
- alloc_policy: values.alloc_policy,
- guest_dns: values.guest_dns,
- guest_domain: values.guest_domain,
- guest_ntp: values.guest_ntp,
- name: values.name,
- description: values.description,
- vpc: values.vpc,
- zone: values.zone,
- project_id: values.project?.key,
- is_auto_alloc: values.is_auto_alloc,
- guest_dhcp,
- __meta__: values.__meta__,
- }
- if (ipPrefix) {
- obj.guest_ip_prefix = ipPrefix
- }
- if (ip6Prefix) {
- obj.guest_ip6_prefix = ip6Prefix
- }
- data.push(obj)
- }
- return data
- }
- if (this.regionProvider === typeClouds.providerMap.ZStack.key ||
- (this.cloudEnv === 'private' && this.curVpc?.brand === 'Cloudpods' && this.curVpc?.external_id === 'default')) {
- return {
- project_id: values.project?.key,
- guest_ip_prefix: values.guest_ip_prefix[0],
- guest_ip6_prefix: values.guest_ip6_prefix[0],
- name: values.name,
- description: values.description,
- wire_id: values.wire,
- is_auto_alloc: values.is_auto_alloc,
- guest_dhcp,
- __meta__: values.__meta__,
- }
- } else if (this.regionProvider === typeClouds.providerMap.CNware.key) {
- return {
- project_id: values.project?.key,
- guest_ip_prefix: values.guest_ip_prefix && values.guest_ip_prefix[0],
- guest_ip6_prefix: values.guest_ip6_prefix && values.guest_ip6_prefix[0],
- name: values.name,
- wire_id: values.wire,
- description: values.description,
- vpc: values.vpc,
- zone: values?.zone,
- is_auto_alloc: values.is_auto_alloc,
- guest_dhcp,
- __meta__: values.__meta__,
- }
- }
- return {
- project_id: values.project?.key,
- guest_ip_prefix: values.guest_ip_prefix && values.guest_ip_prefix[0],
- guest_ip6_prefix: values.guest_ip6_prefix && values.guest_ip6_prefix[0],
- name: values.name,
- description: values.description,
- vpc: values.vpc,
- zone: values?.zone,
- is_auto_alloc: values.is_auto_alloc,
- guest_dhcp,
- __meta__: values.__meta__,
- }
- },
- clearIpSubnetsError () {
- this.ipSubnetsValidateStatus = ''
- this.ipSubnetsHelp = ''
- },
- clearGuestIpPrefixError () {
- this.guestIpPrefixValidateStatus = ''
- this.guestIpPrefixHelp = ''
- },
- async handleSubmit () {
- const ListPath = this.$router.resolve(this.$route.path)
- try {
- const values = await this.form.fc.validateFields()
- this.submiting = true
- if (this.cloudEnv === 'onpremise' && this.show && !this.isGroupGuestIpPrefix) {
- const keys = Object.keys(values.startip)
- let error = false
- keys.forEach(key => {
- if (!((values.startip[key] && values.endip[key] && values.gateway[key] && !values.startip6[key] && !values.endip6[key] && !values.gateway6[key]) || (values.startip6[key] && values.endip6[key] && values.gateway6[key] && !values.startip[key] && !values.endip[key] && !values.gateway[key]) || (values.startip[key] && values.endip[key] && values.gateway[key] && values.startip6[key] && values.endip6[key] && values.gateway6[key]))) {
- error = true
- }
- })
- if (error) {
- this.ipSubnetsHelp = this.$t('network.required_ipv4_or_ipv6_1')
- return
- }
- }
- // 验证ipv4 和 ipv6 网段 有一个必填
- if (!this.show && !this.isGroupGuestIpPrefix) {
- const guest_ip_prefix = R.is(Array, values.guest_ip_prefix) ? values.guest_ip_prefix[0] : values.guest_ip_prefix
- const guest_ip_prefix6 = R.is(Array, values.guest_ip6_prefix) ? values.guest_ip6_prefix[0] : values.guest_ip6_prefix
- if (!guest_ip_prefix && !guest_ip_prefix6) {
- this.guestIpPrefixValidateStatus = 'error'
- if (this.curVpc && this.curVpc.cidr_block && this.curVpc.cidr_block6) {
- this.guestIpPrefixHelp = this.$t('network.required_ipv4_or_ipv6')
- } else {
- this.guestIpPrefixHelp = this.$t('network.text_597')
- }
- return
- }
- }
- if (this.isGroupGuestIpPrefix && (R.isNil(values.guest_ip_prefix) || R.isEmpty(values.guest_ip_prefix))) {
- this.guestIpPrefixValidateStatus = 'error'
- this.guestIpPrefixHelp = this.$t('network.text_605')
- return
- }
- this.guestIpPrefixHelp = ''
- this.ipSubnetsHelp = ''
- const data = this.genData(values)
- const manager = new Manager('networks')
- if (this.cloudEnv === 'onpremise') {
- for (let i = 0, len = data.length; i < len; i++) {
- const bodyData = { ...data[i] }
- if (i > 0) {
- bodyData.name = `${bodyData.name}-${i + 1}`
- }
- await manager.create({
- data: {
- ...bodyData,
- dry_run: true,
- },
- })
- await manager.create({ data: bodyData })
- }
- } else {
- await manager.create({ data })
- }
- this.$router.push({ path: ListPath.resolved.matched[0].path })
- } catch (error) {
- throw error
- } finally {
- this.submiting = false
- }
- },
- filterOption (input, option) {
- const lastIdx = option.componentOptions.children.length - 1
- return (
- option.componentOptions.children[lastIdx].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
- )
- },
- },
- }
- </script>
- <style lang="less" scoped>
- .error-tips {
- color: #f5222d;
- margin-bottom: 3px;
- line-height: 16px;
- }
- </style>
|