Skip to content

Commit

Permalink
fix: workaround decorator ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
iocanel committed Feb 15, 2023
1 parent 5145dd1 commit 21e6b56
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import io.quarkus.kubernetes.spi.KubernetesJobBuildItem;
import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem;
import io.quarkus.kubernetes.spi.KubernetesPortBuildItem;
import io.quarkus.kubernetes.spi.KubernetesProbePortNameBuildItem;
import io.quarkus.kubernetes.spi.KubernetesResourceMetadataBuildItem;
import io.quarkus.kubernetes.spi.KubernetesRoleBindingBuildItem;
import io.quarkus.kubernetes.spi.KubernetesRoleBuildItem;
Expand Down Expand Up @@ -104,6 +105,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
Optional<ContainerImageInfoBuildItem> image,
Optional<KubernetesCommandBuildItem> command,
List<KubernetesPortBuildItem> ports,
Optional<KubernetesProbePortNameBuildItem> portName,
Optional<KubernetesHealthLivenessPathBuildItem> livenessPath,
Optional<KubernetesHealthReadinessPathBuildItem> readinessPath,
List<KubernetesRoleBuildItem> roles,
Expand All @@ -112,6 +114,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic

return DevClusterHelper.createDecorators(KIND, applicationInfo, outputTarget, config, packageConfig,
metricsConfiguration, initContainers, jobs, annotations, labels, envs, baseImage, image, command, ports,
portName,
livenessPath,
readinessPath,
roles, roleBindings, customProjectRoot);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import io.quarkus.kubernetes.spi.KubernetesJobBuildItem;
import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem;
import io.quarkus.kubernetes.spi.KubernetesPortBuildItem;
import io.quarkus.kubernetes.spi.KubernetesProbePortNameBuildItem;
import io.quarkus.kubernetes.spi.KubernetesResourceMetadataBuildItem;
import io.quarkus.kubernetes.spi.KubernetesRoleBindingBuildItem;
import io.quarkus.kubernetes.spi.KubernetesRoleBuildItem;
Expand Down Expand Up @@ -100,6 +101,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
Optional<ContainerImageInfoBuildItem> image,
Optional<KubernetesCommandBuildItem> command,
List<KubernetesPortBuildItem> ports,
Optional<KubernetesProbePortNameBuildItem> portName,
Optional<KubernetesHealthLivenessPathBuildItem> livenessPath,
Optional<KubernetesHealthReadinessPathBuildItem> readinessPath,
List<KubernetesRoleBuildItem> roles,
Expand All @@ -108,6 +110,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic

return DevClusterHelper.createDecorators(MINIKUBE, applicationInfo, outputTarget, config, packageConfig,
metricsConfiguration, initContainers, jobs, annotations, labels, envs, baseImage, image, command, ports,
portName,
livenessPath,
readinessPath,
roles, roleBindings, customProjectRoot);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,89 @@

package io.quarkus.kubernetes.deployment;

import static io.dekorate.utils.Metadata.getMetadata;

import java.util.List;
import java.util.Map;
import java.util.Optional;

import io.dekorate.kubernetes.decorator.AddLivenessProbeDecorator;
import io.dekorate.kubernetes.decorator.AddReadinessProbeDecorator;
import io.dekorate.kubernetes.decorator.AddSidecarDecorator;
import io.dekorate.kubernetes.decorator.ApplicationContainerDecorator;
import io.dekorate.kubernetes.decorator.Decorator;
import io.dekorate.kubernetes.decorator.ResourceProvidingDecorator;
import io.fabric8.kubernetes.api.builder.Builder;
import io.fabric8.kubernetes.api.model.ContainerBuilder;
import io.fabric8.kubernetes.api.model.HTTPGetActionFluent;

