Repository: redhat-developer/service-binding-operator
Pull request #350 (2020-02-26 12:33:41)

Support creation of managed secret without associating it to a workload
Task: https://issues.redhat.com/browse/APPSVC-9

**Description**
Add support for "generic binding".
"In the service catalog UX this meant I just want the information dumped into a Secret, and then I'll choose what to do with it after that. This is good for referencing the Secret from other things like Jobs, or a Tekton pipeline, where your controller may not be able to directly modify a pod spec.
 
The request for this is coming up in discussions about transitioning some IBM brokers off of service catalog to operators instead. I think the use case is valid so we should consider it."

**Acceptance Criteria**
1. If the `ApplicationSelectors` is skipped, only the binding secret should be created with the name of the secret being dumped in the status for arbitrary consumption.
2. If the CR is updated with the `ApplicationSelectors` section, then the controller should inject the previously created secret into the deployment/deploymentconfig.
3. Irrespective of (2), If the credentials change on the backing service side, the binding secret should be updated as well 

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

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/unit | 6495e55a93139ff1a9cadc8baf1986db2173e160 | [link](https://prow.svc.ci.openshift.org/view/gcs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/350/pull-ci-redhat-developer-service-binding-operator-master-unit/1089) | `/test unit`

[Full PR test history](https://prow.svc.ci.openshift.org/pr-history?org=redhat-developer&repo=service-binding-operator&pr=350). [Your PR dashboard](https://prow.svc.ci.openshift.org/pr?query=is:pr+state:open+author:DhritiShikhar). Please help us cut down on flakes by [linking to](https://github.com/kubernetes/community/blob/master/contributors/devel/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/redhat-developer/service-binding-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<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 -->
openshift-ci-robot: @DhritiShikhar: The following tests **failed**, say `/retest` to rerun all failed tests:

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/unit | 6495e55a93139ff1a9cadc8baf1986db2173e160 | [link](https://prow.svc.ci.openshift.org/view/gcs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/350/pull-ci-redhat-developer-service-binding-operator-master-unit/1089) | `/test unit`
ci/prow/4.4-unit | 6495e55a93139ff1a9cadc8baf1986db2173e160 | [link](https://prow.svc.ci.openshift.org/view/gcs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/350/pull-ci-redhat-developer-service-binding-operator-master-4.4-unit/43) | `/test 4.4-unit`

[Full PR test history](https://prow.svc.ci.openshift.org/pr-history?org=redhat-developer&repo=service-binding-operator&pr=350). [Your PR dashboard](https://prow.svc.ci.openshift.org/pr?query=is:pr+state:open+author:DhritiShikhar). Please help us cut down on flakes by [linking to](https://github.com/kubernetes/community/blob/master/contributors/devel/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/redhat-developer/service-binding-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<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 -->
DhritiShikhar: /assign @isutton 
codecov[bot]: # [Codecov](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/350?src=pr&el=h1) Report
> Merging [#350](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/350?src=pr&el=desc) into [master](https://codecov.io/gh/redhat-developer/service-binding-operator/commit/619810c7390cd56500becdce946d493634cc58ca?src=pr&el=desc) will **increase** coverage by `0.86%`.
> The diff coverage is `62.5%`.

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

```diff
@@            Coverage Diff             @@
##           master     #350      +/-   ##
==========================================
+ Coverage   62.24%   63.11%   +0.86%     
==========================================
  Files          21       21              
  Lines        1380     1380              
==========================================
+ Hits          859      871      +12     
+ Misses        388      378      -10     
+ Partials      133      131       -2
```


| [Impacted Files](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/350?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pkg/controller/servicebindingrequest/reconciler.go](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/350/diff?src=pr&el=tree#diff-cGtnL2NvbnRyb2xsZXIvc2VydmljZWJpbmRpbmdyZXF1ZXN0L3JlY29uY2lsZXIuZ28=) | `48.57% <0%> (ø)` | :arrow_up: |
| [pkg/controller/servicebindingrequest/common.go](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/350/diff?src=pr&el=tree#diff-cGtnL2NvbnRyb2xsZXIvc2VydmljZWJpbmRpbmdyZXF1ZXN0L2NvbW1vbi5nbw==) | `55.88% <100%> (+20.58%)` | :arrow_up: |
| [pkg/controller/servicebindingrequest/planner.go](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/350/diff?src=pr&el=tree#diff-cGtnL2NvbnRyb2xsZXIvc2VydmljZWJpbmRpbmdyZXF1ZXN0L3BsYW5uZXIuZ28=) | `88% <100%> (ø)` | :arrow_up: |
| [pkg/controller/servicebindingrequest/binder.go](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/350/diff?src=pr&el=tree#diff-cGtnL2NvbnRyb2xsZXIvc2VydmljZWJpbmRpbmdyZXF1ZXN0L2JpbmRlci5nbw==) | `60.27% <100%> (+1.74%)` | :arrow_up: |
| [pkg/controller/servicebindingrequest/binding.go](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/350/diff?src=pr&el=tree#diff-cGtnL2NvbnRyb2xsZXIvc2VydmljZWJpbmRpbmdyZXF1ZXN0L2JpbmRpbmcuZ28=) | `64.78% <83.33%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/350?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/350?src=pr&el=footer). Last update [619810c...45abadc](https://codecov.io/gh/redhat-developer/service-binding-operator/pull/350?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

sbose78: I don't see code changes, only tests?
DhritiShikhar: @sbose78 All the 3 acceptance criteria is already supported. I wrote test to confirm the 3 acceptance criteria in the task:

1. If the `ApplicationSelectors` is skipped, only the binding secret should be created with the name of the secret being dumped in the status for arbitrary consumption.

2. If the CR is updated with the `ApplicationSelectors` section, then the controller should inject the previously created secret into the deployment/deploymentconfig.

3. Irrespective of (2), If the credentials change on the backing service side, the binding secret should be updated as well.


sbose78: Thank you!
sbose78: The API validations don't let it go through..

![image](https://user-images.githubusercontent.com/545280/75362003-1e927c80-5886-11ea-866e-456ddddef948.png)

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

Test name | Commit | Details | Rerun command
--- | --- | --- | ---
ci/prow/4.4-e2e | 0d204837ec0b55f94b87cf9443a52659b81fea43 | [link](https://prow.svc.ci.openshift.org/view/gcs/origin-ci-test/pr-logs/pull/redhat-developer_service-binding-operator/350/pull-ci-redhat-developer-service-binding-operator-master-4.4-e2e/103) | `/test 4.4-e2e`

[Full PR test history](https://prow.svc.ci.openshift.org/pr-history?org=redhat-developer&repo=service-binding-operator&pr=350). [Your PR dashboard](https://prow.svc.ci.openshift.org/pr?query=is:pr+state:open+author:DhritiShikhar). Please help us cut down on flakes by [linking to](https://github.com/kubernetes/community/blob/master/contributors/devel/flaky-tests.md#filing-issues-for-flaky-tests) an [open issue](https://github.com/redhat-developer/service-binding-operator/issues?q=is:issue+is:open) when you hit one in your PR.

<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 -->
sbose78: .. but you would then get this

```
2020-02-26T11:29:56.327-0500    DEBUG   secret  Secret already exists, updating contents instead...     {"Namespace": "sbose", "Name": "binding-request"}
E0226 11:29:56.372848     560 runtime.go:78] Observed a panic: "invalid memory address or nil pointer dereference" (runtime error: invalid memory address or nil pointer dereference)
goroutine 914 [running]:
k8s.io/apimachinery/pkg/util/runtime.logPanic(0x2127980, 0x30586a0)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go:74 +0xa3
k8s.io/apimachinery/pkg/util/runtime.HandleCrash(0x0, 0x0, 0x0)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go:48 +0x82
panic(0x2127980, 0x30586a0)
        /usr/local/Cellar/go/1.13.8/libexec/src/runtime/panic.go:679 +0x1b2
github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest.(*Binder).search(0xc00027bec0, 0x2, 0xc0004559a0, 0xf)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest/binder.go:53 +0x7c
github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest.(*Binder).Bind(0xc00027bec0, 0xc00088da28, 0x2, 0x2, 0xc0004559a0, 0xf)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest/binder.go:539 +0x2f
github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest.(*ServiceBinder).Bind(0xc0001b34a0, 0x232b02e, 0x30, 0x0, 0x0)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest/binding.go:232 +0x179
github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest.(*Reconciler).bind(0xc0003b2ba0, 0xc000780100, 0xc0001b34a0, 0xc00034a1b8, 0x0, 0x0, 0x0, 0x0)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest/reconciler.go:93 +0xde
github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest.(*Reconciler).Reconcile(0xc0003b2ba0, 0xc000b02fd9, 0x5, 0xc000b02fc0, 0xf, 0xc00088dcd8, 0xc0007485a0, 0xc000748518, 0x25002e0)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest/reconciler.go:176 +0x5c2
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler(0xc000366cc0, 0x217efe0, 0xc00038c380, 0x0)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:256 +0x162
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem(0xc000366cc0, 0xc00012a700)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:232 +0xcb
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).worker(0xc000366cc0)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:211 +0x2b
k8s.io/apimachinery/pkg/util/wait.JitterUntil.func1(0xc00089a8d0)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:152 +0x5e
k8s.io/apimachinery/pkg/util/wait.JitterUntil(0xc00089a8d0, 0x3b9aca00, 0x0, 0xc000ab0501, 0xc0000be240)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:153 +0xf8
k8s.io/apimachinery/pkg/util/wait.Until(0xc00089a8d0, 0x3b9aca00, 0xc0000be240)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88 +0x4d
created by sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func1
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:193 +0x328
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
        panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x1fb694c]

goroutine 914 [running]:
k8s.io/apimachinery/pkg/util/runtime.HandleCrash(0x0, 0x0, 0x0)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/k8s.io/apimachinery/pkg/util/runtime/runtime.go:55 +0x105
panic(0x2127980, 0x30586a0)
        /usr/local/Cellar/go/1.13.8/libexec/src/runtime/panic.go:679 +0x1b2
github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest.(*Binder).search(0xc00027bec0, 0x2, 0xc0004559a0, 0xf)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest/binder.go:53 +0x7c
github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest.(*Binder).Bind(0xc00027bec0, 0xc00088da28, 0x2, 0x2, 0xc0004559a0, 0xf)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest/binder.go:539 +0x2f
github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest.(*ServiceBinder).Bind(0xc0001b34a0, 0x232b02e, 0x30, 0x0, 0x0)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest/binding.go:232 +0x179
github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest.(*Reconciler).bind(0xc0003b2ba0, 0xc000780100, 0xc0001b34a0, 0xc00034a1b8, 0x0, 0x0, 0x0, 0x0)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest/reconciler.go:93 +0xde
github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest.(*Reconciler).Reconcile(0xc0003b2ba0, 0xc000b02fd9, 0x5, 0xc000b02fc0, 0xf, 0xc00088dcd8, 0xc0007485a0, 0xc000748518, 0x25002e0)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/pkg/controller/servicebindingrequest/reconciler.go:176 +0x5c2
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler(0xc000366cc0, 0x217efe0, 0xc00038c380, 0x0)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:256 +0x162
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem(0xc000366cc0, 0xc00012a700)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:232 +0xcb
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).worker(0xc000366cc0)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:211 +0x2b
k8s.io/apimachinery/pkg/util/wait.JitterUntil.func1(0xc00089a8d0)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:152 +0x5e
k8s.io/apimachinery/pkg/util/wait.JitterUntil(0xc00089a8d0, 0x3b9aca00, 0x0, 0xc000ab0501, 0xc0000be240)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:153 +0xf8
k8s.io/apimachinery/pkg/util/wait.Until(0xc00089a8d0, 0x3b9aca00, 0xc0000be240)
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/k8s.io/apimachinery/pkg/util/wait/wait.go:88 +0x4d
created by sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func1
        /Users/sbose/appbinding/src/github.com/redhat-developer/service-binding-operator/vendor/sigs.k8s.io/controller-runtime/pkg/internal/controller/controller.go:193 +0x328
```
sbose78: I tried making a PR to your branch but the history was a bit messed up ( my bad probably ), so created one against the main repo:
https://github.com/redhat-developer/service-binding-operator/pull/351 . I will not be merging this, we'll merge your PR ( current one ).

I've tested https://github.com/redhat-developer/service-binding-operator/pull/351, it works, but doesn't provide any feedback in the `status` block. 

* Could you please take in the changes, and then..
* make improvements if needed, 
* ensure status is updated
* add more tests based on the new changes
isutton: > I tried making a PR to your branch but the history was a bit messed up ( my bad probably ), so created one against the main repo:
> #351 . I will not be merging #351, we'll merge your PR ( current one ).
> 
> I've tested #351, it works, but doesn't provide any feedback in the `status` block.
> 
>     * Could you please take in the changes, and then..
> 
>     * make improvements if needed,
> 
>     * ensure status is updated
> 
>     * add more tests based on the new changes
> 
> 
> Here's the only relevant commit there.
> [ef6f306](https://github.com/redhat-developer/service-binding-operator/commit/ef6f3066ee2d79e6cd4898da41aac35c3b760fbc)

Shouldn't we leave those changes for another PR, since the implemented tests already seem to validate the initial assumption that it currently works?
sbose78: > Shouldn't we leave those changes for another PR, since the implemented tests already seem to validate the initial assumption that it currently works?

Sorry, which changes are you saying we should skip in this PR ? 
sbose78: How's this going? @DhritiShikhar 
openshift-ci-robot: @DhritiShikhar: PR needs rebase.

<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>
isutton: > > Shouldn't we leave those changes for another PR, since the implemented tests already seem to validate the initial assumption that it currently works?
> 
> Sorry, which changes are you saying we should skip in this PR ?

Related to the lack of feedback in the `status` block.


sbose78: But the `status` is empty.
DhritiShikhar: @sbose78 Hmm.. but I added check for `status` in my test. It's not empty there -> https://github.com/redhat-developer/service-binding-operator/pull/350/commits/572adc74db48e12ccf905b6b14dfb8633e93bb48

Both `status.BindingStatus` and `status.Conditions` are non-empty with desirable result.

Patch:
diff --git a/Makefile b/Makefile
index 64fd529e..2d0b97ae 100644
--- a/Makefile
+++ b/Makefile
@@ -113,7 +113,7 @@ GOCOV ?= "-covermode=atomic -coverprofile REPLACE_FILE"
 
 GIT_COMMIT_ID ?= $(shell git rev-parse --short HEAD)
 
-OPERATOR_VERSION ?= 0.1.1
+OPERATOR_VERSION ?= 0.1.0
 OPERATOR_GROUP ?= ${GO_PACKAGE_ORG_NAME}
 OPERATOR_IMAGE ?= quay.io/${OPERATOR_GROUP}/${GO_PACKAGE_REPO_NAME}
 OPERATOR_IMAGE_REL ?= quay.io/${OPERATOR_GROUP}/app-binding-operator
@@ -122,8 +122,8 @@ OPERATOR_TAG_LONG ?= $(OPERATOR_VERSION)-$(GIT_COMMIT_ID)
 OPERATOR_IMAGE_BUILDER ?= buildah
 OPERATOR_SDK_EXTRA_ARGS ?= "--debug"
 COMMIT_COUNT := $(shell git rev-list --count HEAD)
-BUNDLE_VERSION ?= $(OPERATOR_VERSION)-$(COMMIT_COUNT)
-BASE_BUNDLE_VERSION ?= 0.1.0
+BASE_BUNDLE_VERSION ?= $(OPERATOR_VERSION)
+BUNDLE_VERSION ?= $(BASE_BUNDLE_VERSION)-$(COMMIT_COUNT)
 OPERATOR_IMAGE_REF ?= $(OPERATOR_IMAGE_REL):$(GIT_COMMIT_ID)
 CSV_PACKAGE_NAME ?= $(GO_PACKAGE_REPO_NAME)
 CSV_CREATION_TIMESTAMP ?= $(shell TZ=GMT date '+%FT%TZ')
diff --git a/deploy/crds/apps.openshift.io_servicebindingrequests_crd.yaml b/deploy/crds/apps.openshift.io_servicebindingrequests_crd.yaml
index 8337c8ea..676a4306 100644
--- a/deploy/crds/apps.openshift.io_servicebindingrequests_crd.yaml
+++ b/deploy/crds/apps.openshift.io_servicebindingrequests_crd.yaml
@@ -253,8 +253,6 @@ spec:
             mountPathPrefix:
               description: MountPathPrefix is the prefix for volume mount
               type: string
-          required:
-          - applicationSelector
           type: object
         status:
           description: ServiceBindingRequestStatus defines the observed state of ServiceBindingRequest
diff --git a/pkg/apis/apps/v1alpha1/servicebindingrequest_types.go b/pkg/apis/apps/v1alpha1/servicebindingrequest_types.go
index 4a5c7743..31b11993 100644
--- a/pkg/apis/apps/v1alpha1/servicebindingrequest_types.go
+++ b/pkg/apis/apps/v1alpha1/servicebindingrequest_types.go
@@ -43,6 +43,7 @@ type ServiceBindingRequestSpec struct {
 
 	// ApplicationSelector is used to identify the application connecting to the
 	// backing service operator.
+	// +optional
 	ApplicationSelector ApplicationSelector `json:"applicationSelector"`
 
 	// DetectBindingResources is flag used to bind all non-bindable variables from
diff --git a/pkg/apis/apps/v1alpha1/zz_generated.openapi.go b/pkg/apis/apps/v1alpha1/zz_generated.openapi.go
index b667c6c1..3b903ade 100644
--- a/pkg/apis/apps/v1alpha1/zz_generated.openapi.go
+++ b/pkg/apis/apps/v1alpha1/zz_generated.openapi.go
@@ -11,11 +11,11 @@ import (
 
 func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition {
 	return map[string]common.OpenAPIDefinition{
-		"./pkg/apis/apps/v1alpha1.ApplicationSelector":         schema_pkg_apis_apps_v1alpha1_ApplicationSelector(ref),
-		"./pkg/apis/apps/v1alpha1.BackingServiceSelector":      schema_pkg_apis_apps_v1alpha1_BackingServiceSelector(ref),
-		"./pkg/apis/apps/v1alpha1.ServiceBindingRequest":       schema_pkg_apis_apps_v1alpha1_ServiceBindingRequest(ref),
-		"./pkg/apis/apps/v1alpha1.ServiceBindingRequestSpec":   schema_pkg_apis_apps_v1alpha1_ServiceBindingRequestSpec(ref),
-		"./pkg/apis/apps/v1alpha1.ServiceBindingRequestStatus": schema_pkg_apis_apps_v1alpha1_ServiceBindingRequestStatus(ref),
+		"github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.ApplicationSelector":         schema_pkg_apis_apps_v1alpha1_ApplicationSelector(ref),
+		"github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.BackingServiceSelector":      schema_pkg_apis_apps_v1alpha1_BackingServiceSelector(ref),
+		"github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.ServiceBindingRequest":       schema_pkg_apis_apps_v1alpha1_ServiceBindingRequest(ref),
+		"github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.ServiceBindingRequestSpec":   schema_pkg_apis_apps_v1alpha1_ServiceBindingRequestSpec(ref),
+		"github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.ServiceBindingRequestStatus": schema_pkg_apis_apps_v1alpha1_ServiceBindingRequestStatus(ref),
 	}
 }
 
@@ -136,19 +136,19 @@ func schema_pkg_apis_apps_v1alpha1_ServiceBindingRequest(ref common.ReferenceCal
 					},
 					"spec": {
 						SchemaProps: spec.SchemaProps{
-							Ref: ref("./pkg/apis/apps/v1alpha1.ServiceBindingRequestSpec"),
+							Ref: ref("github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.ServiceBindingRequestSpec"),
 						},
 					},
 					"status": {
 						SchemaProps: spec.SchemaProps{
-							Ref: ref("./pkg/apis/apps/v1alpha1.ServiceBindingRequestStatus"),
+							Ref: ref("github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.ServiceBindingRequestStatus"),
 						},
 					},
 				},
 			},
 		},
 		Dependencies: []string{
-			"./pkg/apis/apps/v1alpha1.ServiceBindingRequestSpec", "./pkg/apis/apps/v1alpha1.ServiceBindingRequestStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
+			"github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.ServiceBindingRequestSpec", "github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.ServiceBindingRequestStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
 	}
 }
 
@@ -189,7 +189,7 @@ func schema_pkg_apis_apps_v1alpha1_ServiceBindingRequestSpec(ref common.Referenc
 					"backingServiceSelector": {
 						SchemaProps: spec.SchemaProps{
 							Description: "BackingServiceSelector is used to identify the backing service operator. Deprecation Notice: In the upcoming release, this field would be depcreated. It would be mandatory to set \"backingServiceSelectors\".",
-							Ref:         ref("./pkg/apis/apps/v1alpha1.BackingServiceSelector"),
+							Ref:         ref("github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.BackingServiceSelector"),
 						},
 					},
 					"backingServiceSelectors": {
@@ -199,7 +199,7 @@ func schema_pkg_apis_apps_v1alpha1_ServiceBindingRequestSpec(ref common.Referenc
 							Items: &spec.SchemaOrArray{
 								Schema: &spec.Schema{
 									SchemaProps: spec.SchemaProps{
-										Ref: ref("./pkg/apis/apps/v1alpha1.BackingServiceSelector"),
+										Ref: ref("github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.BackingServiceSelector"),
 									},
 								},
 							},
@@ -208,7 +208,7 @@ func schema_pkg_apis_apps_v1alpha1_ServiceBindingRequestSpec(ref common.Referenc
 					"applicationSelector": {
 						SchemaProps: spec.SchemaProps{
 							Description: "ApplicationSelector is used to identify the application connecting to the backing service operator.",
-							Ref:         ref("./pkg/apis/apps/v1alpha1.ApplicationSelector"),
+							Ref:         ref("github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.ApplicationSelector"),
 						},
 					},
 					"detectBindingResources": {
@@ -219,11 +219,10 @@ func schema_pkg_apis_apps_v1alpha1_ServiceBindingRequestSpec(ref common.Referenc
 						},
 					},
 				},
-				Required: []string{"applicationSelector"},
 			},
 		},
 		Dependencies: []string{
-			"./pkg/apis/apps/v1alpha1.ApplicationSelector", "./pkg/apis/apps/v1alpha1.BackingServiceSelector", "k8s.io/api/core/v1.EnvVar"},
+			"github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.ApplicationSelector", "github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.BackingServiceSelector", "k8s.io/api/core/v1.EnvVar"},
 	}
 }
 
@@ -268,7 +267,7 @@ func schema_pkg_apis_apps_v1alpha1_ServiceBindingRequestStatus(ref common.Refere
 							Items: &spec.SchemaOrArray{
 								Schema: &spec.Schema{
 									SchemaProps: spec.SchemaProps{
-										Ref: ref("./pkg/apis/apps/v1alpha1.BoundApplication"),
+										Ref: ref("github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.BoundApplication"),
 									},
 								},
 							},
@@ -278,6 +277,6 @@ func schema_pkg_apis_apps_v1alpha1_ServiceBindingRequestStatus(ref common.Refere
 			},
 		},
 		Dependencies: []string{
-			"./pkg/apis/apps/v1alpha1.BoundApplication", "github.com/openshift/custom-resource-status/conditions/v1.Condition"},
+			"github.com/openshift/custom-resource-status/conditions/v1.Condition", "github.com/redhat-developer/service-binding-operator/pkg/apis/apps/v1alpha1.BoundApplication"},
 	}
 }
diff --git a/pkg/controller/servicebindingrequest/olm.go b/pkg/controller/servicebindingrequest/olm.go
index c48ab3f2..460ed192 100644
--- a/pkg/controller/servicebindingrequest/olm.go
+++ b/pkg/controller/servicebindingrequest/olm.go
@@ -192,18 +192,12 @@ func buildCRDDescriptionFromCRD(crd *unstructured.Unstructured) (*olmv1alpha1.CR
 		return nil, err
 	}
 
-	specDescriptor, statusDescriptor, err := buildDescriptorsFromAnnotations(crd.GetAnnotations())
+	specDescriptors, statusDescriptors, err := buildDescriptorsFromAnnotations(crd.GetAnnotations())
 	if err != nil {
 		return nil, err
 	}
-
-	if specDescriptor != nil {
-		crdDescription.SpecDescriptors = append(crdDescription.SpecDescriptors, *specDescriptor)
-	}
-
-	if statusDescriptor != nil {
-		crdDescription.StatusDescriptors = append(crdDescription.StatusDescriptors, *statusDescriptor)
-	}
+	crdDescription.SpecDescriptors = append(crdDescription.SpecDescriptors, specDescriptors...)
+	crdDescription.StatusDescriptors = append(crdDescription.StatusDescriptors, statusDescriptors...)
 
 	return crdDescription, nil
 }
@@ -211,12 +205,12 @@ func buildCRDDescriptionFromCRD(crd *unstructured.Unstructured) (*olmv1alpha1.CR
 // buildDescriptorsFromAnnotations builds two descriptors collection, one for spec descriptors and
 // another for status descriptors.
 func buildDescriptorsFromAnnotations(annotations map[string]string) (
-	*olmv1alpha1.SpecDescriptor,
-	*olmv1alpha1.StatusDescriptor,
+	[]olmv1alpha1.SpecDescriptor,
+	[]olmv1alpha1.StatusDescriptor,
 	error,
 ) {
-	var currentSpecDescriptor *olmv1alpha1.SpecDescriptor
-	var currentStatusDescriptor *olmv1alpha1.StatusDescriptor
+	var specDescriptors []olmv1alpha1.SpecDescriptor
+	var statusDescriptors []olmv1alpha1.StatusDescriptor
 
 	acc := make(map[string][]string)
 
@@ -250,19 +244,19 @@ func buildDescriptorsFromAnnotations(annotations map[string]string) (
 		sort.Strings(descriptors)
 		path := strings.Split(fieldPath, ".")
 		if path[0] == "status" {
-			currentStatusDescriptor = &olmv1alpha1.StatusDescriptor{
+			statusDescriptors = append(statusDescriptors, olmv1alpha1.StatusDescriptor{
 				Path:         path[1],
 				XDescriptors: descriptors,
-			}
+			})
 		} else if path[0] == "spec" {
-			currentSpecDescriptor = &olmv1alpha1.SpecDescriptor{
+			specDescriptors = append(specDescriptors, olmv1alpha1.SpecDescriptor{
 				Path:         path[1],
 				XDescriptors: descriptors,
-			}
+			})
 		}
 	}
 
-	return currentSpecDescriptor, currentStatusDescriptor, nil
+	return specDescriptors, statusDescriptors, nil
 }
 
 // extractGVKs loop owned objects and extract the GVK information from them.


Test patch:
diff --git a/pkg/controller/servicebindingrequest/olm_test.go b/pkg/controller/servicebindingrequest/olm_test.go
index 8997454d..53c64398 100644
--- a/pkg/controller/servicebindingrequest/olm_test.go
+++ b/pkg/controller/servicebindingrequest/olm_test.go
@@ -6,6 +6,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/require"
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/types"
 	logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
@@ -75,3 +76,58 @@ func TestOLMNew(t *testing.T) {
 		assertGVKs(t, gvks)
 	})
 }
+
+func TestAnnotationParsing(t *testing.T) {
+	annotations := map[string]interface{}{
+		"servicebindingoperator.redhat.io/status.dbCredentials-db.password": "binding:env:object:secret",
+		"servicebindingoperator.redhat.io/spec.dbName":                      "binding:env:attribute",
+		"servicebindingoperator.redhat.io/spec.image":                       "binding:env:attribute",
+		"servicebindingoperator.redhat.io/status.dbConfigMap-db.host":       "binding:env:object:configmap",
+	}
+	crd := &unstructured.Unstructured{
+		Object: map[string]interface{}{
+			"apiVersion": "apiextensions.k8s.io/v1beta1",
+			"kind":       "CustomResourceDefinition",
+			"metadata":   map[string]interface{}{},
+			"spec": map[string]interface{}{
+				"names": map[string]interface{}{
+					"kind": "Carp",
+				},
+				"group":   "app.dev",
+				"version": "v1",
+			},
+			"status": map[string]interface{}{},
+		},
+	}
+	t.Run("Build CSV from CRD - no annotations", func(t *testing.T) {
+		crdDescription, err := buildCRDDescriptionFromCRD(crd)
+		require.NoError(t, err)
+		require.Len(t, crdDescription.SpecDescriptors, 0)
+		require.Len(t, crdDescription.StatusDescriptors, 0)
+	})
+
+	t.Run("Build CSV from CRD", func(t *testing.T) {
+		crd.Object["metadata"] = map[string]interface{}{
+			"annotations": annotations,
+		}
+		crdDescription, err := buildCRDDescriptionFromCRD(crd)
+		require.NoError(t, err)
+
+		require.Len(t, crdDescription.StatusDescriptors, 2)
+		require.Len(t, crdDescription.SpecDescriptors, 2)
+
+		expected := map[string]string{
+			"dbName":        "binding:env:attribute:spec.dbName",
+			"image":         "binding:env:attribute:spec.image",
+			"dbCredentials": "binding:env:object:secret:db.password",
+			"dbConfigMap":   "binding:env:object:configmap:db.host",
+		}
+		for _, value := range crdDescription.SpecDescriptors {
+			require.Equal(t, expected[value.Path], value.XDescriptors[0])
+		}
+
+		for _, value := range crdDescription.StatusDescriptors {
+			require.Equal(t, expected[value.Path], value.XDescriptors[0])
+		}
+	})
+}
diff --git a/pkg/controller/servicebindingrequest/reconciler_test.go b/pkg/controller/servicebindingrequest/reconciler_test.go
index c9a24bde..9a7825b6 100644
--- a/pkg/controller/servicebindingrequest/reconciler_test.go
+++ b/pkg/controller/servicebindingrequest/reconciler_test.go
@@ -205,3 +205,78 @@ func TestReconcilerReconcileUsingVolumes(t *testing.T) {
 		require.Equal(t, reconcilerName, volumes[0].VolumeSource.Secret.SecretName)
 	})
 }
+
+func TestReconcilerGenericBinding(t *testing.T) {
+	ctx := context.TODO()
+	backingServiceResourceRef := "backingService1"
+	matchLabels := map[string]string{
+		"connects-to": "database",
+		"environment": "reconciler",
+	}
+	f := mocks.NewFake(t, reconcilerNs)
+	f.AddMockedUnstructuredServiceBindingRequest(reconcilerName, backingServiceResourceRef, "", deploymentsGVR, matchLabels)
+	f.AddMockedUnstructuredCSV("cluster-service-version-list")
+	f.AddMockedUnstructuredDatabaseCRD()
+	f.AddMockedUnstructuredDatabaseCR(backingServiceResourceRef)
+	f.AddMockedSecret("db-credentials")
+
+	fakeClient := f.FakeClient()
+	reconciler := &Reconciler{client: fakeClient, dynClient: f.FakeDynClient(), scheme: f.S}
+
+	// Reconcile without deployment
+	res, err := reconciler.Reconcile(reconcileRequest())
+	require.NoError(t, err)
+	require.True(t, res.Requeue)
+
+	namespacedName := types.NamespacedName{Namespace: reconcilerNs, Name: reconcilerName}
+	sbrOutput, err := reconciler.getServiceBindingRequest(namespacedName)
+	require.NoError(t, err)
+
+	require.Equal(t, "BindingFail", sbrOutput.Status.BindingStatus)
+	require.Equal(t, corev1.ConditionFalse, sbrOutput.Status.Conditions[0].Status)
+	require.Equal(t, 0, len(sbrOutput.Status.ApplicationObjects))
+
+	// Reconcile with deployment
+	f.AddMockedUnstructuredDeployment(reconcilerName, matchLabels)
+
+	fakeClient = f.FakeClient()
+	reconciler = &Reconciler{client: fakeClient, dynClient: f.FakeDynClient(), scheme: f.S}
+	res, err = reconciler.Reconcile(reconcileRequest())
+	require.NoError(t, err)
+	require.False(t, res.Requeue)
+
+	d := appsv1.Deployment{}
+	require.NoError(t, fakeClient.Get(ctx, namespacedName, &d))
+
+	sbrOutput2, err := reconciler.getServiceBindingRequest(namespacedName)
+	require.NoError(t, err)
+
+	require.Equal(t, "BindingSuccess", sbrOutput2.Status.BindingStatus)
+	require.Equal(t, reconcilerName, sbrOutput2.Status.Secret)
+	require.Equal(t, corev1.ConditionTrue, sbrOutput2.Status.Conditions[0].Status)
+	require.Equal(t, 1, len(sbrOutput2.Status.ApplicationObjects))
+
+	// Update Credentials
+	s := corev1.Secret{}
+	secretNamespaced := types.NamespacedName{Namespace: reconcilerNs, Name: "db-credentials"}
+	require.NoError(t, fakeClient.Get(ctx, secretNamespaced, &s))
+	s.Data["password"] = []byte("abc123")
+	require.NoError(t, fakeClient.Update(ctx, &s))
+
+	reconciler = &Reconciler{client: fakeClient, dynClient: f.FakeDynClient(), scheme: f.S}
+	res, err = reconciler.Reconcile(reconcileRequest())
+	require.NoError(t, err)
+	require.False(t, res.Requeue)
+
+	sbrOutput3, err := reconciler.getServiceBindingRequest(namespacedName)
+	require.NoError(t, err)
+
+	d = appsv1.Deployment{}
+	require.NoError(t, fakeClient.Get(ctx, namespacedName, &d))
+
+	require.Equal(t, "BindingSuccess", sbrOutput3.Status.BindingStatus)
+	require.Equal(t, corev1.ConditionTrue, sbrOutput3.Status.Conditions[0].Status)
+	require.Equal(t, reconcilerName, sbrOutput3.Status.Secret)
+	require.Equal(t, s.Data["password"], []byte("abc123"))
+	require.Equal(t, 1, len(sbrOutput3.Status.ApplicationObjects))
+}