diff --git a/lib/resourcemerge/core.go b/lib/resourcemerge/core.go index bd14942b9..155351930 100644 --- a/lib/resourcemerge/core.go +++ b/lib/resourcemerge/core.go @@ -104,23 +104,7 @@ func ensureContainer(modified *bool, existing *corev1.Container, required corev1 ensureEnvFromSource(modified, &existing.EnvFrom, required.EnvFrom) setStringIfSet(modified, &existing.WorkingDir, required.WorkingDir) ensureResourceRequirements(modified, &existing.Resources, required.Resources) - - // any port we specify, we require - for _, required := range required.Ports { - var existingCurr *corev1.ContainerPort - for j, curr := range existing.Ports { - if curr.Name == required.Name { - existingCurr = &existing.Ports[j] - break - } - } - if existingCurr == nil { - *modified = true - existing.Ports = append(existing.Ports, corev1.ContainerPort{}) - existingCurr = &existing.Ports[len(existing.Ports)-1] - } - ensureContainerPort(modified, existingCurr, required) - } + ensureContainerPorts(modified, &existing.Ports, required.Ports) // any volume mount we specify, we require for _, required := range required.VolumeMounts { @@ -191,6 +175,37 @@ func ensureProbeHandler(modified *bool, existing *corev1.Handler, required corev } } +func ensureContainerPorts(modified *bool, existing *[]corev1.ContainerPort, required []corev1.ContainerPort) { + for i := len(*existing) - 1; i >= 0; i-- { + existingContainerPort := &(*existing)[i] + var existingCurr *corev1.ContainerPort + for _, requiredContainerPort := range required { + if existingContainerPort.Name == requiredContainerPort.Name { + existingCurr = &(*existing)[i] + ensureContainerPort(modified, existingCurr, requiredContainerPort) + break + } + } + if existingCurr == nil { + *modified = true + *existing = append((*existing)[:i], (*existing)[i+1:]...) + } + } + for _, requiredContainerPort := range required { + match := false + for _, existingContainerPort := range *existing { + if existingContainerPort.Name == requiredContainerPort.Name { + match = true + break + } + } + if !match { + *modified = true + *existing = append(*existing, requiredContainerPort) + } + } +} + func ensureContainerPort(modified *bool, existing *corev1.ContainerPort, required corev1.ContainerPort) { if !equality.Semantic.DeepEqual(required, *existing) { *modified = true diff --git a/lib/resourcemerge/core_test.go b/lib/resourcemerge/core_test.go index 1afc22c64..d9cac7a2d 100644 --- a/lib/resourcemerge/core_test.go +++ b/lib/resourcemerge/core_test.go @@ -1,9 +1,10 @@ package resourcemerge import ( - "k8s.io/apimachinery/pkg/util/intstr" "testing" + "k8s.io/apimachinery/pkg/util/intstr" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/resource" @@ -268,6 +269,96 @@ func TestEnsurePodSpec(t *testing.T) { }, }, }, + { + name: "add ports on container", + existing: corev1.PodSpec{ + Containers: []corev1.Container{ + corev1.Container{Name: "test"}, + }, + }, + input: corev1.PodSpec{ + Containers: []corev1.Container{ + corev1.Container{ + Name: "test", + Ports: []corev1.ContainerPort{ + corev1.ContainerPort{ContainerPort: 8080}, + }, + }, + }, + }, + expectedModified: true, + expected: corev1.PodSpec{ + Containers: []corev1.Container{ + corev1.Container{ + Name: "test", + Ports: []corev1.ContainerPort{ + corev1.ContainerPort{ContainerPort: 8080}, + }, + }, + }, + }, + }, + { + name: "replace ports on container", + existing: corev1.PodSpec{ + Containers: []corev1.Container{ + corev1.Container{ + Name: "test", + Ports: []corev1.ContainerPort{ + corev1.ContainerPort{ContainerPort: 8080}, + }, + }, + }, + }, + input: corev1.PodSpec{ + Containers: []corev1.Container{ + corev1.Container{ + Name: "test", + Ports: []corev1.ContainerPort{ + corev1.ContainerPort{ContainerPort: 9191}, + }, + }, + }, + }, + expectedModified: true, + expected: corev1.PodSpec{ + Containers: []corev1.Container{ + corev1.Container{ + Name: "test", + Ports: []corev1.ContainerPort{ + corev1.ContainerPort{ContainerPort: 9191}, + }, + }, + }, + }, + }, + { + name: "remove container ports", + existing: corev1.PodSpec{ + Containers: []corev1.Container{ + corev1.Container{ + Name: "test", + Ports: []corev1.ContainerPort{ + corev1.ContainerPort{ContainerPort: 8080}, + }, + }, + }, + }, + input: corev1.PodSpec{ + Containers: []corev1.Container{ + corev1.Container{Name: "test"}, + }, + }, + expectedModified: true, + expected: corev1.PodSpec{ + Containers: []corev1.Container{ + corev1.Container{ + Name: "test", + Ports: []corev1.ContainerPort{}, + }, + }, + }, + }, } for _, test := range tests { @@ -295,11 +386,11 @@ func TestEnsureServicePorts(t *testing.T) { expected corev1.Service }{ { - name: "empty inputs", - existing: corev1.Service{}, - input: corev1.Service{}, + name: "empty inputs", + existing: corev1.Service{}, + input: corev1.Service{}, expectedModified: false, - expected: corev1.Service{}, + expected: corev1.Service{}, }, { name: "add port (no name)", @@ -311,7 +402,7 @@ func TestEnsureServicePorts(t *testing.T) { Ports: []corev1.ServicePort{ { Protocol: corev1.ProtocolUDP, - Port: 8282, + Port: 8282, }, }, }, @@ -322,7 +413,7 @@ func TestEnsureServicePorts(t *testing.T) { Ports: []corev1.ServicePort{ { Protocol: corev1.ProtocolUDP, - Port: 8282, + Port: 8282, }, }, }, @@ -337,9 +428,9 @@ func TestEnsureServicePorts(t *testing.T) { Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: "foo", + Name: "foo", Protocol: corev1.ProtocolUDP, - Port: 8282, + Port: 8282, }, }, }, @@ -349,9 +440,9 @@ func TestEnsureServicePorts(t *testing.T) { Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: "foo", + Name: "foo", Protocol: corev1.ProtocolUDP, - Port: 8282, + Port: 8282, }, }, }, @@ -402,9 +493,9 @@ func TestEnsureServicePorts(t *testing.T) { Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: "test", + Name: "test", Protocol: corev1.ProtocolUDP, - Port: 8080, + Port: 8080, }, }, }, @@ -413,9 +504,9 @@ func TestEnsureServicePorts(t *testing.T) { Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: "test", + Name: "test", Protocol: corev1.ProtocolUDP, - Port: 8282, + Port: 8282, }, }, }, @@ -425,9 +516,9 @@ func TestEnsureServicePorts(t *testing.T) { Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: "test", + Name: "test", Protocol: corev1.ProtocolUDP, - Port: 8282, + Port: 8282, }, }, }, @@ -449,7 +540,7 @@ func TestEnsureServicePorts(t *testing.T) { Ports: []corev1.ServicePort{ { Protocol: corev1.ProtocolUDP, - Port: 8282, + Port: 8282, }, }, }, @@ -460,7 +551,7 @@ func TestEnsureServicePorts(t *testing.T) { Ports: []corev1.ServicePort{ { Protocol: corev1.ProtocolUDP, - Port: 8282, + Port: 8282, }, }, }, @@ -486,14 +577,14 @@ func TestEnsureServicePorts(t *testing.T) { Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: "foo", + Name: "foo", Protocol: corev1.ProtocolUDP, - Port: 8282, + Port: 8282, }, { - Name: "bar", + Name: "bar", Protocol: corev1.ProtocolUDP, - Port: 8283, + Port: 8283, }, }, }, @@ -503,14 +594,14 @@ func TestEnsureServicePorts(t *testing.T) { Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: "foo", + Name: "foo", Protocol: corev1.ProtocolUDP, - Port: 8282, + Port: 8282, }, { - Name: "bar", + Name: "bar", Protocol: corev1.ProtocolUDP, - Port: 8283, + Port: 8283, }, }, }, @@ -522,14 +613,14 @@ func TestEnsureServicePorts(t *testing.T) { Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: "foo", + Name: "foo", Protocol: corev1.ProtocolUDP, - Port: 8080, + Port: 8080, }, { - Name: "bar", + Name: "bar", Protocol: corev1.ProtocolUDP, - Port: 8081, + Port: 8081, }, }, }, @@ -538,14 +629,14 @@ func TestEnsureServicePorts(t *testing.T) { Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: "bar", + Name: "bar", Protocol: corev1.ProtocolUDP, - Port: 8081, + Port: 8081, }, { - Name: "foo", + Name: "foo", Protocol: corev1.ProtocolUDP, - Port: 8080, + Port: 8080, }, }, }, @@ -555,14 +646,14 @@ func TestEnsureServicePorts(t *testing.T) { Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: "foo", + Name: "foo", Protocol: corev1.ProtocolUDP, - Port: 8080, + Port: 8080, }, { - Name: "bar", + Name: "bar", Protocol: corev1.ProtocolUDP, - Port: 8081, + Port: 8081, }, }, }, @@ -574,14 +665,14 @@ func TestEnsureServicePorts(t *testing.T) { Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: "foo", - Port: 8080, + Name: "foo", + Port: 8080, Protocol: corev1.ProtocolTCP, }, { - Name: "bar", + Name: "bar", Protocol: corev1.ProtocolTCP, - Port: 8081, + Port: 8081, }, }, }, @@ -605,14 +696,14 @@ func TestEnsureServicePorts(t *testing.T) { Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: "foo", + Name: "foo", Protocol: corev1.ProtocolTCP, - Port: 8080, + Port: 8080, }, { - Name: "bar", + Name: "bar", Protocol: corev1.ProtocolTCP, - Port: 8081, + Port: 8081, }, }, }, @@ -624,11 +715,11 @@ func TestEnsureServicePorts(t *testing.T) { Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: "foo", - Port: 8080, + Name: "foo", + Port: 8080, TargetPort: intstr.FromInt(8081), - NodePort: 8081, - Protocol: corev1.ProtocolTCP, + NodePort: 8081, + Protocol: corev1.ProtocolTCP, }, }, }, @@ -648,9 +739,9 @@ func TestEnsureServicePorts(t *testing.T) { Spec: corev1.ServiceSpec{ Ports: []corev1.ServicePort{ { - Name: "foo", + Name: "foo", Protocol: corev1.ProtocolTCP, - Port: 8080, + Port: 8080, }, }, },