diff --git a/docs/src/main/asciidoc/spring-cloud-commons.adoc b/docs/src/main/asciidoc/spring-cloud-commons.adoc index 0b93f878..07548e63 100644 --- a/docs/src/main/asciidoc/spring-cloud-commons.adoc +++ b/docs/src/main/asciidoc/spring-cloud-commons.adoc @@ -393,7 +393,7 @@ TIP: If you see errors like `java.lang.IllegalArgumentException: Can not set org [[ignore-network-interfaces]] === Ignore Network Interfaces -Sometimes it is useful to ignore certain named network interfaces so they can be excluded from Service Discovery registration (eg. running in a Docker container). A list of regular expressions can be set that will cause the desired network interfaces to be ignored. The following configuration will ignore the "docker0" interface and all interfaces that start with "veth". +Sometimes it is useful to ignore certain named network interfaces so they can be excluded from Service Discovery registration (eg. running in a Docker container). A list of regular expressions can be set that will cause the desired network interfaces to be ignored. The following configuration will ignore the "docker0" interface and all interfaces that start with "veth". .application.yml ---- @@ -403,4 +403,26 @@ spring: ignoredInterfaces: - docker0 - veth.* ----- \ No newline at end of file +---- + +You can also force to use only specified network addresses using list of regular expressions: + +.application.yml +---- +spring: + cloud: + inetutils: + preferredNetworks: + - 192.168 + - 10.0 +---- + +You can also force to use only site local addresses. See https://docs.oracle.com/javase/8/docs/api/java/net/Inet4Address.html#isSiteLocalAddress--[Inet4Address.html.isSiteLocalAddress()] for more details what is site local address. + +.application.yml +---- +spring: + cloud: + inetutils: + useOnlySiteLocalInterfaces: true +---- diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtils.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtils.java index 81df0c73..12b4a174 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtils.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtils.java @@ -98,7 +98,8 @@ public class InetUtils implements Closeable { .getInetAddresses(); addrs.hasMoreElements();) { InetAddress address = addrs.nextElement(); if (address instanceof Inet4Address - && !address.isLoopbackAddress()) { + && !address.isLoopbackAddress() + && !ignoreAddress(address)) { log.trace("Found non-loopback interface: " + ifc.getDisplayName()); result = address; @@ -127,7 +128,23 @@ public class InetUtils implements Closeable { return null; } - boolean ignoreInterface(String interfaceName) { + /** for testing */ boolean ignoreAddress(InetAddress address) { + + if (this.properties.isUseOnlySiteLocalInterfaces() && !address.isSiteLocalAddress()) { + log.trace("Ignoring address: " + address.getHostAddress()); + return true; + } + + for (String regex : this.properties.getPreferredNetworks()) { + if (!address.getHostAddress().matches(regex) && !address.getHostAddress().startsWith(regex)) { + log.trace("Ignoring address: " + address.getHostAddress()); + return true; + } + } + return false; + } + + /** for testing */ boolean ignoreInterface(String interfaceName) { for (String regex : this.properties.getIgnoredInterfaces()) { if (interfaceName.matches(regex)) { log.trace("Ignoring interface: " + interfaceName); diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtilsProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtilsProperties.java index 774df8b5..8c6b0dd2 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtilsProperties.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/util/InetUtilsProperties.java @@ -1,5 +1,6 @@ package org.springframework.cloud.commons.util; +import java.net.InetAddress; import java.util.ArrayList; import java.util.List; @@ -36,4 +37,14 @@ public class InetUtilsProperties { * List of Java regex expressions for network interfaces that will be ignored. */ private List ignoredInterfaces = new ArrayList<>(); + + /** + * Use only interfaces with site local addresses. See {@link InetAddress#isSiteLocalAddress()} for more details. + */ + private boolean useOnlySiteLocalInterfaces = false; + + /** + * List of Java regex expressions for network addresses that will be ignored. + */ + private List preferredNetworks = new ArrayList<>(); } diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/InetUtilsTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/InetUtilsTests.java index 988074e3..8b8e4f3b 100644 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/InetUtilsTests.java +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/util/InetUtilsTests.java @@ -86,4 +86,36 @@ public class InetUtilsTests { } } + @Test + public void testSiteLocalAddresses() throws Exception { + InetUtilsProperties properties = new InetUtilsProperties(); + properties.setUseOnlySiteLocalInterfaces(true); + + try (InetUtils utils = new InetUtils(properties)) { + assertFalse(utils.ignoreAddress(InetAddress.getByName("192.168.0.1"))); + assertTrue(utils.ignoreAddress(InetAddress.getByName("5.5.8.1"))); + } + } + + @Test + public void testPrefferedNetworksRegex() throws Exception { + InetUtilsProperties properties = new InetUtilsProperties(); + properties.setPreferredNetworks(Arrays.asList("192.168.*")); + + try (InetUtils utils = new InetUtils(properties)) { + assertFalse(utils.ignoreAddress(InetAddress.getByName("192.168.0.1"))); + assertTrue(utils.ignoreAddress(InetAddress.getByName("5.5.8.1"))); + } + } + + @Test + public void testPrefferedNetworksSimple() throws Exception { + InetUtilsProperties properties = new InetUtilsProperties(); + properties.setPreferredNetworks(Arrays.asList("192")); + + try (InetUtils utils = new InetUtils(properties)) { + assertFalse(utils.ignoreAddress(InetAddress.getByName("192.168.0.1"))); + assertTrue(utils.ignoreAddress(InetAddress.getByName("5.5.8.1"))); + } + } }