mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +01:00
vm wizard: add MAC Address validator (#657)
* vm wizard: add MAC Address validator * show IP range and check valid IP range * add CIDR into expanding of network selection & configuration * hide element when network type !== L2 Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
parent
2ad58f0973
commit
c697322bad
@ -1254,6 +1254,7 @@
|
||||
"label.lun.number": "LUN #",
|
||||
"label.lxcnetworklabel": "LXC Traffic Label",
|
||||
"label.macaddress": "MAC Address",
|
||||
"label.macaddress.example": "The MAC Address. Example: 01:23:45:67:89:ab",
|
||||
"label.macaddresschanges": "MAC Address Changes",
|
||||
"label.macos": "MacOS",
|
||||
"label.make.project.owner": "Make account project owner",
|
||||
@ -2743,6 +2744,7 @@
|
||||
"message.error.internallb.name": "Please specify a name for the Internal LB",
|
||||
"message.error.internallb.source.port": "Please specify a Source Port",
|
||||
"message.error.invalid.range": "Please enter values from {min} to {max}",
|
||||
"message.error.ip.range": "Please enter valid range",
|
||||
"message.error.ipv4.address": "Please enter a valid IPv4 address",
|
||||
"message.error.ipv4.dns1": "Please enter IpV4 DNS 1",
|
||||
"message.error.ipv4.dns2": "Please enter IpV4 DNS 2",
|
||||
@ -2757,6 +2759,7 @@
|
||||
"message.error.limit.value": "The value must not be less than",
|
||||
"message.error.loading.setting": "There was an error loading these settings.",
|
||||
"message.error.lun": "Please enter LUN #",
|
||||
"message.error.macaddress": "Please enter a valid MAC Address.",
|
||||
"message.error.name": "Please enter name",
|
||||
"message.error.netmask": "Please enter Netmask",
|
||||
"message.error.network.domain": "Please enter Network domain",
|
||||
|
||||
@ -25,17 +25,45 @@
|
||||
size="middle"
|
||||
:scroll="{ y: 225 }"
|
||||
>
|
||||
<template slot="name" slot-scope="text, record">
|
||||
<div>{{ text }}</div>
|
||||
<small v-if="record.type!=='L2'">{{ $t('label.cidr') + ': ' + record.cidr }}</small>
|
||||
</template>
|
||||
<template slot="ipAddress" slot-scope="text, record">
|
||||
<a-input
|
||||
style="width: 150px;"
|
||||
:placeholder="$t('label.ipaddress')"
|
||||
@change="($event) => updateNetworkData('ipAddress', record.id, $event.target.value)" />
|
||||
<a-form-item v-if="record.type!=='L2'">
|
||||
<a-input
|
||||
style="width: 150px;"
|
||||
v-decorator="['ipAddress' + record.id, {
|
||||
rules: [{
|
||||
validator: validatorIpAddress,
|
||||
cidr: record.cidr,
|
||||
networkType: record.type
|
||||
}]
|
||||
}]"
|
||||
:placeholder="record.cidr"
|
||||
@change="($event) => updateNetworkData('ipAddress', record.id, $event.target.value)">
|
||||
<a-tooltip v-if="record.type !== 'L2'" slot="suffix" :title="getIpRangeDescription(record)">
|
||||
<a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
|
||||
</a-tooltip>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</template>
|
||||
<template slot="macAddress" slot-scope="text, record">
|
||||
<a-input
|
||||
style="width: 150px;"
|
||||
:placeholder="$t('label.macaddress')"
|
||||
@change="($event) => updateNetworkData('macAddress', record.id, $event.target.value)" />
|
||||
<a-form-item>
|
||||
<a-input
|
||||
style="width: 150px;"
|
||||
:placeholder="$t('label.macaddress')"
|
||||
v-decorator="[`macAddress` + record.id, {
|
||||
rules: [{
|
||||
validator: validatorMacAddress
|
||||
}]
|
||||
}]"
|
||||
@change="($event) => updateNetworkData('macAddress', record.id, $event.target.value)">
|
||||
<a-tooltip slot="suffix" :title="$t('label.macaddress.example')">
|
||||
<a-icon type="info-circle" style="color: rgba(0,0,0,.45)" />
|
||||
</a-tooltip>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
@ -64,7 +92,8 @@ export default {
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: this.$t('label.defaultnetwork'),
|
||||
width: '30%'
|
||||
width: '30%',
|
||||
scopedSlots: { customRender: 'name' }
|
||||
},
|
||||
{
|
||||
dataIndex: 'ip',
|
||||
@ -80,7 +109,9 @@ export default {
|
||||
}
|
||||
],
|
||||
selectedRowKeys: [],
|
||||
dataItems: []
|
||||
dataItems: [],
|
||||
macRegex: /^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$/i,
|
||||
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
|
||||
}
|
||||
},
|
||||
beforeCreate () {
|
||||
@ -150,6 +181,49 @@ export default {
|
||||
this.$emit('select-default-network-item', this.dataItems[0].id)
|
||||
}
|
||||
}
|
||||
},
|
||||
validatorMacAddress (rule, value, callback) {
|
||||
if (!value || value === '') {
|
||||
callback()
|
||||
} else if (!this.macRegex.test(value)) {
|
||||
callback(this.$t('message.error.macaddress'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
validatorIpAddress (rule, value, callback) {
|
||||
if (!value || value === '') {
|
||||
callback()
|
||||
} else if (!this.ipV4Regex.test(value)) {
|
||||
callback(this.$t('message.error.ipv4.address'))
|
||||
} else if (rule.networkType !== 'L2' && !this.isIp4InCidr(value, rule.cidr)) {
|
||||
const rangeIps = this.calculateCidrRange(rule.cidr)
|
||||
const message = `${this.$t('message.error.ip.range')} ${this.$t('label.from')} ${rangeIps[0]} ${this.$t('label.to')} ${rangeIps[1]}`
|
||||
callback(message)
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
},
|
||||
getIpRangeDescription (network) {
|
||||
const rangeIps = this.calculateCidrRange(network.cidr)
|
||||
const rangeIpDescription = [`${this.$t('label.ip.range')}:`, rangeIps[0], '-', rangeIps[1]].join(' ')
|
||||
return rangeIpDescription
|
||||
},
|
||||
isIp4InCidr (ip, cidr) {
|
||||
const [range, bits = 32] = cidr.split('/')
|
||||
const mask = ~(2 ** (32 - bits) - 1)
|
||||
return (this.ip4ToInt(ip) & mask) === (this.ip4ToInt(range) & mask)
|
||||
},
|
||||
calculateCidrRange (cidr) {
|
||||
const [range, bits = 32] = cidr.split('/')
|
||||
const mask = ~(2 ** (32 - bits) - 1)
|
||||
return [this.intToIp4(this.ip4ToInt(range) & mask), this.intToIp4(this.ip4ToInt(range) | ~mask)]
|
||||
},
|
||||
ip4ToInt (ip) {
|
||||
return ip.split('.').reduce((int, oct) => (int << 8) + parseInt(oct, 10), 0) >>> 0
|
||||
},
|
||||
intToIp4 (int) {
|
||||
return [(int >>> 24) & 0xFF, (int >>> 16) & 0xFF, (int >>> 8) & 0xFF, int & 0xFF].join('.')
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -159,4 +233,13 @@ export default {
|
||||
.ant-table-wrapper {
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
/deep/.ant-table-tbody > tr td:not(:first-child) {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
.ant-form .ant-form-item {
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -237,7 +237,7 @@ export default {
|
||||
inject: ['vmFetchNetworks'],
|
||||
methods: {
|
||||
getDetails (network) {
|
||||
return [
|
||||
const detail = [
|
||||
{
|
||||
title: this.$t('label.description'),
|
||||
description: network.displaytext
|
||||
@ -247,6 +247,13 @@ export default {
|
||||
description: network.networkofferingdisplaytext
|
||||
}
|
||||
]
|
||||
if (network.type !== 'L2') {
|
||||
detail.push({
|
||||
title: this.$t('label.cidr'),
|
||||
description: network.cidr
|
||||
})
|
||||
}
|
||||
return detail
|
||||
},
|
||||
handleSearch (value) {
|
||||
this.filter = value
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user