Skip to content

Commit 137bb83

Browse files
iocanelxumk
authored andcommitted
refactor: Split KubernetesProcessor into pieces
1 parent ba679bb commit 137bb83

File tree

22 files changed

+1200
-822
lines changed

22 files changed

+1200
-822
lines changed

extensions/container-image/spi/src/main/java/io/quarkus/container/spi/ContainerImageInfoBuildItem.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,8 @@ public Set<String> getAdditionalTags() {
7575
public String getRepository() {
7676
return repository;
7777
}
78+
79+
public String getGroup() {
80+
return repository == null ? null : repository.split("/")[0];
81+
}
7882
}
Lines changed: 156 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,170 @@
11
package io.quarkus.minikube.deployment;
22

3+
import static io.quarkus.kubernetes.deployment.Constants.DEFAULT_HTTP_PORT;
34
import static io.quarkus.kubernetes.deployment.Constants.DEPLOYMENT;
5+
import static io.quarkus.kubernetes.deployment.Constants.HTTP_PORT;
6+
import static io.quarkus.kubernetes.deployment.Constants.KUBERNETES;
7+
import static io.quarkus.kubernetes.deployment.Constants.MAX_NODE_PORT_VALUE;
8+
import static io.quarkus.kubernetes.deployment.Constants.MAX_PORT_NUMBER;
49
import static io.quarkus.kubernetes.deployment.Constants.MINIKUBE;
10+
import static io.quarkus.kubernetes.deployment.Constants.MIN_NODE_PORT_VALUE;
11+
import static io.quarkus.kubernetes.deployment.Constants.MIN_PORT_NUMBER;
12+
import static io.quarkus.kubernetes.spi.KubernetesDeploymentTargetBuildItem.DEFAULT_PRIORITY;
513

14+
import java.math.BigInteger;
15+
import java.nio.charset.StandardCharsets;
16+
import java.security.MessageDigest;
17+
import java.util.ArrayList;
18+
import java.util.List;
19+
import java.util.Optional;
20+
import java.util.stream.Stream;
21+
22+
import io.dekorate.kubernetes.annotation.ServiceType;
23+
import io.dekorate.kubernetes.config.EnvBuilder;
24+
import io.dekorate.kubernetes.decorator.AddEnvVarDecorator;
25+
import io.dekorate.kubernetes.decorator.ApplicationContainerDecorator;
26+
import io.dekorate.kubernetes.decorator.ApplyImagePullPolicyDecorator;
27+
import io.dekorate.project.Project;
28+
import io.quarkus.container.spi.BaseImageInfoBuildItem;
29+
import io.quarkus.container.spi.ContainerImageInfoBuildItem;
30+
import io.quarkus.container.spi.ContainerImageLabelBuildItem;
631
import io.quarkus.deployment.annotations.BuildProducer;
732
import io.quarkus.deployment.annotations.BuildStep;
33+
import io.quarkus.deployment.builditem.ApplicationInfoBuildItem;
34+
import io.quarkus.deployment.metrics.MetricsCapabilityBuildItem;
35+
import io.quarkus.deployment.pkg.PackageConfig;
36+
import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem;
37+
import io.quarkus.kubernetes.deployment.AddNodePortDecorator;
38+
import io.quarkus.kubernetes.deployment.ApplyContainerImageDecorator;
39+
import io.quarkus.kubernetes.deployment.ApplyHttpGetActionPortDecorator;
40+
import io.quarkus.kubernetes.deployment.ApplyServiceTypeDecorator;
41+
import io.quarkus.kubernetes.deployment.EnvConverter;
42+
import io.quarkus.kubernetes.deployment.KubernetesCommonHelper;
43+
import io.quarkus.kubernetes.deployment.KubernetesConfig;
44+
import io.quarkus.kubernetes.deployment.ResourceNameUtil;
45+
import io.quarkus.kubernetes.spi.ConfiguratorBuildItem;
46+
import io.quarkus.kubernetes.spi.DecoratorBuildItem;
47+
import io.quarkus.kubernetes.spi.KubernetesAnnotationBuildItem;
48+
import io.quarkus.kubernetes.spi.KubernetesCommandBuildItem;
849
import io.quarkus.kubernetes.spi.KubernetesDeploymentTargetBuildItem;
50+
import io.quarkus.kubernetes.spi.KubernetesEnvBuildItem;
51+
import io.quarkus.kubernetes.spi.KubernetesHealthLivenessPathBuildItem;
52+
import io.quarkus.kubernetes.spi.KubernetesHealthReadinessPathBuildItem;
53+
import io.quarkus.kubernetes.spi.KubernetesLabelBuildItem;
54+
import io.quarkus.kubernetes.spi.KubernetesPortBuildItem;
55+
import io.quarkus.kubernetes.spi.KubernetesRoleBindingBuildItem;
56+
import io.quarkus.kubernetes.spi.KubernetesRoleBuildItem;
957

