Add Heat tasks

To manage and track bay status, this adds heat tasks which include:
* Creating stack
* Updating stack
* Deleting stack

Partially-Implements: blueprint magnum-taskflow

Change-Id: Icd388ce7ebd3ca35eac392406c28bbad40b1de24
This commit is contained in:
OTSUKA, Yuanying 2015-03-06 13:59:42 +09:00
parent ac5436ea63
commit 6fe6e884a2
5 changed files with 221 additions and 0 deletions

View File

@ -0,0 +1,22 @@
# Copyright 2015 NEC Corporation. All rights reserved.
#
# 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 taskflow.task as task
class OSBaseTask(task.Task):
def __init__(self, os_client, name=None, **kwargs):
self.os_client = os_client
super(OSBaseTask, self).__init__(name=name, **kwargs)

View File

@ -0,0 +1,55 @@
# Copyright 2015 NEC Corporation. All rights reserved.
#
# 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 magnum.conductor import tasks
class CreateStack(tasks.OSBaseTask):
"""CreateStack Task
This task interfaces with Heat API and creates a stack based on parameters
provided to the Task.
"""
def execute(self, stack_name, parameters, template, files):
stack = self.os_client.stacks.create(stack_name=stack_name,
parameters=parameters,
template=template, files=files)
return stack
class UpdateStack(tasks.OSBaseTask):
"""UpdateStack Task
This task interfaces with Heat API and update a stack based on parameters
provided to the Task.
"""
def execute(self, stack_id, parameters, template, files):
self.os_client.stacks.update(stack_id, parameters=parameters,
template=template, files=files)
class DeleteStack(tasks.OSBaseTask):
"""DeleteStack Task
This task interfaces with Heat API and delete a stack based on parameters
provided to the Task.
"""
def execute(self, stack_id):
self.os_client.stacks.delete(stack_id)

View File

View File

@ -0,0 +1,143 @@
# Copyright 2015 NEC Corporation. All rights reserved.
#
# 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 magnum.conductor.tasks import heat_tasks
from magnum.tests import base
import mock
from taskflow import engines
from taskflow.patterns import linear_flow
class HeatTasksTests(base.TestCase):
def setUp(self):
super(HeatTasksTests, self).setUp()
self.heat_client = mock.MagicMock(name='heat_client')
def _get_create_stack_flow(self, heat_client):
flow = linear_flow.Flow("create stack flow")
flow.add(
heat_tasks.CreateStack(
os_client=heat_client,
requires=('stack_name', 'parameters', 'template', 'files'),
provides='new_stack',
),
)
return flow
def _get_update_stack_flow(self, heat_client):
flow = linear_flow.Flow("update stack flow")
flow.add(
heat_tasks.UpdateStack(
os_client=heat_client,
requires=('stack_id', 'parameters', 'template', 'files'),
),
)
return flow
def _get_delete_stack_flow(self, heat_client):
flow = linear_flow.Flow("delete stack flow")
flow.add(
heat_tasks.DeleteStack(
os_client=heat_client,
requires=('stack_id'),
),
)
return flow
def test_create_stack(self):
heat_client = mock.MagicMock(name='heat_client')
stack_id = 'stack_id'
stack_name = 'stack_name'
stack = {
'stack': {
'id': stack_id
}
}
heat_client.stacks.create.return_value = stack
flow_store = {
'stack_name': stack_name,
'parameters': 'parameters',
'template': 'template',
'files': 'files'
}
flow = self._get_create_stack_flow(heat_client)
result = engines.run(flow, store=flow_store)
heat_client.stacks.create.assert_called_once_with(**flow_store)
self.assertEqual(result['new_stack']['stack']['id'], stack_id)
def test_create_stack_with_error(self):
heat_client = mock.MagicMock(name='heat_client')
heat_client.stacks.create.side_effect = ValueError
stack_name = 'stack_name'
flow_store = {
'stack_name': stack_name,
'parameters': 'parameters',
'template': 'template',
'files': 'files'
}
flow = self._get_create_stack_flow(heat_client)
self.assertRaises(ValueError, engines.run, flow, store=flow_store)
def test_update_stack(self):
heat_client = mock.MagicMock(name='heat_client')
stack_id = 'stack_id'
flow_store = {
'stack_id': stack_id,
'parameters': 'parameters',
'template': 'template',
'files': 'files'
}
flow = self._get_update_stack_flow(heat_client)
expected_params = dict(flow_store)
del expected_params['stack_id']
engines.run(flow, store=flow_store)
heat_client.stacks.update.assert_called_once_with(stack_id,
**expected_params)
def test_update_stack_with_error(self):
heat_client = mock.MagicMock(name='heat_client')
heat_client.stacks.update.side_effect = ValueError
stack_id = 'stack_id'
flow_store = {
'stack_id': stack_id,
'parameters': 'parameters',
'template': 'template',
'files': 'files'
}
flow = self._get_update_stack_flow(heat_client)
self.assertRaises(ValueError, engines.run, flow, store=flow_store)
def test_delete_stack(self):
heat_client = mock.MagicMock(name='heat_client')
stack_id = 'stack_id'
flow_store = {'stack_id': stack_id}
flow = self._get_delete_stack_flow(heat_client)
engines.run(flow, store=flow_store)
heat_client.stacks.delete.assert_called_once_with(stack_id)
def test_delete_stack_with_error(self):
heat_client = mock.MagicMock(name='heat_client')
heat_client.stacks.delete.side_effect = ValueError
stack_id = 'stack_id'
flow_store = {'stack_id': stack_id}
flow = self._get_delete_stack_flow(heat_client)
self.assertRaises(ValueError, engines.run, flow, store=flow_store)

View File

@ -22,6 +22,7 @@ python-keystoneclient>=1.1.0 # Apache-2.0
python-kubernetes>=0.2 # Apache-2.0
six>=1.7.0 # MIT
SQLAlchemy>=0.9.7,<=0.9.99 # MIT
taskflow>=0.6 # Apache-2.0
WSME>=0.6 # MIT
docker-py>=0.5.1 # Apache-2.0
jsonpatch>=1.1 # Modified BSD http://tinyurl.com/kghfvjw