Jump to: navigation, search

Difference between revisions of "Mistral/DSL"

(Triggers)
(Full YAML example:)
Line 116: Line 116:
 
=== Full YAML example: ===
 
=== Full YAML example: ===
  
   Workflow:
+
# This example requires the following properties provided in execution context:
 +
# - nova_url  ## url to Nova service, e.g. http://0.0.0.0:8774/v3
 +
# - server_name ## Name you want to give to new instance
 +
# - image_id  ## image id from Glance service
 +
# - flavor_id ## flavor id - type of instance hardware
 +
# - ssh_username ## username of your VM
 +
# - ssh_password ## password to your VM
 +
# - admin_email ## email address to send notifications to
 +
# - from_email ## email address to send notifications from
 +
# - smtp_server ## SMTP server to use for sending emails (e.g. smtp.gmail.com:587)
 +
# - smtp_password ## password to connect to SMTP server
 +
 
 +
 
 +
Namespaces:
 +
   Nova:
 +
    # Nova actions for creating VM, retrieving IP and VM deleting.
 +
    class: std.http
 +
    actions:
 +
      createVM:
 +
        base-parameters:
 +
          url: '{$.nova_url}/{$.project_id}/servers'
 +
          method: POST
 +
          headers:
 +
            X-Auth-Token: $.auth_token
 +
            Content-Type: application/json
 +
          body:
 +
            server:
 +
              name: $.server_name
 +
              imageRef: $.image_id
 +
              flavorRef: $.flavor_id
 +
        output:
 +
          vm_id: $.content.server.id
 +
 
 +
      getIP:
 +
        base-parameters:
 +
          url: '{$.nova_url}/{$.project_id}/servers/{$.vm_id}'
 +
          method: GET
 +
          headers:
 +
            X-Auth-Token: $.auth_token
 +
        output:
 +
          vm_ip: "$.content.server.addresses.novanetwork.where($.'OS-EXT-IPS:type' = 'floating')[0].addr"
 +
 
 +
      deleteVM:
 +
        base-parameters:
 +
          url: '{$.nova_url}/{$.project_id}/servers/{$.vm_id}'
 +
          method: DELETE
 +
          headers:
 +
            X-Auth-Token: $.auth_token
 +
        output:
 +
          status: $.status
 +
 
 +
  Server:
 +
    actions:
 +
      # HTTP request to the server.
 +
      calcSumm:
 +
        class: std.http
 +
        base-parameters:
 +
          url: 'http://{$.vm_ip}:5000/summ'
 +
          method: POST
 +
          body:
 +
            arguments: $.arguments
 +
        output:
 +
          summ_result: $.content.result
 +
 
 +
  Ssh:
 +
    class: std.ssh
 +
    base-parameters:
 +
      host: $.vm_ip
 +
      username: $.username
 +
      password: $.password
 +
    actions:
 +
      # Simple SSH command.
 +
      waitSSH:
 +
        base-parameters:
 +
          cmd: 'ls -l'
 +
 
 +
      # SSH command to run the server.
 +
      runServer:
 +
        base-parameters:
 +
          cmd: 'nohup python ~/web_app.py > web_app.log &'
 +
 
 +
Workflow:
 
   tasks:
 
   tasks:
     runJob:
+
     # Create a VM (request to Nova).
      requires:
+
     createVM:
        createVM: $.vm_ip != null
+
       action: Nova.createVM
      action: DemoApp:runJob
 
      on-success: deleteVM
 
      on-error: sendJobError
 
 
 
     deleteVM:
 
       action: Nova:deleteVM
 
      on-finish: end
 
 
 
    sendJobError:
 
      action: std:email
 
 
       parameters:
 
       parameters:
         address: admin@mycompany.com
+
         server_name: $.server_name
         subject: Workflow error
+
         image_id: $.image_id
         body: Error occurred while running a VM job in execution {$.execution.id}
+
         flavor_id: $.flavor_id
      on-finish: deleteVM
