Add a handle_delete method to SwiftSignalHandle
Swift containers and objects that were created by a particular SwiftSignalHandle should be deleted when the resource is deleted. Change-Id: Id9df03e139ca0632996f4f66c5f39e27bb04d1fb Closes-Bug: #1379040
This commit is contained in:
parent
6bef85931e
commit
d8dc9a8b9e
@ -105,6 +105,28 @@ class SwiftSignalHandle(resource.Resource):
|
||||
elif key == self.CURL_CLI:
|
||||
return ('curl -i -X PUT \'%s\'' % self.data().get('endpoint'))
|
||||
|
||||
def handle_delete(self):
|
||||
sc = self.client_plugin('swift').client()
|
||||
|
||||
# Delete all versioned objects
|
||||
while True:
|
||||
try:
|
||||
sc.delete_object(self.stack.id, self.physical_resource_name())
|
||||
except Exception as exc:
|
||||
if sc.is_not_found(exc):
|
||||
break
|
||||
raise
|
||||
|
||||
# Delete the container if it is empty
|
||||
try:
|
||||
sc.delete_container(self.stack.id)
|
||||
except Exception as exc:
|
||||
if sc.is_not_found(exc) or sc.is_conflict(exc):
|
||||
pass
|
||||
raise
|
||||
|
||||
self.data_delete('endpoint')
|
||||
|
||||
|
||||
class SwiftSignal(resource.Resource):
|
||||
|
||||
|
@ -19,8 +19,10 @@ import uuid
|
||||
import mock
|
||||
import six
|
||||
from swiftclient import client as swiftclient_client
|
||||
from swiftclient import exceptions as swiftclient_exceptions
|
||||
from testtools.matchers import MatchesRegex
|
||||
|
||||
from heat.common import exception
|
||||
from heat.common import template_format
|
||||
from heat.engine.clients.os import swift
|
||||
from heat.engine import environment
|
||||
@ -150,6 +152,110 @@ class SwiftSignalHandleTest(HeatTestCase):
|
||||
self.assertEqual({'headers': header},
|
||||
mock_swift_object.put_container.call_args[1])
|
||||
|
||||
@mock.patch.object(swift.SwiftClientPlugin, '_create')
|
||||
@mock.patch.object(resource.Resource, 'physical_resource_name')
|
||||
def test_delete_empty_container(self, mock_name, mock_swift):
|
||||
st = create_stack(swiftsignalhandle_template)
|
||||
handle = st['test_wait_condition_handle']
|
||||
|
||||
mock_swift_object = mock.Mock()
|
||||
mock_swift.return_value = mock_swift_object
|
||||
mock_swift_object.head_account.return_value = {
|
||||
'x-account-meta-temp-url-key': "1234"
|
||||
}
|
||||
mock_swift_object.url = "http://fake-host.com:8080/v1/AUTH_1234"
|
||||
obj_name = "%s-%s-abcdefghijkl" % (st.name, handle.name)
|
||||
mock_name.return_value = obj_name
|
||||
st.create()
|
||||
|
||||
exc = swiftclient_exceptions.ClientException("Object DELETE failed",
|
||||
http_status=404)
|
||||
mock_swift_object.delete_object.side_effect = (None, None, None, exc)
|
||||
mock_swift_object.delete_container.return_value = None
|
||||
st.delete()
|
||||
self.assertEqual(4, mock_swift_object.delete_object.call_count)
|
||||
|
||||
@mock.patch.object(swift.SwiftClientPlugin, '_create')
|
||||
@mock.patch.object(resource.Resource, 'physical_resource_name')
|
||||
def test_delete_object_error(self, mock_name, mock_swift):
|
||||
st = create_stack(swiftsignalhandle_template)
|
||||
handle = st['test_wait_condition_handle']
|
||||
|
||||
mock_swift_object = mock.Mock()
|
||||
mock_swift.return_value = mock_swift_object
|
||||
mock_swift_object.head_account.return_value = {
|
||||
'x-account-meta-temp-url-key': "1234"
|
||||
}
|
||||
mock_swift_object.url = "http://fake-host.com:8080/v1/AUTH_1234"
|
||||
obj_name = "%s-%s-abcdefghijkl" % (st.name, handle.name)
|
||||
mock_name.return_value = obj_name
|
||||
st.create()
|
||||
|
||||
exc = swiftclient_exceptions.ClientException("Overlimit",
|
||||
http_status=413)
|
||||
mock_swift_object.delete_object.side_effect = (None, None, None, exc)
|
||||
mock_swift_object.is_not_found.return_value = False
|
||||
rsrc = st.resources['test_wait_condition_handle']
|
||||
exc = self.assertRaises(exception.ResourceFailure,
|
||||
scheduler.TaskRunner(rsrc.delete))
|
||||
self.assertEqual('ClientException: Overlimit: 413', six.text_type(exc))
|
||||
|
||||
@mock.patch.object(swift.SwiftClientPlugin, '_create')
|
||||
@mock.patch.object(resource.Resource, 'physical_resource_name')
|
||||
def test_delete_container_error(self, mock_name, mock_swift):
|
||||
st = create_stack(swiftsignalhandle_template)
|
||||
handle = st['test_wait_condition_handle']
|
||||
|
||||
mock_swift_object = mock.Mock()
|
||||
mock_swift.return_value = mock_swift_object
|
||||
mock_swift_object.head_account.return_value = {
|
||||
'x-account-meta-temp-url-key': "1234"
|
||||
}
|
||||
mock_swift_object.url = "http://fake-host.com:8080/v1/AUTH_1234"
|
||||
obj_name = "%s-%s-abcdefghijkl" % (st.name, handle.name)
|
||||
mock_name.return_value = obj_name
|
||||
st.create()
|
||||
|
||||
exc = swiftclient_exceptions.ClientException("Object DELETE failed",
|
||||
http_status=404)
|
||||
mock_swift_object.delete_object.side_effect = (None, None, None, exc)
|
||||
mock_swift_object.is_not_found.side_effect = (True, False)
|
||||
mock_swift_object.is_conflict.return_value = False
|
||||
|
||||
exc = swiftclient_exceptions.ClientException("Overlimit",
|
||||
http_status=413)
|
||||
mock_swift_object.delete_container.side_effect = (exc,)
|
||||
|
||||
rsrc = st.resources['test_wait_condition_handle']
|
||||
exc = self.assertRaises(exception.ResourceFailure,
|
||||
scheduler.TaskRunner(rsrc.delete))
|
||||
self.assertEqual('ClientException: Overlimit: 413', six.text_type(exc))
|
||||
|
||||
@mock.patch.object(swift.SwiftClientPlugin, '_create')
|
||||
@mock.patch.object(resource.Resource, 'physical_resource_name')
|
||||
def test_delete_non_empty_container(self, mock_name, mock_swift):
|
||||
st = create_stack(swiftsignalhandle_template)
|
||||
handle = st['test_wait_condition_handle']
|
||||
|
||||
mock_swift_object = mock.Mock()
|
||||
mock_swift.return_value = mock_swift_object
|
||||
mock_swift_object.head_account.return_value = {
|
||||
'x-account-meta-temp-url-key': "1234"
|
||||
}
|
||||
mock_swift_object.url = "http://fake-host.com:8080/v1/AUTH_1234"
|
||||
obj_name = "%s-%s-abcdefghijkl" % (st.name, handle.name)
|
||||
mock_name.return_value = obj_name
|
||||
st.create()
|
||||
|
||||
exc = swiftclient_exceptions.ClientException("Object DELETE failed",
|
||||
http_status=404)
|
||||
mock_swift_object.delete_object.side_effect = (None, None, None, exc)
|
||||
exc = swiftclient_exceptions.ClientException("Container DELETE failed",
|
||||
http_status=409)
|
||||
mock_swift_object.delete_container.return_value = exc
|
||||
st.delete()
|
||||
self.assertEqual(4, mock_swift_object.delete_object.call_count)
|
||||
|
||||
@mock.patch.object(swift.SwiftClientPlugin, '_create')
|
||||
def test_handle_update(self, mock_swift):
|
||||
st = create_stack(swiftsignalhandle_template)
|
||||
|
Loading…
Reference in New Issue
Block a user