added support for secured k8s service annotations and labels (v. 2.1.x) (#1151)

This commit is contained in:
fgapito
2022-12-05 16:04:36 +01:00
committed by GitHub
parent a368f05a3d
commit f293d06600
2 changed files with 55 additions and 1 deletions

View File

@@ -56,6 +56,8 @@ public class KubernetesInformerDiscoveryClient implements DiscoveryClient, Initi
private static final String PRIMARY_PORT_NAME_LABEL_KEY = "primary-port-name";
private static final String SECURED_KEY = "secured";
private static final String HTTPS_PORT_NAME = "https";
private static final String HTTP_PORT_NAME = "http";
@@ -145,6 +147,8 @@ public class KubernetesInformerDiscoveryClient implements DiscoveryClient, Initi
}
final String primaryPortName = discoveredPrimaryPortName.orElse(this.properties.getPrimaryPortName());
final boolean secured = isSecured(service);
return ep.getSubsets().stream().filter(subset -> subset.getPorts() != null && subset.getPorts().size() > 0) // safeguard
.flatMap(subset -> {
Map<String, String> metadata = new HashMap<>(svcMetadata);
@@ -167,11 +171,22 @@ public class KubernetesInformerDiscoveryClient implements DiscoveryClient, Initi
return addresses.stream()
.map(addr -> new KubernetesServiceInstance(
addr.getTargetRef() != null ? addr.getTargetRef().getUid() : "", serviceId,
addr.getIp(), port, metadata, false, service.getMetadata().getNamespace(),
addr.getIp(), port, metadata, secured, service.getMetadata().getNamespace(),
service.getMetadata().getClusterName()));
}).collect(Collectors.toList());
}
private static boolean isSecured(V1Service service) {
Optional<String> securedOpt = Optional.empty();
if (service.getMetadata() != null && service.getMetadata().getAnnotations() != null) {
securedOpt = Optional.ofNullable(service.getMetadata().getAnnotations().get(SECURED_KEY));
}
if (securedOpt.isEmpty() && service.getMetadata() != null && service.getMetadata().getLabels() != null) {
securedOpt = Optional.ofNullable(service.getMetadata().getLabels().get(SECURED_KEY));
}
return Boolean.parseBoolean(securedOpt.orElse("false"));
}
private int findEndpointPort(List<V1EndpointPort> endpointPorts, String primaryPortName, String serviceId) {
if (endpointPorts.size() == 1) {
return endpointPorts.get(0).getPort();

View File

@@ -35,6 +35,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties;
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesServiceInstance;
@@ -56,6 +57,15 @@ public class KubernetesInformerDiscoveryClientTests {
.metadata(new V1ObjectMeta().name("test-svc-1").namespace("namespace1"))
.spec(new V1ServiceSpec().loadBalancerIP("1.1.1.1")).status(new V1ServiceStatus());
private static final V1Service testServiceSecuredAnnotation1 = new V1Service()
.metadata(
new V1ObjectMeta().name("test-svc-1").namespace("namespace1").putAnnotationsItem("secured", "true"))
.spec(new V1ServiceSpec().loadBalancerIP("1.1.1.1")).status(new V1ServiceStatus());
private static final V1Service testServiceSecuredLabel1 = new V1Service()
.metadata(new V1ObjectMeta().name("test-svc-1").namespace("namespace1").putLabelsItem("secured", "true"))
.spec(new V1ServiceSpec().loadBalancerIP("1.1.1.1")).status(new V1ServiceStatus());
private static final V1Service testService2 = new V1Service()
.metadata(new V1ObjectMeta().name("test-svc-1").namespace("namespace2"))
.spec(new V1ServiceSpec().loadBalancerIP("1.1.1.1")).status(new V1ServiceStatus());
@@ -177,6 +187,35 @@ public class KubernetesInformerDiscoveryClientTests {
"test-svc-3", "2.2.2.2", 8080, new HashMap<>(), false, "namespace1", null));
}
@Test
public void testDiscoveryInstancesWithSecuredServiceByAnnotations() {
Lister<V1Service> serviceLister = setupServiceLister(testServiceSecuredAnnotation1);
Lister<V1Endpoints> endpointsLister = setupEndpointsLister(testEndpoints1);
when(kubernetesDiscoveryProperties.getMetadata()).thenReturn(new KubernetesDiscoveryProperties.Metadata());
KubernetesInformerDiscoveryClient discoveryClient = new KubernetesInformerDiscoveryClient("namespace1",
sharedInformerFactory, serviceLister, endpointsLister, null, null, kubernetesDiscoveryProperties);
assertThat(discoveryClient.getServices().toArray())
.containsOnly(testServiceSecuredAnnotation1.getMetadata().getName());
ServiceInstance serviceInstance = discoveryClient
.getInstances(testServiceSecuredAnnotation1.getMetadata().getName()).get(0);
assertThat(serviceInstance.isSecure()).isTrue();
}
@Test
public void testDiscoveryInstancesWithSecuredServiceByLabels() {
Lister<V1Service> serviceLister = setupServiceLister(testServiceSecuredLabel1);
Lister<V1Endpoints> endpointsLister = setupEndpointsLister(testEndpoints1);
when(kubernetesDiscoveryProperties.getMetadata()).thenReturn(new KubernetesDiscoveryProperties.Metadata());
KubernetesInformerDiscoveryClient discoveryClient = new KubernetesInformerDiscoveryClient("namespace1",
sharedInformerFactory, serviceLister, endpointsLister, null, null, kubernetesDiscoveryProperties);
assertThat(discoveryClient.getServices().toArray())
.containsOnly(testServiceSecuredLabel1.getMetadata().getName());
ServiceInstance serviceInstance = discoveryClient.getInstances(testServiceSecuredLabel1.getMetadata().getName())
.get(0);
assertThat(serviceInstance.isSecure()).isTrue();
}
@Test
public void testDiscoveryGetServicesOneNamespaceShouldWork() {
Lister<V1Service> serviceLister = setupServiceLister(testService1, testService2);