+
        nova_url: $.nova_url
 
+
        project_id: $.project_id
  # Creating a VM and waiting till it is up (an IP address has been assigned).
+
        auth_token: $.auth_token
 
+
       publish:
    createVM:
+
        vm_id: vm_id
       action: Nova:createVM
 
 
       on-success: waitForIP
 
       on-success: waitForIP
 
       on-error: sendCreateVMError
 
       on-error: sendCreateVMError
 
+
 
 +
    # Wait till the VM is assigned with IP address (request to Nova).
 
     waitForIP:
 
     waitForIP:
       action: std:repeat
+
       action: Nova.getIP
 +
      retry:
 +
        count: 10
 +
        delay: 10
 +
      publish:
 +
        vm_ip: vm_ip
 +
      parameters:
 +
        nova_url: $.nova_url
 +
        project_id: $.project_id
 +
        auth_token: $.auth_token
 +
        vm_id: $.vm_id
 +
      on-success: waitSSH
 +
      on-error: sendCreateVMError
 +
 
 +
    # Wait till operating system on the VM is up (SSH command).
 +
    waitSSH:
 +
      action: Ssh.waitSSH
 +
      retry:
 +
        count: 10
 +
        delay: 10
 +
      parameters:
 +
        username: $.ssh_username
 +
        password: $.ssh_password
 +
        vm_ip: $.vm_ip
 +
      on-success: runServer
 +
      on-error: sendCreateVMError
 +
 
 +
    # When SSH is up, we are able to run the server on VM (SSH command).
 +
    runServer:
 +
      action: Ssh.runServer
 +
      parameters:
 +
        vm_ip: $.vm_ip
 +
        username: $.ssh_username
 +
        password: $.ssh_password
 +
      on-success: calcSumm
 +
      on-error: sendCreateVMError
 +
 
 +
    # Send HTTP request on server and calc the result.
 +
    calcSumm:
 +
      action: Server.calcSumm
 +
      retry:
 +
        count: 10
 +
        delay: 1
 
       parameters:
 
       parameters:
         task: getIP
+
         arguments:
         retries: 5
+
          - 32
        delay: 3000
+
          - 45
         break-on: $.vm_ip != null
+
          - 23
       on-finish:
+
         vm_ip: $.vm_ip
         sendCreateVMError: $.vm_ip = null
+
      publish:
      on-error:
+
         result: summ_result
        sendCreateVMError
+
       on-finish: sendResultEmail
 
+
 
    getIP:
+
    # In case of createVM error send e-mail with error message.
       action: Nova:getIP
+
    sendResultEmail:
 
+
      action: std.email
 +
      parameters:
 +
         params:
 +
          to: [$.admin_email]
 +
          subject: Workflow result
 +
          body: |
 +
            Workflow result of execution {$.__execution.id} is {$.result}
 +
 
 +
            -- Thanks, Mistral Team.
 +
        settings:
 +
          smtp_server: $.smtp_server
 +
          from: $.from_email
 +
          password: $.smtp_password
 +
       on-finish: deleteVM
 +
 
 +
    # In case of createVM error send e-mail with error message.
 
     sendCreateVMError:
 
     sendCreateVMError:
       action: std:email
+
       action: std.email
 
       parameters:
 
       parameters:
         address: admin@mycompany.com
+
         params:
        subject: Workflow error
+
          to: [$.admin_email]
        body: Failed to create a VM in execution {$.execution.id}
+
          subject: Workflow error
      on-finish: end
+
          body: |
 
+
            Failed to create a VM in execution {$.__execution.id}
  # Terminal no-op task.
+
 
 
+
            -- Thanks, Mistral Team.
    end:
+
        settings:
      action: Util:no-op
+
          smtp_server: $.smtp_server
 
+
          from: $.from_email
  events:
+
          password: $.smtp_password
    runJob:
+
       on-finish: deleteVM
       type: periodic
+
 
      tasks: runJob
+
    # Destroy the VM (request to Nova).
      parameters:
