Working on Mistral examples
* Added "vm_job" example (NOT FINISHED) * Refactoring overal examples structure * Minor cosmetic changes. Change-Id: I8dd47d89ccbd3b1ec003115c796b53cfdba247c1
This commit is contained in:
parent
a50a1bd900
commit
50708ea113
|
@ -0,0 +1,75 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- 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): remove "mock" dependency later
|
||||||
|
import mock
|
||||||
|
from mistralclient.api import client as cl
|
||||||
|
|
||||||
|
|
||||||
|
MISTRAL_URL = "http://localhost:8989/v1"
|
||||||
|
WORKBOOK_NAME = "vm_job_workbook"
|
||||||
|
WORKBOOK_DEFINITION_FILE_NAME = "run_vm_job.yaml"
|
||||||
|
|
||||||
|
cl.Client.authenticate = mock.MagicMock(return_value=(MISTRAL_URL,
|
||||||
|
"", "", ""))
|
||||||
|
CLIENT = cl.Client(mistral_url=MISTRAL_URL, project_name="mistral_demo")
|
||||||
|
|
||||||
|
|
||||||
|
def create_workbook(wb_name):
|
||||||
|
"""Create a workbook with the given name if it doesn't exist."""
|
||||||
|
wb = None
|
||||||
|
|
||||||
|
for item in CLIENT.workbooks.list():
|
||||||
|
if item.name == wb_name:
|
||||||
|
wb = item
|
||||||
|
break
|
||||||
|
|
||||||
|
if not wb:
|
||||||
|
wb = CLIENT.workbooks.create(wb_name,
|
||||||
|
description="My test workbook",
|
||||||
|
tags=["test"])
|
||||||
|
print "Created workbook: %s" % wb
|
||||||
|
else:
|
||||||
|
print "Workbook already exists: %s" % wb
|
||||||
|
|
||||||
|
|
||||||
|
def upload_workbook_definition(wb_name, file_name):
|
||||||
|
"""Upload a workbook definition from the given file name."""
|
||||||
|
with open(file_name) as definition_file:
|
||||||
|
definition = definition_file.read()
|
||||||
|
|
||||||
|
CLIENT.workbooks.upload_definition(wb_name, definition)
|
||||||
|
|
||||||
|
print "\nUploaded workbook:\n\"\n%s\"\n" % \
|
||||||
|
CLIENT.workbooks.get_definition(wb_name)
|
||||||
|
|
||||||
|
|
||||||
|
def create_execution(wb_name, task_name):
|
||||||
|
execution = CLIENT.executions.create(wb_name, task_name)
|
||||||
|
|
||||||
|
print "Created execution: %s" % execution
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main script."""
|
||||||
|
create_workbook(WORKBOOK_NAME)
|
||||||
|
upload_workbook_definition(WORKBOOK_NAME, WORKBOOK_DEFINITION_FILE_NAME)
|
||||||
|
create_execution(WORKBOOK_NAME, "runJob")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,97 @@
|
||||||
|
Workflow:
|
||||||
|
tasks:
|
||||||
|
runJob:
|
||||||
|
requires:
|
||||||
|
createVM: $.vm_ip != null
|
||||||
|
action: DemoApp:runJob
|
||||||
|
on-success: deleteVM
|
||||||
|
on-error: sendJobError
|
||||||
|
|
||||||
|
deleteVM:
|
||||||
|
action: Nova:deleteVM
|
||||||
|
on-finish: end
|
||||||
|
|
||||||
|
sendJobError:
|
||||||
|
action: std:email
|
||||||
|
parameters:
|
||||||
|
address: admin@mycompany.com
|
||||||
|
subject: Workflow error
|
||||||
|
body: Error occurred while running a VM job in execution {$.execution.id}
|
||||||
|
on-finish: deleteVM
|
||||||
|
|
||||||
|
# Creating a VM and waiting till it is up (an IP address has been assigned).
|
||||||
|
|
||||||
|
createVM:
|
||||||
|
action: Nova:createVM
|
||||||
|
on-success: waitForIP
|
||||||
|
on-error: sendCreateVMError
|
||||||
|
|
||||||
|
waitForIP:
|
||||||
|
action: std:repeat
|
||||||
|
parameters:
|
||||||
|
task: getIP
|
||||||
|
retries: 5
|
||||||
|
delay: 3000
|
||||||
|
break-on: $.vm_ip != null
|
||||||
|
on-finish:
|
||||||
|
sendCreateVMError: $.vm_ip = null
|
||||||
|
on-error:
|
||||||
|
sendCreateVMError
|
||||||
|
|
||||||
|
getIP:
|
||||||
|
action: Nova:getIP
|
||||||
|
|
||||||
|
sendCreateVMError:
|
||||||
|
action: std:email
|
||||||
|
parameters:
|
||||||
|
address: admin@mycompany.com
|
||||||
|
subject: Workflow error
|
||||||
|
body: Failed to create a VM in execution {$.execution.id}
|
||||||
|
on-finish: end
|
||||||
|
|
||||||
|
# Terminal no-op task.
|
||||||
|
|
||||||
|
end:
|
||||||
|
action: Util:no-op
|
||||||
|
|
||||||
|
# events:
|
||||||
|
# runJob:
|
||||||
|
# type: periodic
|
||||||
|
# tasks: runJob
|
||||||
|
# parameters:
|
||||||
|
# cron-pattern: "*/1 * * * *"
|
||||||
|
|
||||||
|
Services:
|
||||||
|
Nova:
|
||||||
|
type: REST_API
|
||||||
|
parameters:
|
||||||
|
baseUrl: {$.novaURL}
|
||||||
|
actions:
|
||||||
|
createVM:
|
||||||
|
parameters:
|
||||||
|
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
|
|
@ -0,0 +1,17 @@
|
||||||
|
Webhooks scheduling
|
||||||
|
===================
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
For this Mistral example an OpenStack installation is optional.
|
||||||
|
|
||||||
|
In case of running the example without OpenStack server side authentication
|
||||||
|
based on Keystone must be disabled by setting configuration option "auth_enable"
|
||||||
|
under group "pecan" to False like the following:
|
||||||
|
|
||||||
|
[pecan] <br>
|
||||||
|
auth_enable = False <br>
|
||||||
|
|
||||||
|
|
||||||
|
### Running the example
|
||||||
|
From the root folder ("mistral-extra" by default) run the following shell command:<br><br>
|
||||||
|
*tox -evenv -- python examples/webhooks/cmd/api.py --config-file path_to_config*
|
|
@ -18,14 +18,14 @@ import pecan
|
||||||
|
|
||||||
|
|
||||||
app = {
|
app = {
|
||||||
'root': 'simple_app.api.controllers.root.RootController',
|
'root': 'examples.webhooks.api.controllers.root.RootController',
|
||||||
'modules': ['simple_app.api'],
|
'modules': ['examples.webhooks.api'],
|
||||||
'debug': True,
|
'debug': True,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_pecan_config():
|
def get_pecan_config():
|
||||||
# Set up the pecan configuration
|
# Set up the pecan configuration.
|
||||||
return pecan.configuration.conf_from_dict(app)
|
return pecan.configuration.conf_from_dict(app)
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ import pkg_resources as pkg
|
||||||
|
|
||||||
from mistralclient.api import client
|
from mistralclient.api import client
|
||||||
|
|
||||||
from simple_app import version
|
from examples.webhooks import version
|
||||||
|
|
||||||
MISTRAL_URL = "http://localhost:8989/v1"
|
MISTRAL_URL = "http://localhost:8989/v1"
|
||||||
client.Client.authenticate = mock.MagicMock(return_value=(MISTRAL_URL,
|
client.Client.authenticate = mock.MagicMock(return_value=(MISTRAL_URL,
|
||||||
|
@ -40,8 +40,10 @@ def upload_workbook():
|
||||||
description="My test workbook",
|
description="My test workbook",
|
||||||
tags=["test"])
|
tags=["test"])
|
||||||
print("Uploading workbook definition...\n")
|
print("Uploading workbook definition...\n")
|
||||||
|
|
||||||
definition = get_workbook_definition()
|
definition = get_workbook_definition()
|
||||||
CLIENT.workbooks.upload_definition(WB_NAME, definition)
|
CLIENT.workbooks.upload_definition(WB_NAME, definition)
|
||||||
|
|
||||||
print definition
|
print definition
|
||||||
print("\nUploaded.")
|
print("\nUploaded.")
|
||||||
|
|
|
@ -20,9 +20,9 @@ from pecan import rest
|
||||||
from wsme import types as wtypes
|
from wsme import types as wtypes
|
||||||
import wsmeext.pecan as wsme_pecan
|
import wsmeext.pecan as wsme_pecan
|
||||||
|
|
||||||
from simple_app.api.controllers import resource
|
from examples.webhooks.api.controllers import resource
|
||||||
from simple_app.api.controllers import tasks
|
from examples.webhooks.api.controllers import tasks
|
||||||
from simple_app.api import client
|
from examples.webhooks.api import client
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
|
@ -21,7 +21,7 @@ import pecan
|
||||||
from wsme import types as wtypes
|
from wsme import types as wtypes
|
||||||
import wsmeext.pecan as wsme_pecan
|
import wsmeext.pecan as wsme_pecan
|
||||||
|
|
||||||
from simple_app import tasks
|
from examples.webhooks import tasks
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
|
@ -29,9 +29,9 @@ from wsgiref import simple_server
|
||||||
|
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
|
|
||||||
from simple_app import config
|
from examples.webhooks import config
|
||||||
from simple_app.api import app
|
from examples.webhooks.api import app
|
||||||
from simple_app.api import client
|
from examples.webhooks.api import client
|
||||||
|
|
||||||
|
|
||||||
eventlet.monkey_patch(
|
eventlet.monkey_patch(
|
||||||
|
@ -39,7 +39,6 @@ eventlet.monkey_patch(
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARN)
|
logging.basicConfig(level=logging.WARN)
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
CLIENT = client.CLIENT
|
|
||||||
|
|
||||||
|
|
||||||
def upload_wb_and_start():
|
def upload_wb_and_start():
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
|
|
||||||
from simple_app import version
|
from examples.webhooks import version
|
||||||
|
|
||||||
|
|
||||||
api_opts = [
|
api_opts = [
|
|
@ -17,7 +17,7 @@
|
||||||
from time import sleep
|
from time import sleep
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from simple_app.api import client
|
from examples.webhooks.api import client
|
||||||
|
|
||||||
|
|
||||||
CLIENT = client.CLIENT
|
CLIENT = client.CLIENT
|
|
@ -16,5 +16,5 @@
|
||||||
|
|
||||||
from pbr import version
|
from pbr import version
|
||||||
|
|
||||||
version_info = version.VersionInfo('simple_app')
|
version_info = version.VersionInfo('examples.webhooks')
|
||||||
version_string = version_info.version_string
|
version_string = version_info.version_string
|
|
@ -18,10 +18,10 @@ author-email = openstack-dev@lists.openstack.org
|
||||||
|
|
||||||
[files]
|
[files]
|
||||||
packages =
|
packages =
|
||||||
mistralextra
|
examples
|
||||||
|
|
||||||
[nosetests]
|
[nosetests]
|
||||||
cover-package = mistralextra
|
cover-package = examples
|
||||||
|
|
||||||
[extract_messages]
|
[extract_messages]
|
||||||
keywords = _ gettext ngettext l_ lazy_gettext
|
keywords = _ gettext ngettext l_ lazy_gettext
|
||||||
|
|
Loading…
Reference in New Issue