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