+
     deleteVM:
        cron-pattern: "*/1 * * * *"
+
       action: Nova.deleteVM
 
 
  Services:
 
     Nova:
 
       type: REST_API
 
 
       parameters:
 
       parameters:
         baseUrl: {$.novaURL}
+
         nova_url: $.nova_url
      actions:
+
         project_id: $.project_id
         createVM:
+
        auth_token: $.auth_token
          parameters:
+
         vm_id: $.vm_id
            url: /servers/{$.vm_id}
 
            method: POST
 
          response:
 
            select: $.server.id
 
            store-as: vm_id
 
         getIP:
 
          parameters:
 
            url: /servers/{$.vm_id}
 
            method: GET
 
          response:
 
            select: $.server.accessIPv4
 
            store-as: vm_ip
 
        deleteVM:
 
          parameters:
 
            url: /servers/{$.vm_id}
 
            method: DELETE
 
 
 
  DemoAPP:
 
    type: MISTRAL_REST_API
 
    parameters:
 
      baseUrl: http://{$.vm_ip}:8080/
 
    actions:
 
      runJob:
 
        parameters:
 
          url: /runJob
 
          method: GET
 
  
 
==== Initial execution context ====
 
==== Initial execution context ====
 
   {
 
   {
     "novaURL": TBD,
+
     "nova_url": <nova_url>,
     "imageID": TBD
+
     "image_id": <image_id>,
 +
    "flavor_id": <flavor_id>,
 +
    "server_name": <server_name>,
 +
    "ssh_username": <ssh_username>,
 +
    "ssh_password": <ssh_password>,
 +
    "admin_email": <admin_email>,
 +
    "from_email": <from_email>,
 +
    "smtp_server": <smtp_server>,
 +
    "smtp_password": <smtp_password>,
 
   }
 
   }
  
