'Rescue an instance.'

@extensions.expected_errors((400, 404, 409, 501))
@wsgi.action('rescue')
@validation.schema(rescue.rescue)
def _rescue(self, req, id, body):

    context = req.environ['nova.context']
    if (body['rescue'] and ('adminPass' in body['rescue'])):
        password = body['rescue']['adminPass']
    else:
        password = utils.generate_password()
    instance = common.get_instance(self.compute_api, context, id)
    context.can(rescue_policies.BASE_POLICY_NAME, target={'user_id': instance.user_id, 'project_id': instance.project_id})
    rescue_image_ref = None
    if body['rescue']:
        rescue_image_ref = body['rescue'].get('rescue_image_ref')
    try:
        self.compute_api.rescue(context, instance, rescue_password=password, rescue_image_ref=rescue_image_ref)
    except exception.InstanceUnknownCell as e:
        raise exc.HTTPNotFound(explanation=e.format_message())
    except exception.InstanceIsLocked as e:
        raise exc.HTTPConflict(explanation=e.format_message())
    except exception.InstanceInvalidState as state_error:
        common.raise_http_conflict_for_instance_invalid_state(state_error, 'rescue', id)
    except exception.InvalidVolume as volume_error:
        raise exc.HTTPConflict(explanation=volume_error.format_message())
    except exception.InstanceNotRescuable as non_rescuable:
        raise exc.HTTPBadRequest(explanation=non_rescuable.format_message())
    if CONF.api.enable_instance_password:
        return {'adminPass': password}
    else:
        return {}
