From 49db6006dd3da5ef0a35418f32bf7d1d1574e832 Mon Sep 17 00:00:00 2001 From: tengqm Date: Mon, 8 Aug 2016 03:54:13 -0400 Subject: [PATCH] Add SoftwareDeployment resource to orchestration This adds SoftwareDeployment resource type to orchestration service. Change-Id: I746839c7bc3d6f9c95f3a1d0fb0b93b10f662691 --- openstack/orchestration/v1/_proxy.py | 71 ++++++++++++++++++- .../orchestration/v1/software_deployment.py | 64 +++++++++++++++++ .../tests/unit/orchestration/v1/test_proxy.py | 23 ++++++ .../v1/test_software_deployment.py | 59 +++++++++++++++ 4 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 openstack/orchestration/v1/software_deployment.py create mode 100644 openstack/tests/unit/orchestration/v1/test_software_deployment.py diff --git a/openstack/orchestration/v1/_proxy.py b/openstack/orchestration/v1/_proxy.py index cebc4b505..aefd38e12 100644 --- a/openstack/orchestration/v1/_proxy.py +++ b/openstack/orchestration/v1/_proxy.py @@ -12,6 +12,7 @@ from openstack.orchestration.v1 import resource as _resource from openstack.orchestration.v1 import software_config as _sc +from openstack.orchestration.v1 import software_deployment as _sd from openstack.orchestration.v1 import stack as _stack from openstack import proxy2 @@ -154,7 +155,7 @@ class Proxy(proxy2.BaseProxy): return self._list(_sc.SoftwareConfig, paginated=True, **query) def get_software_config(self, software_config): - """Create a software config. + """Get details about a specific software config. :param software_config: The value can be the ID of a software config or a instace of @@ -180,3 +181,71 @@ class Proxy(proxy2.BaseProxy): """ self._delete(_sc.SoftwareConfig, software_config, ignore_missing=ignore_missing) + + def create_software_deployment(self, **attrs): + """Create a new software deployment from attributes + + :param dict attrs: Keyword arguments which will be used to create a + :class:`~openstack.orchestration.v1.software_deployment.SoftwareDeployment`, + comprised of the properties on the SoftwareDeployment class. + + :returns: The results of software deployment creation + :rtype: + :class:`~openstack.orchestration.v1.software_deployment.SoftwareDeployment` + """ + return self._create(_sd.SoftwareDeployment, **attrs) + + def software_deployments(self, **query): + """Returns a generator of software deployments + + :param dict query: Optional query parameters to be sent to limit the + software deployments returned. + :returns: A generator of software deployment objects. + :rtype: + :class:`~openstack.orchestration.v1.software_deployment.SoftwareDeployment` + """ + return self._list(_sd.SoftwareDeployment, paginated=False, **query) + + def get_software_deployment(self, software_deployment): + """Get details about a specific software deployment resource + + :param software_deployment: The value can be the ID of a software + deployment or an instace of + :class:`~openstack.orchestration.v1.software_deployment.SoftwareDeployment`, + + :returns: An object of type + :class:`~openstack.orchestration.v1.software_deployment.SoftwareDeployment` + """ + return self._get(_sd.SoftwareDeployment, software_deployment) + + def delete_software_deployment(self, software_deployment, + ignore_missing=True): + """Delete a software deployment + + :param software_deployment: The value can be either the ID of a + software deployment or an instance of + :class:`~openstack.orchestration.v1.software_deployment.SoftwareDeployment` + :param bool ignore_missing: When set to ``False`` + :class:`~openstack.exceptions.ResourceNotFound` will be + raised when the software deployment does not exist. + When set to ``True``, no exception will be set when + attempting to delete a nonexistent software deployment. + :returns: ``None`` + """ + self._delete(_sd.SoftwareDeployment, software_deployment, + ignore_missing=ignore_missing) + + def update_software_deployment(self, software_deployment, **attrs): + """Update a software deployment + + :param server: Either the ID of a software deployment or an instance of + :class:`~openstack.orchestration.v1.software_deployment.SoftwareDeployment` + :param dict attrs: The attributes to update on the software deployment + represented by ``software_deployment``. + + :returns: The updated software deployment + :rtype: + :class:`~openstack.orchestration.v1.software_deployment.SoftwareDeployment` + """ + return self._update(_sd.SoftwareDeployment, software_deployment, + **attrs) diff --git a/openstack/orchestration/v1/software_deployment.py b/openstack/orchestration/v1/software_deployment.py new file mode 100644 index 000000000..3fb22eafd --- /dev/null +++ b/openstack/orchestration/v1/software_deployment.py @@ -0,0 +1,64 @@ +# 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 openstack.orchestration import orchestration_service +from openstack import resource2 as resource + + +class SoftwareDeployment(resource.Resource): + resource_key = 'software_deployment' + resources_key = 'software_deployments' + base_path = '/software_deployments' + service = orchestration_service.OrchestrationService() + + # capabilities + allow_create = True + allow_list = True + allow_get = True + allow_delete = True + allow_update = True + + # Properties + #: The stack action that triggers this deployment resource. + action = resource.Body('action') + #: The UUID of the software config resource that runs when applying to the + #: server. + config_id = resource.Body('config_id') + #: A map containing the names and values of all inputs to the config. + input_values = resource.Body('input_values', type=dict) + #: A map containing the names and values from the deployment. + output_values = resource.Body('output_values', type=dict) + #: The UUID of the compute server to which the configuration applies. + server_id = resource.Body('server_id') + #: The ID of the authentication project which can also perform operations + #: on this deployment. + stack_user_project_id = resource.Body('stack_user_project_id') + #: Current status of the software deployment. + status = resource.Body('status') + #: Error description for the last status change. + status_reason = resource.Body('status_reason') + #: The date and time when the software deployment resource was created. + created_at = resource.Body('creation_time') + #: The date and time when the software deployment resource was created. + updated_at = resource.Body('updated_time') + + def create(self, session): + # This overrides the default behavior of resource creation because + # heat doesn't accept resource_key in its request. + return super(SoftwareDeployment, self).create( + session, prepend_key=False) + + def update(self, session): + # This overrides the default behavior of resource creation because + # heat doesn't accept resource_key in its request. + return super(SoftwareDeployment, self).update( + session, prepend_key=False) diff --git a/openstack/tests/unit/orchestration/v1/test_proxy.py b/openstack/tests/unit/orchestration/v1/test_proxy.py index 89f6e4011..eb43a4959 100644 --- a/openstack/tests/unit/orchestration/v1/test_proxy.py +++ b/openstack/tests/unit/orchestration/v1/test_proxy.py @@ -17,6 +17,7 @@ from openstack import exceptions from openstack.orchestration.v1 import _proxy from openstack.orchestration.v1 import resource from openstack.orchestration.v1 import software_config as sc +from openstack.orchestration.v1 import software_deployment as sd from openstack.orchestration.v1 import stack from openstack.tests.unit import test_proxy_base2 @@ -108,3 +109,25 @@ class TestOrchestrationProxy(test_proxy_base2.TestProxyBase): sc.SoftwareConfig, True) self.verify_delete(self.proxy.delete_software_config, sc.SoftwareConfig, False) + + def test_create_software_deployment(self): + self.verify_create(self.proxy.create_software_deployment, + sd.SoftwareDeployment) + + def test_software_deployments(self): + self.verify_list(self.proxy.software_deployments, + sd.SoftwareDeployment, paginated=False) + + def test_get_software_deployment(self): + self.verify_get(self.proxy.get_software_deployment, + sd.SoftwareDeployment) + + def test_update_software_deployment(self): + self.verify_update(self.proxy.update_software_deployment, + sd.SoftwareDeployment) + + def test_delete_software_deployment(self): + self.verify_delete(self.proxy.delete_software_deployment, + sd.SoftwareDeployment, True) + self.verify_delete(self.proxy.delete_software_deployment, + sd.SoftwareDeployment, False) diff --git a/openstack/tests/unit/orchestration/v1/test_software_deployment.py b/openstack/tests/unit/orchestration/v1/test_software_deployment.py new file mode 100644 index 000000000..cb03ac0fd --- /dev/null +++ b/openstack/tests/unit/orchestration/v1/test_software_deployment.py @@ -0,0 +1,59 @@ +# 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 testtools + +from openstack.orchestration.v1 import software_deployment + +FAKE = { + 'id': 'ce8ae86c-9810-4cb1-8888-7fb53bc523bf', + 'action': 'CREATE', + 'config_id': 'CONFIG ID', + 'creation_time': '2015-03-09T12:15:57', + 'server_id': 'FAKE_SERVER', + 'stack_user_project_id': 'ANOTHER PROJECT', + 'status': 'IN_PROGRESS', + 'status_reason': 'Why are we here?', + 'input_values': {'foo': 'bar'}, + 'output_values': {'baz': 'zoo'}, + 'updated_time': '2015-03-09T12:15:57', +} + + +class TestSoftwareDeployment(testtools.TestCase): + + def test_basic(self): + sot = software_deployment.SoftwareDeployment() + self.assertEqual('software_deployment', sot.resource_key) + self.assertEqual('software_deployments', sot.resources_key) + self.assertEqual('/software_deployments', sot.base_path) + self.assertEqual('orchestration', sot.service.service_type) + self.assertTrue(sot.allow_create) + self.assertTrue(sot.allow_get) + self.assertTrue(sot.allow_update) + self.assertTrue(sot.allow_delete) + self.assertTrue(sot.allow_list) + + def test_make_it(self): + sot = software_deployment.SoftwareDeployment(**FAKE) + self.assertEqual(FAKE['id'], sot.id) + self.assertEqual(FAKE['action'], sot.action) + self.assertEqual(FAKE['config_id'], sot.config_id) + self.assertEqual(FAKE['creation_time'], sot.created_at) + self.assertEqual(FAKE['server_id'], sot.server_id) + self.assertEqual(FAKE['stack_user_project_id'], + sot.stack_user_project_id) + self.assertEqual(FAKE['input_values'], sot.input_values) + self.assertEqual(FAKE['output_values'], sot.output_values) + self.assertEqual(FAKE['status'], sot.status) + self.assertEqual(FAKE['status_reason'], sot.status_reason) + self.assertEqual(FAKE['updated_time'], sot.updated_at)