Skip to content

Commit 87522eb

Browse files
authored
Merge pull request #39839 from Srivaralakshmi/BindingAppsUsingSBO
Document advanced binding options
2 parents 070af6e + c6f51f9 commit 87522eb

File tree

6 files changed

+389
-0
lines changed

6 files changed

+389
-0
lines changed

_topic_maps/_topic_map.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,6 +1588,8 @@ Topics:
15881588
File: exposing-binding-data-from-a-service
15891589
- Name: Projecting binding data
15901590
File: projecting-binding-data
1591+
- Name: Binding workloads using Service Binding Operator
1592+
File: binding-workloads-using-sbo
15911593
- Name: Connecting an application to a service using the Developer perspective
15921594
File: odc-connecting-an-application-to-a-service-using-the-developer-perspective
15931595
- Name: Working with Helm charts
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
[id="binding-workloads-using-sbo"]
2+
= Binding workloads using Service Binding Operator
3+
include::modules/common-attributes.adoc[]
4+
include::modules/servicebinding-document-attributes.adoc[]
5+
:context: binding-workloads-using-sbo
6+
7+
toc::[]
8+
9+
Application developers must bind a workload to one or more backing services by using a binding secret. This secret is generated for the purpose of storing information to be consumed by the workload.
10+
11+
As an example, consider that the service you want to connect to is already exposing the binding data. In this case, you would also need a workload to be used along with the `ServiceBinding` custom resource (CR). By using this `ServiceBinding` CR, the workload sends a binding request with the details of the services to bind with.
12+
13+
.Example of `ServiceBinding` CR
14+
----
15+
apiVersion: binding.operators.coreos.com/v1alpha1
16+
kind: ServiceBinding
17+
metadata:
18+
name: spring-petclinic-rest
19+
namespace: my-postgresql
20+
spec:
21+
services: <1>
22+
- group: postgres-operator.crunchydata.com
23+
version: v1beta1
24+
kind: PostgresCluster
25+
name: hippo
26+
- group: ""
27+
version: v1
28+
kind: Secret
29+
name: hippo-pguser-hippo
30+
application: <2>
31+
name: spring-petclinic-rest
32+
group: apps
33+
version: v1
34+
resource: deployments
35+
----
36+
<1> Specifies a list of service resources.
37+
<2> The sample application that points to a Deployment or any other similar resource with an embedded PodSpec.
38+
39+
As shown in the previous example, you can also directly use a `ConfigMap` or a `Secret` itself as a service resource to be used as a source of binding data.
40+
41+
include::modules/sbo-naming-strategies.adoc[leveloffset=+1]
42+
include::modules/sbo-advanced-binding-options.adoc[leveloffset=+1]
43+
include::modules/sbo-binding-workloads-that-are-not-compliant-with-PodSpec.adoc[leveloffset=+1]
44+
include::modules/sbo-unbinding-workloads-from-a-backing-service.adoc[leveloffset=+1]
45+
46+
== Additional resources
47+
* xref:../../applications/connecting_applications_to_services/understanding-service-binding-operator.adoc#binding-a-workload-together-with-a-backing-service[Binding a workload together with a backing service].
48+
* xref:../../applications/connecting_applications_to_services/getting-started-with-service-binding.adoc#connecting-the-spring-petclinic-sample-application-to-the-postgresql-database-service[Connecting the Spring PetClinic sample application to the PostgreSQL database service].
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * /applications/connecting_applications_to_services/binding-workloads-using-sbo.adoc
4+
5+
[id="sbo-advanced-binding-options_{context}"]
6+
= Advanced binding options
7+
8+
Advanced binding options are available only for the `binding.operators.coreos.com` API group.
9+
10+
=== Changing the binding names before projecting into the workload
11+
You can specify the rules to change the binding names in the .spec.namingStrategy attribute of the `ServiceBinding` custom resource (CR). For example, consider a Spring PetClinic sample application that connects to the PostgreSQL database. In this case, the host and port fields of the database are exposed by the the PostgreSQL database service to use for binding. The Spring PetClinic sample application can access this exposed binding data through the binding names.
12+
13+
.Example: Spring PetClinic sample application in the `ServiceBinding` CR
14+
[source,yaml]
15+
----
16+
...
17+
application:
18+
name: spring-petclinic-rest
19+
group: apps
20+
version: v1
21+
resource: deployments
22+
...
23+
----
24+
25+
.Example: PostgreSQL database service in the `ServiceBinding` CR
26+
[source,yaml]
27+
----
28+
...
29+
services:
30+
- group: postgres-operator.crunchydata.com
31+
version: v1beta1
32+
kind: PostgresCluster
33+
name: hippo
34+
...
35+
----
36+
37+
If `namingStrategy` is not defined and the binding names are projected as environment variables, then the `host: hippo-pgbouncer` value in the backing service and the projected environment variable would appear as shown in the following example:
38+
39+
.Example
40+
----
41+
DATABASE_HOST: hippo-pgbouncer
42+
----
43+
where:
44+
[horizontal]
45+
`DATABASE`:: Specifies the `kind` backend service.
46+
`HOST`:: Specifies the binding name.
47+
48+
After applying the `POSTGRESQL_{{ .service.kind | upper }}_{{ .name | upper }}_ENV` naming strategy, the list of custom binding names prepared by the service binding request appears as shown in the following example:
49+
50+
.Example
51+
----
52+
POSTGRESQL_DATABASE_HOST_ENV: hippo-pgbouncer
53+
POSTGRESQL_DATABASE_PORT_ENV: 5432
54+
----
55+
56+
The following items describe the expressions defined in the `POSTGRESQL_{{ .service.kind | upper }}_{{ .name | upper }}_ENV` naming strategy:
57+
58+
* `.name`: Refers to the binding name exposed by the backing service. In the previous example, the binding names are `HOST` and `PORT`.
59+
* `.service.kind`: Refers to the kind of service resource whose binding names are changed with the naming strategy.
60+
* `upper`: String function used to post-process the character string while compiling the Go template string.
61+
* `POSTGRESQL`: Prefix of the custom binding name.
62+
* `ENV`: Suffix of the custom binding name.
63+
64+
Similar to the previous example, you can define the string templates in `namingStrategy` to define how each key of the binding names should be prepared by the service binding request.
65+
66+
=== Composing custom binding data
67+
As an application developer, you can compose custom binding data under the following circumstances:
68+
69+
* The backing service does not expose binding data.
70+
* The values exposed are not available in the required format as expected by the workload.
71+
72+
For example, consider a case where the backing service CR exposes the host, port, and database user as binding data, but the workload requires that the binding data be consumed as a connection string.
73+
You can compose custom binding data using attributes in the Kubernetes resource representing the backing service.
74+
75+
.Example
76+
----
77+
apiVersion: binding.operators.coreos.com/v1alpha1
78+
kind: ServiceBinding
79+
metadata:
80+
name: spring-petclinic-rest
81+
namespace: my-postgresql
82+
spec:
83+
services:
84+
- group: postgres-operator.crunchydata.com
85+
version: v1beta1
86+
kind: PostgresCluster
87+
name: hippo <1>
88+
id: postgresDB <2>
89+
- group: ""
90+
version: v1
91+
kind: Secret
92+
name: hippo-pguser-hippo
93+
id: postgresSecret
94+
application:
95+
name: spring-petclinic-rest
96+
group: apps
97+
version: v1
98+
resource: deployments
99+
mappings:
100+
## From the database service
101+
- name: JDBC_URL
102+
value: 'jdbc:postgresql://{{ .postgresDB.metadata.annotations.proxy }}:{{ .postgresDB.spec.port }}/{{ .postgresDB.metadata.name }}'
103+
## From both the services!
104+
- name: CREDENTIALS
105+
value: '{{ .postgresDB.metadata.name }}{{ translationService.postgresSecret.data.password }}'
106+
## Generate JSON
107+
- name: DB_JSON <3>
108+
value: {{ json .postgresDB.status }} <4>
109+
----
110+
<1> Name of the backing service resource.
111+
<2> Optional identifier.
112+
<3> Generated JSON name that is to be projected as the file content or environment value. The JSON name contains the attributes of the backing service custom resource.
113+
<4> Generated JSON value that is to be projected as the file content or environment value. The JSON value contains the attributes of the backing service custom resource.
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * /applications/connecting_applications_to_services/binding-workloads-using-sbo.adoc
4+
5+
[id="sbo-binding-workloads-that-are-not-compliant-with-PodSpec_{context}"]
6+
= Binding secondary workloads that are not compliant with PodSpec
7+
8+
A typical scenario in service binding involves configuring the backing service, the workload (Deployment), and {servicebinding-title}. Consider a scenario that involves a secondary workload (which can also be an application Operator) that is not compliant with PodSpec and is between the primary workload (Deployment) and {servicebinding-title}.
9+
10+
For such secondary workload resources, the location of the container path is arbitrary. For service binding, if the secondary workload in a CR is not compliant with the PodSpec, you must specify the location of the container path. Doing so projects the binding data into the container path specified in the secondary workload of the `ServiceBinding` CR, for example, when you do not want the binding data inside a pod.
11+
12+
{servicebinding-title} provides an option to configure the value of where the container path or secret path is and bind these paths at a custom location. This option is available only for the `binding.operators.coreos.com` API group when the binding data is projected as environment variables.
13+
14+
=== Configuring the custom location of the container path
15+
Consider a secondary workload CR, which is not compliant with the PodSpec and has containers located at the `spec.containers` path:
16+
17+
.Example: Secondary workload CR
18+
[source,yaml]
19+
----
20+
apiVersion: "operator.sbo.com/v1"
21+
kind: SecondaryWorkload
22+
metadata:
23+
name: secondary-workload
24+
spec:
25+
containers:
26+
- name: hello-world
27+
image: quay.io/baijum/secondary-workload:latest
28+
ports:
29+
- containerPort: 9966
30+
----
31+
32+
The following example shows how to configure the `spec.containers` path by specifying a value in the `ServiceBinding` CR and to bind this path to a `spec.application.bindingPath.containersPath` custom location:
33+
34+
.Example: `ServiceBinding` CR with the `spec.containers` path in a custom location
35+
[source,yaml]
36+
----
37+
apiVersion: binding.operators.coreos.com/v1alpha1
38+
kind: ServiceBinding
39+
metadata:
40+
name: spring-petclinic-rest
41+
spec:
42+
services:
43+
- group: postgres-operator.crunchydata.com
44+
version: v1beta1
45+
kind: PostgresCluster
46+
name: hippo
47+
id: postgresDB
48+
- group: ""
49+
version: v1
50+
kind: Secret
51+
name: hippo-pguser-hippo
52+
id: postgresSecret
53+
application: <1>
54+
name: spring-petclinic-rest
55+
group: apps
56+
version: v1
57+
resource: deployments
58+
application: <2>
59+
name: secondary-workload
60+
group: operator.sbo.com
61+
version: v1
62+
resource: secondaryworkloads
63+
bindingPath:
64+
containersPath: spec.containers <3>
65+
----
66+
<1> The sample application that points to a Deployment or any other similar resource with an embedded PodSpec.
67+
<2> The secondary workload, which is not compliant with the PodSpec.
68+
<3> The custom location of the container path.
69+
70+
After you specify the location of the container path, {servicebinding-title} generates the binding data, which becomes available in the container path specified in the secondary workload of the `ServiceBinding` CR.
71+
72+
The following example shows the `spec.containers` path with the `envFrom` and `secretRef` fields:
73+
74+
.Example: Secondary workload CR with the `envFrom` and `secretRef` fields
75+
[source,yaml]
76+
----
77+
apiVersion: "operator.sbo.com/v1"
78+
kind: SecondaryWorkload
79+
metadata:
80+
name: secondary-workload
81+
spec:
82+
containers:
83+
- env: <1>
84+
- name: ServiceBindingOperatorChangeTriggerEnvVar
85+
value: "31793"
86+
envFrom:
87+
- secretRef:
88+
name: secret-resource-name <2>
89+
image: quay.io/baijum/secondary-workload:latest
90+
name: hello-world
91+
ports:
92+
- containerPort: 9966
93+
resources: {}
94+
----
95+
<1> Unique array of containers with values generated by the {servicebinding-title}. These values are based on the backing service CR.
96+
<2> Name of the `Secret` resource generated by the {servicebinding-title}.
97+
98+
=== Configuring the custom location of the secret path
99+
Consider a secondary workload CR, which is not compliant with the PodSpec, with only the secret at the `spec.secret` path:
100+
101+
.Example: Secondary workload CR
102+
[source,yaml]
103+
----
104+
apiVersion: "operator.sbo.com/v1"
105+
kind: SecondaryWorkload
106+
metadata:
107+
name: secondary-workload
108+
spec:
109+
secret: ""
110+
----
111+
112+
The following example shows how to configure the `spec.secret` path by specifying a value in the `ServiceBinding` CR and to bind this path at a `spec.application.bindingPath.secretPath` custom location:
113+
114+
.Example: `ServiceBinding` CR with the `spec.secret` path in a custom location
115+
[source,yaml]
116+
----
117+
apiVersion: binding.operators.coreos.com/v1alpha1
118+
kind: ServiceBinding
119+
metadata:
120+
name: spring-petclinic-rest
121+
spec:
122+
...
123+
application: <1>
124+
name: secondary-workload
125+
group: operator.sbo.com
126+
version: v1
127+
resource: secondaryworkloads
128+
bindingPath:
129+
secretPath: spec.secret <2>
130+
...
131+
----
132+
<1> The secondary workload, which is not compliant with the PodSpec.
133+
<2> The custom location of the secret path that contains the name of the `Secret` resource.
134+
135+
After you specify the location of the secret path, {servicebinding-title} generates the binding data, which becomes available in the secret path specified in the secondary workload of the `ServiceBinding` CR.
136+
137+
The following example shows the `spec.secret` path with the `binding-request` value:
138+
139+
.Example: Secondary workload CR with the `binding-request` value
140+
[source,yaml]
141+
----
142+
...
143+
apiVersion: "operator.sbo.com/v1"
144+
kind: SecondaryWorkload
145+
metadata:
146+
name: secondary-workload
147+
spec:
148+
secret: binding-request-72ddc0c540ab3a290e138726940591debf14c581 <1>
149+
...
150+
----
151+
<1> Unique name of the `Secret` resource generated by the {servicebinding-title}.

