Skip to content

Commit

Permalink
Add ingress and rules fir kind/minikube clusters
Browse files Browse the repository at this point in the history
  • Loading branch information
mcruzdev committed Oct 4, 2024
1 parent aa37d5d commit 13cc3f5
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,6 @@ void externalizeInitTasks(
BuildProducer<KubernetesRoleBuildItem> roles,
BuildProducer<KubernetesRoleBindingBuildItem> roleBindings,
BuildProducer<KubernetesServiceAccountBuildItem> serviceAccount,

BuildProducer<DecoratorBuildItem> decorators) {
final String name = ResourceNameUtil.getResourceName(config, applicationInfo);
if (config.isExternalizeInit()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

package io.quarkus.kubernetes.deployment;

import static io.quarkus.kubernetes.deployment.Constants.INGRESS;
import static io.quarkus.kubernetes.deployment.Constants.KUBERNETES;
import static io.quarkus.kubernetes.deployment.Constants.LIVENESS_PROBE;
import static io.quarkus.kubernetes.deployment.Constants.MAX_NODE_PORT_VALUE;
Expand All @@ -23,8 +24,11 @@

import io.dekorate.kubernetes.annotation.ServiceType;
import io.dekorate.kubernetes.config.EnvBuilder;
import io.dekorate.kubernetes.config.IngressRuleBuilder;
import io.dekorate.kubernetes.config.Port;
import io.dekorate.kubernetes.decorator.AddAnnotationDecorator;
import io.dekorate.kubernetes.decorator.AddEnvVarDecorator;
import io.dekorate.kubernetes.decorator.AddIngressRuleDecorator;
import io.dekorate.kubernetes.decorator.ApplicationContainerDecorator;
import io.dekorate.kubernetes.decorator.ApplyImagePullPolicyDecorator;
import io.dekorate.project.Project;
Expand Down Expand Up @@ -153,6 +157,23 @@ public static List<DecoratorBuildItem> createDecorators(String clusterKind,
ports,
config.ports));

for (Map.Entry<String, String> annotation : config.getIngress().getAnnotations().entrySet()) {
result.add(new DecoratorBuildItem(clusterKind,
new AddAnnotationDecorator(name, annotation.getKey(), annotation.getValue(), INGRESS)));
}

for (IngressRuleConfig rule : config.ingress.rules.values()) {
result.add(new DecoratorBuildItem(clusterKind, new AddIngressRuleDecorator(name, port,
new IngressRuleBuilder()
.withHost(rule.host)
.withPath(rule.path)
.withPathType(rule.pathType)
.withServiceName(rule.serviceName.orElse(null))
.withServicePortName(rule.servicePortName.orElse(null))
.withServicePortNumber(rule.servicePortNumber.orElse(-1))
.build())));
}

// Handle init Containers
result.addAll(KubernetesCommonHelper.createInitContainerDecorators(clusterKind, name, initContainers, result));
result.addAll(KubernetesCommonHelper.createInitJobDecorators(clusterKind, name, jobs, result));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.kubernetes.deployment;

import java.util.Collections;
import java.util.Map;
import java.util.Optional;

Expand Down Expand Up @@ -54,4 +55,7 @@ public class IngressConfig {
@ConfigItem
Map<String, IngressRuleConfig> rules;

public Map<String, String> getAnnotations() {
return Collections.unmodifiableMap(annotations);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -643,4 +643,8 @@ public Map<String, InitTaskConfig> getInitTasks() {
public InitTaskConfig getInitTaskDefaults() {
return initTaskDefaults;
}

public IngressConfig getIngress() {
return ingress;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package io.quarkus.it.kubernetes;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

import java.io.IOException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

import org.assertj.core.api.SoftAssertions;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.networking.v1.Ingress;
import io.fabric8.kubernetes.api.model.networking.v1.IngressRule;
import io.quarkus.builder.Version;
import io.quarkus.maven.dependency.Dependency;
import io.quarkus.test.ProdBuildResults;
import io.quarkus.test.ProdModeTestResults;
import io.quarkus.test.QuarkusProdModeTest;

public class KubernetesWithKindIngress {

private static final String LOCALHOST = "localhost";
@RegisterExtension
static final QuarkusProdModeTest config = new QuarkusProdModeTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class))
.setApplicationName("kind-ingress")
.setApplicationVersion("0.1-SNAPSHOT")
.setLogFileName("k8s.log")
// Configuration provided by issue: https://github.com/quarkusio/quarkus/issues/42294
.overrideConfigKey("quarkus.kubernetes.ingress.expose", "true")
.overrideConfigKey("quarkus.kubernetes.ingress.annotations.\"nginx.ingress.kubernetes.io/rewrite-target\"", "/$2")
.overrideConfigKey("quarkus.kubernetes.ingress.rules.1.host", LOCALHOST)
.overrideConfigKey("quarkus.kubernetes.ingress.rules.1.path", "/game(/|$)(.*)")
.overrideConfigKey("quarkus.kubernetes.ingress.rules.1.path-type", "ImplementationSpecific")
.overrideConfigKey("quarkus.kubernetes.ingress.ingress-class-name", "Nginx")
.setForcedDependencies(Arrays.asList(
Dependency.of("io.quarkus", "quarkus-kind", Version.getVersion()),
Dependency.of("io.quarkus", "quarkus-kubernetes", Version.getVersion())));
private static final Logger log = LoggerFactory.getLogger(KubernetesWithKindIngress.class);

@ProdBuildResults
private ProdModeTestResults prodModeTestResults;

@Test
void shouldCreateKindResourcesWithIngressAnnotationsCorrectly() throws IOException {
final Path kubernetesFile = prodModeTestResults.getBuildDir().resolve("kubernetes").resolve("kind.yml");
List<HasMetadata> kubernetesList = DeserializationUtil.deserializeAsList(kubernetesFile);

SoftAssertions.assertSoftly(softly -> {
softly.assertThat(kubernetesList).filteredOn(k -> k.getKind().equals("Ingress"))
.singleElement().isInstanceOfSatisfying(Ingress.class, ingress -> {

softly.assertThat(ingress.getMetadata().getAnnotations())
.anySatisfy((key, value) -> {
assertThat(key).isEqualTo("nginx.ingress.kubernetes.io/rewrite-target");
assertThat(value).isEqualTo("/$2");
});

softly.assertThat(ingress.getSpec()).satisfies(spec -> {

softly.assertThat(spec.getIngressClassName()).isEqualTo("Nginx");

softly.assertThat(spec.getRules()).hasSize(2);

softly.assertThat(spec.getRules()).filteredOn(byLocalhost())
.singleElement()
.satisfies(rule -> {

softly.assertThat(rule.getHttp().getPaths()).hasSize(1);
softly.assertThat(rule.getHttp().getPaths().get(0)).satisfies(path -> {

softly.assertThat(path.getPathType()).isEqualTo("ImplementationSpecific");
softly.assertThat(path.getPath()).isEqualTo("/game(/|$)(.*)");
softly.assertThat(path.getBackend().getService().getPort().getName())
.isEqualTo("http");
softly.assertThat(path.getBackend().getService().getName())
.isEqualTo("kind-ingress");

});
});
});
});
});
}

private static Predicate<IngressRule> byLocalhost() {
return rule -> rule.getHost() != null && rule.getHost().equals(LOCALHOST);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package io.quarkus.it.kubernetes;

import static org.assertj.core.api.AssertionsForClassTypes.assertThat;

import java.io.IOException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

import org.assertj.core.api.SoftAssertions;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.networking.v1.Ingress;
import io.fabric8.kubernetes.api.model.networking.v1.IngressRule;
import io.quarkus.builder.Version;
import io.quarkus.maven.dependency.Dependency;
import io.quarkus.test.ProdBuildResults;
import io.quarkus.test.ProdModeTestResults;
import io.quarkus.test.QuarkusProdModeTest;

public class KubernetesWithMinikubeIngress {

private static final String LOCALHOST = "localhost";
@RegisterExtension
static final QuarkusProdModeTest config = new QuarkusProdModeTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class))
.setApplicationName("kind-ingress")
.setApplicationVersion("0.1-SNAPSHOT")
.setLogFileName("k8s.log")
// Configuration provided by issue: https://github.com/quarkusio/quarkus/issues/42294
.overrideConfigKey("quarkus.kubernetes.ingress.expose", "true")
.overrideConfigKey("quarkus.kubernetes.ingress.annotations.\"nginx.ingress.kubernetes.io/rewrite-target\"", "/$2")
.overrideConfigKey("quarkus.kubernetes.ingress.rules.1.host", LOCALHOST)
.overrideConfigKey("quarkus.kubernetes.ingress.rules.1.path", "/game(/|$)(.*)")
.overrideConfigKey("quarkus.kubernetes.ingress.rules.1.path-type", "ImplementationSpecific")
.overrideConfigKey("quarkus.kubernetes.ingress.ingress-class-name", "Nginx")
.setForcedDependencies(Arrays.asList(
Dependency.of("io.quarkus", "quarkus-minikube", Version.getVersion()),
Dependency.of("io.quarkus", "quarkus-kubernetes", Version.getVersion())));
private static final Logger log = LoggerFactory.getLogger(KubernetesWithMinikubeIngress.class);

@ProdBuildResults
private ProdModeTestResults prodModeTestResults;

@Test
void shouldCreateKindResourcesWithIngressAnnotationsCorrectly() throws IOException {
final Path kubernetesFile = prodModeTestResults.getBuildDir().resolve("kubernetes").resolve("minikube.yml");
List<HasMetadata> kubernetesList = DeserializationUtil.deserializeAsList(kubernetesFile);

SoftAssertions.assertSoftly(softly -> {
softly.assertThat(kubernetesList).filteredOn(k -> k.getKind().equals("Ingress"))
.singleElement().isInstanceOfSatisfying(Ingress.class, ingress -> {

softly.assertThat(ingress.getMetadata().getAnnotations())
.anySatisfy((key, value) -> {
assertThat(key).isEqualTo("nginx.ingress.kubernetes.io/rewrite-target");
assertThat(value).isEqualTo("/$2");
});

softly.assertThat(ingress.getSpec()).satisfies(spec -> {

softly.assertThat(spec.getIngressClassName()).isEqualTo("Nginx");

softly.assertThat(spec.getRules()).hasSize(2);

softly.assertThat(spec.getRules()).filteredOn(byLocalhost())
.singleElement()
.satisfies(rule -> {

softly.assertThat(rule.getHttp().getPaths()).hasSize(1);
softly.assertThat(rule.getHttp().getPaths().get(0)).satisfies(path -> {

softly.assertThat(path.getPathType()).isEqualTo("ImplementationSpecific");
softly.assertThat(path.getPath()).isEqualTo("/game(/|$)(.*)");
softly.assertThat(path.getBackend().getService().getPort().getName())
.isEqualTo("http");
softly.assertThat(path.getBackend().getService().getName())
.isEqualTo("kind-ingress");

});
});
});
});
});
}

private static Predicate<IngressRule> byLocalhost() {
return rule -> rule.getHost() != null && rule.getHost().equals(LOCALHOST);
}
}

0 comments on commit 13cc3f5

Please sign in to comment.