Skip to content

Commit

Permalink
Create SystemIndexSearcherWrapper
Browse files Browse the repository at this point in the history
Signed-off-by: Craig Perkins <cwperx@amazon.com>
  • Loading branch information
cwperks committed Nov 21, 2024
1 parent 0b11785 commit 83896cd
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

package org.opensearch.plugin.systemindex;

import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.FilterDirectoryReader;
import org.apache.lucene.index.FilterLeafReader;
import org.apache.lucene.index.LeafReader;
import org.apache.lucene.util.Bits;

import java.io.IOException;

//copied from org.apache.lucene.index.AllDeletedFilterReader
//https://github.com/apache/lucene-solr/blob/1d85cd783863f75cea133fb9c452302214165a4d/lucene/test-framework/src/java/org/apache/lucene/index/AllDeletedFilterReader.java

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

class EmptyFilterLeafReader extends FilterLeafReader {

final Bits liveDocs;

public EmptyFilterLeafReader(LeafReader in) {
super(in);
liveDocs = new Bits.MatchNoBits(in.maxDoc());
assert maxDoc() == 0 || hasDeletions();
}

@Override
public Bits getLiveDocs() {
return liveDocs;
}

@Override
public int numDocs() {
return 0;
}

@Override
public CacheHelper getCoreCacheHelper() {
return in.getCoreCacheHelper();
}

@Override
public CacheHelper getReaderCacheHelper() {
return null;
}

private static class EmptySubReaderWrapper extends FilterDirectoryReader.SubReaderWrapper {

@Override
public LeafReader wrap(final LeafReader reader) {
return new EmptyFilterLeafReader(reader);
}

}

static class EmptyDirectoryReader extends FilterDirectoryReader {

public EmptyDirectoryReader(final DirectoryReader in) throws IOException {
super(in, new EmptySubReaderWrapper());
}

@Override
protected DirectoryReader doWrapDirectoryReader(final DirectoryReader in) throws IOException {
return new EmptyDirectoryReader(in);
}

@Override
public CacheHelper getReaderCacheHelper() {
return in.getReaderCacheHelper();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.opensearch.core.xcontent.NamedXContentRegistry;
import org.opensearch.env.Environment;
import org.opensearch.env.NodeEnvironment;
import org.opensearch.index.IndexModule;
import org.opensearch.index.filter.ClusterInfoHolder;
import org.opensearch.index.filter.IndexResolverReplacer;
import org.opensearch.index.filter.SystemIndexFilter;
Expand Down Expand Up @@ -110,6 +111,16 @@ public List<ActionFilter> getActionFilters() {
return filters;
}

@Override
public void onIndexModule(IndexModule indexModule) {
// called for every index!
boolean isEnabled = settings.getAsBoolean(SYSTEM_INDEX_PROTECTION_ENABLED_KEY, false);

if (isEnabled) {
indexModule.setReaderWrapper(indexService -> new SystemIndexSearcherWrapper(indexService, settings));
}
}

@Override
public Collection<Class<? extends LifecycleComponent>> getGuiceServiceClasses() {
final List<Class<? extends LifecycleComponent>> services = new ArrayList<>(1);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

package org.opensearch.plugin.systemindex;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.lucene.index.DirectoryReader;
import org.opensearch.common.CheckedFunction;
import org.opensearch.common.settings.Settings;
import org.opensearch.common.util.concurrent.ThreadContext;
import org.opensearch.core.index.Index;
import org.opensearch.index.IndexService;
import org.opensearch.indices.SystemIndexRegistry;

import java.io.IOException;
import java.util.Set;

import static org.opensearch.plugin.systemindex.SystemIndexProtectionPlugin.SYSTEM_INDEX_PROTECTION_ENABLED_KEY;

public class SystemIndexSearcherWrapper implements CheckedFunction<DirectoryReader, DirectoryReader, IOException> {

protected final Logger log = LogManager.getLogger(this.getClass());
protected final ThreadContext threadContext;
protected final Index index;
private final Boolean systemIndexEnabled;

// constructor is called per index, so avoid costly operations here
public SystemIndexSearcherWrapper(final IndexService indexService, final Settings settings) {
index = indexService.index();
threadContext = indexService.getThreadPool().getThreadContext();

this.systemIndexEnabled = settings.getAsBoolean(SYSTEM_INDEX_PROTECTION_ENABLED_KEY, false);
}

@Override
public final DirectoryReader apply(DirectoryReader reader) throws IOException {

if (systemIndexEnabled && isBlockedSystemIndexRequest() && !threadContext.isSystemContext()) {
log.warn("search action for {} is not allowed", index.getName());
return new EmptyFilterLeafReader.EmptyDirectoryReader(reader);
}

return wrap(reader);
}

protected DirectoryReader wrap(final DirectoryReader reader) {
return reader;
}

protected final boolean isBlockedSystemIndexRequest() {
return !SystemIndexRegistry.matchesSystemIndexPattern(Set.of(index.getName())).isEmpty();
}
}

0 comments on commit 83896cd

Please sign in to comment.