modules/sbo-naming-strategies.adoc

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * /applications/connecting_applications_to_services/binding-workloads-using-sbo.adoc
4+
5+
[id="sbo-naming-strategies_{context}"]
6+
= Naming strategies
7+
8+
Naming strategies are available only for the `binding.operators.coreos.com` API group.
9+
10+
Naming strategies use Go templates to help you define custom binding names through the service binding request. Naming strategies apply for all attributes including the mappings in the `ServiceBinding` custom resource (CR).
11+
12+
A backing service projects the binding names as files or environment variables into the workload. If a workload expects the projected binding names in a particular format, but the binding names to be projected from the backing service are not available in that format, then you can change the binding names using naming strategies.
13+
14+
.Predefined post-processing functions
15+
While using naming strategies, depending on the expectations or requirements of your workload, you can use the following predefined post-processing functions in any combination to convert the character strings:
16+
17+
* `upper`: Converts the character strings into capital or uppercase letters.
18+
* `lower`: Converts the character strings into lowercase letters.
19+
* `title`: Converts the character strings where the first letter of each word is capitalized except for certain minor words.
20+
21+
.Predefined naming strategies
22+
Binding names declared through annotations or Operator Lifecycle Manager (OLM) descriptors are processed for their name change before their projection into the workload according to the following predefined naming strategies:
23+
24+
* `none`: When applied, there are no changes in the binding names.
25+
+
26+
.Example
27+
After the template compilation, the binding names take the `{{ .name }}` form.
28+
+
29+
----
30+
host: hippo-pgbouncer
31+
port: 5432
32+
----
33+
34+
* `upper`: Applied when no `namingStrategy` is defined. When applied, converts all the character strings of the binding name key into capital or uppercase letters.
35+
+
36+
.Example
37+
After the template compilation, the binding names take the `{{ .service.kind | upper}}_{{ .name | upper }}` form.
38+
+
39+
----
40+
DATABASE_HOST: hippo-pgbouncer
41+
DATABASE_PORT: 5432
42+
----
43+
+
44+
If your workload requires a different format, you can define a custom naming strategy and change the binding name using a prefix and a separator, for example, `PORT_DATABASE`.
45+
46+
[NOTE]
47+
====
48+
* When the binding names are projected as files, by default the predefined `none` naming strategy is applied, and the binding names do not change.
49+
* When the binding names are projected as environment variables and no `namingStrategy` is defined, by default the predefined `uppercase` naming strategy is applied.
50+
* You can override the predefined naming strategies by defining custom naming strategies using different combinations of custom binding names and predefined post-processing functions.
51+
====

0 commit comments

Comments
 (0)