Direct way of consuming parameters/credentials as JSON objects?
Is there a direct way of consuming parameters or credentials in porter.yaml as JSON objects (i.e. use their sub-properties as inputs to commands)? Currently one might feed a parameter/credential into an exec command, which calls a bash script, which simply echos the value, which can then be teased into individual outputs using jsonPath. Is there a better way?
We don't currently support that right now, you would need to do the workaround you laid out (using exec mixin to grab the piece you want and output a sub-property).
However it could be possible for parameters with a bit of work in Porter. We support this for custom values defined in porter.yaml, where you can use templating like {{ bundle.custom.myobj.subfield }}.
Let me lay out what I think it could look like, and let me know if it works with your use case:
config.json
{
"color": "blue"
}
porter.yaml
parameters:
- name: config
type: object
path: /cnab/app/config.json # User passes in a json document for this parameter
install:
- exec:
description: Use a sub field on the config property document
command: ./helpers.sh
arguments:
- "{{ bundle.parameters.config.color }}" # passes in "blue"
Porter would need to do some special handling for parameters of type "object" and expand them in the template (instead of providing it as a string) which I think is the right thing here, we just missed it the first time around.
I'm going to assume that this (above) is a workable design but if anyone has feedback on how they would like to use parameters that are a structured object (instead of a simple value), please leave a comment!
Yes, I think that design would work for us.
Thanks for letting me know! I think it's a straightforward change for someone familiar with Go. We would need to attempt to unmarshal the parameter as json, and if it works assign that to the parameter's value. If it can't be read as json, that would be a hard error, since the parameter validation which occurrs before the bundle is run should have checked that it's a json document already.
The change should be made in this function, so that it returns an (interface{}, error) instead of a string.
https://github.com/getporter/porter/blob/9f608fffee0a203c406915a5e5f66acd9ee32b67/pkg/runtime/runtime-manifest.go#L106
If anyone is interested in trying to fix this, I'm happy to help. Otherwise it's on the v1.0 roadmap now.
We can make this work in a v1 minor patch, without a breaking change. To do this we need to preserve this existing functionality
install:
- exec:
command: foo
arguments:
- "{{ bundle.parameters.config }}" # should still inject the string representation of the json document