Repository: cdk8s-team/cdk8s-plus
Pull request #3988 (2024-04-07 09:03:08)

fix(container): allow the same port number with different protocols (#3508)
# Backport

This will backport the following commits from `k8s-28/main` to `k8s-26/main`:
 - [fix(container): allow the same port number with different protocols (#3508)](https://github.com/cdk8s-team/cdk8s-plus/pull/3508)

<!--- Backport version: 8.5.0 -->

### Questions ?
Please refer to the [Backport tool documentation](https://github.com/sqren/backport)


Patch:
diff --git a/src/container.ts b/src/container.ts
index 3357c648..28048a6e 100644
--- a/src/container.ts
+++ b/src/container.ts
@@ -820,14 +820,15 @@ export class Container {
   public addPort(port: ContainerPort) {
 
     const names = this._ports.map(p => p.name).filter(x => x);
-    const numbers = this._ports.map(p => p.number);
+    const numberProtocols = this._ports.map(p => `${p.number}/${p.protocol || Protocol.TCP}`);
 
     if (port.name && names.includes(port.name)) {
       throw new Error(`Port with name ${port.name} already exists`);
     }
 
-    if (numbers.includes(port.number)) {
-      throw new Error(`Port with number ${port.number} already exists`);
+    const protocol = `${port.number}/${port.protocol || Protocol.TCP}`;
+    if (numberProtocols.includes(protocol)) {
+      throw new Error(`Port with number ${port.number} and protocol ${port.protocol || Protocol.TCP} already exists`);
     }
 
     this._ports.push(port);


Test patch:
diff --git a/test/container.test.ts b/test/container.test.ts
index 331b6fd5..eccb9ba7 100644
--- a/test/container.test.ts
+++ b/test/container.test.ts
@@ -180,23 +180,56 @@ describe('EnvValue', () => {
 
 describe('Container', () => {
 
-  test('cannot configure identical ports at instantiation', () => {
+  test('cannot configure identical ports and protocols at instantiation', () => {
 
     expect(() => new kplus.Container({
       image: 'image',
       ports: [
         {
           number: 8080,
+          protocol: kplus.Protocol.TCP,
         },
         {
           number: 8080,
+          protocol: kplus.Protocol.TCP,
         },
       ],
-    })).toThrowError('Port with number 8080 already exists');
+    })).toThrowError('Port with number 8080 and protocol TCP already exists');
 
   });
 
-  test('cannot add an already existing port number', () => {
+  test('can configure identical ports with different protocols at instantiation', () => {
+    const container = new kplus.Container({
+      image: 'image',
+      ports: [
+        {
+          number: 8080,
+          protocol: kplus.Protocol.TCP,
+        },
+        {
+          number: 8080,
+          protocol: kplus.Protocol.UDP,
+        },
+      ],
+    });
+
+    expect(container._toKube().ports).toEqual([{
+      containerPort: 8080,
+      protocol: 'TCP',
+    }, {
+      containerPort: 8080,
+      protocol: 'UDP',
+    }]);
+    expect(container.ports).toEqual([{
+      number: 8080,
+      protocol: kplus.Protocol.TCP,
+    }, {
+      number: 8080,
+      protocol: kplus.Protocol.UDP,
+    }]);
+  });
+
+  test('cannot add an already existing port number with identical protocol', () => {
 
     const container = new kplus.Container({
       image: 'image',
@@ -205,8 +238,38 @@ describe('Container', () => {
       }],
     });
 
-    expect(() => container.addPort({ number: 8080 })).toThrowError('Port with number 8080 already exists');
+    expect(() => container.addPort({ number: 8080 })).toThrowError('Port with number 8080 and protocol TCP already exists');
+
+  });
+
+  test('can add an already existing port number with a different protocol', () => {
+
+    const container = new kplus.Container({
+      image: 'image',
+      ports: [{
+        number: 8080,
+        protocol: kplus.Protocol.TCP,
+      }],
+    });
+    container.addPort({
+      number: 8080,
+      protocol: kplus.Protocol.UDP,
+    });
 
+    expect(container._toKube().ports).toEqual([{
+      containerPort: 8080,
+      protocol: 'TCP',
+    }, {
+      containerPort: 8080,
+      protocol: 'UDP',
+    }]);
+    expect(container.ports).toEqual([{
+      number: 8080,
+      protocol: kplus.Protocol.TCP,
+    }, {
+      number: 8080,
+      protocol: kplus.Protocol.UDP,
+    }]);
   });
 
   test('cannot add an already existing port name', () => {