Skip to content

Commit

Permalink
Fix eclipse-jkube#515: Properties now gets resolved in CustomResource…
Browse files Browse the repository at this point in the history
… fragments

CustomResource fragments are now processed during resource phase and
copied to target/classes/META-INF/jkube/custom-resource directory. They
will be picked and applied during apply phase.
  • Loading branch information
rohanKanojia committed Jan 11, 2021
1 parent 632df5f commit 3d068a4
Show file tree
Hide file tree
Showing 16 changed files with 390 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.google.gson.JsonObject;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.jkube.kit.common.util.JKubeFileInterpolator;
import org.eclipse.jkube.kit.config.image.ImageConfiguration;
import org.eclipse.jkube.kit.config.image.build.BuildConfiguration;
import org.yaml.snakeyaml.Yaml;
Expand Down Expand Up @@ -107,7 +108,7 @@ public static List<String[]> extractLines(File dockerFile, String keyword, Prope
try (BufferedReader reader = new BufferedReader(new FileReader(dockerFile))) {
String line;
while ((line = reader.readLine()) != null) {
String lineInterpolated = JKubeDockerfileInterpolator.interpolate(line, properties, filter);
String lineInterpolated = JKubeFileInterpolator.interpolate(line, properties, filter);
String[] lineParts = lineInterpolated.split("\\s+");
if (lineParts.length > 0 && lineParts[0].equalsIgnoreCase(keyword)) {
ret.add(lineParts);
Expand All @@ -127,14 +128,7 @@ public static List<String[]> extractLines(File dockerFile, String keyword, Prope
* @throws IOException if there's a problem while performin IO operations.
*/
public static String interpolate(File dockerFile, Properties properties, String filter) throws IOException {
StringBuilder ret = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new FileReader(dockerFile))) {
String line;
while ((line = reader.readLine()) != null) {
ret.append(JKubeDockerfileInterpolator.interpolate(line, properties, resolveDockerfileFilter(filter))).append(System.lineSeparator());
}
}
return ret.toString();
return JKubeFileInterpolator.interpolate(dockerFile, properties, resolveDockerfileFilter(filter));
}

private static Reader getFileReaderFromDir(File file) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,21 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.jkube.kit.build.api.helper;
package org.eclipse.jkube.kit.common.util;

import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class JKubeDockerfileInterpolator {
public class JKubeFileInterpolator {

private JKubeDockerfileInterpolator() { }
private JKubeFileInterpolator() { }

/**
* Replace properties in a string
Expand Down Expand Up @@ -65,6 +69,17 @@ protected static Map<String, String> getExpressionMarkersFromFilter(String filte
return expressionMarkers;
}

public static String interpolate(File file, Properties properties, String filter) throws IOException {
StringBuilder ret = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line;
while ((line = reader.readLine()) != null) {
ret.append(JKubeFileInterpolator.interpolate(line, properties, filter)).append(System.lineSeparator());
}
}
return ret.toString();
}

private static String checkForPropertiesInLine(String line, Properties properties, Map<String, String> delimiters) {
// Provided properties
for (String property : properties.stringPropertyNames()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.jkube.kit.build.api.helper;
package org.eclipse.jkube.kit.common.util;

import org.junit.Test;

Expand All @@ -20,12 +20,12 @@
import java.util.Properties;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

public class JKubeDockerfileInterpolatorTest {
public class JKubeFileInterpolatorTest {
@Test
public void testLongDelimitersInContext() {
// Given
Expand All @@ -34,7 +34,7 @@ public void testLongDelimitersInContext() {
p.setProperty("test.label", "test");

// When
String result = JKubeDockerfileInterpolator.interpolate(src, p, Collections.singletonMap("<expression>", "</expression>"));
String result = JKubeFileInterpolator.interpolate(src, p, Collections.singletonMap("<expression>", "</expression>"));

// Then
assertEquals("This is a test for long delimiters in context.", result);
Expand All @@ -48,7 +48,7 @@ public void testLongDelimitersWithNoStartContext() {
p.setProperty("test.label", "test");

// When
String result = JKubeDockerfileInterpolator.interpolate(src, p, Collections.singletonMap("<expression>", "</expression>"));
String result = JKubeFileInterpolator.interpolate(src, p, Collections.singletonMap("<expression>", "</expression>"));

// Then
assertEquals("test for long delimiters in context.", result);
Expand All @@ -62,7 +62,7 @@ public void testLongDelimitersWithNoEndContext() {
p.setProperty("test.label", "test");

// When
String result = JKubeDockerfileInterpolator.interpolate(src, p, Collections.singletonMap("<expression>", "</expression>"));
String result = JKubeFileInterpolator.interpolate(src, p, Collections.singletonMap("<expression>", "</expression>"));

// Then
assertEquals("This is a test", result);
Expand All @@ -75,7 +75,7 @@ public void testLongDelimitersWithNoContext() {
Properties p = new Properties();
p.setProperty("test.label", "test");
// When
String result = JKubeDockerfileInterpolator.interpolate(src, p, Collections.singletonMap("<expression>", "</expression>"));
String result = JKubeFileInterpolator.interpolate(src, p, Collections.singletonMap("<expression>", "</expression>"));

// Then
assertEquals("test", result);
Expand All @@ -88,7 +88,7 @@ public void testSimpleSubstitution() {
p.setProperty("key", "value");

// When
String result = JKubeDockerfileInterpolator.interpolate("This is a test ${key}.", p, Collections.singletonMap("${", "}"));
String result = JKubeFileInterpolator.interpolate("This is a test ${key}.", p, Collections.singletonMap("${", "}"));

// Then
assertEquals("This is a test value.", result);
Expand All @@ -102,7 +102,7 @@ public void testSimpleSubstitution_TwoExpressions() {
p.setProperty("key2", "value2");

// When
String result = JKubeDockerfileInterpolator.interpolate("${key}-${key2}", p, Collections.singletonMap("${", "}"));
String result = JKubeFileInterpolator.interpolate("${key}-${key2}", p, Collections.singletonMap("${", "}"));

// Then
assertEquals("value-value2", result);
Expand All @@ -115,7 +115,7 @@ public void testBrokenExpression_LeaveItAlone() {
p.setProperty("key", "value");

// When
String result = JKubeDockerfileInterpolator.interpolate("This is a test ${key.", p, Collections.singletonMap("${", "}"));
String result = JKubeFileInterpolator.interpolate("This is a test ${key.", p, Collections.singletonMap("${", "}"));

// Then
assertEquals("This is a test ${key.", result);
Expand All @@ -129,7 +129,7 @@ public void testShouldFailOnExpressionCycleParsed() {
props.setProperty("key2", "${key1}");

// When
JKubeDockerfileInterpolator.interpolate("${key1}", props, Collections.singletonMap("${", "}"));
JKubeFileInterpolator.interpolate("${key1}", props, Collections.singletonMap("${", "}"));

fail("Should detect expression cycle and fail.");
}
Expand All @@ -142,7 +142,7 @@ public void testShouldFailOnExpressionCycleDirect() {
props.setProperty("key2", "key1");

// When
JKubeDockerfileInterpolator.interpolate("${key1}", props, Collections.singletonMap("${", "}"));
JKubeFileInterpolator.interpolate("${key1}", props, Collections.singletonMap("${", "}"));

fail("Should detect expression cycle and fail.");
}
Expand All @@ -154,7 +154,7 @@ public void testShouldResolveByMy_getVar_Method() {
properties.put("${var}", "testVar");

// When
String result = JKubeDockerfileInterpolator.interpolate("this is a ${var}", properties, Collections.singletonMap("${", "}"));
String result = JKubeFileInterpolator.interpolate("this is a ${var}", properties, Collections.singletonMap("${", "}"));

// Then
assertEquals("this is a testVar", result);
Expand All @@ -164,7 +164,7 @@ public void testShouldResolveByMy_getVar_Method() {
public void testShouldResolveByEnvar() {
// Given
Properties p = new Properties();
String result = JKubeDockerfileInterpolator.interpolate("this is a ${env.HOME} ${env.PATH}", p, Collections.singletonMap("${env.", "}"));
String result = JKubeFileInterpolator.interpolate("this is a ${env.HOME} ${env.PATH}", p, Collections.singletonMap("${env.", "}"));

// When + Then
assertNotEquals("this is a ${HOME} ${PATH}", result);
Expand All @@ -178,7 +178,7 @@ public void testNotEscapeWithLongEscapeStrAtStart() {
p.setProperty("key", "value");

// When
String result = JKubeDockerfileInterpolator.interpolate("@{key} This is a test.", p, Collections.singletonMap("@{", "}"));
String result = JKubeFileInterpolator.interpolate("@{key} This is a test.", p, Collections.singletonMap("@{", "}"));

// Then
assertEquals("value This is a test.", result);
Expand All @@ -187,7 +187,7 @@ public void testNotEscapeWithLongEscapeStrAtStart() {
@Test
public void testNPEFree() {
// When
String result = JKubeDockerfileInterpolator.interpolate(null, new Properties(), Collections.emptyMap());
String result = JKubeFileInterpolator.interpolate(null, new Properties(), Collections.emptyMap());

// Then
assertNull(result);
Expand All @@ -203,9 +203,9 @@ public void testLinkedInterpolators() {
p.put("test2", "x");

// When
String result1 = JKubeDockerfileInterpolator.interpolate(EXPR, p, Collections.singletonMap("${", "}"));
String result1 = JKubeFileInterpolator.interpolate(EXPR, p, Collections.singletonMap("${", "}"));
p.put("test2.label", "zz");
String result2 = JKubeDockerfileInterpolator.interpolate(EXPR2, p, Collections.singletonMap("${", "}"));
String result2 = JKubeFileInterpolator.interpolate(EXPR2, p, Collections.singletonMap("${", "}"));

// Then
assertEquals("pANDx", result1);
Expand All @@ -223,8 +223,8 @@ public void testDominance() {
p1.put("test2.label", "dominant");

// When + Then
assertEquals("pANDx", JKubeDockerfileInterpolator.interpolate(EXPR, p1,Collections.singletonMap("${", "}")));
assertEquals("pdominantANDx", JKubeDockerfileInterpolator.interpolate(EXPR2, p1, Collections.singletonMap("${", "}")));
assertEquals("pANDx", JKubeFileInterpolator.interpolate(EXPR, p1,Collections.singletonMap("${", "}")));
assertEquals("pdominantANDx", JKubeFileInterpolator.interpolate(EXPR2, p1, Collections.singletonMap("${", "}")));
}

@Test(expected = IllegalArgumentException.class)
Expand All @@ -234,7 +234,7 @@ public void testCyclesWithLinked() {
p.put("key1", "${key2}");
p.put("key2", "${key2}");
// When
JKubeDockerfileInterpolator.interpolate("${key2}", p, Collections.singletonMap("${", "}"));
JKubeFileInterpolator.interpolate("${key2}", p, Collections.singletonMap("${", "}"));
}

@Test(expected = IllegalArgumentException.class)
Expand All @@ -244,7 +244,7 @@ public void testCyclesWithLinked_betweenRootAndOther() {
p.put("key1", "${key2}");
p.put("key2", "${key1}");
// When
JKubeDockerfileInterpolator.interpolate("${key1}", p, Collections.singletonMap("${", "}"));
JKubeFileInterpolator.interpolate("${key1}", p, Collections.singletonMap("${", "}"));
}

@Test
Expand All @@ -253,7 +253,7 @@ public void testGetExpressionMarkersFromFilterWithDefaultFilter() {
String filter = "${*}";

// When
Map<String, String> result = JKubeDockerfileInterpolator.getExpressionMarkersFromFilter(filter);
Map<String, String> result = JKubeFileInterpolator.getExpressionMarkersFromFilter(filter);

// Then
assertEquals(Collections.singletonMap("${", "}"), result);
Expand All @@ -265,7 +265,7 @@ public void testGetExpressionMarkersFromFilterWithSingleCharacterFilter() {
String filter = "@";

// When
Map<String, String> result = JKubeDockerfileInterpolator.getExpressionMarkersFromFilter(filter);
Map<String, String> result = JKubeFileInterpolator.getExpressionMarkersFromFilter(filter);

// Then
assertEquals(Collections.singletonMap("@", "@"), result);
Expand All @@ -277,7 +277,7 @@ public void testGetExpressionMarkersFromFilterWithFalseFilter() {
String filter = "false";

// When
Map<String, String> result = JKubeDockerfileInterpolator.getExpressionMarkersFromFilter(filter);
Map<String, String> result = JKubeFileInterpolator.getExpressionMarkersFromFilter(filter);

// Then
assertTrue(result.isEmpty());
Expand All @@ -289,7 +289,7 @@ public void testGetExpressionMarkersFromFilterWithBlankFilter() {
String filter = "";

// When
Map<String, String> result = JKubeDockerfileInterpolator.getExpressionMarkersFromFilter(filter);
Map<String, String> result = JKubeFileInterpolator.getExpressionMarkersFromFilter(filter);

// Then
assertTrue(result.isEmpty());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,12 @@
import io.fabric8.openshift.client.OpenShiftClient;
import org.eclipse.jkube.kit.common.KitLogger;
import org.eclipse.jkube.kit.common.util.FileUtil;
import org.eclipse.jkube.kit.common.util.JKubeFileInterpolator;
import org.eclipse.jkube.kit.common.util.KubernetesHelper;
import org.eclipse.jkube.kit.common.util.OpenshiftHelper;
import org.eclipse.jkube.kit.common.util.ResourceUtil;
import org.eclipse.jkube.kit.common.util.UserConfigurationCompare;
import org.eclipse.jkube.kit.config.image.build.BuildConfiguration;
import org.eclipse.jkube.kit.config.service.kubernetes.KubernetesClientUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
Expand All @@ -71,6 +73,7 @@
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;

import static org.eclipse.jkube.kit.common.util.KubernetesHelper.getCustomResourcesFileToNameMap;
Expand Down Expand Up @@ -105,11 +108,13 @@ public class ApplyService {
private PatchService patchService;
// This map is to track projects created.
private static final Set<String> projectsCreated = new HashSet<>();
private final Properties properties;

public ApplyService(KubernetesClient kubernetesClient, KitLogger log) {
public ApplyService(KubernetesClient kubernetesClient, KitLogger log, Properties projectProperties) {
this.kubernetesClient = kubernetesClient;
this.patchService = new PatchService(kubernetesClient, log);
this.log = log;
this.properties = projectProperties;
}

/**
Expand Down Expand Up @@ -452,7 +457,7 @@ private void doCreateCustomResourceDefinition(CustomResourceDefinition entity, S
}

public void applyCustomResource(File customResourceFile, String namespace, CustomResourceDefinitionContext context)
throws Exception {
throws Exception {

Map<String, Object> cr = unmarshalCustomResourceFile(customResourceFile);
Map<String, Object> objectMeta = (Map<String, Object>)cr.get("metadata");
Expand All @@ -463,12 +468,12 @@ public void applyCustomResource(File customResourceFile, String namespace, Custo
KubernetesClientUtil.doCreateCustomResource(kubernetesClient, context, namespace, customResourceFile);
log.info("Created Custom Resource: %s %s", KubernetesHelper.getFullyQualifiedApiGroupWithKind(context), name);
} else {
cr = KubernetesClientUtil.doGetCustomResource(kubernetesClient, context, namespace, name);
if (cr == null) {
Map<String, Object> crFromServer = KubernetesClientUtil.doGetCustomResource(kubernetesClient, context, namespace, name);
if (crFromServer == null) {
KubernetesClientUtil.doCreateCustomResource(kubernetesClient, context, namespace, customResourceFile);
log.info("Created Custom Resource: %s", KubernetesHelper.getFullyQualifiedApiGroupWithKind(context), name);
} else {
KubernetesClientUtil.doEditCustomResource(kubernetesClient, context, namespace, name, customResourceFile);
KubernetesClientUtil.doEditCustomResource(kubernetesClient, context, namespace, name, cr);
log.info("Updated Custom Resource: %s", KubernetesHelper.getFullyQualifiedApiGroupWithKind(context), name);
}
}
Expand Down Expand Up @@ -1373,13 +1378,12 @@ public void setRollingUpgradePreserveScale(boolean rollingUpgradePreserveScale)
this.rollingUpgradePreserveScale = rollingUpgradePreserveScale;
}

public void processCustomEntities(List<String> customResourceDefinitions, File resourceDir, String environment, List<String> remotes) throws Exception {
public void processCustomEntities(List<String> customResourceDefinitions, File customResourceOutputDir, List<String> remotes) throws Exception {
if(customResourceDefinitions == null)
return;

List<CustomResourceDefinitionContext> crdContexts = KubernetesClientUtil.getCustomResourceDefinitionContext(kubernetesClient ,customResourceDefinitions);
File resourceDirFinal = ResourceUtil.getFinalResourceDir(resourceDir, environment);
Map<File, String> fileToCrdMap = getCustomResourcesFileToNameMap(resourceDirFinal, remotes, log);
Map<File, String> fileToCrdMap = getCustomResourcesFileToNameMap(customResourceOutputDir, remotes, log);

for(CustomResourceDefinitionContext customResourceDefinitionContext : crdContexts) {
for(Map.Entry<File, String> entry : fileToCrdMap.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ private void init() {
}
this.client = clusterAccess.createDefaultClient();

applyService = new LazyBuilder<>(() -> new ApplyService(client, log));
applyService = new LazyBuilder<>(() -> new ApplyService(client, log, configuration.getProperties()));
buildService = new LazyBuilder<>(() -> {
BuildService ret;
if (JKubeBuildStrategy.jib == buildServiceConfig.getJKubeBuildStrategy()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,11 @@ public static Map<String, Object> doCreateCustomResource(KubernetesClient kubern
}
}

public static Map<String, Object> doEditCustomResource(KubernetesClient kubernetesClient, CustomResourceDefinitionContext crdContext, String namespace, String name, File customResourceFile) throws IOException {
public static Map<String, Object> doEditCustomResource(KubernetesClient kubernetesClient, CustomResourceDefinitionContext crdContext, String namespace, String name, Map<String, Object> customResource) throws IOException {
if ("Namespaced".equals(crdContext.getScope())) {
return kubernetesClient.customResource(crdContext).edit(namespace, name, new FileInputStream(customResourceFile.getAbsolutePath()));
return kubernetesClient.customResource(crdContext).edit(namespace, name, customResource);
} else {
return kubernetesClient.customResource(crdContext).edit(name, doGetCustomResourceAsString(customResourceFile));
return kubernetesClient.customResource(crdContext).edit(name, customResource);
}
}

Expand Down
Loading

0 comments on commit 3d068a4

Please sign in to comment.