Skip to content

Commit 7c77db1

Browse files
committed
reduce index-patterns for cluster-admins
1 parent a2bc6f3 commit 7c77db1

File tree

6 files changed

+260
-71
lines changed

6 files changed

+260
-71
lines changed

src/main/java/io/fabric8/elasticsearch/plugin/ConfigurationSettings.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,11 @@ public interface ConfigurationSettings extends KibanaIndexMode{
7777
static final String DEFAULT_USER_PROFILE_PREFIX = ".kibana";
7878
static final String[] DEFAULT_WHITELISTED_USERS = new String[] { "$logging.$infra.$fluentd",
7979
"$logging.$infra.$kibana", "$logging.$infra.$curator" };
80-
80+
81+
static final String [] DEFAULT_KIBANA_OPS_INDEX_PATTERNS = new String[] {
82+
".operations.*", ".orphaned.*", "project.*", ".all"
83+
};
84+
8185
/**
8286
* The configurations for enabling/disabling portions of this plugin
8387
* defaults to 'true' => enabled.
@@ -95,6 +99,11 @@ public interface ConfigurationSettings extends KibanaIndexMode{
9599
static final String DEFAULT_ACL_ROLE_STRATEGY = "user";
96100

97101
static final String OPENSHIFT_KIBANA_REWRITE_ENABLED_FLAG = "openshift.kibana.rewrite.enabled";
102+
103+
/**
104+
* List of index patterns to create for operations users
105+
*/
106+
static final String OPENSHIFT_KIBANA_OPS_INDEX_PATTERNS = "openshift.kibana.ops_index_patterns";
98107

99108

100109
static final boolean OPENSHIFT_DYNAMIC_ENABLED_DEFAULT = true;

src/main/java/io/fabric8/elasticsearch/plugin/OpenshiftRequestContextFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ public static class OpenshiftRequestContext {
184184
private final String kibanaIndex;
185185
private final String kibanaIndexMode;
186186

187-
protected OpenshiftRequestContext(final String user, final String token, boolean isClusterAdmin,
187+
public OpenshiftRequestContext(final String user, final String token, boolean isClusterAdmin,
188188
Set<String> projects, String kibanaIndex, final String kibanaIndexMode) {
189189
this.user = user;
190190
this.token = token;

src/main/java/io/fabric8/elasticsearch/plugin/PluginClient.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,32 @@
1616

1717
package io.fabric8.elasticsearch.plugin;
1818

19+
import java.io.IOException;
1920
import java.util.HashSet;
2021
import java.util.Map;
2122
import java.util.Set;
23+
import java.util.concurrent.ExecutionException;
2224

25+
import org.apache.commons.lang.StringUtils;
2326
import org.elasticsearch.action.ActionRequestBuilder;
2427
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequestBuilder;
2528
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesResponse;
2629
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequestBuilder;
2730
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse;
31+
import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;
32+
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
2833
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequestBuilder;
2934
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
35+
import org.elasticsearch.action.admin.indices.get.GetIndexRequestBuilder;
36+
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
37+
import org.elasticsearch.action.admin.indices.refresh.RefreshRequestBuilder;
38+
import org.elasticsearch.action.admin.indices.refresh.RefreshResponse;
3039
import org.elasticsearch.action.get.GetRequestBuilder;
3140
import org.elasticsearch.action.get.GetResponse;
3241
import org.elasticsearch.action.index.IndexRequestBuilder;
3342
import org.elasticsearch.action.index.IndexResponse;
43+
import org.elasticsearch.action.update.UpdateRequestBuilder;
44+
import org.elasticsearch.action.update.UpdateResponse;
3445
import org.elasticsearch.client.Client;
3546
import org.elasticsearch.common.inject.Inject;
3647
import org.elasticsearch.common.logging.ESLogger;
@@ -53,13 +64,56 @@ public PluginClient(Client client) {
5364
this.client = client;
5465
}
5566

67+
public UpdateResponse update(String index, String type, String id, String source) {
68+
69+
LOGGER.debug("UPDATE: '{}/{}/{}' source: '{}'", index, type, id, source);
70+
71+
UpdateRequestBuilder builder = client.prepareUpdate(index, type, id).setDoc(source).setDocAsUpsert(true);
72+
addCommonHeaders(builder);
73+
UpdateResponse response = builder.get();
74+
75+
LOGGER.debug("Created with update? '{}'", response.isCreated());
76+
return response;
77+
}
78+
5679
public IndexResponse createDocument(String index, String type, String id, String source) {
5780
LOGGER.trace("create document: '{}/{}/{}' source: '{}'", index, type, id, source);
5881
IndexRequestBuilder builder = client.prepareIndex(index, type, id).setSource(source);
5982
addCommonHeaders(builder);
6083
IndexResponse response = builder.get();
6184
return response;
6285
}
86+
87+
public GetIndexResponse getIndices(String... indices) throws InterruptedException, ExecutionException {
88+
if (LOGGER.isTraceEnabled()) {
89+
LOGGER.trace("Getting indices '{}'", StringUtils.join(indices, ", "));
90+
}
91+
GetIndexRequestBuilder builder = client.admin().indices().prepareGetIndex().setIndices(indices);
92+
addCommonHeaders(builder);
93+
return builder.get();
94+
}
95+
96+
public CreateIndexResponse copyIndex(final String source, final String target, String... types) throws InterruptedException, ExecutionException, IOException {
97+
LOGGER.trace("Copying {} index to {} for types {}", source, target, types);
98+
GetIndexResponse response = getIndices(source);
99+
CreateIndexRequestBuilder builder = client.admin().indices()
100+
.prepareCreate(target)
101+
.setSettings(response.getSettings().get(source));
102+
for (String type : types) {
103+
builder.addMapping(type, response.mappings().get(source).get(type).getSourceAsMap());
104+
}
105+
addCommonHeaders(builder);
106+
return builder.get();
107+
}
108+
109+
public RefreshResponse refreshIndices(String... indices) {
110+
RefreshRequestBuilder builder = client.admin().indices().prepareRefresh(indices);
111+
addCommonHeaders(builder);
112+
RefreshResponse response = builder.get();
113+
LOGGER.debug("Refreshed '{}' successfully on {} of {} shards", indices, response.getSuccessfulShards(),
114+
response.getTotalShards());
115+
return response;
116+
}
63117

64118
public boolean indexExists(final String index) {
65119
LOGGER.trace("Checking for existance of index '{}'", index);

src/main/java/io/fabric8/elasticsearch/plugin/PluginSettings.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
import static io.fabric8.elasticsearch.plugin.acl.SearchGuardSyncStrategyFactory.PROJECT;
2020
import static io.fabric8.elasticsearch.plugin.acl.SearchGuardSyncStrategyFactory.USER;
2121

22+
import java.util.Arrays;
23+
import java.util.HashSet;
24+
import java.util.Set;
25+
2226
import org.apache.commons.lang.ArrayUtils;
2327
import org.elasticsearch.common.inject.Inject;
2428
import org.elasticsearch.common.logging.ESLogger;
@@ -37,6 +41,7 @@ public class PluginSettings implements ConfigurationSettings {
3741
private final String kibanaVersion;
3842
private final String kbnVersionHeader;
3943
private final Boolean enabled;
44+
private final Set<String> opsIndexPatterns;
4045

4146
@Inject
4247
public PluginSettings(final Settings settings) {
@@ -57,6 +62,7 @@ public PluginSettings(final Settings settings) {
5762
this.kibanaVersion = settings.get(KIBANA_CONFIG_VERSION, DEFAULT_KIBANA_VERSION);
5863
this.kbnVersionHeader = settings.get(KIBANA_VERSION_HEADER, DEFAULT_KIBANA_VERSION_HEADER);
5964
this.enabled = settings.getAsBoolean(OPENSHIFT_DYNAMIC_ENABLED_FLAG, OPENSHIFT_DYNAMIC_ENABLED_DEFAULT);
65+
this.opsIndexPatterns = new HashSet<String>(Arrays.asList(settings.getAsArray(OPENSHIFT_KIBANA_OPS_INDEX_PATTERNS, DEFAULT_KIBANA_OPS_INDEX_PATTERNS)));
6066

6167
LOGGER.info("Using kibanaIndexMode: '{}'", this.kibanaIndexMode);
6268
LOGGER.debug("searchGuardIndex: {}", this.searchGuardIndex);
@@ -99,4 +105,8 @@ public Boolean isEnabled() {
99105
public void setKibanaIndexMode(String kibanaIndexMode) {
100106
this.kibanaIndexMode = kibanaIndexMode;
101107
}
108+
109+
public Set<String> getKibanaOpsIndexPatterns() {
110+
return opsIndexPatterns;
111+
}
102112
}

src/main/java/io/fabric8/elasticsearch/plugin/kibana/KibanaSeed.java

Lines changed: 50 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,16 @@
2626
import java.util.concurrent.ExecutionException;
2727

2828
import org.apache.commons.lang.StringUtils;
29-
import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest;
30-
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
31-
import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
32-
import org.elasticsearch.action.admin.indices.get.GetIndexResponse;
33-
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
34-
import org.elasticsearch.action.admin.indices.refresh.RefreshResponse;
3529
import org.elasticsearch.action.delete.DeleteRequest;
3630
import org.elasticsearch.action.get.GetRequest;
3731
import org.elasticsearch.action.get.GetResponse;
3832
import org.elasticsearch.action.search.SearchRequest;
3933
import org.elasticsearch.action.search.SearchResponse;
40-
import org.elasticsearch.action.update.UpdateRequest;
4134
import org.elasticsearch.client.Client;
4235
import org.elasticsearch.common.inject.Inject;
4336
import org.elasticsearch.common.logging.ESLogger;
4437
import org.elasticsearch.common.logging.Loggers;
38+
import org.elasticsearch.common.xcontent.XContentFactory;
4539
import org.elasticsearch.index.IndexNotFoundException;
4640
import org.elasticsearch.search.SearchHit;
4741
import org.elasticsearch.transport.RemoteTransportException;
@@ -69,40 +63,75 @@ public class KibanaSeed implements ConfigurationSettings {
6963
private final IndexMappingLoader mappingLoader;
7064
private final PluginClient pluginClient;
7165
private final String defaultKibanaIndex;
66+
private final PluginSettings settings;
7267

7368
@Inject
7469
public KibanaSeed(final PluginSettings settings, final IndexMappingLoader loader, final PluginClient pluginClient) {
7570
this.mappingLoader = loader;
7671
this.pluginClient = pluginClient;
7772
this.defaultKibanaIndex = settings.getDefaultKibanaIndex();
73+
this.settings = settings;
7874
}
79-
75+
8076
public void setDashboards(final OpenshiftRequestContext context, Client client, String kibanaVersion, final String projectPrefix) {
8177

8278
LOGGER.debug("Begin setDashboards: projectPrefix '{}' for user '{}' projects '{}' kibanaIndex '{}'",
8379
projectPrefix, context.getUser(), context.getProjects(), context.getKibanaIndex());
84-
80+
8581
// We want to seed the Kibana user index initially
8682
// since the logic from Kibana has changed to create before this plugin
8783
// starts...
8884
boolean changed = initialSeedKibanaIndex(context, client);
85+
86+
if (context.isOperationsUser()) {
87+
changed = seedOperationsIndexPatterns(context, client, kibanaVersion, projectPrefix);
88+
} else {
89+
changed = seedUsersIndexPatterns(context, client, kibanaVersion, projectPrefix);
90+
}
91+
92+
if ( changed ) {
93+
pluginClient.refreshIndices(context.getKibanaIndex());
94+
}
95+
}
8996

97+
private boolean seedOperationsIndexPatterns(final OpenshiftRequestContext context, final Client client, String kibanaVersion, final String projectPrefix) {
98+
boolean changed = false;
99+
boolean defaultSet = false;
100+
for (String pattern : settings.getKibanaOpsIndexPatterns()) {
101+
if(!pluginClient.documentExists(context.getKibanaIndex(), INDICIES_TYPE, pattern)) {
102+
LOGGER.trace("Creating index-pattern '{}'", pattern);
103+
String source = StringUtils.replace(mappingLoader.getOperationsMappingsTemplate(), "$TITLE$", pattern);
104+
pluginClient.createDocument(context.getKibanaIndex(), INDICIES_TYPE, pattern, source);
105+
if (!defaultSet) {
106+
try {
107+
String update = XContentFactory.jsonBuilder()
108+
.startObject()
109+
.field(KibanaSeed.DEFAULT_INDEX_FIELD, pattern)
110+
.endObject().string();
111+
pluginClient.update(context.getKibanaIndex(), DEFAULT_INDEX_TYPE, kibanaVersion, update);
112+
defaultSet = true;
113+
} catch (IOException e) {
114+
LOGGER.error("Unable to set default index-pattern", e);
115+
}
116+
}
117+
changed = true;
118+
}
119+
}
120+
return changed;
121+
}
122+
123+
private boolean seedUsersIndexPatterns(final OpenshiftRequestContext context, final Client client, final String kibanaVersion, final String projectPrefix) {
124+
boolean changed = false;
90125
// GET .../.kibana/index-pattern/_search?pretty=true&fields=
91126
// compare results to projects; handle any deltas (create, delete?)
92-
93127
Set<String> indexPatterns = getProjectNamesFromIndexes(context, client, projectPrefix);
94128
LOGGER.debug("Found '{}' Index patterns for user", indexPatterns.size());
95129

96130
Set<String> projects = new HashSet<>(context.getProjects());
97-
if(context.isOperationsUser()) {
98-
projects.add(OPERATIONS_PROJECT);
99-
}
100131
List<String> filteredProjects = new ArrayList<String>(filterProjectsWithIndices(projectPrefix, projects));
101132
LOGGER.debug("projects for '{}' that have existing indexes: '{}'", context.getUser(), filteredProjects);
102133

103-
if (context.isOperationsUser()) {
104-
filteredProjects.add(ADMIN_ALIAS_NAME);
105-
}else if (filteredProjects.isEmpty()) {
134+
if (filteredProjects.isEmpty()) {
106135
filteredProjects.add(BLANK_PROJECT);
107136
}
108137

@@ -153,12 +182,9 @@ public void setDashboards(final OpenshiftRequestContext context, Client client,
153182
}
154183
}
155184
}
156-
157-
if ( changed ) {
158-
refreshKibanaUser(context.getKibanaIndex(), client);
159-
}
185+
return changed;
160186
}
161-
187+
162188
/*
163189
* Given a list of projects, filter out those which do not have any
164190
* index associated with it
@@ -174,16 +200,6 @@ private List<String> filterProjectsWithIndices(final String projectPrefix, Set<S
174200
return result;
175201
}
176202

177-
private void refreshKibanaUser(String kibanaIndex, Client esClient) {
178-
179-
RefreshRequest request = new RefreshRequest().indices(kibanaIndex);
180-
request.putHeader(ConfigConstants.SG_CONF_REQUEST_HEADER, "true");
181-
RefreshResponse response = esClient.admin().indices().refresh(request).actionGet();
182-
183-
LOGGER.debug("Refreshed '{}' successfully on {} of {} shards", kibanaIndex, response.getSuccessfulShards(),
184-
response.getTotalShards());
185-
}
186-
187203
private boolean initialSeedKibanaIndex(final OpenshiftRequestContext context, Client esClient) {
188204

189205
try {
@@ -194,29 +210,7 @@ private boolean initialSeedKibanaIndex(final OpenshiftRequestContext context, Cl
194210
// copy the defaults if the userindex is not the kibanaindex
195211
if (!kibanaIndexExists && !defaultKibanaIndex.equals(userIndex)) {
196212
LOGGER.debug("Copying '{}' to '{}'", defaultKibanaIndex, userIndex);
197-
198-
GetIndexRequest getRequest = new GetIndexRequest().indices(defaultKibanaIndex);
199-
getRequest.putHeader(ConfigConstants.SG_CONF_REQUEST_HEADER, "true");
200-
GetIndexResponse getResponse = esClient.admin().indices().getIndex(getRequest).get();
201-
202-
CreateIndexRequest createRequest = new CreateIndexRequest().index(userIndex);
203-
createRequest.putHeader(ConfigConstants.SG_CONF_REQUEST_HEADER, "true");
204-
205-
createRequest.settings(getResponse.settings().get(defaultKibanaIndex));
206-
207-
Map<String, Object> configMapping = getResponse.mappings().get(defaultKibanaIndex).get("config")
208-
.getSourceAsMap();
209-
210-
createRequest.mapping("config", configMapping);
211-
212-
esClient.admin().indices().create(createRequest).actionGet();
213-
214-
// Wait for health status of YELLOW
215-
ClusterHealthRequest healthRequest = new ClusterHealthRequest().indices(new String[] { userIndex })
216-
.waitForYellowStatus();
217-
218-
esClient.admin().cluster().health(healthRequest).actionGet().getStatus();
219-
213+
pluginClient.copyIndex(defaultKibanaIndex, userIndex, DEFAULT_INDEX_TYPE);
220214
return true;
221215
}
222216
} catch (ExecutionException | InterruptedException | IOException e) {
@@ -233,7 +227,7 @@ private void setDefaultIndex(String kibanaIndex, String project, Client esClient
233227
// .kibana.username
234228
String source = new DocumentBuilder().defaultIndex(getIndexPattern(project, projectPrefix)).build();
235229

236-
executeUpdate(kibanaIndex, DEFAULT_INDEX_TYPE, kibanaVersion, source, esClient);
230+
pluginClient.update(kibanaIndex, DEFAULT_INDEX_TYPE, kibanaVersion, source);
237231
}
238232

239233
private String getDefaultIndex(OpenshiftRequestContext context, Client esClient, String kibanaVersion, String projectPrefix) {
@@ -339,9 +333,7 @@ private void createIndexPattern(String kibanaIndex, String project, Client esCli
339333

340334
final String indexPattern = getIndexPattern(project, projectPrefix);
341335
String source;
342-
if (project.equalsIgnoreCase(OPERATIONS_PROJECT) || project.startsWith(ADMIN_ALIAS_NAME)) {
343-
source = mappingLoader.getOperationsMappingsTemplate();
344-
} else if (project.equalsIgnoreCase(BLANK_PROJECT)) {
336+
if (project.equalsIgnoreCase(BLANK_PROJECT)) {
345337
source = mappingLoader.getEmptyProjectMappingsTemplate();
346338
} else {
347339
source = mappingLoader.getApplicationMappingsTemplate();
@@ -361,17 +353,6 @@ private void deleteIndex(String kibanaIndex, String project, Client esClient, St
361353
executeDelete(kibanaIndex, INDICIES_TYPE, getIndexPattern(project, projectPrefix), esClient);
362354
}
363355

364-
private void executeUpdate(String index, String type, String id, String source, Client esClient) {
365-
366-
LOGGER.debug("UPDATE: '{}/{}/{}' source: '{}'", index, type, id, source);
367-
368-
UpdateRequest request = esClient.prepareUpdate(index, type, id).setDoc(source).setDocAsUpsert(true).request();
369-
request.putHeader(ConfigConstants.SG_CONF_REQUEST_HEADER, "true");
370-
371-
372-
LOGGER.debug("Created with update? '{}'", esClient.update(request).actionGet().isCreated());
373-
}
374-
375356
private void executeDelete(String index, String type, String id, Client esClient) {
376357

377358
LOGGER.debug("DELETE: '{}/{}/{}'", index, type, id);

0 commit comments

Comments
 (0)