Skip to content

Commit

Permalink
Prevent generating duplicate Ingress paths rules
Browse files Browse the repository at this point in the history
  • Loading branch information
Sgitario committed Oct 25, 2022
1 parent 2dac352 commit 6fd0f46
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,8 @@
*/
package io.dekorate.kubernetes.decorator;

import static io.dekorate.kubernetes.decorator.AddServiceResourceDecorator.distinct;

import java.util.Arrays;
import java.util.Optional;

import io.dekorate.kubernetes.config.BaseConfig;
import io.dekorate.kubernetes.config.IngressRule;
import io.dekorate.kubernetes.config.Port;
import io.dekorate.utils.Strings;
Expand All @@ -38,27 +34,24 @@ public class AddIngressRuleDecorator extends NamedResourceDecorator<IngressSpecB
private static final String DEFAULT_PREFIX = "Prefix";
private static final String DEFAULT_PATH = "/";

private final BaseConfig config;
private final Optional<Port> defaultHostPort;
private final IngressRule rule;

public AddIngressRuleDecorator(BaseConfig config, IngressRule rule) {
super(config.getName());
this.config = config;
public AddIngressRuleDecorator(String name, Optional<Port> defaultHostPort, IngressRule rule) {
super(name);
this.defaultHostPort = defaultHostPort;
this.rule = rule;
}

@Override
public void andThenVisit(IngressSpecBuilder spec, ObjectMeta meta) {
Optional<Port> defaultHostPort = Arrays.asList(config.getPorts()).stream()
.filter(distinct(p -> p.getName()))
.findFirst();
if (!spec.hasMatchingRule(existingRule -> Strings.equals(rule.getHost(), existingRule.getHost()))) {
spec.addNewRule()
.withHost(rule.getHost())
.withNewHttp()
.addNewPath()
.withPathType(Strings.defaultIfEmpty(rule.getPathType(), DEFAULT_PREFIX))
.withPath(Strings.defaultIfEmpty(rule.getPath(), DEFAULT_PATH))
.withPathType(pathType())
.withPath(path())
.withNewBackend()
.withNewService()
.withName(serviceName())
Expand All @@ -77,6 +70,14 @@ private String serviceName() {
return Strings.defaultIfEmpty(rule.getServiceName(), name);
}

private String path() {
return Strings.defaultIfEmpty(rule.getPath(), defaultHostPort.map(p -> p.getPath()).orElse(DEFAULT_PATH));
}

private String pathType() {
return Strings.defaultIfEmpty(rule.getPathType(), DEFAULT_PREFIX);
}

private ServiceBackendPort createPort(Optional<Port> defaultHostPort) {
ServiceBackendPortBuilder builder = new ServiceBackendPortBuilder();
if (Strings.isNotNullOrEmpty(rule.getServicePortName())) {
Expand Down Expand Up @@ -111,20 +112,21 @@ public void visit(IngressRuleBuilder existingRule) {
if (!existingRule.hasHttp()) {
existingRule.withNewHttp()
.addNewPath()
.withPathType(Strings.defaultIfEmpty(rule.getPathType(), DEFAULT_PREFIX))
.withPath(Strings.defaultIfEmpty(rule.getPath(), DEFAULT_PATH))
.withPathType(pathType())
.withPath(path())
.withNewBackend()
.withNewService()
.withName(serviceName())
.withPort(createPort(defaultHostPort))
.endService()
.endBackend()
.endPath().endHttp();
} else if (existingRule.getHttp().getPaths().stream().noneMatch(p -> Strings.equals(p.getPath(), rule.getPath()))) {
} else if (existingRule.getHttp().getPaths().stream()
.noneMatch(p -> Strings.equals(p.getPath(), path()) && Strings.equals(p.getPathType(), pathType()))) {
existingRule.editHttp()
.addNewPath()
.withPathType(Strings.defaultIfEmpty(rule.getPathType(), DEFAULT_PREFIX))
.withPath(Strings.defaultIfEmpty(rule.getPath(), DEFAULT_PATH))
.withPathType(pathType())
.withPath(path())
.withNewBackend()
.withNewService()
.withName(serviceName())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/
package io.dekorate.kubernetes.manifest;

import static io.dekorate.kubernetes.decorator.AddServiceResourceDecorator.distinct;

import java.util.Arrays;
import java.util.Optional;

import io.dekorate.AbstractKubernetesManifestGenerator;
Expand All @@ -32,6 +35,7 @@
import io.dekorate.kubernetes.config.IngressRuleBuilder;
import io.dekorate.kubernetes.config.KubernetesConfig;
import io.dekorate.kubernetes.config.KubernetesConfigBuilder;
import io.dekorate.kubernetes.config.Port;
import io.dekorate.kubernetes.configurator.ApplyDeployToApplicationConfiguration;
import io.dekorate.kubernetes.decorator.AddCommitIdAnnotationDecorator;
import io.dekorate.kubernetes.decorator.AddIngressDecorator;
Expand Down Expand Up @@ -138,10 +142,14 @@ protected void addDecorators(String group, KubernetesConfig config) {
resourceRegistry.decorate(group, new AddServiceResourceDecorator(config));
}

Optional<Port> defaultHostPort = Arrays.asList(config.getPorts()).stream()
.filter(distinct(p -> p.getName()))
.findFirst();

Ports.getHttpPort(config).ifPresent(p -> {
resourceRegistry.decorate(group, new AddIngressDecorator(config, Labels.createLabelsAsMap(config, "Ingress")));
resourceRegistry.decorate(group,
new AddIngressRuleDecorator(config, new IngressRuleBuilder()
new AddIngressRuleDecorator(config.getName(), defaultHostPort, new IngressRuleBuilder()
.withHost(config.getIngress().getHost())
.withPath(p.getPath())
.withServicePortName(p.getName())
Expand All @@ -155,7 +163,7 @@ protected void addDecorators(String group, KubernetesConfig config) {

if (config.getIngress().getRules() != null) {
for (IngressRule ingressRule : config.getIngress().getRules()) {
resourceRegistry.decorate(group, new AddIngressRuleDecorator(config, ingressRule));
resourceRegistry.decorate(group, new AddIngressRuleDecorator(config.getName(), defaultHostPort, ingressRule));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package io.dekorate.annotationless;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
Expand Down Expand Up @@ -44,6 +45,8 @@ public void shouldHaveMatchingPath() {
assertNotNull(c);
assertTrue(c.getPorts().stream().filter(p -> "http".equals(p.getName())).findAny().isPresent());
Ingress i = findFirst(list, Ingress.class).orElseThrow(() -> new IllegalStateException());
assertEquals(1, i.getSpec().getRules().size());
assertEquals(1, i.getSpec().getRules().get(0).getHttp().getPaths().size());
assertTrue(i.getSpec().getRules().stream().flatMap(r -> r.getHttp().getPaths().stream())
.anyMatch(p -> p.getPath().equals("/app")));
}
Expand Down

0 comments on commit 6fd0f46

Please sign in to comment.