From fdb83d97fa7bb4fab9e34cca46ad204ffae16be5 Mon Sep 17 00:00:00 2001 From: James Nord Date: Mon, 5 Aug 2024 13:58:27 +0100 Subject: [PATCH 01/15] Attempt to restore the Linux ITs --- Jenkinsfile | 4 +--- pom.xml | 7 +++++++ .../ActiveDirectoryGenericContainer.java | 5 ++++- .../EntoEndUserCacheLookupDisabledTest.java | 3 --- .../EntoEndUserCacheLookupEnabledTest.java | 3 --- .../docker/TheFlintstonesIT.java | 19 +++++++++++++++---- .../docker/TheFlintstonesTest.java | 3 --- 7 files changed, 27 insertions(+), 17 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index dbb74f72..d0815e1e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -4,18 +4,16 @@ buildPlugin(useContainerAgent: false, configurations: [ [platform: 'windows', jdk: 17], ]) -/* TODO rewrite tests to use Testcontainers (and select Linux VM nodes above) node('docker') { stage('checkout') { checkout scm } stage('maven') { - sh 'docker build -t fixture src/test/resources/fixture && docker run --add-host=samdom.example.com:127.0.0.1 -v /var/lib/docker --privileged --dns=127.0.0.1 --dns=8.8.8.8 -v $WORKSPACE:/project fixture clean install -P onlyITs' + sh 'mvn clean install -P onlyITs' } stage('surefire-report') { junit 'target/surefire-reports/*.xml' } } -*/ diff --git a/pom.xml b/pom.xml index cfdb9c8c..e484b106 100644 --- a/pom.xml +++ b/pom.xml @@ -129,6 +129,13 @@ 1.19.0 test + + + org.burningwave + tools + 0.26.1 + test + diff --git a/src/test/java/hudson/plugins/active_directory/docker/ActiveDirectoryGenericContainer.java b/src/test/java/hudson/plugins/active_directory/docker/ActiveDirectoryGenericContainer.java index 720e5bcd..59a1f7d0 100644 --- a/src/test/java/hudson/plugins/active_directory/docker/ActiveDirectoryGenericContainer.java +++ b/src/test/java/hudson/plugins/active_directory/docker/ActiveDirectoryGenericContainer.java @@ -3,6 +3,8 @@ import java.io.IOException; import org.testcontainers.containers.GenericContainer; import org.testcontainers.containers.InternetProtocol; +import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy; +import org.testcontainers.containers.wait.strategy.WaitStrategy; import org.testcontainers.images.builder.ImageFromDockerfile; import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.command.CreateContainerCmd; @@ -25,7 +27,8 @@ public ActiveDirectoryGenericContainer() { .withFileFromClasspath("named.conf.options", "hudson/plugins/active_directory/docker/TheFlintstonesTest/TheFlintstones/named.conf.options") .withFileFromClasspath("sssd.conf", "hudson/plugins/active_directory/docker/TheFlintstonesTest/TheFlintstones/sssd.conf") .withFileFromClasspath("supervisord.conf", "hudson/plugins/active_directory/docker/TheFlintstonesTest/TheFlintstones/supervisord.conf")); - setWaitStrategy(null); + // wait for the custom.sh script to complete successfully + setWaitStrategy(new LogMessageWaitStrategy().withRegEx(".*\\Qexited: custom (exit status 0; expected)\\E.*")); } /* diff --git a/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupDisabledTest.java b/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupDisabledTest.java index 40fdc3ac..d8abe3ae 100644 --- a/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupDisabledTest.java +++ b/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupDisabledTest.java @@ -59,9 +59,6 @@ public void customSingleADSetup(ActiveDirectoryDomain activeDirectoryDomain, Str ActiveDirectorySecurityRealm activeDirectorySecurityRealm = new ActiveDirectorySecurityRealm(null, domains, site, bindName, bindPassword, null, groupLookupStrategy, removeIrrelevantGroups, customDomain, cache, startTls, internalUsersDatabase, false); j.getInstance().setSecurityRealm(activeDirectorySecurityRealm); - while(!docker.getLogs().contains("custom (exit status 0; expected)")) { - Thread.sleep(1000); - } UserDetails userDetails = null; int i = 0; while (i < MAX_RETRIES && userDetails == null) { diff --git a/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupEnabledTest.java b/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupEnabledTest.java index 55fc773e..a9e1ae87 100644 --- a/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupEnabledTest.java +++ b/src/test/java/hudson/plugins/active_directory/docker/EntoEndUserCacheLookupEnabledTest.java @@ -80,9 +80,6 @@ public void customSingleADSetup(ActiveDirectoryDomain activeDirectoryDomain, Str ActiveDirectorySecurityRealm activeDirectorySecurityRealm = new ActiveDirectorySecurityRealm(null, domains, site, bindName, bindPassword, null, groupLookupStrategy, removeIrrelevantGroups, customDomain, cache, startTls, internalUsersDatabase, false); j.getInstance().setSecurityRealm(activeDirectorySecurityRealm); - while(!docker.getLogs().contains("custom (exit status 0; expected)")) { - Thread.sleep(1000); - } UserDetails userDetails = null; int i = 0; while (i < MAX_RETRIES && userDetails == null) { diff --git a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java index bfe4f966..e631d0ae 100644 --- a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java +++ b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java @@ -34,6 +34,10 @@ import hudson.plugins.active_directory.TlsConfiguration; import org.acegisecurity.AuthenticationServiceException; import org.acegisecurity.userdetails.UserDetails; +import org.burningwave.tools.net.DNSClientHostResolver; +import org.burningwave.tools.net.DefaultHostResolver; +import org.burningwave.tools.net.HostResolutionRequestInterceptor; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.Issue; @@ -48,18 +52,28 @@ */ public class TheFlintstonesIT { + @Rule(order = 0) public RequireDockerRule rdr = new RequireDockerRule(); @Rule(order = 1) public ActiveDirectoryGenericContainer docker = new ActiveDirectoryGenericContainer<>().withStaticPorts(); - @Rule(order = 2) // start Jenkins after the container so that timeouts do not apply to container building. + @Rule(order = 4) // start Jenkins after the container so that timeouts do not apply to container building. public JenkinsRule j = new JenkinsRule(); @Rule public LoggerRule l = new LoggerRule(); + @Before + public void configureDNSServer() { + // we need to pint the JVMs DNS resolver at the samba server + // for AD to work correctly it needs to be able to resolve hosts and do SRV lookups on the domain + HostResolutionRequestInterceptor.INSTANCE.install( + new DNSClientHostResolver("127.0.0.1"), // The SAMBA Server + DefaultHostResolver.INSTANCE); + } + public final static String AD_DOMAIN = "samdom.example.com"; public final static String AD_MANAGER_DN = "CN=Administrator,CN=Users,DC=SAMDOM,DC=EXAMPLE,DC=COM"; public final static String AD_MANAGER_DN_PASSWORD = "ia4uV1EeKait"; @@ -81,9 +95,6 @@ public void dynamicSetUp(boolean requireTLS) throws Exception { domains.add(activeDirectoryDomain); ActiveDirectorySecurityRealm activeDirectorySecurityRealm = new ActiveDirectorySecurityRealm(null, domains, null, null, null, null, GroupLookupStrategy.RECURSIVE, false, true, null, false, null, requireTLS); j.getInstance().setSecurityRealm(activeDirectorySecurityRealm); - while(!docker.getLogs().contains("custom (exit status 0; expected)")) { - Thread.sleep(1000); - } UserDetails userDetails = null; int i = 0; while (i < MAX_RETRIES && userDetails == null) { diff --git a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesTest.java b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesTest.java index f5abb8a3..e6909e1f 100644 --- a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesTest.java +++ b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesTest.java @@ -117,9 +117,6 @@ public void dynamicSetUp() throws Exception { domains.add(activeDirectoryDomain); ActiveDirectorySecurityRealm activeDirectorySecurityRealm = new ActiveDirectorySecurityRealm(null, domains, null, null, null, null, GroupLookupStrategy.RECURSIVE, false, true, null, false, null, false); j.getInstance().setSecurityRealm(activeDirectorySecurityRealm); - while(!docker.getLogs().contains("custom (exit status 0; expected)")) { - Thread.sleep(1000); - } UserDetails userDetails = null; int i = 0; while (i < MAX_RETRIES && userDetails == null) { From ceded0b224bbb4148aa4d6460b6b367448d8b7a3 Mon Sep 17 00:00:00 2001 From: James Nord Date: Mon, 5 Aug 2024 16:26:45 +0100 Subject: [PATCH 02/15] quicker testing --- Jenkinsfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index d0815e1e..49937eb9 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,8 +1,9 @@ -buildPlugin(useContainerAgent: false, configurations: [ +/*buildPlugin(useContainerAgent: false, configurations: [ [platform: 'linux', jdk: 21], [platform: 'linux', jdk: 11], [platform: 'windows', jdk: 17], ]) +*/ node('docker') { stage('checkout') { @@ -10,6 +11,8 @@ node('docker') { } stage('maven') { + sh 'systemctl status systemd-resolved' + sh 'netstat -tul' sh 'mvn clean install -P onlyITs' } From 4f051c0e21cb9b7cf8a025f937a700478a556825 Mon Sep 17 00:00:00 2001 From: James Nord Date: Mon, 5 Aug 2024 16:44:42 +0100 Subject: [PATCH 03/15] be more correct in a comment --- .../plugins/active_directory/docker/TheFlintstonesIT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java index e631d0ae..f8c72197 100644 --- a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java +++ b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java @@ -67,7 +67,7 @@ public class TheFlintstonesIT { @Before public void configureDNSServer() { - // we need to pint the JVMs DNS resolver at the samba server + // we need to pint the JVMs DNS resolver at the AD (samba) server // for AD to work correctly it needs to be able to resolve hosts and do SRV lookups on the domain HostResolutionRequestInterceptor.INSTANCE.install( new DNSClientHostResolver("127.0.0.1"), // The SAMBA Server From ca5c7f18977770d88c6c5b8a66ab784f752f9c5d Mon Sep 17 00:00:00 2001 From: James Nord Date: Mon, 5 Aug 2024 17:56:00 +0100 Subject: [PATCH 04/15] more testing --- Jenkinsfile | 2 +- hack_systemd_resolve.sh | 11 +++++++ .../docker/TheFlintstonesIT.java | 31 +++++++++++++++++-- 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100755 hack_systemd_resolve.sh diff --git a/Jenkinsfile b/Jenkinsfile index 49937eb9..5205eed9 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -11,7 +11,7 @@ node('docker') { } stage('maven') { - sh 'systemctl status systemd-resolved' + sh 'sudo ./hack_systemd_resolve.sh' sh 'netstat -tul' sh 'mvn clean install -P onlyITs' } diff --git a/hack_systemd_resolve.sh b/hack_systemd_resolve.sh new file mode 100755 index 00000000..1669afcd --- /dev/null +++ b/hack_systemd_resolve.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# the FlintsonesIT will not work if the the DNS ports can not be bound +# usually because you are running a DNS server locally (but why!) +# for some ungodly known reason this appears to the default on some systemd installations + +systemctl stop systemd-resolved +sed -i 's/#DNS=.*/DNS=8.8.8.8/g' /etc/systemd/resolved.conf +sed -i 's/DNSStubListener=yes/DNSStubListener=no/g' /etc/systemd/resolved.conf +ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf +systemctl start systemd-resolved diff --git a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java index f8c72197..5c583ebe 100644 --- a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java +++ b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java @@ -25,7 +25,13 @@ package hudson.plugins.active_directory.docker; import static org.junit.Assert.assertEquals; +import static org.junit.Assume.assumeFalse; +import static org.junit.Assume.assumeTrue; + +import java.io.File; import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; import javax.naming.NamingException; @@ -37,7 +43,9 @@ import org.burningwave.tools.net.DNSClientHostResolver; import org.burningwave.tools.net.DefaultHostResolver; import org.burningwave.tools.net.HostResolutionRequestInterceptor; +import org.burningwave.tools.net.HostResolver; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.Issue; @@ -66,14 +74,33 @@ public class TheFlintstonesIT { public LoggerRule l = new LoggerRule(); @Before - public void configureDNSServer() { + public void configureDNSServer() throws UnknownHostException { // we need to pint the JVMs DNS resolver at the AD (samba) server // for AD to work correctly it needs to be able to resolve hosts and do SRV lookups on the domain + + String host = docker.getHost(); + // whilst the `getHost()` is supposed to return an IPAddress in some cases it will return "localhost" + // we need a resolved address to configure the resolver do a lookup before we change the DNS. + InetAddress hostInetAddr = InetAddress.getByName(host); + HostResolutionRequestInterceptor.INSTANCE.install( - new DNSClientHostResolver("127.0.0.1"), // The SAMBA Server + new DNSClientHostResolver(hostInetAddr.getHostAddress()), DefaultHostResolver.INSTANCE); } + @Before + public void ensureSaneNetworkingSetup() { + // the docker network used needs to be reachable from the host + // if we are using the default "bridge" network then windows based hosts can not by default get access to the non mapped ports + // on the bridge network (as the bridge network is not routable from windows!) + // the AD server will respond to queries for it's domain with its own IP address - and this would be an address on the bridge network + // that windows can not get access to + // There will likely be other scenarious in Linux and or mac also that may need to be added. + // whilst host based networking should work everywhere (new ActiveDirectoryGenericContainer<>().withNetworkMode("host")) this also seems to fail + // as the DNS request timeout + assumeFalse(File.pathSeparatorChar == ';'); + } + public final static String AD_DOMAIN = "samdom.example.com"; public final static String AD_MANAGER_DN = "CN=Administrator,CN=Users,DC=SAMDOM,DC=EXAMPLE,DC=COM"; public final static String AD_MANAGER_DN_PASSWORD = "ia4uV1EeKait"; From c2ddc63a4e63e4cefd71193314fc091abbb40476 Mon Sep 17 00:00:00 2001 From: James Nord Date: Mon, 5 Aug 2024 18:02:23 +0100 Subject: [PATCH 05/15] there is no netstat --- Jenkinsfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 5205eed9..0eda8163 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -12,7 +12,6 @@ node('docker') { stage('maven') { sh 'sudo ./hack_systemd_resolve.sh' - sh 'netstat -tul' sh 'mvn clean install -P onlyITs' } From 1cf54075a2c6473ed1183d9ae2dbba29488d0f31 Mon Sep 17 00:00:00 2001 From: James Nord Date: Mon, 5 Aug 2024 18:15:59 +0100 Subject: [PATCH 06/15] more debugging --- Jenkinsfile | 2 +- hack_systemd_resolve.sh | 8 +++++++- .../plugins/active_directory/docker/TheFlintstonesIT.java | 5 +++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 0eda8163..9d209f42 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -12,7 +12,7 @@ node('docker') { stage('maven') { sh 'sudo ./hack_systemd_resolve.sh' - sh 'mvn clean install -P onlyITs' + sh 'mvn -B clean install -P onlyITs -Dtest=TheFlintstonesIT' } stage('surefire-report') { diff --git a/hack_systemd_resolve.sh b/hack_systemd_resolve.sh index 1669afcd..3f0480ab 100755 --- a/hack_systemd_resolve.sh +++ b/hack_systemd_resolve.sh @@ -1,11 +1,17 @@ #!/bin/bash - +set -x # the FlintsonesIT will not work if the the DNS ports can not be bound # usually because you are running a DNS server locally (but why!) # for some ungodly known reason this appears to the default on some systemd installations +# uses instructions from https://www.linuxuprising.com/2020/07/ubuntu-how-to-free-up-port-53-used-by.html + +lsod -i :53 systemctl stop systemd-resolved +lsod -i :53 sed -i 's/#DNS=.*/DNS=8.8.8.8/g' /etc/systemd/resolved.conf sed -i 's/DNSStubListener=yes/DNSStubListener=no/g' /etc/systemd/resolved.conf ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf +lsod -i :53 systemctl start systemd-resolved +lsod -i :53 diff --git a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java index 5c583ebe..5c7be248 100644 --- a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java +++ b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java @@ -57,6 +57,9 @@ /** * Integration tests with Docker and requiring custom DNS in the target env with fixed ports. + * NOTE: these tests will fail if you have port53 (or any other port required by Samba bound locally) + * for DNS (port53 issues on linux see hack_systemd_resolve.sh or + * Ubuntu: How To Free Up Port 53, Used By systemd-resolved} */ public class TheFlintstonesIT { @@ -64,6 +67,8 @@ public class TheFlintstonesIT { @Rule(order = 0) public RequireDockerRule rdr = new RequireDockerRule(); + // if the rule fails as port 53 is in use (on linux) see hack_systemd_resolve.sh + // or https://www.linuxuprising.com/2020/07/ubuntu-how-to-free-up-port-53-used-by.html @Rule(order = 1) public ActiveDirectoryGenericContainer docker = new ActiveDirectoryGenericContainer<>().withStaticPorts(); From 8e0013fc9f7bd46071f11ad92ef24f1661af51ce Mon Sep 17 00:00:00 2001 From: James Nord Date: Mon, 5 Aug 2024 18:21:32 +0100 Subject: [PATCH 07/15] s/lsod/lsof/ --- hack_systemd_resolve.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hack_systemd_resolve.sh b/hack_systemd_resolve.sh index 3f0480ab..bf403cc9 100755 --- a/hack_systemd_resolve.sh +++ b/hack_systemd_resolve.sh @@ -6,12 +6,12 @@ set -x # uses instructions from https://www.linuxuprising.com/2020/07/ubuntu-how-to-free-up-port-53-used-by.html -lsod -i :53 +lsof -i :53 systemctl stop systemd-resolved -lsod -i :53 +lsof -i :53 sed -i 's/#DNS=.*/DNS=8.8.8.8/g' /etc/systemd/resolved.conf sed -i 's/DNSStubListener=yes/DNSStubListener=no/g' /etc/systemd/resolved.conf ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf -lsod -i :53 +lsof -i :53 systemctl start systemd-resolved -lsod -i :53 +lsof -i :53 From 9f21a9e18c04b789de51224cd66170acf125d3a4 Mon Sep 17 00:00:00 2001 From: James Nord Date: Mon, 5 Aug 2024 18:30:04 +0100 Subject: [PATCH 08/15] more debugging --- hack_systemd_resolve.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hack_systemd_resolve.sh b/hack_systemd_resolve.sh index bf403cc9..87bfe1f5 100755 --- a/hack_systemd_resolve.sh +++ b/hack_systemd_resolve.sh @@ -9,9 +9,13 @@ set -x lsof -i :53 systemctl stop systemd-resolved lsof -i :53 +cat /etc/systemd/resolved.conf +cat /run/systemd/resolve/resolv.conf sed -i 's/#DNS=.*/DNS=8.8.8.8/g' /etc/systemd/resolved.conf sed -i 's/DNSStubListener=yes/DNSStubListener=no/g' /etc/systemd/resolved.conf ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf lsof -i :53 systemctl start systemd-resolved lsof -i :53 +cat /etc/systemd/resolved.conf +cat /run/systemd/resolve/resolv.conf From df1b94f87becdb16f6426265a5a3d8a47853d56b Mon Sep 17 00:00:00 2001 From: James Nord Date: Mon, 5 Aug 2024 19:40:19 +0100 Subject: [PATCH 09/15] tweak sed to correctly pickup option --- hack_systemd_resolve.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hack_systemd_resolve.sh b/hack_systemd_resolve.sh index 87bfe1f5..06f50e6a 100755 --- a/hack_systemd_resolve.sh +++ b/hack_systemd_resolve.sh @@ -11,8 +11,8 @@ systemctl stop systemd-resolved lsof -i :53 cat /etc/systemd/resolved.conf cat /run/systemd/resolve/resolv.conf -sed -i 's/#DNS=.*/DNS=8.8.8.8/g' /etc/systemd/resolved.conf -sed -i 's/DNSStubListener=yes/DNSStubListener=no/g' /etc/systemd/resolved.conf +sed -i 's/#?DNS=.*/DNS=8.8.8.8/g' /etc/systemd/resolved.conf +sed -i 's/#?DNSStubListener=yes/DNSStubListener=no/g' /etc/systemd/resolved.conf ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf lsof -i :53 systemctl start systemd-resolved From 0116b828d919d29e41a7bac291cf355030e2cd4c Mon Sep 17 00:00:00 2001 From: James Nord Date: Mon, 5 Aug 2024 20:48:19 +0100 Subject: [PATCH 10/15] map DNS ports and configure ports on the DNS server to make things work where systemd is stupid... --- .../ActiveDirectoryGenericContainer.java | 4 +- .../docker/TheFlintstonesIT.java | 43 +++++++++++-------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/test/java/hudson/plugins/active_directory/docker/ActiveDirectoryGenericContainer.java b/src/test/java/hudson/plugins/active_directory/docker/ActiveDirectoryGenericContainer.java index 59a1f7d0..b5125596 100644 --- a/src/test/java/hudson/plugins/active_directory/docker/ActiveDirectoryGenericContainer.java +++ b/src/test/java/hudson/plugins/active_directory/docker/ActiveDirectoryGenericContainer.java @@ -38,8 +38,8 @@ public ActiveDirectoryGenericContainer() { public ActiveDirectoryGenericContainer withStaticPorts() { addFixedExposedPort(3268, 3268); // global catalog addFixedExposedPort(3269, 3269); // global catalog over tls - addFixedExposedPort(53, 53, InternetProtocol.TCP); // DNS over TCP - addFixedExposedPort(53, 53, InternetProtocol.UDP); // DNS over UDP + addFixedExposedPort(553, 53, InternetProtocol.TCP); // DNS over TCP + addFixedExposedPort(553, 53, InternetProtocol.UDP); // DNS over UDP return this; } diff --git a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java index 5c7be248..a1bff489 100644 --- a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java +++ b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java @@ -31,9 +31,13 @@ import java.io.File; import java.io.IOException; import java.net.InetAddress; +import java.net.URI; import java.net.UnknownHostException; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; + import javax.naming.NamingException; import javax.servlet.ServletException; @@ -44,6 +48,7 @@ import org.burningwave.tools.net.DefaultHostResolver; import org.burningwave.tools.net.HostResolutionRequestInterceptor; import org.burningwave.tools.net.HostResolver; +import org.burningwave.tools.net.MappedHostResolver; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Rule; @@ -53,6 +58,7 @@ import org.jvnet.hudson.test.LoggerRule; import hudson.plugins.active_directory.ActiveDirectoryDomain; import hudson.plugins.active_directory.ActiveDirectorySecurityRealm; +import hudson.plugins.active_directory.DNSUtils; import hudson.plugins.active_directory.GroupLookupStrategy; /** @@ -79,31 +85,33 @@ public class TheFlintstonesIT { public LoggerRule l = new LoggerRule(); @Before - public void configureDNSServer() throws UnknownHostException { + public void overrideDNSServers() throws UnknownHostException { // we need to pint the JVMs DNS resolver at the AD (samba) server // for AD to work correctly it needs to be able to resolve hosts and do SRV lookups on the domain - String host = docker.getHost(); // whilst the `getHost()` is supposed to return an IPAddress in some cases it will return "localhost" // we need a resolved address to configure the resolver do a lookup before we change the DNS. - InetAddress hostInetAddr = InetAddress.getByName(host); + + InetAddress hostInetAddr = InetAddress.getByName(docker.getHost()); + String hostIP = hostInetAddr.getHostAddress(); + + // but additionally we need to use the locally bound ports and not what AD returns for name resolution + Map hostAliases = new LinkedHashMap<>(); + hostAliases.put("dc1.samdom.example.com", hostIP); + hostAliases.put("samdom.example.com", hostIP); + // this adds the A entry for the PDC, but will leave the discovery of this to the SRV lookup HostResolutionRequestInterceptor.INSTANCE.install( - new DNSClientHostResolver(hostInetAddr.getHostAddress()), + new MappedHostResolver(hostAliases), + new DNSClientHostResolver(hostIP, 553), DefaultHostResolver.INSTANCE); - } + // we also need to set the JNDI default + // see hudson.plugins.active_directory.ActiveDirectoryDomain.createDNSLookupContext() + // getHost returns a hostname not IPaddress... + // use our DNS to resolve that to an IP address. + System.setProperty(DNSUtils.OVERRIDE_DNS_PROPERTY, "dns://"+hostIP+":553"); + - @Before - public void ensureSaneNetworkingSetup() { - // the docker network used needs to be reachable from the host - // if we are using the default "bridge" network then windows based hosts can not by default get access to the non mapped ports - // on the bridge network (as the bridge network is not routable from windows!) - // the AD server will respond to queries for it's domain with its own IP address - and this would be an address on the bridge network - // that windows can not get access to - // There will likely be other scenarious in Linux and or mac also that may need to be added. - // whilst host based networking should work everywhere (new ActiveDirectoryGenericContainer<>().withNetworkMode("host")) this also seems to fail - // as the DNS request timeout - assumeFalse(File.pathSeparatorChar == ';'); } public final static String AD_DOMAIN = "samdom.example.com"; @@ -120,7 +128,8 @@ public void dynamicSetUp() throws Exception { } public void dynamicSetUp(boolean requireTLS) throws Exception { - dockerIp = requireTLS ? docker.getHost() : "dc1.samdom.example.com"; + //dockerIp = requireTLS ? docker.getHost() : "dc1.samdom.example.com"; + dockerIp = "dc1.samdom.example.com"; dockerPort = docker.getMappedPort(requireTLS ? GLOBAL_CATALOG_TLS : GLOBAL_CATALOG_PLAIN_TEXT); ActiveDirectoryDomain activeDirectoryDomain = new ActiveDirectoryDomain(AD_DOMAIN, dockerIp + ":" + dockerPort , null, AD_MANAGER_DN, AD_MANAGER_DN_PASSWORD); List domains = new ArrayList<>(1); From 25b72aadac8b8d43db59974fe451e8f6dce255b8 Mon Sep 17 00:00:00 2001 From: James Nord Date: Tue, 6 Aug 2024 10:08:53 +0100 Subject: [PATCH 11/15] Changes to allow the FlintStonesIT to be able to run without special setup Separates the Windows ITs from the others as these need a specific windows machine (snowflake) --- Jenkinsfile | 18 +------ pom.xml | 50 +++++++++++++++++++ .../WindowsAdsiModeUserCacheDisabledIT.java | 2 +- .../WindowsAdsiModeUserCacheEnabledIT.java | 2 +- .../docker/TheFlintstonesIT.java | 26 ++++------ 5 files changed, 63 insertions(+), 35 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 9d209f42..fac3e806 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,21 +1,5 @@ -/*buildPlugin(useContainerAgent: false, configurations: [ +buildPlugin(useContainerAgent: false, configurations: [ [platform: 'linux', jdk: 21], [platform: 'linux', jdk: 11], [platform: 'windows', jdk: 17], ]) -*/ - -node('docker') { - stage('checkout') { - checkout scm - } - - stage('maven') { - sh 'sudo ./hack_systemd_resolve.sh' - sh 'mvn -B clean install -P onlyITs -Dtest=TheFlintstonesIT' - } - - stage('surefire-report') { - junit 'target/surefire-reports/*.xml' - } -} diff --git a/pom.xml b/pom.xml index e484b106..8d139b72 100644 --- a/pom.xml +++ b/pom.xml @@ -172,6 +172,9 @@ **/*IT.java + + **/Windows*IT.java + @@ -179,6 +182,9 @@ ITs + + true + @@ -194,6 +200,9 @@ **/*IT.java + + **/Windows*IT.java + @@ -201,6 +210,47 @@ + + onlyWindowsITs + + + + maven-surefire-plugin + + 1 + + **/Windows*IT.java + + + + + + + + WindowsITs + + + + maven-surefire-plugin + + + WindowsITs + + test + + + 1 + + **/Windows*IT.java + + + + + + + + + diff --git a/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheDisabledIT.java b/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheDisabledIT.java index d1fe261c..47ac79c1 100644 --- a/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheDisabledIT.java +++ b/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheDisabledIT.java @@ -20,7 +20,7 @@ /** * This tests requires a very specific windows environment to run, the windows machine * needs to be joined to a function domain that has the user fred with the password ia4uV1EeKait. - * It is enabled in the ITs profile, but will skip on I as that profile is enabled only on the special Linux environment. + * It is enabled in the WindowsITs profile, but will skip on I as that profile is enabled only on the special Linux environment. */ public class WindowsAdsiModeUserCacheDisabledIT { diff --git a/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheEnabledIT.java b/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheEnabledIT.java index 5009b954..445a1ade 100644 --- a/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheEnabledIT.java +++ b/src/test/java/hudson/plugins/active_directory/WindowsAdsiModeUserCacheEnabledIT.java @@ -22,7 +22,7 @@ /** * This tests requires a very specific windows environment to run, the windows machine * needs to be joined to a function domain that has the user fred with the password ia4uV1EeKait. - * It is enabled in the ITs profile, but will skip on I as that profile is enabled only on the special Linux environment. + * It is enabled in the windowsITs profile, but will skip on I as that profile is enabled only on the special Linux environment. */ public class WindowsAdsiModeUserCacheEnabledIT { diff --git a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java index a1bff489..f7b7928f 100644 --- a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java +++ b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java @@ -25,13 +25,9 @@ package hudson.plugins.active_directory.docker; import static org.junit.Assert.assertEquals; -import static org.junit.Assume.assumeFalse; -import static org.junit.Assume.assumeTrue; -import java.io.File; import java.io.IOException; import java.net.InetAddress; -import java.net.URI; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -47,10 +43,9 @@ import org.burningwave.tools.net.DNSClientHostResolver; import org.burningwave.tools.net.DefaultHostResolver; import org.burningwave.tools.net.HostResolutionRequestInterceptor; -import org.burningwave.tools.net.HostResolver; import org.burningwave.tools.net.MappedHostResolver; +import org.junit.After; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.Issue; @@ -62,10 +57,7 @@ import hudson.plugins.active_directory.GroupLookupStrategy; /** - * Integration tests with Docker and requiring custom DNS in the target env with fixed ports. - * NOTE: these tests will fail if you have port53 (or any other port required by Samba bound locally) - * for DNS (port53 issues on linux see hack_systemd_resolve.sh or - * Ubuntu: How To Free Up Port 53, Used By systemd-resolved} + * Integration tests with Docker and using samba as a DNS server */ public class TheFlintstonesIT { @@ -78,7 +70,7 @@ public class TheFlintstonesIT { @Rule(order = 1) public ActiveDirectoryGenericContainer docker = new ActiveDirectoryGenericContainer<>().withStaticPorts(); - @Rule(order = 4) // start Jenkins after the container so that timeouts do not apply to container building. + @Rule(order = 2) // start Jenkins after the container so that timeouts do not apply to container building. public JenkinsRule j = new JenkinsRule(); @Rule @@ -91,27 +83,30 @@ public void overrideDNSServers() throws UnknownHostException { // whilst the `getHost()` is supposed to return an IPAddress in some cases it will return "localhost" // we need a resolved address to configure the resolver do a lookup before we change the DNS. - InetAddress hostInetAddr = InetAddress.getByName(docker.getHost()); String hostIP = hostInetAddr.getHostAddress(); - // but additionally we need to use the locally bound ports and not what AD returns for name resolution + // but additionally we need to use the locally bound ports for the catalog and not what AD returns for name resolution Map hostAliases = new LinkedHashMap<>(); hostAliases.put("dc1.samdom.example.com", hostIP); - hostAliases.put("samdom.example.com", hostIP); // this adds the A entry for the PDC, but will leave the discovery of this to the SRV lookup HostResolutionRequestInterceptor.INSTANCE.install( new MappedHostResolver(hostAliases), new DNSClientHostResolver(hostIP, 553), DefaultHostResolver.INSTANCE); + // we also need to set the JNDI default // see hudson.plugins.active_directory.ActiveDirectoryDomain.createDNSLookupContext() // getHost returns a hostname not IPaddress... // use our DNS to resolve that to an IP address. System.setProperty(DNSUtils.OVERRIDE_DNS_PROPERTY, "dns://"+hostIP+":553"); - + } + @After + public void restoreDNS() { + HostResolutionRequestInterceptor.INSTANCE.install(DefaultHostResolver.INSTANCE); + System.clearProperty(DNSUtils.OVERRIDE_DNS_PROPERTY); } public final static String AD_DOMAIN = "samdom.example.com"; @@ -128,7 +123,6 @@ public void dynamicSetUp() throws Exception { } public void dynamicSetUp(boolean requireTLS) throws Exception { - //dockerIp = requireTLS ? docker.getHost() : "dc1.samdom.example.com"; dockerIp = "dc1.samdom.example.com"; dockerPort = docker.getMappedPort(requireTLS ? GLOBAL_CATALOG_TLS : GLOBAL_CATALOG_PLAIN_TEXT); ActiveDirectoryDomain activeDirectoryDomain = new ActiveDirectoryDomain(AD_DOMAIN, dockerIp + ":" + dockerPort , null, AD_MANAGER_DN, AD_MANAGER_DN_PASSWORD); From e3094b72bf41fd6a8f12d0ef5383d12acfa8c092 Mon Sep 17 00:00:00 2001 From: James Nord Date: Tue, 6 Aug 2024 10:24:51 +0100 Subject: [PATCH 12/15] remove left over file --- hack_systemd_resolve.sh | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100755 hack_systemd_resolve.sh diff --git a/hack_systemd_resolve.sh b/hack_systemd_resolve.sh deleted file mode 100755 index 06f50e6a..00000000 --- a/hack_systemd_resolve.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -set -x -# the FlintsonesIT will not work if the the DNS ports can not be bound -# usually because you are running a DNS server locally (but why!) -# for some ungodly known reason this appears to the default on some systemd installations - -# uses instructions from https://www.linuxuprising.com/2020/07/ubuntu-how-to-free-up-port-53-used-by.html - -lsof -i :53 -systemctl stop systemd-resolved -lsof -i :53 -cat /etc/systemd/resolved.conf -cat /run/systemd/resolve/resolv.conf -sed -i 's/#?DNS=.*/DNS=8.8.8.8/g' /etc/systemd/resolved.conf -sed -i 's/#?DNSStubListener=yes/DNSStubListener=no/g' /etc/systemd/resolved.conf -ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf -lsof -i :53 -systemctl start systemd-resolved -lsof -i :53 -cat /etc/systemd/resolved.conf -cat /run/systemd/resolve/resolv.conf From 6bf200dbf0aaced22a6b6b7ceb32db1b5376eacd Mon Sep 17 00:00:00 2001 From: James Nord Date: Tue, 6 Aug 2024 10:39:09 +0100 Subject: [PATCH 13/15] remove obsolete/missleading comments --- .../plugins/active_directory/docker/TheFlintstonesIT.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java index f7b7928f..cf66aa99 100644 --- a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java +++ b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java @@ -65,8 +65,6 @@ public class TheFlintstonesIT { @Rule(order = 0) public RequireDockerRule rdr = new RequireDockerRule(); - // if the rule fails as port 53 is in use (on linux) see hack_systemd_resolve.sh - // or https://www.linuxuprising.com/2020/07/ubuntu-how-to-free-up-port-53-used-by.html @Rule(order = 1) public ActiveDirectoryGenericContainer docker = new ActiveDirectoryGenericContainer<>().withStaticPorts(); @@ -98,8 +96,6 @@ public void overrideDNSServers() throws UnknownHostException { // we also need to set the JNDI default // see hudson.plugins.active_directory.ActiveDirectoryDomain.createDNSLookupContext() - // getHost returns a hostname not IPaddress... - // use our DNS to resolve that to an IP address. System.setProperty(DNSUtils.OVERRIDE_DNS_PROPERTY, "dns://"+hostIP+":553"); } From 5b890d8ae88c666abd8a2a687efd14066fe7abd3 Mon Sep 17 00:00:00 2001 From: James Nord Date: Tue, 6 Aug 2024 17:55:28 +0100 Subject: [PATCH 14/15] leave a comment about the profiles --- pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pom.xml b/pom.xml index 8d139b72..356d5b92 100644 --- a/pom.xml +++ b/pom.xml @@ -163,6 +163,7 @@ onlyITs + @@ -181,6 +182,7 @@ + ITs true @@ -211,6 +213,7 @@ + onlyWindowsITs @@ -227,6 +230,7 @@ + WindowsITs From e7b692d493e2b9dedd13249261afb363e5f4b8b1 Mon Sep 17 00:00:00 2001 From: James Nord Date: Tue, 6 Aug 2024 17:55:49 +0100 Subject: [PATCH 15/15] be tollerant of IPv6 addresses --- .../plugins/active_directory/docker/TheFlintstonesIT.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java index cf66aa99..64e7ebc8 100644 --- a/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java +++ b/src/test/java/hudson/plugins/active_directory/docker/TheFlintstonesIT.java @@ -27,6 +27,7 @@ import static org.junit.Assert.assertEquals; import java.io.IOException; +import java.net.Inet6Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; @@ -96,7 +97,11 @@ public void overrideDNSServers() throws UnknownHostException { // we also need to set the JNDI default // see hudson.plugins.active_directory.ActiveDirectoryDomain.createDNSLookupContext() - System.setProperty(DNSUtils.OVERRIDE_DNS_PROPERTY, "dns://"+hostIP+":553"); + if (hostInetAddr instanceof Inet6Address) { + System.setProperty(DNSUtils.OVERRIDE_DNS_PROPERTY, "dns://["+hostIP+"]:553"); + } else { + System.setProperty(DNSUtils.OVERRIDE_DNS_PROPERTY, "dns://"+hostIP+":553"); + } } @After