Removing v1 examples
Change-Id: I487e68978574c57a1e599f4a34a15cc7716bde13
This commit is contained in:
parent
e86568c851
commit
a90e96a3e5
2
AUTHORS
2
AUTHORS
|
@ -5,5 +5,5 @@ Jeremy Stanley <fungi@yuggoth.org>
|
|||
Kirill Izotov <enykeev@stackstorm.com>
|
||||
Nikolay Mahotkin <nmakhotkin@mirantis.com>
|
||||
Renat Akhmerov <rakhmerov@mirantis.com>
|
||||
Tetiana Lashchova <tlashchova@mirantis.com>
|
||||
Timur Nurlygayanov <tnurlygayanov@mirantis.com>
|
||||
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
Create VM example
|
||||
==================
|
||||
|
||||
It demonstrates Mistral project features:
|
||||
This example connects to OpenStack Nova and creates a VM with image and flavor id provided.
|
||||
|
||||
How to run
|
||||
----------
|
||||
|
||||
1. Make sure that python-mistralclient have been installed. If not, install it:
|
||||
|
||||
git clone https://github.com/stackforge/python-mistralclient.git
|
||||
cd python-mistralclient
|
||||
python setup.py install
|
||||
|
||||
2. Make sure that Mistral API and at least one Mistral-executor are up and running
|
||||
3. Create workbook and upload the definition
|
||||
|
||||
mistral workbook-create myWorkbook description tag1,tag2 <path to create_vm_example.yaml>
|
||||
|
||||
4. Create context file (simple json, which contains needed by workflow properties)
|
||||
|
||||
{
|
||||
"server_name": "mistral-vm",
|
||||
"nova_url": "http://localhost:8774/v2",
|
||||
"image_id": "[copy from horizon or nova cli client]",
|
||||
"flavor_id": "1"
|
||||
}
|
||||
|
||||
5. Start execution
|
||||
|
||||
mistral execution-create myWorkbook create-vm <path-to-the-context-file>
|
|
@ -1,36 +0,0 @@
|
|||
# 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 of the new instance
|
||||
# - image_id ## image id from Glance service
|
||||
# - flavor_id ## flavor id - type of instance hardware
|
||||
|
||||
Namespaces:
|
||||
Nova:
|
||||
class: std.http
|
||||
actions:
|
||||
create-vm:
|
||||
base-parameters:
|
||||
url: '<% $.nova_url %>/<% $.openstack.project_id %>/servers'
|
||||
method: POST
|
||||
headers:
|
||||
X-Auth-Token: <% $.openstack.auth_token %>
|
||||
Content-Type: application/json
|
||||
body:
|
||||
server:
|
||||
name: <% $.server_name %>
|
||||
imageRef: <% $.image_id %>
|
||||
flavorRef: <% $.flavor_id %>
|
||||
output:
|
||||
vm_id: <% $.content.server.id %>
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
create-vm:
|
||||
action: Nova.create-vm
|
||||
parameters:
|
||||
server_name: <% $.server_name %>
|
||||
image_id: <% $.image_id %>
|
||||
flavor_id: <% $.flavor_id %>
|
||||
nova_url: <% $.nova_url %>
|
||||
publish:
|
||||
vm_id: <% $.vm_id %>
|
|
@ -1,66 +0,0 @@
|
|||
Run VM job example
|
||||
==================
|
||||
|
||||
Run VM job example is created to demonstrate Mistral project features:
|
||||
It is needed for spinning up a VM and use it to do some useful work given calculator as an example.
|
||||
|
||||
What this example does
|
||||
--------------------
|
||||
|
||||
1. Creates a VM
|
||||
2. Waits till it is up and running
|
||||
3. Runs small web server on VM
|
||||
4. Sends request to the server
|
||||
5. If an error occurred, it sends a email to admin with error message
|
||||
|
||||
How to run
|
||||
----------
|
||||
|
||||
1. Preparing
|
||||
|
||||
1. Create an image of virtual machine
|
||||
2. Make sure that VM has SSH server in running state
|
||||
3. Make sure that VM has password access via SSH
|
||||
4. Install packages (example for Debian/Ubuntu based systems)
|
||||
|
||||
sudo apt-get install python-dev
|
||||
sudo apt-get install python-pip
|
||||
sudo pip install flask
|
||||
|
||||
5. Put *web_app.py* file into user's home directory. To check if it works, type
|
||||
|
||||
python ~/web_app.py
|
||||
|
||||
This should run a small server on 5000 port.
|
||||
|
||||
6. Save image
|
||||
|
||||
2. Make sure that python-mistralclient have been installed. If not, install it:
|
||||
|
||||
git clone https://github.com/stackforge/python-mistralclient.git
|
||||
cd python-mistralclient
|
||||
python setup.py install
|
||||
|
||||
3. Make sure that Mistral API and at least one Mistral-executor are up and running
|
||||
4. Create workbook and upload the definition
|
||||
|
||||
mistral workbook-create myWorkbook description tag1,tag2 <path to run_vm_job.yaml>
|
||||
|
||||
5. Create context file (simple json, which contains needed by workflow properties)
|
||||
|
||||
{
|
||||
"server_name": "mistral-vm",
|
||||
"nova_url": "http://172.16.80.100:8774/v2",
|
||||
"image_id": "[copy from horizon or nova cli client]",
|
||||
"flavor_id": "1",
|
||||
"ssh_username": "[VM username]",
|
||||
"ssh_password": "[VM password]",
|
||||
"smtp_server": "[address to smtp server]",
|
||||
"from_email": "[email address]",
|
||||
"smtp_password": "[email password]",
|
||||
"admin_email": "[address the message should be sent to]",
|
||||
}
|
||||
|
||||
6. Start execution
|
||||
|
||||
mistral execution-create myWorkbook createVM <path-to-the-context-file>
|
|
@ -1,190 +0,0 @@
|
|||
# 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 of the new instance
|
||||
# - image_id ## image id from Glance service
|
||||
# - flavor_id ## flavor id - type of instance hardware
|
||||
# - ssh_username ## VM username
|
||||
# - ssh_password ## VM password
|
||||
# - 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
|
||||
base-parameters:
|
||||
headers:
|
||||
X-Auth-Token: <% $.openstack.auth_token %>
|
||||
actions:
|
||||
createVM:
|
||||
base-parameters:
|
||||
url: <% $.nova_url %>/<% $.openstack.project_id %>/servers
|
||||
method: POST
|
||||
headers:
|
||||
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 %>/<% $.openstack.project_id %>/servers/<% $.vm_id %>
|
||||
method: GET
|
||||
output:
|
||||
vm_ip: <% $.content.server.addresses.novanetwork.where($.'OS-EXT-IPS:type' = 'floating')[0].addr %>
|
||||
|
||||
deleteVM:
|
||||
base-parameters:
|
||||
url: <% $.nova_url %>/<% $.openstack.project_id %>/servers/<% $.vm_id %>
|
||||
method: DELETE
|
||||
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 %>
|
||||
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 %>
|
||||
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:
|
||||
from_addr: <% $.from_email %>
|
||||
to_addrs: [<% $.admin_email %>]
|
||||
subject: Workflow result
|
||||
body: |
|
||||
Workflow result of execution <% $.__execution.id %> is <% $.result %>
|
||||
|
||||
-- Thanks, Mistral Team.
|
||||
smtp_server: <% $.smtp_server %>
|
||||
smtp_password: <% $.smtp_password %>
|
||||
on-finish: deleteVM
|
||||
|
||||
# In case of createVM error send e-mail with error message.
|
||||
sendCreateVMError:
|
||||
action: std.email
|
||||
parameters:
|
||||
from_addr: <% $.from_email %>
|
||||
to_addrs: [<% $.admin_email %>]
|
||||
subject: Workflow error
|
||||
body: |
|
||||
Failed to create a VM in execution <% $.__execution.id %>
|
||||
|
||||
-- Thanks, Mistral Team.
|
||||
smtp_server: <% $.smtp_server %>
|
||||
smtp_password: <% $.smtp_password %>
|
||||
on-finish: deleteVM
|
||||
|
||||
# Destroy the VM (request to Nova).
|
||||
deleteVM:
|
||||
action: Nova.deleteVM
|
||||
parameters:
|
||||
nova_url: <% $.nova_url %>
|
||||
vm_id: <% $.vm_id %>
|
||||
|
||||
#triggers:
|
||||
# runJob:
|
||||
# type: periodic
|
||||
# tasks: runJob
|
||||
# parameters:
|
||||
# cron-pattern: "*/1 * * * *"
|
|
@ -1,44 +0,0 @@
|
|||
# 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.
|
||||
|
||||
import flask
|
||||
|
||||
|
||||
app = flask.Flask(__name__)
|
||||
host = "0.0.0.0"
|
||||
port = 5000
|
||||
|
||||
|
||||
@app.route('/summ', methods=["POST"])
|
||||
def summ():
|
||||
summ = 0
|
||||
args = flask.request.data
|
||||
|
||||
try:
|
||||
args_list = flask.json.loads(args).get('arguments')
|
||||
except:
|
||||
return (403, "Please, specify list of arguments in the request body"
|
||||
" in form '{\"arguments\": [arg1, arg2, .., argN]}'")
|
||||
|
||||
for a in args_list:
|
||||
try:
|
||||
summ += int(a)
|
||||
except:
|
||||
return 403, "Sorry, need to use only integer arguments!"
|
||||
|
||||
return flask.jsonify({'result': summ})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host=host, port=port)
|
|
@ -1,23 +0,0 @@
|
|||
Webhooks scheduling
|
||||
===================
|
||||
|
||||
### What does this example do?
|
||||
|
||||
It runs small web-server and exposes one URL - 0.0.0.0:8988/ (host and port by default)
|
||||
We can make request to /<name>, where name is the task name which will run on the server.
|
||||
Actually, the server doesn't do any work, just sleeps for a few seconds (for simulate long execution) and then sends to Mistral info about task result and state.
|
||||
|
||||
### 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]
|
||||
auth_enable = False
|
||||
|
||||
### Running the example
|
||||
From the root folder ("mistral-extra" by default) run the following shell command:
|
||||
|
||||
tox -evenv -- python examples/v1/webhooks/cmd/run.py
|
|
@ -1,42 +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.
|
||||
|
||||
import pecan
|
||||
|
||||
|
||||
app = {
|
||||
'root': 'examples.v1.webhooks.api.controllers.root.RootController',
|
||||
'modules': ['examples.v1.webhooks.api'],
|
||||
'debug': True,
|
||||
}
|
||||
|
||||
|
||||
def get_pecan_config():
|
||||
# Set up the pecan configuration.
|
||||
return pecan.configuration.conf_from_dict(app)
|
||||
|
||||
|
||||
def setup_app(config=None):
|
||||
if not config:
|
||||
config = get_pecan_config()
|
||||
|
||||
app_conf = dict(config)
|
||||
|
||||
return pecan.make_app(
|
||||
app_conf.pop('root'),
|
||||
logging=getattr(config, 'logging', {}),
|
||||
**app_conf
|
||||
)
|
|
@ -1,74 +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.
|
||||
|
||||
import pkg_resources as pkg
|
||||
|
||||
from mistralclient.api import client
|
||||
from mistralclient.openstack.common.cliutils import env
|
||||
|
||||
from examples.v1.webhooks import version
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
|
||||
MISTRAL_URL = env('OS_MISTRAL_URL', default=cfg.CONF.client.mistral_url)
|
||||
if MISTRAL_URL.find("v2") != -1:
|
||||
raise RuntimeError("Can not run this example, please provide the correct"
|
||||
"Mistral v1 URL (default is %s)"
|
||||
% cfg.CONF.client.mistral_url)
|
||||
|
||||
|
||||
CLIENT = client.client(
|
||||
mistral_url=MISTRAL_URL,
|
||||
auth_url=env('OS_AUTH_URL', default=cfg.CONF.client.auth_url),
|
||||
username=env('OS_USERNAME', default=cfg.CONF.client.username),
|
||||
api_key=env('OS_PASSWORD', default=cfg.CONF.client.password),
|
||||
project_name=env('OS_TENANT_NAME', default=cfg.CONF.client.tenant_name)
|
||||
)
|
||||
|
||||
|
||||
WB_NAME = "myWorkbook"
|
||||
TASK = "execute_backup"
|
||||
|
||||
|
||||
def upload_workbook():
|
||||
try:
|
||||
CLIENT.workbooks.get(WB_NAME)
|
||||
except:
|
||||
CLIENT.workbooks.create(WB_NAME,
|
||||
description="My test workbook",
|
||||
tags=["test"])
|
||||
print("Uploading workbook definition...\n")
|
||||
|
||||
definition = get_workbook_definition()
|
||||
CLIENT.workbooks.upload_definition(WB_NAME, definition)
|
||||
|
||||
print definition
|
||||
print("\nUploaded.")
|
||||
|
||||
|
||||
def get_workbook_definition():
|
||||
return open(pkg.resource_filename(version.version_info.package,
|
||||
"demo.yaml")).read()
|
||||
|
||||
|
||||
def start_execution():
|
||||
import threading
|
||||
t = threading.Thread(target=CLIENT.executions.create,
|
||||
kwargs={'workbook_name': WB_NAME,
|
||||
'task': TASK})
|
||||
t.start()
|
||||
return "accepted"
|
|
@ -1,54 +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.
|
||||
|
||||
import logging
|
||||
from wsme import types as wtypes
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
API_STATUS = wtypes.Enum(str, 'SUPPORTED', 'CURRENT', 'DEPRECATED')
|
||||
|
||||
|
||||
class Resource(wtypes.Base):
|
||||
"""REST API Resource."""
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, d):
|
||||
# TODO: take care of nested resources
|
||||
obj = cls()
|
||||
|
||||
for key, val in d.items():
|
||||
if hasattr(obj, key):
|
||||
setattr(obj, key, val)
|
||||
|
||||
return obj
|
||||
|
||||
def __str__(self):
|
||||
"""WSME based implementation of __str__."""
|
||||
|
||||
res = "%s [" % type(self).__name__
|
||||
|
||||
first = True
|
||||
for attr in self._wsme_attributes:
|
||||
if not first:
|
||||
res += ', '
|
||||
else:
|
||||
first = False
|
||||
|
||||
res += "%s='%s'" % (attr.name, getattr(self, attr.name))
|
||||
|
||||
return res + "]"
|
|
@ -1,69 +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.
|
||||
|
||||
import logging
|
||||
import pecan
|
||||
from pecan import rest
|
||||
from wsme import types as wtypes
|
||||
import wsmeext.pecan as wsme_pecan
|
||||
|
||||
from examples.v1.webhooks.api.controllers import resource
|
||||
from examples.v1.webhooks.api.controllers import tasks
|
||||
from examples.v1.webhooks.api import client
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
API_STATUS = wtypes.Enum(str, 'SUPPORTED', 'CURRENT', 'DEPRECATED')
|
||||
|
||||
|
||||
class Link(resource.Resource):
|
||||
"""Web link."""
|
||||
|
||||
href = wtypes.text
|
||||
target = wtypes.text
|
||||
|
||||
|
||||
class APIVersion(resource.Resource):
|
||||
"""API Version."""
|
||||
|
||||
id = wtypes.text
|
||||
status = API_STATUS
|
||||
link = Link
|
||||
|
||||
|
||||
class StartController(rest.RestController):
|
||||
@wsme_pecan.wsexpose(wtypes.text)
|
||||
def get(self):
|
||||
print("Start execution for: %s" % client.TASK)
|
||||
|
||||
return client.start_execution()
|
||||
|
||||
|
||||
class RootController(object):
|
||||
|
||||
tasks = tasks.Controller()
|
||||
start = StartController()
|
||||
|
||||
@wsme_pecan.wsexpose([APIVersion])
|
||||
def index(self):
|
||||
LOG.debug("Fetching API versions.")
|
||||
|
||||
host_url = '%s/%s' % (pecan.request.host_url, 'v1')
|
||||
api_v1 = APIVersion(id='v1.0',
|
||||
status='CURRENT',
|
||||
link=Link(href=host_url, target='v1'))
|
||||
|
||||
return [api_v1]
|
|
@ -1,70 +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.
|
||||
|
||||
import logging
|
||||
from pecan import abort
|
||||
from pecan import rest
|
||||
import pecan
|
||||
from wsme import types as wtypes
|
||||
import wsmeext.pecan as wsme_pecan
|
||||
|
||||
from examples.v1.webhooks import tasks
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Controller(rest.RestController):
|
||||
"""API root controller"""
|
||||
|
||||
@wsme_pecan.wsexpose(wtypes.text)
|
||||
def get_all(self):
|
||||
LOG.debug("Fetch items.")
|
||||
|
||||
values = {
|
||||
'tasks': [
|
||||
'put_service_on_hold',
|
||||
'backup_user_data',
|
||||
'backup_service_data',
|
||||
'execute_backup'
|
||||
]
|
||||
}
|
||||
|
||||
if not values:
|
||||
abort(404)
|
||||
else:
|
||||
return values
|
||||
|
||||
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
|
||||
def get(self, name):
|
||||
print("Task '%s' is running." % name)
|
||||
|
||||
value = "Task %s accepted" % name
|
||||
tasks.start_task(**self.get_mistral_headers())
|
||||
return value
|
||||
|
||||
def get_mistral_headers(self):
|
||||
headers = pecan.request.headers
|
||||
try:
|
||||
needed_headers = {
|
||||
'workbook_name': headers['Mistral-Workbook-Name'],
|
||||
'execution_id': headers['Mistral-Execution-Id'],
|
||||
'task_id': headers['Mistral-Task-Id']
|
||||
}
|
||||
return needed_headers
|
||||
except KeyError:
|
||||
raise RuntimeError("Could not find http headers for "
|
||||
"defining mistral task")
|
|
@ -1,97 +0,0 @@
|
|||
#! /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.
|
||||
|
||||
"""Script to start Demo API service."""
|
||||
|
||||
import eventlet
|
||||
|
||||
import logging
|
||||
import os
|
||||
from requests import exceptions
|
||||
import sys
|
||||
import threading
|
||||
import asyncore
|
||||
from time import sleep
|
||||
from wsgiref import simple_server
|
||||
from SocketServer import ThreadingMixIn
|
||||
from smtpd import DebuggingServer
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from examples.v1.webhooks import config
|
||||
from examples.v1.webhooks.api import app
|
||||
from examples.v1.webhooks.api import client
|
||||
|
||||
|
||||
eventlet.monkey_patch(
|
||||
os=True, select=True, socket=True, thread=True, time=True)
|
||||
|
||||
logging.basicConfig(level=logging.WARN)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def upload_wb_and_start():
|
||||
sleep(5)
|
||||
|
||||
try:
|
||||
client.upload_workbook()
|
||||
except exceptions.ConnectionError:
|
||||
LOG.error("Error. Mistral service probably is not working now")
|
||||
sys.exit(1)
|
||||
|
||||
print("Start execution for: %s" % client.TASK)
|
||||
|
||||
client.start_execution()
|
||||
|
||||
|
||||
class ThreadingWSGIServer(ThreadingMixIn, simple_server.WSGIServer):
|
||||
pass
|
||||
|
||||
|
||||
def _run_smtpd():
|
||||
# TODO: get address/port from demo.yaml smtp_server to match.
|
||||
DebuggingServer(('localhost', 10025), None)
|
||||
asyncore.loop()
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
config.parse_args()
|
||||
|
||||
host = cfg.CONF.api.host
|
||||
port = cfg.CONF.api.port
|
||||
|
||||
server = simple_server.make_server(
|
||||
host, port, app.setup_app(), ThreadingWSGIServer)
|
||||
|
||||
LOG.info("Demo app API is serving on http://%s:%s (PID=%s)" %
|
||||
(host, port, os.getpid()))
|
||||
server.serve_forever()
|
||||
except RuntimeError, e:
|
||||
sys.stderr.write("ERROR: %s\n" % e)
|
||||
sys.exit(1)
|
||||
except KeyboardInterrupt:
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
upload_thread = threading.Thread(target=upload_wb_and_start)
|
||||
upload_thread.run()
|
||||
smtp_thread = threading.Thread(target=_run_smtpd)
|
||||
smtp_thread.daemon = True
|
||||
smtp_thread.start()
|
||||
main()
|
|
@ -1,45 +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 oslo.config import cfg
|
||||
|
||||
from examples.v1.webhooks import version
|
||||
|
||||
|
||||
api_opts = [
|
||||
cfg.StrOpt('host', default='0.0.0.0', help='Simple-app API server host'),
|
||||
cfg.IntOpt('port', default=8988, help='Simple-app API server port')
|
||||
]
|
||||
|
||||
client_opts = [
|
||||
cfg.StrOpt('mistral_url', default='http://localhost:8989/v1'),
|
||||
cfg.StrOpt('auth_url', default='http://localhost:5000/v3'),
|
||||
cfg.StrOpt('username', default='admin'),
|
||||
cfg.StrOpt('password', default='openstack'),
|
||||
cfg.StrOpt('tenant_name', default='admin')
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(api_opts, group='api')
|
||||
CONF.register_opts(client_opts, group='client')
|
||||
|
||||
|
||||
def parse_args(args=None, usage=None, default_config_files=None):
|
||||
CONF(args=args,
|
||||
project='mistral-demo',
|
||||
version=version,
|
||||
usage=usage,
|
||||
default_config_files=default_config_files)
|
|
@ -1,63 +0,0 @@
|
|||
Namespaces:
|
||||
MyRest:
|
||||
actions:
|
||||
put_service_on_hold:
|
||||
class: std.mistral_http
|
||||
base-parameters:
|
||||
url: http://localhost:8988/tasks/put_service_on_hold
|
||||
|
||||
backup_user_data:
|
||||
class: std.mistral_http
|
||||
base-parameters:
|
||||
url: http://localhost:8988/tasks/backup_user_data
|
||||
|
||||
backup_service_data:
|
||||
class: std.mistral_http
|
||||
base-parameters:
|
||||
url: http://localhost:8988/tasks/backup_service_data
|
||||
|
||||
execute_backup:
|
||||
class: std.mistral_http
|
||||
base-parameters:
|
||||
url: http://localhost:8988/tasks/execute_backup
|
||||
|
||||
Workflow:
|
||||
tasks:
|
||||
put_service_on_hold:
|
||||
action: MyRest.put_service_on_hold
|
||||
|
||||
backup_user_data:
|
||||
requires: [put_service_on_hold]
|
||||
action: MyRest.backup_user_data
|
||||
|
||||
backup_service_data:
|
||||
requires: [put_service_on_hold]
|
||||
action: MyRest.backup_service_data
|
||||
|
||||
send_email:
|
||||
requires: [backup_service_data, backup_user_data]
|
||||
action: std.email
|
||||
parameters:
|
||||
from_addr: mistral@example.com
|
||||
to_addrs: [mistral@example.com, boss@example.com]
|
||||
subject: Backup complete
|
||||
body: |
|
||||
Congratulations, the backup is complete
|
||||
|
||||
-- Thanks, Mistral Team.
|
||||
|
||||
-- Thanks, Mistral Team.
|
||||
smtp_server: localhost:10025
|
||||
# Use password if smtpd requires TLS authentication (password: None).
|
||||
smtp_password: null
|
||||
|
||||
execute_backup:
|
||||
requires: [backup_user_data, backup_service_data, send_email]
|
||||
action: MyRest.execute_backup
|
||||
|
||||
# triggers:
|
||||
# execute_backup:
|
||||
# type: periodic
|
||||
# tasks: execute_backup
|
||||
# parameters:
|
||||
# cron-pattern: "*/1 * * * *"
|
|
@ -1,37 +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 time import sleep
|
||||
import threading
|
||||
|
||||
from examples.v1.webhooks.api import client
|
||||
|
||||
|
||||
CLIENT = client.CLIENT
|
||||
|
||||
|
||||
def start_task(**kwargs):
|
||||
thread = threading.Thread(target=finish_task, kwargs=kwargs)
|
||||
thread.start()
|
||||
|
||||
|
||||
def finish_task(task_id, execution_id, workbook_name):
|
||||
# simulate working
|
||||
sleep(8)
|
||||
|
||||
task = CLIENT.tasks.update(workbook_name, execution_id,
|
||||
task_id, "SUCCESS")
|
||||
print("Task '%s' - SUCCESS" % task.name)
|
|
@ -1,20 +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 pbr import version
|
||||
|
||||
version_info = version.VersionInfo('examples.v1.webhooks')
|
||||
version_string = version_info.version_string
|
Loading…
Reference in New Issue