Expressions

To pass a step’s output as another step’s parameter, there must be an intermediary storage mechanism of values. In Tonomi Platform, variables can be initialized either to values of the workflow parameters or of the output of an action invocation. To access values kept in these variables, JSON path expressions enclosed in curly braces can be used.

Setting Variables to the Workflow Parameter

A workflow parameter creates a variable in the workflow that has the same name as the parameter name. Consequently, you can access the parameter value within the workflow using a JSON path (no extra steps required).

Setting Variables to the Output of an Action Invocation

Consider the following snippet of code:

- provision-vm:
  action: provisionAmazonVm
  output:
    public-IP-addresses: ips

After the execution of this step, the variable public-IP-addresses will be set to the value returned by the output ips of the action provisionAmazonVm.

Accessing the Variable Values

The variable values can be accessed using JSON paths with the variable name at the expression root. Consider the following snippet of code:

- ping:
  action: execrun
  parameters:
    command:
      - ping
      - '{$.public-IP-addresses[0]}'

Before the execution of this step, the second item in the command parameter will be set to the value of the first entry in the variable named public-IP-addresses.

String Interpolation

When an opening brace ({) followed by a closing brace (}) is encountered within a string, the string is interpolated to evaluate JSON path expressions contained between the braces. For example:

command:
  - wget
  - 'http://{$.public-IP-addresses[0]}/index.html'

will be expanded to

command:
  - wget
  - http://[value of the 1st entry of public-IP-addresses]/index.html

Note

If the interpolated JSON path expression is a list, the result will be a list of strings, each containing one interpolated value from the original list.

For example if public-IP-addresses is an array like this:

['172.16.1.1', '172.16.1.2', '172.16.1.3']

then interpolation of the string 'http://{$.public-IP-addresses}/index.html' will result in the following array of URLs:

- 'http://172.16.1.1/index.html'
- 'http://172.16.1.2/index.html'
- 'http://172.16.1.3/index.html'

Escaping Rules

The characters {, } and $ have special meaning and need to be escaped when used as literals:

'http://{{$$.public-IP-addresses}}/index.html'

will be transformed to this one:

'http://{$.public-IP-addresses}/index.html'

Note

The public-IP-addresses is not evaluated in this case.

Escaping can be necessary when a string contains one or more bash commands. For example, the following string:

'export PATH=/home/user/bin;$${{PATH}}'

will be expanded to the valid bash command:

'export PATH=/home/user/bin;${PATH}'

Customizable Expressions

There can be cases when the curly braces or the dollar sign are used in a source string so frequently that the necessity to escape these symbols becomes a problem. To address it the customizable expression syntax is introduced.

To make use of the new syntax, prepend a source string with the !expr YAML tag. The tagged string has the distinguished treatment:

  • The dollar sign has no special meaning so it should not be escaped at all.
  • First two symbols in the string are reserved for the replacement opening and closing symbols, normally { and }, for enclosing expressions in the subsequent string. These first two symbols are special and will not be emitted into the processed string.
  • If these brace symbols have to be treated in the source string literally, they should be escaped by doubling.

Consider the following example:

steps:
  exec-powershell:
    action: execrun
    parameters:
      command:
        - |
            If ($$SomePowerShellVariable -eq {$.env.foo["bar"]}) {{
              Do-Something
            }}

To avoid doubling of curly braces and dollar signs in the underlying PowerShell script, one could prefer to enclose expressions into some other symbols, for example angle brackets < and >. This can be achieved with the !expr tag:

command:
  - !expr |
      <>
      If ($SomePowerShellVariable -eq <$.env.foo["bar"]>) {
        Do-Something
      }

Thus, curly braces are not doubled here because the other symbols – angle brackets – are defined as the braces for expressions.

In fact, it is even possible to use a single symbol, for example a backslash \, for both opening and closing braces:

command:
  - !expr |
      \\
      If ($SomePowerShellVariable -eq \$.env.foo["bar"]\) {
        Do-Something
      }

The following example demonstrates the necessity to escape symbols defined for bracing in places where they should be treated literally:

command:
  - !expr |
      ()
      If (($SomePowerShellVariable -eq ($.env.foo["bar"]))) {
        Do-Something
      }

Any non-whitespace symbol can be used for bracing, but it is suggested to avoid using symbols that can also be used within expressions: $, @, ., [, ], -, ~, ", ' and any of alphanumeric characters. However, one can manage on his or her own which symbols he or she prefer to use in expressions. For example, there’re square brackets in the list above and the following tagged string won’t work:

command:
  - !expr |
      []
      If ($SomePowerShellVariable -eq [$.env.foo["bar"]]) {
        Do-Something
      }

It is possible to rewrite this particular expression by replacing the index-like access with the property-like access which doesn’t require square braces and the following modified tagged string will be processed correctly:

command:
  - !expr |
      []
      If ($SomePowerShellVariable -eq [$.env.foo.bar]) {
        Do-Something
      }