Add DSL parser

* DSL parser
 * Unit tests

Change-Id: I3e56ad7125233ecdafd41036d8b717fb95e2955c
This commit is contained in:
Nikolay Mahotkin 2013-12-11 16:41:58 +04:00
parent 6f245b199c
commit 7d716311df
4 changed files with 184 additions and 1 deletions

53
mistral/dsl.py Normal file
View File

@ -0,0 +1,53 @@
# Copyright (c) 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.
import yaml
from yaml import error
class Parser(object):
"""Mistral DSL parser.
Loads a workbook definition in YAML format as described in Mistral DSL
specification and provides various methods to access DSL entities like
tasks and actions in a form of dictionary.
"""
def __init__(self, workbook_definition):
try:
self.doc = yaml.safe_load(workbook_definition)
except error.YAMLError as exc:
raise RuntimeError("Definition could not be parsed: %s\n"
% exc.message)
def get_service(self):
return self.doc["Service"]
def get_events(self):
events_from_doc = self.doc["Workflow"]["events"]
events = []
for name in events_from_doc:
event_dict = {'name': name}
event_dict.update(events_from_doc[name])
events.append(event_dict)
return events
def get_tasks(self):
return self.doc["Workflow"]["tasks"]
def get_service_name(self):
return self.doc['Service']['name']
def get_event_task_name(self, event_name):
return self.doc["Workflow"]["events"][event_name]['tasks']

View File

@ -0,0 +1,76 @@
Service:
name: MyRest
type: REST_API
parameters:
baseUrl: http://some_host
actions:
create-vm:
parameters:
url: /service/action/execute
method: GET
task-parameters:
flavor_id:
optional: false
image_id:
optional: false
backup-vm:
parameters:
url: url_for_backup
method: GET
task-parameters:
server_id:
optional: false
attach-volume:
parameters:
url: url_for_attach
method: GET
task-parameters:
size:
optional: false
mnt_path:
optional: false
format-volume:
parameters:
url: url_for_format
method: GET
task-parameters:
volume_id:
optional: false
server_id:
optional: false
Workflow:
tasks:
create-vms:
action: MyRest:create-vm
parameters:
image_id: 1234
flavor_id: 42
attach-volumes:
action: Nova:attach-volume
parameters:
size:
optional: false
mnt_path:
optional: false
dependsOn: [create-vms]
format-volumes:
action: Nova:format-volume
parameters:
server_id:
optional: false
dependsOn: [attach-volumes]
backup-vms:
action: Nova:backup-vm
parameters:
server_id:
optional: false
dependsOn: [create-vms]
events:
create-vms:
type: periodic
tasks: create-vms
parameters:
cron-pattern: "* * * * *"

View File

@ -0,0 +1,54 @@
# Copyright (c) 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.
import pkg_resources as pkg
import unittest2
from mistral import dsl
from mistral import version
class DSLParserTest(unittest2.TestCase):
def setUp(self):
doc = open(pkg.resource_filename(
version.version_info.package,
"tests/resources/test_rest.yaml")).read()
self.dsl = dsl.Parser(doc)
def test_service(self):
service = self.dsl.get_service()
self.assertEqual(service["name"], "MyRest")
self.assertEqual(service["type"], "REST_API")
self.assertIn("baseUrl", service["parameters"])
def test_events(self):
events = self.dsl.get_events()
self.assertIn("create-vms", events[0]['name'])
def test_tasks(self):
tasks = self.dsl.get_tasks()
self.assertIn("create-vms", tasks)
self.assertIn("parameters", tasks["create-vms"])
self.assertEqual(tasks["backup-vms"]["action"],
"Nova:backup-vm")
def test_broken_definition(self):
broken_yaml = """
Workflow:
[tasks:
create-vms/:
"""
self.assertRaises(RuntimeError, dsl.Parser, broken_yaml)

View File

@ -15,5 +15,5 @@
from pbr import version
version_info = version.VersionInfo('Mistral')
version_info = version.VersionInfo('mistral')
version_string = version_info.version_string