cnabio / cnab-spec

Cloud Native Application Bundle Specification
https://cnab.io
Other
956 stars 99 forks source link

Define a bundle interface #422

Open carolynvs opened 2 years ago

carolynvs commented 2 years ago

In order to support having a dependency on another bundle, where the exact bundle is not specified but you know what you need from the bundle, we need to define what is a bundle's interface.

Similar to the Go programming language, the interface is defined by the bundle that would use it, not the bundle that implements it. So a bundle doesn't say "I implement the mysql interface", instead a bundle that needs mysql would define the interface it requires and any bundle could match.

For example, a wordpress bundle that just needs a mysql database of any type could define the dependency as follows:

dependencies:
  requires:
    - name: mysql
       reference: getporter/mysql:v0.1.1
       interfaceDocument: # bundle.json document embedded

Reference another bundle and use it as an interface

dependencies:
  requires:
    - name: mysql
       reference: getporter/mysql:v0.1.1
       interfaceReference: getporter/mysql:v0.1.1

Any bundle that outputs a string parameter named connectionString could then be used for that dependency.

Just going by name and type is a bit difficult however. From experience I know that getting bundle authors to all use the same names for anything is a challenge. Since output supports jsonschema, we could also have interfaces be based on a set of matching characteristics. So whatever is defined on the output, must be matched on the outputs on the candidate bundle.

One way to help bundle authors use consistent naming that would support dependencies matching the correct characteristics would be to provide a non-normative spec section just for interfaces that people are using. In the example below, the output would need its $id field to be a well-known string (a URI in this case but it doesn't have to be) that indicates the intent of the output. In this case a mysql connection string.

dependencies:
  requires:
    - name: mysql
       interface:
         outputs:
           - $id: "https://cnab.io/interfaces/mysql#connectionString"
              type: string

Note that bundle dependencies cannot alter the exposed interface of the parent bundle. The parent bundle is responsible for defining any parameters/credentials/outputs necessary to use the dependency and then manage wiring up those values so that they are exposed.

The question is then

carolynvs commented 2 years ago

Q: When the tool provides an existing installation to the runtime to use as a dependency, do we compare the entire interface or just outputs and custom action?

A: It's up to the tool to look at the interface and decide if it can make that work. Some tools may need to ignore different fields (like description) and others may use comment/id to make decisions. We can make a non-normative section with recommendations and then tools can customize as needed.