Skip to content

Commit

Permalink
Remove mappings from the ServiceBinding resource
Browse files Browse the repository at this point in the history
The existing mappings on the ServiceBinding resource were introduced as
a way to make it easier for a user to enrich an existing Secret into a
form appropriate for binding to an application workload. This approch
had a few issues that can be better addressed by other resources that
interoperate with the ServiceBiding resource. The issues include:
- the ServiceBinding controller needs to be able to read and write
  Secrets
- Go templates were used to compose new values, which worked for basic
  templating, but were limited in their capabilities
- the capabilities of the Go templates are an implemenation detail of
  how the controller is built and could change over time independent of
  the speced behavior.

The behavior applied by mappings can be reintroduced as dedicated
resources that can themselves expose a Secret as a ProvisionedService,
which can be consumed by a ServiceBinding. This change further separates
the concerns of provisioning a service from binding a service.

Refs servicebinding#145

Signed-off-by: Scott Andrews <[email protected]>
  • Loading branch information
scothis committed May 14, 2021
1 parent 44c1d8e commit 9c5594c
Show file tree
Hide file tree
Showing 3 changed files with 1 addition and 88 deletions.
52 changes: 1 addition & 51 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ Behavior within the project is governed by the [Contributor Covenant Code of Con
- [Resource Type Schema](#resource-type-schema-1)
- [Minimal Example Resource](#minimal-example-resource)
- [Label Selector Example Resource](#label-selector-example-resource)
- [Mappings Example Resource](#mappings-example-resource)
- [Environment Variables Example Resource](#environment-variables-example-resource)
- [Reconciler Implementation](#reconciler-implementation)
- [Ready Condition Status](#ready-condition-status)
Expand Down Expand Up @@ -263,9 +262,7 @@ The Service Binding resource **MAY** define `.spec.application.containers`, as a
- if the value is a string (`${containerString}`), a container or init container matching by name (`.spec.template.spec.containers[?(@.name=='${containerString}')]` or `.spec.template.spec.initContainers[?(@.name=='${containerString}')]`) **MUST** be bound
- values that do not match a container or init container **SHOULD** be ignored

A Service Binding Resource **MAY** define a `.spec.mappings` which is an array of `Mapping` objects. A `Mapping` object **MUST** define `name` and `value` entries. The `value` of a `Mapping` **MUST** be handled as a [Go Template][gt] exposing binding `Secret` keys for substitution. The executed output of the template **MUST** be added to the `Secret` exposed to the resource represented by `application` as the key specified by the `name` of the `Mapping`. If the `name` of a `Mapping` matches that of a Provisioned Service `Secret` key, the value from `Mapping` **MUST** be used for binding.

A Service Binding Resource **MAY** define a `.spec.env` which is an array of `EnvMapping`. An `EnvMapping` object **MUST** define `name` and `key` entries. The `key` of an `EnvMapping` **MUST** refer to a binding `Secret` key name including any key defined by a `Mapping`. The value of this `Secret` entry **MUST** be configured as an environment variable on the resource represented by `application`.
A Service Binding Resource **MAY** define a `.spec.env` which is an array of `EnvMapping`. An `EnvMapping` object **MUST** define `name` and `key` entries. The `key` of an `EnvMapping` **MUST** refer to a binding `Secret` key name. The value of this `Secret` entry **MUST** be configured as an environment variable on the resource represented by `application`.

A Service Binding resource **MUST** define `.status.conditions` which is an array of `Condition` objects as defined in [meta/v1 Condition][mv1c]. At least one condition containing a `type` of `Ready` **MUST** be defined. The `Ready` condition **SHOULD** contain appropriate values defined by the implementation. As label selectors are inherently queries that return zero-to-many resources, it is **RECOMMENDED** that `ServiceBinding` authors use a combination of labels that yield a single resource, but implementors **MUST** handle each matching resource as if it was specified by name in a distinct `ServiceBinding` resource. Partial failures **MUST** be aggregated and reported on the binding status's `Ready` condition. A Service Binding resource **SHOULD** reflect the secret projected into the application as `.status.binding.name`.

Expand All @@ -285,8 +282,6 @@ metadata:
...
spec:
name: # string, optional, default: .metadata.name
type: # string, optional
provider: # string, optional
application: # ObjectReference-like
apiVersion: # string
Expand All @@ -300,10 +295,6 @@ spec:
kind: # string
name: # string
mappings: # []Mapping, optional
- name: # string
value: # string
env: # []EnvMapping, optional
- name: # string
key: # string
Expand Down Expand Up @@ -374,39 +365,6 @@ status:
lastTransitionTime: '2021-01-20T17:00:00Z'
```
## Mappings Example Resource
```yaml
apiVersion: service.binding/v1alpha2
kind: ServiceBinding
metadata:
name: account-service
spec:
application:
apiVersion: apps/v1
kind: Deployment
name: online-banking

service:
apiVersion: com.example/v1alpha1
kind: AccountService
name: prod-account-service

mappings:
- name: accountServiceUri
value: https://{{ urlquery .username }}:{{ urlquery .password }}@{{ .host }}:{{ .port }}/{{ .path }}

status:
binding:
name: prod-account-service-projection
conditions:
- type: Ready
status: 'True'
reason: 'Projected'
message: ''
lastTransitionTime: '2021-01-20T17:00:00Z'
```
## Environment Variables Example Resource
```yaml
Expand All @@ -425,19 +383,13 @@ spec:
kind: AccountService
name: prod-account-service

mappings:
- name: accountServiceUri
value: https://{{ urlquery .username }}:{{ urlquery .password }}@{{ .host }}:{{ .port }}/{{ .path }}

env:
- name: ACCOUNT_SERVICE_HOST
key: host
- name: ACCOUNT_SERVICE_USERNAME
key: username
- name: ACCOUNT_SERVICE_PASSWORD
key: password
- name: ACCOUNT_SERVICE_URI
key: accountServiceUri

status:
binding:
Expand All @@ -460,8 +412,6 @@ If the `$SERVICE_BINDING_ROOT` environment variable has already been configured

The `$SERVICE_BINDING_ROOT` environment variable **MUST NOT** be reset if it is already configured on the resource represented by `application`.

If a `.spec.type` is set, the `type` entry in the binding `Secret` **MUST** be set to its value overriding any existing value. If a `.spec.provider` is set, the `provider` entry in the binding `Secret` **MUST** be set to its value overriding any existing value.

### Ready Condition Status

If the modification of the Application resource is completed successfully, the `Ready` condition status **MUST** be set to `True`. If the modification of the Application resource is not completed successfully the `Ready` condition status **MUST NOT** be set to `True`.
Expand Down
15 changes: 0 additions & 15 deletions internal/service.binding/v1alpha2/service_binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,31 +64,16 @@ type EnvMapping struct {
Key string `json:"key"`
}

// ServiceBindingMapping defines a mapping from the existing collection of Secret values to a new Secret entry.
type ServiceBindingMapping struct {
// Name is the name of the mapped Secret entry
Name string `json:"name"`
// Value is the value of the new Secret entry. Contents may be a Go template and refer to the other secret entries
// by name.
Value string `json:"value"`
}

// ServiceBindingSpec defines the desired state of ServiceBinding
type ServiceBindingSpec struct {
// Name is the name of the service as projected into the application container. Defaults to .metadata.name.
Name string `json:"name,omitempty"`
// Type is the type of the service as projected into the application container
Type string `json:"type,omitempty"`
// Provider is the provider of the service as projected into the application container
Provider string `json:"provider,omitempty"`
// Application is a reference to an object
Application ServiceBindingApplicationReference `json:"application"`
// Service is a reference to an object that fulfills the ProvisionedService duck type
Service ServiceBindingServiceReference `json:"service"`
// Env is the collection of mappings from Secret entries to environment variables
Env []EnvMapping `json:"env,omitempty"`
// Mappings is the collection of mappings from existing Secret entries to new Secret entries
Mappings []ServiceBindingMapping `json:"mappings,omitempty"`
}

// These are valid conditions of ServiceBinding.
Expand Down
22 changes: 0 additions & 22 deletions service.binding_servicebindings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -112,28 +112,9 @@ spec:
- name
type: object
type: array
mappings:
description: Mappings is the collection of mappings from existing Secret entries to new Secret entries
items:
description: ServiceBindingMapping defines a mapping from the existing collection of Secret values to a new Secret entry.
properties:
name:
description: Name is the name of the mapped Secret entry
type: string
value:
description: Value is the value of the new Secret entry. Contents may be a Go template and refer to the other secret entries by name.
type: string
required:
- name
- value
type: object
type: array
name:
description: Name is the name of the service as projected into the application container. Defaults to .metadata.name.
type: string
provider:
description: Provider is the provider of the service as projected into the application container
type: string
service:
description: Service is a reference to an object that fulfills the ProvisionedService duck type
properties:
Expand All @@ -151,9 +132,6 @@ spec:
- kind
- name
type: object
type:
description: Type is the type of the service as projected into the application container
type: string
required:
- application
- service
Expand Down

0 comments on commit 9c5594c

Please sign in to comment.