Handle deletion of errored instances

When a new instance is created and the state is in error,
the event "compute.instance.create.end" is never sent.

However, when we delete an errored instance the deletion event is
sent, but the entity doesn't exists in te database.

This fix avoid false positives in the critical queue.

Change-Id: I70a4ae92bda37909cfd6021e0311a69b7ad189bc
This commit is contained in:
Frédéric Guillot 2017-01-18 16:29:20 -05:00
parent f66cc7ef44
commit 4fbb9d7b56
2 changed files with 46 additions and 1 deletions

View File

@ -12,7 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from oslo_log import log as logging
from almanach.collector.handlers import base_handler
from almanach.core import exception
LOG = logging.getLogger(__name__)
class InstanceHandler(base_handler.BaseHandler):
@ -45,7 +50,15 @@ class InstanceHandler(base_handler.BaseHandler):
def _on_instance_deleted(self, notification):
date = notification.payload.get("terminated_at")
instance_id = notification.payload.get("instance_id")
self.controller.delete_instance(instance_id, date)
try:
self.controller.delete_instance(instance_id, date)
except exception.EntityNotFoundException as e:
if notification.payload.get('state') == 'error':
LOG.info('Instance deletion event ignored because instance %s was badly created',
instance_id)
else:
raise e
def _on_instance_resized(self, notification):
date = notification.context.get("timestamp")

View File

@ -15,6 +15,7 @@
import mock
from almanach.collector.handlers import instance_handler
from almanach.core import exception
from almanach.tests.unit import base
from almanach.tests.unit.builders import notification as builder
@ -59,6 +60,37 @@ class TestInstanceHandler(base.BaseTestCase):
notification.payload['terminated_at']
)
def test_instance_deleted_but_never_created(self):
notification = builder.InstanceNotificationBuilder() \
.with_event_type('compute.instance.delete.end') \
.with_payload_value('terminated_at', 'a_date') \
.build()
self.controller.delete_instance.side_effect = exception.EntityNotFoundException('Instance not found')
self.assertRaises(exception.EntityNotFoundException,
self.instance_handler.handle_events, notification)
self.controller.delete_instance.assert_called_once_with(
notification.payload['instance_id'],
notification.payload['terminated_at']
)
def test_instance_in_error_deleted(self):
notification = builder.InstanceNotificationBuilder() \
.with_event_type('compute.instance.delete.end') \
.with_payload_value('terminated_at', 'a_date') \
.with_payload_value('state', 'error') \
.build()
self.controller.delete_instance.side_effect = exception.EntityNotFoundException('Instance not found')
self.instance_handler.handle_events(notification)
self.controller.delete_instance.assert_called_once_with(
notification.payload['instance_id'],
notification.payload['terminated_at']
)
def test_instance_resized(self):
notification = builder.InstanceNotificationBuilder() \
.with_event_type('compute.instance.resize.confirm.end') \