Skip to content

Commit

Permalink
improve: double brackets to handle non string values in object templates
Browse files Browse the repository at this point in the history
Signed-off-by: Attila Mészáros <[email protected]>
  • Loading branch information
csviri committed Jan 5, 2025
1 parent 7c0accc commit 1f9d383
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 8 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ spec:
parent:
apiVersion: glueoperator.sample/v1 # watches all the custom resource of type WebPage
kind: WebPage
statusTemplate: | # update the status of the custom resource at the end of reconciliation
observedGeneration: {parent.metadata.generation}
status: # update the status of the custom resource at the end of reconciliation
observedGeneration: "{{parent.metadata.generation}}" # since it's a non-string value needs double curly brackets
childResources:
- name: htmlconfigmap
resource:
Expand Down
27 changes: 25 additions & 2 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,31 @@ Although it is limited only to Kubernetes resources it makes it very easy to use

## Generic Notes

- All templates (both object and string based) uses [Qute templating engine](https://quarkus.io/guides/qute-reference). While objects allow only
placeholders, you can use the full power of qute in string templates.
- All templates (both object and string-based) uses [Qute templating engine](https://quarkus.io/guides/qute-reference). While objects allow only
placeholders, you can use the full power of qute in string templates.

ONLY for object-based templates (thus not string templates) the values can be set using the placeholder notation from Qute:
```yaml
value: "{string.value.reference}"
```
With this standard notation, the result value will be always encoded in double quotes:
```yaml
value: "1"
```
Since there is no simple way to check if the referenced value is a string or other value
(boolean, numeric, etc) for non-string values, user should use double brackets:
```yaml
value: "{{nonstring.value.reference}}"
```
what would result in a value without enclosed double quotes in the produced yaml:
```yaml
value: 1
```
See sample [here](https://github.com/java-operator-sdk/kubernetes-glue-operator/blob/main/src/test/resources/sample/webpage/webpage.operator.yaml#L10).
Implementation wise, this is a preprocessor that strips the enclosed quotes and additional curly bracket
before it is passed to Qute.
In the future, we might remove such obligation by checking the type
of the target value in the related schema.
## [Glue resource](https://github.com/java-operator-sdk/kubernetes-glue-operator/releases/latest/download/glues.glue-v1.yml)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public String processTemplate(Map<String, Map<?, ?>> data, String template,

private String handleDoubleCurlyBrackets(String template) {
template = template.replace("\"{{", "{");
return template.replace("}}\n", "}");
return template.replace("}}\"", "}");
}

public String processInputAndTemplate(Map<String, GenericKubernetesResource> data,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
package io.javaoperatorsdk.operator.glue.templating;

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

import org.junit.jupiter.api.Test;

import io.fabric8.kubernetes.client.utils.Serialization;

import static org.junit.jupiter.api.Assertions.*;

class GenericTemplateHandlerTest {

GenericTemplateHandler templateHandler = new GenericTemplateHandler();

@Test
void testDoubleCurlyBrackets() {
fail();
var template = """
intValue: "{{spec.intvalue}}"
stringValue: "{spec.stringvalue}"
""";

Map<String, Map<?, ?>> data = new HashMap<>();

Map values = new HashMap();
values.put("intvalue", 1);
values.put("stringvalue", "value1");
data.put("spec", values);

var result = templateHandler.processTemplate(data, template, true);

Map mapResult = Serialization.unmarshal(result, Map.class);

assertEquals(1, mapResult.get("intValue"));
assertEquals("value1", mapResult.get("stringValue"));
}

}
4 changes: 2 additions & 2 deletions src/test/resources/sample/webpage/webpage.operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ spec:
parent:
apiVersion: glueoperator.sample/v1
kind: WebPage
statusTemplate: |
observedGeneration: {parent.metadata.generation}
status:
observedGeneration: "{{parent.metadata.generation}}"
childResources:
- name: htmlconfigmap
resource:
Expand Down

0 comments on commit 1f9d383

Please sign in to comment.