Line 223: Line 329:
  
 
   {
 
   {
     "novaURL": TBD,
+
     "nova_url": TBD,
     "imageID": TBD,
+
     "image_id": TBD,
     "execution": {
+
     "image_id": <image_id>,
 +
    "flavor_id": <flavor_id>,
 +
    "server_name": <server_name>,
 +
    "ssh_username": <ssh_username>,
 +
    "ssh_password": <ssh_password>,
 +
    "admin_email": <admin_email>,
 +
    "from_email": <from_email>,
 +
    "smtp_server": <smtp_server>,
 +
    "smtp_password": <smtp_password>,
 +
    "__execution": {
 
       "id": "234234",
 
       "id": "234234",
 
       "workbook_name" : "my_workbook",
 
       "workbook_name" : "my_workbook",

Revision as of 11:01, 5 May 2014

Mistral DSL specification

Version 0.1

Main objects

  • Namespace
  • Action
  • Workflow
  • Task
  • Trigger

Namespaces

Provides some specific functionality. For example, Nova service provides functionality for VMs management in OpenStack.

Attributes

All attributes are inside main keys of Namespaces - namespaces names

  • class - currently we support the following classes: std.http, std.mistral_http, std.echo, std.email, std.ssh, this is an optional attribute
  • base-parameters - dictionary depending on type of the namespace, this parameter can be optional. Values of this parameters apply to all actions inside namespace. For example for std.http it can contain url, method, body and headers.
  • actions - list of actions provided by this namespace

YAML example:

 Namespaces:
    Nova:
      class: std.http
      parameters:
          method: GET
      actions:
          create-vm:
            ......
          delete-vm:  
            .....

Action

A function provided by specific Namespaces.

Attributes

  • name - string without space, mandatory attribute
  • base-parameters - dictionary, which structured is defined by action class (or namespace class if defined). For std.http class it contains url, method, body and headers.
  • parameters - list containing parameter names which should or could be specified in task
  • output - dictionary-transformer for action output to send this output next to task. Keys of this dictionary will be included in task result, values are YAQL-expression per key which mean how the specific output should be retrieved from raw output (from action)

YAML example:

 create-vm:
     base-parameters:
         url: servers
     parameters:
         - name
         - server_name  
     output:
       vm_id: $.content.server.id

Workflow

Attributes

  • tasks - list of task in this workflow, each task represent some step in worflow

YAML example:

 Workflow:
    tasks:
       create-vms:
         .....
       attache-volumes: 
         .....

Task

Represents a step in workflow, for example creating the VM

Attributes

  • action - name of action to perform
  • requires - list of tasks which should be execute before this tasks, or list of task names as a keys and condition as a value, this is optional parameter
  • parameters - actual parameters for the task, each value can be either some number, string etc, or YAQL expression to retrieve value from task context
  • on-success - task which will be scheduled on execution after current task has finished with state 'SUCCESS'
  • on-error - task which will be scheduled on execution after current task has finished with state 'ERROR'
  • on-finish - task which will be scheduled on execution after current task has finished

YAML example:

 create-vm:
    action: Nova.create-vm
    parameters:
     image_id: $.image_id
     flavor_id: 42
   requires:
     task2: '$.value2 = 123'
     task4: '$.value4 = 122'
   on-success: task3

Triggers

By trigger it is possible to invoke specific task and put it on schedule.

Attributes

  • type - can be PERIODIC, TIMER, CEILOMETER_ALARM
  • tasks - list of tasks which should be execute on trigger
  • parameters - list of parameters, defined by task

YAML example:

 backup-vm:
    type: periodic
    tasks: [create_backup, delete_old_backup] 
    parameters:
       time: 1 0 * * *

Full YAML example:

  1. This example requires the following properties provided in execution context:
  2. - nova_url ## url to Nova service, e.g. http://0.0.0.0:8774/v3
  3. - server_name ## Name you want to give to new instance
  4. - image_id ## image id from Glance service
  5. - flavor_id ## flavor id - type of instance hardware
  6. - ssh_username ## username of your VM
  7. - ssh_password ## password to your VM
  8. - admin_email ## email address to send notifications to
  9. - from_email ## email address to send notifications from
  10. - smtp_server ## SMTP server to use for sending emails (e.g. smtp.gmail.com:587)
  11. - smtp_password ## password to connect to SMTP server


Namespaces:
 Nova:
   # Nova actions for creating VM, retrieving IP and VM deleting.
   class: std.http
   actions:
     createVM:
       base-parameters:
         url: '{$.nova_url}/{$.project_id}/servers'
         method: POST
         headers:
           X-Auth-Token: $.auth_token
           Content-Type: application/json
         body:
           server:
             name: $.server_name
             imageRef: $.image_id
             flavorRef: $.flavor_id
       output:
         vm_id: $.content.server.id
     getIP:
       base-parameters:
         url: '{$.nova_url}/{$.project_id}/servers/{$.vm_id}'
         method: GET
         headers:
           X-Auth-Token: $.auth_token
       output:
         vm_ip: "$.content.server.addresses.novanetwork.where($.'OS-EXT-IPS:type' = 'floating')[0].addr"
     deleteVM:
       base-parameters:
         url: '{$.nova_url}/{$.project_id}/servers/{$.vm_id}'
         method: DELETE
         headers:
           X-Auth-Token: $.auth_token
       output:
         status: $.status
 Server:
   actions:
     # HTTP request to the server.
     calcSumm:
       class: std.http
       base-parameters:
         url: 'http://{$.vm_ip}:5000/summ'
         method: POST
         body:
           arguments: $.arguments
       output:
         summ_result: $.content.result
 Ssh:
   class: std.ssh
   base-parameters:
     host: $.vm_ip
     username: $.username
     password: $.password
   actions:
     # Simple SSH command.
     waitSSH:
       base-parameters:
         cmd: 'ls -l'
     # SSH command to run the server.
     runServer:
       base-parameters:
         cmd: 'nohup python ~/web_app.py > web_app.log &'
Workflow:
 tasks:
   # Create a VM (request to Nova).
   createVM:
     action: Nova.createVM
     parameters:
       server_name: $.server_name
       image_id: $.image_id
       flavor_id: $.flavor_id
       nova_url: $.nova_url
       project_id: $.project_id
       auth_token: $.auth_token
     publish:
       vm_id: vm_id
     on-success: waitForIP
     on-error: sendCreateVMError
   # Wait till the VM is assigned with IP address (request to Nova).
   waitForIP:
     action: Nova.getIP
     retry:
       count: 10
       delay: 10
     publish:
       vm_ip: vm_ip
     parameters:
       nova_url: $.nova_url
       project_id: $.project_id
       auth_token: $.auth_token
       vm_id: $.vm_id
     on-success: waitSSH
     on-error: sendCreateVMError
   # Wait till operating system on the VM is up (SSH command).
   waitSSH:
     action: Ssh.waitSSH
     retry:
       count: 10
       delay: 10
     parameters:
       username: $.ssh_username
       password: $.ssh_password
       vm_ip: $.vm_ip
     on-success: runServer
     on-error: sendCreateVMError
   # When SSH is up, we are able to run the server on VM (SSH command).
   runServer:
     action: Ssh.runServer
     parameters:
       vm_ip: $.vm_ip
       username: $.ssh_username
       password: $.ssh_password
     on-success: calcSumm
     on-error: sendCreateVMError
   # Send HTTP request on server and calc the result.
   calcSumm:
     action: Server.calcSumm
     retry:
       count: 10
       delay: 1
     parameters:
       arguments:
         - 32
         - 45
         - 23
       vm_ip: $.vm_ip
     publish:
       result: summ_result
     on-finish: sendResultEmail
   # In case of createVM error send e-mail with error message.
   sendResultEmail:
     action: std.email
     parameters:
       params:
         to: [$.admin_email]
         subject: Workflow result
         body: |
           Workflow result of execution {$.__execution.id} is {$.result}
           -- Thanks, Mistral Team.
       settings:
         smtp_server: $.smtp_server
         from: $.from_email
         password: $.smtp_password
     on-finish: deleteVM
   # In case of createVM error send e-mail with error message.
   sendCreateVMError:
     action: std.email
     parameters:
       params:
         to: [$.admin_email]
         subject: Workflow error
         body: |
           Failed to create a VM in execution {$.__execution.id}
           -- Thanks, Mistral Team.
       settings:
         smtp_server: $.smtp_server
         from: $.from_email
         password: $.smtp_password
     on-finish: deleteVM
   # Destroy the VM (request to Nova).
   deleteVM:
     action: Nova.deleteVM
     parameters:
       nova_url: $.nova_url
       project_id: $.project_id
       auth_token: $.auth_token
       vm_id: $.vm_id

Initial execution context

 {
   "nova_url": <nova_url>,
   "image_id": <image_id>,
   "flavor_id": <flavor_id>,
   "server_name": <server_name>,
   "ssh_username": <ssh_username>,
   "ssh_password": <ssh_password>,
   "admin_email": <admin_email>,
   "from_email": <from_email>,
   "smtp_server": <smtp_server>,
   "smtp_password": <smtp_password>,
 }

When a workflow starts Mistral also adds execution information into the context so the context looks like the following:

 {
   "nova_url": TBD,
   "image_id": TBD,
   "image_id": <image_id>,
   "flavor_id": <flavor_id>,
   "server_name": <server_name>,
   "ssh_username": <ssh_username>,
   "ssh_password": <ssh_password>,
   "admin_email": <admin_email>,
   "from_email": <from_email>,
   "smtp_server": <smtp_server>,
   "smtp_password": <smtp_password>,
   "__execution": {
     "id": "234234",
     "workbook_name" : "my_workbook",
     "project_id": "ghfgsdfasdfasdf"
     "auth_token": "sdfljsdfsdf-234234234",
     "trust_id": "oiretoilkjsdfglkjsdfglkjsdfg"
   }
 }