DSL Reference

CloudSlang is a YAML (version 1.2) based language for describing a workflow. Using CloudSlang you can easily define a workflow in a structured, easy-to-understand format that can be run by the CloudSlang Orchestration Engine (Score). CloudSlang files can be run by the CloudSlang CLI or by an embedded instance of Score using the Slang API.

This reference begins with a brief introduction to CloudSlang files and their structure, then continues with a brief explanation of CloudSlang expressions and variable contexts. Finally, there are alphabetical listings of the CloudSlang keywords and functions. See the examples section for the full code examples from which many of the code snippets in this reference are taken.

CloudSlang Files

CloudSlang files are written using YAML. The recommended extension for CloudSlang flow and operation file names is .sl, but .sl.yaml and .sl.yml will work as well. CloudSlang system properties file names end with the .prop.sl extension.

Since CloudSlang is YAML-based, proper indentation is crucial. For more information, see the YAML Overview.

There are four types of CloudSlang files:

  • flow - contains a list of steps and navigation logic that calls operations or subflows
  • operation - contains an action that runs a script or method
  • decision - contains decision logic without an action
  • system properties - contains a list of system property keys and values

The following properties are for all types of CloudSlang files. For properties specific to flow, operation, or system properties files, see their respective sections below.

Property Required Default Value Type Description More Info
namespace no string
namespace
of the file
namespace
imports no
list of
key:value pairs
files to import imports
extensions no
information to be
ignored by the compiler
extensions

Naming

