Merge "feature: Add allocation pools validate rules"
This commit is contained in:
commit
88ac78a8db
@ -685,6 +685,7 @@
|
||||
"GRE": "GRE",
|
||||
"Gateway IP": "Gateway IP",
|
||||
"Gateway Time-out (code: 504) ": "Gateway Time-out (code: 504) ",
|
||||
"Gateway ip {gateway_ip} conflicts with allocation pool {pool}": "Gateway ip {gateway_ip} conflicts with allocation pool {pool}",
|
||||
"General Computing Type": "General Computing Type",
|
||||
"General Purpose": "General Purpose",
|
||||
"Get OpenRC file": "Get OpenRC file",
|
||||
@ -1090,6 +1091,7 @@
|
||||
"Other Protocol": "Other Protocol",
|
||||
"Others": "Others",
|
||||
"Outputs": "Outputs",
|
||||
"Overlapping allocation pools: {pools}": "Overlapping allocation pools: {pools}",
|
||||
"Owned Network": "Owned Network",
|
||||
"Owned Network ID": "Owned Network ID",
|
||||
"Owned Project": "Owned Project",
|
||||
|
@ -685,6 +685,7 @@
|
||||
"GRE": "",
|
||||
"Gateway IP": "网关IP",
|
||||
"Gateway Time-out (code: 504) ": "网关超时(错误码:504 )",
|
||||
"Gateway ip {gateway_ip} conflicts with allocation pool {pool}": "网关地址 {gateway_ip} 和分配地址池 {pool} 冲突",
|
||||
"General Computing Type": "通用计算型",
|
||||
"General Purpose": "通用型",
|
||||
"Get OpenRC file": "获取Openstack RC 文件",
|
||||
@ -1090,6 +1091,7 @@
|
||||
"Other Protocol": "其他协议",
|
||||
"Others": "其他",
|
||||
"Outputs": "输出",
|
||||
"Overlapping allocation pools: {pools}": "重叠的分配地址池: {pools}",
|
||||
"Owned Network": "所属网络",
|
||||
"Owned Network ID": "所属网络ID",
|
||||
"Owned Project": "所属项目",
|
||||
|
@ -27,8 +27,7 @@ const {
|
||||
physicalNetworkArray,
|
||||
segmentationNetworkArray,
|
||||
segmentationNetworkRequireArray,
|
||||
checkAllocation_pools,
|
||||
checkIpv6Allocation_pools,
|
||||
validateAllocationPoolsWithGatewayIp,
|
||||
checkDNS,
|
||||
checkIpv6DNS,
|
||||
checkHostRoutes,
|
||||
@ -230,6 +229,10 @@ export default class CreateNetwork extends ModalAction {
|
||||
return true;
|
||||
};
|
||||
|
||||
validateAllocationPools = (rule, value) => {
|
||||
return validateAllocationPoolsWithGatewayIp.call(this, rule, value);
|
||||
};
|
||||
|
||||
get formItems() {
|
||||
const {
|
||||
more,
|
||||
@ -482,6 +485,11 @@ export default class CreateNetwork extends ModalAction {
|
||||
name: 'gateway_ip',
|
||||
label: t('Gateway IP'),
|
||||
type: 'ip-input',
|
||||
onChange: (e) => {
|
||||
this.setState({
|
||||
gateway_ip: e.target.value,
|
||||
});
|
||||
},
|
||||
tip: t(
|
||||
'If no gateway is specified, the first IP address will be defaulted.'
|
||||
),
|
||||
@ -491,6 +499,11 @@ export default class CreateNetwork extends ModalAction {
|
||||
name: 'gateway_ip',
|
||||
label: t('Gateway IP'),
|
||||
type: 'input',
|
||||
onChange: (e) => {
|
||||
this.setState({
|
||||
gateway_ip: e.target.value,
|
||||
});
|
||||
},
|
||||
tip: t(
|
||||
'If no gateway is specified, the first IP address will be defaulted.'
|
||||
),
|
||||
@ -532,7 +545,8 @@ export default class CreateNetwork extends ModalAction {
|
||||
ip: isIpv4 ? '192.168.1.2,192.168.1.200' : '1001:1001::,1001:1002::',
|
||||
}),
|
||||
hidden: !(create_subnet && more),
|
||||
validator: isIpv4 ? checkAllocation_pools : checkIpv6Allocation_pools,
|
||||
validator: this.validateAllocationPools,
|
||||
dependencies: ['gateway_ip'],
|
||||
},
|
||||
{
|
||||
name: 'dns',
|
||||
|
@ -23,8 +23,7 @@ import globalRootStore from 'stores/root';
|
||||
import networkUtil from './networkUtil';
|
||||
|
||||
const {
|
||||
checkAllocation_pools,
|
||||
checkIpv6Allocation_pools,
|
||||
validateAllocationPoolsWithGatewayIp,
|
||||
checkDNS,
|
||||
checkIpv6DNS,
|
||||
checkHostRoutes,
|
||||
@ -125,6 +124,10 @@ export default class CreateSubnet extends ModalAction {
|
||||
return checkPolicyRule('skyline:system_admin');
|
||||
}
|
||||
|
||||
validateAllocationPools = (rule, value) => {
|
||||
return validateAllocationPoolsWithGatewayIp.call(this, rule, value);
|
||||
};
|
||||
|
||||
get formItems() {
|
||||
const { more, ip_version = 'ipv4', disable_gateway = false } = this.state;
|
||||
const isIpv4 = ip_version === 'ipv4';
|
||||
@ -230,6 +233,11 @@ export default class CreateSubnet extends ModalAction {
|
||||
name: 'gateway_ip',
|
||||
label: t('Gateway IP'),
|
||||
type: 'ip-input',
|
||||
onChange: (e) => {
|
||||
this.setState({
|
||||
gateway_ip: e.target.value,
|
||||
});
|
||||
},
|
||||
tip: t(
|
||||
'If no gateway is specified, the first IP address will be defaulted.'
|
||||
),
|
||||
@ -239,6 +247,11 @@ export default class CreateSubnet extends ModalAction {
|
||||
name: 'gateway_ip',
|
||||
label: t('Gateway IP'),
|
||||
type: 'input',
|
||||
onChange: (e) => {
|
||||
this.setState({
|
||||
gateway_ip: e.target.value,
|
||||
});
|
||||
},
|
||||
tip: t(
|
||||
'If no gateway is specified, the first IP address will be defaulted.'
|
||||
),
|
||||
@ -275,7 +288,7 @@ export default class CreateSubnet extends ModalAction {
|
||||
ip: isIpv4 ? '192.168.1.2,192.168.1.200' : '1001:1001::,1001:1002::',
|
||||
}),
|
||||
hidden: !more,
|
||||
validator: isIpv4 ? checkAllocation_pools : checkIpv6Allocation_pools,
|
||||
validator: this.validateAllocationPools,
|
||||
},
|
||||
{
|
||||
name: 'dns',
|
||||
|
@ -12,8 +12,9 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import _, { isString } from 'lodash';
|
||||
import { isString } from 'lodash';
|
||||
import { ipValidate } from 'utils/validate';
|
||||
import { Address4, Address6 } from 'ip-address';
|
||||
|
||||
const { ipFull, isIpCidr, isIPv6Cidr, isIPv4, isIpv6, compareIpv6 } =
|
||||
ipValidate;
|
||||
@ -25,7 +26,7 @@ const segmentationNetworkArray = ['vxlan', 'vlan', 'gre'];
|
||||
const segmentationNetworkRequireArray = ['vlan', 'gre'];
|
||||
|
||||
const checkAllocation_pools = (rule, value) => {
|
||||
if (value && _.isString(value)) {
|
||||
if (value && isString(value)) {
|
||||
const lines = value.trim().split(/\s*[\r\n]+\s*/g);
|
||||
const flag = !lines.some(hasError);
|
||||
return flag
|
||||
@ -53,7 +54,7 @@ const checkAllocation_pools = (rule, value) => {
|
||||
};
|
||||
|
||||
const checkIpv6Allocation_pools = (rule, value) => {
|
||||
if (value && _.isString(value)) {
|
||||
if (value && isString(value)) {
|
||||
const lines = value.trim().split(/\s*[\r\n]+\s*/g);
|
||||
const flag = !lines.some(hasError);
|
||||
return flag
|
||||
@ -81,8 +82,112 @@ const checkIpv6Allocation_pools = (rule, value) => {
|
||||
}
|
||||
};
|
||||
|
||||
function validateAllocationPoolsWithGatewayIp(rule, value) {
|
||||
const { ip_version = 'ipv4', gateway_ip } = this.state;
|
||||
const isIpv4 = ip_version === 'ipv4';
|
||||
const IPAddressConstructor = isIpv4 ? Address4 : Address6;
|
||||
let translateIPSuccess = true;
|
||||
|
||||
if (value && isString(value)) {
|
||||
const lines = value.trim().split(/\s*[\r\n]+\s*/g);
|
||||
const sortedLines = Array.from(lines).sort((a, b) => {
|
||||
try {
|
||||
const ip1 = new IPAddressConstructor(a.split(',')[0]);
|
||||
const ip2 = new IPAddressConstructor(b.split(',')[0]);
|
||||
return ip1.bigInteger().compareTo(ip2.bigInteger());
|
||||
} catch (e) {
|
||||
translateIPSuccess = false;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
if (sortedLines.length > 0 && translateIPSuccess) {
|
||||
if (gateway_ip) {
|
||||
// check if gateway ip is include
|
||||
let conflictPool;
|
||||
let isGatewayIPIn;
|
||||
try {
|
||||
const gatewayIP = new IPAddressConstructor(gateway_ip);
|
||||
conflictPool = '';
|
||||
isGatewayIPIn = sortedLines.some((l) => {
|
||||
const ipStart = new IPAddressConstructor(l.split(',')[0]);
|
||||
const ipEnd = new IPAddressConstructor(l.split(',')[1]);
|
||||
if (
|
||||
gatewayIP.bigInteger().compareTo(ipStart.bigInteger()) >= 0 &&
|
||||
ipEnd.bigInteger().compareTo(gatewayIP.bigInteger()) >= 0
|
||||
) {
|
||||
isGatewayIPIn = true;
|
||||
conflictPool = l;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
} catch (e) {
|
||||
translateIPSuccess = false;
|
||||
}
|
||||
|
||||
if (isGatewayIPIn && translateIPSuccess) {
|
||||
return Promise.reject(
|
||||
new Error(
|
||||
t(
|
||||
'Gateway ip {gateway_ip} conflicts with allocation pool {pool}',
|
||||
{
|
||||
gateway_ip,
|
||||
pool: conflictPool.replace(',', '-'),
|
||||
}
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
// check if gateway ip is include
|
||||
}
|
||||
|
||||
// check if is overlapping
|
||||
let errorIdxStart = 0;
|
||||
|
||||
const isOverlapping = sortedLines.some((i, idx) => {
|
||||
if (idx < sortedLines.length - 1) {
|
||||
try {
|
||||
const ipBefore = new IPAddressConstructor(i.split(',')[1]);
|
||||
const ipAfter = new IPAddressConstructor(
|
||||
sortedLines[idx + 1].split(',')[0]
|
||||
);
|
||||
const f = ipAfter.bigInteger().compareTo(ipBefore.bigInteger());
|
||||
if (f > 0) {
|
||||
errorIdxStart = idx;
|
||||
}
|
||||
return f < 0;
|
||||
} catch (e) {
|
||||
translateIPSuccess = false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (isOverlapping && translateIPSuccess) {
|
||||
const pools = `${sortedLines[errorIdxStart].replace(
|
||||
',',
|
||||
'-'
|
||||
)}, ${sortedLines[errorIdxStart + 1].replace(',', '-')}`;
|
||||
return Promise.reject(
|
||||
new Error(
|
||||
t('Overlapping allocation pools: {pools}', {
|
||||
pools,
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
// check if is overlapping
|
||||
}
|
||||
}
|
||||
|
||||
return isIpv4
|
||||
? checkAllocation_pools(rule, value)
|
||||
: checkIpv6Allocation_pools(rule, value);
|
||||
}
|
||||
|
||||
const checkDNS = (rule, value) => {
|
||||
if (value && _.isString(value)) {
|
||||
if (value && isString(value)) {
|
||||
const lines = value.trim().split(/\s*[\r\n]+\s*/g);
|
||||
const flag = !lines.some(hasError);
|
||||
return flag
|
||||
@ -98,7 +203,7 @@ const checkDNS = (rule, value) => {
|
||||
};
|
||||
|
||||
const checkIpv6DNS = (rule, value) => {
|
||||
if (value && _.isString(value)) {
|
||||
if (value && isString(value)) {
|
||||
const lines = value.trim().split(/\s*[\r\n]+\s*/g);
|
||||
const flag = !lines.some(hasError);
|
||||
return flag
|
||||
@ -114,7 +219,7 @@ const checkIpv6DNS = (rule, value) => {
|
||||
};
|
||||
|
||||
const checkHostRoutes = (rule, value) => {
|
||||
if (value && _.isString(value)) {
|
||||
if (value && isString(value)) {
|
||||
const lines = value.trim().split(/\s*[\r\n]+\s*/g);
|
||||
const flag = !lines.some(hasError);
|
||||
return flag
|
||||
@ -133,7 +238,7 @@ const checkHostRoutes = (rule, value) => {
|
||||
};
|
||||
|
||||
const checkIpv6HostRoutes = (rule, value) => {
|
||||
if (value && _.isString(value)) {
|
||||
if (value && isString(value)) {
|
||||
const lines = value.trim().split(/\s*[\r\n]+\s*/g);
|
||||
const flag = !lines.some(hasError);
|
||||
return flag
|
||||
@ -153,7 +258,7 @@ const checkIpv6HostRoutes = (rule, value) => {
|
||||
|
||||
const getAllocationPools = (allocation_pools) => {
|
||||
const allocationPools = [];
|
||||
if (allocation_pools && _.isString(allocation_pools)) {
|
||||
if (allocation_pools && isString(allocation_pools)) {
|
||||
const lines = allocation_pools.trim().split(/\s*[\r\n]+\s*/g);
|
||||
lines.forEach((item) => {
|
||||
const [start, end] = item.split(',');
|
||||
@ -168,7 +273,7 @@ const getAllocationPools = (allocation_pools) => {
|
||||
|
||||
const getHostRouters = (host_routes) => {
|
||||
const hostRouters = [];
|
||||
if (host_routes && _.isString(host_routes)) {
|
||||
if (host_routes && isString(host_routes)) {
|
||||
const lines = host_routes.trim().split(/\s*[\r\n]+\s*/g);
|
||||
lines.forEach((item) => {
|
||||
const [destination, nexthop] = item.split(',');
|
||||
@ -217,6 +322,7 @@ export default {
|
||||
physicalNetworkArray,
|
||||
segmentationNetworkArray,
|
||||
segmentationNetworkRequireArray,
|
||||
validateAllocationPoolsWithGatewayIp,
|
||||
checkAllocation_pools,
|
||||
checkIpv6Allocation_pools,
|
||||
checkDNS,
|
||||
|
Loading…
Reference in New Issue
Block a user