Gracefully fail to delete nonempty S3 Bucket
The AWS::S3::Bucket resource is susceptible to bug #1406263 as it is backed by the same Swift container - on deleting non empty container it produces incomprehensible truncated message. This patch uses the same logic as it is now in OS::Swift::Container resource, making the reason of failure clear. The error message is made to resemble the error produced by this resource on real AWS in the same usage scenario. Change-Id: Ib67c55f010613c8edb913bb264d3cc4a7315d847 Related-Bug: #1406263
This commit is contained in:
parent
e930bc2887
commit
3eda662713
@ -14,6 +14,7 @@ import six
|
||||
|
||||
from six.moves.urllib import parse as urlparse
|
||||
|
||||
from heat.common import exception
|
||||
from heat.common.i18n import _
|
||||
from heat.engine import attributes
|
||||
from heat.engine import constraints
|
||||
@ -153,6 +154,13 @@ class S3Bucket(resource.Resource):
|
||||
try:
|
||||
self.swift().delete_container(self.resource_id)
|
||||
except Exception as ex:
|
||||
if self.client_plugin().is_conflict(ex):
|
||||
container, objects = self.swift().get_container(
|
||||
self.resource_id)
|
||||
if objects:
|
||||
msg = _("The bucket you tried to delete is not empty (%s)."
|
||||
) % self.resource_id
|
||||
raise exception.ResourceActionNotSupported(action=msg)
|
||||
self.client_plugin().ignore_not_found(ex)
|
||||
|
||||
def FnGetRefId(self):
|
||||
|
@ -11,7 +11,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import six
|
||||
import swiftclient.client as sc
|
||||
|
||||
from heat.common import exception
|
||||
@ -67,6 +67,7 @@ class s3Test(common.HeatTestCase):
|
||||
super(s3Test, self).setUp()
|
||||
self.m.CreateMock(sc.Connection)
|
||||
self.m.StubOutWithMock(sc.Connection, 'put_container')
|
||||
self.m.StubOutWithMock(sc.Connection, 'get_container')
|
||||
self.m.StubOutWithMock(sc.Connection, 'delete_container')
|
||||
self.m.StubOutWithMock(sc.Connection, 'get_auth')
|
||||
self.stub_keystoneclient()
|
||||
@ -233,6 +234,48 @@ class s3Test(common.HeatTestCase):
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_delete_conflict_not_empty(self):
|
||||
container_name = utils.PhysName('test_stack', 'test_resource')
|
||||
sc.Connection.put_container(
|
||||
container_name,
|
||||
{'X-Container-Write': 'test_tenant:test_username',
|
||||
'X-Container-Read': 'test_tenant:test_username'}).AndReturn(None)
|
||||
sc.Connection.delete_container(container_name).AndRaise(
|
||||
sc.ClientException('Not empty', http_status=409))
|
||||
sc.Connection.get_container(container_name).AndReturn(
|
||||
({'name': container_name}, [{'name': 'test_object'}]))
|
||||
self.m.ReplayAll()
|
||||
t = template_format.parse(swift_template)
|
||||
stack = utils.parse_stack(t)
|
||||
rsrc = self.create_resource(t, stack, 'S3Bucket')
|
||||
deleter = scheduler.TaskRunner(rsrc.delete)
|
||||
ex = self.assertRaises(exception.ResourceFailure, deleter)
|
||||
self.assertIn("ResourceActionNotSupported: The bucket "
|
||||
"you tried to delete is not empty", six.text_type(ex))
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_delete_conflict_empty(self):
|
||||
container_name = utils.PhysName('test_stack', 'test_resource')
|
||||
sc.Connection.put_container(
|
||||
container_name,
|
||||
{'X-Container-Write': 'test_tenant:test_username',
|
||||
'X-Container-Read': 'test_tenant:test_username'}).AndReturn(None)
|
||||
sc.Connection.delete_container(container_name).AndRaise(
|
||||
sc.ClientException('Conflict', http_status=409))
|
||||
sc.Connection.get_container(container_name).AndReturn(
|
||||
({'name': container_name}, []))
|
||||
|
||||
self.m.ReplayAll()
|
||||
t = template_format.parse(swift_template)
|
||||
stack = utils.parse_stack(t)
|
||||
rsrc = self.create_resource(t, stack, 'S3Bucket')
|
||||
deleter = scheduler.TaskRunner(rsrc.delete)
|
||||
ex = self.assertRaises(exception.ResourceFailure, deleter)
|
||||
self.assertIn("Conflict", six.text_type(ex))
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_delete_retain(self):
|
||||
# first run, with retain policy
|
||||
sc.Connection.put_container(
|
||||
|
Loading…
Reference in New Issue
Block a user