blob: e44d3347a365c6ac6150349d249a2367b868951e [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
<template>
<div>
<a-card
class="ant-form-text"
style="text-align: justify; margin: 10px 0; padding: 24px;"
v-html="$t(description)">
</a-card>
<a-form class="form-content" :form="form" @submit="handleSubmit">
<a-form-item
:label="$t('label.name')"
v-bind="formItemLayout"
has-feedback>
<a-input
v-decorator="['name', {
rules: [{
required: true,
message: $t('message.error.zone.name'),
initialValue: name
}]
}]"
/>
</a-form-item>
<a-form-item
:label="$t('label.ipv4.dns1')"
v-bind="formItemLayout"
has-feedback>
<a-input
v-decorator="['ipv4Dns1', {
rules: [
{
required: true,
message: $t('message.error.ipv4.dns1'),
initialValue: ipv4Dns1
},
{
validator: checkIpFormat,
ipV4: true,
message: $t('message.error.ipv4.address')
}
]
}]"
/>
</a-form-item>
<a-form-item
:label="$t('label.ipv4.dns2')"
v-bind="formItemLayout"
has-feedback>
<a-input
v-decorator="['ipv4Dns2', {
rules: [
{
message: $t('message.error.ipv4.dns2'),
initialValue: ipv4Dns2
},
{
validator: checkIpFormat,
ipV4: true,
message: $t('message.error.ipv4.address')
}
]
}]"
/>
</a-form-item>
<a-form-item
:label="$t('label.ipv6.dns1')"
v-bind="formItemLayout"
v-if="isAdvancedZone"
has-feedback>
<a-input
v-decorator="['ipv6Dns1', {
rules: [
{
message: $t('message.error.ipv6.dns1'),
initialValue: ipv6Dns1
},
{
validator: checkIpFormat,
ipV6: true,
message: $t('message.error.ipv6.address')
}
]
}]"
/>
</a-form-item>
<a-form-item
:label="$t('label.ipv6.dns2')"
v-bind="formItemLayout"
v-if="isAdvancedZone"
has-feedback>
<a-input
v-decorator="['ipv6Dns2', {
rules: [
{
message: $t('message.error.ipv6.dns2'),
initialValue: ipv6Dns2
},
{
validator: checkIpFormat,
ipV6: true,
message: $t('message.error.ipv6.address')
}
]
}]"
/>
</a-form-item>
<a-form-item
:label="$t('label.ip6cidr')"
v-bind="formItemLayout"
v-if="isAdvancedZone && securityGroupsEnabled"
has-feedback>
<a-input
v-decorator="['ipv6Cidr', {
rules: [
{
message: $t('message.error.ipv6.cidr'),
initialValue: ipv6Cidr
}
]
}]"
/>
</a-form-item>
<a-form-item
:label="$t('label.ip6gateway')"
v-bind="formItemLayout"
v-if="isAdvancedZone && securityGroupsEnabled"
has-feedback>
<a-input
v-decorator="['ip6gateway', {
rules: [
{
message: $t('message.error.ipv6.gateway'),
initialValue: ip6gateway
},
{
validator: checkIpFormat,
ipV6: true,
message: $t('message.error.ipv6.gateway.format')
}
]
}]"
/>
</a-form-item>
<a-form-item
:label="$t('label.internal.dns.1')"
v-bind="formItemLayout"
has-feedback>
<a-input
v-decorator="['internalDns1', {
rules: [
{
required: true,
message: $t('message.error.internal.dns1'),
initialValue: internalDns1
},
{
validator: checkIpFormat,
ipV4: true,
message: $t('message.error.ipv4.address')
}
]
}]"
/>
</a-form-item>
<a-form-item
:label="$t('label.internal.dns.2')"
v-bind="formItemLayout"
has-feedback>
<a-input
v-decorator="['internalDns2', {
rules: [
{
message: $t('message.error.internal.dns2'),
initialValue: internalDns2
},
{
validator: checkIpFormat,
ipV4: true,
message: $t('message.error.ipv4.address')
}
]
}]"
/>
</a-form-item>
<a-form-item
:label="$t('label.hypervisor')"
v-bind="formItemLayout"
has-feedback>
<a-select
:loading="hypervisors === null"
showSearch
v-decorator="['hypervisor',{
rules: [{
required: true,
message: $t('message.error.hypervisor.type'),
initialValue: currentHypervisor
}]
}]"
:placeholder="$t('message.error.hypervisor.type')"
>
<a-select-option v-for="hypervisor in hypervisors" :key="hypervisor.name">
{{ hypervisor.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item
:label="$t('label.network.offering')"
v-bind="formItemLayout"
v-if="!isAdvancedZone || securityGroupsEnabled"
has-feedback>
<a-select
:loading="availableNetworkOfferings === null"
v-decorator="['networkOfferingId', {
rules: [{
message: $t('message.error.network.offering'),
initialValue: currentNetworkOfferingId
}]
}]"
:placeholder="$t('message.error.network.offering')"
>
<a-select-option
v-for="networkOffering in availableNetworkOfferings"
:key="networkOffering.id">
{{ networkOffering.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item
:label="$t('label.network.domain')"
v-bind="formItemLayout"
has-feedback>
<a-input
v-decorator="['networkDomain', {
rules: [{
message: $t('message.error.network.domain'),
intialValue: networkDomain
}]
}]"
/>
</a-form-item>
<a-form-item
:label="$t('label.guest.cidr')"
v-bind="formItemLayout"
v-if="isAdvancedZone && !securityGroupsEnabled"
has-feedback>
<a-input
v-decorator="['guestcidraddress', {
rules: [{
intialValue: guestcidraddress
}]
}]"
/>
</a-form-item>
<a-form-item
:label="$t('label.dedicated')"
v-bind="formItemLayout">
<a-switch
v-decorator="['isDedicated', { valuePropName: 'checked' }]"
:value="isDedicated"
/>
</a-form-item>
<a-form-item
:label="$t('label.domains')"
v-bind="formItemLayout"
has-feedback
v-if="isDedicated">
<a-select
:loading="domains === null"
v-decorator="['domainId', {
rules: [{
initialValue: domain
}]
}]"
:placeholder="$t('message.error.select.domain.to.dedicate')"
>
<a-select-option v-for="dom in domains" :key="dom.id">
{{ dom.path }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item
:label="$t('label.account')"
v-bind="formItemLayout"
v-if="isDedicated">
<a-input
v-decorator="['account', {
rules: [{
intialValue: guestcidraddress
}]
}]"
/>
</a-form-item>
<a-form-item
:label="$t('label.local.storage.enabled')"
v-bind="formItemLayout">
<a-switch
v-decorator="['localstorageenabled', { valuePropName: 'checked' }]"
:value="localstorageenabled"
/>
</a-form-item>
<a-form-item
:label="$t('label.local.storage.enabled.system.vms')"
v-bind="formItemLayout">
<a-switch
v-decorator="['localstorageenabledforsystemvm', { valuePropName: 'checked' }]"
:value="localstorageenabledforsystemvm"
/>
</a-form-item>
</a-form>
<div class="form-action">
<a-button
@click="handleBack"
class="button-back"
v-if="!isFixError">
{{ $t('label.previous') }}
</a-button>
<a-button type="primary" @click="handleSubmit" class="button-next">
{{ $t('label.next') }}
</a-button>
</div>
</div>
</template>
<script>
import { api } from '@/api'
export default {
props: {
prefillContent: {
type: Object,
default: function () {
return {}
}
},
isFixError: {
type: Boolean,
default: false
}
},
data: () => ({
description: 'message.desc.zone',
formItemLayout: {
labelCol: { span: 8 },
wrapperCol: { span: 12 }
},
hypervisors: null,
networkOfferings: null,
domains: null,
baremetalProviders: ['BaremetalDhcpProvider', 'BaremetalPxeProvider', 'BaremetalUserdataProvider'],
selectedBaremetalProviders: [],
availableNetworkOfferings: null,
ipV4Regex: /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i,
ipV6Regex: /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i
}),
created () {
this.hypervisors = this.prefillContent.hypervisors ? this.prefillContent.hypervisors : null
this.networkOfferings = this.prefillContent.networkOfferings ? this.prefillContent.networkOfferings : null
this.form = this.$form.createForm(this, {
onFieldsChange: (_, changedFields) => {
if (changedFields.networkOfferingId && this.prefillContent.networkOfferingSelected) {
if (this.prefillContent.networkOfferingSelected.id !== changedFields.networkOfferingId.value) {
changedFields.physicalNetworks = []
}
}
if (this.networkOfferings && changedFields.networkOfferingId) {
changedFields.networkOfferings = this.networkOfferings
changedFields.networkOfferingSelected = this.networkOfferings[changedFields.networkOfferingId.value]
}
if (this.hypervisors && changedFields.hypervisor) {
changedFields.hypervisors = this.hypervisors
this.availableNetworkOfferings = this.getAvailableNetworkOfferings(changedFields.hypervisor)
}
if (this.domains && changedFields.domain) {
changedFields.domains = this.domains
}
this.$emit('fieldsChanged', changedFields)
}
})
},
mounted () {
this.form.setFieldsValue({
name: this.name,
ipv4Dns1: this.ipv4Dns1,
ipv4Dns2: this.ipv4Dns2,
ipv6Dns1: this.ipv6Dns1,
ipv6Dns2: this.ipv6Dns2,
internalDns1: this.internalDns1,
internalDns2: this.internalDns2,
hypervisor: this.currentHypervisor,
networkOfferingId: this.currentNetworkOfferingId,
networkDomain: this.networkDomain,
guestcidraddress: this.isAdvancedZone && !this.securityGroupsEnabled ? this.guestcidraddress : null,
isDedicated: this.isDedicated,
domain: this.domain,
account: this.account,
localstorageenabled: this.localstorageenabled,
localstorageenabledforsystemvm: this.localstorageenabledforsystemvm
})
const cForm = this.form
api('listHypervisors', { listAll: true }).then(json => {
this.hypervisors = json.listhypervisorsresponse.hypervisor
if ('listSimulatorHAStateTransitions' in this.$store.getters.apis) {
this.hypervisors.push({ name: 'Simulator' })
}
cForm.setFieldsValue({
hypervisor: this.currentHypervisor
})
})
if (!this.isAdvancedZone || this.securityGroupsEnabled) {
api('listNetworkOfferings', { state: 'Enabled', guestiptype: 'Shared' }).then(json => {
this.networkOfferings = {}
json.listnetworkofferingsresponse.networkoffering.forEach(offering => {
this.setupNetworkOfferingAdditionalFlags(offering)
this.networkOfferings[offering.id] = offering
})
this.availableNetworkOfferings = this.getAvailableNetworkOfferings(this.currentHypervisor)
cForm.setFieldsValue({
networkOfferingId: this.currentNetworkOfferingId
})
})
}
api('listDomains', { listAll: true }).then(json => {
this.domains = {}
json.listdomainsresponse.domain.forEach(dom => {
this.domains[dom.id] = dom
})
cForm.setFieldsValue({
domain: this.domain
})
})
},
computed: {
isAdvancedZone () {
return this.zoneType === 'Advanced'
},
zoneType () {
return this.prefillContent.zoneType ? this.prefillContent.zoneType.value : null
},
securityGroupsEnabled () {
return this.isAdvancedZone && (this.prefillContent.securityGroupsEnabled ? this.prefillContent.securityGroupsEnabled.value : false)
},
name () {
return this.prefillContent.name ? this.prefillContent.name.value : null
},
ipv4Dns1 () {
return this.prefillContent.ipv4Dns1 ? this.prefillContent.ipv4Dns1.value : null
},
ipv4Dns2 () {
return this.prefillContent.ipv4Dns2 ? this.prefillContent.ipv4Dns2.value : null
},
ipv6Dns1 () {
return this.prefillContent.ipv6Dns1 ? this.prefillContent.ipv6Dns1.value : null
},
ipv6Dns2 () {
return this.prefillContent.ipv6Dns2 ? this.prefillContent.ipv6Dns2.value : null
},
internalDns1 () {
return this.prefillContent.internalDns1 ? this.prefillContent.internalDns1.value : null
},
internalDns2 () {
return this.prefillContent.internalDns2 ? this.prefillContent.internalDns2.value : null
},
ipv6Cidr () {
return this.prefillContent.ipv6Cidr ? this.prefillContent.ipv6Cidr.value : null
},
ip6gateway () {
return this.prefillContent.ip6gateway ? this.prefillContent.ip6gateway.value : null
},
currentHypervisor () {
if (this.prefillContent.hypervisor) {
return this.prefillContent.hypervisor.value
} else if (this.hypervisors && this.hypervisors.length > 0) {
return this.hypervisors[0]
}
return null
},
currentNetworkOfferingId () {
const lastNetworkOfferingId = this.prefillContent.networkOfferingSelected ? this.prefillContent.networkOfferingSelected.id : null
if (this.networkOfferings) {
if (lastNetworkOfferingId !== null && this.networkOfferings[lastNetworkOfferingId]) {
return lastNetworkOfferingId
}
return this.availableNetworkOfferings[0].id
}
return null
},
networkDomain () {
return this.prefillContent.networkDomain ? this.prefillContent.networkDomain.value : null
},
guestcidraddress () {
return this.prefillContent.guestcidraddress ? this.prefillContent.guestcidraddress.value : '10.1.1.0/24'
},
isDedicated () {
return this.prefillContent.isDedicated ? this.prefillContent.isDedicated.value : false
},
domain () {
const lastDomainId = this.prefillContent.domainId ? this.prefillContent.domainId.value : null
if (this.domains !== null && lastDomainId !== null && this.domains[lastDomainId]) {
return lastDomainId
}
return null
},
account () {
return this.prefillContent.account ? this.prefillContent.account.value : null
},
localstorageenabled () {
return this.prefillContent.localstorageenabled ? this.prefillContent.localstorageenabled.value : false
},
localstorageenabledforsystemvm () {
return this.prefillContent.localstorageenabledforsystemvm ? this.prefillContent.localstorageenabledforsystemvm.value : false
}
},
methods: {
handleSubmit (e) {
e.preventDefault()
this.form.validateFields((err, values) => {
if (err) {
return
}
if (this.isFixError) {
this.$emit('submitLaunchZone')
return
}
this.$emit('nextPressed')
})
},
handleBack (e) {
this.$emit('backPressed')
},
setupNetworkOfferingAdditionalFlags (nOffering) {
nOffering.havingNetscaler = false
nOffering.havingSG = false
nOffering.havingEIP = false
nOffering.havingELB = false
nOffering.selectedBaremetalProviders = []
nOffering.service.forEach(service => {
service.provider.forEach(provider => {
if (provider.name === 'Netscaler') {
nOffering.havingNetscaler = true
} else if (this.baremetalProviders.includes(provider.name)) {
this.selectedBaremetalProviders.push(this.name)
nOffering.selectedBaremetalProviders = this.selectedBaremetalProviders
}
})
if (service.name === 'SecurityGroup') {
nOffering.havingSG = true
} else if (service.name === 'StaticNat') {
service.capability.forEach(capability => {
if (capability.name === 'ElasticIp' && capability.value === 'true') {
nOffering.havingEIP = true
}
})
} else if (service.name === 'Lb') {
service.capability.forEach(capability => {
if (capability.name === 'ElasticLb' && capability.value === 'true') {
nOffering.havingELB = true
}
})
}
})
},
getAvailableNetworkOfferings (hypervisor) {
if (this.networkOfferings) {
return Object.values(this.networkOfferings).filter(nOffering => {
if ((hypervisor === 'VMware' ||
(this.isAdvancedZone && this.securityGroupsEnabled)) &&
(nOffering.havingEIP && nOffering.havingELB)) {
return false
}
if (this.isAdvancedZone && this.securityGroupsEnabled && !nOffering.havingSG) {
return false
}
return true
})
}
return null
},
checkIpFormat (rule, value, callback) {
if (!value || value === '') {
callback()
} else if (rule.ipV4 && !this.ipV4Regex.test(value)) {
callback(rule.message)
} else if (rule.ipV6 && !this.ipV6Regex.test(value)) {
callback(rule.message)
} else {
callback()
}
}
}
}
</script>
<style scoped lang="less">
.form-content {
border: 1px dashed #e9e9e9;
border-radius: 6px;
background-color: #fafafa;
min-height: 200px;
text-align: center;
vertical-align: center;
padding: 8px;
padding-top: 16px;
margin-top: 8px;
max-height: 40vh;
overflow-y: auto;
/deep/.has-error {
.ant-form-explain {
text-align: left;
}
}
/deep/.ant-form-item-control {
text-align: left;
}
}
</style>