From f24eaf571200a906a29a956e9a9a62fb3172d2fb Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Tue, 5 Apr 2016 17:06:35 +0300 Subject: [PATCH] Introduce Flow DeployDriver Partially implements blueprint: pluggable-do-actions Change-Id: I1bb6a5e904741a8689d08e1939a3e098864a5d03 --- bareon/actions/__init__.py | 0 bareon/actions/base.py | 41 ++++++++++++++++++++++++ bareon/drivers/data/base.py | 3 ++ bareon/drivers/deploy/flow.py | 37 ++++++++++++++++++++++ bareon/tests/test_flow_driver.py | 53 ++++++++++++++++++++++++++++++++ setup.cfg | 1 + 6 files changed, 135 insertions(+) create mode 100644 bareon/actions/__init__.py create mode 100644 bareon/actions/base.py create mode 100644 bareon/drivers/deploy/flow.py create mode 100644 bareon/tests/test_flow_driver.py diff --git a/bareon/actions/__init__.py b/bareon/actions/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/bareon/actions/base.py b/bareon/actions/base.py new file mode 100644 index 0000000..f7497d0 --- /dev/null +++ b/bareon/actions/base.py @@ -0,0 +1,41 @@ +# Copyright 2016 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 abc + +import six + + +@six.add_metaclass(abc.ABCMeta) +class BaseAction(object): + """BaseAction + + + Validates data and executes the action + """ + + def __init__(self, driver): + self.driver = driver + + @abc.abstractmethod + def validate(self): + """Validate + + Validates that data/objects of data driver satisfied all necessary + requirements + """ + + @abc.abstractmethod + def execute(self): + """Executes the action""" diff --git a/bareon/drivers/data/base.py b/bareon/drivers/data/base.py index f77561c..7084f07 100644 --- a/bareon/drivers/data/base.py +++ b/bareon/drivers/data/base.py @@ -28,6 +28,9 @@ class BaseDataDriver(object): def __init__(self, data): self.data = copy.deepcopy(data) + self.flow = [] + if self.data and self.data.get('flow'): + self.flow = self.data.get('flow', []) @six.add_metaclass(abc.ABCMeta) diff --git a/bareon/drivers/deploy/flow.py b/bareon/drivers/deploy/flow.py new file mode 100644 index 0000000..d9dda43 --- /dev/null +++ b/bareon/drivers/deploy/flow.py @@ -0,0 +1,37 @@ +# +# Copyright 2016 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 bareon.drivers.deploy import base +from bareon.drivers.deploy import mixins +from bareon.openstack.common import log as logging + +import stevedore.named + +LOG = logging.getLogger(__name__) + + +class Flow(base.SimpleDeployDriver, mixins.MountableMixin): + + def __init__(self, data_driver): + super(Flow, self).__init__(data_driver) + self.ext_mgr = stevedore.named.NamedExtensionManager( + 'bareon.do_actions', names=self.driver.flow, + invoke_on_load=True, invoke_args=(self.driver, ), + name_order=True) + + def execute_flow(self): + for action in self.ext_mgr: + action.validate() + action.execute() diff --git a/bareon/tests/test_flow_driver.py b/bareon/tests/test_flow_driver.py new file mode 100644 index 0000000..df8f240 --- /dev/null +++ b/bareon/tests/test_flow_driver.py @@ -0,0 +1,53 @@ +# Copyright 2016 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 six +import unittest2 + +from bareon.actions import base as base_action +from bareon.drivers.deploy import flow + +import stevedore + +if six.PY2: + import mock +elif six.PY3: + import unittest.mock as mock + + +class TestFlowDriver(unittest2.TestCase): + + @mock.patch.object(flow.Flow, '__init__', + return_value=None) + def test_execute_flow(self, mock_init): + fake_ext = mock.Mock(spec=base_action.BaseAction) + fake_ext.name = 'foo' + self.drv = flow.Flow('fake_data_driver') + self.drv.ext_mgr = stevedore.NamedExtensionManager.make_test_instance( + [fake_ext], namespace='TESTING') + self.drv.execute_flow() + self.assertEqual(['foo'], self.drv.ext_mgr.names()) + fake_ext.validate.assert_called_once_with() + fake_ext.execute.assert_called_once_with() + + @mock.patch('stevedore.named.NamedExtensionManager') + def test_init(self, mock_stevedore): + fake_data_driver = mock.Mock() + expected_flow = ['action1', 'action3'] + fake_data_driver.flow = expected_flow + self.drv = flow.Flow(fake_data_driver) + mock_stevedore.assert_called_once_with( + 'bareon.do_actions', names=expected_flow, + invoke_on_load=True, invoke_args=(fake_data_driver,), + name_order=True) diff --git a/setup.cfg b/setup.cfg index a341719..293fe47 100644 --- a/setup.cfg +++ b/setup.cfg @@ -37,6 +37,7 @@ bareon.drivers.deploy = nailgun = bareon.drivers.deploy.nailgun:Manager swift = bareon.drivers.deploy.swift:Swift rsync = bareon.drivers.deploy.rsync:Rsync + flow = bareon.drivers.deploy.flow:Flow oslo.config.opts = bareon.manager = bareon.manager:list_opts