From d8be4d0c122a2dddb4c530379be5c5a6175bcd06 Mon Sep 17 00:00:00 2001 From: Zane Bitter Date: Thu, 17 Jan 2013 11:10:15 +0100 Subject: [PATCH] RPC API: Add a ResourceNotAvailable exception Change-Id: I7f535b7823288b74cbe27f43b645a8d0f3180905 Signed-off-by: Zane Bitter --- heat/api/aws/exception.py | 1 + heat/api/openstack/v1/util.py | 1 + heat/common/exception.py | 4 ++++ heat/engine/resource.py | 2 +- heat/engine/service.py | 2 +- heat/engine/timestamp.py | 4 +++- heat/tests/test_api_openstack_v1.py | 26 ++++++++++++++++++++++++++ 7 files changed, 37 insertions(+), 3 deletions(-) diff --git a/heat/api/aws/exception.py b/heat/api/aws/exception.py index 5ccfa23962..117e468eeb 100644 --- a/heat/api/aws/exception.py +++ b/heat/api/aws/exception.py @@ -249,6 +249,7 @@ def map_remote_error(ex): 'InvalidTenant', 'StackNotFound', 'ResourceNotFound', + 'ResourceNotAvailable', 'StackExists', ) diff --git a/heat/api/openstack/v1/util.py b/heat/api/openstack/v1/util.py index 1cd4b7ada7..a7e7ae0c70 100644 --- a/heat/api/openstack/v1/util.py +++ b/heat/api/openstack/v1/util.py @@ -93,6 +93,7 @@ def remote_error(ex, force_exists=False): 'ValueError': client_error, 'StackNotFound': exc.HTTPNotFound, 'ResourceNotFound': exc.HTTPNotFound, + 'ResourceNotAvailable': exc.HTTPNotFound, 'InvalidTenant': exc.HTTPForbidden, 'StackExists': exc.HTTPConflict, } diff --git a/heat/common/exception.py b/heat/common/exception.py index 9136e52940..dd3cb0d3fc 100644 --- a/heat/common/exception.py +++ b/heat/common/exception.py @@ -220,3 +220,7 @@ class StackExists(OpenstackException): class ResourceNotFound(OpenstackException): message = _("The Resource (%(resource_name)s) could not be found " "in Stack %(stack_name)s.") + + +class ResourceNotAvailable(OpenstackException): + message = _("The Resource (%(resource_name)s) is not available.") diff --git a/heat/engine/resource.py b/heat/engine/resource.py index 8ca3f30b43..aee065f436 100644 --- a/heat/engine/resource.py +++ b/heat/engine/resource.py @@ -70,7 +70,7 @@ class Metadata(object): def __set__(self, resource, metadata): '''Update the metadata for the owning resource.''' if resource.id is None: - raise AttributeError("Resource has not yet been created") + raise exception.ResourceNotAvailable(resource_name=resource.name) rs = db_api.resource_get(resource.stack.context, resource.id) rs.update_and_save({'rsrc_metadata': metadata}) diff --git a/heat/engine/service.py b/heat/engine/service.py index 6ed9371eb3..34fb17422c 100644 --- a/heat/engine/service.py +++ b/heat/engine/service.py @@ -381,7 +381,7 @@ class EngineService(service.Service): resource = stack[resource_name] if resource.id is None: - raise AttributeError('Resource not created') + raise exception.ResourceNotAvailable(resource_name=resource_name) return api.format_stack_resource(stack[resource_name]) diff --git a/heat/engine/timestamp.py b/heat/engine/timestamp.py index c271c5c10d..c318cbefff 100644 --- a/heat/engine/timestamp.py +++ b/heat/engine/timestamp.py @@ -13,6 +13,8 @@ # License for the specific language governing permissions and limitations # under the License. +from heat.common import exception + class Timestamp(object): ''' @@ -42,6 +44,6 @@ class Timestamp(object): def __set__(self, obj, timestamp): '''Update the timestamp for the given object.''' if obj.id is None: - raise AttributeError("%s has not yet been created" % str(obj)) + raise exception.ResourceNotAvailable(resource_name=obj.name) o = self.db_fetch(obj.context, obj.id) o.update_and_save({self.attribute: timestamp}) diff --git a/heat/tests/test_api_openstack_v1.py b/heat/tests/test_api_openstack_v1.py index eae72227c4..436abd04c3 100644 --- a/heat/tests/test_api_openstack_v1.py +++ b/heat/tests/test_api_openstack_v1.py @@ -1073,6 +1073,32 @@ class ResourceControllerTest(ControllerTest, unittest.TestCase): resource_name=res_name) self.m.VerifyAll() + def test_show_uncreated_resource(self): + res_name = 'WikiDatabase' + stack_identity = identifier.HeatIdentifier(self.tenant, + 'wordpress', '1') + res_identity = identifier.ResourceIdentifier(resource_name=res_name, + **stack_identity) + + req = self._get(res_identity._tenant_path()) + + self.m.StubOutWithMock(rpc, 'call') + rpc.call(req.context, self.topic, + {'method': 'describe_stack_resource', + 'args': {'stack_identity': stack_identity, + 'resource_name': res_name}, + 'version': self.api_version}, + None).AndRaise(rpc_common.RemoteError("ResourceNotAvailable")) + self.m.ReplayAll() + + self.assertRaises(webob.exc.HTTPNotFound, + self.controller.show, + req, tenant_id=self.tenant, + stack_name=stack_identity.stack_name, + stack_id=stack_identity.stack_id, + resource_name=res_name) + self.m.VerifyAll() + def test_metadata_show(self): res_name = 'WikiDatabase' stack_identity = identifier.HeatIdentifier(self.tenant,