Skip to content

Commit

Permalink
Merge pull request #179 from jcantrill/1705589_blank_page
Browse files Browse the repository at this point in the history
PR merged. Thanks!
  • Loading branch information
fusesource-ci authored Jul 2, 2019
2 parents a3bd6db + 349d00f commit fdd03d9
Show file tree
Hide file tree
Showing 24 changed files with 373 additions and 195 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public interface ConfigurationSettings extends KibanaIndexMode{
* The maximum time time in milliseconds to wait for SearchGuard to sync the
* ACL from a write from this plugin until load by searchguard
*/

/** OpenShift settings here **/
static final String OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_APP = "io.fabric8.elasticsearch.kibana.mapping.app";
static final String OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_OPERATIONS = "io.fabric8.elasticsearch.kibana.mapping.ops";
Expand All @@ -71,6 +72,7 @@ public interface ConfigurationSettings extends KibanaIndexMode{
static final String[] DEFAULT_OPENSHIFT_OPS_PROJECTS = new String[] { "default", "openshift", "openshift-infra",
"kube-system" };
static final String OPENSHIFT_REQUEST_CONTEXT = "x-openshift-request-context";
static final String SYNC_AND_SEED = "x-openshift-sync-and-seed-acls";

static final String DEFAULT_AUTH_PROXY_HEADER = "X-Proxy-Remote-User";
static final String DEFAULT_SECURITY_CONFIG_INDEX = "searchguard";
Expand All @@ -83,6 +85,11 @@ public interface ConfigurationSettings extends KibanaIndexMode{
};

static final String OPENSHIFT_ACL_EXPIRE_IN_MILLIS = "openshift.acl.expire_in_millis";

static final String OPENSHIFT_CONTEXT_CACHE_MAXSIZE = "openshift.context.cache.maxsize";
static final String OPENSHIFT_CONTEXT_CACHE_EXPIRE_SECONDS = "openshift.context.cache.expireseconds";
static final int DEFAULT_OPENSHIFT_CONTEXT_CACHE_MAXSIZE = 500;
static final long DEFAULT_OPENSHIFT_CONTEXT_CACHE_EXPIRE_SECONDS = 120;

/**
* The strategy to use for generating roles and role mappings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,12 @@ public Collection<Object> createComponents(Client client, ClusterService cluster
final OpenshiftAPIService apiService = new OpenshiftAPIService();
final RequestUtils requestUtils = new RequestUtils(pluginSettings, apiService);
final OpenshiftRequestContextFactory contextFactory = new OpenshiftRequestContextFactory(settings, requestUtils,
apiService);
apiService, threadPool.getThreadContext());
final SearchGuardSyncStrategyFactory documentFactory = new SearchGuardSyncStrategyFactory(pluginSettings);
final KibanaUtils kUtils = new KibanaUtils(pluginSettings, pluginClient);
final KibanaSeed seed = new KibanaSeed(pluginSettings, indexMappingLoader, pluginClient, kUtils);
final ACLDocumentManager aclDocumentManager = new ACLDocumentManager(pluginClient, pluginSettings, documentFactory, threadPool);
this.aclFilter = new DynamicACLFilter(pluginSettings, seed, client, threadPool, requestUtils, aclDocumentManager);
OpenShiftElasticSearchService osElasticService = new OpenShiftElasticSearchService(aclDocumentManager, pluginSettings);
clusterService.addLocalNodeMasterListener(osElasticService);

PluginServiceFactory.setApiService(apiService);
PluginServiceFactory.setContextFactory(contextFactory);
Expand All @@ -119,7 +117,6 @@ public Collection<Object> createComponents(Client client, ClusterService cluster
list.add(kUtils);
list.add(seed);
list.add(aclFilter);
list.add(osElasticService);
list.add(new FieldStatsResponseFilter(pluginClient));
list.addAll(sgPlugin.createComponents(client, clusterService, threadPool, resourceWatcherService, scriptService,
namedXContentRegistry));
Expand Down Expand Up @@ -204,6 +201,8 @@ public Settings additionalSettings() {
@Override
public List<Setting<?>> getSettings() {
List<Setting<?>> settings = sgPlugin.getSettings();
settings.add(Setting.intSetting(OPENSHIFT_CONTEXT_CACHE_MAXSIZE, DEFAULT_OPENSHIFT_CONTEXT_CACHE_MAXSIZE, Property.NodeScope));
settings.add(Setting.longSetting(OPENSHIFT_CONTEXT_CACHE_EXPIRE_SECONDS, DEFAULT_OPENSHIFT_CONTEXT_CACHE_EXPIRE_SECONDS, 0, Property.NodeScope));
settings.add(Setting.simpleString(OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_APP, Property.NodeScope));
settings.add(Setting.simpleString(OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_OPERATIONS, Property.NodeScope));
settings.add(Setting.simpleString(OPENSHIFT_ES_KIBANA_SEED_MAPPINGS_EMPTY, Property.NodeScope));
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.ArrayUtils;
Expand All @@ -36,15 +40,24 @@
import org.elasticsearch.SpecialPermission;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.rest.RestRequest;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;

import io.fabric8.elasticsearch.plugin.model.Project;
import io.fabric8.elasticsearch.util.RequestUtils;

/**
* Context of information regarding a use
*/
public class OpenshiftRequestContextFactory {
public class OpenshiftRequestContextFactory
extends CacheLoader<String, OpenshiftRequestContextFactory.OpenshiftRequestContext>
implements RemovalListener<String, OpenshiftRequestContextFactory.OpenshiftRequestContext> {

private static final Logger LOGGER = Loggers.getLogger(OpenshiftRequestContextFactory.class);

Expand All @@ -53,11 +66,15 @@ public class OpenshiftRequestContextFactory {
private final String[] operationsProjects;
private final String kibanaPrefix;
private String kibanaIndexMode;
private LoadingCache<String, OpenshiftRequestContext> contextCache;
private ThreadContext threadContext;

public OpenshiftRequestContextFactory(
final Settings settings,
final RequestUtils utils,
final OpenshiftAPIService apiService) {
final OpenshiftAPIService apiService,
final ThreadContext threadContext){
this.threadContext = threadContext;
this.apiService = apiService;
this.utils = utils;
this.operationsProjects = settings.getAsArray(ConfigurationSettings.OPENSHIFT_CONFIG_OPS_PROJECTS,
Expand All @@ -69,6 +86,43 @@ public OpenshiftRequestContextFactory(
this.kibanaIndexMode = UNIQUE;
}
LOGGER.info("Using kibanaIndexMode: '{}'", this.kibanaIndexMode);

contextCache = CacheBuilder.newBuilder()
.maximumSize(settings.getAsInt(ConfigurationSettings.OPENSHIFT_CONTEXT_CACHE_MAXSIZE,
ConfigurationSettings.DEFAULT_OPENSHIFT_CONTEXT_CACHE_MAXSIZE))
.expireAfterWrite(settings.getAsLong(ConfigurationSettings.OPENSHIFT_CONTEXT_CACHE_EXPIRE_SECONDS,
ConfigurationSettings.DEFAULT_OPENSHIFT_CONTEXT_CACHE_EXPIRE_SECONDS), TimeUnit.SECONDS)
.removalListener(this)
.build(this);
}



@Override
public void onRemoval(RemovalNotification<String, OpenshiftRequestContext> event) {
if(LOGGER.isDebugEnabled()) {
LOGGER.debug("Evicted cache entry for {} because: {}",event.getValue().getUser(), event.getCause().name() );
}
}

@Override
public OpenshiftRequestContextFactory.OpenshiftRequestContext load(String token) throws Exception {
String user = utils.assertUser(token);
boolean isClusterAdmin = utils.isOperationsUser(user, token);
if(user.contains("\\")){
user = user.replace("\\", "/");
}
Set<Project> projects = new HashSet<>();
if(!isClusterAdmin) { //skip fetching projects because getting full access anyway
projects = listProjectsFor(user, token);
}
Collection<String> backend = PluginServiceFactory.getBackendRoleRetriever().retrieveBackendRoles(token);
threadContext.putTransient(ConfigurationSettings.SYNC_AND_SEED, Boolean.TRUE);
OpenshiftRequestContext context
= new OpenshiftRequestContext(user, token, isClusterAdmin, projects, getKibanaIndex(user, isClusterAdmin), this.kibanaIndexMode, backend);
LOGGER.debug("Loaded cache for context '{}'", context.getUser());
LOGGER.trace("Loaded cache for context '{}'", context);
return context;
}

/**
Expand All @@ -80,24 +134,21 @@ public OpenshiftRequestContextFactory(
*/
public OpenshiftRequestContext create(final RestRequest request) throws Exception {
logRequest(request);

Set<Project> projects = new HashSet<>();
boolean isClusterAdmin = false;
String user = utils.getUser(request);
if(!PluginServiceFactory.isReady()) {
return OpenshiftRequestContext.EMPTY;
}
String token = utils.getBearerToken(request);
if (StringUtils.isNotBlank(token)){
user = utils.assertUser(request);
isClusterAdmin = utils.isOperationsUser(request);
if(user.contains("\\")){
user = user.replace("\\", "/");
try {
return contextCache.get(token);
} catch(ExecutionException e) {
LOGGER.error("Error trying to fetch user's context from the cache",e);
}
projects = listProjectsFor(user, token);
return new OpenshiftRequestContext(user, token, isClusterAdmin, projects, getKibanaIndex(user, isClusterAdmin), this.kibanaIndexMode);
}
LOGGER.debug("Returning EMPTY request context; either was provided client cert or empty token.");
return OpenshiftRequestContext.EMPTY;
}

private void logRequest(final RestRequest request) {
if (LOGGER.isDebugEnabled()) {
String user = utils.getUser(request);
Expand Down Expand Up @@ -174,23 +225,37 @@ public static String getUsernameHash(String username) {
public static class OpenshiftRequestContext {

public static final OpenshiftRequestContext EMPTY = new OpenshiftRequestContext("", "", false,
new HashSet<Project>(), "", "");
new HashSet<Project>(), "", "", Collections.emptyList());

private final String user;
private final String token;
private final boolean isClusterAdmin;
private final Set<Project> projects;
private final String kibanaIndex;
private final String kibanaIndexMode;
private final Collection<String> backendRoles;

public OpenshiftRequestContext(final String user, final String token, boolean isClusterAdmin,
Set<Project> projects, String kibanaIndex, final String kibanaIndexMode) {
Set<Project> projects, String kibanaIndex, final String kibanaIndexMode, Collection<String> backend) {
this.user = user;
this.token = token;
this.isClusterAdmin = isClusterAdmin;
this.projects = new HashSet<>(projects);
this.kibanaIndex = kibanaIndex;
this.kibanaIndexMode = kibanaIndexMode;
this.backendRoles = backend;
}

public String toString() {
return new StringBuilder()
.append("OpenshiftRequestContext[")
.append("user=").append(user).append(",")
.append("isClusterAdmin=").append(isClusterAdmin).append(",")
.append("projects=").append(projects).append(",")
.append("kibanaIndex=").append(kibanaIndex).append(",")
.append("backendroles=").append(backendRoles)
.append("]")
.toString();
}

/**
Expand Down Expand Up @@ -230,5 +295,10 @@ public String getKibanaIndex() {
public String getKibanaIndexMode() {
return this.kibanaIndexMode;
}

public Collection<String> getBackendRoles() {
return backendRoles;
}
}

}
Loading

0 comments on commit fdd03d9

Please sign in to comment.