| // Licensed to the Apache Software Foundation (ASF) under one | |
| // or more contributor license agreements. See the NOTICE file | |
| // distributed with this work for additional information | |
| // regarding copyright ownership. The ASF licenses this file | |
| // to you under the Apache License, Version 2.0 (the | |
| // "License"); you may not use this file except in compliance | |
| // with the License. You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, | |
| // software distributed under the License is distributed on an | |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| // KIND, either express or implied. See the License for the | |
| // specific language governing permissions and limitations | |
| // under the License. | |
| <template> | |
| <div class="form-layout" @keyup.ctrl.enter="handleSubmit"> | |
| <a-spin :spinning="loading"> | |
| <a-form | |
| :ref="formRef" | |
| :model="form" | |
| :rules="rules" | |
| @finish="handleSubmit" | |
| layout="vertical"> | |
| <a-form-item name="name" ref="name"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.name')" :tooltip="apiParams.name.description"/> | |
| </template> | |
| <a-input | |
| v-focus="true" | |
| v-model:value="form.name" | |
| :placeholder="apiParams.name.description"/> | |
| </a-form-item> | |
| <a-form-item name="displaytext" ref="displaytext"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.displaytext')" :tooltip="apiParams.displaytext.description"/> | |
| </template> | |
| <a-input | |
| v-model:value="form.displaytext" | |
| :placeholder="apiParams.displaytext.description"/> | |
| </a-form-item> | |
| <a-form-item name="networkrate" ref="networkrate" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.networkrate')" :tooltip="apiParams.networkrate.description"/> | |
| </template> | |
| <a-input | |
| v-model:value="form.networkrate" | |
| :placeholder="apiParams.networkrate.description"/> | |
| </a-form-item> | |
| <a-form-item name="guestiptype" ref="guestiptype"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.guestiptype')" :tooltip="apiParams.guestiptype.description"/> | |
| </template> | |
| <a-radio-group | |
| v-model:value="form.guestiptype" | |
| buttonStyle="solid" | |
| @change="selected => { handleGuestTypeChange(selected.target.value) }"> | |
| <a-radio-button value="isolated"> | |
| {{ $t('label.isolated') }} | |
| </a-radio-button> | |
| <a-radio-button value="l2" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> | |
| {{ $t('label.l2') }} | |
| </a-radio-button> | |
| <a-radio-button value="shared" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> | |
| {{ $t('label.shared') }} | |
| </a-radio-button> | |
| </a-radio-group> | |
| </a-form-item> | |
| <a-form-item name="internetprotocol" ref="internetprotocol" v-if="guestType === 'isolated'"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.internetprotocol')" :tooltip="apiParams.internetprotocol.description"/> | |
| </template> | |
| <span v-if="!ipv6NetworkOfferingEnabled || internetProtocolValue!=='ipv4'"> | |
| <a-alert type="warning"> | |
| <template #message> | |
| <span v-html="ipv6NetworkOfferingEnabled ? $t('message.offering.internet.protocol.warning') : $t('message.offering.ipv6.warning')" /> | |
| </template> | |
| </a-alert> | |
| <br/> | |
| </span> | |
| <a-radio-group | |
| v-model:value="form.internetprotocol" | |
| :disabled="!ipv6NetworkOfferingEnabled" | |
| buttonStyle="solid" | |
| @change="e => { internetProtocolValue = e.target.value }" > | |
| <a-radio-button value="ipv4"> | |
| {{ $t('label.ip.v4') }} | |
| </a-radio-button> | |
| <a-radio-button value="dualstack"> | |
| {{ $t('label.ip.v4.v6') }} | |
| </a-radio-button> | |
| </a-radio-group> | |
| </a-form-item> | |
| <a-row :gutter="12" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> | |
| <a-col :md="12" :lg="12"> | |
| <a-form-item name="specifyvlan" ref="specifyvlan"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.specifyvlan')" :tooltip="apiParams.specifyvlan.description"/> | |
| </template> | |
| <a-switch v-model:checked="form.specifyvlan" /> | |
| </a-form-item> | |
| </a-col> | |
| <a-col :md="12" :lg="12"> | |
| <a-form-item name="ispersistent" ref="ispersistent" v-if="guestType !== 'shared'"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.ispersistent')" :tooltip="apiParams.ispersistent.description"/> | |
| </template> | |
| <a-switch v-model:checked="form.ispersistent" /> | |
| </a-form-item> | |
| </a-col> | |
| </a-row> | |
| <a-row :gutter="12"> | |
| <a-col :md="12" :lg="12"> | |
| <a-form-item name="forvpc" ref="forvpc" v-if="guestType === 'isolated'"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.vpc')" :tooltip="apiParams.forvpc.description"/> | |
| </template> | |
| <a-switch v-model:checked="form.forvpc" @change="handleForVpcChange" /> | |
| </a-form-item> | |
| </a-col> | |
| <a-col :md="12" :lg="12"> | |
| <a-form-item name="provider" ref="provider"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.provider')" :tooltip="apiParams.provider.description"/> | |
| </template> | |
| <a-select | |
| v-model:value="form.provider" | |
| v-focus="true" | |
| @change="handleProviderChange" | |
| showSearch | |
| optionFilterProp="label" | |
| :filterOption="(input, option) => { | |
| return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 | |
| }" | |
| :placeholder="apiParams.provider.description" > | |
| <a-select-option key="" >{{ }}</a-select-option> | |
| <a-select-option :value="'NSX'" :label="$t('label.nsx')"> {{ $t('label.nsx') }} </a-select-option> | |
| <a-select-option :value="'Netris'" :label="$t('label.netris')"> {{ $t('label.netris') }} </a-select-option> | |
| </a-select> | |
| </a-form-item> | |
| </a-col> | |
| </a-row> | |
| <a-row :gutter="12" v-if="form.provider === 'NSX'"> | |
| <a-col :md="12" :lg="12"> | |
| <a-form-item name="nsxsupportlb" ref="nsxsupportlb" v-if="guestType === 'isolated'"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.nsx.supports.lb')" :tooltip="apiParams.nsxsupportlb.description"/> | |
| </template> | |
| <a-switch v-model:checked="form.nsxsupportlb" @change="val => { handleNsxLbService(val) }" /> | |
| </a-form-item> | |
| </a-col> | |
| <a-col :md="12" :lg="12" v-if="form.nsxsupportlb && form.forvpc"> | |
| <a-form-item name="nsxsupportsinternallb" ref="nsxsupportsinternallb" v-if="guestType === 'isolated'"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.nsx.supports.internal.lb')" :tooltip="apiParams.nsxsupportsinternallb.description"/> | |
| </template> | |
| <a-switch v-model:checked="form.nsxsupportsinternallb"/> | |
| </a-form-item> | |
| </a-col> | |
| </a-row> | |
| <a-form-item name="networkmode" ref="networkmode" v-if="guestType === 'isolated'"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.networkmode')" :tooltip="apiParams.networkmode.description"/> | |
| </template> | |
| <a-select | |
| optionFilterProp="label" | |
| v-model:value="form.networkmode" | |
| @change="val => { handleForNetworkModeChange(val) }" | |
| :filterOption="(input, option) => { | |
| return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 | |
| }" | |
| :placeholder="apiParams.networkmode.description"> | |
| <a-select-option v-for="(opt) in networkmodes" :key="opt.name" :label="opt.name"> | |
| {{ opt.name }} | |
| </a-select-option> | |
| </a-select> | |
| </a-form-item> | |
| <a-form-item name="routingmode" ref="routingmode" v-if="networkmode === 'ROUTED' || internetProtocolValue === 'ipv6' || internetProtocolValue === 'dualstack'"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.routingmode')" :tooltip="apiParams.routingmode.description"/> | |
| </template> | |
| <a-radio-group | |
| v-model:value="form.routingmode" | |
| buttonStyle="solid" | |
| @change="selected => { routingMode = selected.target.value }"> | |
| <a-radio-button value="static"> | |
| {{ $t('label.static') }} | |
| </a-radio-button> | |
| <a-radio-button value="dynamic"> | |
| {{ $t('label.dynamic') }} | |
| </a-radio-button> | |
| </a-radio-group> | |
| </a-form-item> | |
| <a-row :gutter="12" v-if="routingMode === 'dynamic' && !forVpc && form.provider === 'NSX'"> | |
| <a-col :md="12" :lg="12"> | |
| <a-form-item name="specifyasnumber" ref="specifyasnumber"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.specifyasnumber')"/> | |
| </template> | |
| <a-switch v-model:checked="form.specifyasnumber" /> | |
| </a-form-item> | |
| </a-col> | |
| </a-row> | |
| <a-form-item name="userdatal2" ref="userdatal2" :label="$t('label.user.data')" v-if="guestType === 'l2'"> | |
| <a-switch v-model:checked="form.userdatal2" /> | |
| </a-form-item> | |
| <a-row :gutter="12"> | |
| <a-col :md="12" :lg="12"> | |
| <a-form-item name="promiscuousmode" ref="promiscuousmode" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.promiscuousmode')" :tooltip="$t('message.network.offering.promiscuous.mode')"/> | |
| </template> | |
| <a-radio-group | |
| v-model:value="form.promiscuousmode" | |
| buttonStyle="solid"> | |
| <a-radio-button value=""> | |
| {{ $t('label.none') }} | |
| </a-radio-button> | |
| <a-radio-button value="true"> | |
| {{ $t('label.accept') }} | |
| </a-radio-button> | |
| <a-radio-button value="false"> | |
| {{ $t('label.reject') }} | |
| </a-radio-button> | |
| </a-radio-group> | |
| </a-form-item> | |
| <a-form-item name="macaddresschanges" ref="macaddresschanges" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.macaddresschanges')" :tooltip="$t('message.network.offering.mac.address.changes')"/> | |
| </template> | |
| <a-radio-group | |
| v-model:value="form.macaddresschanges" | |
| buttonStyle="solid"> | |
| <a-radio-button value=""> | |
| {{ $t('label.none') }} | |
| </a-radio-button> | |
| <a-radio-button value="true"> | |
| {{ $t('label.accept') }} | |
| </a-radio-button> | |
| <a-radio-button value="false"> | |
| {{ $t('label.reject') }} | |
| </a-radio-button> | |
| </a-radio-group> | |
| </a-form-item> | |
| </a-col> | |
| <a-col :md="12" :lg="12"> | |
| <a-form-item name="forgedtransmits" ref="forgedtransmits" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.forgedtransmits')" :tooltip="$t('message.network.offering.forged.transmits')"/> | |
| </template> | |
| <a-radio-group | |
| v-model:value="form.forgedtransmits" | |
| buttonStyle="solid"> | |
| <a-radio-button value=""> | |
| {{ $t('label.none') }} | |
| </a-radio-button> | |
| <a-radio-button value="true"> | |
| {{ $t('label.accept') }} | |
| </a-radio-button> | |
| <a-radio-button value="false"> | |
| {{ $t('label.reject') }} | |
| </a-radio-button> | |
| </a-radio-group> | |
| </a-form-item> | |
| <a-form-item name="maclearning" ref="maclearning" v-if="form.provider !== 'NSX' && form.provider !== 'Netris'"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.maclearning')" :tooltip="$t('message.network.offering.mac.learning')"/> | |
| </template> | |
| <span v-if="form.maclearning !== ''"> | |
| <a-alert type="warning"> | |
| <template #message> | |
| <div v-html="$t('message.network.offering.mac.learning.warning')"></div> | |
| </template> | |
| </a-alert> | |
| <br/> | |
| </span> | |
| <a-radio-group | |
| v-model:value="form.maclearning" | |
| buttonStyle="solid"> | |
| <a-radio-button value=""> | |
| {{ $t('label.none') }} | |
| </a-radio-button> | |
| <a-radio-button value="true"> | |
| {{ $t('label.accept') }} | |
| </a-radio-button> | |
| <a-radio-button value="false"> | |
| {{ $t('label.reject') }} | |
| </a-radio-button> | |
| </a-radio-group> | |
| </a-form-item> | |
| </a-col> | |
| </a-row> | |
| <a-form-item v-if="guestType !== 'l2'"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.supportedservices')" :tooltip="apiParams.supportedservices.description"/> | |
| </template> | |
| <div class="supported-services-container" scroll-to="last-child"> | |
| <a-list itemLayout="horizontal" :dataSource="supportedServices"> | |
| <template #renderItem="{item}"> | |
| <a-list-item> | |
| <CheckBoxSelectPair | |
| :resourceKey="item.name" | |
| :checkBoxLabel="item.description" | |
| :forExternalNetProvider="form.provider === 'NSX' || form.provider === 'Netris'" | |
| :defaultCheckBoxValue="form.provider === 'NSX' || form.provider === 'Netris'" | |
| :selectOptions="!supportedServiceLoading ? item.provider: []" | |
| @handle-checkselectpair-change="handleSupportedServiceChange"/> | |
| </a-list-item> | |
| </template> | |
| </a-list> | |
| </div> | |
| </a-form-item> | |
| <a-form-item name="lbtype" ref="lbtype" :label="$t('label.lbtype')" v-if="forVpc && lbServiceChecked"> | |
| <a-radio-group | |
| v-model:value="form.lbtype" | |
| buttonStyle="solid" | |
| @change="e => { handleLbTypeChange(e.target.value) }" > | |
| <a-radio-button value="publicLb"> | |
| {{ $t('label.public.lb') }} | |
| </a-radio-button> | |
| <a-radio-button value="internalLb"> | |
| {{ $t('label.internal.lb') }} | |
| </a-radio-button> | |
| </a-radio-group> | |
| </a-form-item> | |
| <a-form-item name="serviceofferingid" ref="serviceofferingid" v-if="guestType !== 'l2'"> | |
| <a-alert v-if="!isVirtualRouterForAtLeastOneService" type="warning" style="margin-bottom: 10px"> | |
| <template #message> | |
| <span v-html="$t('message.vr.alert.upon.network.offering.creation.others')" /> | |
| </template> | |
| </a-alert> | |
| <template #label> | |
| <tooltip-label :title="$t('label.serviceofferingid')" :tooltip="apiParams.serviceofferingid.description"/> | |
| </template> | |
| <a-select | |
| :getPopupContainer="(trigger) => trigger.parentNode" | |
| showSearch | |
| optionFilterProp="label" | |
| v-model:value="form.serviceofferingid" | |
| :filterOption="(input, option) => { | |
| return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 | |
| }" | |
| :loading="serviceOfferingLoading" | |
| :placeholder="apiParams.serviceofferingid.description"> | |
| <a-select-option | |
| v-for="(offering, index) in serviceOfferings" | |
| :value="offering.id" | |
| :key="index"> | |
| {{ offering.displaytext || offering.name }} | |
| </a-select-option> | |
| </a-select> | |
| </a-form-item> | |
| <a-form-item | |
| name="redundantroutercapability" | |
| ref="redundantroutercapability" | |
| :label="$t('label.redundantrouter')" | |
| v-if="(guestType === 'shared' || guestType === 'isolated') && sourceNatServiceChecked && !isVpcVirtualRouterForAtLeastOneService"> | |
| <a-switch v-model:checked="form.redundantroutercapability" /> | |
| </a-form-item> | |
| <a-form-item name="sourcenattype" ref="sourcenattype" :label="$t('label.sourcenattype')" v-if="(guestType === 'shared' || guestType === 'isolated') && sourceNatServiceChecked"> | |
| <a-radio-group | |
| v-model:value="form.sourcenattype" | |
| buttonStyle="solid"> | |
| <a-radio-button value="peraccount"> | |
| {{ $t('label.per.account') }} | |
| </a-radio-button> | |
| <a-radio-button value="perzone"> | |
| {{ $t('label.per.zone') }} | |
| </a-radio-button> | |
| </a-radio-group> | |
| </a-form-item> | |
| <a-form-item | |
| name="vmautoscalingcapability" | |
| ref="vmautoscalingcapability" | |
| :label="$t('label.supportsvmautoscaling')" | |
| v-if="lbServiceChecked && ['Netscaler', 'VirtualRouter', 'VpcVirtualRouter'].includes(lbServiceProvider)"> | |
| <a-switch v-model:checked="form.vmautoscalingcapability" /> | |
| </a-form-item> | |
| <a-form-item | |
| name="elasticlb" | |
| ref="elasticlb" | |
| :label="$t('label.service.lb.elasticlbcheckbox')" | |
| v-if="guestType === 'shared' && lbServiceChecked && lbServiceProvider === 'Netscaler'"> | |
| <a-switch v-model:checked="form.elasticlb" /> | |
| </a-form-item> | |
| <a-form-item | |
| name="inlinemode" | |
| ref="inlinemode" | |
| :label="$t('label.service.lb.inlinemodedropdown')" | |
| v-if="['shared', 'isolated'].includes(guestType) && lbServiceChecked && firewallServiceChecked && ['F5BigIp', 'Netscaler'].includes(lbServiceProvider) && ['JuniperSRX'].includes(firewallServiceProvider)"> | |
| <a-radio-group | |
| v-model:value="form.inlinemode" | |
| buttonStyle="solid"> | |
| <a-radio-button value="false"> | |
| {{ $t('side.by.side') }} | |
| </a-radio-button> | |
| <a-radio-button value="true"> | |
| {{ $t('inline') }} | |
| </a-radio-button> | |
| </a-radio-group> | |
| </a-form-item> | |
| <a-form-item | |
| name="netscalerservicepackages" | |
| ref="netscalerservicepackages" | |
| :label="$t('label.service.lb.netscaler.servicepackages')" | |
| v-if="(guestType === 'shared' || guestType === 'isolated') && lbServiceChecked && lbServiceProvider === 'Netscaler'"> | |
| <a-select | |
| v-model:value="form.netscalerservicepackages" | |
| showSearch | |
| optionFilterProp="label" | |
| :filterOption="(input, option) => { | |
| return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 | |
| }" | |
| :loading="registeredServicePackageLoading" | |
| :placeholder="$t('label.service.lb.netscaler.servicepackages')"> | |
| <a-select-option v-for="(opt, optIndex) in registeredServicePackages" :key="optIndex" :label="opt.name || opt.description"> | |
| {{ opt.name || opt.description }} | |
| </a-select-option> | |
| </a-select> | |
| </a-form-item> | |
| <a-form-item | |
| name="netscalerservicepackagesdescription" | |
| ref="netscalerservicepackagesdescription" | |
| :label="$t('label.service.lb.netscaler.servicepackages.description')" | |
| v-if="(guestType === 'shared' || guestType === 'isolated') && lbServiceChecked && lbServiceProvider === 'Netscaler'"> | |
| <a-input | |
| v-model:value="form.netscalerservicepackagesdescription" | |
| :placeholder="$t('label.service.lb.netscaler.servicepackages.description')"/> | |
| </a-form-item> | |
| <a-form-item name="isolation" ref="isolation" :title="$t('label.service.lb.lbisolationdropdown')" v-show="false"> | |
| <a-radio-group | |
| v-model:value="form.isolation" | |
| buttonStyle="solid"> | |
| <a-radio-button value="dedicated"> | |
| {{ $t('label.dedicated') }} | |
| </a-radio-button> | |
| <a-radio-button value="shared"> | |
| {{ $t('label.shared') }} | |
| </a-radio-button> | |
| </a-radio-group> | |
| </a-form-item> | |
| <a-form-item | |
| name="elasticip" | |
| ref="elasticip" | |
| :label="$t('label.service.staticnat.elasticipcheckbox')" | |
| v-if="guestType === 'shared' && staticNatServiceChecked && staticNatServiceProvider === 'Netscaler'"> | |
| <a-switch v-model:checked="form.elasticip" /> | |
| </a-form-item> | |
| <a-form-item | |
| name="associatepublicip" | |
| ref="associatepublicip" | |
| :label="$t('label.service.staticnat.associatepublicip')" | |
| v-if="isElasticIp && staticNatServiceChecked && staticNatServiceProvider === 'Netscaler'"> | |
| <a-switch v-model:checked="form.associatepublicip" /> | |
| </a-form-item> | |
| <a-form-item | |
| name="supportsstrechedl2subnet" | |
| ref="supportsstrechedl2subnet" | |
| :label="$t('label.supportsstrechedl2subnet')" | |
| v-if="connectivityServiceChecked"> | |
| <a-switch v-model:checked="form.supportsstrechedl2subnet" /> | |
| </a-form-item> | |
| <a-form-item name="supportspublicaccess" ref="supportspublicaccess" :label="$t('label.supportspublicaccess')" v-show="false"> | |
| <a-switch v-model:checked="form.supportspublicaccess" /> | |
| </a-form-item> | |
| <a-form-item | |
| name="conservemode" | |
| ref="conservemode" | |
| v-if="(guestType === 'shared' || guestType === 'isolated') && | |
| (form.provider !== 'NSX' && form.provider !== 'Netris') && networkmode !== 'ROUTED'"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.conservemode')" :tooltip="apiParams.conservemode.description"/> | |
| </template> | |
| <a-switch v-model:checked="form.conservemode" /> | |
| </a-form-item> | |
| <a-form-item name="tags" ref="tags"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.tags')" :tooltip="apiParams.tags.description"/> | |
| </template> | |
| <a-input | |
| v-model:value="form.tags" | |
| :placeholder="apiParams.tags.description"/> | |
| </a-form-item> | |
| <a-form-item name="availability" ref="availability" v-if="requiredNetworkOfferingExists && guestType === 'isolated' && sourceNatServiceChecked"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.availability')" :tooltip="apiParams.availability.description"/> | |
| </template> | |
| <a-radio-group | |
| v-model:value="form.availability" | |
| buttonStyle="solid"> | |
| <a-radio-button value="optional"> | |
| {{ $t('label.optional') }} | |
| </a-radio-button> | |
| <a-radio-button value="required"> | |
| {{ $t('label.required') }} | |
| </a-radio-button> | |
| </a-radio-group> | |
| </a-form-item> | |
| <a-form-item name="egressdefaultpolicy" ref="egressdefaultpolicy" v-if="firewallServiceChecked"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.egressdefaultpolicy')" :tooltip="apiParams.egressdefaultpolicy.description"/> | |
| </template> | |
| <a-radio-group | |
| v-model:value="form.egressdefaultpolicy" | |
| buttonStyle="solid"> | |
| <a-radio-button value="allow"> | |
| {{ $t('label.allow') }} | |
| </a-radio-button> | |
| <a-radio-button value="deny"> | |
| {{ $t('label.deny') }} | |
| </a-radio-button> | |
| </a-radio-group> | |
| </a-form-item> | |
| <a-form-item name="ispublic" ref="ispublic" :label="$t('label.ispublic')" v-show="isAdmin()"> | |
| <a-switch v-model:checked="form.ispublic" @change="val => { isPublic = val }" /> | |
| </a-form-item> | |
| <a-form-item name="domainid" ref="domainid" v-if="!isPublic"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.domainid')" :tooltip="apiParams.domainid.description"/> | |
| </template> | |
| <a-select | |
| mode="multiple" | |
| :getPopupContainer="(trigger) => trigger.parentNode" | |
| v-model:value="form.domainid" | |
| showSearch | |
| optionFilterProp="label" | |
| :filterOption="(input, option) => { | |
| return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 | |
| }" | |
| :loading="domainLoading" | |
| :placeholder="apiParams.domainid.description"> | |
| <a-select-option v-for="(opt, optIndex) in domains" :key="optIndex" :label="opt.path || opt.name || opt.description"> | |
| <span> | |
| <resource-icon v-if="opt && opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/> | |
| <block-outlined v-else style="margin-right: 5px" /> | |
| {{ opt.path || opt.name || opt.description }} | |
| </span> | |
| </a-select-option> | |
| </a-select> | |
| </a-form-item> | |
| <a-form-item name="zoneid" ref="zoneid"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.zoneid')" :tooltip="apiParams.zoneid.description"/> | |
| </template> | |
| <a-select | |
| id="zone-selection" | |
| mode="multiple" | |
| :getPopupContainer="(trigger) => trigger.parentNode" | |
| v-model:value="form.zoneid" | |
| showSearch | |
| optionFilterProp="label" | |
| :filterOption="(input, option) => { | |
| return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 | |
| }" | |
| :loading="zoneLoading" | |
| :placeholder="apiParams.zoneid.description"> | |
| <a-select-option v-for="(opt, optIndex) in zones" :key="optIndex" :label="opt.name || opt.description"> | |
| <span> | |
| <resource-icon v-if="opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/> | |
| <global-outlined v-else style="margin-right: 5px"/> | |
| {{ opt.name || opt.description }} | |
| </span> | |
| </a-select-option> | |
| </a-select> | |
| </a-form-item> | |
| <a-form-item name="enable" ref="enable" v-if="apiParams.enable"> | |
| <template #label> | |
| <tooltip-label :title="$t('label.enable.network.offering')" :tooltip="apiParams.enable.description"/> | |
| </template> | |
| <a-switch v-model:checked="form.enable" /> | |
| </a-form-item> | |
| </a-form> | |
| <div :span="24" class="action-button"> | |
| <a-button @click="closeAction">{{ $t('label.cancel') }}</a-button> | |
| <a-button :loading="loading" ref="submit" type="primary" @click="handleSubmit">{{ $t('label.ok') }}</a-button> | |
| </div> | |
| </a-spin> | |
| </div> | |
| </template> | |
| <script> | |
| import { ref, reactive, toRaw } from 'vue' | |
| import { getAPI, postAPI } from '@/api' | |
| import { isAdmin } from '@/role' | |
| import { mixinForm } from '@/utils/mixin' | |
| import CheckBoxSelectPair from '@/components/CheckBoxSelectPair' | |
| import ResourceIcon from '@/components/view/ResourceIcon' | |
| import TooltipLabel from '@/components/widgets/TooltipLabel' | |
| import { buildServiceCapabilityParams } from '@/composables/useServiceCapabilityParams' | |
| export default { | |
| name: 'AddNetworkOffering', | |
| mixins: [mixinForm], | |
| components: { | |
| CheckBoxSelectPair, | |
| ResourceIcon, | |
| TooltipLabel | |
| }, | |
| data () { | |
| return { | |
| hasAdvanceZone: false, | |
| requiredNetworkOfferingExists: false, | |
| guestType: 'isolated', | |
| internetProtocolValue: 'ipv4', | |
| selectedDomains: [], | |
| selectedZones: [], | |
| forVpc: false, | |
| provider: '', | |
| lbType: 'publicLb', | |
| macLearningValue: '', | |
| supportedServices: [], | |
| supportedSvcs: [], | |
| supportedServiceLoading: false, | |
| isVirtualRouterForAtLeastOneService: false, | |
| isVpcVirtualRouterForAtLeastOneService: false, | |
| serviceOfferings: [], | |
| serviceOfferingLoading: false, | |
| sourceNatServiceChecked: false, | |
| lbServiceChecked: false, | |
| lbServiceProvider: '', | |
| registeredServicePackages: [], | |
| registeredServicePackageLoading: false, | |
| isElasticIp: false, | |
| staticNatServiceChecked: false, | |
| staticNatServiceProvider: '', | |
| connectivityServiceChecked: false, | |
| firewallServiceChecked: false, | |
| firewallServiceProvider: '', | |
| selectedServiceProviderMap: {}, | |
| isPublic: true, | |
| domains: [], | |
| domainLoading: false, | |
| zones: [], | |
| zoneLoading: false, | |
| ipv6NetworkOfferingEnabled: false, | |
| routedNetworkEnabled: false, | |
| loading: false, | |
| networkmode: '', | |
| networkmodes: [ | |
| { | |
| id: 0, | |
| name: 'NATTED' | |
| }, | |
| { | |
| id: 1, | |
| name: 'ROUTED' | |
| } | |
| ], | |
| routingMode: 'static', | |
| VPCVR: { | |
| name: 'VPCVirtualRouter', | |
| description: 'VPCVirtualRouter', | |
| enabled: true | |
| }, | |
| VR: { | |
| name: 'VirtualRouter', | |
| description: 'VirtualRouter', | |
| enabled: true | |
| }, | |
| NSX: { | |
| name: 'Nsx', | |
| description: 'Nsx', | |
| enabled: true | |
| }, | |
| Netris: { | |
| name: 'Netris', | |
| description: 'Netris', | |
| enabled: true | |
| }, | |
| nsxSupportedServicesMap: {}, | |
| netrisSupportedServicesMap: {} | |
| } | |
| }, | |
| beforeCreate () { | |
| this.apiParams = this.$getApiParams('createNetworkOffering') | |
| }, | |
| created () { | |
| this.zones = [ | |
| { | |
| id: null, | |
| name: this.$t('label.all.zone') | |
| } | |
| ] | |
| this.initForm() | |
| this.fetchData() | |
| }, | |
| methods: { | |
| initForm () { | |
| this.formRef = ref() | |
| this.form = reactive({ | |
| internetprotocol: this.internetProtocolValue, | |
| guestiptype: this.guestType, | |
| specifyvlan: true, | |
| lbtype: this.lbType, | |
| promiscuousmode: '', | |
| macaddresschanges: '', | |
| forgedtransmits: '', | |
| maclearning: this.macLearningValue, | |
| sourcenattype: 'peraccount', | |
| inlinemode: 'false', | |
| vmautoscalingcapability: true, | |
| isolation: 'dedicated', | |
| conservemode: true, | |
| availability: 'optional', | |
| egressdefaultpolicy: 'deny', | |
| ispublic: this.isPublic, | |
| nsxsupportlb: true, | |
| routingmode: 'static' | |
| }) | |
| this.rules = reactive({ | |
| name: [{ required: true, message: this.$t('message.error.name') }], | |
| networkrate: [{ type: 'number', validator: this.validateNumber }], | |
| domainid: [{ type: 'array', required: true, message: this.$t('message.error.select') }], | |
| zoneid: [{ | |
| type: 'array', | |
| validator: async (rule, value) => { | |
| if (value && value.length > 1 && value.indexOf(0) !== -1) { | |
| return Promise.reject(this.$t('message.error.zone.combined')) | |
| } | |
| return Promise.resolve() | |
| } | |
| }] | |
| }) | |
| }, | |
| fetchData () { | |
| this.fetchDomainData() | |
| this.fetchZoneData() | |
| this.fetchSupportedServiceData() | |
| this.fetchServiceOfferingData() | |
| this.fetchIpv6NetworkOfferingConfiguration() | |
| this.fetchRoutedNetworkConfiguration() | |
| }, | |
| isAdmin () { | |
| return isAdmin() | |
| }, | |
| isSupportedServiceObject (obj) { | |
| return (obj !== null && obj !== undefined && Object.keys(obj).length > 0 && obj.constructor === Object && 'provider' in obj) | |
| }, | |
| isVpcCoreProvider (providerName, serviceName) { | |
| if (['VpcVirtualRouter', 'Netscaler', 'BigSwitchBcf', 'ConfigDrive'].includes(providerName)) { | |
| return true | |
| } | |
| return serviceName === 'Connectivity' && ['NiciraNvp', 'Ovs', 'JuniperContrailVpcRouter'].includes(providerName) | |
| }, | |
| isBuiltInNetworkProvider (providerName) { | |
| const builtInProviders = [ | |
| 'VirtualRouter', 'JuniperContrailRouter', 'JuniperContrailVpcRouter', 'JuniperSRX', 'PaloAlto', | |
| 'F5BigIp', 'Netscaler', 'ExternalDhcpServer', 'ExternalGateWay', 'ElasticLoadBalancerVm', | |
| 'SecurityGroupProvider', 'VpcVirtualRouter', 'None', 'NiciraNvp', 'InternalLbVm', 'CiscoVnmc', | |
| 'Ovs', 'Opendaylight', 'BrocadeVcs', 'GloboDns', 'BigSwitchBcf', 'ConfigDrive', 'Tungsten', | |
| 'Nsx', 'Netris', 'BaremetalDhcpProvider', 'BaremetalPxeProvider', 'BaremetalUserdataProvider', | |
| 'StratosphereSsp' | |
| ] | |
| return builtInProviders.includes(providerName) | |
| }, | |
| fetchDomainData () { | |
| const params = {} | |
| params.listAll = true | |
| params.showicon = true | |
| params.details = 'min' | |
| this.domainLoading = true | |
| getAPI('listDomains', params).then(json => { | |
| const listDomains = json.listdomainsresponse.domain | |
| this.domains = this.domains.concat(listDomains) | |
| }).finally(() => { | |
| this.domainLoading = false | |
| }) | |
| }, | |
| fetchIpv6NetworkOfferingConfiguration () { | |
| this.ipv6NetworkOfferingEnabled = false | |
| var params = { name: 'ipv6.offering.enabled' } | |
| getAPI('listConfigurations', params).then(json => { | |
| var value = json?.listconfigurationsresponse?.configuration?.[0].value || null | |
| this.ipv6NetworkOfferingEnabled = value === 'true' | |
| }) | |
| }, | |
| fetchRoutedNetworkConfiguration () { | |
| this.routedNetworkEnabled = false | |
| var params = { name: 'routed.network.vpc.enabled' } | |
| getAPI('listConfigurations', params).then(json => { | |
| var value = json?.listconfigurationsresponse?.configuration?.[0].value || null | |
| this.routedNetworkEnabled = value === 'true' | |
| if (!this.routedNetworkEnabled) { | |
| this.networkmodes.pop() | |
| } | |
| }) | |
| }, | |
| fetchZoneData () { | |
| const params = {} | |
| params.showicon = true | |
| this.zoneLoading = true | |
| getAPI('listZones', params).then(json => { | |
| const listZones = json.listzonesresponse.zone | |
| this.zones = this.zones.concat(listZones) | |
| }).finally(() => { | |
| this.zoneLoading = false | |
| }) | |
| }, | |
| handleGuestTypeChange (val) { | |
| this.guestType = val | |
| this.networkmode = '' | |
| this.form.networkmode = '' | |
| if (val === 'l2') { | |
| this.form.forvpc = false | |
| this.form.lbtype = 'publicLb' | |
| this.isVirtualRouterForAtLeastOneService = false | |
| this.isVpcVirtualRouterForAtLeastOneService = false | |
| this.serviceOfferingLoading = false | |
| this.sourceNatServiceChecked = false | |
| this.lbServiceChecked = false | |
| this.lbServiceProvider = '' | |
| this.registeredServicePackages = [] | |
| this.registeredServicePackageLoading = false | |
| this.isElasticIp = false | |
| this.staticNatServiceChecked = false | |
| this.staticNatServiceProvider = '' | |
| this.connectivityServiceChecked = false | |
| this.firewallServiceChecked = false | |
| this.firewallServiceProvider = '' | |
| this.selectedServiceProviderMap = {} | |
| } | |
| this.fetchSupportedServiceData() | |
| }, | |
| fetchSupportedServiceData () { | |
| this.supportedServiceLoading = true | |
| this.supportedServices = [] | |
| getAPI('listSupportedNetworkServices').then(json => { | |
| this.supportedServices = json.listsupportednetworkservicesresponse.networkservice | |
| for (var i in this.supportedServices) { | |
| var networkServiceObj = this.supportedServices[i] | |
| var serviceName = networkServiceObj.name | |
| var serviceDisplayName = serviceName | |
| // Sanitize names | |
| // switch (serviceName) { | |
| // case 'Vpn': | |
| // serviceDisplayName = this.$t('label.vpn') | |
| // break | |
| // case 'Dhcp': | |
| // serviceDisplayName = this.$t('label.dhcp') | |
| // break | |
| // case 'Dns': | |
| // serviceDisplayName = this.$t('label.dns') | |
| // break | |
| // case 'Lb': | |
| // serviceDisplayName = this.$t('label.load.balancer') | |
| // break | |
| // case 'SourceNat': | |
| // serviceDisplayName = this.$t('label.source.nat') | |
| // break | |
| // case 'StaticNat': | |
| // serviceDisplayName = this.$t('label.static.nat') | |
| // break | |
| // case 'PortForwarding': | |
| // serviceDisplayName = this.$t('label.port.forwarding') | |
| // break | |
| // case 'UserData': | |
| // serviceDisplayName = this.$t('label.user.data') | |
| // break | |
| // case 'Connectivity': | |
| // serviceDisplayName = this.$t('label.virtual.networking') | |
| // break | |
| // default: | |
| // serviceDisplayName = serviceName | |
| // break | |
| // } | |
| var providers = [] | |
| for (var j in this.supportedServices[i].provider) { | |
| var provider = this.supportedServices[i].provider[j] | |
| provider.description = provider.name | |
| provider.displaytext = this.isBuiltInNetworkProvider(provider.name) | |
| ? provider.name | |
| : `${provider.name} (${this.$t('label.extension')})` | |
| provider.enabled = true | |
| if (provider.name === 'VpcVirtualRouter') { | |
| provider.enabled = false | |
| } | |
| if (provider.name === 'VirtualRouter') { | |
| providers.unshift(provider) | |
| } else { | |
| providers.push(provider) | |
| } | |
| } | |
| this.supportedServices[i].provider = providers | |
| this.supportedServices[i].description = serviceDisplayName | |
| } | |
| }).finally(() => { | |
| this.supportedServiceLoading = false | |
| this.updateSupportedServices() | |
| }) | |
| }, | |
| fetchServiceOfferingData () { | |
| const params = {} | |
| params.issystem = true | |
| params.systemvmtype = 'domainrouter' | |
| this.serviceOfferingLoading = true | |
| getAPI('listServiceOfferings', params).then(json => { | |
| this.serviceOfferings = json?.listserviceofferingsresponse?.serviceoffering || [] | |
| }).finally(() => { | |
| this.serviceOfferingLoading = false | |
| }) | |
| }, | |
| fetchRegisteredServicePackageData () { | |
| this.registeredServicePackageLoading = true | |
| this.registeredServicePackages = [] | |
| getAPI('listRegisteredServicePackages', {}).then(json => { | |
| var servicePackages = json.listregisteredservicepackage.registeredServicepackage | |
| if (servicePackages === undefined || servicePackages == null || !servicePackages) { | |
| servicePackages = json.listregisteredservicepackage | |
| } | |
| for (var i in servicePackages) { | |
| this.registeredServicePackages.push({ | |
| id: servicePackages[i].id, | |
| description: servicePackages[i].name, | |
| desc: servicePackages[i].description | |
| }) | |
| } | |
| }).finally(() => { | |
| this.registeredServicePackageLoading = false | |
| }) | |
| }, | |
| updateSupportedServices () { | |
| this.supportedServiceLoading = true | |
| var supportedServices = this.supportedServices | |
| var self = this | |
| if (this.provider !== 'NSX' && this.provider !== 'Netris') { | |
| if (this.networkmode === 'ROUTED' && this.guestType === 'isolated') { | |
| supportedServices = supportedServices.filter(service => { | |
| return !['SourceNat', 'StaticNat', 'Lb', 'PortForwarding', 'Vpn'].includes(service.name) | |
| }) | |
| } | |
| supportedServices.forEach(function (svc, index) { | |
| if (svc.name !== 'Connectivity') { | |
| var providers = svc.provider | |
| providers.forEach(function (provider, providerIndex) { | |
| if (self.forVpc) { // *** vpc *** | |
| // Keep the known VPC-safe providers allowlisted and only additionally enable | |
| // extension providers, which listSupportedNetworkServices() already only returns | |
| // for a service once the extension is confirmed to support it. | |
| if (provider.name === 'InternalLbVm') { | |
| provider.enabled = self.lbType === 'internalLb' && svc.name === 'Lb' | |
| } else { | |
| provider.enabled = self.isVpcCoreProvider(provider.name, svc.name) || | |
| !self.isBuiltInNetworkProvider(provider.name) | |
| } | |
| if (svc.name === 'Firewall' && provider.name === 'VpcVirtualRouter') { | |
| provider.enabled = false | |
| } | |
| } else { // *** non-vpc *** | |
| provider.enabled = !['InternalLbVm', 'VpcVirtualRouter', 'Nsx', 'Netris'].includes(provider.name) | |
| } | |
| providers[providerIndex] = provider | |
| }) | |
| svc.provider = providers | |
| supportedServices[index] = svc | |
| } | |
| }) | |
| setTimeout(() => { | |
| self.supportedSvcs = self.supportedServices | |
| self.supportedServices = supportedServices | |
| self.supportedServiceLoading = false | |
| }, 50) | |
| } else { | |
| supportedServices = this.supportedSvcs | |
| supportedServices = supportedServices.filter(svc => { | |
| if (this.provider === 'NSX') { | |
| return Object.keys(this.nsxSupportedServicesMap).includes(svc.name) | |
| } else if (this.provider === 'Netris') { | |
| return Object.keys(this.netrisSupportedServicesMap).includes(svc.name) | |
| } | |
| }) | |
| supportedServices = supportedServices.map(svc => { | |
| if (!['Dhcp', 'Dns', 'UserData'].includes(svc.name)) { | |
| if (this.provider === 'NSX') { | |
| svc.provider = [this.NSX] | |
| } else if (this.provider === 'Netris') { | |
| svc.provider = [this.Netris] | |
| } | |
| } else { | |
| if (this.forVpc) { | |
| svc.provider = [this.VPCVR] | |
| } else { | |
| svc.provider = [this.VR] | |
| } | |
| } | |
| return svc | |
| }) | |
| self.supportedSvcs = self.supportedServices | |
| self.supportedServices = supportedServices | |
| self.supportedServiceLoading = false | |
| } | |
| }, | |
| handleForVpcChange (forVpc) { | |
| this.forVpc = forVpc | |
| if (this.provider === 'NSX') { | |
| this.nsxSupportedServicesMap = { | |
| Dhcp: this.forVpc ? this.VPCVR : this.VR, | |
| Dns: this.forVpc ? this.VPCVR : this.VR, | |
| UserData: this.forVpc ? this.VPCVR : this.VR, | |
| ...(this.networkmode === 'NATTED' && { | |
| SourceNat: this.NSX, | |
| StaticNat: this.NSX, | |
| PortForwarding: this.NSX, | |
| Lb: this.NSX | |
| }), | |
| ...(forVpc && { NetworkACL: this.NSX }), | |
| ...(!forVpc && { Firewall: this.NSX }) | |
| } | |
| } else if (this.provider === 'Netris') { | |
| this.netrisSupportedServicesMap = { | |
| Dhcp: this.forVpc ? this.VPCVR : this.VR, | |
| Dns: this.forVpc ? this.VPCVR : this.VR, | |
| UserData: this.forVpc ? this.VPCVR : this.VR, | |
| ...(this.networkmode === 'NATTED' && { | |
| SourceNat: this.Netris, | |
| StaticNat: this.Netris, | |
| PortForwarding: this.Netris, | |
| Lb: this.Netris | |
| }), | |
| ...(forVpc && { NetworkACL: this.Netris }), | |
| ...(!forVpc && { Firewall: this.Netris }) | |
| } | |
| } | |
| this.updateSupportedServices() | |
| }, | |
| handleProviderChange (provider) { | |
| this.provider = provider | |
| if (this.provider === 'NSX') { | |
| this.nsxSupportedServicesMap = { | |
| Dhcp: this.forVpc ? this.VPCVR : this.VR, | |
| Dns: this.forVpc ? this.VPCVR : this.VR, | |
| UserData: this.forVpc ? this.VPCVR : this.VR, | |
| ...(this.networkmode === 'NATTED' && { | |
| SourceNat: this.NSX, | |
| StaticNat: this.NSX, | |
| PortForwarding: this.NSX, | |
| Lb: this.NSX | |
| }), | |
| ...(this.forVpc && { NetworkACL: this.NSX }), | |
| ...(!this.forVpc && { Firewall: this.NSX }) | |
| } | |
| } else if (this.provider === 'Netris') { | |
| this.netrisSupportedServicesMap = { | |
| Dhcp: this.forVpc ? this.VPCVR : this.VR, | |
| Dns: this.forVpc ? this.VPCVR : this.VR, | |
| UserData: this.forVpc ? this.VPCVR : this.VR, | |
| ...(this.networkmode === 'NATTED' && { | |
| SourceNat: this.Netris, | |
| StaticNat: this.Netris, | |
| PortForwarding: this.Netris, | |
| Lb: this.Netris | |
| }), | |
| ...(this.forVpc && { NetworkACL: this.Netris }), | |
| ...(!this.forVpc && { Firewall: this.Netris }) | |
| } | |
| } | |
| this.fetchSupportedServiceData() | |
| }, | |
| handleForNetworkModeChange (networkMode) { | |
| this.networkmode = networkMode | |
| this.fetchSupportedServiceData() | |
| }, | |
| handleNsxLbService (supportLb) { | |
| if (!supportLb && 'Lb' in this.nsxSupportedServicesMap) { | |
| delete this.nsxSupportedServicesMap.Lb | |
| } | |
| if (supportLb && !('Lb' in this.nsxSupportedServicesMap)) { | |
| this.nsxSupportedServicesMap.Lb = this.NSX | |
| } | |
| this.fetchSupportedServiceData() | |
| }, | |
| handleLbTypeChange (lbType) { | |
| this.lbType = lbType | |
| this.updateSupportedServices() | |
| }, | |
| handleSupportedServiceChange (service, checked, provider) { | |
| if (service === 'SourceNat') { | |
| this.sourceNatServiceChecked = checked | |
| } else if (service === 'Lb') { | |
| if (checked) { | |
| this.fetchRegisteredServicePackageData() | |
| if (provider != null & provider !== undefined) { | |
| this.lbServiceProvider = provider | |
| } | |
| } else { | |
| this.lbServiceProvider = '' | |
| } | |
| this.lbServiceChecked = checked | |
| } else if (service === 'StaticNat') { | |
| this.staticNatServiceChecked = checked | |
| if (checked && provider != null & provider !== undefined) { | |
| this.staticNatServiceProvider = provider | |
| } else { | |
| this.staticNatServiceProvider = '' | |
| } | |
| } else if (service === 'Connectivity') { | |
| this.connectivityServiceChecked = checked | |
| } else if (service === 'Firewall') { | |
| this.firewallServiceChecked = checked | |
| if (checked && provider != null & provider !== undefined) { | |
| this.staticNatServiceProvider = provider | |
| } else { | |
| this.staticNatServiceProvider = '' | |
| } | |
| } | |
| if (checked && provider != null & provider !== undefined) { | |
| this.selectedServiceProviderMap[service] = provider | |
| } else { | |
| delete this.selectedServiceProviderMap[service] | |
| } | |
| var providers = Object.values(this.selectedServiceProviderMap) | |
| this.isVirtualRouterForAtLeastOneService = false | |
| this.isVpcVirtualRouterForAtLeastOneService = false | |
| var self = this | |
| providers.forEach(function (prvdr, idx) { | |
| if (prvdr === 'VirtualRouter') { | |
| self.isVirtualRouterForAtLeastOneService = true | |
| } | |
| if (prvdr === 'VpcVirtualRouter') { | |
| self.isVpcVirtualRouterForAtLeastOneService = true | |
| } | |
| if ((self.isVirtualRouterForAtLeastOneService || self.isVpcVirtualRouterForAtLeastOneService) && | |
| self.serviceOfferings.length === 0) { | |
| self.fetchServiceOfferingData() | |
| } | |
| }) | |
| }, | |
| handleSubmit (e) { | |
| e.preventDefault() | |
| if (this.loading) return | |
| this.formRef.value.validate().then(() => { | |
| const formRaw = toRaw(this.form) | |
| const values = this.handleRemoveFields(formRaw) | |
| var params = {} | |
| var keys = Object.keys(values) | |
| const detailsKey = ['promiscuousmode', 'macaddresschanges', 'forgedtransmits', 'maclearning'] | |
| const ignoredKeys = [...detailsKey, 'state', 'status', 'allocationstate', 'forvpc', 'lbType', 'specifyvlan', 'ispublic', 'domainid', 'zoneid', 'egressdefaultpolicy', 'isolation', 'supportspublicaccess'] | |
| keys.forEach(function (key, keyIndex) { | |
| if (!ignoredKeys.includes(key) && | |
| values[key] != null && values[key] !== undefined && | |
| !(key === 'availability' && values[key] === 'Optional')) { | |
| params[key] = values[key] | |
| } | |
| }) | |
| if (values.guestiptype === 'shared') { // specifyVlan checkbox is disabled, so inputData won't include specifyVlan | |
| if (values.specifyvlan === true) { | |
| params.specifyvlan = true | |
| } | |
| params.specifyipranges = true | |
| delete params.ispersistent | |
| } else if (values.guestiptype === 'isolated') { // specifyVlan checkbox is shown | |
| if (values.specifyvlan === true) { | |
| params.specifyvlan = true | |
| } | |
| if (values.ispersistent) { | |
| params.ispersistent = true | |
| } else { // Isolated Network with Non-persistent network | |
| delete params.ispersistent | |
| } | |
| } else if (values.guestiptype === 'l2') { | |
| if (values.specifyvlan === true) { | |
| params.specifyvlan = true | |
| } | |
| if (values.userdatal2 === true) { | |
| params['serviceProviderList[0].service'] = 'UserData' | |
| params['serviceProviderList[0].provider'] = 'ConfigDrive' | |
| params.supportedservices = 'UserData' | |
| } | |
| // Conserve mode is irrelevant on L2 network offerings as there are no resources to conserve, do not pass it, true by default on server side | |
| delete params.conservemode | |
| } | |
| if (values.forvpc === true) { | |
| params.forvpc = true | |
| } | |
| if (!values.forVpc) { | |
| params.specifyasnumber = values.specifyasnumber | |
| } | |
| params.routingmode = values.routingmode | |
| const forNsx = values.provider === 'NSX' | |
| if (forNsx === true) { | |
| params.provider = 'NSX' | |
| params.nsxsupportlb = values.nsxsupportlb | |
| params.nsxsupportsinternallb = values.nsxsupportsinternallb | |
| } | |
| const forNetris = values.provider === 'Netris' | |
| if (forNetris) { | |
| params.provider = 'Netris' | |
| } | |
| if (values.guestiptype === 'isolated') { | |
| params.networkmode = values.networkmode | |
| } | |
| if (values.guestiptype === 'shared' || values.guestiptype === 'isolated') { | |
| if (values.conservemode !== true) { | |
| params.conservemode = false | |
| } | |
| } | |
| if (this.selectedServiceProviderMap != null) { | |
| buildServiceCapabilityParams(params, values, this.selectedServiceProviderMap, this.registeredServicePackages) | |
| } else { | |
| if (!('supportedservices' in params)) { | |
| params.supportedservices = '' | |
| } | |
| } | |
| if (values.guestiptype === 'l2' && values.userdatal2 === true) { | |
| params.supportedservices = 'UserData' | |
| } | |
| if ('egressdefaultpolicy' in values && values.egressdefaultpolicy !== 'allow') { | |
| params.egressdefaultpolicy = false | |
| } | |
| for (const key of detailsKey) { | |
| if (values[key]) { | |
| params['details[0].' + key] = values[key] | |
| } | |
| } | |
| if (values.ispublic !== true) { | |
| var domainIndexes = values.domainid | |
| var domainId = null | |
| if (domainIndexes && domainIndexes.length > 0) { | |
| var domainIds = [] | |
| for (var i = 0; i < domainIndexes.length; i++) { | |
| domainIds = domainIds.concat(this.domains[domainIndexes[i]].id) | |
| } | |
| domainId = domainIds.join(',') | |
| } | |
| if (domainId) { | |
| params.domainid = domainId | |
| } | |
| } | |
| var zoneIndexes = values.zoneid | |
| var zoneId = null | |
| if (zoneIndexes && zoneIndexes.length > 0) { | |
| var zoneIds = [] | |
| for (var j = 0; j < zoneIndexes.length; j++) { | |
| zoneIds = zoneIds.concat(this.zones[zoneIndexes[j]].id) | |
| } | |
| zoneId = zoneIds.join(',') | |
| } | |
| if (zoneId) { | |
| params.zoneid = zoneId | |
| } | |
| if (values.enable) { | |
| params.enable = values.enable | |
| } | |
| params.traffictype = 'GUEST' // traffic type dropdown has been removed since it has only one option ('Guest'). Hardcode traffic type value here. | |
| postAPI('createNetworkOffering', params).then(json => { | |
| this.$message.success('Network offering created: ' + values.name) | |
| this.$emit('refresh-data') | |
| this.closeAction() | |
| }).catch(error => { | |
| this.$notifyError(error) | |
| }).finally(() => { | |
| this.loading = false | |
| }) | |
| }) | |
| }, | |
| closeAction () { | |
| this.$emit('close-action') | |
| }, | |
| async validateNumber (rule, value) { | |
| if (value && (isNaN(value) || value <= 0)) { | |
| return Promise.reject(this.$t('message.error.number')) | |
| } | |
| return Promise.resolve() | |
| } | |
| } | |
| } | |
| </script> | |
| <style scoped lang="scss"> | |
| .form-layout { | |
| width: 80vw; | |
| @media (min-width: 800px) { | |
| width: 600px; | |
| } | |
| } | |
| .supported-services-container { | |
| height: 250px; | |
| overflow: auto; | |
| } | |
| </style> |