public class ApplyHttpGetActionPortDecorator extends ApplicationContainerDecorator<HTTPGetActionFluent<?>> {
public class ApplyHttpGetActionPortDecorator extends Decorator<HTTPGetActionFluent<?>> {

private final String deployment;
private final String container;
private final Integer port;
private final String probeKind;

public ApplyHttpGetActionPortDecorator(Integer port) {
this(ANY, ANY, port);
this(ANY, ANY, port, ANY);
}

public ApplyHttpGetActionPortDecorator(Integer port, String probeKind) {
this(ANY, ANY, port, probeKind);
}

public ApplyHttpGetActionPortDecorator(String deployment, Integer port) {
this(deployment, ANY, port);
this(deployment, ANY, port, ANY);
}

public ApplyHttpGetActionPortDecorator(String deployment, Integer port, String probeKind) {
this(deployment, ANY, port, probeKind);
}

public ApplyHttpGetActionPortDecorator(String deployment, String container, Integer port) {
super(deployment, container);
this(deployment, container, port, ANY);
}

public ApplyHttpGetActionPortDecorator(String deployment, String container, Integer port, String probeKind) {
this.deployment = deployment;
this.container = container;
this.port = port;
this.probeKind = probeKind;
}

@Override
public void visit(List<Map.Entry<String, Object>> path, HTTPGetActionFluent<?> action) {
boolean inMatchingProbe = probeKind == ANY || path.stream().map(e -> e.getKey()).anyMatch(i -> i.equals(probeKind));
if (!inMatchingProbe) {
return;
}

boolean inMatchingContainer = container == ANY || path.stream()
.map(e -> e.getValue())
.filter(v -> v instanceof ContainerBuilder)
.map(v -> (ContainerBuilder) v)
.anyMatch(c -> c.getName() != null && c.getName().equals(container));

if (!inMatchingContainer) {
return;
}

boolean inMatchingResource = deployment == ANY || path.stream()
.map(e -> e.getValue())
.filter(v -> v instanceof Builder)
.map(v -> (Builder) v)
.map(b -> getMetadata(b))
.filter(m -> m.isPresent())
.map(Optional::get)
.anyMatch(m -> m.getName() != null && m.getName().equals(deployment));

if (!inMatchingResource) {
return;
}

visit(action);
}

@Override
public void andThenVisit(HTTPGetActionFluent<?> action) {
public void visit(HTTPGetActionFluent<?> action) {
if (port == null) {
// workaround to make sure we don't get a NPE
action.withNewPort((String) null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ public ChangeDeploymentTriggerDecorator(String containerName, String imageStream
public Class<? extends Decorator>[] after() {
return new Class[] { ApplyDeploymentTriggerDecorator.class, RemoveDeploymentTriggerDecorator.class };
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

package io.quarkus.kubernetes.deployment;

import static io.quarkus.kubernetes.deployment.Constants.DEFAULT_HTTP_PORT;
import static io.quarkus.kubernetes.deployment.Constants.KUBERNETES;
import static io.quarkus.kubernetes.deployment.Constants.MAX_NODE_PORT_VALUE;
import static io.quarkus.kubernetes.deployment.Constants.MAX_PORT_NUMBER;
Expand Down Expand Up @@ -42,6 +41,7 @@
import io.quarkus.kubernetes.spi.KubernetesJobBuildItem;
import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem;
import io.quarkus.kubernetes.spi.KubernetesPortBuildItem;
import io.quarkus.kubernetes.spi.KubernetesProbePortNameBuildItem;
import io.quarkus.kubernetes.spi.KubernetesRoleBindingBuildItem;
import io.quarkus.kubernetes.spi.KubernetesRoleBuildItem;

Expand All @@ -64,6 +64,7 @@ public static List<DecoratorBuildItem> createDecorators(String clusterKind,
Optional<ContainerImageInfoBuildItem> image,
Optional<KubernetesCommandBuildItem> command,
List<KubernetesPortBuildItem> ports,
Optional<KubernetesProbePortNameBuildItem> portName,
Optional<KubernetesHealthLivenessPathBuildItem> livenessPath,
Optional<KubernetesHealthReadinessPathBuildItem> readinessPath,
List<KubernetesRoleBuildItem> roles,
Expand Down Expand Up @@ -118,8 +119,14 @@ public static List<DecoratorBuildItem> createDecorators(String clusterKind,
}

//Probe port handling
Integer portNumber = port.map(Port::getContainerPort).orElse(DEFAULT_HTTP_PORT);
result.add(new DecoratorBuildItem(clusterKind, new ApplyHttpGetActionPortDecorator(name, name, portNumber)));
result.add(
KubernetesCommonHelper.createProbeHttpPortDecorator(name, clusterKind, "livenessProbe", config.livenessProbe,
portName,
ports));
result.add(
KubernetesCommonHelper.createProbeHttpPortDecorator(name, clusterKind, "readinessProbe", config.readinessProbe,
portName,
ports));

// Handle init Containers
result.addAll(KubernetesCommonHelper.createInitContainerDecorators(clusterKind, name, initContainers, result));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
result.add(new DecoratorBuildItem(KNATIVE, new ApplyServiceTypeDecorator(name, config.getServiceType().name())));

//In Knative its expected that all http ports in probe are omitted (so we set them to null).
result.add(new DecoratorBuildItem(KNATIVE, new ApplyHttpGetActionPortDecorator(name, null)));
result.add(new DecoratorBuildItem(KNATIVE, new ApplyHttpGetActionPortDecorator(name, (Integer) null)));

//Traffic Splitting
config.revisionName.ifPresent(r -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -698,9 +698,15 @@ private static List<DecoratorBuildItem> createAnnotationDecorators(Optional<Proj
* 3. if a `KubernetesPorbePortBuild` is set, then use that to lookup the port.
* 4. if we still haven't found a port fallback to 8080.
*
* @param name The name of the deployment / container.
* @param target The deployment target
* @param the probe kind (e.g. readinessProbe, livenessProbe etc)
* @param portName the probe port name build item
* @paramt ports a list of kubernetes port build items
* @return a decorator for configures the port of the http action of the probe.
*/
public static DecoratorBuildItem createProbeHttpPortDecorator(String name, String target, ProbeConfig probeConfig,
public static DecoratorBuildItem createProbeHttpPortDecorator(String name, String target, String probeKind,
ProbeConfig probeConfig,
Optional<KubernetesProbePortNameBuildItem> portName,
List<KubernetesPortBuildItem> ports) {

Expand All @@ -714,7 +720,7 @@ public static DecoratorBuildItem createProbeHttpPortDecorator(String name, Strin
Integer port = probeConfig.httpActionPort
.orElse(ports.stream().filter(p -> httpPortName.equals(p.getName()))
.map(KubernetesPortBuildItem::getPort).findFirst().orElse(DEFAULT_HTTP_PORT));
return new DecoratorBuildItem(target, new ApplyHttpGetActionPortDecorator(name, name, port));
return new DecoratorBuildItem(target, new ApplyHttpGetActionPortDecorator(name, name, port, probeKind));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,13 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
}

// Probe port handling
result.add(KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, config.livenessProbe, portName, ports));
result.add(KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, "livenssProbe", config.livenessProbe,
portName,
ports));
result.add(
KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, config.readinessProbe, portName, ports));
KubernetesCommonHelper.createProbeHttpPortDecorator(name, OPENSHIFT, "readinessProbe", config.readinessProbe,
portName,
ports));

// Handle non-openshift builds
if (deploymentKind == DeploymentResourceKind.DeploymentConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ public void andThenVisit(DeploymentConfigSpecFluent<?> deploymentConfigSpec, Obj
}

@Override
public Class<? extends Decorator>[] after() {
return new Class[] { ApplyDeploymentTriggerDecorator.class };
public Class<? extends Decorator>[] before() {
return new Class[] { ChangeDeploymentTriggerDecorator.class };
}

@Override
public Class<? extends Decorator>[] before() {
return new Class[] { ChangeDeploymentTriggerDecorator.class };
public Class<? extends Decorator>[] after() {
return new Class[] { ApplyDeploymentTriggerDecorator.class };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -243,9 +243,13 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic

// Probe port handling
result.add(
KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, config.livenessProbe, portName, ports));
KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, "livenessProbe", config.livenessProbe,
portName,
ports));
result.add(
KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, config.readinessProbe, portName, ports));
KubernetesCommonHelper.createProbeHttpPortDecorator(name, KUBERNETES, "readinessProbe", config.readinessProbe,
portName,
ports));

// Handle remote debug configuration
if (config.remoteDebug.enabled) {
Expand Down Expand Up @@ -277,5 +281,4 @@ void externalizeInitTasks(
decorators);
}
}

}

0 comments on commit 21e6b56

Please sign in to comment.