Skip to content
This repository has been archived by the owner on Jun 19, 2024. It is now read-only.

Commit

Permalink
Improve support for sidecar containers (#1202)
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolaferraro authored and lordofthejars committed Mar 13, 2019
1 parent f832592 commit 3a640a4
Show file tree
Hide file tree
Showing 21 changed files with 850 additions and 51 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ After this we will switch probably to real [Semantic Versioning 2.0.0](http://se
* Refactor 678: Enricher Workflow to allow direct generation of OpenShift objects.
* Refactor 802: Remove resource object post processing.
* Feature 729: Select custom resources depending on environment.
* Feature 968: Improved support for sidecar containers with sidecar auto-detection and targeted health checks
* Feature 601: Adds healthcheck for webapp
* Fix 1460: Upgraded kubernetes client to 4.1.1
* Fix 690: Removes deprecated _legacyPortMapping_ property.
Expand Down Expand Up @@ -58,6 +59,7 @@ After this we will switch probably to real [Semantic Versioning 2.0.0](http://se
### 3.5-SNAPSHOT
* Fix 1390: Provides better exception message in case of invalid `application.yml` in Spring Boot
* Fix 1382: Allow to provide additional fragment filename mappings
* Fix 918: Sanitize Maven project names when artifactId starts with a number

### 4.0.0-M1 (2018-11-09)
* Feature: Move to Java 1.8 as minimal requirement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ public class DeploymentConfigHandler {
}

public DeploymentConfig getDeploymentConfig(ResourceConfig config,
List<ImageConfiguration> images, Long openshiftDeployTimeoutSeconds, Boolean imageChangeTrigger, Boolean enableAutomaticTrigger, PlatformMode platformMode) {
List<ImageConfiguration> images, Long openshiftDeployTimeoutSeconds, Boolean imageChangeTrigger, Boolean enableAutomaticTrigger, Boolean isOpenshiftBuildStrategy) {

DeploymentConfig deploymentConfig = new DeploymentConfigBuilder()
.withMetadata(createDeploymentConfigMetaData(config))
.withSpec(createDeploymentConfigSpec(config, images, openshiftDeployTimeoutSeconds, imageChangeTrigger, enableAutomaticTrigger, platformMode))
.withSpec(createDeploymentConfigSpec(config, images, openshiftDeployTimeoutSeconds, imageChangeTrigger, enableAutomaticTrigger, isOpenshiftBuildStrategy))
.build();

return deploymentConfig;
Expand All @@ -60,7 +60,7 @@ private ObjectMeta createDeploymentConfigMetaData(ResourceConfig config) {
.build();
}

private DeploymentConfigSpec createDeploymentConfigSpec(ResourceConfig config, List<ImageConfiguration> images, Long openshiftDeployTimeoutSeconds, Boolean imageChangeTrigger, Boolean enableAutomaticTrigger, PlatformMode platformMode) {
private DeploymentConfigSpec createDeploymentConfigSpec(ResourceConfig config, List<ImageConfiguration> images, Long openshiftDeployTimeoutSeconds, Boolean imageChangeTrigger, Boolean enableAutomaticTrigger, Boolean isOpenshiftBuildStrategy) {
DeploymentConfigSpecBuilder specBuilder = new DeploymentConfigSpecBuilder();

PodTemplateSpec podTemplateSpec = podTemplateHandler.getPodTemplate(config,images);
Expand All @@ -80,7 +80,7 @@ private DeploymentConfigSpec createDeploymentConfigSpec(ResourceConfig config, L
}

// add a new image change trigger for the build stream
if (containerToImageMap.size() != 0 && imageChangeTrigger) {
if (containerToImageMap.size() != 0 && imageChangeTrigger && isOpenshiftBuildStrategy) {
for (Map.Entry<String, String> entry : containerToImageMap.entrySet()) {
String containerName = entry.getKey();
ImageName image = new ImageName(entry.getValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -653,12 +653,16 @@ public static void mergePodSpec(PodSpecBuilder builder, PodSpec defaultPodSpec,
if (containers == null || containers.isEmpty()) {
builder.addToContainers(defaultContainers.toArray(new Container[size]));
} else {
int idx = 0;
for (Container defaultContainer : defaultContainers) {
Container container;
if (idx < containers.size()) {
container = containers.get(idx);
} else {
Container container = null;
for (Container fragmentContainer : containers) {
if (fragmentContainer.getName() == null || fragmentContainer.getName().equals(defaultContainer.getName())) {
container = fragmentContainer;
break;
}
}

if (container == null) {
container = new Container();
containers.add(container);
}
Expand All @@ -684,15 +688,16 @@ public static void mergePodSpec(PodSpecBuilder builder, PodSpec defaultPodSpec,
if (container.getSecurityContext() == null) {
container.setSecurityContext(defaultContainer.getSecurityContext());
}
idx++;
}
builder.withContainers(containers);
}
} else if (!containers.isEmpty()) {
// lets default the container name if there's none specified in the custom yaml file
Container container = containers.get(0);
if (StringUtils.isBlank(container.getName())) {
container.setName(defaultName);
for (Container container : containers) {
if (StringUtils.isBlank(container.getName())) {
container.setName(defaultName);
break; // do it for one container only, but not necessarily the first one
}
}
builder.withContainers(containers);
}
Expand Down
2 changes: 1 addition & 1 deletion doc/src/main/asciidoc/inc/_enricher.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1172,4 +1172,4 @@ This creates a `Secret` data with the key `application.properties` (part defined

== Enricher API

_howto write your own enricher and install them_
_howto write your own enricher and install them_
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public abstract class BaseEnricher implements Enricher {

private final EnricherConfig config;
private final String name;
private EnricherContext enricherContext;
protected EnricherContext enricherContext;

protected Logger log;

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

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import io.fabric8.maven.core.model.Configuration;
import io.fabric8.maven.core.model.Dependency;
Expand Down Expand Up @@ -46,6 +47,11 @@ public interface EnricherContext {
*/
Configuration getConfiguration();


Map<String, String> getProcessingInstructions();

void setProcessingInstructions(Map<String, String> instructions);

/**
* Base directory of the project. E.g. for Maven that's the directory
* where the pom.xml is placed in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public class MavenEnricherContext implements EnricherContext {

private Settings settings;

private Map<String, String> processingInstruction;

private MavenProject project;
private Logger log;

Expand All @@ -75,6 +77,14 @@ public Settings getSettings() {
return settings;
}

public Map<String, String> getProcessingInstructions() {
return processingInstruction;
}

public void setProcessingInstructions(Map<String, String> instruction) {
this.processingInstruction = instruction;
}

@Override
public Logger getLog() {
return log;
Expand Down Expand Up @@ -132,7 +142,7 @@ public ProjectClassLoaders getProjectClassLoaders() {

@Override
public Object getProperty(String key) {
return properties.getProperty(key);
return properties != null ? properties.getProperty(key) : null;
}

// ========================================================================
Expand Down Expand Up @@ -232,6 +242,11 @@ public Builder properties(Properties properties) {
return this;
}

public Builder processingInstructions(Map<String, String> pi) {
ctx.processingInstruction = pi;
return this;
}

public MavenEnricherContext build() {
ctx.configuration =
new Configuration.Builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,41 +21,57 @@
import io.fabric8.kubernetes.api.model.KubernetesListBuilder;
import io.fabric8.kubernetes.api.model.Probe;
import io.fabric8.maven.core.config.PlatformMode;
import io.fabric8.maven.core.util.Configs;
import io.fabric8.maven.enricher.api.BaseEnricher;
import io.fabric8.maven.enricher.api.MavenEnricherContext;
import io.fabric8.maven.enricher.api.EnricherContext;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

/**
* Enriches containers with health check probes.
*/
public abstract class AbstractHealthCheckEnricher extends BaseEnricher {

public AbstractHealthCheckEnricher(MavenEnricherContext buildContext, String name) {
public static String ENRICH_CONTAINERS = "fabric8.enricher.basic.enrichContainers";

public static String ENRICH_ALL_CONTAINERS = "fabric8.enricher.basic.enrichAllContainers";

private enum Config implements Configs.Key {
enrichAllContainers {{ d = "false"; }},
enrichContainers {{ d = null; }};

public String def() { return d; } protected String d;
}

public AbstractHealthCheckEnricher(EnricherContext buildContext, String name) {
super(buildContext, name);
}

@Override
public void create(PlatformMode platformMode, KubernetesListBuilder builder) {
if(!checkIfhealthChecksDisabled(false)) {
builder.accept(new TypedVisitor<ContainerBuilder>() {
@Override
public void visit(ContainerBuilder container) {
if (!container.hasReadinessProbe()) {
Probe probe = getReadinessProbe(container);
if (probe != null) {
log.info("Adding readiness " + describe(probe));
container.withReadinessProbe(probe);
}
for(ContainerBuilder container : getContainersToEnrich(builder)) {
if (!container.hasReadinessProbe()) {
Probe probe = getReadinessProbe(container);
if (probe != null) {
log.info("Adding readiness " + describe(probe));
container.withReadinessProbe(probe);
}
}

if (!container.hasLivenessProbe()) {
Probe probe = getLivenessProbe(container);
if (probe != null) {
log.info("Adding liveness " + describe(probe));
container.withLivenessProbe(probe);
}
if (!container.hasLivenessProbe()) {
Probe probe = getLivenessProbe(container);
if (probe != null) {
log.info("Adding liveness " + describe(probe));
container.withLivenessProbe(probe);
}
}
});
}
}
}

Expand Down Expand Up @@ -85,13 +101,64 @@ private String describe(Probe probe) {
}

protected Boolean checkIfhealthChecksDisabled(Boolean defaultValue) {
if(getContext().getProperty("fabric8.skipHealthCheck") != null) {
if (getContext().getProperty("fabric8.skipHealthCheck") != null) {
return Boolean.parseBoolean(getContext().getProperty("fabric8.skipHealthCheck").toString());
} else {
return defaultValue;
}
}

private List<String> getFabric8GeneratedContainers() {
List<String> containers = new ArrayList<>();
if(enricherContext.getProcessingInstructions() != null) {
if(enricherContext.getProcessingInstructions().get("FABRIC8_GENERATED_CONTAINERS") != null) {
containers.addAll(Arrays.asList(enricherContext.getProcessingInstructions().get("FABRIC8_GENERATED_CONTAINERS").split(",")));
}
}
return containers;
}

protected List<ContainerBuilder> getContainersToEnrich(KubernetesListBuilder builder) {
final List<ContainerBuilder> containerBuilders = new LinkedList<>();
builder.accept(new TypedVisitor<ContainerBuilder>() {
@Override
public void visit(ContainerBuilder containerBuilder) {
containerBuilders.add(containerBuilder);
}
});

boolean enrichAllContainers = "true".equalsIgnoreCase(getConfig(Config.enrichAllContainers));
String enrichContainers = getConfig(Config.enrichContainers);
Set<String> containersToEnrich = new HashSet<>();
if (enrichContainers != null) {
containersToEnrich.addAll(Arrays.asList(enrichContainers.split(",")));
}

if (enrichAllContainers) {
return containerBuilders;
} else if (!containersToEnrich.isEmpty()) {
List<ContainerBuilder> filteredContainers = new LinkedList<>();
for (ContainerBuilder container : containerBuilders) {
if (container.hasName() && containersToEnrich.contains(container.getName())) {
filteredContainers.add(container);
}
}
return filteredContainers;
} else if (containerBuilders.size() == 1) {
return containerBuilders;
} else {
// Multiple unfiltered containers, enrich only the generated ones
List<ContainerBuilder> generatedContainers = new LinkedList<>();
List<String> fabric8GeneratedContainers = getFabric8GeneratedContainers();
for (ContainerBuilder container : containerBuilders) {
if (container.hasName() && fabric8GeneratedContainers.contains(container.getName())) {
generatedContainers.add(container);
}
}
return generatedContainers;
}
}

/**
* Override this method to create a per-container readiness probe.
*/
Expand Down
Loading

0 comments on commit 3a640a4

Please sign in to comment.