'Returns a list of servers, based on any search options specified.'

def _get_servers(self, req, is_detail):

    search_opts = {}
    search_opts.update(req.GET)
    context = req.environ['nova.context']
    remove_invalid_options(context, search_opts, self._get_server_search_options(req))
    for search_opt in search_opts:
        if ((search_opt in schema_servers.JOINED_TABLE_QUERY_PARAMS_SERVERS.keys()) or search_opt.startswith('_')):
            msg = (_('Invalid    filter    field:    %s.') % search_opt)
            raise exc.HTTPBadRequest(explanation=msg)
    search_opts.pop('status', None)
    if ('status' in req.GET.keys()):
        statuses = req.GET.getall('status')
        states = common.task_and_vm_state_from_status(statuses)
        (vm_state, task_state) = states
        if ((not vm_state) and (not task_state)):
            if api_version_request.is_supported(req, min_version='2.38'):
                msg = _('Invalid    status    value')
                raise exc.HTTPBadRequest(explanation=msg)
            return {'servers': []}
        search_opts['vm_state'] = vm_state
        if ('default' not in task_state):
            search_opts['task_state'] = task_state
    if ('changes-since' in search_opts):
        search_opts['changes-since'] = timeutils.parse_isotime(search_opts['changes-since'])
    if ('deleted' not in search_opts):
        if ('changes-since' not in search_opts):
            search_opts['deleted'] = False
    else:
        search_opts['deleted'] = strutils.bool_from_string(search_opts['deleted'], default=False)
    if (search_opts.get('vm_state') == ['deleted']):
        if context.is_admin:
            search_opts['deleted'] = True
        else:
            msg = _('Only    administrators    may    list    deleted    instances')
            raise exc.HTTPForbidden(explanation=msg)
    if api_version_request.is_supported(req, min_version='2.26'):
        for tag_filter in TAG_SEARCH_FILTERS:
            if (tag_filter in search_opts):
                search_opts[tag_filter] = search_opts[tag_filter].split(',')
    all_tenants = common.is_all_tenants(search_opts)
    search_opts.pop('all_tenants', None)
    elevated = None
    if all_tenants:
        if is_detail:
            context.can((server_policies.SERVERS % 'detail:get_all_tenants'))
        else:
            context.can((server_policies.SERVERS % 'index:get_all_tenants'))
        elevated = context.elevated()
    else:
        search_opts.pop('tenant_id', None)
        if context.project_id:
            search_opts['project_id'] = context.project_id
        else:
            search_opts['user_id'] = context.user_id
    (limit, marker) = common.get_limit_and_marker(req)
    (sort_keys, sort_dirs) = common.get_sort_params(req.params)
    (sort_keys, sort_dirs) = remove_invalid_sort_keys(context, sort_keys, sort_dirs, schema_servers.SERVER_LIST_IGNORE_SORT_KEY, ('host', 'node'))
    expected_attrs = []
    if is_detail:
        expected_attrs.append('services')
        if api_version_request.is_supported(req, '2.26'):
            expected_attrs.append('tags')
        expected_attrs = self._view_builder.get_show_expected_attrs(expected_attrs)
    try:
        instance_list = self.compute_api.get_all((elevated or context), search_opts=search_opts, limit=limit, marker=marker, expected_attrs=expected_attrs, sort_keys=sort_keys, sort_dirs=sort_dirs)
    except exception.MarkerNotFound:
        msg = (_('marker    [%s]    not    found') % marker)
        raise exc.HTTPBadRequest(explanation=msg)
    except exception.FlavorNotFound:
        LOG.debug("Flavor    '%s'    could    not    be    found    ", search_opts['flavor'])
        instance_list = objects.InstanceList()
    if is_detail:
        instance_list._context = context
        instance_list.fill_faults()
        response = self._view_builder.detail(req, instance_list)
    else:
        response = self._view_builder.index(req, instance_list)
    req.cache_db_instances(instance_list)
    return response