1058
public class MinikubeProcessor {
1159

60+
public static final String DEFAULT_HASH_ALGORITHM = "SHA-256";
61+
private static final int MINIKUBE_PRIORITY = DEFAULT_PRIORITY + 20;
62+
63+
@BuildStep
64+
public void checkMinikube(BuildProducer<KubernetesDeploymentTargetBuildItem> deploymentTargets) {
65+
deploymentTargets.produce(new KubernetesDeploymentTargetBuildItem(MINIKUBE, DEPLOYMENT, MINIKUBE_PRIORITY, true));
66+
}
67+
68+
@BuildStep
69+
public void createAnnotations(KubernetesConfig config, BuildProducer<KubernetesAnnotationBuildItem> annotations) {
70+
config.getAnnotations().forEach((k, v) -> {
71+
annotations.produce(new KubernetesAnnotationBuildItem(k, v, MINIKUBE));
72+
});
73+
}
74+
1275
@BuildStep
13-
public void checkOpenshift(BuildProducer<KubernetesDeploymentTargetBuildItem> deploymentTargets) {
14-
deploymentTargets
15-
.produce(new KubernetesDeploymentTargetBuildItem(MINIKUBE, DEPLOYMENT, true));
76+
public void createLabels(KubernetesConfig config, BuildProducer<KubernetesLabelBuildItem> labels,
77+
BuildProducer<ContainerImageLabelBuildItem> imageLabels) {
78+
config.getLabels().forEach((k, v) -> {
79+
labels.produce(new KubernetesLabelBuildItem(k, v, MINIKUBE));
80+
imageLabels.produce(new ContainerImageLabelBuildItem(k, v));
81+
});
1682
}
83+
84+
@BuildStep
85+
public List<ConfiguratorBuildItem> createConfigurators(KubernetesConfig config, List<KubernetesPortBuildItem> ports) {
86+
List<ConfiguratorBuildItem> result = new ArrayList<>();
87+
result.addAll(KubernetesCommonHelper.createPlatformConfigurators(config));
88+
result.addAll(KubernetesCommonHelper.createGlobalConfigurators(ports));
89+
return result;
90+
91+
}
92+
93+
@BuildStep
94+
public List<DecoratorBuildItem> createDecorators(ApplicationInfoBuildItem applicationInfo,
95+
OutputTargetBuildItem outputTarget,
96+
KubernetesConfig config,
97+
PackageConfig packageConfig,
98+
Optional<MetricsCapabilityBuildItem> metricsConfiguration,
99+
List<KubernetesAnnotationBuildItem> annotations,
100+
List<KubernetesLabelBuildItem> labels,
101+
List<KubernetesEnvBuildItem> envs,
102+
Optional<BaseImageInfoBuildItem> baseImage,
103+
Optional<ContainerImageInfoBuildItem> image,
104+
Optional<KubernetesCommandBuildItem> command,
105+
List<KubernetesPortBuildItem> ports,
106+
Optional<KubernetesHealthLivenessPathBuildItem> livenessPath,
107+
Optional<KubernetesHealthReadinessPathBuildItem> readinessPath,
108+
List<KubernetesRoleBuildItem> roles,
109+
List<KubernetesRoleBindingBuildItem> roleBindings) {
110+
111+
List<DecoratorBuildItem> result = new ArrayList<>();
112+
String name = ResourceNameUtil.getResourceName(config, applicationInfo);
113+
114+
Project project = KubernetesCommonHelper.createProject(applicationInfo, outputTarget, packageConfig);
115+
result.addAll(KubernetesCommonHelper.createDecorators(project, MINIKUBE, name, config, metricsConfiguration,
116+
annotations, labels, command,
117+
ports, livenessPath, readinessPath, roles, roleBindings));
118+
119+
image.ifPresent(i -> {
120+
result.add(new DecoratorBuildItem(MINIKUBE, new ApplyContainerImageDecorator(name, i.getImage())));
121+
});
122+
123+
Stream.concat(config.convertToBuildItems().stream(),
124+
envs.stream().filter(e -> e.getTarget() == null || KUBERNETES.equals(e.getTarget()))).forEach(e -> {
125+
result.add(new DecoratorBuildItem(MINIKUBE,
126+
new AddEnvVarDecorator(ApplicationContainerDecorator.ANY, name, new EnvBuilder()
127+
.withName(EnvConverter.convertName(e.getName()))
128+
.withValue(e.getValue())
129+
.withSecret(e.getSecret())
130+
.withConfigmap(e.getConfigMap())
131+
.withField(e.getField())
132+
.build())));
133+
});
134+
135+
result.add(new DecoratorBuildItem(MINIKUBE, new ApplyImagePullPolicyDecorator(name, "IfNotPresent")));
136+
137+
//Service handling
138+
result.add(new DecoratorBuildItem(MINIKUBE, new ApplyServiceTypeDecorator(name, ServiceType.NodePort.name())));
139+
result.add(new DecoratorBuildItem(MINIKUBE, new AddNodePortDecorator(name, config.getNodePort()
140+
.orElseGet(() -> getStablePortNumberInRange(name, MIN_NODE_PORT_VALUE, MAX_NODE_PORT_VALUE)))));
141+
142+
//Probe port handling
143+
Integer port = ports.stream().filter(p -> HTTP_PORT.equals(p.getName())).map(KubernetesPortBuildItem::getPort)
144+
.findFirst().orElse(DEFAULT_HTTP_PORT);
145+
result.add(new DecoratorBuildItem(MINIKUBE, new ApplyHttpGetActionPortDecorator(port)));
146+
147+
return result;
148+
}
149+
150+
/**
151+
* Given a string, generate a port number within the supplied range
152+
* The output is always the same (between {@code min} and {@code max})
153+
* given the same input and it's useful when we need to generate a port number
154+
* which needs to stay the same but we don't care about the exact value
155+
*/
156+
private int getStablePortNumberInRange(String input, int min, int max) {
157+
if (min < MIN_PORT_NUMBER || max > MAX_PORT_NUMBER) {
158+
throw new IllegalArgumentException(
159+
String.format("Port number range must be within [%d-%d]", MIN_PORT_NUMBER, MAX_PORT_NUMBER));
160+
}
161+
162+
try {
163+
byte[] hash = MessageDigest.getInstance(DEFAULT_HASH_ALGORITHM).digest(input.getBytes(StandardCharsets.UTF_8));
164+
return min + new BigInteger(hash).mod(BigInteger.valueOf(max - min)).intValue();
165+
} catch (Exception e) {
166+
throw new RuntimeException("Unable to generate stable port number from input string: '" + input + "'", e);
167+
}
168+
}
169+
17170
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package io.quarkus.kubernetes.spi;
2+
3+
import java.util.Optional;
4+
5+
import io.quarkus.builder.item.MultiBuildItem;
6+
7+
/**
8+
* A build item that wraps around Configurator objects.
9+
* The purpose of those build items is influence the configuration that will be feed to the generator process.
10+
* Configurators are similar to decorators, but are applied to configuration instead of generated resources.
11+
*/
12+
public final class ConfiguratorBuildItem extends MultiBuildItem {
13+
14+
/**
15+
* The configurator
16+
*/
17+
private final Object configurator;
18+
19+
public ConfiguratorBuildItem(Object configurator) {
20+
this.configurator = configurator;
21+
}
22+
23+
public Object getConfigurator() {
24+
return this.configurator;
25+
}
26+
27+
public boolean matches(Class type) {
28+
return type.isInstance(configurator);
29+
30+
}
31+
32+
public <C> Optional<C> getConfigurator(Class<C> type) {
33+
if (matches(type)) {
34+
return Optional.<C> of((C) configurator);
35+
}
36+
return Optional.empty();
37+
}
38+
}

extensions/kubernetes/spi/src/main/java/io/quarkus/kubernetes/spi/DecoratorBuildItem.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55

66
import io.quarkus.builder.item.MultiBuildItem;
77

8+
/**
9+
* A build item that wraps around Decorator objects.
10+
* The purpose of those build items is to perform modification on the generated resources.
11+
*/
812
public final class DecoratorBuildItem extends MultiBuildItem {
913

1014
/**
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
package io.quarkus.kubernetes.deployment;
3+
4+
import io.dekorate.kubernetes.config.Configurator;
5+
import io.dekorate.kubernetes.config.ImageConfigurationFluent;
6+
7+
public class ApplyImageGroupConfigurator extends Configurator<ImageConfigurationFluent<?>> {
8+
9+
private final String group;
10+
11+
public ApplyImageGroupConfigurator(String group) {
12+
this.group = group;
13+
}
14+
15+
@Override
16+
public void visit(ImageConfigurationFluent<?> config) {
17+
config.withGroup(group);
18+
}
19+
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
package io.quarkus.kubernetes.deployment;
3+
4+
import io.dekorate.kubernetes.config.Configurator;
5+
import io.dekorate.kubernetes.config.ImageConfigurationFluent;
6+
7+
public class ApplyImageRegistryConfigurator extends Configurator<ImageConfigurationFluent<?>> {
8+
9+
private final String registry;
10+
11+
public ApplyImageRegistryConfigurator(String registry) {
12+
this.registry = registry;
13+
}
14+
15+
@Override
16+
public void visit(ImageConfigurationFluent<?> config) {
17+
config.withRegistry(registry);
18+
}
19+
}

extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/Constants.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
public final class Constants {
44

5-
static final String KUBERNETES = "kubernetes";
5+
public static final String KUBERNETES = "kubernetes";
66
public static final String MINIKUBE = "minikube";
77
public static final String DEPLOYMENT = "Deployment";
88
static final String DOCKER = "docker";
@@ -28,13 +28,13 @@ public final class Constants {
2828
static final String QUARKUS_ANNOTATIONS_VCS_URL = "app.quarkus.io/vcs-url";
2929
static final String QUARKUS_ANNOTATIONS_BUILD_TIMESTAMP = "app.quarkus.io/build-timestamp";
3030

31-
static final String HTTP_PORT = "http";
32-
static final int DEFAULT_HTTP_PORT = 8080;
31+
public static final String HTTP_PORT = "http";
32+
public static final int DEFAULT_HTTP_PORT = 8080;
3333

34-
static final int MIN_PORT_NUMBER = 1;
35-
static final int MAX_PORT_NUMBER = 65535;
36-
static final int MIN_NODE_PORT_VALUE = 30000;
37-
static final int MAX_NODE_PORT_VALUE = 31999;
34+
public static final int MIN_PORT_NUMBER = 1;
35+
public static final int MAX_PORT_NUMBER = 65535;
36+
public static final int MIN_NODE_PORT_VALUE = 30000;
37+
public static final int MAX_NODE_PORT_VALUE = 31999;
3838

3939
private Constants() {
4040
}

extensions/kubernetes/vanilla/deployment/src/main/java/io/quarkus/kubernetes/deployment/ContainerAdapter.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,7 @@ public static Container adapt(io.dekorate.kubernetes.config.Container container)
4444
builder.accept(new AddMountDecorator(mount));
4545
}
4646

47-
builder.accept(new ApplyImagePullPolicyDecorator(container.getImagePullPolicy()));
48-
47+
builder.accept(new ApplyImagePullPolicyDecorator(name, container.getImagePullPolicy()));
4948
builder.accept(new AddLivenessProbeDecorator(name, container.getLivenessProbe()));
5049
builder.accept(new AddReadinessProbeDecorator(name, container.getReadinessProbe()));
5150
return builder.build();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
package io.quarkus.kubernetes.deployment;
3+
4+
import io.dekorate.kubernetes.config.Configurator;
5+
import io.dekorate.s2i.config.S2iBuildConfigFluent;
6+
7+
public class DisableS2iConfigurator extends Configurator<S2iBuildConfigFluent<?>> {
8+
9+
@Override
10+
public void visit(S2iBuildConfigFluent<?> s2i) {
11+
s2i.withEnabled(false);
12+
}
13+
}

0 commit comments

Comments
 (0)