-
Story
-
Resolution: Done
-
Major
-
None
-
13
-
False
-
False
-
-
AppSvc Sprint 211, AppSvc Sprint 212, AppSvc Sprint 214, AppSvc Sprint 216, AppSvc Sprint 217
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
- is documented by
-
RHDEVDOCS-3491 [SB] Document support for Workload Resource Mapping
- Closed