Removing left v1 related stuff (resources, DSL specs)
Change-Id: Ie85296368e326cfad1da1dfb99e84e24107051e2
This commit is contained in:
parent
f74541085d
commit
3544888543
@ -21,7 +21,6 @@ from mistral.actions import action_factory
|
||||
from mistral.actions import generator_factory
|
||||
from mistral.db.v2 import api as db_api
|
||||
from mistral import exceptions as exc
|
||||
from mistral import expressions as expr
|
||||
from mistral.openstack.common import log as logging
|
||||
from mistral.services import actions
|
||||
from mistral import utils
|
||||
@ -168,42 +167,3 @@ def _has_argument(action, attributes, argument_name):
|
||||
|
||||
def has_action_context(action, attributes):
|
||||
return _has_argument(action, attributes, _ACTION_CTX_PARAM)
|
||||
|
||||
|
||||
def resolve_adhoc_action_name(workbook, action_name):
|
||||
action_spec = workbook.get_action(action_name)
|
||||
|
||||
if not action_spec:
|
||||
msg = ('Ad-hoc action class is not registered '
|
||||
'[workbook=%s, action=%s, action_spec=%s]' %
|
||||
(workbook, action_name, action_spec))
|
||||
raise exc.ActionException(msg)
|
||||
|
||||
base_cls = get_action_class(action_spec.clazz)
|
||||
|
||||
if not base_cls:
|
||||
msg = ('Ad-hoc action base class is not registered '
|
||||
'[workbook=%s, action=%s, base_class=%s]' %
|
||||
(workbook, action_name, base_cls))
|
||||
raise exc.ActionException(msg)
|
||||
|
||||
return action_spec.clazz
|
||||
|
||||
|
||||
def convert_adhoc_action_params(workbook, action_name, params):
|
||||
base_params = workbook.get_action(action_name).base_parameters
|
||||
|
||||
if not base_params:
|
||||
return {}
|
||||
|
||||
return expr.evaluate_recursively(base_params, params)
|
||||
|
||||
|
||||
def convert_adhoc_action_result(workbook, action_name, result):
|
||||
transformer = workbook.get_action(action_name).output
|
||||
|
||||
if not transformer:
|
||||
return result
|
||||
|
||||
# Use base action result as a context for evaluating expressions.
|
||||
return expr.evaluate_recursively(transformer, result)
|
||||
|
@ -1,53 +0,0 @@
|
||||
Namespaces:
|
||||
MyRest:
|
||||
class: std.mistral_http
|
||||
base-parameters:
|
||||
method: GET
|
||||
headers:
|
||||
X-Auth-Token: <% $.auth_token %>
|
||||
|
||||
actions:
|
||||
async-action:
|
||||
base-parameters:
|
||||
url: http://some_host/service/action/execute
|
||||
headers:
|
||||
Content-Type: 'application/json'
|
||||
parameters:
|
||||
- input1
|
||||
- input2
|
||||
output:
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
start-task:
|
||||
action: MyRest.async-action
|
||||
parameters:
|
||||
input1: foo
|
||||
input2: bar
|
||||
on-success:
|
||||
task-one
|
||||
on-error:
|
||||
- task-three
|
||||
- task-four
|
||||
on-finish:
|
||||
task-two
|
||||
|
||||
task-one:
|
||||
action: MyRest.async-action
|
||||
on-success: task-two
|
||||
|
||||
task-two:
|
||||
action: MyRest.async-action
|
||||
|
||||
task-three:
|
||||
action: MyRest.async-action
|
||||
|
||||
task-four:
|
||||
action: MyRest.async-action
|
||||
|
||||
Triggers:
|
||||
my-cron:
|
||||
type: periodic
|
||||
tasks: start-task
|
||||
parameters:
|
||||
cron-pattern: "* * * * *"
|
@ -1,7 +0,0 @@
|
||||
Workflow:
|
||||
tasks:
|
||||
task1:
|
||||
action: std.http
|
||||
parameters:
|
||||
method: GET
|
||||
url: http://some_url
|
@ -1,26 +0,0 @@
|
||||
Namespaces:
|
||||
MyRest:
|
||||
class: std.mistral_http
|
||||
base-parameters:
|
||||
method: GET
|
||||
headers:
|
||||
X-Auth-Token: <% $.auth_token %>
|
||||
|
||||
actions:
|
||||
create-vm:
|
||||
base-parameters:
|
||||
url: http://some_host/service/action/execute
|
||||
headers:
|
||||
Content-Type: 'application/json'
|
||||
parameters:
|
||||
- image_id
|
||||
- flavor_id
|
||||
output:
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
create-vms:
|
||||
action: MyRest.create-vm
|
||||
parameters:
|
||||
image_id: 1234
|
||||
flavor_id: 42
|
@ -1,17 +0,0 @@
|
||||
Namespaces:
|
||||
Nova:
|
||||
actions:
|
||||
create-vm:
|
||||
class: std.http
|
||||
base-parameters:
|
||||
url: http://path_to_nova/url_for_create
|
||||
output:
|
||||
vm_id: <% $.base_output.server_id %>
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
std_http_task:
|
||||
action: std.http
|
||||
parameters:
|
||||
method: GET
|
||||
url: http://some_url
|
@ -1,20 +0,0 @@
|
||||
Namespaces:
|
||||
MyActions:
|
||||
actions:
|
||||
concat:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: '<% $.left %> <% $.right %>'
|
||||
parameters:
|
||||
- left
|
||||
- right
|
||||
output:
|
||||
string: <% $.output %>
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
build_name:
|
||||
action: MyActions.concat
|
||||
parameters:
|
||||
left: Stormin
|
||||
right: Stanley
|
@ -1,34 +0,0 @@
|
||||
Namespaces:
|
||||
MyActions:
|
||||
actions:
|
||||
concat:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: '<% $.left %> <% $.right %>'
|
||||
parameters:
|
||||
- left
|
||||
- right
|
||||
output:
|
||||
string: <% $.output %>
|
||||
start:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: 'Starting...'
|
||||
output:
|
||||
info: <% $.output %>
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
startup:
|
||||
action: MyActions.start
|
||||
build_name:
|
||||
action: MyActions.concat
|
||||
parameters:
|
||||
left: Stormin
|
||||
right: Stanley
|
||||
greet:
|
||||
requires: [startup, build_name]
|
||||
action: MyActions.concat
|
||||
parameters:
|
||||
left: Greetings
|
||||
right: <% $.string %>
|
@ -1,62 +0,0 @@
|
||||
Namespaces:
|
||||
MyService:
|
||||
# These ad-hoc actions based on std.echo have parameters only for test
|
||||
# purposes. In practice, it's more convenient just to use std.echo and
|
||||
# specify parameter 'output'.
|
||||
actions:
|
||||
concat:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: '<% $.left %> <% $.right %>'
|
||||
parameters:
|
||||
- left
|
||||
- right
|
||||
output:
|
||||
string: <% $ %>
|
||||
|
||||
Workflow:
|
||||
# context = {
|
||||
# 'person': {
|
||||
# 'first_name': 'John',
|
||||
# 'last_name': 'Doe',
|
||||
# 'address': {
|
||||
# 'street': '124352 Broadway Street',
|
||||
# 'city': 'Gloomington',
|
||||
# 'country': 'USA'
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
|
||||
tasks:
|
||||
build_full_name:
|
||||
action: MyService.concat
|
||||
parameters:
|
||||
left: <% $.person.first_name %>
|
||||
right: <% $.person.last_name %>
|
||||
publish:
|
||||
full_name: <% $.string %>
|
||||
|
||||
build_greeting:
|
||||
requires: [build_full_name]
|
||||
action: MyService.concat
|
||||
parameters:
|
||||
left: Dear
|
||||
right: <% $.full_name %>
|
||||
publish:
|
||||
greeting: <% $.string %>
|
||||
|
||||
build_address:
|
||||
requires: [build_full_name]
|
||||
action: MyService.concat
|
||||
parameters:
|
||||
left: To
|
||||
right: <% $.full_name %>
|
||||
publish:
|
||||
address: <% $.string %>
|
||||
|
||||
send_greeting:
|
||||
requires: [build_address, build_greeting]
|
||||
action: MyService.concat
|
||||
parameters:
|
||||
left: '<% $.address %>.'
|
||||
right: '<% $.greeting %>,..'
|
@ -1,67 +0,0 @@
|
||||
Namespaces:
|
||||
MyService:
|
||||
# These ad-hoc actions based on std.echo have parameters only for test
|
||||
# purposes. In practice, it's more convenient just to use std.echo and
|
||||
# specify parameter 'output'.
|
||||
actions:
|
||||
build_full_name:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: '<% $.first_name %> <% $.last_name %>'
|
||||
parameters:
|
||||
- first_name
|
||||
- last_name
|
||||
output:
|
||||
full_name: <% $ %>
|
||||
|
||||
build_greeting:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: Cheers!
|
||||
output:
|
||||
greeting: <% $ %>
|
||||
|
||||
send_greeting:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: True
|
||||
parameters:
|
||||
- f_name
|
||||
- greet_msg
|
||||
output:
|
||||
greeting_sent: <% $ %>
|
||||
|
||||
Workflow:
|
||||
# context = {
|
||||
# 'person': {
|
||||
# 'first_name': 'John',
|
||||
# 'last_name': 'Doe',
|
||||
# 'address': {
|
||||
# 'street': '124352 Broadway Street',
|
||||
# 'city': 'Gloomington',
|
||||
# 'country': 'USA'
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
|
||||
tasks:
|
||||
build_full_name:
|
||||
action: MyService.build_full_name
|
||||
parameters:
|
||||
first_name: <% $.person.first_name %>
|
||||
last_name: <% $.person.last_name %>
|
||||
publish:
|
||||
f_name: <% $.full_name %>
|
||||
|
||||
build_greeting:
|
||||
requires: [build_full_name]
|
||||
action: MyService.build_greeting
|
||||
publish:
|
||||
greet_msg: <% $.greeting %>
|
||||
|
||||
send_greeting:
|
||||
requires: [build_full_name, build_greeting]
|
||||
action: MyService.send_greeting
|
||||
parameters:
|
||||
f_name: <% $.f_name %>
|
||||
greet_msg: <% $.greet_msg %>
|
@ -1,72 +0,0 @@
|
||||
Namespaces:
|
||||
MyService:
|
||||
# These ad-hoc actions based on std.echo have parameters only for test
|
||||
# purposes. In practice, it's more convenient just to use std.echo and
|
||||
# specify parameter 'output'.
|
||||
actions:
|
||||
build_full_name:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: '<% $.first_name %> <% $.last_name %>'
|
||||
parameters:
|
||||
- first_name
|
||||
- last_name
|
||||
output:
|
||||
full_name: <% $ %>
|
||||
|
||||
build_greeting:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: 'Hello, <% $.full_name %>!'
|
||||
parameters:
|
||||
- full_name
|
||||
output:
|
||||
greeting: <% $ %>
|
||||
|
||||
send_greeting:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: True
|
||||
parameters:
|
||||
- greeting
|
||||
output:
|
||||
greeting_sent: <% $ %>
|
||||
|
||||
|
||||
Workflow:
|
||||
# context = {
|
||||
# 'person': {
|
||||
# 'first_name': 'John',
|
||||
# 'last_name': 'Doe',
|
||||
# 'address': {
|
||||
# 'street': '124352 Broadway Street',
|
||||
# 'city': 'Gloomington',
|
||||
# 'country': 'USA'
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
|
||||
tasks:
|
||||
build_full_name:
|
||||
action: MyService.build_full_name
|
||||
parameters:
|
||||
first_name: <% $.person.first_name %>
|
||||
last_name: <% $.person.last_name %>
|
||||
publish:
|
||||
f_name: <% $.full_name %>
|
||||
on-success: build_greeting
|
||||
|
||||
build_greeting:
|
||||
action: MyService.build_greeting
|
||||
parameters:
|
||||
full_name: <% $.f_name %>
|
||||
publish:
|
||||
greet_msg: <% $.greeting %>
|
||||
on-success: send_greeting
|
||||
|
||||
send_greeting:
|
||||
action: MyService.send_greeting
|
||||
parameters:
|
||||
greeting: <% $.task.build_greeting.greeting %>
|
||||
publish:
|
||||
sent: <% $.greeting_sent %>
|
@ -1,53 +0,0 @@
|
||||
Namespaces:
|
||||
MyService:
|
||||
actions:
|
||||
# These ad-hoc actions based on std.echo have parameters only for test
|
||||
# purposes. In practice, it's more convenient just to use std.echo and
|
||||
# specify parameter 'output'.
|
||||
build_full_name:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: '<% $.first_name %> <% $.last_name %>'
|
||||
parameters:
|
||||
- first_name
|
||||
- last_name
|
||||
output:
|
||||
full_name: <% $ %>
|
||||
|
||||
build_greeting:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: 'Hello, <% $.full_name %>!'
|
||||
parameters:
|
||||
- full_name
|
||||
output:
|
||||
greeting: <% $ %>
|
||||
|
||||
|
||||
Workflow:
|
||||
# context = {
|
||||
# 'person': {
|
||||
# 'first_name': 'John',
|
||||
# 'last_name': 'Doe',
|
||||
# 'address': {
|
||||
# 'street': '124352 Broadway Street',
|
||||
# 'city': 'Gloomington',
|
||||
# 'country': 'USA'
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
|
||||
tasks:
|
||||
build_full_name:
|
||||
action: MyService.build_full_name
|
||||
parameters:
|
||||
first_name: <% $.person.first_name %>
|
||||
last_name: <% $.person.last_name %>
|
||||
publish:
|
||||
f_name: <% $.full_name %>
|
||||
|
||||
build_greeting:
|
||||
requires: [build_full_name]
|
||||
action: MyService.build_greeting
|
||||
parameters:
|
||||
full_name: <% $.f_name %>
|
@ -1,56 +0,0 @@
|
||||
Namespaces:
|
||||
MyService:
|
||||
# These ad-hoc actions based on std.echo have parameters only for test
|
||||
# purposes. In practice, it's more convenient just to use std.echo and
|
||||
# specify parameter 'output'.
|
||||
actions:
|
||||
build_full_name:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: '<% $.first_name %> <% $.last_name %>'
|
||||
parameters:
|
||||
- first_name
|
||||
- last_name
|
||||
output:
|
||||
full_name: <% $ %>
|
||||
|
||||
build_greeting:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: 'Hello, <% $.full_name %>!'
|
||||
parameters:
|
||||
- full_name
|
||||
output:
|
||||
greeting:
|
||||
greet_message: <% $ %>
|
||||
|
||||
|
||||
Workflow:
|
||||
# context = {
|
||||
# 'person': {
|
||||
# 'first_name': 'John',
|
||||
# 'last_name': 'Doe',
|
||||
# 'address': {
|
||||
# 'street': '124352 Broadway Street',
|
||||
# 'city': 'Gloomington',
|
||||
# 'country': 'USA'
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
|
||||
tasks:
|
||||
build_full_name:
|
||||
action: MyService.build_full_name
|
||||
parameters:
|
||||
first_name: <% $.person.first_name %>
|
||||
last_name: <% $.person.last_name %>
|
||||
publish:
|
||||
f_name: <% $.full_name %>
|
||||
on-success: build_greeting
|
||||
|
||||
build_greeting:
|
||||
action: MyService.build_greeting
|
||||
parameters:
|
||||
full_name: <% $.f_name %>
|
||||
publish:
|
||||
greet_msg: <% $.greeting %>
|
@ -1,4 +0,0 @@
|
||||
Workflow:
|
||||
tasks:
|
||||
glance_image_list:
|
||||
action: glance.images_list
|
@ -1,15 +0,0 @@
|
||||
Workflow:
|
||||
tasks:
|
||||
image_list:
|
||||
action: glance.images_list
|
||||
publish:
|
||||
image_id: <% $[0].id %>
|
||||
on-success: image_get
|
||||
|
||||
image_get:
|
||||
action: glance.images_get
|
||||
parameters:
|
||||
image_id: <% $.image_id %>
|
||||
publish:
|
||||
image_id: <% $.id %>
|
||||
image_name: <% $.name %>
|
@ -1,4 +0,0 @@
|
||||
Workflow:
|
||||
tasks:
|
||||
heat_stack_list:
|
||||
action: heat.stacks_list
|
@ -1,4 +0,0 @@
|
||||
Workflow:
|
||||
tasks:
|
||||
keystone_user_list:
|
||||
action: keystone.users_list
|
@ -1,6 +0,0 @@
|
||||
Workflow:
|
||||
tasks:
|
||||
get_some_endpoint:
|
||||
action: keystone.service_catalog_get_data
|
||||
publish:
|
||||
endpoint_url: <% $[0].endpoints[0].url %>
|
@ -1,7 +0,0 @@
|
||||
Workflow:
|
||||
tasks:
|
||||
nova_server_findall:
|
||||
action: nova.servers_findall
|
||||
parameters:
|
||||
status: ACTIVE
|
||||
tenant_id: 8e44eb2ce32
|
@ -1,31 +0,0 @@
|
||||
Workflow:
|
||||
tasks:
|
||||
server_create:
|
||||
action: nova.servers_create
|
||||
parameters:
|
||||
name: <% $.server_name %>
|
||||
image: <% $.image_ref %>
|
||||
flavor: <% $.flavor_ref %>
|
||||
publish:
|
||||
server_id: <% $.id %>
|
||||
on-success: check_server_exists
|
||||
|
||||
check_server_exists:
|
||||
action: nova.servers_get
|
||||
parameters:
|
||||
server: <% $.server_id %>
|
||||
publish:
|
||||
server_exists: True
|
||||
on-success:
|
||||
wait_instance
|
||||
|
||||
wait_instance:
|
||||
action: nova.servers_find
|
||||
retry:
|
||||
delay: 5
|
||||
count: 15
|
||||
parameters:
|
||||
id: <% $.server_id %>
|
||||
status: 'ACTIVE'
|
||||
publish:
|
||||
instance_id: <% $.id %>
|
@ -1,4 +0,0 @@
|
||||
Workflow:
|
||||
tasks:
|
||||
neutron_list_networks:
|
||||
action: neutron.list_networks
|
@ -1,20 +0,0 @@
|
||||
Namespaces:
|
||||
MyService:
|
||||
actions:
|
||||
some-action:
|
||||
class: std.mistral_http
|
||||
base-parameters:
|
||||
url: http://path_to_service/action_url
|
||||
method: GET
|
||||
output:
|
||||
output: <% $ %>
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
delay_retry_task:
|
||||
action: MyService.some-action
|
||||
retry:
|
||||
count: 2
|
||||
delay: 0.1
|
||||
publish:
|
||||
rt_output: output
|
@ -1,19 +0,0 @@
|
||||
Namespaces:
|
||||
MyService:
|
||||
actions:
|
||||
some-action:
|
||||
class: std.mistral_http
|
||||
base-parameters:
|
||||
url: http://path_to_service/action_url
|
||||
method: GET
|
||||
output:
|
||||
output: <% $ %>
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
retry_task:
|
||||
action: MyService.some-action
|
||||
retry:
|
||||
count: 5
|
||||
publish:
|
||||
rt_output: <% $.output %>
|
@ -1,18 +0,0 @@
|
||||
Namespaces:
|
||||
MyService:
|
||||
actions:
|
||||
sync-action:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: Cheers!
|
||||
output:
|
||||
greeting: <% $ %>
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
sync-task:
|
||||
action: MyService.sync-action
|
||||
retry:
|
||||
count: 5
|
||||
publish:
|
||||
st_output: <% $.greeting %>
|
@ -1,26 +0,0 @@
|
||||
Namespaces:
|
||||
MyService:
|
||||
actions:
|
||||
some-action:
|
||||
class: std.mistral_http
|
||||
base-parameters:
|
||||
url: http://path_to_service/action_url
|
||||
method: GET
|
||||
output:
|
||||
output: <% $ %>
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
no_retry_task:
|
||||
action: MyService.some-action
|
||||
publish:
|
||||
n_rt_output: <% $.output %>
|
||||
on-success: delay_retry_task
|
||||
|
||||
delay_retry_task:
|
||||
action: MyService.some-action
|
||||
retry:
|
||||
count: 2
|
||||
delay: 0.1
|
||||
publish:
|
||||
rt_output: output
|
@ -1,63 +0,0 @@
|
||||
Namespaces:
|
||||
Nova:
|
||||
class: std.mistral_http
|
||||
base-parameters:
|
||||
method: GET
|
||||
headers:
|
||||
X-Auth-Token: <% $.auth_token %>
|
||||
|
||||
actions:
|
||||
create-vm:
|
||||
base-parameters:
|
||||
url: http://some_host/service/action/execute
|
||||
headers:
|
||||
Content-Type: 'application/json'
|
||||
parameters:
|
||||
- image_id
|
||||
- flavor_id
|
||||
|
||||
Echo:
|
||||
actions:
|
||||
concat:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: '<% $.left %> <% $.right %>'
|
||||
parameters:
|
||||
- left
|
||||
- right
|
||||
output:
|
||||
string: <% $ %>
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
task1:
|
||||
action: Nova.create-vm
|
||||
parameters:
|
||||
image_id: 1234
|
||||
flavor_id: 42
|
||||
on-error: task2
|
||||
|
||||
task2:
|
||||
action: Echo.concat
|
||||
parameters:
|
||||
left: workflow
|
||||
right: is
|
||||
publish:
|
||||
result2: <% $.string %>
|
||||
on-finish: task3
|
||||
|
||||
task3:
|
||||
action: Nova.create-vm
|
||||
parameters:
|
||||
image_id: 1234
|
||||
flavor_id: 42
|
||||
on-finish: task4
|
||||
|
||||
task4:
|
||||
action: Echo.concat
|
||||
parameters:
|
||||
left: <% $.result2 %>
|
||||
right: complete!
|
||||
publish:
|
||||
result4: <% $.string %>
|
||||
|
@ -1,40 +0,0 @@
|
||||
Namespaces:
|
||||
MyService:
|
||||
actions:
|
||||
concat:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: '<% $.left %> <% $.right %>'
|
||||
parameters:
|
||||
- left
|
||||
- right
|
||||
output:
|
||||
string: <% $ %>
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
task1:
|
||||
action: MyService.concat
|
||||
parameters:
|
||||
left: workflow
|
||||
right: is
|
||||
publish:
|
||||
result1: <% $.string %>
|
||||
|
||||
task2:
|
||||
requires: [task1]
|
||||
action: MyService.concat
|
||||
parameters:
|
||||
left: <% $.result1 %>
|
||||
right: complete
|
||||
publish:
|
||||
result2: <% $.string %>
|
||||
on-success: task3
|
||||
|
||||
task3:
|
||||
action: MyService.concat
|
||||
parameters:
|
||||
left: <% $.result2 %>
|
||||
right: '!'
|
||||
publish:
|
||||
result3: <% $.string %>
|
@ -1,29 +0,0 @@
|
||||
Workflow:
|
||||
tasks:
|
||||
task:
|
||||
requires: [atask, pretask]
|
||||
action: std.echo
|
||||
parameters:
|
||||
output: some
|
||||
btask:
|
||||
requires: [ztask]
|
||||
action: std.echo
|
||||
parameters:
|
||||
output: some
|
||||
ztask:
|
||||
action: std.echo
|
||||
parameters:
|
||||
output: some
|
||||
atask:
|
||||
action: std.echo
|
||||
parameters:
|
||||
output: some
|
||||
ctask:
|
||||
action: std.echo
|
||||
parameters:
|
||||
output: some
|
||||
pretask:
|
||||
requires: [btask, ztask]
|
||||
action: std.echo
|
||||
parameters:
|
||||
output: some
|
@ -1,101 +0,0 @@
|
||||
Namespaces:
|
||||
MyRest:
|
||||
class: std.mistral_http
|
||||
base-parameters:
|
||||
method: GET
|
||||
headers:
|
||||
X-Auth-Token: $.auth_token
|
||||
|
||||
actions:
|
||||
create-vm:
|
||||
base-parameters:
|
||||
url: http://some_host/service/action/execute
|
||||
headers:
|
||||
Content-Type: 'application/json'
|
||||
parameters:
|
||||
- image_id
|
||||
- flavor_id
|
||||
output:
|
||||
|
||||
backup-vm:
|
||||
base-parameters:
|
||||
url: http://some_host/url_for_backup
|
||||
parameters:
|
||||
- server_id
|
||||
|
||||
attach-volume:
|
||||
base-parameters:
|
||||
url: /url_for_attach
|
||||
parameters:
|
||||
- size
|
||||
- mnt_path
|
||||
|
||||
format-volume:
|
||||
base-parameters:
|
||||
url: /url_for_format
|
||||
parameters:
|
||||
- server_id
|
||||
|
||||
Nova:
|
||||
actions:
|
||||
create-vm:
|
||||
class: std.http
|
||||
base-parameters:
|
||||
url: http://path_to_nova/url_for_create
|
||||
parameters:
|
||||
- image_id
|
||||
- flavor_id
|
||||
output:
|
||||
vm_id: $.base_output.server_id
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
create-vms:
|
||||
action: MyRest.create-vm
|
||||
parameters:
|
||||
image_id: 1234
|
||||
flavor_id: 42
|
||||
|
||||
attach-volumes:
|
||||
requires: [create-vms]
|
||||
action: MyRest.attach-volume
|
||||
parameters:
|
||||
size:
|
||||
mnt_path:
|
||||
|
||||
format-volumes:
|
||||
requires: [attach-volumes]
|
||||
action: MyRest.format-volume
|
||||
parameters:
|
||||
server_id:
|
||||
|
||||
backup-vms:
|
||||
requires: [create-vms]
|
||||
action: MyRest.backup-vm
|
||||
parameters:
|
||||
server_id:
|
||||
|
||||
create-vm-nova:
|
||||
action: Nova.create-vm
|
||||
parameters:
|
||||
image_id: 1234
|
||||
flavor_id: 2
|
||||
|
||||
test_subsequent:
|
||||
action: MyRest.backup-vm
|
||||
parameters:
|
||||
server_id: 1
|
||||
on-success:
|
||||
attach-volumes
|
||||
on-error:
|
||||
- backup-vms: $.status != 'OK'
|
||||
- attach-volumes
|
||||
on-finish:
|
||||
create-vms
|
||||
|
||||
Triggers:
|
||||
create-vms:
|
||||
type: periodic
|
||||
tasks: create-vms
|
||||
parameters:
|
||||
cron-pattern: "* * * * *"
|
@ -4,8 +4,9 @@ Namespaces:
|
||||
hello:
|
||||
class: std.echo
|
||||
base-parameters:
|
||||
output: Hello!
|
||||
output: Hello!
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
hello:
|
||||
action: Greetings.hello
|
||||
action: Greetings.hello
|
@ -1,154 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2014 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from mistral.actions import std_actions as std
|
||||
from mistral.openstack.common import log as logging
|
||||
from mistral.services import action_manager as a_m
|
||||
from mistral.tests import base
|
||||
from mistral.workbook import parser as spec_parser
|
||||
|
||||
# TODO(rakhmerov): Deprecated. Remove it once engine v1 is gone.
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
DB_TASK = {
|
||||
'task_spec': {
|
||||
'name': 'my_task',
|
||||
'action': 'std.http'
|
||||
},
|
||||
'name': 'my_task',
|
||||
'workbook_name': 'my_workbook',
|
||||
'execution_id': '123',
|
||||
'id': '123',
|
||||
'in_context': {},
|
||||
'tags': ['deployment', 'test'],
|
||||
'parameters': {
|
||||
'url': 'http://some.url',
|
||||
'params': {
|
||||
'param1': 'val1',
|
||||
'param2': 'val2'
|
||||
},
|
||||
'method': 'POST',
|
||||
'headers': {
|
||||
'content-type': 'text/json'
|
||||
},
|
||||
'body': {
|
||||
'my_object': {
|
||||
'prop1': 'val1',
|
||||
'prop2': 'val2'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DB_TASK_ADHOC = {
|
||||
'task_spec': {
|
||||
'name': 'my_task',
|
||||
'action': 'my_namespace.my_action'
|
||||
},
|
||||
'action_spec': {
|
||||
'name': 'my_action',
|
||||
'namespace': 'my_namespace',
|
||||
'class': 'std.echo',
|
||||
'base-parameters': {
|
||||
'output': '<% $.first %> and <% $.second %>'
|
||||
},
|
||||
'parameters': ['first', 'second'],
|
||||
'output': {
|
||||
'res': '<% $ %>'
|
||||
}
|
||||
},
|
||||
'name': 'my_task',
|
||||
'workbook_name': 'my_workbook',
|
||||
'execution_id': '123',
|
||||
'id': '123',
|
||||
'in_context': {},
|
||||
'tags': ['deployment', 'test'],
|
||||
'parameters': {
|
||||
'first': 'Tango',
|
||||
'second': 'Cash'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ActionFactoryTest(base.DbTestCase):
|
||||
def test_register_standard_actions(self):
|
||||
action_list = a_m.get_registered_actions()
|
||||
|
||||
self._assert_single_item(action_list, name="std.echo")
|
||||
self._assert_single_item(action_list, name="std.email")
|
||||
self._assert_single_item(action_list, name="std.http")
|
||||
self._assert_single_item(action_list, name="std.mistral_http")
|
||||
self._assert_single_item(action_list, name="std.ssh")
|
||||
self._assert_single_item(action_list, name="std.javascript")
|
||||
|
||||
self._assert_single_item(action_list, name="nova.servers_get")
|
||||
self._assert_single_item(action_list, name="nova.volumes_delete")
|
||||
|
||||
self._assert_single_item(action_list, name="keystone.users_list")
|
||||
self._assert_single_item(action_list, name="keystone.trusts_create")
|
||||
|
||||
self._assert_single_item(action_list, name="glance.images_list")
|
||||
self._assert_single_item(action_list, name="glance.images_delete")
|
||||
|
||||
def test_get_action_class(self):
|
||||
self.assertEqual(std.EchoAction, a_m.get_action_class("std.echo"))
|
||||
self.assertEqual(std.HTTPAction, a_m.get_action_class("std.http"))
|
||||
self.assertEqual(std.MistralHTTPAction,
|
||||
a_m.get_action_class("std.mistral_http"))
|
||||
self.assertEqual(std.SendEmailAction,
|
||||
a_m.get_action_class("std.email"))
|
||||
self.assertEqual(std.JavaScriptAction,
|
||||
a_m.get_action_class("std.javascript"))
|
||||
|
||||
def test_resolve_adhoc_action_name(self):
|
||||
wb = spec_parser.get_workbook_spec_from_yaml(
|
||||
base.get_resource('control_flow/one_sync_task.yaml'))
|
||||
|
||||
action_name = 'MyActions.concat'
|
||||
|
||||
action = a_m.resolve_adhoc_action_name(wb, action_name)
|
||||
|
||||
self.assertEqual('std.echo', action)
|
||||
|
||||
def test_convert_adhoc_action_params(self):
|
||||
wb = spec_parser.get_workbook_spec_from_yaml(
|
||||
base.get_resource('control_flow/one_sync_task.yaml'))
|
||||
|
||||
action_name = 'MyActions.concat'
|
||||
params = {
|
||||
'left': 'Stormin',
|
||||
'right': 'Stanley'
|
||||
}
|
||||
|
||||
parameters = a_m.convert_adhoc_action_params(wb,
|
||||
action_name,
|
||||
params)
|
||||
|
||||
self.assertEqual({'output': 'Stormin Stanley'}, parameters)
|
||||
|
||||
def test_convert_adhoc_action_result(self):
|
||||
wb = spec_parser.get_workbook_spec_from_yaml(
|
||||
base.get_resource('control_flow/one_sync_task.yaml'))
|
||||
|
||||
action_name = 'MyActions.concat'
|
||||
result = {'output': 'Stormin Stanley'}
|
||||
|
||||
parameters = a_m.convert_adhoc_action_result(wb,
|
||||
action_name,
|
||||
result)
|
||||
|
||||
self.assertEqual({'string': 'Stormin Stanley'}, parameters)
|
60
mistral/tests/unit/actions/test_action_manager.py
Normal file
60
mistral/tests/unit/actions/test_action_manager.py
Normal file
@ -0,0 +1,60 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2014 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from mistral.actions import std_actions as std
|
||||
from mistral.openstack.common import log as logging
|
||||
from mistral.services import action_manager as a_m
|
||||
from mistral.tests import base
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ActionFactoryTest(base.DbTestCase):
|
||||
def test_register_standard_actions(self):
|
||||
action_list = a_m.get_registered_actions()
|
||||
|
||||
self._assert_single_item(action_list, name="std.echo")
|
||||
self._assert_single_item(action_list, name="std.email")
|
||||
self._assert_single_item(action_list, name="std.http")
|
||||
self._assert_single_item(action_list, name="std.mistral_http")
|
||||
self._assert_single_item(action_list, name="std.ssh")
|
||||
self._assert_single_item(action_list, name="std.javascript")
|
||||
|
||||
self._assert_single_item(action_list, name="nova.servers_get")
|
||||
self._assert_single_item(action_list, name="nova.volumes_delete")
|
||||
|
||||
self._assert_single_item(action_list, name="keystone.users_list")
|
||||
self._assert_single_item(action_list, name="keystone.trusts_create")
|
||||
|
||||
self._assert_single_item(action_list, name="glance.images_list")
|
||||
self._assert_single_item(action_list, name="glance.images_delete")
|
||||
|
||||
def test_get_action_class(self):
|
||||
self.assertEqual(std.EchoAction, a_m.get_action_class("std.echo"))
|
||||
self.assertEqual(std.HTTPAction, a_m.get_action_class("std.http"))
|
||||
self.assertEqual(
|
||||
std.MistralHTTPAction,
|
||||
a_m.get_action_class("std.mistral_http")
|
||||
)
|
||||
self.assertEqual(
|
||||
std.SendEmailAction,
|
||||
a_m.get_action_class("std.email")
|
||||
)
|
||||
self.assertEqual(
|
||||
std.JavaScriptAction,
|
||||
a_m.get_action_class("std.javascript")
|
||||
)
|
@ -54,7 +54,7 @@ workflows:
|
||||
|
||||
RESUME_WORKBOOK_REVERSE = """
|
||||
---
|
||||
version: 2.0
|
||||
version: '2.0'
|
||||
|
||||
name: resume_reverse
|
||||
|
||||
|
@ -1,112 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from mistral.tests import base
|
||||
from mistral.workbook import parser
|
||||
|
||||
|
||||
SIMPLE_WORKBOOK = """
|
||||
Workflow:
|
||||
tasks:
|
||||
create-vms:
|
||||
action: MyRest.create-vm
|
||||
"""
|
||||
|
||||
|
||||
class DSLv1ModelTest(base.BaseTest):
|
||||
def setUp(self):
|
||||
super(DSLv1ModelTest, self).setUp()
|
||||
|
||||
# TODO(rakhmerov): Need to have a dedicated resource.
|
||||
self.doc = base.get_resource("test_rest.yaml")
|
||||
|
||||
def test_load_dsl(self):
|
||||
wb = parser.get_workbook_spec_from_yaml(self.doc)
|
||||
|
||||
self.assertEqual(wb.workflow.tasks.items, wb.tasks.items)
|
||||
self.assertEqual(wb.tasks.get("create-vms").name, "create-vms")
|
||||
self.assertEqual(4, len(wb.namespaces.get("MyRest").actions))
|
||||
|
||||
def test_tasks(self):
|
||||
wb = parser.get_workbook_spec_from_yaml(self.doc)
|
||||
|
||||
self.assertEqual(len(wb.tasks), 6)
|
||||
|
||||
attach_volumes = wb.tasks.get("attach-volumes")
|
||||
|
||||
self.assertEqual(attach_volumes.get_action_namespace(), "MyRest")
|
||||
|
||||
t_parameters = {"image_id": 1234, "flavor_id": 2}
|
||||
create_vm_nova = wb.tasks.get("create-vm-nova")
|
||||
|
||||
self.assertEqual(create_vm_nova.parameters, t_parameters)
|
||||
|
||||
attach_requires = {"create-vms": ''}
|
||||
|
||||
self.assertEqual(attach_volumes.requires, attach_requires)
|
||||
|
||||
subsequent = wb.tasks.get("test_subsequent")
|
||||
|
||||
subseq_success = subsequent.get_on_success()
|
||||
subseq_error = subsequent.get_on_error()
|
||||
subseq_finish = subsequent.get_on_finish()
|
||||
|
||||
self.assertEqual(subseq_success, {"attach-volumes": ''})
|
||||
self.assertEqual(subseq_error, {"backup-vms": "$.status != 'OK'",
|
||||
"attach-volumes": ''})
|
||||
self.assertEqual(subseq_finish, {"create-vms": ''})
|
||||
|
||||
def test_actions(self):
|
||||
wb = parser.get_workbook_spec_from_yaml(self.doc)
|
||||
|
||||
actions = wb.namespaces.get("MyRest").actions
|
||||
|
||||
self.assertEqual(len(actions), 4)
|
||||
|
||||
create_vm = actions.get("create-vm")
|
||||
|
||||
base_params = create_vm.base_parameters
|
||||
|
||||
self.assertEqual('std.mistral_http', create_vm.clazz)
|
||||
self.assertIn('method', base_params)
|
||||
self.assertIn('headers', base_params)
|
||||
self.assertEqual('$.auth_token',
|
||||
base_params['headers']['X-Auth-Token'])
|
||||
self.assertEqual('application/json',
|
||||
base_params['headers']['Content-Type'])
|
||||
|
||||
action = wb.get_action("MyRest.create-vm")
|
||||
|
||||
self.assertIsNotNone(action)
|
||||
self.assertEqual("create-vm", action.name)
|
||||
self.assertEqual("MyRest", action.namespace)
|
||||
|
||||
def test_namespaces(self):
|
||||
wb = parser.get_workbook_spec_from_yaml(self.doc)
|
||||
|
||||
self.assertEqual(len(wb.namespaces), 2)
|
||||
|
||||
nova_namespace = wb.namespaces.get("Nova")
|
||||
|
||||
self.assertEqual(1, len(nova_namespace.actions))
|
||||
|
||||
def test_workbook_without_namespaces(self):
|
||||
parser.get_workbook_spec_from_yaml(SIMPLE_WORKBOOK)
|
||||
|
||||
def test_triggers(self):
|
||||
wb = parser.get_workbook_spec_from_yaml(self.doc)
|
||||
|
||||
self.assertEqual(len(wb.get_triggers()), 1)
|
@ -1,56 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2013 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# TODO(rakhmerov): Can we just extend dsl_specs_v1.py and remove this one?.
|
||||
|
||||
SAMPLE_TASK_SPEC = {
|
||||
'action': 'MyRest:create-vm',
|
||||
'name': 'create-vms',
|
||||
'on-success': ["format-volumes", {'task1': 'expression'}, {'task2': ''}],
|
||||
'on-finish': "attach-volumes",
|
||||
'on-error': ["task1", "task2"]
|
||||
}
|
||||
|
||||
from mistral.tests import base
|
||||
from mistral.workbook.v1 import tasks
|
||||
|
||||
|
||||
class GetOnStateTest(base.BaseTest):
|
||||
def setUp(self):
|
||||
super(GetOnStateTest, self).setUp()
|
||||
|
||||
self.task = tasks.TaskSpec(SAMPLE_TASK_SPEC)
|
||||
|
||||
def test_state_finish(self):
|
||||
on_finish = self.task.get_on_finish()
|
||||
|
||||
self.assertIsInstance(on_finish, dict)
|
||||
self.assertIn("attach-volumes", on_finish)
|
||||
|
||||
def test_state_error(self):
|
||||
on_error = self.task.get_on_error()
|
||||
|
||||
self.assertIsInstance(on_error, dict)
|
||||
self.assertEqual(len(on_error), 2)
|
||||
self.assertIn("task1", on_error)
|
||||
|
||||
def test_state_success(self):
|
||||
on_success = self.task.get_on_success()
|
||||
|
||||
self.assertIsInstance(on_success, dict)
|
||||
self.assertEqual(len(on_success), 3)
|
||||
self.assertIn("task1", on_success)
|
||||
self.assertIsNotNone(on_success["task1"])
|
@ -17,20 +17,14 @@ import yaml
|
||||
from yaml import error
|
||||
|
||||
from mistral import exceptions as exc
|
||||
from mistral.workbook.v1 import actions as actions_v1
|
||||
from mistral.workbook.v1 import namespaces as ns_v1
|
||||
from mistral.workbook.v1 import tasks as tasks_v1
|
||||
from mistral.workbook.v1 import workbook as wb_v1
|
||||
from mistral.workbook.v1 import workflow as wf_v1
|
||||
from mistral.workbook.v2 import actions as actions_v2
|
||||
from mistral.workbook.v2 import tasks as tasks_v2
|
||||
from mistral.workbook.v2 import workbook as wb_v2
|
||||
from mistral.workbook.v2 import workflows as wf_v2
|
||||
|
||||
V1_0 = '1.0'
|
||||
V2_0 = '2.0'
|
||||
|
||||
ALL_VERSIONS = [V1_0, V2_0]
|
||||
ALL_VERSIONS = [V2_0]
|
||||
|
||||
|
||||
def parse_yaml(text):
|
||||
@ -49,8 +43,8 @@ def parse_yaml(text):
|
||||
|
||||
|
||||
def _get_spec_version(spec_dict):
|
||||
# If version is not specified it will '1.0' by default.
|
||||
ver = V1_0
|
||||
# If version is not specified it will '2.0' by default.
|
||||
ver = V2_0
|
||||
|
||||
if 'version' in spec_dict:
|
||||
ver = spec_dict['version']
|
||||
@ -66,31 +60,22 @@ def _get_spec_version(spec_dict):
|
||||
|
||||
|
||||
def get_workbook_spec(spec_dict):
|
||||
if _get_spec_version(spec_dict) == V1_0:
|
||||
return wb_v1.WorkbookSpec(spec_dict)
|
||||
else:
|
||||
if _get_spec_version(spec_dict) == V2_0:
|
||||
return wb_v2.WorkbookSpec(spec_dict)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_workbook_spec_from_yaml(text):
|
||||
spec_dict = parse_yaml(text)
|
||||
|
||||
return get_workbook_spec(spec_dict)
|
||||
|
||||
|
||||
def get_namespace_spec(spec_dict):
|
||||
if _get_spec_version(spec_dict) == V1_0:
|
||||
return ns_v1.NamespaceSpec(spec_dict)
|
||||
else:
|
||||
return None
|
||||
return get_workbook_spec(parse_yaml(text))
|
||||
|
||||
|
||||
def get_action_spec(spec_dict):
|
||||
if _get_spec_version(spec_dict) == V1_0:
|
||||
return actions_v1.ActionSpec(spec_dict)
|
||||
else:
|
||||
if _get_spec_version(spec_dict) == V2_0:
|
||||
return actions_v2.ActionSpec(spec_dict)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_action_spec_from_yaml(text, action_name):
|
||||
spec_dict = parse_yaml(text)
|
||||
@ -105,17 +90,15 @@ def get_action_list_spec(spec_dict):
|
||||
|
||||
|
||||
def get_action_list_spec_from_yaml(text):
|
||||
spec_dict = parse_yaml(text)
|
||||
|
||||
return get_action_list_spec(spec_dict)
|
||||
return get_action_list_spec(parse_yaml(text))
|
||||
|
||||
|
||||
def get_workflow_spec(spec_dict):
|
||||
if _get_spec_version(spec_dict) == V1_0:
|
||||
return wf_v1.WorkflowSpec(spec_dict)
|
||||
else:
|
||||
if _get_spec_version(spec_dict) == V2_0:
|
||||
return wf_v2.WorkflowSpec(spec_dict)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def get_workflow_list_spec(spec_dict):
|
||||
return wf_v2.WorkflowListSpec(spec_dict)
|
||||
@ -134,9 +117,7 @@ def get_workflow_list_spec_from_yaml(text):
|
||||
|
||||
|
||||
def get_task_spec(spec_dict):
|
||||
if _get_spec_version(spec_dict) == V1_0:
|
||||
return tasks_v1.TaskSpec(spec_dict)
|
||||
else:
|
||||
if _get_spec_version(spec_dict) == V2_0:
|
||||
workflow_type = spec_dict.get('type')
|
||||
|
||||
if workflow_type == 'direct':
|
||||
@ -146,7 +127,4 @@ def get_task_spec(spec_dict):
|
||||
else:
|
||||
raise Exception('Unsupported workflow type "%s".' % workflow_type)
|
||||
|
||||
|
||||
def get_trigger_spec(spec_dict):
|
||||
# TODO(rakhmerov): Implement.
|
||||
pass
|
||||
return None
|
||||
|
@ -1,47 +0,0 @@
|
||||
# Copyright 2014 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from mistral.workbook import base
|
||||
|
||||
|
||||
class ActionSpec(base.BaseSpec):
|
||||
# See http://json-schema.org
|
||||
_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"version": {"type": "string"},
|
||||
"name": {"type": "string"},
|
||||
"class": {"type": "string"},
|
||||
"namespace": {"type": "string"},
|
||||
"base-parameters": {"type": "object"},
|
||||
"parameters": {"type": "array"},
|
||||
"output": {"type": ["string", "object", "array", "null"]},
|
||||
},
|
||||
"required": ["name", "class", "namespace"],
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
def __init__(self, data):
|
||||
super(ActionSpec, self).__init__(data)
|
||||
|
||||
self.name = data['name']
|
||||
self.clazz = data['class']
|
||||
self.namespace = data['namespace']
|
||||
self.base_parameters = data.get('base-parameters', {})
|
||||
self.parameters = data.get('parameters', {})
|
||||
self.output = data.get('output')
|
||||
|
||||
|
||||
class ActionSpecList(base.BaseSpecList):
|
||||
item_class = ActionSpec
|
@ -1,68 +0,0 @@
|
||||
# Copyright 2014 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from mistral import utils
|
||||
from mistral.workbook import base
|
||||
from mistral.workbook.v1 import actions
|
||||
|
||||
|
||||
def merge_base_parameters(action, ns_base_parameters):
|
||||
if not ns_base_parameters:
|
||||
return
|
||||
|
||||
if 'base-parameters' not in action:
|
||||
action['base-parameters'] = ns_base_parameters
|
||||
return
|
||||
|
||||
action_base_parameters = action['base-parameters']
|
||||
|
||||
utils.merge_dicts(action_base_parameters, ns_base_parameters)
|
||||
|
||||
|
||||
class NamespaceSpec(base.BaseSpec):
|
||||
# See http://json-schema.org
|
||||
_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"version": {"type": "string"},
|
||||
"name": {"type": "string"},
|
||||
"class": {"type": ["string", "null"]},
|
||||
"base-parameters": {"type": ["object", "null"]},
|
||||
"actions": {"type": "object"}
|
||||
},
|
||||
"required": ["name", "actions"],
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
def __init__(self, data):
|
||||
super(NamespaceSpec, self).__init__(data)
|
||||
|
||||
self.name = data['name']
|
||||
self.clazz = data.get('class')
|
||||
self.base_parameters = data.get('base-parameters')
|
||||
self.parameters = data.get('parameters')
|
||||
|
||||
for _, action in data['actions'].iteritems():
|
||||
action['namespace'] = self.name
|
||||
|
||||
if 'class' not in action:
|
||||
action['class'] = self.clazz
|
||||
|
||||
merge_base_parameters(action, self.base_parameters)
|
||||
|
||||
self.actions = actions.ActionSpecList(data['actions'])
|
||||
|
||||
|
||||
class NamespaceSpecList(base.BaseSpecList):
|
||||
item_class = NamespaceSpec
|
@ -1,102 +0,0 @@
|
||||
# Copyright 2014 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from mistral.workbook import base
|
||||
|
||||
|
||||
class TaskSpec(base.BaseSpec):
|
||||
# See http://json-schema.org
|
||||
_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"version": {"type": "string"},
|
||||
"name": {"type": "string"},
|
||||
"action": {"type": ["string", "null"]},
|
||||
"parameters": {"type": ["object", "null"]},
|
||||
"publish": {"type": ["object", "null"]},
|
||||
"retry": {"type": ["object", "null"]},
|
||||
"requires": {"type": ["object", "string", "array", "null"]},
|
||||
"on-finish": {"type": ["string", "array", "null"]},
|
||||
"on-success": {"type": ["string", "array", "null"]},
|
||||
"on-error": {"type": ["string", "array", "null"]}
|
||||
},
|
||||
"required": ["name", "action"],
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
def __init__(self, data):
|
||||
super(TaskSpec, self).__init__(data)
|
||||
|
||||
self._prepare(data)
|
||||
|
||||
self.requires = data.get('requires')
|
||||
self.action = data['action']
|
||||
self.name = data['name']
|
||||
self.parameters = data.get('parameters', {})
|
||||
|
||||
def _prepare(self, task):
|
||||
if task:
|
||||
req = task.get("requires", {})
|
||||
|
||||
if req and isinstance(req, list):
|
||||
task["requires"] = dict(zip(req, [''] * len(req)))
|
||||
elif isinstance(req, dict):
|
||||
task['requires'] = req
|
||||
|
||||
def get_property(self, property_name, default=None):
|
||||
return self._data.get(property_name, default)
|
||||
|
||||
def get_requires(self):
|
||||
return self._as_dict('requires').keys()
|
||||
|
||||
def get_on_error(self):
|
||||
return self._as_dict("on-error")
|
||||
|
||||
def get_on_success(self):
|
||||
return self._as_dict("on-success")
|
||||
|
||||
def get_on_finish(self):
|
||||
return self._as_dict("on-finish")
|
||||
|
||||
def get_action_namespace(self):
|
||||
return self.action.split('.')[0]
|
||||
|
||||
def get_action_name(self):
|
||||
return self.action.split('.')[1]
|
||||
|
||||
def get_full_action_name(self):
|
||||
return self.action
|
||||
|
||||
def is_retry_task(self):
|
||||
return self.get_property("retry") is not None
|
||||
|
||||
def get_retry_parameters(self):
|
||||
iterations = 0
|
||||
break_on = None
|
||||
delay = 0
|
||||
retry = self.get_property("retry")
|
||||
|
||||
if retry:
|
||||
if "count" in retry:
|
||||
iterations = retry["count"]
|
||||
if "break-on" in retry:
|
||||
break_on = retry["break-on"]
|
||||
if "delay" in retry:
|
||||
delay = retry["delay"]
|
||||
|
||||
return iterations, break_on, delay
|
||||
|
||||
|
||||
class TaskSpecList(base.BaseSpecList):
|
||||
item_class = TaskSpec
|
@ -1,73 +0,0 @@
|
||||
# Copyright 2014 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from mistral.workbook import base
|
||||
from mistral.workbook.v1 import namespaces
|
||||
from mistral.workbook.v1 import workflow
|
||||
|
||||
|
||||
class WorkbookSpec(base.BaseSpec):
|
||||
# See http://json-schema.org
|
||||
_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"Namespaces": {"type": "object"},
|
||||
"Workflow": {"type": "object"},
|
||||
"Triggers": {"type": "object"}
|
||||
},
|
||||
"required": ["Workflow"],
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
def __init__(self, doc):
|
||||
super(WorkbookSpec, self).__init__(doc)
|
||||
|
||||
self.namespaces = self._spec_property('Namespaces',
|
||||
namespaces.NamespaceSpecList)
|
||||
self.workflow = self._spec_property('Workflow', workflow.WorkflowSpec)
|
||||
self.tasks = self.workflow.tasks
|
||||
|
||||
def get_triggers(self):
|
||||
triggers_from_data = self._data.get("Triggers", None)
|
||||
|
||||
if not triggers_from_data:
|
||||
return []
|
||||
|
||||
triggers = []
|
||||
for name in triggers_from_data:
|
||||
trigger_dict = {'name': name}
|
||||
trigger_dict.update(triggers_from_data[name])
|
||||
triggers.append(trigger_dict)
|
||||
|
||||
return triggers
|
||||
|
||||
def get_action(self, full_action_name):
|
||||
if not self.namespaces:
|
||||
return None
|
||||
|
||||
if full_action_name.find(".") == -1:
|
||||
return {}
|
||||
|
||||
ns_name = full_action_name.split('.')[0]
|
||||
action_name = full_action_name.split('.')[1]
|
||||
|
||||
if ns_name in self.namespaces.item_keys():
|
||||
return self.namespaces[ns_name].actions.get(action_name)
|
||||
|
||||
def get_actions(self, namespace_name):
|
||||
return self.namespaces.get(namespace_name).actions
|
||||
|
||||
def get_trigger_task_name(self, trigger_name):
|
||||
trigger = self._data["Triggers"].get(trigger_name)
|
||||
return trigger.get('tasks') if trigger else ""
|
@ -1,33 +0,0 @@
|
||||
# Copyright 2014 - Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from mistral.workbook import base
|
||||
from mistral.workbook.v1 import tasks
|
||||
|
||||
|
||||
class WorkflowSpec(base.BaseSpec):
|
||||
# See http://json-schema.org
|
||||
_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tasks": {"type": "object"},
|
||||
},
|
||||
"required": ["tasks"],
|
||||
"additionalProperties": False
|
||||
}
|
||||
|
||||
def __init__(self, workflow):
|
||||
super(WorkflowSpec, self).__init__(workflow)
|
||||
|
||||
self.tasks = tasks.TaskSpecList(workflow['tasks'])
|
Loading…
Reference in New Issue
Block a user