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 12, 2021
1 parent 104a4d9 commit b5be373
Show file tree
Hide file tree
Showing 16 changed files with 379 additions and 63 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Usage:
* Fix #387: Update Fabric8 Kubernetes Client to v4.13.0 to support `networking.k8s.io/v1` `Ingress`
* Fix #473: Debug goals work with QuarkusGenerator generated container images
* Fix #484: cacheFrom configuration parameter is missing
* Fix #515: Properties now get resolved in CustomResource fragments

### 1.0.2 (2020-10-30)
* Fix #429: Added quickstart for Micronaut framework
Expand Down
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 @@ -467,12 +467,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 @@ -1377,13 +1377,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 Expand Up @@ -1411,15 +1410,14 @@ public void applyNamespaceOrProjectIfPresent(Collection<HasMetadata> entities) {
}

public void applyEntities(String fileName, Set<HasMetadata> entities, KitLogger serviceLogger,
long serviceUrlWaitTimeSeconds, ResourceConfig resources, File resourceDir,
String environment) throws Exception {
long serviceUrlWaitTimeSeconds, ResourceConfig resources, File resourceDir) throws Exception {
// Apply Namespace/Project first
applyNamespaceOrProjectIfPresent(entities);
// Apply all items
applyStandardEntities(fileName, entities);
logExposeServiceUrl(entities, serviceLogger, serviceUrlWaitTimeSeconds);
processCustomEntities(resources != null ? resources.getCustomResourceDefinitions() : null,
resourceDir, environment, resources != null ? resources.getRemotes() : null);
resourceDir, resources != null ? resources.getRemotes() : null);
}

private void logExposeServiceUrl(Set<HasMetadata> entities, KitLogger serviceLogger, long serviceUrlWaitTimeSeconds) throws InterruptedException {
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 b5be373

Please sign in to comment.