fix(container): binding ip disappear after duplicate container [BE-11413] (#177)

release/2.25
Oscar Zhou 2024-11-29 08:56:44 +13:00 committed by GitHub
parent faa6b2b790
commit 219c9593e0
1 changed files with 45 additions and 32 deletions

View File

@ -14,13 +14,8 @@ type StringPortBinding = {
containerPort: number; containerPort: number;
}; };
type NumericPortBinding = {
hostPort: number;
protocol: Protocol;
containerPort: number;
};
type RangePortBinding = { type RangePortBinding = {
hostIp: string;
hostPort: Range; hostPort: Range;
protocol: Protocol; protocol: Protocol;
containerPort: Range; containerPort: Range;
@ -42,9 +37,7 @@ export function toViewModel(portBindings: PortMap): Values {
return value === 'tcp' || value === 'udp'; return value === 'tcp' || value === 'udp';
} }
function parsePorts( function parsePorts(portBindings: PortMap): Array<StringPortBinding> {
portBindings: PortMap
): Array<StringPortBinding | NumericPortBinding> {
return Object.entries(portBindings).flatMap(([key, bindings]) => { return Object.entries(portBindings).flatMap(([key, bindings]) => {
const [containerPort, protocol] = key.split('/'); const [containerPort, protocol] = key.split('/');
@ -63,15 +56,24 @@ export function toViewModel(portBindings: PortMap): Values {
} }
return bindings.map((binding) => { return bindings.map((binding) => {
let port = '';
if (binding.HostPort) {
port = binding.HostPort;
}
if (binding.HostIp) {
port = `${binding.HostIp}:${port}`;
}
if (binding.HostPort?.includes('-')) { if (binding.HostPort?.includes('-')) {
// Range port
return { return {
hostPort: binding.HostPort, hostPort: port,
protocol, protocol,
containerPort: containerPortNumber, containerPort: containerPortNumber,
}; };
} }
return { return {
hostPort: parseInt(binding.HostPort || '0', 10), hostPort: port,
protocol, protocol,
containerPort: containerPortNumber, containerPort: containerPortNumber,
}; };
@ -79,9 +81,9 @@ export function toViewModel(portBindings: PortMap): Values {
}); });
} }
function sortPorts(ports: Array<StringPortBinding | NumericPortBinding>) { function sortPorts(ports: Array<StringPortBinding>) {
const rangePorts = ports.filter(isStringPortBinding); const rangePorts = ports.filter(isRangePortBinding);
const nonRangePorts = ports.filter(isNumericPortBinding); const nonRangePorts = ports.filter((port) => !isRangePortBinding(port));
return { return {
rangePorts, rangePorts,
@ -93,27 +95,40 @@ export function toViewModel(portBindings: PortMap): Values {
}; };
} }
function combinePorts(ports: Array<NumericPortBinding>) { function combinePorts(ports: Array<StringPortBinding>) {
return ports return ports
.reduce((acc, port) => { .reduce((acc, port) => {
let hostIp = '';
let hostPort = 0;
if (port.hostPort.includes(':')) {
const [ipStr, portStr] = port.hostPort.split(':');
hostIp = ipStr;
hostPort = parseInt(portStr || '0', 10);
} else {
hostPort = parseInt(port.hostPort || '0', 10);
}
const lastPort = acc[acc.length - 1]; const lastPort = acc[acc.length - 1];
if ( if (
lastPort && lastPort &&
lastPort.hostIp === hostIp &&
lastPort.containerPort.end === port.containerPort - 1 && lastPort.containerPort.end === port.containerPort - 1 &&
lastPort.hostPort.end === port.hostPort - 1 && lastPort.hostPort.end === hostPort - 1 &&
lastPort.protocol === port.protocol lastPort.protocol === port.protocol
) { ) {
lastPort.hostIp = hostIp;
lastPort.containerPort.end = port.containerPort; lastPort.containerPort.end = port.containerPort;
lastPort.hostPort.end = port.hostPort; lastPort.hostPort.end = hostPort;
return acc; return acc;
} }
return [ return [
...acc, ...acc,
{ {
hostIp,
hostPort: { hostPort: {
start: port.hostPort, start: hostPort,
end: port.hostPort, end: hostPort,
}, },
containerPort: { containerPort: {
start: port.containerPort, start: port.containerPort,
@ -123,34 +138,32 @@ export function toViewModel(portBindings: PortMap): Values {
}, },
]; ];
}, [] as Array<RangePortBinding>) }, [] as Array<RangePortBinding>)
.map(({ protocol, containerPort, hostPort }) => ({ .map(({ protocol, containerPort, hostPort, hostIp }) => ({
hostPort: getRange(hostPort.start, hostPort.end), hostPort: getRange(hostPort.start, hostPort.end, hostIp),
containerPort: getRange(containerPort.start, containerPort.end), containerPort: getRange(containerPort.start, containerPort.end),
protocol, protocol,
})); }));
function getRange(start: number, end: number): string { function getRange(start: number, end: number, hostIp?: string): string {
if (start === end) { if (start === end) {
if (start === 0) { if (start === 0) {
return ''; return '';
} }
if (hostIp) {
return `${hostIp}:${start}`;
}
return start.toString(); return start.toString();
} }
if (hostIp) {
return `${hostIp}:${start}-${end}`;
}
return `${start}-${end}`; return `${start}-${end}`;
} }
} }
} }
function isNumericPortBinding( function isRangePortBinding(port: StringPortBinding): boolean {
port: StringPortBinding | NumericPortBinding return port.hostPort.includes('-');
): port is NumericPortBinding {
return port.hostPort !== 'string';
}
function isStringPortBinding(
port: StringPortBinding | NumericPortBinding
): port is StringPortBinding {
return port.hostPort === 'string';
} }