Java tutorial
/* * Copyright 2015 floragunn UG (haftungsbeschrnkt) * * Licensed 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. * */ package com.floragunn.searchguard.tools; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Reader; import java.io.Writer; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.charset.Charset; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.Locale; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.elasticsearch.action.WriteConsistencyLevel; import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.Version; import org.elasticsearch.action.admin.cluster.health.ClusterHealthRequest; import org.elasticsearch.action.admin.cluster.health.ClusterHealthResponse; import org.elasticsearch.action.admin.cluster.node.info.NodeInfo; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequest; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsRequest; import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse; import org.elasticsearch.action.admin.cluster.settings.ClusterUpdateSettingsRequest; import org.elasticsearch.action.admin.cluster.state.ClusterStateRequest; import org.elasticsearch.action.admin.cluster.state.ClusterStateResponse; import org.elasticsearch.action.admin.cluster.tasks.PendingClusterTasksRequest; import org.elasticsearch.action.admin.cluster.tasks.PendingClusterTasksResponse; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest; import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsRequest; import org.elasticsearch.action.admin.indices.settings.put.UpdateSettingsResponse; import org.elasticsearch.action.admin.indices.stats.IndicesStatsRequest; import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.client.Client; import org.elasticsearch.client.transport.NoNodeAvailableException; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.cluster.health.ClusterHealthStatus; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.loader.JsonSettingsLoader; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.IndexNotFoundException; import com.floragunn.searchguard.SearchGuardPlugin; import com.floragunn.searchguard.action.configupdate.ConfigUpdateAction; import com.floragunn.searchguard.action.configupdate.ConfigUpdateRequest; import com.floragunn.searchguard.action.configupdate.ConfigUpdateResponse; import com.floragunn.searchguard.ssl.SearchGuardSSLPlugin; import com.floragunn.searchguard.ssl.util.SSLConfigConstants; import com.floragunn.searchguard.support.ConfigConstants; import com.google.common.io.Files; public class SearchGuardAdmin { private static final String SG_TS_PASS = "SG_TS_PASS"; private static final String SG_KS_PASS = "SG_KS_PASS"; //not used in multithreaded fashion private static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MMM-dd_HH-mm-ss", Locale.ENGLISH); private static final Settings ENABLE_ALL_ALLOCATIONS_SETTINGS = Settings.builder() .put("cluster.routing.allocation.enable", "all").build(); public static void main(final String[] args) { try { main0(args); } catch (NoNodeAvailableException e) { System.out.println( "ERR: Cannot connect to elasticsearch. Please refer to elasticsearch logfile for more information"); System.out.println("Trace:"); e.printStackTrace(); System.exit(-1); } catch (IndexNotFoundException e) { System.out.println( "ERR: No searchguard configuartion index found. Pls. execute sgadmin with different command line parameters"); System.out.println("When you run it for the first time to not specify -us, -era, -dra or -rl"); System.out.println( "For more informations look here: https://github.com/floragunncom/search-guard/issues/228"); System.exit(-1); } catch (Exception e) { System.out .println("ERR: An unexpected " + e.getClass().getSimpleName() + " occured: " + e.getMessage()); System.out.println("Trace:"); e.printStackTrace(); System.exit(-1); } } private static void main0(final String[] args) throws Exception { System.setProperty("sg.nowarn.client", "true"); final HelpFormatter formatter = new HelpFormatter(); Options options = new Options(); options.addOption("nhnv", "disable-host-name-verification", false, "Disable hostname verification"); options.addOption("nrhn", "disable-resolve-hostname", false, "Disable hostname beeing resolved"); options.addOption(Option.builder("ts").longOpt("truststore").hasArg().argName("file").required() .desc("Path to truststore (JKS/PKCS12 format)").build()); options.addOption(Option.builder("ks").longOpt("keystore").hasArg().argName("file").required() .desc("Path to keystore (JKS/PKCS12 format").build()); options.addOption(Option.builder("tst").longOpt("truststore-type").hasArg().argName("type") .desc("JKS or PKCS12, if not given use file ext. to dectect type").build()); options.addOption(Option.builder("kst").longOpt("keystore-type").hasArg().argName("type") .desc("JKS or PKCS12, if not given use file ext. to dectect type").build()); options.addOption(Option.builder("tspass").longOpt("truststore-password").hasArg().argName("password") .desc("Truststore password").build()); options.addOption(Option.builder("kspass").longOpt("keystore-password").hasArg().argName("password") .desc("Keystore password").build()); options.addOption(Option.builder("cd").longOpt("configdir").hasArg().argName("directory") .desc("Directory for config files").build()); options.addOption(Option.builder("h").longOpt("hostname").hasArg().argName("host") .desc("Elasticsearch host").build()); options.addOption(Option.builder("p").longOpt("port").hasArg().argName("port") .desc("Elasticsearch transport port (normally 9300)").build()); options.addOption(Option.builder("cn").longOpt("clustername").hasArg().argName("clustername") .desc("Clustername").build()); options.addOption("sniff", "enable-sniffing", false, "Enable client.transport.sniff"); options.addOption("icl", "ignore-clustername", false, "Ignore clustername"); options.addOption(Option.builder("r").longOpt("retrieve").desc("retrieve current config").build()); options.addOption(Option.builder("f").longOpt("file").hasArg().argName("file").desc("file").build()); options.addOption( Option.builder("t").longOpt("type").hasArg().argName("file-type").desc("file-type").build()); options.addOption(Option.builder("tsalias").longOpt("truststore-alias").hasArg().argName("alias") .desc("Truststore alias").build()); options.addOption(Option.builder("ksalias").longOpt("keystore-alias").hasArg().argName("alias") .desc("Keystore alias").build()); options.addOption(Option.builder("ec").longOpt("enabled-ciphers").hasArg().argName("cipers") .desc("Comma separated list of TLS ciphers").build()); options.addOption(Option.builder("ep").longOpt("enabled-protocols").hasArg().argName("protocols") .desc("Comma separated list of TLS protocols").build()); //TODO mark as deprecated and replace it with "era" if "era" is mature enough options.addOption(Option.builder("us").longOpt("update_settings").hasArg().argName("number of replicas") .desc("update the number of replicas and reload configuration on all nodes and exit").build()); options.addOption(Option.builder("i").longOpt("index").hasArg().argName("indexname") .desc("The index Searchguard uses to store its configs in").build()); options.addOption(Option.builder("era").longOpt("enable-replica-autoexpand") .desc("enable replica auto expand and exit").build()); options.addOption(Option.builder("dra").longOpt("disable-replica-autoexpand") .desc("disable replica auto expand and exit").build()); options.addOption( Option.builder("rl").longOpt("reload").desc("reload configuration on all nodes and exit").build()); options.addOption( Option.builder("ff").longOpt("fail-fast").desc("fail-fast if something goes wrong").build()); options.addOption( Option.builder("dg").longOpt("diagnose").desc("Log diagnostic trace into a file").build()); options.addOption(Option.builder("dci").longOpt("delete-config-index") .desc("Delete 'searchguard' config index and exit.").build()); options.addOption(Option.builder("esa").longOpt("enable-shard-allocation") .desc("Enable all shard allocation and exit.").build()); String hostname = "localhost"; int port = 9300; String kspass = System.getenv(SG_KS_PASS) != null ? System.getenv(SG_KS_PASS) : "changeit"; String tspass = System.getenv(SG_TS_PASS) != null ? System.getenv(SG_TS_PASS) : kspass; String cd = "."; String ks; String ts; String kst = null; String tst = null; boolean nhnv = false; boolean nrhn = false; boolean sniff = false; boolean icl = false; String clustername = "elasticsearch"; String file = null; String type = null; boolean retrieve = false; String ksAlias = null; String tsAlias = null; String[] enabledProtocols = new String[0]; String[] enabledCiphers = new String[0]; Integer updateSettings = null; String index = ConfigConstants.SG_DEFAULT_CONFIG_INDEX; Boolean replicaAutoExpand = null; boolean reload = false; boolean failFast = false; boolean diagnose = false; boolean deleteConfigIndex = false; boolean enableShardAllocation = false; CommandLineParser parser = new DefaultParser(); try { CommandLine line = parser.parse(options, args); hostname = line.getOptionValue("h", hostname); port = Integer.parseInt(line.getOptionValue("p", String.valueOf(port))); kspass = line.getOptionValue("kspass", kspass); //TODO null? //when no passwd is set tspass = line.getOptionValue("tspass", tspass); //TODO null? //when no passwd is set cd = line.getOptionValue("cd", cd); if (!cd.endsWith(File.separator)) { cd += File.separator; } ks = line.getOptionValue("ks"); ts = line.getOptionValue("ts"); kst = line.getOptionValue("kst", kst); tst = line.getOptionValue("tst", tst); nhnv = line.hasOption("nhnv"); nrhn = line.hasOption("nrhn"); clustername = line.getOptionValue("cn", clustername); sniff = line.hasOption("sniff"); icl = line.hasOption("icl"); file = line.getOptionValue("f", file); type = line.getOptionValue("t", type); retrieve = line.hasOption("r"); ksAlias = line.getOptionValue("ksalias", ksAlias); tsAlias = line.getOptionValue("tsalias", tsAlias); index = line.getOptionValue("i", index); String enabledCiphersString = line.getOptionValue("ec", null); String enabledProtocolsString = line.getOptionValue("ep", null); if (enabledCiphersString != null) { enabledCiphers = enabledCiphersString.split(","); } if (enabledProtocolsString != null) { enabledProtocols = enabledProtocolsString.split(","); } updateSettings = line.hasOption("us") ? Integer.parseInt(line.getOptionValue("us")) : null; reload = line.hasOption("rl"); if (line.hasOption("era")) { replicaAutoExpand = true; } if (line.hasOption("dra")) { replicaAutoExpand = false; } failFast = line.hasOption("ff"); diagnose = line.hasOption("dg"); deleteConfigIndex = line.hasOption("dci"); enableShardAllocation = line.hasOption("esa"); } catch (ParseException exp) { System.err.println("ERR: Parsing failed. Reason: " + exp.getMessage()); formatter.printHelp("sgadmin.sh", options, true); return; } if (port < 9300) { System.out.println("WARNING: Seems you want connect to the a HTTP port." + System.lineSeparator() + " sgadmin connect through the transport port which is normally 9300."); } System.out.print("Will connect to " + hostname + ":" + port); Socket socket = new Socket(); try { socket.connect(new InetSocketAddress(hostname, port)); } catch (java.net.ConnectException ex) { System.out.println(); System.out.println( "ERR: Seems there is no elasticsearch running on " + hostname + ":" + port + " - Will exit"); System.exit(-1); } finally { try { socket.close(); } catch (Exception e) { //ignore } } System.out.println(" ... done"); final Settings.Builder settingsBuilder = Settings.builder().put("path.home", ".").put("path.conf", ".") .put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_KEYSTORE_FILEPATH, ks) .put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_TRUSTSTORE_FILEPATH, ts) .put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_KEYSTORE_PASSWORD, kspass) .put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_TRUSTSTORE_PASSWORD, tspass) .put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, !nhnv) .put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION_RESOLVE_HOST_NAME, !nrhn) .put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_ENABLED, true) .put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_KEYSTORE_TYPE, kst == null ? (ks.endsWith(".jks") ? "JKS" : "PKCS12") : kst) .put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_TRUSTSTORE_TYPE, tst == null ? (ts.endsWith(".jks") ? "JKS" : "PKCS12") : tst) .putArray(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_ENABLED_CIPHERS, enabledCiphers) .putArray(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_ENABLED_PROTOCOLS, enabledProtocols) .put("cluster.name", clustername).put("client.transport.ignore_cluster_name", icl) .put("client.transport.sniff", sniff); if (ksAlias != null) { settingsBuilder.put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_KEYSTORE_ALIAS, ksAlias); } if (tsAlias != null) { settingsBuilder.put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_TRUSTSTORE_ALIAS, tsAlias); } Settings settings = settingsBuilder.build(); try (TransportClient tc = TransportClient.builder().settings(settings).addPlugin(SearchGuardSSLPlugin.class) .addPlugin(SearchGuardPlugin.class) //needed for config update action only .build() .addTransportAddress(new InetSocketTransportAddress(new InetSocketAddress(hostname, port)))) { if (updateSettings != null) { Settings indexSettings = Settings.builder().put("index.number_of_replicas", updateSettings).build(); tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest( new String[] { "config", "roles", "rolesmapping", "internalusers", "actiongroups" })) .actionGet(); final UpdateSettingsResponse response = tc.admin().indices() .updateSettings((new UpdateSettingsRequest(index).settings(indexSettings))).actionGet(); System.out.println("Reload config on all nodes"); System.out.println("Update number of replicas to " + (updateSettings) + " with result: " + response.isAcknowledged()); System.exit(response.isAcknowledged() ? 0 : -1); } if (reload) { tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest( new String[] { "config", "roles", "rolesmapping", "internalusers", "actiongroups" })) .actionGet(); System.out.println("Reload config on all nodes"); System.exit(0); } if (replicaAutoExpand != null) { Settings indexSettings = Settings.builder() .put("index.auto_expand_replicas", replicaAutoExpand ? "0-all" : "false").build(); tc.execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest( new String[] { "config", "roles", "rolesmapping", "internalusers", "actiongroups" })) .actionGet(); final UpdateSettingsResponse response = tc.admin().indices() .updateSettings((new UpdateSettingsRequest(index).settings(indexSettings))).actionGet(); System.out.println("Reload config on all nodes"); System.out.println("Auto-expand replicas " + (replicaAutoExpand ? "enabled" : "disabled")); System.exit(response.isAcknowledged() ? 0 : -1); } if (enableShardAllocation) { final boolean successful = tc.admin().cluster() .updateSettings(new ClusterUpdateSettingsRequest() .transientSettings(ENABLE_ALL_ALLOCATIONS_SETTINGS) .persistentSettings(ENABLE_ALL_ALLOCATIONS_SETTINGS)) .actionGet().isAcknowledged(); if (successful) { System.out.println("Persistent and transient shard allocation enabled"); } else { System.out.println("ERR: Unable to enable shard allocation"); } System.exit(successful ? 0 : -1); } if (failFast) { System.out.println("Failfast is activated"); } if (diagnose) { generateDiagnoseTrace(tc); } System.out.println( "Contacting elasticsearch cluster '" + clustername + "' and wait for YELLOW clusterstate ..."); ClusterHealthResponse chr = null; while (chr == null) { try { chr = tc.admin().cluster().health( new ClusterHealthRequest().timeout(TimeValue.timeValueMinutes(5)).waitForYellowStatus()) .actionGet(); } catch (Exception e) { if (!failFast) { System.out.println("Cannot retrieve cluster state due to: " + e.getMessage() + ". This is not an error, will keep on trying ..."); System.out.println( " * Try running sgadmin.sh with -icl and -nhnv (If thats works you need to check your clustername as well as hostnames in your SSL certificates)"); System.out.println( " * If this is not working, try running sgadmin.sh with --diagnose and see diagnose trace log file)"); } else { System.out.println("ERR: Cannot retrieve cluster state due to: " + e.getMessage() + "."); System.out.println( " * Try running sgadmin.sh with -icl and -nhnv (If thats works you need to check your clustername as well as hostnames in your SSL certificates)"); System.out.println( " * If this is not working, try running sgadmin.sh with --diagnose and see diagnose trace log file)"); System.exit(-1); } Thread.sleep(3000); continue; } } final boolean timedOut = chr.isTimedOut(); if (timedOut) { System.out.println("ERR: Timed out while waiting for a green or yellow cluster state."); System.out.println( " * Try running sgadmin.sh with -icl and -nhnv (If thats works you need to check your clustername as well as hostnames in your SSL certificates)"); System.exit(-1); } System.out.println("Clustername: " + chr.getClusterName()); System.out.println("Clusterstate: " + chr.getStatus()); System.out.println("Number of nodes: " + chr.getNumberOfNodes()); System.out.println("Number of data nodes: " + chr.getNumberOfDataNodes()); final boolean indexExists = tc.admin().indices().exists(new IndicesExistsRequest(index)).actionGet() .isExists(); final NodesInfoResponse nodesInfo = tc.admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet(); if (deleteConfigIndex) { boolean success = true; if (indexExists) { success = tc.admin().indices().delete(new DeleteIndexRequest(index)).actionGet() .isAcknowledged(); System.out.print("Deleted index '" + index + "'"); } else { System.out.print("No index '" + index + "' exists, so no need to delete it"); } System.exit(success ? 0 : -1); } if (!indexExists) { System.out.print(index + " index does not exists, attempt to create it ... "); int replicas = chr.getNumberOfDataNodes() - 1; final boolean indexCreated = tc.admin().indices().create(new CreateIndexRequest(index) // .mapping("config", source) // .settings(settings) //TODO "index.auto_expand_replicas", "0-all" .settings("index.number_of_shards", 1, "index.number_of_replicas", replicas)).actionGet() .isAcknowledged(); if (indexCreated) { System.out.println("done (with " + replicas + " replicas, auto expand replicas is off)"); } else { System.out.println("failed!"); System.out.println("FAIL: Unable to create the " + index + " index. See elasticsearch logs for more details"); System.exit(-1); } } else { System.out.println(index + " index already exists, so we do not need to create one."); try { ClusterHealthResponse chrsg = tc.admin().cluster().health(new ClusterHealthRequest(index)) .actionGet(); if (chrsg.isTimedOut()) { System.out.println("ERR: Timed out while waiting for " + index + " index state."); } if (chrsg.getStatus() == ClusterHealthStatus.RED) { System.out.println("ERR: " + index + " index state is RED."); } if (chrsg.getStatus() == ClusterHealthStatus.YELLOW) { System.out.println( "INFO: " + index + " index state is YELLOW, it seems you miss some replicas"); } } catch (Exception e) { if (!failFast) { System.out.println("Cannot retrieve " + index + " index state state due to " + e.getMessage() + ". This is not an error, will keep on trying ..."); } else { System.out.println("ERR: Cannot retrieve " + index + " index state state due to " + e.getMessage() + "."); System.exit(-1); } } } if (retrieve) { String date = DATE_FORMAT.format(new Date()); boolean success = retrieveFile(tc, cd + "sg_config_" + date + ".yml", index, "config"); success = success & retrieveFile(tc, cd + "sg_roles_" + date + ".yml", index, "roles"); success = success & retrieveFile(tc, cd + "sg_roles_mapping_" + date + ".yml", index, "rolesmapping"); success = success & retrieveFile(tc, cd + "sg_internal_users_" + date + ".yml", index, "internalusers"); success = success & retrieveFile(tc, cd + "sg_action_groups_" + date + ".yml", index, "actiongroups"); System.exit(success ? 0 : -1); } boolean isCdAbs = new File(cd).isAbsolute(); System.out.println("Populate config from " + (isCdAbs ? cd : new File(".", cd).getCanonicalPath())); if (file != null) { if (type == null) { System.out.println("ERR: type missing"); System.exit(-1); } if (!Arrays .asList(new String[] { "config", "roles", "rolesmapping", "internalusers", "actiongroups" }) .contains(type)) { System.out.println("ERR: Invalid type '" + type + "'"); System.exit(-1); } boolean success = uploadFile(tc, file, index, type); System.exit(success ? 0 : -1); } boolean success = uploadFile(tc, cd + "sg_config.yml", index, "config"); success = success & uploadFile(tc, cd + "sg_roles.yml", index, "roles"); success = success & uploadFile(tc, cd + "sg_roles_mapping.yml", index, "rolesmapping"); success = success & uploadFile(tc, cd + "sg_internal_users.yml", index, "internalusers"); success = success & uploadFile(tc, cd + "sg_action_groups.yml", index, "actiongroups"); if (failFast && !success) { System.out.println("ERR: cannot upload configuration, see errors above"); System.exit(-1); } ConfigUpdateResponse cur = tc .execute(ConfigUpdateAction.INSTANCE, new ConfigUpdateRequest( new String[] { "config", "roles", "rolesmapping", "internalusers", "actiongroups" })) .actionGet(); success = success & checkConfigUpdateResponse(cur, nodesInfo, 5); System.out.println("Done with " + (success ? "success" : "failures")); System.exit(success ? 0 : -1); } // TODO audit changes to searchguard index } private static boolean checkConfigUpdateResponse(ConfigUpdateResponse response, NodesInfoResponse nir, int expectedConfigCount) { int expectedNodeCount = 0; for (NodeInfo ni : nir) { Settings nodeSettings = ni.getSettings(); //do not count tribe clients if (nodeSettings.get("tribe.name", null) == null) { expectedNodeCount++; } } boolean success = response.getNodes().length == expectedNodeCount; if (!success) { System.out.println("FAIL: Expected " + expectedNodeCount + " nodes to return response, but got only " + response.getNodes().length); } for (String nodeId : response.getNodesMap().keySet()) { ConfigUpdateResponse.Node node = (ConfigUpdateResponse.Node) response.getNodesMap().get(nodeId); boolean successNode = (node.getUpdatedConfigTypes() != null && node.getUpdatedConfigTypes().length == expectedConfigCount); if (!successNode) { System.out.println("FAIL: Expected " + expectedConfigCount + " config types for node " + nodeId + " but got only " + Arrays.toString(node.getUpdatedConfigTypes()) + " due to: " + node.getMessage() == null ? "unknown reason" : node.getMessage()); } success = success & successNode; } return success; } private static boolean uploadFile(Client tc, String filepath, String index, String type) { System.out.println("Will update '" + type + "' with " + filepath); try (Reader reader = new FileReader(filepath)) { final String id = tc.index(new IndexRequest(index).type(type).id("0").refresh(true) .consistencyLevel(WriteConsistencyLevel.DEFAULT) .source(readXContent(reader, XContentType.YAML))).actionGet().getId(); if ("0".equals(id)) { System.out.println(" SUCC: Configuration for '" + type + "' created or updated"); return true; } else { System.out.println(" FAIL: Configuration for '" + type + "' failed for unknown reasons. Pls. consult logfile of elasticsearch"); } } catch (Exception e) { System.out.println(" FAIL: Configuration for '" + type + "' failed because of " + e.toString()); } return false; } private static boolean retrieveFile(Client tc, String filepath, String index, String type) { System.out.println("Will retrieve '" + type + "' into " + filepath); try (Writer writer = new FileWriter(filepath)) { final GetResponse response = tc .get(new GetRequest(index).type(type).id("0").refresh(true).realtime(false)).actionGet(); if (response.isExists()) { if (response.isSourceEmpty()) { System.out.println(" FAIL: Configuration for '" + type + "' failed because of empty source"); return false; } String yaml = convertToYaml(response.getSourceAsBytesRef(), true); writer.write(yaml); System.out.println(" SUCC: Configuration for '" + type + "' stored in " + filepath); return true; } else { System.out.println(" FAIL: Get configuration for '" + type + "' because it does not exist"); } } catch (Exception e) { System.out.println(" FAIL: Get configuration for '" + type + "' failed because of " + e.toString()); } return false; } private static BytesReference readXContent(final Reader reader, final XContentType xContentType) throws IOException { BytesReference retVal; XContentParser parser = null; try { parser = XContentFactory.xContent(xContentType).createParser(reader); parser.nextToken(); final XContentBuilder builder = XContentFactory.jsonBuilder(); builder.copyCurrentStructure(parser); retVal = builder.bytes(); } finally { if (parser != null) { parser.close(); } } //validate Settings.builder().put(new JsonSettingsLoader().load(XContentHelper.createParser(retVal))).build(); return retVal; } private static String convertToYaml(BytesReference bytes, boolean prettyPrint) throws IOException { try (XContentParser parser = XContentFactory.xContent(XContentFactory.xContentType(bytes)) .createParser(bytes.streamInput())) { parser.nextToken(); XContentBuilder builder = XContentFactory.yamlBuilder(); if (prettyPrint) { builder.prettyPrint(); } builder.copyCurrentStructure(parser); return builder.string(); } } protected static void generateDiagnoseTrace(final Client tc) { final String date = DATE_FORMAT.format(new Date()); final StringBuilder sb = new StringBuilder(); sb.append("Diagnostic sgadmin trace" + System.lineSeparator()); sb.append("ES client version: " + Version.CURRENT + System.lineSeparator()); sb.append("Client properties: " + System.getProperties() + System.lineSeparator()); sb.append(date + System.lineSeparator()); sb.append(System.lineSeparator()); try { sb.append("ClusterHealthRequest:" + System.lineSeparator()); ClusterHealthResponse nir = tc.admin().cluster().health(new ClusterHealthRequest()).actionGet(); sb.append(XContentHelper.toString(nir)); } catch (Exception e1) { sb.append(ExceptionsHelper.stackTrace(e1)); } try { sb.append(System.lineSeparator() + "NodesInfoResponse:" + System.lineSeparator()); NodesInfoResponse nir = tc.admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet(); sb.append(XContentHelper.toString(nir)); } catch (Exception e1) { sb.append(ExceptionsHelper.stackTrace(e1)); } try { sb.append(System.lineSeparator() + "NodesStatsRequest:" + System.lineSeparator()); NodesStatsResponse nir = tc.admin().cluster().nodesStats(new NodesStatsRequest()).actionGet(); sb.append(XContentHelper.toString(nir)); } catch (Exception e1) { sb.append(ExceptionsHelper.stackTrace(e1)); } try { sb.append(System.lineSeparator() + "PendingClusterTasksRequest:" + System.lineSeparator()); PendingClusterTasksResponse nir = tc.admin().cluster() .pendingClusterTasks(new PendingClusterTasksRequest()).actionGet(); sb.append(XContentHelper.toString(nir)); } catch (Exception e1) { sb.append(ExceptionsHelper.stackTrace(e1)); } try { sb.append(System.lineSeparator() + "ClusterStateRequest:" + System.lineSeparator()); ClusterStateResponse nir = tc.admin().cluster().state(new ClusterStateRequest()).actionGet(); sb.append(XContentHelper.toString(nir.getState())); } catch (Exception e1) { sb.append(ExceptionsHelper.stackTrace(e1)); } try { sb.append(System.lineSeparator() + "IndicesStatsRequest:" + System.lineSeparator()); IndicesStatsResponse nir = tc.admin().indices().stats(new IndicesStatsRequest()).actionGet(); sb.append(XContentHelper.toString(nir)); } catch (Exception e1) { sb.append(ExceptionsHelper.stackTrace(e1)); } try { File dfile = new File("sgadmin_diag_trace_" + date + ".txt"); Files.write(sb, dfile, Charset.forName("UTF-8")); System.out.println("Diagnostic trace written to: " + dfile.getAbsolutePath()); } catch (Exception e1) { System.out.println("ERR: cannot write diag trace file due to " + e1); } } }