Repository: redhat-developer/service-binding-operator
Pull request #412 (2020-04-03 14:04:08)

Introduce "json" function in templating to generate inline "json" as custom env var



### Motivation

Sometimes we need a json format custom env var

### Changes

Add a function json into custom_env_parser to do the json marshal.


openshift-ci-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by:
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **isutton**
You can assign the PR to them by writing `/assign @isutton` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=redhat-developer%2Fservice-binding-operator).

<details open>
Needs approval from an approver in each of these files:

- **[OWNERS](https://github.com/redhat-developer/service-binding-operator/blob/master/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["isutton"]} -->
openshift-ci-robot: Hi @qibobo. Thanks for your PR.

I'm waiting for a [redhat-developer](https://github.com/orgs/redhat-developer/people) member to verify that this patch is reasonable to test. If it is, they should reply with `/ok-to-test` on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should [join the org](https://github.com/orgs/redhat-developer/people) to skip this step.

Once the patch is verified, the new status will be reflected by the `ok-to-test` label.

I understand the commands that are listed [here](https://go.k8s.io/bot-commands?repo=redhat-developer%2Fservice-binding-operator).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>

sbose78: /ok-to-test
codecov[bot]: # [Codecov](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/412?src=pr&el=h1) Report
> :exclamation: No coverage uploaded for pull request base (`master@6c323f2`). [Click here to learn what that means](https://docs.codecov.io/docs/error-reference#section-missing-base-commit).
> The diff coverage is `66.66%`.

[![Impacted file tree graph](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/412/graphs/tree.svg?width=650&token=CICBeVWlrC&height=150&src=pr)](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/412?src=pr&el=tree)

```diff
@@            Coverage Diff            @@
##             master     #412   +/-   ##
=========================================
  Coverage          ?   64.95%           
=========================================
  Files             ?       21           
  Lines             ?     1418           
  Branches          ?        0           
=========================================
  Hits              ?      921           
  Misses            ?      372           
  Partials          ?      125
```


| [Impacted Files](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/412?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [...troller/servicebindingrequest/custom\_env\_parser.go](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/412/diff?src=pr&el=tree#diff-cGtnL2NvbnRyb2xsZXIvc2VydmljZWJpbmRpbmdyZXF1ZXN0L2N1c3RvbV9lbnZfcGFyc2VyLmdv) | `71.42% <66.66%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/412?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/412?src=pr&el=footer). Last update [6c323f2...52c2c12](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/412?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

sbose78: Nice @qibobo !
sbose78: /lgtm
/approve
openshift-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/redhat-developer/service-binding-operator/pull/412#issuecomment-608536613" title="Approved">sbose78</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=redhat-developer%2Fservice-binding-operator).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/redhat-developer/service-binding-operator/blob/master/OWNERS)~~ [sbose78]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->

Patch:
diff --git a/pkg/controller/servicebindingrequest/custom_env_parser.go b/pkg/controller/servicebindingrequest/custom_env_parser.go
index 6f6b5b31..f2a3e28f 100644
--- a/pkg/controller/servicebindingrequest/custom_env_parser.go
+++ b/pkg/controller/servicebindingrequest/custom_env_parser.go
@@ -2,6 +2,7 @@ package servicebindingrequest
 
 import (
 	"bytes"
+	"encoding/json"
 	"text/template"
 
 	corev1 "k8s.io/api/core/v1"
@@ -25,7 +26,7 @@ func NewCustomEnvParser(envMap []corev1.EnvVar, cache map[string]interface{}) *C
 func (c *CustomEnvParser) Parse() (map[string]interface{}, error) {
 	data := make(map[string]interface{})
 	for _, v := range c.EnvMap {
-		tmpl, err := template.New("set").Parse(v.Value)
+		tmpl, err := template.New("set").Funcs(template.FuncMap{"json": marshalToJSON}).Parse(v.Value)
 		if err != nil {
 			return data, err
 		}
@@ -42,3 +43,10 @@ func (c *CustomEnvParser) Parse() (map[string]interface{}, error) {
 	}
 	return data, nil
 }
+func marshalToJSON(m interface{}) (string, error) {
+	bytes, err := json.Marshal(m)
+	if err != nil {
+		return "", err
+	}
+	return string(bytes), nil
+}


Test patch:
diff --git a/pkg/controller/servicebindingrequest/custom_env_parser_test.go b/pkg/controller/servicebindingrequest/custom_env_parser_test.go
index 9dcf4b25..8e9988a0 100644
--- a/pkg/controller/servicebindingrequest/custom_env_parser_test.go
+++ b/pkg/controller/servicebindingrequest/custom_env_parser_test.go
@@ -74,3 +74,62 @@ func TestCustomEnvPath_Parse_exampleCase(t *testing.T) {
 	str2 := values["JDBC_PASSWORD"]
 	require.Equal(t, "database-pass", str2, "Connection string is not matching")
 }
+
+func TestCustomEnvPath_Parse_ToJson(t *testing.T) {
+	cache := map[string]interface{}{
+		"spec": map[string]interface{}{
+			"dbName": "database-name",
+		},
+		"status": map[string]interface{}{
+			"creds": map[string]interface{}{
+				"user": "database-user",
+				"pass": "database-pass",
+			},
+		},
+	}
+
+	envMap := []corev1.EnvVar{
+		corev1.EnvVar{
+			Name:  "root",
+			Value: `{{ json . }}`,
+		},
+		corev1.EnvVar{
+			Name:  "spec",
+			Value: `{{ json .spec }}`,
+		},
+		corev1.EnvVar{
+			Name:  "status",
+			Value: `{{ json .status }}`,
+		},
+		corev1.EnvVar{
+			Name:  "creds",
+			Value: `{{ json .status.creds }}`,
+		},
+		corev1.EnvVar{
+			Name:  "dbName",
+			Value: `{{ json .spec.dbName }}`,
+		},
+		corev1.EnvVar{
+			Name:  "notExist",
+			Value: `{{ json .notExist }}`,
+		},
+	}
+	customEnvPath := NewCustomEnvParser(envMap, cache)
+	values, err := customEnvPath.Parse()
+	if err != nil {
+		t.Error(err)
+		t.Fail()
+	}
+	str := values["root"]
+	require.Equal(t, `{"spec":{"dbName":"database-name"},"status":{"creds":{"pass":"database-pass","user":"database-user"}}}`, str, "root path json string is not matching")
+	str2 := values["spec"]
+	require.Equal(t, `{"dbName":"database-name"}`, str2, "spec json string is not matching")
+	str3 := values["status"]
+	require.Equal(t, `{"creds":{"pass":"database-pass","user":"database-user"}}`, str3, "status json string is not matching")
+	str4 := values["creds"]
+	require.Equal(t, `{"pass":"database-pass","user":"database-user"}`, str4, "creds json string is not matching")
+	str5 := values["dbName"]
+	require.Equal(t, `"database-name"`, str5, "dbName json string is not matching")
+	str6 := values["notExist"]
+	require.Equal(t, "null", str6, "notExist json string is not matching")
+}