Skip to content

Commit

Permalink
Enable Mail & Kafka test certificates to be regenerated for the docke…
Browse files Browse the repository at this point in the history
…r host name or ip address
  • Loading branch information
jamesnetherton committed Nov 23, 2023
1 parent 7eef399 commit 067d3cc
Show file tree
Hide file tree
Showing 12 changed files with 273 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@
*/
package org.apache.camel.quarkus.test.support.kafka;

import java.nio.file.Path;
import java.util.Optional;
import java.util.Properties;

import org.apache.kafka.clients.CommonClientConfigs;
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;
import org.testcontainers.DockerClientFactory;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.MountableFile;

public final class KafkaTestSupport {

Expand Down Expand Up @@ -55,4 +59,37 @@ public static void setKafkaConfigProperty(Properties props, String key) {
public static void setKafkaConfigFromProperty(Properties props, String key, String valueKey) {
props.put(key, getKafkaConfigValue(valueKey));
}

public static void regenerateCertificatesForDockerHost(
Path configDir,
String certificateScript,
String keyStoreFile,
String trustStoreFile) {
String dockerHost = DockerClientFactory.instance().dockerHostIpAddress();
if (!dockerHost.equals("localhost") && !dockerHost.equals("127.0.0.1")) {
// Run certificate generation in a container in case the target platform does not have prerequisites like OpenSSL installed (E.g on Windows)
String imageName = ConfigProvider.getConfig().getValue("eclipse-temurin.container.image", String.class);
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
container.withCreateContainerCmdModifier(modifier -> {
modifier.withEntrypoint("/bin/bash");
modifier.withStdinOpen(true);
});
container.setWorkingDirectory("/");
container.start();

String host = container.getHost();
container.copyFileToContainer(
MountableFile.forClasspathResource("config/" + certificateScript),
"/" + certificateScript);
container.execInContainer("/bin/bash", "/" + certificateScript, host,
"DNS:%s,IP:%s".formatted(host, host));
container.copyFileFromContainer("/" + keyStoreFile,
configDir.resolve(keyStoreFile).toString());
container.copyFileFromContainer("/" + trustStoreFile,
configDir.resolve(trustStoreFile).toString());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
25 changes: 8 additions & 17 deletions integration-tests/kafka-sasl-ssl/README.adoc
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
== Camel Quarkus Kafka SASL SSL integration tests

To regenerate the SSL key and trust stores, do the following:
To regenerate the SSL certificates and trust stores for use with local host testing run the following script:

[source,shell]
----
cd src/test/resources/config
rm -f *.p12
export SECRET=kafkas3cret
export JKS_FILE=kafka-keystore.jks
export JKS_TRUST_FILE=kafka-truststore.jks
export CERT_FILE=localhost.crt
export PKCS_FILE=kafka-keystore.p12
export PKCS_TRUST_FILE=kafka-truststore.p12
export PEM_FILE_CERT=kafka-cert.pem
export PEM_FILE_KEY=kafka-key.pem
./regenerate-certificates.sh
----

keytool -genkey -alias kafka-test-store -keyalg RSA -keystore ${JKS_FILE} -keysize 2048 -validity 3650 -dname CN=localhost -keypass ${SECRET} -storepass ${SECRET}
keytool -export -alias kafka-test-store -file ${CERT_FILE} -keystore ${JKS_FILE} -keypass ${SECRET} -storepass ${SECRET}
keytool -importkeystore -srckeystore ${JKS_FILE} -srcstorepass ${SECRET} -destkeystore ${PKCS_FILE} -deststoretype PKCS12 -deststorepass ${SECRET}
keytool -keystore ${JKS_TRUST_FILE} -import -file ${CERT_FILE} -keypass ${SECRET} -storepass ${SECRET} -noprompt
keytool -importkeystore -srckeystore ${JKS_TRUST_FILE} -srcstorepass ${SECRET} -destkeystore ${PKCS_TRUST_FILE} -deststoretype PKCS12 -deststorepass ${SECRET}
If required, you can override the default certificate CN and SAN configuration by passing them as script arguments:

rm -f *.crt *.jks
[source,shell]
----
cd src/test/resources/config
./regenerate-certificates.sh "other-dns-or-ip" "DNS:another-dns,IP:192.168.1.150"
----
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import com.github.dockerjava.api.command.InspectContainerResponse;
import org.apache.camel.quarkus.test.support.kafka.KafkaTestResource;
import org.apache.camel.quarkus.test.support.kafka.KafkaTestSupport;
import org.apache.camel.util.CollectionHelper;
import org.apache.commons.io.FileUtils;
import org.testcontainers.containers.KafkaContainer;
Expand All @@ -41,12 +42,12 @@ public class KafkaSaslSslTestResource extends KafkaTestResource {
private static final String KAFKA_KEYSTORE_TYPE = "PKCS12";
private static final String KAFKA_SSL_CREDS_FILE = "broker-creds";
private static final String KAFKA_TRUSTSTORE_FILE = "kafka-truststore.p12";
private Path configDir;
private static final String KAFKA_CERTIFICATE_SCRIPT = "generate-certificates.sh";
private static Path configDir;
private SaslSslKafkaContainer container;

@Override
public Map<String, String> start() {
// Set up the SSL key / trust store directory
try {
configDir = Files.createTempDirectory("KafkaSaslSslTestResource-");
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Expand All @@ -62,6 +63,9 @@ public Map<String, String> start() {
throw new RuntimeException(e);
}

KafkaTestSupport.regenerateCertificatesForDockerHost(configDir, KAFKA_CERTIFICATE_SCRIPT, KAFKA_KEYSTORE_FILE,
KAFKA_TRUSTSTORE_FILE);

container = new SaslSslKafkaContainer(KAFKA_IMAGE_NAME);
container.start();

Expand Down Expand Up @@ -144,13 +148,15 @@ protected void containerIsStarting(InspectContainerResponse containerInfo, boole
MountableFile.forClasspathResource("config/kafka_server_jaas.conf"),
"/etc/kafka/kafka_server_jaas.conf");

copyFileToContainer(
MountableFile.forClasspathResource("config/" + KAFKA_KEYSTORE_FILE),
"/etc/kafka/secrets/" + KAFKA_KEYSTORE_FILE);

copyFileToContainer(
MountableFile.forClasspathResource("config/" + KAFKA_TRUSTSTORE_FILE),
"/etc/kafka/secrets/" + KAFKA_TRUSTSTORE_FILE);
Stream.of(KAFKA_KEYSTORE_FILE, KAFKA_TRUSTSTORE_FILE)
.forEach(keyStoreFile -> {
try {
copyFileToContainer(Transferable.of(Files.readAllBytes(configDir.resolve(keyStoreFile))),
"/etc/kafka/secrets/" + keyStoreFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
});

copyFileToContainer(
Transferable.of(KAFKA_KEYSTORE_PASSWORD.getBytes(StandardCharsets.UTF_8)),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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
#
# http://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.
#


rm -f *.p12

export CN=${1:-localhost}
export SUBJECT_ALT_NAMES=${2:-"DNS:localhost,IP:127.0.0.1"}
export SECRET=kafkas3cret
export JKS_FILE=kafka-keystore.jks
export JKS_TRUST_FILE=kafka-truststore.jks
export CERT_FILE=localhost.crt
export PKCS_FILE=kafka-keystore.p12
export PKCS_TRUST_FILE=kafka-truststore.p12
export PEM_FILE_CERT=kafka-cert.pem
export PEM_FILE_KEY=kafka-key.pem

keytool -genkey -alias kafka-test-store -keyalg RSA -keystore ${JKS_FILE} -keysize 2048 -validity 3650 -ext "san=${SUBJECT_ALT_NAMES}" -dname CN=${CN} -keypass ${SECRET} -storepass ${SECRET}
keytool -export -alias kafka-test-store -file ${CERT_FILE} -keystore ${JKS_FILE} -keypass ${SECRET} -storepass ${SECRET}
keytool -importkeystore -srckeystore ${JKS_FILE} -srcstorepass ${SECRET} -destkeystore ${PKCS_FILE} -deststoretype PKCS12 -deststorepass ${SECRET}
keytool -keystore ${JKS_TRUST_FILE} -import -file ${CERT_FILE} -keypass ${SECRET} -storepass ${SECRET} -noprompt
keytool -importkeystore -srckeystore ${JKS_TRUST_FILE} -srcstorepass ${SECRET} -destkeystore ${PKCS_TRUST_FILE} -deststoretype PKCS12 -deststorepass ${SECRET}

rm -f *.crt *.jks
25 changes: 8 additions & 17 deletions integration-tests/kafka-ssl/README.adoc
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
== Camel Quarkus Kafka SSL integration tests

To regenerate the SSL key and trust stores, do the following:
To regenerate the SSL certificates and trust stores for use with local host testing run the following script:

[source,shell]
----
cd src/test/resources/config
rm -f *.p12
export SECRET=kafkas3cret
export JKS_FILE=kafka-keystore.jks
export JKS_TRUST_FILE=kafka-truststore.jks
export CERT_FILE=localhost.crt
export PKCS_FILE=kafka-keystore.p12
export PKCS_TRUST_FILE=kafka-truststore.p12
export PEM_FILE_CERT=kafka-cert.pem
export PEM_FILE_KEY=kafka-key.pem
./regenerate-certificates.sh
----

keytool -genkey -alias kafka-test-store -keyalg RSA -keystore ${JKS_FILE} -keysize 2048 -validity 3650 -dname CN=localhost -keypass ${SECRET} -storepass ${SECRET}
keytool -export -alias kafka-test-store -file ${CERT_FILE} -keystore ${JKS_FILE} -keypass ${SECRET} -storepass ${SECRET}
keytool -importkeystore -srckeystore ${JKS_FILE} -srcstorepass ${SECRET} -destkeystore ${PKCS_FILE} -deststoretype PKCS12 -deststorepass ${SECRET}
keytool -keystore ${JKS_TRUST_FILE} -import -file ${CERT_FILE} -keypass ${SECRET} -storepass ${SECRET} -noprompt
keytool -importkeystore -srckeystore ${JKS_TRUST_FILE} -srcstorepass ${SECRET} -destkeystore ${PKCS_TRUST_FILE} -deststoretype PKCS12 -deststorepass ${SECRET}
If required, you can override the default certificate CN and SAN configuration by passing them as script arguments:

rm -f *.crt *.jks
[source,shell]
----
cd src/test/resources/config
./regenerate-certificates.sh "other-dns-or-ip" "DNS:another-dns,IP:192.168.1.150"
----
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@

import com.github.dockerjava.api.command.InspectContainerResponse;
import org.apache.camel.quarkus.test.support.kafka.KafkaTestResource;
import org.apache.camel.quarkus.test.support.kafka.KafkaTestSupport;
import org.apache.camel.util.CollectionHelper;
import org.apache.commons.io.FileUtils;
import org.apache.kafka.clients.CommonClientConfigs;
import org.testcontainers.containers.KafkaContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.images.builder.Transferable;
import org.testcontainers.utility.DockerImageName;
import org.testcontainers.utility.MountableFile;

public class KafkaSslTestResource extends KafkaTestResource {

Expand All @@ -42,12 +42,12 @@ public class KafkaSslTestResource extends KafkaTestResource {
private static final String KAFKA_KEYSTORE_TYPE = "PKCS12";
private static final String KAFKA_SSL_CREDS_FILE = "broker-creds";
private static final String KAFKA_TRUSTSTORE_FILE = "kafka-truststore.p12";
private Path configDir;
private static final String KAFKA_CERTIFICATE_SCRIPT = "generate-certificates.sh";
private static Path configDir;
private SSLKafkaContainer container;

@Override
public Map<String, String> start() {
// Set up the SSL key / trust store directory
try {
configDir = Files.createTempDirectory("KafkaSaslSslTestResource-");
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Expand All @@ -63,6 +63,9 @@ public Map<String, String> start() {
throw new RuntimeException(e);
}

KafkaTestSupport.regenerateCertificatesForDockerHost(configDir, KAFKA_CERTIFICATE_SCRIPT, KAFKA_KEYSTORE_FILE,
KAFKA_TRUSTSTORE_FILE);

container = new SSLKafkaContainer(KAFKA_IMAGE_NAME);
container.start();

Expand Down Expand Up @@ -133,13 +136,16 @@ protected void configure() {
@Override
protected void containerIsStarting(InspectContainerResponse containerInfo, boolean reused) {
super.containerIsStarting(containerInfo, reused);
copyFileToContainer(
MountableFile.forClasspathResource("config/" + KAFKA_KEYSTORE_FILE),
"/etc/kafka/secrets/" + KAFKA_KEYSTORE_FILE);

copyFileToContainer(
MountableFile.forClasspathResource("config/" + KAFKA_TRUSTSTORE_FILE),
"/etc/kafka/secrets/" + KAFKA_TRUSTSTORE_FILE);
Stream.of(KAFKA_KEYSTORE_FILE, KAFKA_TRUSTSTORE_FILE)
.forEach(keyStoreFile -> {
try {
copyFileToContainer(Transferable.of(Files.readAllBytes(configDir.resolve(keyStoreFile))),
"/etc/kafka/secrets/" + keyStoreFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
});

copyFileToContainer(
Transferable.of(KAFKA_KEYSTORE_PASSWORD.getBytes(StandardCharsets.UTF_8)),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You 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
#
# http://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.
#


rm -f *.p12

export CN=${1:-localhost}
export SUBJECT_ALT_NAMES=${2:-"DNS:localhost,IP:127.0.0.1"}
export SECRET=kafkas3cret
export JKS_FILE=kafka-keystore.jks
export JKS_TRUST_FILE=kafka-truststore.jks
export CERT_FILE=localhost.crt
export PKCS_FILE=kafka-keystore.p12
export PKCS_TRUST_FILE=kafka-truststore.p12
export PEM_FILE_CERT=kafka-cert.pem
export PEM_FILE_KEY=kafka-key.pem

keytool -genkey -alias kafka-test-store -keyalg RSA -keystore ${JKS_FILE} -keysize 2048 -validity 3650 -ext "san=${SUBJECT_ALT_NAMES}" -dname CN=${CN} -keypass ${SECRET} -storepass ${SECRET}
keytool -export -alias kafka-test-store -file ${CERT_FILE} -keystore ${JKS_FILE} -keypass ${SECRET} -storepass ${SECRET}
keytool -importkeystore -srckeystore ${JKS_FILE} -srcstorepass ${SECRET} -destkeystore ${PKCS_FILE} -deststoretype PKCS12 -deststorepass ${SECRET}
keytool -keystore ${JKS_TRUST_FILE} -import -file ${CERT_FILE} -keypass ${SECRET} -storepass ${SECRET} -noprompt
keytool -importkeystore -srckeystore ${JKS_TRUST_FILE} -srcstorepass ${SECRET} -destkeystore ${PKCS_TRUST_FILE} -deststoretype PKCS12 -deststorepass ${SECRET}

rm -f *.crt *.jks
17 changes: 17 additions & 0 deletions integration-tests/mail/README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
== Camel Quarkus Mail integration tests

To regenerate the SSL certificates and trust stores for use with local host testing run the following script:

[source,shell]
----
cd src/test/resources
./regenerate-certificates.sh
----

If required, you can override the default certificate CN and SAN configuration by passing them as script arguments:

[source,shell]
----
cd src/test/resources
./regenerate-certificates.sh "other-dns-or-ip" "DNS:another-dns,IP:192.168.1.150"
----
Loading

0 comments on commit 067d3cc

Please sign in to comment.