Names that are interpreted by YAML as non-string types (e.g. booleans, numbers) cannot be used without enclosing them in quotes (') to force YAML to recognize them as strings.

Namespace Names

Namespaces can be named using alphanumeric characters (a-z, A-Z and 0-9), underscores (_) and dashes (-) while using a period (.) as a delimiter.

Since namespaces reflect the folder structure where their respective files are found, they cannot be named using names that are invalid as Windows or Linux folder names.

Namespaces are found in:

  • system property fully qualified names
  • flow, operation, decision and system properties namespaces
  • import values
  • step references

Variable Names

Variable names in CloudSlang files cannot contain localized characters. They can be named using alphanumeric characters (a-z, A-Z and 0-9) and an underscore (_), but may not begin with a number.

CloudSlang variable names must conform to both Python’s naming constraints as well as Java’s naming constraints.

Variable name rules apply to:

  • inputs
  • outputs
  • published variables
  • loop variables

Other Names

All other names can be named using alphanumeric characters (a-z, A-Z and 0-9).

Since flow, operation and decision names must match the names of their respective files, they cannot be named using names that are invalid as Windows or Linux file names.

These rules apply to:

  • import section aliases
  • flow, operation and decision names
  • step names
  • result names
  • navigation keys
  • break keys

Uniqueness and Case Sensitivity

Inputs, outputs, results, publish values, fully qualified system properties and fully qualified executable names must be unique and are validated as case insensitive. When using any of the above, they must be referred to using the case in which they were declared.

Encoding

When using the CLI or Build Tool, CloudSlang will use the encoding found in the CLI configuration file or Build Tool configuration file for input values respectively. If no encoding is found in the configuration file, the CLI or Build Tool will use UTF-8.

Expressions

Many CloudSlang keys map to either an expression or literal value.

Literal Values

Literal values are denoted as they are in standard YAML. Numbers are interpreted as numerical values and strings may be written unquoted, single quoted or double quoted.

Example: literal values

literal_number: 4
literal_unquoted_string: cloudslang
literal_single_quoted_string: 'cloudslang'
literal_double_quoted_string: "cloudslang"

Note

Where expressions are allowed as values (input defaults, output and result values, etc.) and a literal string value is being used, you are encouraged to use a quoted style of literal string.

Example: recommended style for literal strings

flow:
  name: flow_name #expression not allowed - unquoted literal string

  workflow:
    - step1:
        do:
          print:
            - text: "hello" #expression allowed - quoted literal string

Standard Expressions

Expressions are preceded by a dollar sign ($) and enclosed in curly brackets ({}).

Example: expressions

- expression_1: ${4 + 7}
- expression_2: ${some_input}
- expression_3: ${get('input1', 'default_input')}

Expressions with Special Characters

Expressions that contain characters that are considered special characters in YAML must be enclosed in quotes or use YAML block notation. If using quotes, use the style of quotes that are not already used in the expression. For example, if your expression contains single quotes ('), enclose the expression using double quotes (").

Example: escaping special characters

- expression1: "${var1 + ': ' + var2}"
- expression2: >
    ${var1 + ': ' + var2}
- expression3: |
    ${var1 + ': ' + var2}

Maps

To use a map where an expression is allowed use the default property.

Example: passing a map using the default property

- map1:
    default: {a: 1, b: c}
- map2:
    default: {'a key': 1, b: c}

It is also possible to use two sets of quotes and an expression marker, but the approach detailed above is the recommended one.

Example: passing a map using the expression marker and quotes

- map3: "${{'a key': 1, 'b': 'c'}}"
- map4: >
    ${{'a key': 1, 'b': 'c'}}

Contexts

Throughout the execution of a flow, its steps, operations, decisions and subflows there are different variable contexts that are accessible. Which contexts are accessible depends on the current section of the flow, operation or decision.

The table below summarizes the accessible contexts at any given location in a flow, operation or decision.

Contexts/
Location
Context
Passed To
Executable
Flow
Context
Operation/
Decision
Context
Action
Outputs
Context
Subflow/
Operation/
Outputs
Context
Step
Arguments
Branched
Step
Output
Values
Already
Bound
Values
flow
inputs
Yes             Yes
flow
outputs
  Yes           Yes
operation/
decision
inputs
Yes             Yes
operation/
decision
outputs
    Yes Yes       Yes
operation/
decision
results
    Yes Yes        
step
arguments
  Yes           Yes
step
publish
        Yes Yes
Yes - using
branches_context
Yes
step
navigation
        Yes Yes    
action
inputs
    Yes          

Keywords (A-Z)

branches_context

May appear in the publish section of a parallel step.

As branches of a parallel_loop complete, values that have been output and the branch’s result get placed as a dictionary into the branches_context list. The list is therefore in the order the branches have completed.

A specific value can be accessed using the index representing its branch’s place in the finishing order and the name of the variable or the branch_result key.

Example - retrieves the name variable from the first branch to finish

publish:
  - first_name: ${branches_context[0]['name']}

More commonly, the branches_context is used to aggregate the values that have been published by all of the branches.

Example - aggregates name values into a list

publish:
  - name_list: ${map(lambda x:str(x['name']), branches_context)}

branch_result

May appear in the publish section of a parallel step.

As branches of a parallel_loop complete, branch results get placed into the branches_context list under the branch_result key.

Example - aggregates branch results

publish:
  - branch_results_list: ${map(lambda x:str(x['branch_result']), branches_context)}

break

The key break is a property of a loop. It is mapped to a list of results on which to break out of the loop or an empty list ([]) to override the default breaking behavior for a list. When the operation or subflow of the iterative step returns a result in the break’s list, the iteration halts and the iterative step’s navigation logic is run.

If the break property is not defined, the loop will break on results of FAILURE by default. This behavior may be overriden so that iteration will continue even when a result of FAILURE is returned by defining alternate break behavior or mapping the break key to an empty list ([]).

Example - loop that breaks on result of CUSTOM

loop:
  for: value in range(1,7)
  do:
    custom_op:
      - text: ${str(value)}
  break:
    - CUSTOM
navigate:
  - CUSTOM: print_end

Example - loop that continues even on result of FAILURE

loop:
  for: value in range(1,7)
  do:
    custom_op:
      - text: ${str(value)}
  break: []

class_name

The key class_name is a property of a java_action. It is mapped to the name of the Java class where an annotated @Action resides.

decision

The key decision is mapped to the properties which make up the decision contents.

Property Required Default Value Type Description More Info
name yes string
name of the
decision
name
inputs no list decision inputs inputs
outputs no list decision outputs outputs
results yes list
possible decision
results
results

Example - decision that compares two values

decision:
  name: compare

  inputs:
    - x
    - y

  outputs:
    - sum: ${str(int(x) + int(y))}

  results:
    - EQUAL: ${x == y}
    - LESS_THAN: ${int(x) < int(y)}
    - GREATER_THAN

default

The key default is a property of an input name. It is mapped to an expression value.

The expression’s value will be passed to the flow operation or decision if no other value for that input parameter is explicitly passed or if the input’s private parameter is set to true. Passing an empty string (''), null, or an expression that evaluates to None is the same as not passing any value at all and will not override the default value.

Example - default values

inputs:
  - str_literal:
      default: "default value"
  - int_exp:
      default: ${str(5 + 6)}
  - from_variable:
      default: ${variable_name}
  - from_system_property:
      default: $ { get_sp('system.property.key') }

A default value can also be defined inline by entering it as the value mapped to the input parameter’s key.

Example - inline default values

inputs:
  - str_literal: "default value"
  - int_exp: ${str(5 + 6)}
  - from_variable: ${variable_name}
  - from_system_property: $ { get_sp('system.property.key') }

do

The key do is a property of a step name, a loop, or a parallel_loop. It is mapped to a property that references an operation or flow.

Calls an operation or flow and passes in relevant arguments.

The operation or flow may be called in several ways:

  • by referencing the operation or flow by name when it is in the default namespace (the same namespace as the calling flow)
  • by using a fully qualified name, for example, path.to.operation.op_name
    • a path is recognized as a fully qualified name if the prefix (before the first .) is not a defined alias
  • by using an alias defined in the flow’s imports section followed by the operation or flow name (e.g alias_name.op_name)
  • by using an alias defined in the flow’s imports section followed by a continuation of the path to the operation or flow and its name (e.g alias_name.path.cont.op_name)

For more information, see the Operation Paths example.

Arguments are passed to a step using a list of argument names and optional mapped expressions. The step must pass values for all inputs found in the called operation, decision or subflow that are required and don’t have a default value. Passing an empty string (''), null, or an expression that evaluates to None is the same as not passing any value at all.

Argument names should be different than the output names found in the operation, decision or subflow being called in the step.

Argument names must conform to the rules for valid variable names.

An argument name without an expression will take its value from a variable with the same name in the flow context. Expression values will supersede values bound to flow inputs with the same name. To force the operation, decision or subflow being called to use it’s own default value, as opposed to a value passed in via expression or the flow context, omit the variable from the calling step’s argument list.

For a list of which contexts are available in the arguments section of a step, see Contexts.

Example - call to a divide operation with list of mapped step arguments

do:
  divide:
    - dividend: ${input1}
    - divisor: ${input2}

Example - force an operation to use default value for punctuation input

flow:
  name: flow

  inputs:
      - punctuation: "!"

  workflow:
    - step1:
        do:
          punc_printer:
            - text: "some text"
            #- punctuation
            #commenting out the above line forces the operation to use its default value (".")
            #leaving it in would cause the operation to take the value from the flow context ("!")
operation:
  name: operation
  inputs:
    - text
    - punctuation: "."
  python_action:
    script: |
      print text + punctuation

extensions

The key extensions is mapped to information that the compiler will ignore and can therefore be used for various purposes.

Example - a flow that contains an extensions section

namespace: examples.extensions

flow:
  name: flow_with_extensions_tag

  workflow:
    - noop_step:
      do:
        noop: []

extensions:
  - some_key:
      a: b
      c: d
  - another

flow

The key flow is mapped to the properties which make up the flow contents.

A flow is the basic executable unit of CloudSlang. A flow can run on its own or it can be used by another flow in the do property of a step.

Property Required Default Value Type Description More Info
name yes string name of the flow name
inputs no list inputs for the flow inputs
workflow yes list of steps
container for
workflow steps
workflow
outputs no list list of outputs outputs
results no
(SUCCESS /
FAILURE )
list
possible results
of the flow
results

Example - a flow that performs a division of two numbers

flow:
  name: division

  inputs:
    - input1
    - input2

  workflow:
    - divider:
        do:
          divide:
            - dividend: ${input1}
            - divisor: ${input2}
        publish:
          - answer: ${quotient}
        navigate:
          - ILLEGAL: ILLEGAL
          - SUCCESS: printer
    - printer:
        do:
          print:
            - text: ${input1 + "/" + input2 + " = " + answer}
        navigate:
          - SUCCESS: SUCCESS

  outputs:
    - quotient: ${answer}

  results:
    - ILLEGAL
    - SUCCESS

for

The key for is a property of a loop or an parallel_loop.

loop: for

A for loop iterates through a list or a map.

The iterative step will run once for each element in the list or key in the map.

Loop variables must conform to the rules for valid variable names.

Iterating through a list

When iterating through a list, the for key is mapped to an iteration variable followed by in followed by a list, an expression that evaluates to a list, or a comma delimited string.

Example - loop that iterates through the values in a list

- print_values:
    loop:
      for: value in [1,2,3]
      do:
        print:
          - text: ${str(value)}

Example - loop that iterates through the values in a comma delimited string

- print_values:
    loop:
      for: value in "1,2,3"
      do:
        print:
          - text: ${value}

Example - loop that iterates through the values returned from an expression

- print_values:
    loop:
      for: value in range(1,4)
      do:
        print:
          - text: ${str(value)}
Iterating through a map

When iterating through a map, the for key is mapped to iteration variables for the key and value followed by in followed by a map or an expression that evaluates to a map.

Example - step that iterates through the values returned from an expression

- print_values:
    loop:
      for: k, v in map
      do:
        print2:
          - text1: ${k}
          - text2: ${v}

parallel_loop: for

A parallel for loop loops in parallel branches over the items in a list.

The parallel step will run one branch for each element in the list.

The for key is mapped to an iteration variable followed by in followed by a list or an expression that evaluates to a list.

Example - step that loops in parallel through the values in a list

- print_values:
    parallel_loop:
      for: value in values_list
      do:
        print_branch:
          - ID: ${value}

gav

The key gav is a property of a java_action. It is mapped to the group:artifact:version of the Maven project in which an annotated Java @Action resides.

Upon operation execution, the Maven project and all the required resources specified in its pom’s dependencies will be resolved and downloaded (if necessary).

Example - referencing Maven artifact using gav

java_action:
  gav: io.cloudslang.content:cs-xml:0.0.2
  class_name: io.cloudslang.content.mail.actions.SendMailAction
  method_name: execute

imports

The key imports is mapped to the files to import as follows:

  • key - alias
  • value - namespace of file to be imported

Specifies the file’s dependencies, operations and subflows, by the namespace defined in their source file and the aliases they will be referenced by in the file.

Using an alias is one way to reference the operations and subflows used in a flow’s steps. For all the ways to reference operations and subflows used in a flow’s steps, see the do keyword and the Operation Paths example.

Import aliases must conform to the rules for valid names.

Example - import operations and sublflow into flow

imports:
  ops: examples.utils
  subs: examples.subflows

flow:
  name: hello_flow

  workflow:
    - print_hi:
        do:
          ops.print:
            - text: "Hi"
    - run_subflow:
        do:
          subs.division:
            - input1: "5"
            - input2: "3"

In this example, the ops alias refers to the `examples.utils namespace. This alias is used in the print_hi step to refer to the print operation, whose source file defines its namespace as examples.utils. Similarly, the subs alias refers to the examples.subflows namespace. The subs alias is used in the run_subflow step to refer to the division subflow, whose source file defines its namespace as examples.subflows.

inputs

The key inputs is a property of a flow, operation or decision. It is mapped to a list of input names. Each input name may in turn be mapped to its properties or an input expression.

Inputs are used to pass parameters to flows, operations or decisions. Non-private input names for a specific flow, operation or decision must be different than the output names of the same flow, operation or decision.

Input values must evaluate to type string.

For a list of which contexts are available in the inputs section of a flow, operation or decision, see Contexts.

Input names must conform to the rules for valid variable names and uniqueness.

Property Required Default Value Type Description More info
required no true boolean
is the input
required
required
default no expression
default value
of the input
default
private no false boolean
if true, the
default value
always overrides
values passed in
private
sensitive no
transitive
sensitivity
or false
boolean
is the input
sensitive
sensitive

Example - several inputs

inputs:
  - input1:
      default: "default value"
      private: true
  - input2
  - input3: "default value"
  - input4: ${'input1 is ' + input1}
  - password:
      sensitive: true

java_action

The key java_action is a property of an operation. It is mapped to the properties that define where an annotated Java @Action resides.

Property Required Default Value Type Description More info
gav yes string group:artifact:version gav
class_name yes string
fully qualified
Java class name
class_name
method_name no string Java method name method_name

Example - CloudSlang call to a Java action

namespace: io.cloudslang.base.mail

operation:
  name: send_mail

  inputs:
    - hostname
    - port
    - from
    - to
    - subject
    - body

  java_action:
    gav: io.cloudslang.content:cs-xml:0.0.2
    class_name: io.cloudslang.content.mail.actions.SendMailAction
    method_name: execute

  results:
    - SUCCESS: ${ returnCode == '0' }
    - FAILURE

Existing Java Actions

There are many existing Java actions which are bundled with the CloudSlang CLI. The source code for these Java actions can be found in the cs-actions repository.

Adding a New Java Action

To add a new Java action:

Write an Annotated Java Method

Create a Java method that conforms to the signature public Map<String, String> doSomething(paramaters) and use the following annotations from com.hp.oo.sdk.content.annotations:

  • @Action: specifies action information

    • name: name of the action
    • outputs: array of @Output annotations
    • responses: array of @Response annotations
  • @Output: action output name

  • @Response: action response

    • text: name of the response
    • field: result to be checked
    • value: value to check against
    • matchType: type of check
    • responseType: type of response
    • isDefault: whether or not response is the default response
    • isOnFail: whether or not response is the failure response
  • @Param: action parameter

    • value: name of the parameter
    • required: whether or not the parameter is required

Values are passed to a Java action from an operation using CloudSlang inputs that match the annotated parameters.

Values are passed back from the Java action to an operation using the returned Map<String, String>, where the map’s elements each correspond to a name:value that matches a CloudSlang output.

Example - Java action

package com.example.content.actions;

import com.hp.oo.sdk.content.annotations.Action;
import com.hp.oo.sdk.content.annotations.Output;
import com.hp.oo.sdk.content.annotations.Param;
import com.hp.oo.sdk.content.annotations.Response;
import com.hp.oo.sdk.content.plugin.ActionMetadata.MatchType;

import java.util.Map;
import java.util.HashMap;

public class SaySomething {

      @Action(name = "Example Test Action",
              outputs = {
                      @Output("message")
              },
              responses = {
                      @Response(text = "success", field = "message", value = "fail", matchType = MatchType.COMPARE_NOT_EQUAL),
                      @Response(text = "failure", field = "message", value = "fail", matchType = MatchType.COMPARE_EQUAL, isDefault = true, isOnFail = true)
              }
      )
      public Map<String, String> speak(@Param(value = "text", required = true) String text) {
          Map<String, String> results = new HashMap<>();

          System.out.println("I say " + text);

          results.put("message", text);

          return  results;
      }
}
Release to remote Maven repository

Note

Maven version used in the CLI, Builder and cs-actions is 3.3.9 There might be some issues while building the Java Actions with other versions.

Use Maven to package the project containing the Java action method and release it to the remote repository defined in the CLI’s configuration file.

Below is an example pom.xml file that can be used for your Maven project.

Example - sample pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example.content</groupId>
    <artifactId>action-example</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>${project.groupId}:${project.artifactId}</name>
    <description>Test Java action</description>
    <dependencies>
        <dependency>
            <groupId>com.hp.score.sdk</groupId>
            <artifactId>score-content-sdk</artifactId>
            <version>1.10.6</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
Reference Maven artifact

Reference your Maven artifact using the gav key in the java_action section of your operation.

Upon the operation’s first execution, the Maven project and all the required resources specified in its pom’s dependencies will be resolved and downloaded.

loop

The key loop is a property of an iterative step’s name. It is mapped to the iterative step’s properties.

For each value in the loop’s list the do will run an operation or subflow. If the returned result is in the break list, or if break does not appear and the returned result is FAILURE, or if the list has been exhausted, the step’s navigation will run.

Property Required Default Value Type Description More Info
for yes variable in list iteration logic for
do yes
operation or
subflow call
the operation or
subflow this step
will run iteratively
publish no
list of
key:value pairs
operation or subflow
outputs to aggregate and
publish to the flow level
break no list of results
operation or subflow
results on which to
break out of the loop
break

Example: loop that breaks on a result of custom

- custom3:
    loop:
      for: value in "1,2,3,4,5"
      do:
        custom3:
          - text: ${value}
      break:
        - CUSTOM
    navigate:
      - CUSTOM: aggregate
      - SUCCESS: skip_this

method_name

The key method_name is a property of a java_action. It is mapped to the name of the Java method where an annotated @Action resides.

name

The key name is a property of flow, operation or decision. It is mapped to a value that is used as the name of the flow or operation.

The name of a flow, operation or decision may be used when called from a flow’s step.

The name of a flow, operation or decision must match the name of the file in which it resides, excluding the extension.

The name must conform to the rules for names and uniqueness.

Example - naming the flow found in the file division_flow.sl

name: division_flow

namespace

The key namespace is mapped to a string value that defines the file’s namespace.

The namespace of a file may be used by a flow to import dependencies.

Example - definition a namespace

namespace: examples.hello_world

Example - using a namespace in an imports definition

imports:
  ops: examples.hello_world

Namespace values must conform to the rules described in Namespace Names. For more information about choosing a file’s namespace, see the CloudSlang Content Best Practices section.

Note

If the imported file resides in a folder that is different from the folder in which the importing file resides, the imported file’s directory must be added using the --cp flag when running from the CLI (see Run with Dependencies).

on_failure

The key on_failure is a property of a workflow. It is mapped to a step.

Defines the step, which when using default navigation, is the target of a FAILURE result returned from an operation or flow. The on_failure step can also be reached by mapping one of a step’s navigation keys to on_failure. If a step’s navigation explicitly maps to on_failure, but there is no on_failure step defined in the flow, the flow ends with a result of FAILURE.

The on_failure step must be the last step in the flow.

The on_failure step cannot contain a navigation section. It always causes the flow to end with a result of FAILURE.

Example - failure step which calls a print operation to print an error message

- on_failure:
  - failure:
      do:
        print:
          - text: ${error_msg}

Example - explicitly navigating to the on_failure step

- go_to_failure:
    do:
      some_operation:
        - input1
    navigate:
      - SUCCESS: SUCCESS
      - FAILURE: on_failure

operation

The key operation is mapped to the properties which make up the operation contents.

Property Required Default Value Type Description More Info
name yes string
name of the
operation
name
inputs no list operation inputs inputs
python_action no script key operation logic python_action
java_action     map operation logic java_action
outputs no list operation outputs outputs
results no SUCCESS list
possible operation
results
results

Example - operation that adds two inputs and outputs the answer

operation:
  name: add

  inputs:
    - left
    - right

  python_action:
    script: ans = int(left) + int(right)

  outputs:
    - out: ${str(ans)}

  results:
    - SUCCESS

outputs

The key outputs is a property of a flow, operation or decision. It is mapped to a list of output variable names. Each output name may in turn be mapped to its properties or an output expression. Output expressions must evaluate to strings.

Defines the parameters a flow, operation or decision exposes to possible publication by a step. The calling step refers to an output by its name.

Output names for a specific flow, operation or decision must be different than the non-private input names of the same flow, operation or decision.

Output values must evaluate to type string.

For a list of which contexts are available in the outputs section of a flow, operation or decision, see Contexts.

Output identifiers must conform to the rules for valid variable names and uniqueness.

Property Required Default Value Type Description More info
value no expression
value of
the output
value
sensitive no
transitive
sensitivity
or false
boolean
is the output
sensitive
sensitive

Example - various types of outputs

outputs:
  - existing_variable
  - output2: ${some_variable}
  - output3: ${str(5 + 6)}
  - password:
      value: ${password}
      sensitive: true

parallel_loop

The key parallel_loop is a property of a parallel step’s name. It is mapped to the parallel step’s properties.

For each value in the loop’s list a branch is created and the do will run an operation or subflow. When all the branches have finished, the parallel step’s publish and navigation will run.

Property Required Default Value Type Description More Info
for yes
variable in
list
loop values for
do yes
operation or
subflow call
operation or subflow
this step will
run in parallel

Example: loop that breaks on a result of custom

- print_values:
    parallel_loop:
      for: value in values
      do:
        print_branch:
          - ID: ${value}
    publish:
        - name_list: ${map(lambda x:str(x['name']), branches_context)}
    navigate:
        - SUCCESS: print_list
        - FAILURE: FAILURE

private

The key private is a property of an input name. It is mapped to a boolean value.

A value of true will ensure that the input parameter’s default value will not be overridden by values passed into the flow, operation or decision. An input set as private: true must also declare a default value. If private is not defined, values passed in will override the default value.

Example - default value of text input parameter will not be overridden by values passed in

inputs:
  - text:
      default: "default text"
      private: true

properties

The key properties is mapped to a list of key:value pairs that define one or more system properties. Each system property name may in turn be mapped to its properties or a value.

System property names (keys) can contain alphanumeric characters (A-Za-z0-9), underscores (_) and hyphens (-). The names must conform to the rules for uniqueness.

System property values are retrieved using the get_sp() function.

Note

System property values that are non-string types (numeric, list, map, etc.) are converted to string representations. A system property may have a value of null.

Property Required Default Value Type Description More info
value no  
value of
the property
value
sensitive no false boolean
is the property
sensitive
sensitive

Example - system properties file

namespace: examples.sysprops

properties:
  - host: 'localhost'
  - port: 8080
  - password:
      value: 'pwd'
      sensitive: true

An empty system properties file can be defined using an empty list.

Example - empty system properties file

namespace: examples.sysprops

properties: []

publish

The key publish is a property of a step name, a loop or a parallel_loop. It is mapped to a list of key:value pairs where the key is the published variable name and the value is an expression, usually involving an output received from an operation or flow.

For a list of which contexts are available in the publish section of a step, see Contexts.

Publish names must conform to the rules for valid variable names and uniqueness.

Standard publish

In a standard step, publish binds an expression, usually involving an output from an operation or flow, to a variable whose scope is the current flow and can therefore be used by other steps or as the flow’s own output.

Example - publish the quotient output as ans

- division1:
    do:
      division:
        - input1: ${dividend1}
        - input2: ${divisor1}
    publish:
      - ans: ${quotient}

Iterative publish

In an iterative step the publish mechanism is run during each iteration after the operation or subflow has completed, therefore allowing for aggregation.

Example - publishing in an iterative step to aggregate output: add the squares of values in a range

- aggregate:
    loop:
      for: value in range(1,6)
      do:
        square:
          - to_square: ${str(value)}
          - sum
      publish:
        - sum: ${str(int(sum) + int(squared))}

Parallel publish

In a parallel step the publish mechanism defines the step’s aggregation logic, generally making use of the branches_context construct.

After all branches of a parallel step have completed, execution of the flow continues with the publish section. The expression of each name:value pair is evaluated and published to the flow’s scope. The expression generally makes use of the branches_context construct to access the values published by each of the parallel loop’s branches and their results using the branch_result key.

For a list of which contexts are available in the publish section of a step, see Contexts.

For more information, see the Parallel Loop example.

Example - publishing in an parallel step to aggregate output

- print_values:
    parallel_loop:
      for: value in values_list
      do:
        print_branch:
          - ID: ${value}
    publish:
        - name_list: ${map(lambda x:str(x['name']), branches_context)}

Example - extracting information from a specific branch

- print_values:
    parallel_loop:
      for: value in values_list
      do:
        print_branch:
          - ID: ${value}
    publish:
        - first_name: ${branches_context[0]['name']}

Example - create a list of branch results

- print_values:
    parallel_loop:
      for: value in values
      do:
        print_branch:
          - ID: ${ value }
    publish:
      - branch_results_list: ${map(lambda x:str(x['branch_result']), branches_context)}

python_action

The key python_action is a property of an operation. It is mapped to a script property that contains the actual Python script.

results

The key results is a property of a flow, operation or decision.

The results of a flow, operation or decision can be used by the calling step for navigation purposes.

A result name must conform to the rules for names and uniqueness. Additionally, a result cannot be named on_failure.

Note

The only results of an operation, decision or subflow called in a parallel_loop that are evaluated are SUCCESS and FAILURE. Any other results will be evaluated as SUCCESS.

Flow Results

In a flow, the key results is mapped to a list of result names.

Defines the possible results of the flow. By default a flow has two results, SUCCESS and FAILURE. The defaults can be overridden with any number of user-defined results.

When overriding, the defaults are lost and must be redefined if they are to be used.

All result possibilities must be listed. When being used as a subflow all flow results must be handled by the calling step.

Example - a user-defined result

results:
  - SUCCESS
  - ILLEGAL
  - FAILURE

Operation and Decision Results

In an operation or decision the key results is mapped to a list of key:value pairs of result names and boolean expressions.

Defines the possible results of the operation or decision. By default, if no results exist, the result of an operation is SUCCESS. A decision does not have any default results.

The first result in the list whose expression evaluates to true, or does not have an expression at all, will be passed back to the calling step to be used for navigation purposes.

If results are present, the list must include exactly one default ending result which is not mapped to anything (- result) or is mapped to the value true (- result: true).

All operation or decision results must be handled by the calling step.

For a list of which contexts are available in the results section of an operation or decision, see Contexts.

Example - three user-defined results

results:
  - POSITIVE: ${polarity == '+'}
  - NEGATIVE: ${polarity == '-'}
  - NEUTRAL

required

The key required is a property of an input name. It is mapped to a boolean value.

A value of false will allow the flow or operation to be called without passing the input parameter. If required is not defined, the input parameter defaults to being required.

Required inputs must receive a value or declare a default value. Passing an empty string (''), null, or an expression that evaluates to None to a required input is the same as not passing any value at all.

Example - input2 is optional

inputs:
  - input1
  - input2:
      required: false

script

The key script is a property of python_action. It is mapped to a value containing a Python script.

All variables in scope at the conclusion of the Python script must be serializable. If non-serializable variables are used, remove them from scope by using the del keyword before the script exits.

Note

CloudSlang uses the Jython implementation of Python 2.7. For information on Jython’s limitations, see the Jython FAQ.

Example - action with Python script that divides two numbers

name: divide

inputs:
  - dividend
  - divisor

python_action:
  script: |
    if divisor == '0':
      quotient = 'division by zero error'
    else:
      quotient = float(dividend) / float(divisor)

outputs:
  - quotient: ${str(quotient)}

results:
  - ILLEGAL: ${quotient == 'division by zero error'}
  - SUCCESS

Note

Single-line Python scripts can be written inline with the script key. Multi-line Python scripts can use the YAML pipe (|) indicator as in the example above.

Importing External Python Packages

There are three approaches to importing and using external Python modules:

  • Installing packages into the python-lib folder
  • Editing the executable file
  • Adding the package location to sys.path
Installing Packages into the python-lib Folder

Prerequisites: Python 2.7 and pip.

You can download Python (version 2.7) from here. Python 2.7.9 and later include pip by default. If you already have Python but don’t have pip, see the pip documentation for installation instructions.

  1. Edit the requirements.txt file in the python-lib folder, which is found at the same level as the bin folder that contains the CLI executable.

    • If not using a pre-built CLI, you may have to create the python-lib folder and requirements.txt file.
  2. Enter the Python package and all its dependencies in the requirements file.

    • See the pip documentation for information on how to format the requirements file (see example below).
  3. Run the following command from inside the python-lib folder: pip install -r requirements.txt -t.

    Note

    If your machine is behind a proxy you will need to specify the proxy using pip’s --proxy flag.

  4. Import the package as you normally would in Python from within the action’s script:

python_action:
  script: |
    from pyfiglet import Figlet
    f = Figlet(font='slant')
    print f.renderText(text)

Example - requirements file

pyfiglet == 0.7.2
setuptools

Note

If you have defined a JYTHONPATH environment variable, you will need to add the python-lib folder’s path to its value.

Editing the Executable File
  1. Open the executable found in the bin folder for editing.
  2. Change the Dpython.path key’s value to the desired path.
  3. Import the package as you normally would in Python from within the action’s script.
Adding the Package Location to sys.path
  1. In the action’s Python script, import the sys module.
  2. Use sys.path.append() to add the path to the desired module.
  3. Import the module and use it.

Example - takes path as input parameter, adds it to sys.path and imports desired module

inputs:
  - path
python_action:
  script: |
    import sys
    sys.path.append(path)
    import module_to_import
    print module_to_import.something()

Importing Python Scripts

To import a Python script in a python_action:

  1. Add the Python script to the python-lib folder, which is found at the same level as the bin folder that contains the CLI executable.
  2. Import the script as you normally would in Python from within the action’s script.

Note

If you have defined a JYTHONPATH environment variable, you will need to add the python-lib folder’s path to its value.

sensitive

The key sensitive is a property of an input, output or system property name. It is mapped to a boolean value.

The sensitivity of an input or output is transitive, and is therefore determined by its sensitive property and by the sensitivity of variables used in its related value expression.

The “sensitive” property works for both flow input and step input.

Values that are sensitive will not be printed in logs, events or in outputs of the CLI and Build Tool.

Example - two sensitive inputs

inputs:
  - input1:
      default: "default value"
      sensitive: true
  - input1plus:
      default: ${ get("input1") + "something else" }

Example - two sensitive outputs

outputs:
  - output1:
      value: ${output1}
      sensitive: true
  - output2: ${already_sensitive_value}

Example - a sensitive system property

properties:
  - password:
      value: 'pwd'
      sensitive: true

step

A name of a step which is a property of workflow.

A step name must conform to the rules for names and uniqueness. Additionally, a step cannot be named on_failure.

Every step which is not declared with the on_failure keyword must be reachable from another step.

step input

Property Required Default Value Type Description More info
value no expression
value of
the step input
value
sensitive no
transitive
sensitivity
or false
boolean
is the step
input
sensitive
sensitive

There are several types of steps:

Example - step with two arguments, one of which contains a default value

- divider:
    do:
      some_op:
        - host
        - port: '25'

Standard Step

A standard step calls an operation or subflow once.

The step name is mapped to the step’s properties.

Property Required Default Value Type Description More Info
do yes
operation
or subflow
call
the operation or
subflow this step
will run
publish no
list of
key:value
pairs
operation outputs
to publish to the
flow level
navigate no
FAILURE: on_failure
or flow finish
SUCCESS: next step
list of
key:value
pairs
navigation logic
from operation or
flow results

Example - step that performs a division of two inputs, publishes the answer and navigates accordingly

- divider:
    do:
      divide:
        - dividend: ${input1}
        - divisor: ${input2}
    publish:
      - answer: ${quotient}
    navigate:
      - ILLEGAL: FAILURE
      - SUCCESS: printer

Iterative Step

An iterative step calls an operation or subflow iteratively, for each value in a list.

The step name is mapped to the iterative step’s properties.

Property Required Default Value Type Description More Info
loop yes key
container for
loop properties
for
navigate no
FAILURE:
on_failure
or flow finish
SUCCESS:
next step
key:value
pairs
navigation logic from
break or the result
of the last iteration of
the operation or flow

Example - step prints all the values in value_list and then navigates to a step named “another_step”

- print_values:
    loop:
      for: value in value_list
      do:
        print:
          - text: ${value}
    navigate:
      - SUCCESS: another_step
      - FAILURE: FAILURE

Parallel Step

A parallel step calls an operation or subflow in parallel branches, for each value in a list.

The step name is mapped to the parallel step’s properties.

Property Required Default Value Type Description More Info
parallel_loop yes key
container for
parallel loop
properties
parallel_loop
publish no
list of
key:values
values to
aggregate from
parallel branches
loop properties
publish
navigate no
FAILURE: on_failure
or flow finish
SUCCESS: next step
key:value
pairs
navigation logic

Example - step prints all the values in value_list in parallel and then navigates to a step named “another_step”

- print_values:
    parallel_loop:
      for: value in values_list
      do:
        print_branch:
          - ID: ${value}
    publish:
        - name_list: ${map(lambda x:str(x['name']), branches_context)}
    navigate:
        - SUCCESS: another_step
        - FAILURE: FAILURE

value

The key value is a property of an step input, output or system property name. In an output, the key is mapped to an expression value. In a system property, the key is mapped to a valid system property value.

The value key is most often used in conjunction with the sensitive key. Otherwise, an output or system property’s value can be defined inline by mapping it to the output or system property’s name.

Example - output values

outputs:
  - password:
      value: ${password}
      sensitive: true
  - another_output: ${op_output}

Example - system property values

properties:
  - props.password:
      value: 'pwd'
      sensitive: true
  - props.another_property: 'prop value'

workflow

The key workflow is a property of a flow. It is mapped to a list of the workflow’s steps.

Defines a container for the steps, their published variables and navigation logic.

The first step in the workflow is the starting step of the flow. From there the flow continues sequentially by default upon receiving results of SUCCESS, to the flow finish or to on_failure upon a result of FAILURE, or following whatever overriding navigation logic that is present.

Property | Required | Default | Value Type | Description | More Info
on_failure no step
default navigation
target for FAILURE

Example - workflow that divides two numbers and prints them out if the division was legal

workflow:
  - divider:
      do:
        divide:
          - dividend: ${input1}
          - divisor: ${input2}
      publish:
        - answer: ${quotient}
      navigate:
        - ILLEGAL: FAILURE
        - SUCCESS: printer
  - printer:
      do:
        print:
          - text: ${input1 + "/" + input2 + " = " + answer}

Functions (A-Z)

check_empty()

May appear in the value of an input, output, publish or result expression.

The function in the form of check_empty(expression1, expression2) returns the value associated with expression1 if expression1 does not evaluate to None. If expression1 evaluates to None the function returns the value associated with expression2.

Example - usage of check_empty to check operation output in a flow

flow:
  name: flow
  inputs:
    - in1
  workflow:
    - step1:
        do:
          operation:
            - in1
        publish:
          - pub1: ${check_empty(out1, 'x marks the spot')}
          #if in1 was not 'x' then out1 is 'not x' and pub1 is therefore 'not x'
          #if in1 was 'x' then out1 is None and pub1 is therefore 'x marks the spot'
  outputs:
    - pub1
operation:
  name: operation
  inputs:
    - in1
  python_action:
    script: |
      out1 = 'not x' if in1 != 'x' else None
  outputs:
    - out1

get()

May appear in the value of an input, output, publish or result expression.

The function in the form of get('key') returns the value associated with key if the key is defined. If the key is undefined the function returns None.

The function in the form of get('key', 'default_value') returns the value associated with key if the key is defined and its value is not None. If the key is undefined or its value is None the function returns the default_value.

Example - usage of get function in inputs and outputs

inputs:
  - input1:
      required: false
  - input1_safe:
      default: ${get('input1', 'default_input')}
      private: true

workflow:
  - step1:
      do:
        print:
          - text: ${input1_safe}
      publish:
        - some_output: ${get('output1', 'default_output')}

outputs:
  - some_output

get_sp()

May appear in the value of an input, step argument, publish, output or result expression.

The function in the form of get_sp('key', 'default_value') returns the value associated with the system property named key if the key is defined and its value is not null. If the key is undefined or its value is null the function returns the default_value. The key is the fully qualified name of the system property, meaning the namespace (if there is one) of the file in which it is found followed by a dot . and the name of the key.

System property values are always strings or null. Values of other types (numeric, list, map, etc.) are converted to string representations.

System properties are not enforced at compile time. They are assigned at runtime.

Note

If multiple system properties files are being used and they contain a system property with the same fully qualified name, the property in the file that is loaded last will overwrite the others with the same name.

Example - system properties file

namespace: examples.sysprops

properties:
  - host: 'localhost'
  - port: 8080

Example - system properties used as input values

inputs:
  - host: ${get_sp('examples.sysprops.hostname')}
  - port: ${get_sp('examples.sysprops.port', '8080')}

To pass a system properties file to the CLI, see Run with System Properties.