From aea94fb59ae138197e4cc0f8189def7512af9e21 Mon Sep 17 00:00:00 2001 From: erabii Date: Mon, 20 Mar 2023 01:56:37 +0200 Subject: [PATCH] Fix 976 (#1265) --- .../discovery/Fabric8ServicePortData.java | 23 +++ .../discovery/KubernetesDiscoveryClient.java | 9 +- .../KubernetesDiscoveryClientUtils.java | 56 +++---- .../discovery/ServicePortSecureResolver.java | 36 ++--- .../KubernetesDiscoveryClientUtilsTests.java | 53 ++++--- .../ServicePortSecureResolverTest.java | 142 ++++++++++++++++-- 6 files changed, 238 insertions(+), 81 deletions(-) create mode 100644 spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/Fabric8ServicePortData.java diff --git a/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/Fabric8ServicePortData.java b/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/Fabric8ServicePortData.java new file mode 100644 index 00000000..3016900f --- /dev/null +++ b/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/Fabric8ServicePortData.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.kubernetes.fabric8.discovery; + +/** + * @author wind57 + */ +record Fabric8ServicePortData(int portNumber, String portName) { +} diff --git a/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClient.java b/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClient.java index 59322600..254a4993 100644 --- a/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClient.java +++ b/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClient.java @@ -120,8 +120,9 @@ public class KubernetesDiscoveryClient implements DiscoveryClient, EnvironmentAw for (Service service : services) { Map serviceMetadata = serviceMetadata(serviceId, service, properties, List.of(), service.getMetadata().getNamespace()); - ServiceInstance externalNameServiceInstance = serviceInstance(null, service, null, -1, serviceId, - serviceMetadata, service.getMetadata().getNamespace(), properties, client); + ServiceInstance externalNameServiceInstance = serviceInstance(null, service, null, + new Fabric8ServicePortData(-1, null), serviceId, serviceMetadata, + service.getMetadata().getNamespace(), properties, client); instances.add(externalNameServiceInstance); } } @@ -148,11 +149,11 @@ public class KubernetesDiscoveryClient implements DiscoveryClient, EnvironmentAw Map serviceMetadata = serviceMetadata(serviceId, service, properties, subsets, namespace); for (EndpointSubset endpointSubset : subsets) { - int endpointPort = endpointsPort(endpointSubset, serviceId, properties, service); + Fabric8ServicePortData portData = endpointsPort(endpointSubset, serviceId, properties, service); List addresses = addresses(endpointSubset, properties); for (EndpointAddress endpointAddress : addresses) { ServiceInstance serviceInstance = serviceInstance(servicePortSecureResolver, service, endpointAddress, - endpointPort, serviceId, serviceMetadata, namespace, properties, client); + portData, serviceId, serviceMetadata, namespace, properties, client); instances.add(serviceInstance); } } diff --git a/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClientUtils.java b/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClientUtils.java index 5eadf0b0..71a24daa 100644 --- a/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClientUtils.java +++ b/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClientUtils.java @@ -59,6 +59,7 @@ import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesD import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryConstants.NAMESPACE_METADATA_KEY; import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryConstants.PRIMARY_PORT_NAME_LABEL_KEY; import static org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryConstants.SERVICE_TYPE; +import static org.springframework.cloud.kubernetes.fabric8.discovery.ServicePortSecureResolver.Input; /** * @author wind57 @@ -75,49 +76,50 @@ final class KubernetesDiscoveryClientUtils { return new EndpointSubsetNS(endpoints.getMetadata().getNamespace(), endpoints.getSubsets()); } - static int endpointsPort(EndpointSubset endpointSubset, String serviceId, KubernetesDiscoveryProperties properties, - Service service) { + static Fabric8ServicePortData endpointsPort(EndpointSubset endpointSubset, String serviceId, + KubernetesDiscoveryProperties properties, Service service) { List endpointPorts = endpointSubset.getPorts(); if (endpointPorts.size() == 0) { LOG.debug(() -> "no ports found for service : " + serviceId + ", will return zero"); - return 0; + return new Fabric8ServicePortData(0, "http"); } if (endpointPorts.size() == 1) { - int port = endpointPorts.get(0).getPort(); + EndpointPort single = endpointPorts.get(0); + int port = single.getPort(); LOG.debug(() -> "endpoint ports has a single entry, using port : " + port); - return port; + return new Fabric8ServicePortData(single.getPort(), single.getName()); } else { - Optional port; + Optional portData; String primaryPortName = primaryPortName(properties, service, serviceId); Map existingPorts = endpointPorts.stream() .filter(endpointPort -> StringUtils.hasText(endpointPort.getName())) .collect(Collectors.toMap(EndpointPort::getName, EndpointPort::getPort)); - port = fromMap(existingPorts, primaryPortName, "found primary-port-name (with value: '" + primaryPortName - + "') via properties or service labels to match port"); - if (port.isPresent()) { - return port.get(); + portData = fromMap(existingPorts, primaryPortName, "found primary-port-name (with value: '" + + primaryPortName + "') via properties or service labels to match port"); + if (portData.isPresent()) { + return portData.get(); } - port = fromMap(existingPorts, HTTPS, "found primary-port-name via 'https' to match port"); - if (port.isPresent()) { - return port.get(); + portData = fromMap(existingPorts, HTTPS, "found primary-port-name via 'https' to match port"); + if (portData.isPresent()) { + return portData.get(); } - port = fromMap(existingPorts, HTTP, "found primary-port-name via 'http' to match port"); - if (port.isPresent()) { - return port.get(); + portData = fromMap(existingPorts, HTTP, "found primary-port-name via 'http' to match port"); + if (portData.isPresent()) { + return portData.get(); } logWarnings(); - return endpointPorts.get(0).getPort(); + return new Fabric8ServicePortData(endpointPorts.get(0).getPort(), endpointPorts.get(0).getName()); } } @@ -244,9 +246,9 @@ final class KubernetesDiscoveryClientUtils { } static ServiceInstance serviceInstance(@Nullable ServicePortSecureResolver servicePortSecureResolver, - Service service, @Nullable EndpointAddress endpointAddress, int endpointPort, String serviceId, - Map serviceMetadata, String namespace, KubernetesDiscoveryProperties properties, - KubernetesClient client) { + Service service, @Nullable EndpointAddress endpointAddress, Fabric8ServicePortData portData, + String serviceId, Map serviceMetadata, String namespace, + KubernetesDiscoveryProperties properties, KubernetesClient client) { // instanceId is usually the pod-uid as seen in the .metadata.uid String instanceId = Optional.ofNullable(endpointAddress).map(EndpointAddress::getTargetRef) .map(ObjectReference::getUid).orElseGet(() -> service.getMetadata().getUid()); @@ -256,9 +258,8 @@ final class KubernetesDiscoveryClientUtils { secured = false; } else { - secured = servicePortSecureResolver - .resolve(new ServicePortSecureResolver.Input(endpointPort, service.getMetadata().getName(), - service.getMetadata().getLabels(), service.getMetadata().getAnnotations())); + secured = servicePortSecureResolver.resolve(new Input(portData, service.getMetadata().getName(), + service.getMetadata().getLabels(), service.getMetadata().getAnnotations())); } String host = Optional.ofNullable(endpointAddress).map(EndpointAddress::getIp) @@ -267,8 +268,8 @@ final class KubernetesDiscoveryClientUtils { Map> podMetadata = podMetadata(client, serviceMetadata, properties, endpointAddress, namespace); - return new DefaultKubernetesServiceInstance(instanceId, serviceId, host, endpointPort, serviceMetadata, secured, - namespace, null, podMetadata); + return new DefaultKubernetesServiceInstance(instanceId, serviceId, host, portData.portNumber(), serviceMetadata, + secured, namespace, null, podMetadata); } static List services(KubernetesDiscoveryProperties properties, KubernetesClient client, @@ -350,7 +351,8 @@ final class KubernetesDiscoveryClientUtils { } - private static Optional fromMap(Map existingPorts, String key, String message) { + private static Optional fromMap(Map existingPorts, String key, + String message) { Integer fromPrimaryPortName = existingPorts.get(key); if (fromPrimaryPortName == null) { LOG.debug(() -> "not " + message); @@ -358,7 +360,7 @@ final class KubernetesDiscoveryClientUtils { } else { LOG.debug(() -> message + " : " + fromPrimaryPortName); - return Optional.of(fromPrimaryPortName); + return Optional.of(new Fabric8ServicePortData(fromPrimaryPortName, key)); } } diff --git a/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/ServicePortSecureResolver.java b/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/ServicePortSecureResolver.java index b775cc1c..941fcf61 100644 --- a/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/ServicePortSecureResolver.java +++ b/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/ServicePortSecureResolver.java @@ -17,6 +17,7 @@ package org.springframework.cloud.kubernetes.fabric8.discovery; import java.util.Map; +import java.util.Optional; import java.util.Set; import org.apache.commons.logging.LogFactory; @@ -49,23 +50,29 @@ class ServicePortSecureResolver { */ boolean resolve(Input input) { - String securedLabelValue = input.serviceLabels().getOrDefault("secured", "false"); String serviceName = input.serviceName(); - Integer port = input.port(); + Fabric8ServicePortData portData = input.portData(); - if (TRUTHY_STRINGS.contains(securedLabelValue)) { - logEntry(serviceName, port, "the service contains a true value for the 'secured' label"); + Optional securedLabelValue = Optional.ofNullable(input.serviceLabels().get("secured")); + if (securedLabelValue.isPresent() && TRUTHY_STRINGS.contains(securedLabelValue.get())) { + logEntry(serviceName, portData.portNumber(), "the service contains a true value for the 'secured' label"); return true; } - String securedAnnotationValue = input.serviceAnnotations().getOrDefault("secured", "false"); - if (TRUTHY_STRINGS.contains(securedAnnotationValue)) { - logEntry(serviceName, port, "the service contains a true value for the 'secured' annotation"); + Optional securedAnnotationValue = Optional.ofNullable(input.serviceAnnotations().get("secured")); + if (securedAnnotationValue.isPresent() && TRUTHY_STRINGS.contains(securedAnnotationValue.get())) { + logEntry(serviceName, portData.portNumber(), + "the service contains a true value for the 'secured' annotation"); return true; } - if (port != null && properties.knownSecurePorts().contains(port)) { - logEntry(serviceName, port, "port is known to be a https port"); + if (properties.knownSecurePorts().contains(portData.portNumber())) { + logEntry(serviceName, portData.portNumber(), "port is known to be a https port"); + return true; + } + + if ("https".equalsIgnoreCase(input.portData().portName())) { + logEntry(serviceName, portData.portNumber(), "port-name is 'https'"); return true; } @@ -80,17 +87,12 @@ class ServicePortSecureResolver { /** * @author wind57 */ - record Input(Integer port, String serviceName, Map serviceLabels, + record Input(Fabric8ServicePortData portData, String serviceName, Map serviceLabels, Map serviceAnnotations) { - // used only for testing - Input(Integer port, String serviceName) { - this(port, serviceName, null, null); - } - - Input(Integer port, String serviceName, Map serviceLabels, + Input(Fabric8ServicePortData portData, String serviceName, Map serviceLabels, Map serviceAnnotations) { - this.port = port; + this.portData = portData; this.serviceName = serviceName; this.serviceLabels = serviceLabels == null ? Map.of() : serviceLabels; this.serviceAnnotations = serviceAnnotations == null ? Map.of() : serviceAnnotations; diff --git a/spring-cloud-kubernetes-fabric8-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClientUtilsTests.java b/spring-cloud-kubernetes-fabric8-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClientUtilsTests.java index ffa67e92..11d85f3d 100644 --- a/spring-cloud-kubernetes-fabric8-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClientUtilsTests.java +++ b/spring-cloud-kubernetes-fabric8-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClientUtilsTests.java @@ -169,8 +169,10 @@ class KubernetesDiscoveryClientUtilsTests { KubernetesDiscoveryProperties properties = KubernetesDiscoveryProperties.DEFAULT; Service service = new ServiceBuilder().build(); - Integer port = KubernetesDiscoveryClientUtils.endpointsPort(endpointSubset, serviceId, properties, service); - Assertions.assertEquals(port, 0); + Fabric8ServicePortData portData = KubernetesDiscoveryClientUtils.endpointsPort(endpointSubset, serviceId, + properties, service); + Assertions.assertEquals(portData.portNumber(), 0); + Assertions.assertEquals(portData.portName(), "http"); Assertions.assertTrue(output.getOut().contains("no ports found for service : spring-k8s, will return zero")); } @@ -182,13 +184,15 @@ class KubernetesDiscoveryClientUtilsTests { @Test void testEndpointsPortSinglePort(CapturedOutput output) { EndpointSubset endpointSubset = new EndpointSubsetBuilder() - .withPorts(new EndpointPortBuilder().withPort(8080).build()).build(); + .withPorts(new EndpointPortBuilder().withPort(8080).withName("http").build()).build(); String serviceId = "spring-k8s"; KubernetesDiscoveryProperties properties = KubernetesDiscoveryProperties.DEFAULT; Service service = new ServiceBuilder().build(); - Integer port = KubernetesDiscoveryClientUtils.endpointsPort(endpointSubset, serviceId, properties, service); - Assertions.assertEquals(port, 8080); + Fabric8ServicePortData portData = KubernetesDiscoveryClientUtils.endpointsPort(endpointSubset, serviceId, + properties, service); + Assertions.assertEquals(portData.portNumber(), 8080); + Assertions.assertEquals(portData.portName(), "http"); Assertions.assertTrue(output.getOut().contains("endpoint ports has a single entry, using port : 8080")); } @@ -207,8 +211,10 @@ class KubernetesDiscoveryClientUtilsTests { KubernetesDiscoveryProperties properties = KubernetesDiscoveryProperties.DEFAULT; Service service = new ServiceBuilder().withMetadata(new ObjectMeta()).build(); - Integer port = KubernetesDiscoveryClientUtils.endpointsPort(endpointSubset, serviceId, properties, service); - Assertions.assertEquals(port, 8080); + Fabric8ServicePortData portData = KubernetesDiscoveryClientUtils.endpointsPort(endpointSubset, serviceId, + properties, service); + Assertions.assertEquals(portData.portNumber(), 8080); + Assertions.assertNull(portData.portName()); Assertions.assertTrue(output.getOut().contains( "did not find a primary-port-name in neither properties nor service labels for service with ID : spring-k8s")); Assertions.assertTrue(output.getOut() @@ -241,8 +247,10 @@ class KubernetesDiscoveryClientUtilsTests { Service service = new ServiceBuilder().withMetadata(new ObjectMeta()).build(); - Integer port = KubernetesDiscoveryClientUtils.endpointsPort(endpointSubset, serviceId, properties, service); - Assertions.assertEquals(port, 8080); + Fabric8ServicePortData portData = KubernetesDiscoveryClientUtils.endpointsPort(endpointSubset, serviceId, + properties, service); + Assertions.assertEquals(portData.portNumber(), 8080); + Assertions.assertEquals(portData.portName(), "one"); Assertions.assertTrue( output.getOut().contains("will use primaryPortName : three for service with ID = spring-k8s")); Assertions.assertTrue(output.getOut() @@ -275,8 +283,10 @@ class KubernetesDiscoveryClientUtilsTests { Service service = new ServiceBuilder().withMetadata(new ObjectMeta()).build(); - Integer port = KubernetesDiscoveryClientUtils.endpointsPort(endpointSubset, serviceId, properties, service); - Assertions.assertEquals(port, 8081); + Fabric8ServicePortData portData = KubernetesDiscoveryClientUtils.endpointsPort(endpointSubset, serviceId, + properties, service); + Assertions.assertEquals(portData.portNumber(), 8081); + Assertions.assertEquals(portData.portName(), "two"); Assertions.assertTrue( output.getOut().contains("will use primaryPortName : two for service with ID = spring-k8s")); Assertions.assertTrue(output.getOut().contains( @@ -304,8 +314,10 @@ class KubernetesDiscoveryClientUtilsTests { Service service = new ServiceBuilder().withMetadata(new ObjectMeta()).build(); - Integer port = KubernetesDiscoveryClientUtils.endpointsPort(endpointSubset, serviceId, properties, service); - Assertions.assertEquals(port, 8082); + Fabric8ServicePortData portData = KubernetesDiscoveryClientUtils.endpointsPort(endpointSubset, serviceId, + properties, service); + Assertions.assertEquals(portData.portNumber(), 8082); + Assertions.assertEquals(portData.portName(), "https"); Assertions.assertTrue( output.getOut().contains("will use primaryPortName : three for service with ID = spring-k8s")); Assertions.assertTrue(output.getOut().contains( @@ -334,8 +346,10 @@ class KubernetesDiscoveryClientUtilsTests { Service service = new ServiceBuilder().withMetadata(new ObjectMeta()).build(); - Integer port = KubernetesDiscoveryClientUtils.endpointsPort(endpointSubset, serviceId, properties, service); - Assertions.assertEquals(port, 8082); + Fabric8ServicePortData portData = KubernetesDiscoveryClientUtils.endpointsPort(endpointSubset, serviceId, + properties, service); + Assertions.assertEquals(portData.portNumber(), 8082); + Assertions.assertEquals(portData.portName(), "http"); Assertions.assertTrue( output.getOut().contains("will use primaryPortName : three for service with ID = spring-k8s")); Assertions.assertTrue(output.getOut().contains( @@ -718,8 +732,9 @@ class KubernetesDiscoveryClientUtilsTests { EndpointAddress address = new EndpointAddressBuilder().withNewTargetRef().withUid("123").endTargetRef() .withIp("127.0.0.1").build(); + Fabric8ServicePortData portData = new Fabric8ServicePortData(8080, "http"); ServiceInstance serviceInstance = KubernetesDiscoveryClientUtils.serviceInstance(resolver, service, address, - 8080, "my-service", Map.of("a", "b"), "k8s", properties, null); + portData, "my-service", Map.of("a", "b"), "k8s", properties, null); Assertions.assertTrue(serviceInstance instanceof DefaultKubernetesServiceInstance); DefaultKubernetesServiceInstance defaultInstance = (DefaultKubernetesServiceInstance) serviceInstance; Assertions.assertEquals(defaultInstance.getInstanceId(), "123"); @@ -740,7 +755,8 @@ class KubernetesDiscoveryClientUtilsTests { .withSpec(new ServiceSpecBuilder().withExternalName("spring.io").withType("ExternalName").build()) .withMetadata(new ObjectMetaBuilder().withUid("123").build()).build(); - ServiceInstance serviceInstance = KubernetesDiscoveryClientUtils.serviceInstance(null, service, null, -1, + Fabric8ServicePortData portData = new Fabric8ServicePortData(-1, "http"); + ServiceInstance serviceInstance = KubernetesDiscoveryClientUtils.serviceInstance(null, service, null, portData, "my-service", Map.of("a", "b"), "k8s", KubernetesDiscoveryProperties.DEFAULT, null); Assertions.assertTrue(serviceInstance instanceof DefaultKubernetesServiceInstance); DefaultKubernetesServiceInstance defaultInstance = (DefaultKubernetesServiceInstance) serviceInstance; @@ -763,8 +779,9 @@ class KubernetesDiscoveryClientUtilsTests { EndpointAddress endpointAddress = new EndpointAddressBuilder().withIp("127.0.0.1").build(); + Fabric8ServicePortData portData = new Fabric8ServicePortData(0, "http"); ServiceInstance serviceInstance = KubernetesDiscoveryClientUtils.serviceInstance(null, service, endpointAddress, - 0, "my-service", Map.of("a", "b"), "k8s", KubernetesDiscoveryProperties.DEFAULT, null); + portData, "my-service", Map.of("a", "b"), "k8s", KubernetesDiscoveryProperties.DEFAULT, null); Assertions.assertTrue(serviceInstance instanceof DefaultKubernetesServiceInstance); DefaultKubernetesServiceInstance defaultInstance = (DefaultKubernetesServiceInstance) serviceInstance; Assertions.assertEquals(defaultInstance.getInstanceId(), "123"); diff --git a/spring-cloud-kubernetes-fabric8-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/discovery/ServicePortSecureResolverTest.java b/spring-cloud-kubernetes-fabric8-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/discovery/ServicePortSecureResolverTest.java index d390195b..64c9a56e 100644 --- a/spring-cloud-kubernetes-fabric8-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/discovery/ServicePortSecureResolverTest.java +++ b/spring-cloud-kubernetes-fabric8-discovery/src/test/java/org/springframework/cloud/kubernetes/fabric8/discovery/ServicePortSecureResolverTest.java @@ -21,11 +21,16 @@ import java.util.Map; import java.util.Set; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.test.system.CapturedOutput; +import org.springframework.boot.test.system.OutputCaptureExtension; import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties; import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.cloud.kubernetes.fabric8.discovery.ServicePortSecureResolver.Input; +@ExtendWith(OutputCaptureExtension.class) class ServicePortSecureResolverTest { private static final Map SECURED_TRUE_MAP = Collections.singletonMap("secured", "true"); @@ -36,17 +41,17 @@ class ServicePortSecureResolverTest { private static final Map SECURED_ON_MAP = Collections.singletonMap("secured", "on"); - private static final ServicePortSecureResolver.Input SECURED_TRUE = new ServicePortSecureResolver.Input(8080, - "dummy", SECURED_TRUE_MAP, Collections.emptyMap()); + private static final ServicePortSecureResolver.Input SECURED_TRUE = new ServicePortSecureResolver.Input( + new Fabric8ServicePortData(8080, "http"), "dummy", SECURED_TRUE_MAP, Collections.emptyMap()); - private static final ServicePortSecureResolver.Input SECURED_1 = new ServicePortSecureResolver.Input(1234, "dummy", - SECURED_1_MAP, Collections.emptyMap()); + private static final ServicePortSecureResolver.Input SECURED_1 = new ServicePortSecureResolver.Input( + new Fabric8ServicePortData(1234, "http"), "dummy", SECURED_1_MAP, Collections.emptyMap()); - private static final ServicePortSecureResolver.Input SECURED_YES = new ServicePortSecureResolver.Input(4321, - "dummy", SECURED_YES_MAP, Collections.emptyMap()); + private static final ServicePortSecureResolver.Input SECURED_YES = new ServicePortSecureResolver.Input( + new Fabric8ServicePortData(4321, "http"), "dummy", SECURED_YES_MAP, Collections.emptyMap()); - private static final ServicePortSecureResolver.Input SECURED_ON = new ServicePortSecureResolver.Input(4321, "dummy", - SECURED_ON_MAP, Collections.emptyMap()); + private static final ServicePortSecureResolver.Input SECURED_ON = new ServicePortSecureResolver.Input( + new Fabric8ServicePortData(4321, "http"), "dummy", SECURED_ON_MAP, Collections.emptyMap()); @Test void testPortNumbersOnly() { @@ -56,13 +61,20 @@ class ServicePortSecureResolverTest { ServicePortSecureResolver secureResolver = new ServicePortSecureResolver(properties); - assertThat(secureResolver.resolve(new ServicePortSecureResolver.Input(null, "dummy"))).isFalse(); - assertThat(secureResolver.resolve(new ServicePortSecureResolver.Input(8080, "dummy"))).isFalse(); - assertThat(secureResolver.resolve(new ServicePortSecureResolver.Input(1234, "dummy"))).isFalse(); - - assertThat(secureResolver.resolve(new ServicePortSecureResolver.Input(443, "dummy"))).isTrue(); - assertThat(secureResolver.resolve(new ServicePortSecureResolver.Input(8443, "dummy"))).isTrue(); - assertThat(secureResolver.resolve(new ServicePortSecureResolver.Input(12345, "dummy"))).isTrue(); + assertThat( + secureResolver.resolve(new Input(new Fabric8ServicePortData(-1, "http"), "dummy", Map.of(), Map.of()))) + .isFalse(); + assertThat(secureResolver + .resolve(new Input(new Fabric8ServicePortData(8080, "http"), "dummy", Map.of(), Map.of()))).isFalse(); + assertThat(secureResolver + .resolve(new Input(new Fabric8ServicePortData(1234, "http"), "dummy", Map.of(), Map.of()))).isFalse(); + assertThat( + secureResolver.resolve(new Input(new Fabric8ServicePortData(443, "http"), "dummy", Map.of(), Map.of()))) + .isTrue(); + assertThat(secureResolver + .resolve(new Input(new Fabric8ServicePortData(8443, "http"), "dummy", Map.of(), Map.of()))).isTrue(); + assertThat(secureResolver + .resolve(new Input(new Fabric8ServicePortData(12345, "http"), "dummy", Map.of(), Map.of()))).isTrue(); } @Test @@ -75,4 +87,104 @@ class ServicePortSecureResolverTest { assertThat(secureResolver.resolve(SECURED_ON)).isTrue(); } + @Test + void testNoneConditionsMet(CapturedOutput output) { + KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(true, true, Set.of(), true, 60, + false, null, Set.of(443, 8443, 12345), Map.of(), null, KubernetesDiscoveryProperties.Metadata.DEFAULT, + 0, true); + ServicePortSecureResolver secureResolver = new ServicePortSecureResolver(properties); + Fabric8ServicePortData portData = new Fabric8ServicePortData(8080, "http"); + Input input = new Input(portData, "dummy", Map.of(), Map.of()); + + boolean result = secureResolver.resolve(input); + assertThat(result).isFalse(); + assertThat(output.getOut()).isEmpty(); + } + + @Test + void securedLabelPresentWrongValue(CapturedOutput output) { + KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(true, true, Set.of(), true, 60, + false, null, Set.of(443, 8443), Map.of(), null, KubernetesDiscoveryProperties.Metadata.DEFAULT, 0, + true); + ServicePortSecureResolver secureResolver = new ServicePortSecureResolver(properties); + Fabric8ServicePortData portData = new Fabric8ServicePortData(8080, "http"); + Input input = new Input(portData, "dummy", Map.of("secured", "right"), Map.of()); + + boolean result = secureResolver.resolve(input); + assertThat(result).isFalse(); + assertThat(output.getOut()).isEmpty(); + } + + @Test + void securedLabelPresentCorrectValue(CapturedOutput output) { + KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(true, true, Set.of(), true, 60, + false, null, Set.of(443, 8443), Map.of(), null, KubernetesDiscoveryProperties.Metadata.DEFAULT, 0, + true); + ServicePortSecureResolver secureResolver = new ServicePortSecureResolver(properties); + Fabric8ServicePortData portData = new Fabric8ServicePortData(8080, "http"); + Input input = new Input(portData, "dummy", Map.of("secured", "true"), Map.of()); + + boolean result = secureResolver.resolve(input); + assertThat(result).isTrue(); + assertThat(output.getOut()).contains( + "Considering service with name: dummy and port 8080 to be secure since the service contains a true value for the 'secured' label"); + } + + @Test + void securedAnnotationPresentWrongValue(CapturedOutput output) { + KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(true, true, Set.of(), true, 60, + false, null, Set.of(443, 8443), Map.of(), null, KubernetesDiscoveryProperties.Metadata.DEFAULT, 0, + true); + ServicePortSecureResolver secureResolver = new ServicePortSecureResolver(properties); + Fabric8ServicePortData portData = new Fabric8ServicePortData(8080, "http"); + Input input = new Input(portData, "dummy", Map.of(), Map.of("secured", "right")); + + boolean result = secureResolver.resolve(input); + assertThat(result).isFalse(); + assertThat(output.getOut()).isEmpty(); + } + + @Test + void securedAnnotationPresentCorrectValue(CapturedOutput output) { + KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(true, true, Set.of(), true, 60, + false, null, Set.of(443, 8443), Map.of(), null, KubernetesDiscoveryProperties.Metadata.DEFAULT, 0, + true); + ServicePortSecureResolver secureResolver = new ServicePortSecureResolver(properties); + Fabric8ServicePortData portData = new Fabric8ServicePortData(8080, "http"); + Input input = new Input(portData, "dummy", Map.of(), Map.of("secured", "true")); + + boolean result = secureResolver.resolve(input); + assertThat(result).isTrue(); + assertThat(output.getOut()).contains( + "Considering service with name: dummy and port 8080 to be secure since the service contains a true value for the 'secured' annotation"); + } + + @Test + void knownPortsMatches(CapturedOutput output) { + KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(true, true, Set.of(), true, 60, + false, null, Set.of(8080), Map.of(), null, KubernetesDiscoveryProperties.Metadata.DEFAULT, 0, true); + ServicePortSecureResolver secureResolver = new ServicePortSecureResolver(properties); + Fabric8ServicePortData portData = new Fabric8ServicePortData(8080, "http"); + Input input = new Input(portData, "dummy", Map.of(), Map.of()); + + boolean result = secureResolver.resolve(input); + assertThat(result).isTrue(); + assertThat(output.getOut()).contains( + "Considering service with name: dummy and port 8080 to be secure since port is known to be a https port"); + } + + @Test + void noConditionsMatchButPortIsHttps(CapturedOutput output) { + KubernetesDiscoveryProperties properties = new KubernetesDiscoveryProperties(true, true, Set.of(), true, 60, + false, null, Set.of(8081), Map.of(), null, KubernetesDiscoveryProperties.Metadata.DEFAULT, 0, true); + ServicePortSecureResolver secureResolver = new ServicePortSecureResolver(properties); + Fabric8ServicePortData portData = new Fabric8ServicePortData(8080, "https"); + Input input = new Input(portData, "dummy", Map.of(), Map.of()); + + boolean result = secureResolver.resolve(input); + assertThat(result).isTrue(); + assertThat(output.getOut()) + .contains("Considering service with name: dummy and port 8080 to be secure since port-name is 'https'"); + } + }