Skip to content

Commit

Permalink
Merge pull request #30302 from Sgitario/29999
Browse files Browse the repository at this point in the history
Add HTTPS port in generated containers by Kubernetes
  • Loading branch information
Sgitario authored Jan 26, 2023
2 parents 7dc5975 + b89fece commit a02a81a
Show file tree
Hide file tree
Showing 27 changed files with 193 additions and 94 deletions.
1 change: 1 addition & 0 deletions docs/src/main/asciidoc/deploying-to-kubernetes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,7 @@ To secure the incoming connections, Kubernetes allows enabling https://kubernete
[source]
----
quarkus.kubernetes.ingress.expose=true
quarkus.kubernetes.ingress.target-port=https
## Ingress TLS configuration:
quarkus.kubernetes.ingress.tls.my-secret.enabled=true
----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,8 @@ public void createLabels(KubernetesConfig config, BuildProducer<KubernetesLabelB
public List<ConfiguratorBuildItem> createConfigurators(KubernetesConfig config,
List<KubernetesPortBuildItem> ports) {
List<ConfiguratorBuildItem> result = new ArrayList<>();
KubernetesCommonHelper.combinePorts(ports, config).entrySet().forEach(e -> {
result.add(new ConfiguratorBuildItem(new AddPortToKubernetesConfig(e.getValue())));
});
KubernetesCommonHelper.combinePorts(ports, config).values()
.forEach(value -> result.add(new ConfiguratorBuildItem(new AddPortToKubernetesConfig(value))));
return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import static io.quarkus.kubernetes.deployment.Constants.*;

import java.util.Optional;
import java.util.function.Predicate;

import org.jboss.logging.Logger;
Expand All @@ -18,13 +17,9 @@ public class AddNodePortDecorator extends NamedResourceDecorator<ServiceSpecFlue
private static final Logger log = Logger.getLogger(AddNodePortDecorator.class);

private final int nodePort;
private final Optional<String> matchingPortName;
private final String matchingPortName;

public AddNodePortDecorator(String name, int nodePort) {
this(name, nodePort, Optional.empty());
}

public AddNodePortDecorator(String name, int nodePort, Optional<String> matchingPortName) {
public AddNodePortDecorator(String name, int nodePort, String matchingPortName) {
super(name);
if (nodePort < MIN_NODE_PORT_VALUE || nodePort > MAX_NODE_PORT_VALUE) {
log.info("Using a port outside of the " + MIN_NODE_PORT_VALUE + "-" + MAX_NODE_PORT_VALUE
Expand All @@ -37,18 +32,12 @@ public AddNodePortDecorator(String name, int nodePort, Optional<String> matching
@SuppressWarnings("unchecked")
@Override
public void andThenVisit(ServiceSpecFluent service, ObjectMeta resourceMeta) {
ServiceSpecFluent.PortsNested<?> editPort;
if (matchingPortName.isPresent()) {
editPort = service.editMatchingPort(new Predicate<ServicePortBuilder>() {
@Override
public boolean test(ServicePortBuilder servicePortBuilder) {
return (servicePortBuilder.hasName())
&& (servicePortBuilder.getName().equals(matchingPortName.get()));
}
});
} else {
editPort = service.editFirstPort();
}
ServiceSpecFluent.PortsNested<?> editPort = service.editMatchingPort(new Predicate<ServicePortBuilder>() {
@Override
public boolean test(ServicePortBuilder servicePortBuilder) {
return servicePortBuilder.hasName() && servicePortBuilder.getName().equals(matchingPortName);
}
});
editPort.withNodePort(nodePort);
editPort.endPort();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ public void visit(OpenshiftConfigFluent config) {
routeBuilder.withHost(routeConfig.host.get());
}

if (routeConfig.targetPort.isPresent()) {
routeBuilder.withTargetPort(routeConfig.targetPort.get());
}

routeBuilder.withTargetPort(routeConfig.targetPort);
routeBuilder.endRoute();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
package io.quarkus.kubernetes.deployment;

import static io.quarkus.kubernetes.deployment.Constants.DEFAULT_HTTP_PORT;
import static io.quarkus.kubernetes.deployment.Constants.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 All @@ -21,6 +20,7 @@

import io.dekorate.kubernetes.annotation.ServiceType;
import io.dekorate.kubernetes.config.EnvBuilder;
import io.dekorate.kubernetes.config.Port;
import io.dekorate.kubernetes.decorator.AddEnvVarDecorator;
import io.dekorate.kubernetes.decorator.ApplicationContainerDecorator;
import io.dekorate.kubernetes.decorator.ApplyImagePullPolicyDecorator;
Expand Down Expand Up @@ -75,10 +75,11 @@ public static List<DecoratorBuildItem> createDecorators(String clusterKind,

Optional<Project> project = KubernetesCommonHelper.createProject(applicationInfo, customProjectRoot, outputTarget,
packageConfig);
Optional<Port> port = KubernetesCommonHelper.getPort(ports, config);
result.addAll(KubernetesCommonHelper.createDecorators(project, clusterKind, name, config,
metricsConfiguration,
annotations, labels, command,
ports, livenessPath, readinessPath, roles, roleBindings));
port, livenessPath, readinessPath, roles, roleBindings));

image.ifPresent(i -> {
result.add(new DecoratorBuildItem(clusterKind, new ApplyContainerImageDecorator(name, i.getImage())));
Expand Down Expand Up @@ -106,17 +107,19 @@ public static List<DecoratorBuildItem> createDecorators(String clusterKind,
if (!nodeConfigPorts.isEmpty()) {
for (Map.Entry<String, PortConfig> entry : nodeConfigPorts) {
result.add(new DecoratorBuildItem(KUBERNETES,
new AddNodePortDecorator(name, entry.getValue().nodePort.getAsInt(), Optional.of(entry.getKey()))));
new AddNodePortDecorator(name, entry.getValue().nodePort.getAsInt(), entry.getKey())));
}
} else {
result.add(new DecoratorBuildItem(clusterKind, new AddNodePortDecorator(name, config.getNodePort()
.orElseGet(() -> getStablePortNumberInRange(name, MIN_NODE_PORT_VALUE, MAX_NODE_PORT_VALUE)))));
result.add(new DecoratorBuildItem(clusterKind,
new AddNodePortDecorator(name,
config.getNodePort().orElseGet(
() -> getStablePortNumberInRange(name, MIN_NODE_PORT_VALUE, MAX_NODE_PORT_VALUE)),
config.ingress.targetPort)));
}

//Probe port handling
Integer port = ports.stream().filter(p -> HTTP_PORT.equals(p.getName())).map(KubernetesPortBuildItem::getPort)
.findFirst().orElse(DEFAULT_HTTP_PORT);
result.add(new DecoratorBuildItem(clusterKind, new ApplyHttpGetActionPortDecorator(name, name, port)));
Integer portNumber = port.map(Port::getContainerPort).orElse(DEFAULT_HTTP_PORT);
result.add(new DecoratorBuildItem(clusterKind, new ApplyHttpGetActionPortDecorator(name, name, portNumber)));

// 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 @@ -29,6 +29,7 @@
import io.dekorate.knative.decorator.ApplyServiceAccountToRevisionSpecDecorator;
import io.dekorate.knative.decorator.ApplyTrafficDecorator;
import io.dekorate.kubernetes.config.EnvBuilder;
import io.dekorate.kubernetes.config.Port;
import io.dekorate.kubernetes.decorator.AddConfigMapDataDecorator;
import io.dekorate.kubernetes.decorator.AddConfigMapResourceProvidingDecorator;
import io.dekorate.kubernetes.decorator.AddEnvVarDecorator;
Expand Down Expand Up @@ -116,9 +117,12 @@ public void createLabels(KnativeConfig config, BuildProducer<KubernetesLabelBuil
@BuildStep
public List<ConfiguratorBuildItem> createConfigurators(KnativeConfig config, List<KubernetesPortBuildItem> ports) {
List<ConfiguratorBuildItem> result = new ArrayList<>();
KubernetesCommonHelper.combinePorts(ports, config).values().forEach(value -> {
result.add(new ConfiguratorBuildItem(new AddPortToKnativeConfig(value)));
});
KubernetesCommonHelper.combinePorts(ports, config).values()
.stream()
// At the moment, Knative only supports single port binding: https://github.com/knative/serving/issues/8471
.filter(p -> p.getName().equals("http"))
.findFirst()
.ifPresent(value -> result.add(new ConfiguratorBuildItem(new AddPortToKnativeConfig(value))));
return result;
}

Expand Down Expand Up @@ -151,9 +155,9 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
String name = ResourceNameUtil.getResourceName(config, applicationInfo);
Optional<Project> project = KubernetesCommonHelper.createProject(applicationInfo, customProjectRoot, outputTarget,
packageConfig);
result.addAll(KubernetesCommonHelper.createDecorators(project, KNATIVE, name, config, metricsConfiguration,
annotations,
labels, command, ports, livenessPath, readinessPath, roles, roleBindings));
Optional<Port> port = KubernetesCommonHelper.getPort(ports, config, "http");
result.addAll(KubernetesCommonHelper.createDecorators(project, KNATIVE, name, config, metricsConfiguration, annotations,
labels, command, port, livenessPath, readinessPath, roles, roleBindings));

image.ifPresent(i -> {
result.add(new DecoratorBuildItem(KNATIVE, new ApplyContainerImageDecorator(name, i.getImage())));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

package io.quarkus.kubernetes.deployment;

import static io.dekorate.kubernetes.decorator.AddServiceResourceDecorator.distinct;
import static io.quarkus.kubernetes.deployment.Constants.QUARKUS_ANNOTATIONS_BUILD_TIMESTAMP;
import static io.quarkus.kubernetes.deployment.Constants.QUARKUS_ANNOTATIONS_COMMIT_ID;
import static io.quarkus.kubernetes.deployment.Constants.QUARKUS_ANNOTATIONS_VCS_URL;
Expand Down Expand Up @@ -118,6 +119,23 @@ public static Optional<Project> createProject(ApplicationInfoBuildItem app,
}
}

/**
* Creates the configurator build items.
*/
public static Optional<Port> getPort(List<KubernetesPortBuildItem> ports, KubernetesConfig config) {
return getPort(ports, config, config.ingress.targetPort);
}

/**
* Creates the configurator build items.
*/
public static Optional<Port> getPort(List<KubernetesPortBuildItem> ports, PlatformConfiguration config, String targetPort) {
return combinePorts(ports, config).values().stream()
.filter(distinct(p -> p.getName()))
.filter(p -> p.getName().equals(targetPort))
.findFirst();
}

/**
* Creates the configurator build items.
*/
Expand Down Expand Up @@ -159,15 +177,15 @@ public static List<DecoratorBuildItem> createDecorators(Optional<Project> projec
List<KubernetesAnnotationBuildItem> annotations,
List<KubernetesLabelBuildItem> labels,
Optional<KubernetesCommandBuildItem> command,
List<KubernetesPortBuildItem> ports,
Optional<Port> port,
Optional<KubernetesHealthLivenessPathBuildItem> livenessProbePath,
Optional<KubernetesHealthReadinessPathBuildItem> readinessProbePath,
List<KubernetesRoleBuildItem> roles,
List<KubernetesRoleBindingBuildItem> roleBindings) {
List<DecoratorBuildItem> result = new ArrayList<>();

result.addAll(createLabelDecorators(project, target, name, config, labels));
result.addAll(createAnnotationDecorators(project, target, name, config, metricsConfiguration, annotations, ports));
result.addAll(createAnnotationDecorators(project, target, name, config, metricsConfiguration, annotations, port));
result.addAll(createPodDecorators(project, target, name, config));
result.addAll(createContainerDecorators(project, target, name, config));
result.addAll(createMountAndVolumeDecorators(project, target, name, config));
Expand All @@ -177,7 +195,7 @@ public static List<DecoratorBuildItem> createDecorators(Optional<Project> projec
result.addAll(createArgsDecorator(project, target, name, config, command));

//Handle Probes
if (!ports.isEmpty()) {
if (!port.isEmpty()) {
result.addAll(createProbeDecorators(name, target, config.getLivenessProbe(), config.getReadinessProbe(),
livenessProbePath, readinessProbePath));
}
Expand Down Expand Up @@ -606,7 +624,7 @@ private static List<DecoratorBuildItem> createAnnotationDecorators(Optional<Proj
PlatformConfiguration config,
Optional<MetricsCapabilityBuildItem> metricsConfiguration,
List<KubernetesAnnotationBuildItem> annotations,
List<KubernetesPortBuildItem> ports) {
Optional<Port> port) {
List<DecoratorBuildItem> result = new ArrayList<>();

annotations.forEach(a -> {
Expand Down Expand Up @@ -649,14 +667,14 @@ private static List<DecoratorBuildItem> createAnnotationDecorators(Optional<Proj
metricsConfiguration.ifPresent(m -> {
String path = m.metricsEndpoint();
String prefix = config.getPrometheusConfig().prefix;
if (!ports.isEmpty() && path != null) {
if (port.isPresent() && path != null) {
result.add(new DecoratorBuildItem(target, new AddAnnotationDecorator(name,
config.getPrometheusConfig().scrape.orElse(prefix + "/scrape"), "true",
PROMETHEUS_ANNOTATION_TARGETS)));
result.add(new DecoratorBuildItem(target, new AddAnnotationDecorator(name,
config.getPrometheusConfig().path.orElse(prefix + "/path"), path, PROMETHEUS_ANNOTATION_TARGETS)));
result.add(new DecoratorBuildItem(target, new AddAnnotationDecorator(name,
config.getPrometheusConfig().port.orElse(prefix + "/port"), "" + ports.get(0).getPort(),
config.getPrometheusConfig().port.orElse(prefix + "/port"), "" + port.get().getContainerPort(),
PROMETHEUS_ANNOTATION_TARGETS)));
result.add(new DecoratorBuildItem(target, new AddAnnotationDecorator(name,
config.getPrometheusConfig().scheme.orElse(prefix + "/scheme"), "http",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import static io.quarkus.kubernetes.deployment.Constants.DEFAULT_HTTP_PORT;
import static io.quarkus.kubernetes.deployment.Constants.DEFAULT_S2I_IMAGE_NAME;
import static io.quarkus.kubernetes.deployment.Constants.HTTP_PORT;
import static io.quarkus.kubernetes.deployment.Constants.OPENSHIFT;
import static io.quarkus.kubernetes.deployment.Constants.OPENSHIFT_APP_RUNTIME;
import static io.quarkus.kubernetes.deployment.Constants.QUARKUS;
Expand All @@ -21,6 +20,7 @@
import io.dekorate.kubernetes.config.EnvBuilder;
import io.dekorate.kubernetes.config.ImageConfiguration;
import io.dekorate.kubernetes.config.ImageConfigurationBuilder;
import io.dekorate.kubernetes.config.Port;
import io.dekorate.kubernetes.decorator.AddAnnotationDecorator;
import io.dekorate.kubernetes.decorator.AddEnvVarDecorator;
import io.dekorate.kubernetes.decorator.AddLabelDecorator;
Expand Down Expand Up @@ -197,10 +197,11 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic

Optional<Project> project = KubernetesCommonHelper.createProject(applicationInfo, customProjectRoot, outputTarget,
packageConfig);
Optional<Port> port = KubernetesCommonHelper.getPort(ports, config, config.route.targetPort);
result.addAll(KubernetesCommonHelper.createDecorators(project, OPENSHIFT, name, config,
metricsConfiguration,
annotations, labels, command,
ports, livenessPath, readinessPath, roles, roleBindings));
port, livenessPath, readinessPath, roles, roleBindings));

if (config.flavor == v3) {
//Openshift 3.x doesn't recognize 'app.kubernetes.io/name', it uses 'app' instead.
Expand Down Expand Up @@ -295,13 +296,13 @@ public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applic
// Service handling
result.add(new DecoratorBuildItem(OPENSHIFT, new ApplyServiceTypeDecorator(name, config.getServiceType().name())));
if ((config.getServiceType() == ServiceType.NodePort) && config.nodePort.isPresent()) {
result.add(new DecoratorBuildItem(OPENSHIFT, new AddNodePortDecorator(name, config.nodePort.getAsInt())));
result.add(new DecoratorBuildItem(OPENSHIFT,
new AddNodePortDecorator(name, config.nodePort.getAsInt(), config.route.targetPort)));
}

// Probe port handling
Integer port = ports.stream().filter(p -> HTTP_PORT.equals(p.getName())).map(KubernetesPortBuildItem::getPort)
.findFirst().orElse(DEFAULT_HTTP_PORT);
result.add(new DecoratorBuildItem(OPENSHIFT, new ApplyHttpGetActionPortDecorator(name, name, port)));
Integer portNumber = port.map(Port::getContainerPort).orElse(DEFAULT_HTTP_PORT);
result.add(new DecoratorBuildItem(OPENSHIFT, new ApplyHttpGetActionPortDecorator(name, name, portNumber)));

// Handle non-openshift builds
if (deploymentKind == DeploymentResourceKind.DeploymentConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ public class RouteConfig {

/**
* The target named port. If not provided, it will be deducted from the Service resource ports.
* Options are: "http" and "https".
*/
@ConfigItem
Optional<String> targetPort;
@ConfigItem(defaultValue = "http")
String targetPort;

/**
* Custom annotations to add to exposition (route or ingress) resources
Expand Down
Loading

0 comments on commit a02a81a

Please sign in to comment.