Add Upgrade API Index Upgrade Info action (elastic/x-pack-elasticsearch#1264)
Adds a new Upgrade API with the first action, index upgrade info, that returns that list of indices that require upgrade in the current cluster before the cluster can be upgraded to the next major version. Relates to elastic/x-pack-elasticsearch#1214 Original commit: elastic/x-pack-elasticsearch@761e7d2128
This commit is contained in:
parent
84574c0367
commit
bb034f42b8
|
@ -100,6 +100,8 @@ import org.elasticsearch.xpack.security.authc.AuthenticationService;
|
|||
import org.elasticsearch.xpack.security.authc.support.UsernamePasswordToken;
|
||||
import org.elasticsearch.xpack.ssl.SSLConfigurationReloader;
|
||||
import org.elasticsearch.xpack.ssl.SSLService;
|
||||
import org.elasticsearch.xpack.upgrade.Upgrade;
|
||||
import org.elasticsearch.xpack.upgrade.InternalIndexUpgradeCheck;
|
||||
import org.elasticsearch.xpack.watcher.Watcher;
|
||||
import org.elasticsearch.xpack.watcher.WatcherFeatureSet;
|
||||
|
||||
|
@ -108,11 +110,7 @@ import java.io.IOException;
|
|||
import java.nio.file.Path;
|
||||
import java.security.AccessController;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.time.Clock;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -203,6 +201,7 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I
|
|||
protected MachineLearning machineLearning;
|
||||
protected Logstash logstash;
|
||||
protected Deprecation deprecation;
|
||||
protected Upgrade upgrade;
|
||||
|
||||
public XPackPlugin(
|
||||
final Settings settings,
|
||||
|
@ -221,6 +220,7 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I
|
|||
this.machineLearning = new MachineLearning(settings, env, licenseState);
|
||||
this.logstash = new Logstash(settings);
|
||||
this.deprecation = new Deprecation();
|
||||
this.upgrade = new Upgrade(settings, Collections.singletonList(new InternalIndexUpgradeCheck()));
|
||||
// Check if the node is a transport client.
|
||||
if (transportClientMode == false) {
|
||||
this.extensionsService = new XPackExtensionsService(settings, resolveXPackExtensionsFile(env), getExtensions());
|
||||
|
@ -301,6 +301,9 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I
|
|||
|
||||
components.addAll(logstash.createComponents(internalClient, clusterService));
|
||||
|
||||
components.addAll(upgrade.createComponents(internalClient, clusterService, threadPool, resourceWatcherService,
|
||||
scriptService, xContentRegistry));
|
||||
|
||||
// just create the reloader as it will pull all of the loaded ssl configurations and start watching them
|
||||
new SSLConfigurationReloader(settings, env, sslService, resourceWatcherService);
|
||||
return components;
|
||||
|
@ -425,6 +428,7 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I
|
|||
actions.addAll(graph.getActions());
|
||||
actions.addAll(machineLearning.getActions());
|
||||
actions.addAll(deprecation.getActions());
|
||||
actions.addAll(upgrade.getActions());
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
@ -436,6 +440,7 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I
|
|||
filters.addAll(security.getActionFilters());
|
||||
filters.addAll(watcher.getActionFilters());
|
||||
filters.addAll(machineLearning.getActionFilters());
|
||||
filters.addAll(upgrade.getActionFilters());
|
||||
return filters;
|
||||
}
|
||||
|
||||
|
@ -460,6 +465,8 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I
|
|||
indexNameExpressionResolver, nodesInCluster));
|
||||
handlers.addAll(deprecation.getRestHandlers(settings, restController, clusterSettings, indexScopedSettings, settingsFilter,
|
||||
indexNameExpressionResolver, nodesInCluster));
|
||||
handlers.addAll(upgrade.getRestHandlers(settings, restController, clusterSettings, indexScopedSettings, settingsFilter,
|
||||
indexNameExpressionResolver, nodesInCluster));
|
||||
return handlers;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.upgrade;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Generic upgrade check applicable to all indices to be upgraded from the current version
|
||||
* to the next major version
|
||||
*/
|
||||
public class GenericIndexUpgradeCheck implements IndexUpgradeCheck {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "generic";
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpgradeActionRequired actionRequired(IndexMetaData indexMetaData, Map<String, String> params, ClusterState state) {
|
||||
if (indexMetaData.getCreationVersion().before(Version.V_5_0_0_alpha1)) {
|
||||
return UpgradeActionRequired.REINDEX;
|
||||
}
|
||||
return UpgradeActionRequired.UP_TO_DATE;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.upgrade;
|
||||
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Interface that for an index check and upgrade process
|
||||
*/
|
||||
public interface IndexUpgradeCheck {
|
||||
String getName();
|
||||
|
||||
UpgradeActionRequired actionRequired(IndexMetaData indexMetaData, Map<String, String> params, ClusterState state);
|
||||
|
||||
default Collection<String> supportedParams() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.upgrade;
|
||||
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.common.component.AbstractComponent;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class IndexUpgradeService extends AbstractComponent {
|
||||
|
||||
private final List<IndexUpgradeCheck> upgradeChecks;
|
||||
|
||||
private final IndexNameExpressionResolver indexNameExpressionResolver;
|
||||
|
||||
public IndexUpgradeService(Settings settings, List<IndexUpgradeCheck> upgradeChecks) {
|
||||
super(settings);
|
||||
this.upgradeChecks = upgradeChecks;
|
||||
this.indexNameExpressionResolver = new IndexNameExpressionResolver(settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the information about required upgrade action for the given indices
|
||||
*
|
||||
* @param indices list of indices to check, specify _all for all indices
|
||||
* @param options wild card resolution option
|
||||
* @param params list of additional parameters that will be passed to upgrade checks
|
||||
* @param state the current cluster state
|
||||
* @return a list of indices that should be upgraded/reindexed
|
||||
*/
|
||||
public Map<String, UpgradeActionRequired> upgradeInfo(String[] indices, IndicesOptions options, Map<String, String> params,
|
||||
ClusterState state) {
|
||||
Map<String, UpgradeActionRequired> results = new HashMap<>();
|
||||
String[] concreteIndexNames = indexNameExpressionResolver.concreteIndexNames(state, options, indices);
|
||||
MetaData metaData = state.getMetaData();
|
||||
for (String index : concreteIndexNames) {
|
||||
IndexMetaData indexMetaData = metaData.index(index);
|
||||
indexCheck:
|
||||
for (IndexUpgradeCheck check : upgradeChecks) {
|
||||
UpgradeActionRequired upgradeActionRequired = check.actionRequired(indexMetaData, params, state);
|
||||
logger.trace("[{}] check [{}] returned [{}]", index, check.getName(), upgradeActionRequired);
|
||||
switch (upgradeActionRequired) {
|
||||
case UPGRADE:
|
||||
case REINDEX:
|
||||
// this index needs to be upgraded or reindexed - skipping all other checks
|
||||
results.put(index, upgradeActionRequired);
|
||||
break indexCheck;
|
||||
case UP_TO_DATE:
|
||||
// this index is good - skipping all other checks
|
||||
break indexCheck;
|
||||
case NOT_APPLICABLE:
|
||||
// this action is not applicable to this index - skipping to the next one
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("unknown upgrade action " + upgradeActionRequired + " for the index "
|
||||
+ index);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.upgrade;
|
||||
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.regex.Regex;
|
||||
import org.elasticsearch.tasks.TaskResultsService;
|
||||
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
||||
import org.elasticsearch.xpack.watcher.watch.Watch;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Generic upgrade check applicable to all indices to be upgraded from the current version
|
||||
* to the next major version
|
||||
*/
|
||||
public class InternalIndexUpgradeCheck implements IndexUpgradeCheck {
|
||||
private final Set<String> KNOWN_INTERNAL_INDICES = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
|
||||
Watch.INDEX,
|
||||
SecurityLifecycleService.SECURITY_INDEX_NAME,
|
||||
TaskResultsService.TASK_INDEX
|
||||
)));
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "inner";
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpgradeActionRequired actionRequired(IndexMetaData indexMetaData, Map<String, String> params, ClusterState state) {
|
||||
String indexName = indexMetaData.getIndex().getName();
|
||||
if (KNOWN_INTERNAL_INDICES.contains(indexName)) {
|
||||
return UpgradeActionRequired.UPGRADE;
|
||||
}
|
||||
if (isKibanaIndex(params.getOrDefault("kibana_indices", ".kibana"), indexName)) {
|
||||
return UpgradeActionRequired.UPGRADE;
|
||||
}
|
||||
return UpgradeActionRequired.NOT_APPLICABLE;
|
||||
}
|
||||
|
||||
private boolean isKibanaIndex(String kibanaIndicesMasks, String indexName) {
|
||||
String[] kibanaIndices = Strings.delimitedListToStringArray(kibanaIndicesMasks, ",");
|
||||
return Regex.simpleMatch(kibanaIndices, indexName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> supportedParams() {
|
||||
return Collections.singletonList("kibana_indices");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.upgrade;
|
||||
|
||||
import org.elasticsearch.action.ActionRequest;
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNodes;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.IndexScopedSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.SettingsFilter;
|
||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||
import org.elasticsearch.license.XPackLicenseState;
|
||||
import org.elasticsearch.plugins.ActionPlugin;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestHandler;
|
||||
import org.elasticsearch.script.ScriptService;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.watcher.ResourceWatcherService;
|
||||
import org.elasticsearch.xpack.security.InternalClient;
|
||||
import org.elasticsearch.xpack.upgrade.actions.IndexUpgradeInfoAction;
|
||||
import org.elasticsearch.xpack.upgrade.rest.RestIndexUpgradeInfoAction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class Upgrade implements ActionPlugin {
|
||||
|
||||
private Settings settings;
|
||||
private List<IndexUpgradeCheck> customUpgradeChecks;
|
||||
private Set<String> extraParameters;
|
||||
|
||||
public Upgrade(Settings settings, List<IndexUpgradeCheck> customUpgradeChecks) {
|
||||
this.settings = settings;
|
||||
this.customUpgradeChecks = customUpgradeChecks;
|
||||
this.extraParameters = new HashSet<>();
|
||||
for (IndexUpgradeCheck check : customUpgradeChecks) {
|
||||
extraParameters.addAll(check.supportedParams());
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<Object> createComponents(InternalClient internalClient, ClusterService clusterService, ThreadPool threadPool,
|
||||
ResourceWatcherService resourceWatcherService, ScriptService scriptService,
|
||||
NamedXContentRegistry xContentRegistry) {
|
||||
|
||||
List<IndexUpgradeCheck> upgradeChecks = new ArrayList<>(customUpgradeChecks);
|
||||
|
||||
// The generic test goes to the end of the list
|
||||
upgradeChecks.add(new GenericIndexUpgradeCheck());
|
||||
|
||||
return Collections.singletonList(new IndexUpgradeService(settings, upgradeChecks));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> getActions() {
|
||||
return Collections.singletonList(
|
||||
new ActionHandler<>(IndexUpgradeInfoAction.INSTANCE, IndexUpgradeInfoAction.TransportAction.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RestHandler> getRestHandlers(Settings settings, RestController restController, ClusterSettings clusterSettings,
|
||||
IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter,
|
||||
IndexNameExpressionResolver indexNameExpressionResolver,
|
||||
Supplier<DiscoveryNodes> nodesInCluster) {
|
||||
return Collections.singletonList(
|
||||
new RestIndexUpgradeInfoAction(settings, restController, extraParameters)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.upgrade;
|
||||
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Indicates the type of the upgrade required for the index
|
||||
*/
|
||||
public enum UpgradeActionRequired implements Writeable {
|
||||
NOT_APPLICABLE, // Indicates that the check is not applicable to this index type, the next check will be performed
|
||||
UP_TO_DATE, // Indicates that the check finds this index to be up to date - no additional checks are required
|
||||
REINDEX, // The index should be reindex
|
||||
UPGRADE; // The index should go through the upgrade procedure
|
||||
|
||||
public static UpgradeActionRequired fromString(String value) {
|
||||
return UpgradeActionRequired.valueOf(value.toUpperCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
public static UpgradeActionRequired readFromStream(StreamInput in) throws IOException {
|
||||
return in.readEnum(UpgradeActionRequired.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeEnum(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.upgrade.actions;
|
||||
|
||||
import org.elasticsearch.action.Action;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.ActionRequestValidationException;
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.action.IndicesRequest;
|
||||
import org.elasticsearch.action.support.ActionFilters;
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.action.support.master.MasterNodeReadOperationRequestBuilder;
|
||||
import org.elasticsearch.action.support.master.MasterNodeReadRequest;
|
||||
import org.elasticsearch.action.support.master.TransportMasterNodeReadAction;
|
||||
import org.elasticsearch.client.ElasticsearchClient;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.block.ClusterBlockException;
|
||||
import org.elasticsearch.cluster.block.ClusterBlockLevel;
|
||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
import org.elasticsearch.xpack.upgrade.IndexUpgradeService;
|
||||
import org.elasticsearch.xpack.upgrade.UpgradeActionRequired;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.elasticsearch.action.ValidateActions.addValidationError;
|
||||
|
||||
public class IndexUpgradeInfoAction extends Action<IndexUpgradeInfoAction.Request, IndexUpgradeInfoAction.Response,
|
||||
IndexUpgradeInfoAction.RequestBuilder> {
|
||||
|
||||
public static final IndexUpgradeInfoAction INSTANCE = new IndexUpgradeInfoAction();
|
||||
public static final String NAME = "cluster:admin/xpack/upgrade/info";
|
||||
|
||||
private IndexUpgradeInfoAction() {
|
||||
super(NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestBuilder newRequestBuilder(ElasticsearchClient client) {
|
||||
return new RequestBuilder(client, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response newResponse() {
|
||||
return new Response();
|
||||
}
|
||||
|
||||
public static class Response extends ActionResponse implements ToXContentObject {
|
||||
private Map<String, UpgradeActionRequired> actions;
|
||||
|
||||
protected Response() {
|
||||
|
||||
}
|
||||
|
||||
public Response(Map<String, UpgradeActionRequired> actions) {
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFrom(StreamInput in) throws IOException {
|
||||
super.readFrom(in);
|
||||
actions = in.readMap(StreamInput::readString, UpgradeActionRequired::readFromStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
super.writeTo(out);
|
||||
out.writeMap(actions, StreamOutput::writeString, (out1, value) -> value.writeTo(out1));
|
||||
}
|
||||
|
||||
public Map<String, UpgradeActionRequired> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
{
|
||||
builder.startObject("indices");
|
||||
for (Map.Entry<String, UpgradeActionRequired> entry : actions.entrySet()) {
|
||||
builder.startObject(entry.getKey());
|
||||
{
|
||||
builder.field("action_required", entry.getValue().toString());
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Response response = (Response) o;
|
||||
return Objects.equals(actions, response.actions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(actions);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Request extends MasterNodeReadRequest<Request> implements IndicesRequest.Replaceable {
|
||||
|
||||
private String[] indices = null;
|
||||
private IndicesOptions indicesOptions = IndicesOptions.fromOptions(false, false, true, true);
|
||||
private Map<String, String> extraParams = Collections.emptyMap();
|
||||
|
||||
// for serialization
|
||||
public Request() {
|
||||
|
||||
}
|
||||
|
||||
public Request(String... indices) {
|
||||
this.indices = indices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] indices() {
|
||||
return indices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request indices(String... indices) {
|
||||
this.indices = indices;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndicesOptions indicesOptions() {
|
||||
return indicesOptions;
|
||||
}
|
||||
|
||||
public void indicesOptions(IndicesOptions indicesOptions) {
|
||||
this.indicesOptions = indicesOptions;
|
||||
}
|
||||
|
||||
public Map<String, String> extraParams() {
|
||||
return extraParams;
|
||||
}
|
||||
|
||||
public Request extraParams(Map<String, String> extraParams) {
|
||||
this.extraParams = extraParams;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionRequestValidationException validate() {
|
||||
ActionRequestValidationException validationException = null;
|
||||
if (indices == null) {
|
||||
validationException = addValidationError("index/indices is missing", validationException);
|
||||
}
|
||||
if (extraParams == null) {
|
||||
validationException = addValidationError("params are missing", validationException);
|
||||
}
|
||||
return validationException;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFrom(StreamInput in) throws IOException {
|
||||
super.readFrom(in);
|
||||
indices = in.readStringArray();
|
||||
indicesOptions = IndicesOptions.readIndicesOptions(in);
|
||||
extraParams = in.readMap(StreamInput::readString, StreamInput::readString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
super.writeTo(out);
|
||||
out.writeStringArray(indices);
|
||||
indicesOptions.writeIndicesOptions(out);
|
||||
out.writeMap(extraParams, StreamOutput::writeString, StreamOutput::writeString);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Request request = (Request) o;
|
||||
return Arrays.equals(indices, request.indices) &&
|
||||
Objects.equals(indicesOptions.toString(), request.indicesOptions.toString()) &&
|
||||
Objects.equals(extraParams, request.extraParams);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(Arrays.hashCode(indices), indicesOptions.toString(), extraParams);
|
||||
}
|
||||
}
|
||||
|
||||
public static class RequestBuilder extends MasterNodeReadOperationRequestBuilder<Request, Response, RequestBuilder> {
|
||||
|
||||
protected RequestBuilder(ElasticsearchClient client, IndexUpgradeInfoAction action) {
|
||||
super(client, action, new Request());
|
||||
}
|
||||
|
||||
public RequestBuilder setIndices(String... indices) {
|
||||
request.indices(indices);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder setIndicesOptions(IndicesOptions indicesOptions) {
|
||||
request.indicesOptions(indicesOptions);
|
||||
return this;
|
||||
}
|
||||
|
||||
public RequestBuilder setExtraParams(Map<String, String> params) {
|
||||
request.extraParams(params);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static class TransportAction extends TransportMasterNodeReadAction<Request, Response> {
|
||||
|
||||
private final IndexUpgradeService indexUpgradeService;
|
||||
|
||||
@Inject
|
||||
public TransportAction(Settings settings, TransportService transportService, ClusterService clusterService,
|
||||
ThreadPool threadPool, ActionFilters actionFilters,
|
||||
IndexUpgradeService indexUpgradeService,
|
||||
IndexNameExpressionResolver indexNameExpressionResolver) {
|
||||
super(settings, IndexUpgradeInfoAction.NAME, transportService, clusterService, threadPool, actionFilters,
|
||||
indexNameExpressionResolver, Request::new);
|
||||
this.indexUpgradeService = indexUpgradeService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String executor() {
|
||||
return ThreadPool.Names.GENERIC;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Response newResponse() {
|
||||
return new Response();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClusterBlockException checkBlock(Request request, ClusterState state) {
|
||||
// Cluster is not affected but we look up repositories in metadata
|
||||
return state.blocks().globalBlockedException(ClusterBlockLevel.METADATA_READ);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void masterOperation(final Request request, ClusterState state, final ActionListener<Response> listener) {
|
||||
Map<String, UpgradeActionRequired> results =
|
||||
indexUpgradeService.upgradeInfo(request.indices(), request.indicesOptions(), request.extraParams(), state);
|
||||
listener.onResponse(new Response(results));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.upgrade.rest;
|
||||
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.client.node.NodeClient;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.rest.BaseRestHandler;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
import org.elasticsearch.rest.action.RestToXContentListener;
|
||||
import org.elasticsearch.xpack.upgrade.actions.IndexUpgradeInfoAction;
|
||||
import org.elasticsearch.xpack.upgrade.actions.IndexUpgradeInfoAction.Request;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class RestIndexUpgradeInfoAction extends BaseRestHandler {
|
||||
private final Set<String> extraParameters;
|
||||
|
||||
public RestIndexUpgradeInfoAction(Settings settings, RestController controller, Set<String> extraParameters) {
|
||||
super(settings);
|
||||
controller.registerHandler(RestRequest.Method.GET, "/_xpack/_upgrade", this);
|
||||
controller.registerHandler(RestRequest.Method.GET, "{index}/_xpack/_upgrade", this);
|
||||
this.extraParameters = extraParameters;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
|
||||
if (request.method().equals(RestRequest.Method.GET)) {
|
||||
return handleGet(request, client);
|
||||
} else {
|
||||
throw new IllegalArgumentException("illegal method [" + request.method() + "] for request [" + request.path() + "]");
|
||||
}
|
||||
}
|
||||
|
||||
private RestChannelConsumer handleGet(final RestRequest request, NodeClient client) {
|
||||
Request infoRequest = new Request(Strings.splitStringByCommaToArray(request.param("index")));
|
||||
infoRequest.indicesOptions(IndicesOptions.fromRequest(request, infoRequest.indicesOptions()));
|
||||
Map<String, String> extraParamsMap = new HashMap<>();
|
||||
for (String param : extraParameters) {
|
||||
String value = request.param(param);
|
||||
if (value != null) {
|
||||
extraParamsMap.put(param, value);
|
||||
}
|
||||
}
|
||||
infoRequest.extraParams(extraParamsMap);
|
||||
return channel -> client.execute(IndexUpgradeInfoAction.INSTANCE, infoRequest, new RestToXContentListener<>(channel));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.upgrade;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.common.UUIDs;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.hamcrest.core.IsEqual.equalTo;
|
||||
|
||||
public class IndexUpgradeCheckTests extends ESTestCase {
|
||||
|
||||
public void testGenericUpgradeCheck() {
|
||||
IndexUpgradeCheck check = new GenericIndexUpgradeCheck();
|
||||
assertThat(check.getName(), equalTo("generic"));
|
||||
IndexMetaData goodIndex = newTestIndexMeta("good", Settings.EMPTY);
|
||||
IndexMetaData badIndex = newTestIndexMeta("bad",
|
||||
Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.fromString("2.0.0")).build());
|
||||
|
||||
assertThat(check.actionRequired(goodIndex, Collections.emptyMap(), ClusterState.EMPTY_STATE),
|
||||
equalTo(UpgradeActionRequired.UP_TO_DATE));
|
||||
assertThat(check.actionRequired(badIndex, Collections.emptyMap(), ClusterState.EMPTY_STATE),
|
||||
equalTo(UpgradeActionRequired.REINDEX));
|
||||
}
|
||||
|
||||
public void testInternalUpgradeCheck() {
|
||||
IndexUpgradeCheck check = new InternalIndexUpgradeCheck();
|
||||
assertThat(check.getName(), equalTo("inner"));
|
||||
IndexMetaData goodKibanaIndex = newTestIndexMeta(".kibana", Settings.EMPTY);
|
||||
assertThat(check.actionRequired(goodKibanaIndex, Collections.emptyMap(), ClusterState.EMPTY_STATE),
|
||||
equalTo(UpgradeActionRequired.UPGRADE));
|
||||
|
||||
IndexMetaData renamedKibanaIndex = newTestIndexMeta(".kibana2", Settings.EMPTY);
|
||||
assertThat(check.actionRequired(renamedKibanaIndex, Collections.emptyMap(), ClusterState.EMPTY_STATE),
|
||||
equalTo(UpgradeActionRequired.NOT_APPLICABLE));
|
||||
|
||||
assertThat(check.actionRequired(renamedKibanaIndex, Collections.singletonMap("kibana_indices", ".kibana*"),
|
||||
ClusterState.EMPTY_STATE), equalTo(UpgradeActionRequired.UPGRADE));
|
||||
|
||||
assertThat(check.actionRequired(renamedKibanaIndex, Collections.singletonMap("kibana_indices", ".kibana1,.kibana2"),
|
||||
ClusterState.EMPTY_STATE), equalTo(UpgradeActionRequired.UPGRADE));
|
||||
|
||||
IndexMetaData watcherIndex = newTestIndexMeta(".watches", Settings.EMPTY);
|
||||
assertThat(check.actionRequired(watcherIndex, Collections.singletonMap("kibana_indices", ".kibana*"), ClusterState.EMPTY_STATE),
|
||||
equalTo(UpgradeActionRequired.UPGRADE));
|
||||
|
||||
IndexMetaData securityIndex = newTestIndexMeta(".security", Settings.EMPTY);
|
||||
assertThat(check.actionRequired(securityIndex, Collections.singletonMap("kibana_indices", ".kibana*"), ClusterState.EMPTY_STATE),
|
||||
equalTo(UpgradeActionRequired.UPGRADE));
|
||||
}
|
||||
|
||||
public static IndexMetaData newTestIndexMeta(String name, Settings indexSettings) {
|
||||
Settings build = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 1)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
|
||||
.put(IndexMetaData.SETTING_CREATION_DATE, 1)
|
||||
.put(IndexMetaData.SETTING_INDEX_UUID, UUIDs.randomBase64UUID())
|
||||
.put(IndexMetaData.SETTING_VERSION_UPGRADED, Version.V_5_0_0_beta1)
|
||||
.put(indexSettings)
|
||||
.build();
|
||||
return IndexMetaData.builder(name).settings(build).build();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.upgrade;
|
||||
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.test.ESIntegTestCase;
|
||||
import org.elasticsearch.xpack.XPackPlugin;
|
||||
import org.elasticsearch.xpack.XPackSettings;
|
||||
import org.elasticsearch.xpack.ml.MachineLearning;
|
||||
import org.elasticsearch.xpack.upgrade.actions.IndexUpgradeInfoAction;
|
||||
import org.elasticsearch.xpack.upgrade.actions.IndexUpgradeInfoAction.Response;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.core.IsEqual.equalTo;
|
||||
|
||||
public class IndexUpgradeIT extends ESIntegTestCase {
|
||||
|
||||
@Override
|
||||
protected boolean ignoreExternalCluster() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Settings nodeSettings(int nodeOrdinal) {
|
||||
Settings.Builder settings = Settings.builder().put(super.nodeSettings(nodeOrdinal));
|
||||
settings.put(MachineLearning.AUTODETECT_PROCESS.getKey(), false);
|
||||
settings.put(XPackSettings.MACHINE_LEARNING_ENABLED.getKey(), false);
|
||||
settings.put(XPackSettings.SECURITY_ENABLED.getKey(), false);
|
||||
settings.put(XPackSettings.WATCHER_ENABLED.getKey(), false);
|
||||
settings.put(XPackSettings.MONITORING_ENABLED.getKey(), false);
|
||||
settings.put(XPackSettings.GRAPH_ENABLED.getKey(), false);
|
||||
return settings.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Settings transportClientSettings() {
|
||||
Settings.Builder settings = Settings.builder().put(super.transportClientSettings());
|
||||
settings.put(MachineLearning.AUTODETECT_PROCESS.getKey(), false);
|
||||
settings.put(XPackSettings.MACHINE_LEARNING_ENABLED.getKey(), false);
|
||||
settings.put(XPackSettings.SECURITY_ENABLED.getKey(), false);
|
||||
settings.put(XPackSettings.WATCHER_ENABLED.getKey(), false);
|
||||
settings.put(XPackSettings.MONITORING_ENABLED.getKey(), false);
|
||||
settings.put(XPackSettings.GRAPH_ENABLED.getKey(), false);
|
||||
return settings.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> nodePlugins() {
|
||||
return Collections.singleton(XPackPlugin.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Class<? extends Plugin>> transportClientPlugins() {
|
||||
return nodePlugins();
|
||||
}
|
||||
|
||||
|
||||
public void testIndexUpgradeInfo() {
|
||||
assertAcked(client().admin().indices().prepareCreate("test").get());
|
||||
assertAcked(client().admin().indices().prepareCreate("kibana_test").get());
|
||||
ensureYellow("test");
|
||||
Response response = client().prepareExecute(IndexUpgradeInfoAction.INSTANCE).setIndices("test", "kibana_test")
|
||||
.setExtraParams(Collections.singletonMap("kibana_indices", "kibana_test")).get();
|
||||
logger.info("Got response [{}]", Strings.toString(response));
|
||||
assertThat(response.getActions().size(), equalTo(1));
|
||||
assertThat(response.getActions().get("kibana_test"), equalTo(UpgradeActionRequired.UPGRADE));
|
||||
assertThat(Strings.toString(response), containsString("kibana_test"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.upgrade;
|
||||
|
||||
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.xpack.upgrade.IndexUpgradeCheckTests.newTestIndexMeta;
|
||||
import static org.hamcrest.core.IsEqual.equalTo;
|
||||
|
||||
public class IndexUpgradeServiceTests extends ESTestCase {
|
||||
|
||||
private IndexUpgradeCheck upgradeBarCheck = new IndexUpgradeCheck() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "upgrade_bar";
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpgradeActionRequired actionRequired(IndexMetaData indexMetaData, Map<String, String> params, ClusterState state) {
|
||||
if ("bar".equals(indexMetaData.getSettings().get("test.setting"))) {
|
||||
return UpgradeActionRequired.UPGRADE;
|
||||
}
|
||||
return UpgradeActionRequired.NOT_APPLICABLE;
|
||||
}
|
||||
};
|
||||
|
||||
private IndexUpgradeCheck reindexFooCheck = new IndexUpgradeCheck() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "reindex_foo";
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpgradeActionRequired actionRequired(IndexMetaData indexMetaData, Map<String, String> params, ClusterState state) {
|
||||
if ("foo".equals(indexMetaData.getSettings().get("test.setting"))) {
|
||||
return UpgradeActionRequired.REINDEX;
|
||||
}
|
||||
return UpgradeActionRequired.NOT_APPLICABLE;
|
||||
}
|
||||
};
|
||||
|
||||
private IndexUpgradeCheck everythingIsFineCheck = new IndexUpgradeCheck() {
|
||||
@Override
|
||||
public String getName() {
|
||||
return "everything_is_fine";
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpgradeActionRequired actionRequired(IndexMetaData indexMetaData, Map<String, String> params, ClusterState state) {
|
||||
return UpgradeActionRequired.UP_TO_DATE;
|
||||
}
|
||||
};
|
||||
|
||||
private IndexUpgradeCheck unreachableCheck = new IndexUpgradeCheck() {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "unreachable";
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpgradeActionRequired actionRequired(IndexMetaData indexMetaData, Map<String, String> params, ClusterState state) {
|
||||
fail("Unreachable check is called");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
public void testIndexUpgradeServiceMultipleCheck() {
|
||||
IndexUpgradeService service;
|
||||
if (randomBoolean()) {
|
||||
service = new IndexUpgradeService(Settings.EMPTY, Arrays.asList(
|
||||
upgradeBarCheck,
|
||||
reindexFooCheck,
|
||||
everythingIsFineCheck,
|
||||
unreachableCheck // This one should never be called
|
||||
));
|
||||
} else {
|
||||
service = new IndexUpgradeService(Settings.EMPTY, Arrays.asList(
|
||||
reindexFooCheck,
|
||||
upgradeBarCheck,
|
||||
everythingIsFineCheck,
|
||||
unreachableCheck // This one should never be called
|
||||
));
|
||||
}
|
||||
|
||||
IndexMetaData fooIndex = newTestIndexMeta("bar", Settings.builder().put("test.setting", "bar").build());
|
||||
IndexMetaData barIndex = newTestIndexMeta("foo", Settings.builder().put("test.setting", "foo").build());
|
||||
IndexMetaData bazIndex = newTestIndexMeta("baz", Settings.EMPTY);
|
||||
|
||||
ClusterState clusterState = mockClusterState(fooIndex, barIndex, bazIndex);
|
||||
|
||||
Map<String, UpgradeActionRequired> result = service.upgradeInfo(new String[]{"bar", "foo", "baz"},
|
||||
IndicesOptions.lenientExpandOpen(), Collections.emptyMap(), clusterState);
|
||||
|
||||
assertThat(result.size(), equalTo(2));
|
||||
assertThat(result.get("bar"), equalTo(UpgradeActionRequired.UPGRADE));
|
||||
assertThat(result.get("foo"), equalTo(UpgradeActionRequired.REINDEX));
|
||||
|
||||
result = service.upgradeInfo(new String[]{"b*"}, IndicesOptions.lenientExpandOpen(), Collections.emptyMap(), clusterState);
|
||||
|
||||
assertThat(result.size(), equalTo(1));
|
||||
assertThat(result.get("bar"), equalTo(UpgradeActionRequired.UPGRADE));
|
||||
}
|
||||
|
||||
|
||||
public void testNoMatchingChecks() {
|
||||
IndexUpgradeService service = new IndexUpgradeService(Settings.EMPTY, Arrays.asList(
|
||||
upgradeBarCheck,
|
||||
reindexFooCheck
|
||||
));
|
||||
|
||||
IndexMetaData fooIndex = newTestIndexMeta("bar", Settings.builder().put("test.setting", "bar").build());
|
||||
IndexMetaData barIndex = newTestIndexMeta("foo", Settings.builder().put("test.setting", "foo").build());
|
||||
IndexMetaData bazIndex = newTestIndexMeta("baz", Settings.EMPTY);
|
||||
|
||||
ClusterState clusterState = mockClusterState(fooIndex, barIndex, bazIndex);
|
||||
|
||||
Map<String, UpgradeActionRequired> result = service.upgradeInfo(new String[]{"bar", "foo", "baz"},
|
||||
IndicesOptions.lenientExpandOpen(), Collections.emptyMap(), clusterState);
|
||||
|
||||
assertThat(result.size(), equalTo(2));
|
||||
assertThat(result.get("bar"), equalTo(UpgradeActionRequired.UPGRADE));
|
||||
assertThat(result.get("foo"), equalTo(UpgradeActionRequired.REINDEX));
|
||||
}
|
||||
|
||||
public void testEarlierChecksWin() {
|
||||
|
||||
IndexUpgradeService service = new IndexUpgradeService(Settings.EMPTY, Arrays.asList(
|
||||
everythingIsFineCheck,
|
||||
upgradeBarCheck,
|
||||
reindexFooCheck
|
||||
));
|
||||
|
||||
IndexMetaData fooIndex = newTestIndexMeta("bar", Settings.builder().put("test.setting", "bar").build());
|
||||
IndexMetaData barIndex = newTestIndexMeta("foo", Settings.builder().put("test.setting", "foo").build());
|
||||
IndexMetaData bazIndex = newTestIndexMeta("baz", Settings.EMPTY);
|
||||
|
||||
ClusterState clusterState = mockClusterState(fooIndex, barIndex, bazIndex);
|
||||
|
||||
Map<String, UpgradeActionRequired> result = service.upgradeInfo(new String[]{"bar", "foo", "baz"},
|
||||
IndicesOptions.lenientExpandOpen(), Collections.emptyMap(), clusterState);
|
||||
|
||||
assertThat(result.size(), equalTo(0)); // everything as the first checker should indicate that everything is fine
|
||||
|
||||
}
|
||||
|
||||
private ClusterState mockClusterState(IndexMetaData... indices) {
|
||||
MetaData.Builder metaDataBuilder = MetaData.builder();
|
||||
for (IndexMetaData indexMetaData : indices) {
|
||||
metaDataBuilder.put(indexMetaData, false);
|
||||
}
|
||||
return ClusterState.builder(ClusterName.DEFAULT).metaData(metaDataBuilder).build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.upgrade.actions;
|
||||
|
||||
import org.elasticsearch.action.support.IndicesOptions;
|
||||
import org.elasticsearch.test.AbstractStreamableTestCase;
|
||||
import org.elasticsearch.xpack.upgrade.actions.IndexUpgradeInfoAction.Request;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class IndexUpgradeInfoActionRequestTests extends AbstractStreamableTestCase<Request> {
|
||||
@Override
|
||||
protected Request createTestInstance() {
|
||||
int indexCount = randomInt(4);
|
||||
String[] indices = new String[indexCount];
|
||||
for (int i = 0; i < indexCount; i++) {
|
||||
indices[i] = randomAlphaOfLength(10);
|
||||
}
|
||||
Request request = new Request(indices);
|
||||
if (randomBoolean()) {
|
||||
request.extraParams(Collections.singletonMap(randomAlphaOfLength(10), randomAlphaOfLength(20)));
|
||||
}
|
||||
if (randomBoolean()) {
|
||||
request.indicesOptions(IndicesOptions.fromOptions(randomBoolean(), randomBoolean(), randomBoolean(), randomBoolean()));
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Request createBlankInstance() {
|
||||
return new Request();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.upgrade.actions;
|
||||
|
||||
import org.elasticsearch.test.AbstractStreamableTestCase;
|
||||
import org.elasticsearch.xpack.upgrade.UpgradeActionRequired;
|
||||
import org.elasticsearch.xpack.upgrade.actions.IndexUpgradeInfoAction.Response;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class IndexUpgradeInfoActionResponseTests extends AbstractStreamableTestCase<Response> {
|
||||
|
||||
|
||||
@Override
|
||||
protected Response createTestInstance() {
|
||||
int actionsCount = randomIntBetween(0, 5);
|
||||
Map<String, UpgradeActionRequired> actions = new HashMap<>(actionsCount);
|
||||
for (int i = 0; i < actionsCount; i++) {
|
||||
actions.put(randomAlphaOfLength(10), randomFrom(EnumSet.allOf(UpgradeActionRequired.class)));
|
||||
}
|
||||
return new Response(actions);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Response createBlankInstance() {
|
||||
return new Response();
|
||||
}
|
||||
}
|
|
@ -156,3 +156,4 @@ indices:data/write/update/byquery
|
|||
indices:data/write/delete/byquery
|
||||
indices:data/write/reindex
|
||||
cluster:admin/xpack/deprecation/info
|
||||
cluster:admin/xpack/upgrade/info
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"xpack.upgrade.info": {
|
||||
"methods": [ "GET" ],
|
||||
"url": {
|
||||
"path": "/_xpack/_upgrade",
|
||||
"paths": [
|
||||
"/_xpack/_upgrade",
|
||||
"/{index}/_xpack/_upgrade"
|
||||
],
|
||||
"parts": {
|
||||
"index": {
|
||||
"type" : "list",
|
||||
"description" : "A comma-separated list of index names; use `_all` or empty string to perform the operation on all indices"
|
||||
}
|
||||
},
|
||||
"params": {
|
||||
"allow_no_indices": {
|
||||
"type" : "boolean",
|
||||
"description" : "Whether to ignore if a wildcard indices expression resolves into no concrete indices. (This includes `_all` string or when no indices have been specified)"
|
||||
},
|
||||
"expand_wildcards": {
|
||||
"type" : "enum",
|
||||
"options" : ["open","closed","none","all"],
|
||||
"default" : "open",
|
||||
"description" : "Whether to expand wildcard expression to concrete indices that are open, closed or both."
|
||||
},
|
||||
"ignore_unavailable": {
|
||||
"type" : "boolean",
|
||||
"description" : "Whether specified concrete indices should be ignored when unavailable (missing or closed)"
|
||||
},
|
||||
"wait_for_completion": {
|
||||
"type" : "boolean",
|
||||
"description" : "Specify whether the request should block until the all segments are upgraded (default: false)"
|
||||
},
|
||||
"kibana_indices": {
|
||||
"type": "list",
|
||||
"description": "A comma separated list of indices that should be treated as kibana indices"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
setup:
|
||||
- do:
|
||||
indices.create:
|
||||
index: test1
|
||||
|
||||
- do:
|
||||
indices.create:
|
||||
index: test2
|
||||
|
||||
---
|
||||
"Index - all":
|
||||
- do:
|
||||
xpack.upgrade.info: { index: _all }
|
||||
|
||||
- length: { indices: 0 }
|
||||
|
||||
---
|
||||
"Index - treat test2 as kibana":
|
||||
- do:
|
||||
xpack.upgrade.info: { index: _all, kibana_indices: test2 }
|
||||
|
||||
- length: { indices: 1 }
|
||||
- match: { indices.test2.action_required: "upgrade" }
|
Loading…
Reference in New Issue