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

Commit

Permalink
Fix #1299 : autotls feature doesn't work with OpenShift 3.9 (Kubernet…
Browse files Browse the repository at this point in the history
…es 1.8+) due to InitContainer annotation deprecation
  • Loading branch information
rohanKanojia committed Jul 19, 2018
1 parent d9939b2 commit 49cb572
Show file tree
Hide file tree
Showing 13 changed files with 349 additions and 208 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ After this we will switch probably to real [Semantic Versioning 2.0.0](http://se

###3.5.41
* Feature 1032: Improvements of the Vert.x Generator and enrichers
* Removed unused Maven goals. Please contact us if something's missing for you.
* Fix 1313: Removed unused Maven goals. Please contact us if something's missing for you.
* Fix 1299: autotls feature doesn't work with OpenShift 3.9 (Kubernetes 1.8+) due to InitContainer annotation deprecation

###3.5.40
* Feature 1264: Added `osio` profile, with enricher to apply OpenShift.io space labels to resources
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,11 @@

package io.fabric8.maven.enricher.api.util;

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

import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.PodTemplateSpecBuilder;
import io.fabric8.maven.core.util.JSONUtil;
import io.fabric8.maven.docker.util.Logger;
import io.fabric8.utils.Strings;
import org.json.JSONArray;
import org.json.JSONObject;

/**
* @author roland
Expand All @@ -44,56 +40,32 @@ public boolean hasInitContainer(PodTemplateSpecBuilder builder, String name) {
return getInitContainer(builder, name) != null;
}

public JSONObject getInitContainer(PodTemplateSpecBuilder builder, String name) {
if (builder.hasMetadata()) {
String initContainerAnnotation = builder.buildMetadata().getAnnotations().get(INIT_CONTAINER_ANNOTATION);
if (Strings.isNotBlank(initContainerAnnotation)) {
JSONArray initContainers = new JSONArray(initContainerAnnotation);
for (int i = 0; i < initContainers.length(); i++) {
JSONObject obj = initContainers.getJSONObject(i);
String existingName = obj.getString("name");
if (name.equals(existingName)) {
return obj;
}
public Container getInitContainer(PodTemplateSpecBuilder builder, String name) {
if (builder.hasSpec()) {
List<Container> initContainerList = builder.buildSpec().getInitContainers();
for(Container initContainer : initContainerList) {
if(initContainer.getName().equals(name)) {
return initContainer;
}
}
}
return null;
}

public void removeInitContainer(PodTemplateSpecBuilder builder, String initContainerName) {
if (hasInitContainer(builder, initContainerName)) {
ObjectMeta meta = builder.buildMetadata();
Map<String, String> annos = meta.getAnnotations();
JSONArray newInitContainers = removeFromInitContainersJson(annos.get(INIT_CONTAINER_ANNOTATION), initContainerName);
if (newInitContainers.length() > 0) {
annos.put(INIT_CONTAINER_ANNOTATION, newInitContainers.toString());
} else {
annos.remove(INIT_CONTAINER_ANNOTATION);
}
meta.setAnnotations(annos);
}
}

private JSONArray removeFromInitContainersJson(String initContainersJson, String initContainerName) {
JSONArray newInitContainers = new JSONArray();
JSONArray initContainers = new JSONArray(initContainersJson);

for (int i = 0; i < initContainers.length(); i++) {
JSONObject obj = initContainers.getJSONObject(i);
String existingName = obj.getString("name");
if (!initContainerName.equals(existingName)) {
newInitContainers.put(obj);
}
Container initContainer = getInitContainer(builder, initContainerName);
if (initContainer != null) {
List<Container> initContainers = builder.buildSpec().getInitContainers();
initContainers.remove(initContainer);
builder.editSpec().withInitContainers(initContainers).endSpec();
}
return newInitContainers;
}

public void appendInitContainer(PodTemplateSpecBuilder builder, JSONObject initContainer) {
String name = initContainer.getString("name");
JSONObject existing = getInitContainer(builder, name);
public void appendInitContainer(PodTemplateSpecBuilder builder, Container initContainer) {
String name = initContainer.getName();
Container existing = getInitContainer(builder, name);
if (existing != null) {
if (JSONUtil.equals(existing, initContainer)) {
if (existing.equals(initContainer)) {
log.warn("Trying to add init-container %s a second time. Ignoring ....", name);
return;
} else {
Expand All @@ -103,16 +75,14 @@ public void appendInitContainer(PodTemplateSpecBuilder builder, JSONObject initC
builder.build().getMetadata().getName(), name));
}
}
ensureMetadata(builder);
String initContainerAnnotation = builder.buildMetadata().getAnnotations().get(INIT_CONTAINER_ANNOTATION);
JSONArray initContainers = Strings.isNullOrBlank(initContainerAnnotation) ? new JSONArray() : new JSONArray(initContainerAnnotation);
initContainers.put(initContainer);
builder.editMetadata().addToAnnotations(INIT_CONTAINER_ANNOTATION, initContainers.toString()).endMetadata();

ensureSpec(builder);
builder.editSpec().addToInitContainers(initContainer).endSpec();
}

private void ensureMetadata(PodTemplateSpecBuilder obj) {
if (obj.buildMetadata() == null) {
obj.withNewMetadata().endMetadata();
private void ensureSpec(PodTemplateSpecBuilder obj) {
if (obj.buildSpec() == null) {
obj.withNewSpec().endSpec();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,16 @@

package io.fabric8.maven.enricher.api.util;

import java.util.HashMap;
import java.util.Map;
import java.util.*;

import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.ContainerBuilder;
import io.fabric8.kubernetes.api.model.PodTemplateSpec;
import io.fabric8.kubernetes.api.model.PodTemplateSpecBuilder;
import io.fabric8.maven.core.util.JSONUtil;
import io.fabric8.maven.docker.util.Logger;
import mockit.Expectations;
import mockit.Mocked;
import mockit.integration.junit4.JMockit;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -56,20 +54,20 @@ public void setUp() {
public void simple() {
PodTemplateSpecBuilder builder = getPodTemplateBuilder();
assertFalse(handler.hasInitContainer(builder, "blub"));
JSONObject initContainer = createInitContainer("blub", "foo/blub");
Container initContainer = createInitContainer("blub", "foo/blub");
handler.appendInitContainer(builder, initContainer);
assertTrue(handler.hasInitContainer(builder, "blub"));
verifyBuilder(builder,initContainer);
verifyBuilder(builder, Arrays.asList(initContainer));
}

@Test
public void append() {
PodTemplateSpecBuilder builder = getPodTemplateBuilder("bla", "foo/bla");
assertFalse(handler.hasInitContainer(builder, "blub"));
JSONObject initContainer = createInitContainer("blub", "foo/blub");
Container initContainer = createInitContainer("blub", "foo/blub");
handler.appendInitContainer(builder, initContainer);
assertTrue(handler.hasInitContainer(builder, "blub"));
verifyBuilder(builder,createInitContainer("bla", "foo/bla"), initContainer);
verifyBuilder(builder, Arrays.asList(createInitContainer("bla", "foo/bla"), initContainer));
}

@Test
Expand All @@ -78,7 +76,7 @@ public void removeAll() {
assertTrue(handler.hasInitContainer(builder, "bla"));
handler.removeInitContainer(builder, "bla");
assertFalse(handler.hasInitContainer(builder, "bla"));
verifyBuilder(builder);
verifyBuilder(builder, null);
}

@Test
Expand All @@ -89,7 +87,7 @@ public void removeOne() {
handler.removeInitContainer(builder, "bla");
assertFalse(handler.hasInitContainer(builder, "bla"));
assertTrue(handler.hasInitContainer(builder, "blub"));
verifyBuilder(builder, createInitContainer("blub", "foo/blub"));
verifyBuilder(builder, Arrays.asList(createInitContainer("blub", "foo/blub")));
}

@Test
Expand All @@ -100,63 +98,57 @@ public void existingSame() {

PodTemplateSpecBuilder builder = getPodTemplateBuilder("blub", "foo/blub");
assertTrue(handler.hasInitContainer(builder, "blub"));
JSONObject initContainer = createInitContainer("blub", "foo/blub");
Container initContainer = createInitContainer("blub", "foo/blub");
handler.appendInitContainer(builder, initContainer);
assertTrue(handler.hasInitContainer(builder, "blub"));
verifyBuilder(builder, initContainer);
verifyBuilder(builder, Arrays.asList(initContainer));
}

@Test
public void existingDifferent() {
try {
PodTemplateSpecBuilder builder = getPodTemplateBuilder("blub", "foo/bla");
assertTrue(handler.hasInitContainer(builder, "blub"));
JSONObject initContainer = createInitContainer("blub", "foo/blub");
Container initContainer = createInitContainer("blub", "foo/blub");
handler.appendInitContainer(builder, initContainer);
fail();
} catch (IllegalArgumentException exp) {
assertTrue(exp.getMessage().contains("blub"));
}
}

private void verifyBuilder(PodTemplateSpecBuilder builder, JSONObject ... initContainers) {
private void verifyBuilder(PodTemplateSpecBuilder builder, List<Container> initContainers) {
PodTemplateSpec spec = builder.build();
String containers = spec.getMetadata().getAnnotations().get(InitContainerHandler.INIT_CONTAINER_ANNOTATION);
if (initContainers.length == 0) {
assertNull(containers);
List<Container> initContainersInSpec = spec.getSpec().getInitContainers();
if (initContainersInSpec.size() == 0) {
assertNull(initContainers);
} else {
JSONArray got = new JSONArray(containers);
assertEquals(got.length(), initContainers.length);
for (int i = 0; i < initContainers.length; i++) {
assertTrue(JSONUtil.equals(got.getJSONObject(i), initContainers[i]));
assertEquals(initContainersInSpec.size(), initContainers.size());
for (int i = 0; i < initContainers.size(); i++) {
assertEquals(initContainersInSpec.get(i), initContainers.get(i));
}
}
}

private PodTemplateSpecBuilder getPodTemplateBuilder(String ... definitions) {
PodTemplateSpecBuilder ret = new PodTemplateSpecBuilder();
ret.withNewMetadata()
.withAnnotations(getInitContainerAnnotation(definitions))
.endMetadata();
ret.withNewMetadata().withName("test-pod-templateSpec").endMetadata().withNewSpec().withInitContainers(getInitContainerList(definitions)).endSpec();
return ret;
}

private Map<String, String> getInitContainerAnnotation(String ... definitions) {
Map<String, String> ret = new HashMap<>();
JSONArray initContainers = new JSONArray();
private List<Container> getInitContainerList(String ... definitions) {
List<Container> ret = new ArrayList<>();
for (int i = 0; i < definitions.length; i += 2 ) {
initContainers.put(createInitContainer(definitions[i], definitions[i+1]));
}
if (initContainers.length() > 0) {
ret.put(InitContainerHandler.INIT_CONTAINER_ANNOTATION, initContainers.toString());
ret.add(createInitContainer(definitions[i], definitions[i+1]));
}
return ret;
}

private JSONObject createInitContainer(String name, String image) {
JSONObject initContainer = new JSONObject();
initContainer.put("name", name);
initContainer.put("image", image);
private Container createInitContainer(String name, String image) {
Container initContainer = new ContainerBuilder()
.withName(name)
.withImage(image)
.build();
return initContainer;
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,14 @@
package io.fabric8.maven.enricher.fabric8;

import io.fabric8.kubernetes.api.builder.TypedVisitor;
import io.fabric8.kubernetes.api.model.ContainerBuilder;
import io.fabric8.kubernetes.api.model.KubernetesListBuilder;
import io.fabric8.kubernetes.api.model.PodSpecBuilder;
import io.fabric8.kubernetes.api.model.PodTemplateSpecBuilder;
import io.fabric8.kubernetes.api.model.Volume;
import io.fabric8.kubernetes.api.model.VolumeMount;
import io.fabric8.kubernetes.api.model.*;
import io.fabric8.maven.core.util.Configs;
import io.fabric8.maven.enricher.api.BaseEnricher;
import io.fabric8.maven.enricher.api.EnricherContext;
import io.fabric8.maven.enricher.api.Kind;
import io.fabric8.maven.enricher.api.util.InitContainerHandler;
import org.json.JSONArray;
import org.json.JSONObject;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.*;

/**
* Enriches declarations with auto-TLS annotations, required secrets reference,
Expand Down Expand Up @@ -143,40 +134,41 @@ public void visit(PodTemplateSpecBuilder builder) {
initContainerHandler.appendInitContainer(builder, createInitContainer());
}

private JSONObject createInitContainer() {
JSONObject entry = new JSONObject();
entry.put("name", getConfig(Config.pemToJKSInitContainerName));
entry.put("image", getConfig(Config.pemToJKSInitContainerImage));
entry.put("imagePullPolicy","IfNotPresent");
entry.put("args", createArgsArray());
entry.put("volumeMounts", createMounts());
return entry;
private Container createInitContainer() {
return new ContainerBuilder()
.withName(getConfig(Config.pemToJKSInitContainerName))
.withImage(getConfig(Config.pemToJKSInitContainerImage))
.withImagePullPolicy("IfNotPresent")
.withArgs(createArgsArray())
.withVolumeMounts(createMounts())
.build();
}

private JSONArray createArgsArray() {
JSONArray ret = new JSONArray();
ret.put("-cert-file");
ret.put(getConfig(Config.keystoreCertAlias) + "=/tls-pem/tls.crt");
ret.put("-key-file");
ret.put(getConfig(Config.keystoreCertAlias) + "=/tls-pem/tls.key");
ret.put("-keystore");
ret.put("/tls-jks/" + getConfig(Config.keystoreFileName));
ret.put("-keystore-password");
ret.put(getConfig(Config.keystorePassword));
private List<String> createArgsArray() {
List<String> ret = new ArrayList<>();
ret.add("-cert-file");
ret.add(getConfig(Config.keystoreCertAlias) + "=/tls-pem/tls.crt");
ret.add("-key-file");
ret.add(getConfig(Config.keystoreCertAlias) + "=/tls-pem/tls.key");
ret.add("-keystore");
ret.add("/tls-jks/" + getConfig(Config.keystoreFileName));
ret.add("-keystore-password");
ret.add(getConfig(Config.keystorePassword));
return ret;
}

private JSONArray createMounts() {
JSONObject pemMountPoint = new JSONObject();
pemMountPoint.put("name", getConfig(Config.tlsSecretVolumeName));
pemMountPoint.put("mountPath", "/tls-pem");
JSONObject jksMountPoint = new JSONObject();
jksMountPoint.put("name", getConfig(Config.jksVolumeName));
jksMountPoint.put("mountPath", "/tls-jks");
JSONArray ret = new JSONArray();
ret.put(pemMountPoint);
ret.put(jksMountPoint);
return ret;
private List<VolumeMount> createMounts() {

VolumeMount pemMountPoint = new VolumeMountBuilder()
.withName(getConfig(Config.tlsSecretVolumeName))
.withMountPath("/tls-pem")
.build();
VolumeMount jksMountPoint = new VolumeMountBuilder()
.withName(getConfig(Config.jksVolumeName))
.withMountPath("/tls-jks")
.build();

return Arrays.asList(pemMountPoint, jksMountPoint);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.util.*;

import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.KubernetesListBuilder;
import io.fabric8.kubernetes.api.model.PodTemplate;
import io.fabric8.maven.core.config.PlatformMode;
Expand Down Expand Up @@ -177,9 +178,8 @@ public void testAdapt() throws Exception {
enricher.adapt(klb);
PodTemplate pt = (PodTemplate) klb.getItems().get(0);

String initContainers = pt.getTemplate().getMetadata().getAnnotations()
.get(InitContainerHandler.INIT_CONTAINER_ANNOTATION);
assertEquals(tc.mode == PlatformMode.openshift, initContainers != null);
List<Container> initContainers = pt.getTemplate().getSpec().getInitContainers();
assertEquals(tc.mode == PlatformMode.openshift, !initContainers.isEmpty());

if (tc.mode == PlatformMode.kubernetes) {
continue;
Expand Down
Loading

0 comments on commit 49cb572

Please sign in to comment.