Supports zone-configuratin for eureka

Signed-off-by: kvmw <mshamsi@broadcom.com>
This commit is contained in:
kvmw
2024-11-07 10:29:40 +01:00
parent 18db60a113
commit 3572d747d1
2 changed files with 75 additions and 4 deletions

View File

@@ -22,6 +22,7 @@ import org.springframework.core.env.Environment;
import org.springframework.cloud.bindings.boot.pem.PemSslStoreHelper;
import org.springframework.util.StringUtils;
import java.net.URI;
import java.nio.file.Path;
import java.util.Map;
@@ -51,14 +52,19 @@ final class EurekaBindingsPropertiesProcessor implements BindingsPropertiesProce
map.from("uri").to("eureka.client.serviceUrl.defaultZone",
(uri) -> String.format("%s/eureka/", uri)
);
map.from("uri").to("eureka.instance.metadata-map.zone",
this::hostnameFromUri
);
properties.put("eureka.client.region", "default");
properties.put("spring.cloud.loadbalancer.configurations", "zone-preference");
String caCert = secret.get("ca.crt");
if (caCert != null && !caCert.isEmpty()) {
// generally apps using TLS bindings will be running in k8s where the host name is not meaningful,
// but we don't want to override the endpoint behavior the app has already set, in case they want to
// explicitly set eureka.instance.hostname to route traffic through normal ingress.
if (! environment.containsProperty("eureka.instance.preferIpAddress")) {
if (!environment.containsProperty("eureka.instance.preferIpAddress")) {
properties.put("eureka.instance.preferIpAddress", true);
}
@@ -68,7 +74,7 @@ final class EurekaBindingsPropertiesProcessor implements BindingsPropertiesProce
Path trustFilePath = PemSslStoreHelper.createKeyStoreFile("eureka-truststore", generatedPassword, caCert, null, "rootca");
properties.put("eureka.client.tls.enabled", true);
properties.put("eureka.client.tls.trust-store", "file:"+trustFilePath);
properties.put("eureka.client.tls.trust-store", "file:" + trustFilePath);
properties.put("eureka.client.tls.trust-store-type", PemSslStoreHelper.PKCS12_STORY_TYPE);
properties.put("eureka.client.tls.trust-store-password", generatedPassword);
@@ -91,4 +97,23 @@ final class EurekaBindingsPropertiesProcessor implements BindingsPropertiesProce
}
});
}
private String hostnameFromUri(String uri) {
if (!StringUtils.hasText(uri)) {
return "";
}
try {
URI u = URI.create(uri);
if (u.getHost() != null) {
return u.getHost();
}
if (u.getScheme() == null) {
return URI.create("ignore://" + uri).getHost();
}
} catch (IllegalArgumentException e) {
//ignore malformed uri
}
return "";
}
}

View File

@@ -40,7 +40,7 @@ final class EurekaBindingsPropertiesProcessorTest {
new Binding("test-name", Paths.get("test-path"),
new FluentMap()
.withEntry(Binding.TYPE, TYPE)
.withEntry("uri", "test-uri")
.withEntry("uri", "https://test-uri")
)
);
private final MockEnvironment environment = new MockEnvironment();
@@ -63,7 +63,9 @@ final class EurekaBindingsPropertiesProcessorTest {
assertThat(properties)
.containsEntry("eureka.client.region", "default")
.containsEntry("eureka.client.serviceUrl.defaultZone", "test-uri/eureka/")
.containsEntry("eureka.client.serviceUrl.defaultZone", "https://test-uri/eureka/")
.containsEntry("spring.cloud.loadbalancer.configurations", "zone-preference")
.containsEntry("eureka.instance.metadata-map.zone", "test-uri")
.doesNotContainKey("eureka.client.oauth2.client-id")
.doesNotContainKey("eureka.client.oauth2.access-token-uri")
.doesNotContainKey("eureka.client.tls.trust-store")
@@ -226,6 +228,7 @@ final class EurekaBindingsPropertiesProcessorTest {
new EurekaBindingsPropertiesProcessor().process(environment, bindings, properties);
});
}
@Test
@DisplayName("throws when tls.crt is set but tls.key isn't")
void testNoTlsKey() {
@@ -243,6 +246,7 @@ final class EurekaBindingsPropertiesProcessorTest {
new EurekaBindingsPropertiesProcessor().process(environment, bindings, properties);
});
}
@Test
@DisplayName("throws when tls.key is set but tls.crt isn't")
void testNoTlsCrt() {
@@ -261,6 +265,48 @@ final class EurekaBindingsPropertiesProcessorTest {
});
}
@Test
@DisplayName("handles eureka zone for uri without scheme")
void zoneFromUriWithoutScheme() {
bindings = new Bindings(
new Binding("test-name", Paths.get("test-path"),
new FluentMap()
.withEntry(Binding.TYPE, TYPE)
.withEntry("uri", "test-uri")
)
);
new EurekaBindingsPropertiesProcessor().process(environment, bindings, properties);
assertThat(properties)
.containsExactlyInAnyOrderEntriesOf(new FluentMap()
.withEntry("eureka.client.region", "default")
.withEntry("eureka.client.serviceUrl.defaultZone", "test-uri/eureka/")
.withEntry("spring.cloud.loadbalancer.configurations", "zone-preference")
.withEntry("eureka.instance.metadata-map.zone", "test-uri")
);
}
@Test
@DisplayName("handles eureka zone for malformed uri")
void zoneFromMalformedUri() {
bindings = new Bindings(
new Binding("test-name", Paths.get("test-path"),
new FluentMap()
.withEntry(Binding.TYPE, TYPE)
.withEntry("uri", "http:")
)
);
new EurekaBindingsPropertiesProcessor().process(environment, bindings, properties);
assertThat(properties)
.containsExactlyInAnyOrderEntriesOf(new FluentMap()
.withEntry("eureka.client.region", "default")
.withEntry("eureka.client.serviceUrl.defaultZone", "http:/eureka/")
.withEntry("spring.cloud.loadbalancer.configurations", "zone-preference")
.withEntry("eureka.instance.metadata-map.zone", "")
);
}
@Test
@DisplayName("can be disabled")
void disabled() {