Repository: redhat-developer/service-binding-operator
Pull request #729 (2020-10-14 15:54:34)

Fix annotations with sliceOfStrings
### Motivation

Implements:
* https://github.com/k8s-service-bindings/spec/issues/131
* [APPSVC-739](https://issues.redhat.com/browse/APPSVC-739)

Fixes:
* https://github.com/redhat-developer/service-binding-operator/issues/728
* [APPSVC-729](https://issues.redhat.com/browse/APPSVC-729)

The `unsupported type` error is thrown because when using a list of strings (a.k.a. slice of strings) the env variable building piece of SBO does not recognize it because it ends up as `[]string` which is not the case of `[]interface{}` or any other considered case.

### Changes

This PR:
* Adds a case for `[]string` in a similar way as `[]interface{}` is in the env variable build part of SBO.
* Improves a bit of error logs related to the issue.
* Implements case for `sliceOfStrings` without `sourceValue`
* Adds acceptance tests

### Testing

`make test-unit`
`TEST_ACCEPTANCE_TAGS=@annotations make test-acceptance`


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 **pmacik** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @pmacik` 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":["pmacik"]} -->
DhritiShikhar: @pmacik 

Is there even a use-case for `[]interface{}`?
I referred this -> https://github.com/golang/go/wiki/InterfaceSlice 
DhritiShikhar: @pmacik 

I edited postgresql CRD to include annotation `service.binding/tags: path={.spec.tags},elementType=sliceOfStrings` but I corresponding envVar wasnot generated.

Here is the video of what I did to test your PR - https://youtu.be/HZpFbZ2Z7ks
pmacik: > I edited postgresql CRD to include annotation `service.binding/tags: path={.spec.tags},elementType=sliceOfStrings` but I corresponding envVar wasnot generated.
> 
> Here is the video of what I did to test your PR - https://youtu.be/HZpFbZ2Z7ks

@DhritiShikhar There is a problem currently in `master` with the `sliceOfStrings` (https://github.com/redhat-developer/service-binding-operator/issues/728) and this PR fixes part of it.
DhritiShikhar: > @DhritiShikhar There is a problem currently in `master` with the `sliceOfStrings` (#728) and this PR suggests a fix for part of it.

Got it.
pmacik: > @pmacik
> 
> Is there even a use-case for `[]interface{}`?
> I referred this -> https://github.com/golang/go/wiki/InterfaceSlice

To be honest, I'm not sure - @isutton, any thoughts?
DhritiShikhar: /lgtm 
openshift-ci-robot: New changes are detected. LGTM label has been removed.
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 **dhritishikhar** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @dhritishikhar` 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":["dhritishikhar"]} -->
pmacik: Rebased and squashed commits after update...
DhritiShikhar: /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/729#issuecomment-714402608" title="Approved">DhritiShikhar</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)~~ [DhritiShikhar]

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":[]} -->
openshift-merge-robot: @pmacik: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/4.5-acceptance | e6342f11ddbd9b03f4341a5aee514bc8a380d1d1 | [link](https://prow.ci.openshift.org/view/gs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/729/pull-ci-redhat-developer-service-binding-operator-master-4.5-acceptance/1319227775713808384) | `/test 4.5-acceptance`

[Full PR test history](https://prow.ci.openshift.org/pr-history?org=redhat-developer&repo=service-binding-operator&pr=729). [Your PR dashboard](https://prow.ci.openshift.org/pr?query=is:pr+state:open+author:pmacik).

<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. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
pmacik: /retest

openshift-merge-robot: @pmacik: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/4.5-acceptance | e6342f11ddbd9b03f4341a5aee514bc8a380d1d1 | [link](https://prow.ci.openshift.org/view/gs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/729/pull-ci-redhat-developer-service-binding-operator-master-4.5-acceptance/1319281431460974592) | `/test 4.5-acceptance`

[Full PR test history](https://prow.ci.openshift.org/pr-history?org=redhat-developer&repo=service-binding-operator&pr=729). [Your PR dashboard](https://prow.ci.openshift.org/pr?query=is:pr+state:open+author:pmacik).

<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. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
pmacik: /retest
openshift-ci-robot: New changes are detected. LGTM label has been removed.
pmacik: /test all
openshift-merge-robot: @pmacik: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/4.5-acceptance | 3fc8dc8a273140bbe072cfb2d391b5549d8b0659 | [link](https://prow.ci.openshift.org/view/gs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/729/pull-ci-redhat-developer-service-binding-operator-master-4.5-acceptance/1320755564740874240) | `/test 4.5-acceptance`

[Full PR test history](https://prow.ci.openshift.org/pr-history?org=redhat-developer&repo=service-binding-operator&pr=729). [Your PR dashboard](https://prow.ci.openshift.org/pr?query=is:pr+state:open+author:pmacik).

<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. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
pmacik: /test all
openshift-merge-robot: @pmacik: The following test **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/4.5-acceptance | e1e61108f2e3d05581ae069ce044f34a5554226a | [link](https://prow.ci.openshift.org/view/gs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/729/pull-ci-redhat-developer-service-binding-operator-master-4.5-acceptance/1320832554986639360) | `/test 4.5-acceptance`

[Full PR test history](https://prow.ci.openshift.org/pr-history?org=redhat-developer&repo=service-binding-operator&pr=729). [Your PR dashboard](https://prow.ci.openshift.org/pr?query=is:pr+state:open+author:pmacik).

<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. I understand the commands that are listed [here](https://go.k8s.io/bot-commands).
</details>
<!-- test report -->
pmacik: /retest
pmacik: > Is there even a use-case for `[]interface{}`?
> I referred this -> https://github.com/golang/go/wiki/InterfaceSlice

Actually `[]string` is [not supported by the k8s apimachinery](https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/runtime/converter.go#L468) and fails with panic `cannot deep copy []string`. That is why I needed to update the [sliceOfStringsFromPathDefinition.Apply](https://github.com/redhat-developer/service-binding-operator/pull/729/files#diff-683b572d1128c0146299426b61dba4689c73102cdfb31e0033473c11279ce830R289) method accordingly
Avni-Sharma: /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/729#issuecomment-718964564" title="Approved">Avni-Sharma</a>*, *<a href="https://github.com/redhat-developer/service-binding-operator/pull/729#issuecomment-714402608" title="Approved">DhritiShikhar</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)~~ [Avni-Sharma,DhritiShikhar]

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/examples/java_postgresql_customvar/README.md b/examples/java_postgresql_customvar/README.md
index 9e388528..ec8e7054 100644
--- a/examples/java_postgresql_customvar/README.md
+++ b/examples/java_postgresql_customvar/README.md
@@ -100,7 +100,7 @@ kubectl edit crd databases.postgresql.baiju.dev
 Add these annotations under `metadata.annotations` along with other annotations.
 
 ```yaml
-service.binding/tags: path={.spec.tags}
+service.binding/tags: path={.spec.tags},elementType=sliceOfStrings
 service.binding/userLabels: path={.spec.userLabels},elementType=map
 service.binding/secretName: path={.spec.secretName},elementType=sliceOfMaps,sourceKey=type,sourceValue=secret
 ```
@@ -324,7 +324,8 @@ DATABASE_PASSWORD=password
 DATABASE_SECRETNAME_PRIMARYSECRETNAME=example-primaryuser
 DATABASE_SECRETNAME_ROOTSECRETNAME=example-rootuser
 DATABASE_SECRETNAME_SECONDARYSECRETNAME=example-secondaryuser
-DATABASE_TAGS=[centos7-12.3 centos7-12.4]
+DATABASE_TAGS_0=centos7-12.3
+DATABASE_TAGS_1=centos7-12.4
 DATABASE_USER=postgres
 DATABASE_USERLABELS_ARCHIVE=false
 DATABASE_USERLABELS_ENVIRONMENT=demo
diff --git a/pkg/controller/servicebinding/binding/definition.go b/pkg/controller/servicebinding/binding/definition.go
index 1548b607..822aecdb 100644
--- a/pkg/controller/servicebinding/binding/definition.go
+++ b/pkg/controller/servicebinding/binding/definition.go
@@ -286,12 +286,19 @@ func (d *sliceOfStringsFromPathDefinition) Apply(u *unstructured.Unstructured) (
 		return nil, errors.New("not found")
 	}
 
-	v := make([]string, 0, len(val))
+	v := make([]interface{}, 0, len(val))
 	for _, e := range val {
-		if mm, ok := e.(map[string]interface{}); ok {
-			sourceValue := mm[d.sourceValue].(string)
-			v = append(v, sourceValue)
+		if d.sourceValue != "" {
+			if mm, ok := e.(map[string]interface{}); ok {
+				sourceValue := mm[d.sourceValue].(string)
+				v = append(v, sourceValue)
+			}
+		} else {
+			if x, ok := e.(string); ok {
+				v = append(v, x)
+			}
 		}
+
 	}
 
 	return &value{v: map[string]interface{}{d.outputName: v}}, nil
diff --git a/pkg/controller/servicebinding/binding/model.go b/pkg/controller/servicebinding/binding/model.go
index deb7f228..1a692f94 100644
--- a/pkg/controller/servicebinding/binding/model.go
+++ b/pkg/controller/servicebinding/binding/model.go
@@ -13,7 +13,7 @@ type model struct {
 	objectType  objectType
 	sourceKey   string
 	sourceValue string
-	bindAs		BindingType
+	bindAs      BindingType
 }
 
 func (m *model) isStringElementType() bool {
diff --git a/pkg/controller/servicebinding/envvars/envvars.go b/pkg/controller/servicebinding/envvars/envvars.go
index fe54a6d7..cc874512 100644
--- a/pkg/controller/servicebinding/envvars/envvars.go
+++ b/pkg/controller/servicebinding/envvars/envvars.go
@@ -2,6 +2,7 @@ package envvars
 
 import (
 	"errors"
+	"fmt"
 	"sort"
 	"strconv"
 	"strings"
@@ -66,12 +67,14 @@ func Build(obj interface{}, path ...string) (map[string]string, error) {
 		return buildString(strconv.FormatInt(val, 10), path), nil
 	case float64:
 		return buildString(strconv.FormatFloat(val, 'f', -1, 64), path), nil
+	case []string:
+		return buildSliceOfStrings(val, path)
 	case []interface{}:
 		return buildSliceOfInterface(val, path)
 	case bool:
 		return buildString(strconv.FormatBool(val), path), nil
 	default:
-		return nil, errUnsupportedType
+		return nil, fmt.Errorf("%v: %v", errUnsupportedType, val)
 	}
 }
 
@@ -116,6 +119,19 @@ func buildMap(obj map[string]interface{}, path []string) (map[string]string, err
 	return envVars, nil
 }
 
+// buildSliceOfStrings returns a slice containing environment variables for
+// all the leaves present in the given 'obj' slice of strings.
+func buildSliceOfStrings(obj []string, acc []string) (map[string]string, error) {
+	envVars := make(map[string]string)
+	for i, v := range obj {
+		k := strconv.Itoa(i)
+		if err := buildInner(acc, k, v, envVars); err != nil {
+			return nil, err
+		}
+	}
+	return envVars, nil
+}
+
 // buildSliceOfInterface retrurns a slice containing environment variables for
 // all the leaves present in the given 'obj' slice.
 func buildSliceOfInterface(obj []interface{}, acc []string) (map[string]string, error) {
diff --git a/pkg/controller/servicebinding/nested/nested.go b/pkg/controller/servicebinding/nested/nested.go
index 8d0aa237..f9f07626 100644
--- a/pkg/controller/servicebinding/nested/nested.go
+++ b/pkg/controller/servicebinding/nested/nested.go
@@ -68,7 +68,7 @@ func convertToSlice(src interface{}) ([]interface{}, error) {
 			obj[i] = e
 		}
 	default:
-		return nil, unsupportedTypeErr
+		return nil, fmt.Errorf("%v: %v", unsupportedTypeErr, t)
 	}
 	return obj, nil
 }


Test patch:
diff --git a/pkg/controller/servicebinding/binding/definition_test.go b/pkg/controller/servicebinding/binding/definition_test.go
index 3df7e396..e0c19074 100644
--- a/pkg/controller/servicebinding/binding/definition_test.go
+++ b/pkg/controller/servicebinding/binding/definition_test.go
@@ -149,7 +149,7 @@ func TestSliceOfStringsFromPath(t *testing.T) {
 	})
 	require.NoError(t, err)
 	v := map[string]interface{}{
-		"bootstrap": []string{"www.example.com", "secure.example.com"},
+		"bootstrap": []interface{}{"www.example.com", "secure.example.com"},
 	}
 	require.Equal(t, v, val.Get())
 }
diff --git a/pkg/controller/servicebinding/binding/spec_test.go b/pkg/controller/servicebinding/binding/spec_test.go
index e674437a..69dfdd8c 100644
--- a/pkg/controller/servicebinding/binding/spec_test.go
+++ b/pkg/controller/servicebinding/binding/spec_test.go
@@ -353,11 +353,11 @@ func TestSpecHandler(t *testing.T) {
 			},
 		},
 		expectedData: map[string]interface{}{
-			"bootstrap": []string{"secure.example.com", "www.example.com"},
+			"bootstrap": []interface{}{"secure.example.com", "www.example.com"},
 		},
 		expectedRawData: map[string]interface{}{
 			"status": map[string]interface{}{
-				"bootstrap": []string{"secure.example.com", "www.example.com"},
+				"bootstrap": []interface{}{"secure.example.com", "www.example.com"},
 			},
 		},
 	}))
@@ -377,11 +377,11 @@ func TestSpecHandler(t *testing.T) {
 			},
 		},
 		expectedData: map[string]interface{}{
-			"urls": []string{"secure.example.com", "www.example.com"},
+			"urls": []interface{}{"secure.example.com", "www.example.com"},
 		},
 		expectedRawData: map[string]interface{}{
 			"status": map[string]interface{}{
-				"urls": []string{"secure.example.com", "www.example.com"},
+				"urls": []interface{}{"secure.example.com", "www.example.com"},
 			},
 		},
 	}))
diff --git a/pkg/controller/servicebinding/envvars/envvars_test.go b/pkg/controller/servicebinding/envvars/envvars_test.go
index 6acef446..14a368d0 100644
--- a/pkg/controller/servicebinding/envvars/envvars_test.go
+++ b/pkg/controller/servicebinding/envvars/envvars_test.go
@@ -136,6 +136,21 @@ func TestBuild(t *testing.T) {
 			},
 			src: "",
 		},
+		{
+			name: "should create envvars for each string in slice",
+			expected: map[string]string{
+				"TAGS_0": "knowledge",
+				"TAGS_1": "is",
+				"TAGS_2": "power",
+			},
+			src: map[string]interface{}{
+				"tags": []string{
+					"knowledge",
+					"is",
+					"power",
+				},
+			},
+		},
 	}
 
 	for _, tc := range testCases {
diff --git a/test/acceptance/features/bindAppToServiceAnnotations.feature b/test/acceptance/features/bindAppToServiceAnnotations.feature
index 3e7a6e28..ecf0fa71 100644
--- a/test/acceptance/features/bindAppToServiceAnnotations.feature
+++ b/test/acceptance/features/bindAppToServiceAnnotations.feature
@@ -135,6 +135,133 @@ Feature: Bind an application to a service using annotations
         And jq ".status.conditions[] | select(.type=="CollectionReady").status" of Service Binding "rsa-2" should be changed to "True"
         And jq ".status.conditions[] | select(.type=="InjectionReady").status" of Service Binding "rsa-2" should be changed to "True"
 
+    Scenario: Each value in referred slice of strings from service resource gets injected into app as separate env variable
+        Given Generic test application "slos-app" is running
+        And The Custom Resource Definition is present
+            """
+            apiVersion: apiextensions.k8s.io/v1beta1
+            kind: CustomResourceDefinition
+            metadata:
+                name: backends.stable.example.com
+                annotations:
+                    service.binding/tags: path={.spec.tags},elementType=sliceOfStrings
+            spec:
+                group: stable.example.com
+                versions:
+                  - name: v1
+                    served: true
+                    storage: true
+                scope: Namespaced
+                names:
+                    plural: backends
+                    singular: backend
+                    kind: Backend
+                    shortNames:
+                      - bk
+            """
+        And The Custom Resource is present
+            """
+            apiVersion: stable.example.com/v1
+            kind: Backend
+            metadata:
+                name: slos-service
+            spec:
+                tags:
+                  - knowledge
+                  - is
+                  - power
+            status:
+                somestatus: good
+            """
+        When Service Binding is applied
+            """
+            apiVersion: operators.coreos.com/v1alpha1
+            kind: ServiceBinding
+            metadata:
+                name: slos-binding
+            spec:
+                services:
+                  - group: stable.example.com
+                    version: v1
+                    kind: Backend
+                    name: slos-service
+                application:
+                    name: slos-app
+                    group: apps
+                    version: v1
+                    resource: deployments
+            """
+        Then jq ".status.conditions[] | select(.type=="CollectionReady").status" of Service Binding "slos-binding" should be changed to "True"
+        And jq ".status.conditions[] | select(.type=="InjectionReady").status" of Service Binding "slos-binding" should be changed to "True"
+        And The application env var "BACKEND_TAGS_0" has value "knowledge"
+        And The application env var "BACKEND_TAGS_1" has value "is"
+        And The application env var "BACKEND_TAGS_2" has value "power"
+
+    Scenario: Values extracted from each map by a given key in referred slice of maps from service resource gets injected into app as separate env variable
+        Given Generic test application "slom-to-slos-app" is running
+        And The Custom Resource Definition is present
+            """
+            apiVersion: apiextensions.k8s.io/v1beta1
+            kind: CustomResourceDefinition
+            metadata:
+                name: backends.stable.example.com
+                annotations:
+                    service.binding/url: path={.spec.connections},elementType=sliceOfStrings,sourceValue=url
+            spec:
+                group: stable.example.com
+                versions:
+                  - name: v1
+                    served: true
+                    storage: true
+                scope: Namespaced
+                names:
+                    plural: backends
+                    singular: backend
+                    kind: Backend
+                    shortNames:
+                      - bk
+            """
+        And The Custom Resource is present
+            """
+            apiVersion: stable.example.com/v1
+            kind: Backend
+            metadata:
+                name: slom-to-slos-service
+            spec:
+                connections:
+                  - type: primary
+                    url: primary.example.com
+                  - type: secondary
+                    url: secondary.example.com
+                  - type: '404'
+                    url: black-hole.example.com
+            status:
+                somestatus: good
+            """
+        When Service Binding is applied
+            """
+            apiVersion: operators.coreos.com/v1alpha1
+            kind: ServiceBinding
+            metadata:
+                name: slom-to-slos-binding
+            spec:
+                services:
+                  - group: stable.example.com
+                    version: v1
+                    kind: Backend
+                    name: slom-to-slos-service
+                application:
+                    name: slom-to-slos-app
+                    group: apps
+                    version: v1
+                    resource: deployments
+            """
+        Then jq ".status.conditions[] | select(.type=="CollectionReady").status" of Service Binding "slom-to-slos-binding" should be changed to "True"
+        And jq ".status.conditions[] | select(.type=="InjectionReady").status" of Service Binding "slom-to-slos-binding" should be changed to "True"
+        And The application env var "BACKEND_URL_0" has value "primary.example.com"
+        And The application env var "BACKEND_URL_1" has value "secondary.example.com"
+        And The application env var "BACKEND_URL_2" has value "black-hole.example.com"
+
     Scenario: Each value in referred slice of maps from service resource gets injected into app as separate env variable
         Given Generic test application "slom-app" is running
         And The Custom Resource Definition is present