Details
-
Story
-
Resolution: Done
-
Major
-
None
-
13
-
False
-
False
-
AppSvc Sprint 211, AppSvc Sprint 212, AppSvc Sprint 214, AppSvc Sprint 216, AppSvc Sprint 217
Description
Owner: Architect:
<Architect is responsible for completing this section to define the details of the story>
Story (Required)
As an OpenShift user I should be able to bind services with workloads that is not PoSpec compatible
Background (Required)
This is an advanced feature described in the spec: https://github.com/servicebinding/spec#workload-resource-mapping
Glossary
<List of new terms and definition used in this story>
Out of scope
<Defines what is not included in this story>
In Scope
<Defines what is included in this story>
Approach(Required)
<Description of the general technical path on how to achieve the goal of the story. Include details like json schema, class definitions>
Dependencies
<Describes what this story depends on. Dependent Stories and EPICs should be linked to the story.>
Edge Case
<Describe edge cases to consider when implementing the story and defining tests>
Acceptance Criteria
Feature: Bind services to workloads based on workload resource mapping As a user, I would like to be able to use workload resource bindings as defined by the specification. Background: Given Namespace [TEST_NAMESPACE] is used And Service Binding Operator is running And CustomResourceDefinition backends.stable.example.com is available Scenario: Deployment identity mappings should not change any behavior Given Generic test application is running And The workload resource mapping is present """ apiVersion: servicebinding.io/v1alpha3 kind: ClusterWorkloadResourceMapping metadata: name: deployments.apps spec: versions: - version: "*" containers: - path: .spec.template.spec.containers[*] name: .name env: .env volumeMounts: .volumeMounts - path: .spec.template.spec.initContainers[*] name: .name env: .env volumeMounts: .volumeMounts volumes: .spec.template.spec.volumes """ And The custom resource is present """ apiVersion: "stable.example.com/v1" kind: Backend metadata: name: $scenario_id-backend annotations: service.binding/host: path={.spec.host} service.binding/username: path={.spec.username} spec: host: example.common username: foo """ When Service Binding is applied """ apiVersion: servicebinding.io/v1alpha3 kind: ServiceBinding metadata: name: $scenario_id-binding spec: type: mysql service: apiVersion: stable.example.com/v1 kind: Backend name: $scenario_id-backend workload: name: $scenario_id apiVersion: apps/v1 kind: Deployment """ Then Service Binding is ready And The application env var "SERVICE_BINDING_ROOT" has value "/bindings" And Content of file "/bindings/$scenario_id-binding/host" in application pod is """ example.common """ And Content of file "/bindings/$scenario_id-binding/port" in application pod is """ 8080 """ And Content of file "/bindings/$scenario_id-binding/type" in application pod is """ mysql """ And The workload resource mapping is deleted """ apiVersion: servicebinding.io/v1alpha3 kind: ClusterWorkloadResourceMapping metadata: name: deployments.apps spec: versions: - version: "*" containers: - path: .spec.template.spec.containers[*] name: .name env: .env volumeMounts: .volumeMounts - path: .spec.template.spec.initContainers[*] name: .name env: .env volumeMounts: .volumeMounts volumes: .spec.template.spec.volumes """ Scenario: Specify container path using Workload Resource Mappings in custom resource Given The Secret is present """ apiVersion: v1 kind: Secret metadata: name: $scenario_id-secret stringData: username: AzureDiamond password: hunter2 """ And The Custom Resource is present """ apiVersion: stable.example.com/v1 kind: Backend metadata: name: $scenario_id-backend annotations: service.binding: path={.status.data.dbCredentials},objectType=Secret,elementType=map status: data: dbCredentials: $scenario_id-secret """ And The Workload Resource Mapping is present """ apiVersion: servicebinding.io/v1alpha3 kind: ClusterWorkloadResourceMapping metadata: name: appconfig.stable.example.com spec: versions: - version: "*" containers: - path: .spec.spec.containers[*] name: .name env: .env volumeMounts: .volumeMounts - path: .spec.spec.initContainers[*] name: .name env: .env volumeMounts: .volumeMounts volumes: .spec.spec.volumes """ And The Custom Resource is present """ apiVersion: "stable.example.com/v1" kind: AppConfig metadata: name: $scenario_id-appconfig spec: uri: "some uri" Command: "some command" image: my-image spec: containers: - name: hello-world # Image from dockerhub, This is the import path for the Go binary to build and run. image: yusufkaratoprak/kubernetes-gosample:latest ports: - containerPort: 8090 """ When Service Binding is applied """ apiVersion: servicebinding.io/v1alpha3 kind: ServiceBinding metadata: name: $scenario_id-binding spec: service: name: $scenario_id-appconfig kind: Backend apiVersion: stable.example.com/v1 workload: apiVersion: stable.example.com/v1 kind: appconfigs name: $scenario_id-backend """ Then Service Binding is ready And Secret has been injected in to CR "wrm-appconfig" of kind "AppConfig" at path "{.spec.spec.containers[0].envFrom[0].secretRef.name}" And The Workload Resource Mapping is deleted """ apiVersion: servicebinding.io/v1alpha3 kind: ClusterWorkloadResourceMapping metadata: name: appconfig.stable.example.com spec: versions: - version: "*" containers: - path: .spec.spec.containers[*] name: .name env: .env volumeMounts: .volumeMounts - path: .spec.spec.initContainers[*] name: .name env: .env volumeMounts: .volumeMounts volumes: .spec.spec.volumes """ Scenario: Projecting values into a non-PodSpec resource Given The sample app "demo-sample" is present And The Custom Resource is present """ apiVersion: "stable.example.com/v1" kind: Backend metadata: name: $scenario_id-backend annotations: service.binding/host: path={.spec.host} service.binding/username: path={.spec.username} spec: host: example.common username: foo """ And The Custom Resource is present """ apiVersion: servicebinding.io/v1alpha3 kind: ClusterWorkloadResourceMapping metadata: name: sampleapps.example.org spec: versions: - version: "*" containers: - path: .samplespec.template.spec.containers[*] name: .name env: .env volumeMounts: .volumeMounts - path: .samplespec.template.spec.initContainers[*] name: .name env: .env volumeMounts: .volumeMounts volumes: .samplespec.template.spec.volumes """ When Service Binding is applied """ apiVersion: binding.operators.coreos.com/v1alpha1 kind: ServiceBinding metadata: name: $scenario_id-binding spec: services: - group: stable.example.com version: v1 kind: Backend name: $scenario_id-backend application: name: demo-cronjob group: example.org version: v1 resource: sampleapps """ Then Service Binding is ready And Check sample app contains values for "host" and "username" Scenario: Projecting values into a non-PodSpec resource for a specific API version Given The sample app "demo-sample" is present And The Custom Resource is present """ apiVersion: "stable.example.com/v1" kind: Backend metadata: name: $scenario_id-backend annotations: service.binding/host: path={.spec.host} service.binding/username: path={.spec.username} spec: host: example.common username: foo """ And The Custom Resource is present """ apiVersion: servicebinding.io/v1alpha3 kind: ClusterWorkloadResourceMapping metadata: name: sampleapps.example.org spec: versions: - version: "v1" containers: - path: .samplespec.template.spec.containers[*] name: .name env: .env volumeMounts: .volumeMounts - path: .samplespec.template.spec.initContainers[*] name: .name env: .env volumeMounts: .volumeMounts volumes: .samplespec.template.spec.volumes """ When Service Binding is applied """ apiVersion: binding.operators.coreos.com/v1alpha1 kind: ServiceBinding metadata: name: $scenario_id-binding spec: services: - group: stable.example.com version: v1 kind: Backend name: backend-demo-svc application: name: demo-cronjob group: example.org version: v1 resource: sampleapps """ Then Service Binding is ready And Check sample app contains values for "host" and "username" Scenario: A workload resource mapping that doesn't specify defaults should use to PodSpec-compatible defaults Given The Secret is present """ apiVersion: v1 kind: Secret metadata: name: $scenario_id-secret stringData: username: AzureDiamond password: hunter2 """ And The Custom Resource is present """ apiVersion: stable.example.com/v1 kind: Backend metadata: name: $scenario_id-backend annotations: service.binding: path={.status.data.dbCredentials},objectType=Secret,elementType=map status: data: dbCredentials: $scenario_id-secret """ And The Workload Resource Mapping is present """ apiVersion: servicebinding.io/v1alpha3 kind: ClusterWorkloadResourceMapping metadata: name: appconfig.stable.example.com spec: versions: - version: "*" containers: - path: .spec.spec.containers[*] - path: .spec.spec.initContainers[*] """ And The Custom Resource is present """ apiVersion: "stable.example.com/v1" kind: AppConfig metadata: name: $scenario_id-appconfig spec: uri: "some uri" Command: "some command" image: my-image spec: containers: - name: hello-world # Image from dockerhub, This is the import path for the Go binary to build and run. image: yusufkaratoprak/kubernetes-gosample:latest ports: - containerPort: 8090 """ When Service Binding is applied """ apiVersion: servicebinding.io/v1alpha3 kind: ServiceBinding metadata: name: $scenario_id-binding spec: service: name: $scenario_id-appconfig kind: Backend apiVersion: stable.example.com/v1 workload: apiVersion: stable.example.com/v1 kind: appconfigs name: $scenario_id-backend """ Then Service Binding is ready And Secret has been injected in to CR "wrm-appconfig" of kind "AppConfig" at path "{.spec.spec.containers[0].envFrom[0].secretRef.name}" And The Workload Resource Mapping is deleted """ apiVersion: servicebinding.io/v1alpha3 kind: ClusterWorkloadResourceMapping metadata: name: appconfig.stable.example.com spec: versions: - version: "*" containers: - path: .spec.spec.containers[*] - path: .spec.spec.initContainers[*] """ Scenario: Binding filtering interacts with workload resource mappings Given The Secret is present """ apiVersion: v1 kind: Secret metadata: name: $scenario_id-secret stringData: username: foo password: bar type: db """ * OLM Operator "custom_app" is running * The Custom Resource is present """ apiVersion: "stable.example.com/v1" kind: AppConfig metadata: name: $scenario_id-appconfig spec: template: spec: initContainers: - image: init:latest name: "foo" - image: setup:latest containers: - image: some/image - name: "foo" image: foo:latest - name: "bar" image: bar:latest - image: some/image """ And The Workload Resource Mapping is present """ apiVersion: servicebinding.io/v1alpha3 kind: ClusterWorkloadResourceMapping metadata: name: appconfig.stable.example.com spec: versions: - version: "*" containers: - path: .spec.template.spec.containers[*] name: .name - path: .spec.template.spec.initContainers[*] name: .name """ When Service Binding is applied """ apiVersion: servicebinding.io/v1alpha3 kind: ServiceBinding metadata: name: $scenario_id-binding spec: service: apiVersion: v1 kind: Secret name: $scenario_id-secret workload: name: $scenario_id-appconfig apiVersion: stable.example.com/v1 kind: AppConfig containers: - foo - bar - bla """ Then Service Binding is ready * jq ".status.binding.name" of Service Binding should be changed to "$scenario_id-secret" * jsonpath "{.spec.template.spec.containers[0].volumeMounts}" on "appconfigs/$scenario_id-appconfig" should return no value * jsonpath "{.spec.template.spec.containers[1].volumeMounts}" on "appconfigs/$scenario_id-appconfig" should return "[{"mountPath":"/bindings/$scenario_id-binding","name":"$scenario_id-binding"}]" * jsonpath "{.spec.template.spec.containers[2].volumeMounts}" on "appconfigs/$scenario_id-appconfig" should return "[{"mountPath":"/bindings/$scenario_id-binding","name":"$scenario_id-binding"}]" * jsonpath "{.spec.template.spec.containers[3].volumeMounts}" on "appconfigs/$scenario_id-appconfig" should return no value * jsonpath "{.spec.template.spec.initContainers[0].volumeMounts}" on "appconfigs/$scenario_id-appconfig" should return "[{"mountPath":"/bindings/$scenario_id-binding","name":"$scenario_id-binding"}]" Scenario: Workload resource mapping with secrets Given The Secret is present """ apiVersion: v1 kind: Secret metadata: name: $scenario_id-secret stringData: username: foo password: bar type: db """ And The workload resource mapping is present """ apiVersion: servicebinding.io/v1alpha3 kind: ClusterWorkloadResourceMapping metadata: name: deployments.apps spec: versions: - version: "*" containers: - path: .spec.template.spec.containers[*] - path: .spec.template.spec.initContainers[*] """ And Generic test application is running When Service Binding is applied """ apiVersion: servicebinding.io/v1alpha3 kind: ServiceBinding metadata: name: $scenario_id-binding spec: service: apiVersion: v1 kind: Secret name: $scenario_id-secret workload: name: $scenario_id apiVersion: apps/v1 kind: Deployment """ Then Service Binding is ready And jq ".status.binding.name" of Service Binding should be changed to "$scenario_id-secret" And Content of file "/bindings/$scenario_id-binding/username" in application pod is """ foo """ And Content of file "/bindings/$scenario_id-binding/password" in application pod is """ bar """ And Content of file "/bindings/$scenario_id-binding/type" in application pod is """ db """
INVEST Checklist
Dependencies identified
Blockers noted and expected delivery timelines set
Design is implementable
Acceptance criteria agreed upon
Story estimated
Legend
Unknown
Verified
Unsatisfied
Attachments
Issue Links
- is documented by
-
RHDEVDOCS-3491 [SB] Document support for Workload Resource Mapping
- Closed