Skip to content

Commit 1f9d383

Browse files
committed
improve: double brackets to handle non string values in object templates
Signed-off-by: Attila Mészáros <[email protected]>
1 parent 7c0accc commit 1f9d383

File tree

5 files changed

+55
-8
lines changed

5 files changed

+55
-8
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ spec:
6767
parent:
6868
apiVersion: glueoperator.sample/v1 # watches all the custom resource of type WebPage
6969
kind: WebPage
70-
statusTemplate: | # update the status of the custom resource at the end of reconciliation
71-
observedGeneration: {parent.metadata.generation}
70+
status: # update the status of the custom resource at the end of reconciliation
71+
observedGeneration: "{{parent.metadata.generation}}" # since it's a non-string value needs double curly brackets
7272
childResources:
7373
- name: htmlconfigmap
7474
resource:

docs/reference.md

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,31 @@ Although it is limited only to Kubernetes resources it makes it very easy to use
88

99
## Generic Notes
1010

11-
- All templates (both object and string based) uses [Qute templating engine](https://quarkus.io/guides/qute-reference). While objects allow only
12-
placeholders, you can use the full power of qute in string templates.
11+
- All templates (both object and string-based) uses [Qute templating engine](https://quarkus.io/guides/qute-reference). While objects allow only
12+
placeholders, you can use the full power of qute in string templates.
13+
14+
ONLY for object-based templates (thus not string templates) the values can be set using the placeholder notation from Qute:
15+
```yaml
16+
value: "{string.value.reference}"
17+
```
18+
With this standard notation, the result value will be always encoded in double quotes:
19+
```yaml
20+
value: "1"
21+
```
22+
Since there is no simple way to check if the referenced value is a string or other value
23+
(boolean, numeric, etc) for non-string values, user should use double brackets:
24+
```yaml
25+
value: "{{nonstring.value.reference}}"
26+
```
27+
what would result in a value without enclosed double quotes in the produced yaml:
28+
```yaml
29+
value: 1
30+
```
31+
See sample [here](https://github.com/java-operator-sdk/kubernetes-glue-operator/blob/main/src/test/resources/sample/webpage/webpage.operator.yaml#L10).
32+
Implementation wise, this is a preprocessor that strips the enclosed quotes and additional curly bracket
33+
before it is passed to Qute.
34+
In the future, we might remove such obligation by checking the type
35+
of the target value in the related schema.
1336
1437
## [Glue resource](https://github.com/java-operator-sdk/kubernetes-glue-operator/releases/latest/download/glues.glue-v1.yml)
1538

src/main/java/io/javaoperatorsdk/operator/glue/templating/GenericTemplateHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public String processTemplate(Map<String, Map<?, ?>> data, String template,
3434

3535
private String handleDoubleCurlyBrackets(String template) {
3636
template = template.replace("\"{{", "{");
37-
return template.replace("}}\n", "}");
37+
return template.replace("}}\"", "}");
3838
}
3939

4040
public String processInputAndTemplate(Map<String, GenericKubernetesResource> data,
Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,38 @@
11
package io.javaoperatorsdk.operator.glue.templating;
22

3+
import java.util.HashMap;
4+
import java.util.Map;
5+
36
import org.junit.jupiter.api.Test;
47

8+
import io.fabric8.kubernetes.client.utils.Serialization;
9+
510
import static org.junit.jupiter.api.Assertions.*;
611

712
class GenericTemplateHandlerTest {
813

14+
GenericTemplateHandler templateHandler = new GenericTemplateHandler();
15+
916
@Test
1017
void testDoubleCurlyBrackets() {
11-
fail();
18+
var template = """
19+
intValue: "{{spec.intvalue}}"
20+
stringValue: "{spec.stringvalue}"
21+
""";
22+
23+
Map<String, Map<?, ?>> data = new HashMap<>();
24+
25+
Map values = new HashMap();
26+
values.put("intvalue", 1);
27+
values.put("stringvalue", "value1");
28+
data.put("spec", values);
29+
30+
var result = templateHandler.processTemplate(data, template, true);
31+
32+
Map mapResult = Serialization.unmarshal(result, Map.class);
33+
34+
assertEquals(1, mapResult.get("intValue"));
35+
assertEquals("value1", mapResult.get("stringValue"));
1236
}
1337

1438
}

src/test/resources/sample/webpage/webpage.operator.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ spec:
66
parent:
77
apiVersion: glueoperator.sample/v1
88
kind: WebPage
9-
statusTemplate: |
10-
observedGeneration: {parent.metadata.generation}
9+
status:
10+
observedGeneration: "{{parent.metadata.generation}}"
1111
childResources:
1212
- name: htmlconfigmap
1313
resource:

0 commit comments

Comments
 (0)