mirror of https://github.com/portainer/portainer
65 lines
1.7 KiB
TypeScript
65 lines
1.7 KiB
TypeScript
import {
|
|
array,
|
|
lazy,
|
|
mixed,
|
|
number,
|
|
NumberSchema,
|
|
object,
|
|
SchemaOf,
|
|
} from 'yup';
|
|
|
|
import { Range, isRange } from './types';
|
|
|
|
export function validation() {
|
|
return array(
|
|
object({
|
|
hostPort: rangeOrNumber(),
|
|
containerPort: mixed().when('hostPort', {
|
|
is: (hostPort: Range | number | undefined) =>
|
|
!hostPort || isRange(hostPort),
|
|
then: rangeOrNumber(),
|
|
otherwise: port().typeError(
|
|
'Container port must be a number when host port is not a range'
|
|
),
|
|
}),
|
|
protocol: mixed().oneOf(['tcp', 'udp']),
|
|
publishMode: mixed().oneOf(['ingress', 'host']),
|
|
}).test({
|
|
message:
|
|
'Invalid port specification: host port range must be equal to container port range',
|
|
test: (portBinding) => {
|
|
const hostPort = portBinding.hostPort as Range | number | undefined;
|
|
return !(
|
|
isRange(hostPort) &&
|
|
isRange(portBinding.containerPort) &&
|
|
hostPort.end - hostPort.start !==
|
|
portBinding.containerPort.end - portBinding.containerPort.start
|
|
);
|
|
},
|
|
})
|
|
);
|
|
}
|
|
|
|
function port() {
|
|
return number()
|
|
.optional()
|
|
.min(0, 'Port must be a number between 0 to 65535')
|
|
.max(65535, 'Port must be a number between 0 to 65535');
|
|
}
|
|
|
|
function rangeOrNumber() {
|
|
return lazy<SchemaOf<Range> | NumberSchema>(
|
|
(value: Range | number | undefined) => (isRange(value) ? range() : port())
|
|
);
|
|
}
|
|
|
|
function range(): SchemaOf<Range> {
|
|
return object({
|
|
start: port().required(),
|
|
end: port().required(),
|
|
}).test({
|
|
message: 'Start port must be less than end port',
|
|
test: (value) => !value.start || !value.end || value.start <= value.end,
|
|
});
|
|
}
|