Uploaded image for project: 'Service Binding'
  1. Service Binding
  2. APPSVC-970

Support Workload Resource Mapping

XMLWordPrintable

    • 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

              ansadler@redhat.com Andy Sadler
              bmuthuka Baiju Muthukadan
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: