The initial proposal is the following (excerpt from the issue above):
apiVersion: apps.openshift.io/v1alpha1
kind: ServiceBindingRequest
metadata:
name: binding-request
namespace: service-binding-demo
spec:
applicationSelector:
resourceRef: nodejs-rest-http-crud
group: sources.eventing.knative.dev
version: v1alpha1
resource: KafkaSource
bindingSecretPath: "spec.template.xyz.envFrom"
backingServiceSelectors:
- group: postgresql.baiju.dev
version: v1alpha1
kind: Database
resourceRef: db-demo
- group: another.group.dev
version: v1alpha1
kind: KafkaUser
resourceRef: my-user-kafka-user
It is assumed that spec.applicationSelector.bindingSecretPath
is the path that should be injected
in all applications matching either resourceRef
or matchLabels
. This approach is likely to not
work, since it can’t be assumed that an application matching matchLabels
will 1) have declared the
field in the object and 2) it is not guaranteed that matchLabels
would return a list of only
Deployment
like objects.
There is a duality in applicationSelector
itself: if matchLabels
is given, then resourceRef
and
the GVK can be ignored (although I could not find any tests exercising this at the time of this
writing).
Another point is that Deployment like objects couldn’t use the bindingSecretPath field to update its containers, meaning there’s actually two different functionalities in there:
-
Application references, where the equivalent of an ObjectReference is stored; if the referred resource doesn’t exist, the binding can’t be performed nor considered successful.
-
Application selector, which GVK can be used as predicate to collect the objects for the binding action. For example, using any complete GVK as predicate can result in a list with none or many objects of a specific GVK.
Given those separate functionalities, a possible approach is to specify strategies to inject secret data in the resolved Applications by mapping those to specific GVKs (the example is using apiVersion/kind for brevity):
- type: PodSpecSlice
path: .spec.template.spec.containers
resources:
- deployments.apps/v1
- replicasets.core/v1
- type: PodSpecSlice
path: .spec.deploymentTemplate.spec.containers
resources:
- deploymentconfigs.openshift/v1
- type: SecretPath
path: .spec.eventSourceSecret
resources:
- kafkasources.sources.eventing.knative.dev/v1alpha1
The secretInjection
is a list of binding instructions, having the following fields:
- Type
-
a valid, known injection type implemented and available in the Operator.
- Resources
-
a list of GroupVersionResource specifying the objects that should be bound with the injector. This mapping decides how the secret data is bound to a particular object kind.
- Path
-
the JSON representing the nodes where the injector should insert the secret.
We currently have implemented the PodSpecSlice
injector, which basically assumes a manifest that
contains container definitions in pre-defined nodes (for example, Deployment
, ReplicaSet
and
DeploymentConfig
all have the same structure).
Even though the contents of this particular example would be a hardcoded configuration, a user could,
in theory, map resources to another entry in the secretInjection
section to use the PodSpecSlice
injection (for example, DeploymentConfig
could be such a case, if we choose to support mainly
Kubernetes and not have any dependency on OpenShift for the core functionality).
The other injector in the example is the SecretPath
injector; the given path indicates the node the
operator should inject the secret reference.
Specifying the mapping configuration in the ServiceBindingRequest
manifest directly allows the SBO
developers to support almost any object to be bound, as long as a compatible injector is available.