From 811286d5a7c5b4e35264133a27e0fbbf8f35b42c Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Thu, 9 Jul 2020 13:48:22 -0700 Subject: [PATCH 01/11] Add license feature usage api This commit adds a new api to track when gold+ features are used within x-pack. The tracking is done internally whenever a feature is checked against the current license. The output of the api is a list of each used feature, which includes the name, license level, and last time it was used. In addition to a unit test for the tracking, a rest test is added which ensures starting up a default configured node does not result in any features registering as used. There are a couple features which currently do not work well with the tracking, as they are checked in a manner that makes them look always used. Those features will be fixed in followups, and in this PR they are omitted from the feature usage output. --- .../common/MemoizedSupplier.java | 40 +++++++++ .../action/AnalyticsInfoTransportAction.java | 2 +- .../AnalyticsInfoTransportActionTests.java | 4 +- .../ccr/CCRInfoTransportActionTests.java | 4 +- x-pack/plugin/core/build.gradle | 20 ++++- .../license/GetFeatureUsageRequest.java | 27 ++++++ .../license/GetFeatureUsageResponse.java | 86 +++++++++++++++++++ .../org/elasticsearch/license/Licensing.java | 4 +- .../license/RestGetFeatureUsageAction.java | 36 ++++++++ .../TransportGetFeatureUsageAction.java | 53 ++++++++++++ .../license/XPackLicenseState.java | 53 ++++++++++-- .../xpack/ccr/CCRInfoTransportAction.java | 2 +- .../elasticsearch/xpack/core/XPackPlugin.java | 6 +- .../license/LicenseFIPSTests.java | 6 +- .../license/LicenseTLSTests.java | 10 +-- .../org/elasticsearch/license/TestUtils.java | 6 +- .../license/XPackLicenseStateTests.java | 45 +++++++--- .../XPackCoreClientYamlTestSuiteIT.java | 39 +++++++++ .../api/license.get_feature_usage.json | 17 ++++ .../test/license/10_feature_usage.yml | 6 ++ .../action/EnrichInfoTransportAction.java | 2 +- .../xpack/eql/EqlInfoTransportAction.java | 2 +- .../eql/EqlInfoTransportActionTests.java | 2 +- .../xpack/graph/GraphInfoTransportAction.java | 2 +- .../graph/GraphInfoTransportActionTests.java | 2 +- .../IndexLifecycleInfoTransportAction.java | 2 +- .../xpack/slm/SLMInfoTransportAction.java | 2 +- ...ndexLifecycleInfoTransportActionTests.java | 4 +- .../logstash/LogstashInfoTransportAction.java | 2 +- .../LogstashInfoTransportActionTests.java | 4 +- .../xpack/ml/InvalidLicenseEnforcer.java | 2 +- ...chineLearningInfoTransportActionTests.java | 10 +-- .../MonitoringInfoTransportAction.java | 2 +- .../MonitoringInfoTransportActionTests.java | 2 +- .../rollup/RollupInfoTransportAction.java | 2 +- .../RollupInfoTransportActionTests.java | 2 +- .../xpack/security/Security.java | 6 +- .../security/SecurityInfoTransportAction.java | 2 +- .../BulkShardRequestInterceptor.java | 6 +- ...cumentLevelSecurityRequestInterceptor.java | 6 +- .../IndicesAliasesRequestInterceptor.java | 34 ++++---- .../interceptor/ResizeRequestInterceptor.java | 26 +++--- .../authz/store/CompositeRolesStore.java | 13 +-- .../security/authz/store/FileRolesStore.java | 5 +- .../authz/store/NativeRolesStore.java | 45 ++++------ .../SecurityInfoTransportActionTests.java | 8 +- .../authz/AuthorizationServiceTests.java | 4 +- .../authz/store/CompositeRolesStoreTests.java | 22 ++--- .../transport/ServerTransportFilterTests.java | 2 +- .../spatial/SpatialInfoTransportAction.java | 2 +- .../SpatialInfoTransportActionTests.java | 2 +- .../xpack/sql/SqlInfoTransportAction.java | 2 +- .../sql/SqlInfoTransportActionTests.java | 2 +- .../TransformInfoTransportAction.java | 2 +- .../TransformInfoTransportActionTests.java | 2 +- .../vectors/VectorsInfoTransportAction.java | 2 +- .../VectorsInfoTransportActionTests.java | 2 +- .../VotingOnlyNodeFeatureSet.java | 2 +- .../watcher/WatcherInfoTransportAction.java | 2 +- .../WatcherInfoTransportActionTests.java | 2 +- 60 files changed, 552 insertions(+), 159 deletions(-) create mode 100644 libs/core/src/main/java/org/elasticsearch/common/MemoizedSupplier.java create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetFeatureUsageRequest.java create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetFeatureUsageResponse.java create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/license/RestGetFeatureUsageAction.java create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/license/TransportGetFeatureUsageAction.java create mode 100644 x-pack/plugin/core/src/yamlRestTest/java/org/elasticsearch/license/XPackCoreClientYamlTestSuiteIT.java create mode 100644 x-pack/plugin/core/src/yamlRestTest/resources/rest-api-spec/api/license.get_feature_usage.json create mode 100644 x-pack/plugin/core/src/yamlRestTest/resources/rest-api-spec/test/license/10_feature_usage.yml diff --git a/libs/core/src/main/java/org/elasticsearch/common/MemoizedSupplier.java b/libs/core/src/main/java/org/elasticsearch/common/MemoizedSupplier.java new file mode 100644 index 0000000000000..d010eac52051e --- /dev/null +++ b/libs/core/src/main/java/org/elasticsearch/common/MemoizedSupplier.java @@ -0,0 +1,40 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.common; + +import java.util.function.Supplier; + +public class MemoizedSupplier implements Supplier { + private Supplier supplier; + private T value; + + public MemoizedSupplier(Supplier supplier) { + this.supplier = supplier; + } + + @Override + public T get() { + if (supplier != null) { + value = supplier.get(); + supplier = null; + } + return value; + } +} diff --git a/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportAction.java b/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportAction.java index 1ceadaab8096c..75a1202db90f7 100644 --- a/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportAction.java +++ b/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportAction.java @@ -31,7 +31,7 @@ public String name() { @Override public boolean available() { - return licenseState.isAllowed(XPackLicenseState.Feature.ANALYTICS); + return licenseState.checkFeature(XPackLicenseState.Feature.ANALYTICS); } @Override diff --git a/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportActionTests.java b/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportActionTests.java index 12df855e33e2a..46083f9a53dfb 100644 --- a/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportActionTests.java +++ b/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportActionTests.java @@ -63,7 +63,7 @@ public void testAvailable() throws Exception { AnalyticsInfoTransportAction featureSet = new AnalyticsInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), licenseState); boolean available = randomBoolean(); - when(licenseState.isAllowed(XPackLicenseState.Feature.ANALYTICS)).thenReturn(available); + when(licenseState.checkFeature(XPackLicenseState.Feature.ANALYTICS)).thenReturn(available); assertThat(featureSet.available(), is(available)); Client client = mockClient(); AnalyticsUsageTransportAction usageAction = new AnalyticsUsageTransportAction(mock(TransportService.class), clusterService, null, @@ -89,7 +89,7 @@ public void testEnabled() throws Exception { assertThat(featureSet.enabled(), is(true)); assertTrue(featureSet.enabled()); boolean available = randomBoolean(); - when(licenseState.isAllowed(XPackLicenseState.Feature.ANALYTICS)).thenReturn(available); + when(licenseState.checkFeature(XPackLicenseState.Feature.ANALYTICS)).thenReturn(available); Client client = mockClient(); AnalyticsUsageTransportAction usageAction = new AnalyticsUsageTransportAction(mock(TransportService.class), clusterService, null, mock(ActionFilters.class), null, licenseState, client); diff --git a/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/CCRInfoTransportActionTests.java b/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/CCRInfoTransportActionTests.java index 373b437177c19..5b591a12dcf8e 100644 --- a/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/CCRInfoTransportActionTests.java +++ b/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/CCRInfoTransportActionTests.java @@ -47,10 +47,10 @@ public void testAvailable() { CCRInfoTransportAction featureSet = new CCRInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), Settings.EMPTY, licenseState); - when(licenseState.isAllowed(XPackLicenseState.Feature.CCR)).thenReturn(false); + when(licenseState.checkFeature(XPackLicenseState.Feature.CCR)).thenReturn(false); assertThat(featureSet.available(), equalTo(false)); - when(licenseState.isAllowed(XPackLicenseState.Feature.CCR)).thenReturn(true); + when(licenseState.checkFeature(XPackLicenseState.Feature.CCR)).thenReturn(true); assertThat(featureSet.available(), equalTo(true)); } diff --git a/x-pack/plugin/core/build.gradle b/x-pack/plugin/core/build.gradle index 34f2ff6b131be..cba9aa4117c27 100644 --- a/x-pack/plugin/core/build.gradle +++ b/x-pack/plugin/core/build.gradle @@ -7,6 +7,7 @@ import java.nio.file.Paths apply plugin: 'elasticsearch.esplugin' apply plugin: 'elasticsearch.publish' apply plugin: 'elasticsearch.internal-cluster-test' +apply plugin: 'elasticsearch.yaml-rest-test' archivesBaseName = 'x-pack-core' @@ -57,6 +58,8 @@ dependencies { transitive = false } + yamlRestTestImplementation project(':x-pack:plugin:core') + } ext.expansions = [ @@ -143,8 +146,17 @@ thirdPartyAudit.ignoreMissingClasses( 'javax.servlet.ServletContextListener' ) -// xpack modules are installed in real clusters as the meta plugin, so -// installing them as individual plugins for integ tests doesn't make sense, -// so we disable integ tests -integTest.enabled = false +restResources { + restApi { + includeCore '*' + } +} + +testClusters.yamlRestTest { + testDistribution = 'default' + setting 'xpack.security.enabled', 'true' + setting 'xpack.license.self_generated.type', 'trial' + keystore 'bootstrap.password', 'x-pack-test-password' + user username: "x_pack_rest_user", password: "x-pack-test-password" +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetFeatureUsageRequest.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetFeatureUsageRequest.java new file mode 100644 index 0000000000000..d8bddd86cc3d5 --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetFeatureUsageRequest.java @@ -0,0 +1,27 @@ +/* + * 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.license; + +import org.elasticsearch.action.ActionRequest; +import org.elasticsearch.action.ActionRequestValidationException; +import org.elasticsearch.common.io.stream.StreamInput; + +import java.io.IOException; + +public class GetFeatureUsageRequest extends ActionRequest { + + public GetFeatureUsageRequest() {} + + public GetFeatureUsageRequest(StreamInput in) throws IOException { + super(in); + } + + @Override + public ActionRequestValidationException validate() { + return null; + } +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetFeatureUsageResponse.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetFeatureUsageResponse.java new file mode 100644 index 0000000000000..e1ca01e09061d --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetFeatureUsageResponse.java @@ -0,0 +1,86 @@ +/* + * 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.license; + +import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.common.io.stream.StreamOutput; +import org.elasticsearch.common.io.stream.Writeable; +import org.elasticsearch.common.xcontent.ToXContentObject; +import org.elasticsearch.common.xcontent.XContentBuilder; + +import java.io.IOException; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +public class GetFeatureUsageResponse extends ActionResponse implements ToXContentObject { + + public static class FeatureUsageInfo implements Writeable { + public final String name; + public final ZonedDateTime lastUsedTime; + public final String licenseLevel; + + public FeatureUsageInfo(String name, ZonedDateTime lastUsedTime, String licenseLevel) { + this.name = name; + this.lastUsedTime = lastUsedTime; + this.licenseLevel = licenseLevel; + } + + public FeatureUsageInfo(StreamInput in) throws IOException { + this.name = in.readString(); + this.lastUsedTime = ZonedDateTime.ofInstant(Instant.ofEpochSecond(in.readLong()), ZoneOffset.UTC); + this.licenseLevel = in.readString(); + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeString(name); + out.writeLong(lastUsedTime.toEpochSecond()); + out.writeString(licenseLevel); + } + } + + private List features; + + public GetFeatureUsageResponse(List features) { + this.features = Collections.unmodifiableList(features); + } + + public GetFeatureUsageResponse(StreamInput in) throws IOException { + this.features = in.readList(FeatureUsageInfo::new); + } + + public List getFeatures() { + return features; + } + + @Override + public void writeTo(StreamOutput out) throws IOException { + out.writeList(features); + } + + @Override + public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { + builder.startObject(); + builder.startArray("features"); + for (FeatureUsageInfo feature : features) { + builder.startObject(); + builder.field("name", feature.name); + builder.field("last_used", feature.lastUsedTime.toString()); + builder.field("license_level", feature.licenseLevel); + builder.endObject(); + } + builder.endArray(); + builder.endObject(); + return builder; + } +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/Licensing.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/Licensing.java index 295f8d8cf9e01..1d9cb73a896fe 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/Licensing.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/Licensing.java @@ -66,7 +66,8 @@ public Licensing(Settings settings) { new ActionHandler<>(PostStartTrialAction.INSTANCE, TransportPostStartTrialAction.class), new ActionHandler<>(GetTrialStatusAction.INSTANCE, TransportGetTrialStatusAction.class), new ActionHandler<>(PostStartBasicAction.INSTANCE, TransportPostStartBasicAction.class), - new ActionHandler<>(GetBasicStatusAction.INSTANCE, TransportGetBasicStatusAction.class)); + new ActionHandler<>(GetBasicStatusAction.INSTANCE, TransportGetBasicStatusAction.class), + new ActionHandler<>(TransportGetFeatureUsageAction.TYPE, TransportGetFeatureUsageAction.class)); } @Override @@ -81,6 +82,7 @@ public List getRestHandlers(Settings settings, RestController restC handlers.add(new RestGetBasicStatus()); handlers.add(new RestPostStartTrialLicense()); handlers.add(new RestPostStartBasicLicense()); + handlers.add(new RestGetFeatureUsageAction()); return handlers; } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/RestGetFeatureUsageAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/RestGetFeatureUsageAction.java new file mode 100644 index 0000000000000..2f0a71c16aba7 --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/RestGetFeatureUsageAction.java @@ -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.license; + +import org.elasticsearch.client.node.NodeClient; +import org.elasticsearch.rest.BaseRestHandler; +import org.elasticsearch.rest.RestRequest; +import org.elasticsearch.rest.action.RestToXContentListener; + +import java.io.IOException; +import java.util.List; + +import static org.elasticsearch.rest.RestRequest.Method.GET; + +public class RestGetFeatureUsageAction extends BaseRestHandler { + + @Override + public String getName() { + return "get_feature_usage"; + } + + @Override + public List routes() { + return List.of(new Route(GET, "/_license/feature_usage")); + } + + @Override + protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException { + return channel -> client.execute(TransportGetFeatureUsageAction.TYPE, new GetFeatureUsageRequest(), + new RestToXContentListener<>(channel)); + } +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/TransportGetFeatureUsageAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/TransportGetFeatureUsageAction.java new file mode 100644 index 0000000000000..4077f1d435055 --- /dev/null +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/TransportGetFeatureUsageAction.java @@ -0,0 +1,53 @@ +/* + * 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.license; + +import org.elasticsearch.action.ActionListener; +import org.elasticsearch.action.ActionType; +import org.elasticsearch.action.support.ActionFilters; +import org.elasticsearch.action.support.HandledTransportAction; +import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.tasks.Task; +import org.elasticsearch.transport.TransportService; + +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +public class TransportGetFeatureUsageAction extends HandledTransportAction { + + public static final ActionType TYPE = + new ActionType<>("cluster:admin/xpack/license/feature_usage", GetFeatureUsageResponse::new); + + private final XPackLicenseState licenseState; + + @Inject + public TransportGetFeatureUsageAction(TransportService transportService, ActionFilters actionFilters, + XPackLicenseState licenseState) { + super(TYPE.name(), transportService, actionFilters, GetFeatureUsageRequest::new); + this.licenseState = licenseState; + } + + + @Override + protected void doExecute(Task task, GetFeatureUsageRequest request, ActionListener listener) { + Map featureUsage = licenseState.getLastUsed(); + List usageInfos = new ArrayList<>(); + for (var entry : featureUsage.entrySet()) { + XPackLicenseState.Feature feature = entry.getKey(); + String name = feature.name().toLowerCase(Locale.ROOT); + ZonedDateTime lastUsedTime = Instant.ofEpochMilli(entry.getValue()).atZone(ZoneOffset.UTC); + String licenseLevel = feature.minimumOperationMode.name().toLowerCase(Locale.ROOT); + usageInfos.add(new GetFeatureUsageResponse.FeatureUsageInfo(name, lastUsedTime, licenseLevel)); + } + listener.onResponse(new GetFeatureUsageResponse(usageInfos)); + } +} diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/XPackLicenseState.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/XPackLicenseState.java index f98cb1a945fcc..ba4c2dde5369d 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/XPackLicenseState.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/XPackLicenseState.java @@ -16,14 +16,19 @@ import org.elasticsearch.xpack.core.monitoring.MonitoringField; import java.util.Collections; +import java.util.EnumMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.atomic.LongAccumulator; import java.util.function.BiFunction; import java.util.function.Function; +import java.util.function.LongSupplier; import java.util.function.Predicate; +import java.util.stream.Collectors; /** * A holder for the current state of the license for all xpack features. @@ -104,6 +109,14 @@ public enum Feature { } } + // temporarily non tracked feeatures which need rework in how they are checked + // so they are not tracked as always used + private static final Set NON_TRACKED_FEATURES = Set.of( + Feature.SECURITY_IP_FILTERING, + Feature.SECURITY_ALL_REALMS, + Feature.SECURITY_STANDARD_REALMS + ); + /** Messages for each feature which are printed when the license expires. */ static final Map EXPIRATION_MESSAGES; static { @@ -396,6 +409,8 @@ private static class Status { private final List listeners; private final boolean isSecurityEnabled; private final boolean isSecurityExplicitlyEnabled; + private final Map lastUsed; + private final LongSupplier epochMillisProvider; // Since Status is the only field that can be updated, we do not need to synchronize access to // XPackLicenseState. However, if status is read multiple times in a method, it can change in between @@ -403,18 +418,31 @@ private static class Status { // is only read once. private volatile Status status = new Status(OperationMode.TRIAL, true); - public XPackLicenseState(Settings settings) { + public XPackLicenseState(Settings settings, LongSupplier epochMillisProvider) { this.listeners = new CopyOnWriteArrayList<>(); this.isSecurityEnabled = XPackSettings.SECURITY_ENABLED.get(settings); this.isSecurityExplicitlyEnabled = isSecurityEnabled && isSecurityExplicitlyEnabled(settings); + + // prepopulate feature last used map with entries for non basic features, which are the ones we + // care to actually keep track of + Map lastUsed = new EnumMap<>(Feature.class); + for (Feature feature : Feature.values()) { + if (feature.minimumOperationMode.compareTo(OperationMode.BASIC) > 0 && NON_TRACKED_FEATURES.contains(feature) == false) { + lastUsed.put(feature, new LongAccumulator(Long::max, 0)); + } + } + this.lastUsed = lastUsed; + this.epochMillisProvider = epochMillisProvider; } private XPackLicenseState(List listeners, boolean isSecurityEnabled, boolean isSecurityExplicitlyEnabled, - Status status) { + Status status, Map lastUsed, LongSupplier epochMillisProvider) { this.listeners = listeners; this.isSecurityEnabled = isSecurityEnabled; this.isSecurityExplicitlyEnabled = isSecurityExplicitlyEnabled; this.status = status; + this.lastUsed = lastUsed; + this.epochMillisProvider = epochMillisProvider; } private static boolean isSecurityExplicitlyEnabled(Settings settings) { @@ -478,8 +506,12 @@ public boolean isActive() { * Checks whether the given feature is allowed, tracking the last usage time. */ public boolean checkFeature(Feature feature) { - // TODO: usage tracking is not yet implemented - return isAllowed(feature); + boolean allowed = isAllowed(feature); + LongAccumulator maxEpochAccumulator = lastUsed.get(feature); + if (maxEpochAccumulator != null) { + maxEpochAccumulator.accumulate(epochMillisProvider.getAsLong()); + } + return allowed; } /** @@ -491,6 +523,17 @@ public boolean isAllowed(Feature feature) { return isAllowedByLicense(feature.minimumOperationMode, feature.needsActive); } + /** + * Returns a mapping of gold+ features to the last time that feature was used. + * + * Note that if a feature has not been used, it will not appear in the map. + */ + public Map getLastUsed() { + return lastUsed.entrySet().stream() + .filter(e -> e.getValue().get() != 0) // feature was never used + .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().get())); + } + public static boolean isMachineLearningAllowedForOperationMode(final OperationMode operationMode) { return isAllowedByOperationMode(operationMode, OperationMode.PLATINUM); } @@ -564,7 +607,7 @@ public static boolean isAllowedByOperationMode( */ public XPackLicenseState copyCurrentLicenseState() { return executeAgainstStatus(status -> - new XPackLicenseState(listeners, isSecurityEnabled, isSecurityExplicitlyEnabled, status)); + new XPackLicenseState(listeners, isSecurityEnabled, isSecurityExplicitlyEnabled, status, lastUsed, epochMillisProvider)); } /** diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/ccr/CCRInfoTransportAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/ccr/CCRInfoTransportAction.java index 4c15544a52d6d..74af5eab1386f 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/ccr/CCRInfoTransportAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/ccr/CCRInfoTransportAction.java @@ -43,7 +43,7 @@ public String name() { @Override public boolean available() { - return licenseState.isAllowed(XPackLicenseState.Feature.CCR); + return licenseState.checkFeature(XPackLicenseState.Feature.CCR); } @Override diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java index 128742c4e55d8..fc613254da763 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java @@ -83,6 +83,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.function.LongSupplier; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -131,6 +132,7 @@ public Void run() { private static final SetOnce licenseState = new SetOnce<>(); private static final SetOnce sslService = new SetOnce<>(); private static final SetOnce licenseService = new SetOnce<>(); + private static final SetOnce epochMillisSupplier = new SetOnce<>(); public XPackPlugin( final Settings settings, @@ -140,7 +142,7 @@ public XPackPlugin( // We should only depend on the settings from the Environment object passed to createComponents this.settings = settings; - setLicenseState(new XPackLicenseState(settings)); + setLicenseState(new XPackLicenseState(settings, () -> epochMillisSupplier.get().getAsLong())); this.licensing = new Licensing(settings); } @@ -240,6 +242,8 @@ public Collection createComponents(Client client, ClusterService cluster setLicenseService(new LicenseService(settings, clusterService, getClock(), environment, resourceWatcherService, getLicenseState())); + epochMillisSupplier.set(threadPool::absoluteTimeInMillis); + // It is useful to override these as they are what guice is injecting into actions components.add(sslService); components.add(getLicenseService()); diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/license/LicenseFIPSTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/license/LicenseFIPSTests.java index eb357661d50ca..01a3a421eba38 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/license/LicenseFIPSTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/license/LicenseFIPSTests.java @@ -28,7 +28,7 @@ public void testFIPSCheckWithAllowedLicense() throws Exception { .put("xpack.security.transport.ssl.enabled", true) .put("xpack.security.fips_mode.enabled", randomBoolean()) .build(); - XPackLicenseState licenseState = new XPackLicenseState(settings); + XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0); setInitialState(null, licenseState, settings); licenseService.start(); @@ -52,7 +52,7 @@ public void testFIPSCheckWithoutAllowedLicense() throws Exception { .put("xpack.security.transport.ssl.enabled", true) .put("xpack.security.fips_mode.enabled", true) .build(); - XPackLicenseState licenseState = new XPackLicenseState(settings); + XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0); setInitialState(null, licenseState, settings); licenseService.start(); @@ -67,7 +67,7 @@ public void testFIPSCheckWithoutAllowedLicense() throws Exception { .put("xpack.security.transport.ssl.enabled", true) .put("xpack.security.fips_mode.enabled", false) .build(); - licenseState = new XPackLicenseState(settings); + licenseState = new XPackLicenseState(settings, () -> 0); setInitialState(null, licenseState, settings); licenseService.start(); diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/license/LicenseTLSTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/license/LicenseTLSTests.java index 754b398cd6c9d..2015461a2a79c 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/license/LicenseTLSTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/license/LicenseTLSTests.java @@ -33,7 +33,7 @@ public void testApplyLicenseInDevMode() throws Exception { request.acknowledge(true); request.license(newLicense); Settings settings = Settings.builder().put("xpack.security.enabled", true).build(); - XPackLicenseState licenseState = new XPackLicenseState(settings); + XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0); inetAddress = InetAddress.getLoopbackAddress(); setInitialState(null, licenseState, settings); @@ -48,7 +48,7 @@ public void testApplyLicenseInDevMode() throws Exception { .put("discovery.type", "single-node") .build(); licenseService.stop(); - licenseState = new XPackLicenseState(settings); + licenseState = new XPackLicenseState(settings, () -> 0); setInitialState(null, licenseState, settings); licenseService.start(); licenseService.registerLicense(request, responseFuture); @@ -62,7 +62,7 @@ public void testApplyLicenseInProdMode() throws Exception { request.acknowledge(true); request.license(newLicense); Settings settings = Settings.builder().put("xpack.security.enabled", true).build(); - XPackLicenseState licenseState = new XPackLicenseState(settings); + XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0); inetAddress = TransportAddress.META_ADDRESS; setInitialState(null, licenseState, settings); @@ -74,7 +74,7 @@ public void testApplyLicenseInProdMode() throws Exception { settings = Settings.builder().put("xpack.security.enabled", false).build(); licenseService.stop(); - licenseState = new XPackLicenseState(settings); + licenseState = new XPackLicenseState(settings, () -> 0); setInitialState(null, licenseState, settings); licenseService.start(); licenseService.registerLicense(request, responseFuture); @@ -85,7 +85,7 @@ public void testApplyLicenseInProdMode() throws Exception { .put("xpack.security.transport.ssl.enabled", true) .build(); licenseService.stop(); - licenseState = new XPackLicenseState(settings); + licenseState = new XPackLicenseState(settings, () -> 0); setInitialState(null, licenseState, settings); licenseService.start(); licenseService.registerLicense(request, responseFuture); diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/license/TestUtils.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/license/TestUtils.java index 02129a099b791..27222105f3e39 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/license/TestUtils.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/license/TestUtils.java @@ -362,7 +362,7 @@ public static class AssertingLicenseState extends XPackLicenseState { public final List trialVersionUpdates = new ArrayList<>(); public AssertingLicenseState() { - super(Settings.EMPTY); + super(Settings.EMPTY, () -> 0); } @Override @@ -383,7 +383,7 @@ public UpdatableLicenseState() { } public UpdatableLicenseState(Settings settings) { - super(settings); + super(settings, () -> 0); } @Override @@ -393,7 +393,7 @@ public void update(License.OperationMode mode, boolean active, Version mostRecen } public static XPackLicenseState newTestLicenseState() { - return new XPackLicenseState(Settings.EMPTY); + return new XPackLicenseState(Settings.EMPTY, () -> 0); } public static void putLicense(Metadata.Builder builder, License license) { diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/license/XPackLicenseStateTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/license/XPackLicenseStateTests.java index 2cf3682cf7b18..3f5e6982bdb6d 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/license/XPackLicenseStateTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/license/XPackLicenseStateTests.java @@ -15,6 +15,7 @@ import org.elasticsearch.xpack.core.XPackSettings; import java.util.Arrays; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -25,6 +26,9 @@ import static org.elasticsearch.license.License.OperationMode.STANDARD; import static org.elasticsearch.license.License.OperationMode.TRIAL; import static org.hamcrest.Matchers.is; +import static org.hamcrest.collection.IsMapContaining.hasEntry; +import static org.hamcrest.collection.IsMapContaining.hasKey; +import static org.hamcrest.core.IsNot.not; /** * Unit tests for the {@link XPackLicenseState} @@ -77,7 +81,7 @@ public static OperationMode randomBasicStandardOrGold() { public void testSecurityDefaults() { Settings settings = Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build(); - XPackLicenseState licenseState = new XPackLicenseState(settings); + XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0); assertThat(licenseState.isSecurityEnabled(), is(true)); assertThat(licenseState.checkFeature(Feature.SECURITY_IP_FILTERING), is(true)); assertThat(licenseState.checkFeature(Feature.SECURITY_AUDITING), is(true)); @@ -92,8 +96,7 @@ public void testSecurityDefaults() { public void testTransportSslDoesNotAutomaticallyEnableSecurityOnTrialLicense() { Settings settings = Settings.builder().put(XPackSettings.TRANSPORT_SSL_ENABLED.getKey(), true).build(); - final XPackLicenseState licenseState; - licenseState = new XPackLicenseState(settings); + final XPackLicenseState licenseState= new XPackLicenseState(settings, () -> 0); assertSecurityNotAllowed(licenseState); } @@ -116,7 +119,7 @@ public void testSecurityBasicWithoutExplicitSecurityEnabled() { public void testSecurityBasicWithExplicitSecurityEnabled() { final Settings settings = Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build(); - XPackLicenseState licenseState = new XPackLicenseState(settings); + XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0); licenseState.update(BASIC, true, null); assertThat(licenseState.isSecurityEnabled(), is(true)); @@ -148,7 +151,7 @@ public void testSecurityDefaultBasicExpired() { public void testSecurityEnabledBasicExpired() { Settings settings = Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build(); - XPackLicenseState licenseState = new XPackLicenseState(settings); + XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0); licenseState.update(BASIC, false, null); assertThat(licenseState.isSecurityEnabled(), is(true)); @@ -164,7 +167,7 @@ public void testSecurityEnabledBasicExpired() { public void testSecurityStandard() { Settings settings = randomFrom(Settings.EMPTY, Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()); - XPackLicenseState licenseState = new XPackLicenseState(settings); + XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0); licenseState.update(STANDARD, true, null); assertThat(licenseState.isSecurityEnabled(), is(true)); @@ -178,7 +181,7 @@ public void testSecurityStandard() { public void testSecurityStandardExpired() { Settings settings = randomFrom(Settings.EMPTY, Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()); - XPackLicenseState licenseState = new XPackLicenseState(settings); + XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0); licenseState.update(STANDARD, false, null); assertThat(licenseState.isSecurityEnabled(), is(true)); @@ -192,7 +195,7 @@ public void testSecurityStandardExpired() { public void testSecurityGold() { Settings settings = randomFrom(Settings.EMPTY, Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()); - XPackLicenseState licenseState = new XPackLicenseState(settings); + XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0); licenseState.update(GOLD, true, null); assertThat(licenseState.isSecurityEnabled(), is(true)); @@ -209,7 +212,7 @@ public void testSecurityGold() { public void testSecurityGoldExpired() { Settings settings = randomFrom(Settings.EMPTY, Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()); - XPackLicenseState licenseState = new XPackLicenseState(settings); + XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0); licenseState.update(GOLD, false, null); assertThat(licenseState.isSecurityEnabled(), is(true)); @@ -226,7 +229,7 @@ public void testSecurityGoldExpired() { public void testSecurityPlatinum() { Settings settings = randomFrom(Settings.EMPTY, Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()); - XPackLicenseState licenseState = new XPackLicenseState(settings); + XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0); licenseState.update(PLATINUM, true, null); assertThat(licenseState.isSecurityEnabled(), is(true)); @@ -243,7 +246,7 @@ public void testSecurityPlatinum() { public void testSecurityPlatinumExpired() { Settings settings = randomFrom(Settings.EMPTY, Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()); - XPackLicenseState licenseState = new XPackLicenseState(settings); + XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0); licenseState.update(PLATINUM, false, null); assertThat(licenseState.isSecurityEnabled(), is(true)); @@ -566,4 +569,24 @@ public void testTransformStandard() throws Exception { public void testTransformInactiveBasic() { assertAllowed(BASIC, false, s -> s.checkFeature(Feature.TRANSFORM), false); } + + public void testLastUsed() { + Feature basicFeature = Feature.SECURITY; + Feature goldFeature = Feature.SECURITY_IP_FILTERING; + AtomicInteger currentTime = new AtomicInteger(100); // non zero start time + XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY, currentTime::get); + assertThat("basic features not tracked", licenseState.getLastUsed(), not(hasKey(basicFeature))); + assertThat("initial epoch time", licenseState.getLastUsed(), hasEntry(goldFeature, 0L)); + licenseState.isAllowed(basicFeature); + assertThat("basic features still not tracked", licenseState.getLastUsed(), not(hasKey(basicFeature))); + licenseState.isAllowed(goldFeature); + assertThat("isAllowed does not track", licenseState.getLastUsed(), hasEntry(goldFeature, 0L)); + licenseState.checkFeature(basicFeature); + assertThat("basic features still not tracked", licenseState.getLastUsed(), not(hasKey(basicFeature))); + licenseState.checkFeature(goldFeature); + assertThat("checkFeature tracks used time", licenseState.getLastUsed(), hasEntry(goldFeature, 100L)); + currentTime.set(200); + licenseState.checkFeature(goldFeature); + assertThat("checkFeature updates tracked time", licenseState.getLastUsed(), hasEntry(goldFeature, 200L)); + } } diff --git a/x-pack/plugin/core/src/yamlRestTest/java/org/elasticsearch/license/XPackCoreClientYamlTestSuiteIT.java b/x-pack/plugin/core/src/yamlRestTest/java/org/elasticsearch/license/XPackCoreClientYamlTestSuiteIT.java new file mode 100644 index 0000000000000..dce47903125f3 --- /dev/null +++ b/x-pack/plugin/core/src/yamlRestTest/java/org/elasticsearch/license/XPackCoreClientYamlTestSuiteIT.java @@ -0,0 +1,39 @@ +/* + * 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.license; + +import com.carrotsearch.randomizedtesting.annotations.Name; +import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; +import org.elasticsearch.common.settings.SecureString; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.util.concurrent.ThreadContext; +import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate; +import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase; + +import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; + +public class XPackCoreClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase { + + private static final String BASIC_AUTH_VALUE = + basicAuthHeaderValue("x_pack_rest_user", new SecureString("x-pack-test-password")); + + public XPackCoreClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) { + super(testCandidate); + } + + @ParametersFactory + public static Iterable parameters() throws Exception { + return ESClientYamlSuiteTestCase.createParameters(); + } + + @Override + protected Settings restClientSettings() { + return Settings.builder() + .put(ThreadContext.PREFIX + ".Authorization", BASIC_AUTH_VALUE) + .build(); + } +} diff --git a/x-pack/plugin/core/src/yamlRestTest/resources/rest-api-spec/api/license.get_feature_usage.json b/x-pack/plugin/core/src/yamlRestTest/resources/rest-api-spec/api/license.get_feature_usage.json new file mode 100644 index 0000000000000..57faa00c161a8 --- /dev/null +++ b/x-pack/plugin/core/src/yamlRestTest/resources/rest-api-spec/api/license.get_feature_usage.json @@ -0,0 +1,17 @@ +{ + "license.get_feature_usage":{ + "stability":"experimental", + "url":{ + "paths":[ + { + "path":"/_license/feature_usage", + "methods":[ + "GET" + ] + } + ] + }, + "params":{ + } + } +} diff --git a/x-pack/plugin/core/src/yamlRestTest/resources/rest-api-spec/test/license/10_feature_usage.yml b/x-pack/plugin/core/src/yamlRestTest/resources/rest-api-spec/test/license/10_feature_usage.yml new file mode 100644 index 0000000000000..385bc57f1e8d5 --- /dev/null +++ b/x-pack/plugin/core/src/yamlRestTest/resources/rest-api-spec/test/license/10_feature_usage.yml @@ -0,0 +1,6 @@ +--- +"No features should be used just by starting up with default configuration": + - do: + license.get_feature_usage: {} + + - length: { features: 0 } diff --git a/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichInfoTransportAction.java b/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichInfoTransportAction.java index 44a1befe9e192..3804bccfc9f23 100644 --- a/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichInfoTransportAction.java +++ b/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichInfoTransportAction.java @@ -30,7 +30,7 @@ public String name() { @Override public boolean available() { - return licenseState.isAllowed(XPackLicenseState.Feature.ENRICH); + return licenseState.checkFeature(XPackLicenseState.Feature.ENRICH); } @Override diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/EqlInfoTransportAction.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/EqlInfoTransportAction.java index 7798e91a6f7b4..50203a13f3e07 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/EqlInfoTransportAction.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/EqlInfoTransportAction.java @@ -35,7 +35,7 @@ public String name() { @Override public boolean available() { - return licenseState.isAllowed(XPackLicenseState.Feature.EQL); + return licenseState.checkFeature(XPackLicenseState.Feature.EQL); } @Override diff --git a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/EqlInfoTransportActionTests.java b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/EqlInfoTransportActionTests.java index 887af17db768f..73c010e72077b 100644 --- a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/EqlInfoTransportActionTests.java +++ b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/EqlInfoTransportActionTests.java @@ -59,7 +59,7 @@ public void testAvailable() { EqlInfoTransportAction featureSet = new EqlInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), Settings.EMPTY, licenseState); boolean available = randomBoolean(); - when(licenseState.isAllowed(XPackLicenseState.Feature.EQL)).thenReturn(available); + when(licenseState.checkFeature(XPackLicenseState.Feature.EQL)).thenReturn(available); assertThat(featureSet.available(), is(available)); } diff --git a/x-pack/plugin/graph/src/main/java/org/elasticsearch/xpack/graph/GraphInfoTransportAction.java b/x-pack/plugin/graph/src/main/java/org/elasticsearch/xpack/graph/GraphInfoTransportAction.java index ded865f4e2f47..b8223b64da2e0 100644 --- a/x-pack/plugin/graph/src/main/java/org/elasticsearch/xpack/graph/GraphInfoTransportAction.java +++ b/x-pack/plugin/graph/src/main/java/org/elasticsearch/xpack/graph/GraphInfoTransportAction.java @@ -35,7 +35,7 @@ public String name() { @Override public boolean available() { - return licenseState != null && licenseState.isAllowed(XPackLicenseState.Feature.GRAPH); + return licenseState != null && licenseState.checkFeature(XPackLicenseState.Feature.GRAPH); } @Override diff --git a/x-pack/plugin/graph/src/test/java/org/elasticsearch/xpack/graph/GraphInfoTransportActionTests.java b/x-pack/plugin/graph/src/test/java/org/elasticsearch/xpack/graph/GraphInfoTransportActionTests.java index 0ccbe01e81021..b4ace4d4f5bac 100644 --- a/x-pack/plugin/graph/src/test/java/org/elasticsearch/xpack/graph/GraphInfoTransportActionTests.java +++ b/x-pack/plugin/graph/src/test/java/org/elasticsearch/xpack/graph/GraphInfoTransportActionTests.java @@ -34,7 +34,7 @@ public void testAvailable() throws Exception { GraphInfoTransportAction featureSet = new GraphInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), Settings.EMPTY, licenseState); boolean available = randomBoolean(); - when(licenseState.isAllowed(XPackLicenseState.Feature.GRAPH)).thenReturn(available); + when(licenseState.checkFeature(XPackLicenseState.Feature.GRAPH)).thenReturn(available); assertThat(featureSet.available(), is(available)); var usageAction = new GraphUsageTransportAction(mock(TransportService.class), null, null, diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportAction.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportAction.java index ab834b484eaad..7a1f704310b5d 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportAction.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportAction.java @@ -31,7 +31,7 @@ public String name() { @Override public boolean available() { - return licenseState.isAllowed(XPackLicenseState.Feature.ILM); + return licenseState.checkFeature(XPackLicenseState.Feature.ILM); } @Override diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SLMInfoTransportAction.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SLMInfoTransportAction.java index 2ddd01a53cf0a..0886c9b345b5a 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SLMInfoTransportAction.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SLMInfoTransportAction.java @@ -31,7 +31,7 @@ public String name() { @Override public boolean available() { - return licenseState.isAllowed(XPackLicenseState.Feature.ILM); + return licenseState.checkFeature(XPackLicenseState.Feature.ILM); } @Override diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportActionTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportActionTests.java index 428dab4b6bd46..00ef2f7d69d8e 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportActionTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportActionTests.java @@ -57,10 +57,10 @@ public void testAvailable() { IndexLifecycleInfoTransportAction featureSet = new IndexLifecycleInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), licenseState); - when(licenseState.isAllowed(XPackLicenseState.Feature.ILM)).thenReturn(false); + when(licenseState.checkFeature(XPackLicenseState.Feature.ILM)).thenReturn(false); assertThat(featureSet.available(), equalTo(false)); - when(licenseState.isAllowed(XPackLicenseState.Feature.ILM)).thenReturn(true); + when(licenseState.checkFeature(XPackLicenseState.Feature.ILM)).thenReturn(true); assertThat(featureSet.available(), equalTo(true)); } diff --git a/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportAction.java b/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportAction.java index 3c130877a84c1..016ee32882567 100644 --- a/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportAction.java +++ b/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportAction.java @@ -30,7 +30,7 @@ public String name() { @Override public boolean available() { - return licenseState.isAllowed(XPackLicenseState.Feature.LOGSTASH); + return licenseState.checkFeature(XPackLicenseState.Feature.LOGSTASH); } @Override diff --git a/x-pack/plugin/logstash/src/test/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportActionTests.java b/x-pack/plugin/logstash/src/test/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportActionTests.java index 64fef0069cdd9..2bed9b26b5b72 100644 --- a/x-pack/plugin/logstash/src/test/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportActionTests.java +++ b/x-pack/plugin/logstash/src/test/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportActionTests.java @@ -61,7 +61,7 @@ public void testAvailable() throws Exception { licenseState ); boolean available = randomBoolean(); - when(licenseState.isAllowed(XPackLicenseState.Feature.LOGSTASH)).thenReturn(available); + when(licenseState.checkFeature(XPackLicenseState.Feature.LOGSTASH)).thenReturn(available); assertThat(featureSet.available(), is(available)); var usageAction = newUsageAction(available); @@ -78,7 +78,7 @@ public void testAvailable() throws Exception { private LogstashUsageTransportAction newUsageAction(boolean available) { XPackLicenseState licenseState = mock(XPackLicenseState.class); - when(licenseState.isAllowed(XPackLicenseState.Feature.LOGSTASH)).thenReturn(available); + when(licenseState.checkFeature(XPackLicenseState.Feature.LOGSTASH)).thenReturn(available); return new LogstashUsageTransportAction(mock(TransportService.class), null, null, mock(ActionFilters.class), null, licenseState); } } diff --git a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/InvalidLicenseEnforcer.java b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/InvalidLicenseEnforcer.java index d89e3c75660c1..5be9a3c91ddb4 100644 --- a/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/InvalidLicenseEnforcer.java +++ b/x-pack/plugin/ml/src/main/java/org/elasticsearch/xpack/ml/InvalidLicenseEnforcer.java @@ -48,7 +48,7 @@ void listenForLicenseStateChanges() { @Override public void licenseStateChanged() { assert licenseStateListenerRegistered; - if (licenseState.checkFeature(XPackLicenseState.Feature.MACHINE_LEARNING) == false) { + if (licenseState.isAllowed(XPackLicenseState.Feature.MACHINE_LEARNING) == false) { // if the license has expired, close jobs and datafeeds threadPool.generic().execute(new AbstractRunnable() { @Override diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/MachineLearningInfoTransportActionTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/MachineLearningInfoTransportActionTests.java index e890520580e2f..0f5a2bdbf3b0c 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/MachineLearningInfoTransportActionTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/MachineLearningInfoTransportActionTests.java @@ -131,7 +131,7 @@ public void testAvailable() throws Exception { MachineLearningInfoTransportAction featureSet = new MachineLearningInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), commonSettings, licenseState); boolean available = randomBoolean(); - when(licenseState.isAllowed(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(available); + when(licenseState.checkFeature(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(available); assertThat(featureSet.available(), is(available)); var usageAction = newUsageAction(commonSettings); PlainActionFuture future = new PlainActionFuture<>(); @@ -170,7 +170,7 @@ public void testEnabled() throws Exception { } public void testUsage() throws Exception { - when(licenseState.isAllowed(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); + when(licenseState.checkFeature(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); Settings.Builder settings = Settings.builder().put(commonSettings); settings.put("xpack.ml.enabled", true); @@ -367,7 +367,7 @@ public void testUsageWithOrphanedTask() throws Exception { } public void testUsageDisabledML() throws Exception { - when(licenseState.isAllowed(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); + when(licenseState.checkFeature(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); Settings.Builder settings = Settings.builder().put(commonSettings); settings.put("xpack.ml.enabled", false); @@ -387,7 +387,7 @@ public void testUsageDisabledML() throws Exception { } public void testNodeCount() throws Exception { - when(licenseState.isAllowed(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); + when(licenseState.checkFeature(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); int nodeCount = randomIntBetween(1, 3); ClusterState clusterState = givenNodeCount(nodeCount); Settings.Builder settings = Settings.builder().put(commonSettings); @@ -414,7 +414,7 @@ public void testNodeCount() throws Exception { } public void testUsageGivenMlMetadataNotInstalled() throws Exception { - when(licenseState.isAllowed(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); + when(licenseState.checkFeature(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); Settings.Builder settings = Settings.builder().put(commonSettings); settings.put("xpack.ml.enabled", true); when(clusterService.state()).thenReturn(ClusterState.EMPTY_STATE); diff --git a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportAction.java b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportAction.java index 0ef97311de161..f491d8e9d9f2e 100644 --- a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportAction.java +++ b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportAction.java @@ -31,7 +31,7 @@ public String name() { @Override public boolean available() { - return licenseState.isAllowed(XPackLicenseState.Feature.MONITORING); + return licenseState.checkFeature(XPackLicenseState.Feature.MONITORING); } @Override diff --git a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportActionTests.java b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportActionTests.java index 1b6b0a50e89d6..27707717a0e01 100644 --- a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportActionTests.java +++ b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportActionTests.java @@ -47,7 +47,7 @@ public void testAvailable() { MonitoringInfoTransportAction featureSet = new MonitoringInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), licenseState); boolean available = randomBoolean(); - when(licenseState.isAllowed(XPackLicenseState.Feature.MONITORING)).thenReturn(available); + when(licenseState.checkFeature(XPackLicenseState.Feature.MONITORING)).thenReturn(available); assertThat(featureSet.available(), is(available)); } diff --git a/x-pack/plugin/rollup/src/main/java/org/elasticsearch/xpack/rollup/RollupInfoTransportAction.java b/x-pack/plugin/rollup/src/main/java/org/elasticsearch/xpack/rollup/RollupInfoTransportAction.java index 5887dfe794af1..bc344a04a0d55 100644 --- a/x-pack/plugin/rollup/src/main/java/org/elasticsearch/xpack/rollup/RollupInfoTransportAction.java +++ b/x-pack/plugin/rollup/src/main/java/org/elasticsearch/xpack/rollup/RollupInfoTransportAction.java @@ -31,7 +31,7 @@ public String name() { @Override public boolean available() { - return licenseState.isAllowed(XPackLicenseState.Feature.ROLLUP); + return licenseState.checkFeature(XPackLicenseState.Feature.ROLLUP); } @Override diff --git a/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupInfoTransportActionTests.java b/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupInfoTransportActionTests.java index 69dc1fab5e9db..233df50c8420a 100644 --- a/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupInfoTransportActionTests.java +++ b/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupInfoTransportActionTests.java @@ -35,7 +35,7 @@ public void testAvailable() { RollupInfoTransportAction featureSet = new RollupInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), licenseState); boolean available = randomBoolean(); - when(licenseState.isAllowed(XPackLicenseState.Feature.ROLLUP)).thenReturn(available); + when(licenseState.checkFeature(XPackLicenseState.Feature.ROLLUP)).thenReturn(available); assertThat(featureSet.available(), is(available)); } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java index 6bba14de504d2..824dea00f5d7a 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java @@ -1035,7 +1035,7 @@ public Function> getFieldFilter() { if (enabled) { return index -> { XPackLicenseState licenseState = getLicenseState(); - if (licenseState.isSecurityEnabled() == false || licenseState.checkFeature(Feature.SECURITY_DLS_FLS) == false) { + if (licenseState.isSecurityEnabled() == false) { return MapperPlugin.NOOP_FIELD_PREDICATE; } IndicesAccessControl indicesAccessControl = threadContext.get().getTransient( @@ -1051,6 +1051,10 @@ public Function> getFieldFilter() { if (fieldPermissions.hasFieldLevelSecurity() == false) { return MapperPlugin.NOOP_FIELD_PREDICATE; } + if (licenseState.checkFeature(Feature.SECURITY_DLS_FLS) == false) { + // check license last, once we know FLS is actually used + return MapperPlugin.NOOP_FIELD_PREDICATE; + } return fieldPermissions::grantsAccessTo; }; } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/SecurityInfoTransportAction.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/SecurityInfoTransportAction.java index 88a2696450b7e..7605191a9d6da 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/SecurityInfoTransportAction.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/SecurityInfoTransportAction.java @@ -34,7 +34,7 @@ public String name() { @Override public boolean available() { - return licenseState.isAllowed(XPackLicenseState.Feature.SECURITY); + return licenseState.checkFeature(XPackLicenseState.Feature.SECURITY); } @Override diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/BulkShardRequestInterceptor.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/BulkShardRequestInterceptor.java index c8c4f0c751673..22714ac540d62 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/BulkShardRequestInterceptor.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/BulkShardRequestInterceptor.java @@ -12,6 +12,7 @@ import org.elasticsearch.action.bulk.BulkItemRequest; import org.elasticsearch.action.bulk.BulkShardRequest; import org.elasticsearch.action.update.UpdateRequest; +import org.elasticsearch.common.MemoizedSupplier; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.license.XPackLicenseState.Feature; @@ -41,7 +42,8 @@ public BulkShardRequestInterceptor(ThreadPool threadPool, XPackLicenseState lice @Override public void intercept(RequestInfo requestInfo, AuthorizationEngine authzEngine, AuthorizationInfo authorizationInfo, ActionListener listener) { - boolean shouldIntercept = licenseState.isSecurityEnabled() && licenseState.checkFeature(Feature.SECURITY_DLS_FLS); + boolean shouldIntercept = licenseState.isSecurityEnabled(); + var licenseChecker = new MemoizedSupplier<>(() -> licenseState.checkFeature(Feature.SECURITY_DLS_FLS)); if (requestInfo.getRequest() instanceof BulkShardRequest && shouldIntercept) { IndicesAccessControl indicesAccessControl = threadContext.getTransient(AuthorizationServiceField.INDICES_PERMISSIONS_KEY); @@ -54,7 +56,7 @@ public void intercept(RequestInfo requestInfo, AuthorizationEngine authzEngine, boolean fls = indexAccessControl.getFieldPermissions().hasFieldLevelSecurity(); boolean dls = indexAccessControl.getDocumentPermissions().hasDocumentLevelPermissions(); if (fls || dls) { - if (bulkItemRequest.request() instanceof UpdateRequest) { + if (licenseChecker.get() && bulkItemRequest.request() instanceof UpdateRequest) { found = true; logger.trace("aborting bulk item update request for index [{}]", bulkItemRequest.index()); bulkItemRequest.abort(bulkItemRequest.index(), new ElasticsearchSecurityException("Can't execute a bulk " + diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/FieldAndDocumentLevelSecurityRequestInterceptor.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/FieldAndDocumentLevelSecurityRequestInterceptor.java index 600b11532ddde..331ba11dc8d71 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/FieldAndDocumentLevelSecurityRequestInterceptor.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/FieldAndDocumentLevelSecurityRequestInterceptor.java @@ -9,6 +9,7 @@ import org.apache.logging.log4j.Logger; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.IndicesRequest; +import org.elasticsearch.common.MemoizedSupplier; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.license.XPackLicenseState.Feature; @@ -39,7 +40,8 @@ public void intercept(RequestInfo requestInfo, AuthorizationEngine authorization ActionListener listener) { if (requestInfo.getRequest() instanceof IndicesRequest) { IndicesRequest indicesRequest = (IndicesRequest) requestInfo.getRequest(); - boolean shouldIntercept = licenseState.isSecurityEnabled() && licenseState.checkFeature(Feature.SECURITY_DLS_FLS); + boolean shouldIntercept = licenseState.isSecurityEnabled(); + var licenseChecker = new MemoizedSupplier<>(() -> licenseState.checkFeature(Feature.SECURITY_DLS_FLS)); if (supports(indicesRequest) && shouldIntercept) { final IndicesAccessControl indicesAccessControl = threadContext.getTransient(AuthorizationServiceField.INDICES_PERMISSIONS_KEY); @@ -48,7 +50,7 @@ public void intercept(RequestInfo requestInfo, AuthorizationEngine authorization if (indexAccessControl != null) { boolean fieldLevelSecurityEnabled = indexAccessControl.getFieldPermissions().hasFieldLevelSecurity(); boolean documentLevelSecurityEnabled = indexAccessControl.getDocumentPermissions().hasDocumentLevelPermissions(); - if (fieldLevelSecurityEnabled || documentLevelSecurityEnabled) { + if ((fieldLevelSecurityEnabled || documentLevelSecurityEnabled) && licenseChecker.get()) { logger.trace("intercepted request for index [{}] with field level access controls [{}] " + "document level access controls [{}]. disabling conflicting features", index, fieldLevelSecurityEnabled, documentLevelSecurityEnabled); diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptor.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptor.java index b95e8410f81ed..2f47326dd9167 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptor.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptor.java @@ -8,6 +8,7 @@ import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.common.MemoizedSupplier; import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.license.XPackLicenseState; @@ -52,23 +53,22 @@ public void intercept(RequestInfo requestInfo, AuthorizationEngine authorization final XPackLicenseState frozenLicenseState = licenseState.copyCurrentLicenseState(); final AuditTrail auditTrail = auditTrailService.get(); if (frozenLicenseState.isSecurityEnabled()) { - if (frozenLicenseState.checkFeature(Feature.SECURITY_DLS_FLS)) { - IndicesAccessControl indicesAccessControl = - threadContext.getTransient(AuthorizationServiceField.INDICES_PERMISSIONS_KEY); - for (IndicesAliasesRequest.AliasActions aliasAction : request.getAliasActions()) { - if (aliasAction.actionType() == IndicesAliasesRequest.AliasActions.Type.ADD) { - for (String index : aliasAction.indices()) { - IndicesAccessControl.IndexAccessControl indexAccessControl = - indicesAccessControl.getIndexPermissions(index); - if (indexAccessControl != null) { - final boolean fls = indexAccessControl.getFieldPermissions().hasFieldLevelSecurity(); - final boolean dls = indexAccessControl.getDocumentPermissions().hasDocumentLevelPermissions(); - if (fls || dls) { - listener.onFailure(new ElasticsearchSecurityException("Alias requests are not allowed for " + - "users who have field or document level security enabled on one of the indices", - RestStatus.BAD_REQUEST)); - return; - } + var licenseChecker = new MemoizedSupplier<>(() -> licenseState.checkFeature(Feature.SECURITY_DLS_FLS)); + IndicesAccessControl indicesAccessControl = + threadContext.getTransient(AuthorizationServiceField.INDICES_PERMISSIONS_KEY); + for (IndicesAliasesRequest.AliasActions aliasAction : request.getAliasActions()) { + if (aliasAction.actionType() == IndicesAliasesRequest.AliasActions.Type.ADD) { + for (String index : aliasAction.indices()) { + IndicesAccessControl.IndexAccessControl indexAccessControl = + indicesAccessControl.getIndexPermissions(index); + if (indexAccessControl != null) { + final boolean fls = indexAccessControl.getFieldPermissions().hasFieldLevelSecurity(); + final boolean dls = indexAccessControl.getDocumentPermissions().hasDocumentLevelPermissions(); + if ((fls || dls) && licenseChecker.get()) { + listener.onFailure(new ElasticsearchSecurityException("Alias requests are not allowed for " + + "users who have field or document level security enabled on one of the indices", + RestStatus.BAD_REQUEST)); + return; } } } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/ResizeRequestInterceptor.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/ResizeRequestInterceptor.java index 976acae3a2916..9c41a4e075de0 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/ResizeRequestInterceptor.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/ResizeRequestInterceptor.java @@ -8,6 +8,7 @@ import org.elasticsearch.ElasticsearchSecurityException; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.admin.indices.shrink.ResizeRequest; +import org.elasticsearch.common.MemoizedSupplier; import org.elasticsearch.common.util.concurrent.ThreadContext; import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.license.XPackLicenseState.Feature; @@ -48,19 +49,18 @@ public void intercept(RequestInfo requestInfo, AuthorizationEngine authorization final XPackLicenseState frozenLicenseState = licenseState.copyCurrentLicenseState(); final AuditTrail auditTrail = auditTrailService.get(); if (frozenLicenseState.isSecurityEnabled()) { - if (frozenLicenseState.checkFeature(Feature.SECURITY_DLS_FLS)) { - IndicesAccessControl indicesAccessControl = - threadContext.getTransient(AuthorizationServiceField.INDICES_PERMISSIONS_KEY); - IndicesAccessControl.IndexAccessControl indexAccessControl = - indicesAccessControl.getIndexPermissions(request.getSourceIndex()); - if (indexAccessControl != null) { - final boolean fls = indexAccessControl.getFieldPermissions().hasFieldLevelSecurity(); - final boolean dls = indexAccessControl.getDocumentPermissions().hasDocumentLevelPermissions(); - if (fls || dls) { - listener.onFailure(new ElasticsearchSecurityException("Resize requests are not allowed for users when " + - "field or document level security is enabled on the source index", RestStatus.BAD_REQUEST)); - return; - } + var licenseChecker = new MemoizedSupplier<>(() -> licenseState.checkFeature(Feature.SECURITY_DLS_FLS)); + IndicesAccessControl indicesAccessControl = + threadContext.getTransient(AuthorizationServiceField.INDICES_PERMISSIONS_KEY); + IndicesAccessControl.IndexAccessControl indexAccessControl = + indicesAccessControl.getIndexPermissions(request.getSourceIndex()); + if (indexAccessControl != null) { + final boolean fls = indexAccessControl.getFieldPermissions().hasFieldLevelSecurity(); + final boolean dls = indexAccessControl.getDocumentPermissions().hasDocumentLevelPermissions(); + if ((fls || dls) && licenseChecker.get()) { + listener.onFailure(new ElasticsearchSecurityException("Resize requests are not allowed for users when " + + "field or document level security is enabled on the source index", RestStatus.BAD_REQUEST)); + return; } } diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStore.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStore.java index 4a7a8fc7a8f7d..cce1462bab491 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStore.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStore.java @@ -70,6 +70,7 @@ import java.util.function.Predicate; import java.util.stream.Collectors; +import static java.util.function.Predicate.not; import static org.elasticsearch.common.util.set.Sets.newHashSet; import static org.elasticsearch.xpack.security.support.SecurityIndexManager.isIndexDeleted; import static org.elasticsearch.xpack.security.support.SecurityIndexManager.isMoveFromRedToNonRed; @@ -166,12 +167,14 @@ public void roles(Set roleNames, ActionListener roleActionListener rolesRetrievalResult.getMissingRoles())); } final Set effectiveDescriptors; - if (licenseState.checkFeature(Feature.SECURITY_DLS_FLS)) { - effectiveDescriptors = rolesRetrievalResult.getRoleDescriptors(); + Set roleDescriptors = rolesRetrievalResult.getRoleDescriptors(); + if (roleDescriptors.stream().anyMatch(RoleDescriptor::isUsingDocumentOrFieldLevelSecurity) && + licenseState.checkFeature(Feature.SECURITY_DLS_FLS) == false) { + effectiveDescriptors = roleDescriptors.stream() + .filter(not(RoleDescriptor::isUsingDocumentOrFieldLevelSecurity)) + .collect(Collectors.toSet()); } else { - effectiveDescriptors = rolesRetrievalResult.getRoleDescriptors().stream() - .filter((rd) -> rd.isUsingDocumentOrFieldLevelSecurity() == false) - .collect(Collectors.toSet()); + effectiveDescriptors = roleDescriptors; } logger.trace(() -> new ParameterizedMessage("Exposing effective role descriptors [{}] for role names [{}]", effectiveDescriptors, roleNames)); diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/FileRolesStore.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/FileRolesStore.java index 039db0e965769..01c6ab857fdde 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/FileRolesStore.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/FileRolesStore.java @@ -12,6 +12,7 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchParseException; import org.elasticsearch.action.ActionListener; +import org.elasticsearch.common.MemoizedSupplier; import org.elasticsearch.common.Nullable; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.util.set.Sets; @@ -176,14 +177,14 @@ public static Map parseFile(Path path, Logger logger, bo if (Files.exists(path)) { try { List roleSegments = roleSegments(path); - final boolean flsDlsLicensed = licenseState.checkFeature(Feature.SECURITY_DLS_FLS); + var licenseChecker = new MemoizedSupplier<>(() -> licenseState.checkFeature(Feature.SECURITY_DLS_FLS)); for (String segment : roleSegments) { RoleDescriptor descriptor = parseRoleDescriptor(segment, path, logger, resolvePermission, settings, xContentRegistry); if (descriptor != null) { if (ReservedRolesStore.isReserved(descriptor.getName())) { logger.warn("role [{}] is reserved. the relevant role definition in the mapping file will be ignored", descriptor.getName()); - } else if (flsDlsLicensed == false && descriptor.isUsingDocumentOrFieldLevelSecurity()) { + } else if (descriptor.isUsingDocumentOrFieldLevelSecurity() && licenseChecker.get() == false) { logger.warn("role [{}] uses document and/or field level security, which is not enabled by the current license" + ". this role will be ignored", descriptor.getName()); // we still put the role in the map to avoid unnecessary negative lookups diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/NativeRolesStore.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/NativeRolesStore.java index 454b42751b292..490339ded090f 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/NativeRolesStore.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/NativeRolesStore.java @@ -189,9 +189,7 @@ public void onFailure(Exception e) { } public void putRole(final PutRoleRequest request, final RoleDescriptor role, final ActionListener listener) { - if (licenseState.checkFeature(Feature.SECURITY_DLS_FLS)) { - innerPutRole(request, role, listener); - } else if (role.isUsingDocumentOrFieldLevelSecurity()) { + if (role.isUsingDocumentOrFieldLevelSecurity() && licenseState.checkFeature(Feature.SECURITY_DLS_FLS) == false) { listener.onFailure(LicenseUtils.newComplianceException("field and document level security")); } else { innerPutRole(request, role, listener); @@ -370,30 +368,25 @@ static RoleDescriptor transformRole(String id, BytesReference sourceBytes, Logge // we pass true as last parameter because we do not want to reject permissions if the field permissions // are given in 2.x syntax RoleDescriptor roleDescriptor = RoleDescriptor.parse(name, sourceBytes, true, XContentType.JSON); - if (licenseState.checkFeature(Feature.SECURITY_DLS_FLS)) { - return roleDescriptor; - } else { - final boolean dlsEnabled = - Arrays.stream(roleDescriptor.getIndicesPrivileges()).anyMatch(IndicesPrivileges::isUsingDocumentLevelSecurity); - final boolean flsEnabled = - Arrays.stream(roleDescriptor.getIndicesPrivileges()).anyMatch(IndicesPrivileges::isUsingFieldLevelSecurity); - if (dlsEnabled || flsEnabled) { - List unlicensedFeatures = new ArrayList<>(2); - if (flsEnabled) { - unlicensedFeatures.add("fls"); - } - if (dlsEnabled) { - unlicensedFeatures.add("dls"); - } - Map transientMap = new HashMap<>(2); - transientMap.put("unlicensed_features", unlicensedFeatures); - transientMap.put("enabled", false); - return new RoleDescriptor(roleDescriptor.getName(), roleDescriptor.getClusterPrivileges(), - roleDescriptor.getIndicesPrivileges(), roleDescriptor.getRunAs(), roleDescriptor.getMetadata(), transientMap); - } else { - return roleDescriptor; + final boolean dlsEnabled = + Arrays.stream(roleDescriptor.getIndicesPrivileges()).anyMatch(IndicesPrivileges::isUsingDocumentLevelSecurity); + final boolean flsEnabled = + Arrays.stream(roleDescriptor.getIndicesPrivileges()).anyMatch(IndicesPrivileges::isUsingFieldLevelSecurity); + if ((dlsEnabled || flsEnabled) && licenseState.checkFeature(Feature.SECURITY_DLS_FLS) == false) { + List unlicensedFeatures = new ArrayList<>(2); + if (flsEnabled) { + unlicensedFeatures.add("fls"); } - + if (dlsEnabled) { + unlicensedFeatures.add("dls"); + } + Map transientMap = new HashMap<>(2); + transientMap.put("unlicensed_features", unlicensedFeatures); + transientMap.put("enabled", false); + return new RoleDescriptor(roleDescriptor.getName(), roleDescriptor.getClusterPrivileges(), + roleDescriptor.getIndicesPrivileges(), roleDescriptor.getRunAs(), roleDescriptor.getMetadata(), transientMap); + } else { + return roleDescriptor; } } catch (Exception e) { logger.error(new ParameterizedMessage("error in the format of data for role [{}]", name), e); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityInfoTransportActionTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityInfoTransportActionTests.java index 160163dfa5661..3b653b130d0c7 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityInfoTransportActionTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityInfoTransportActionTests.java @@ -71,10 +71,10 @@ public void init() throws Exception { public void testAvailable() { SecurityInfoTransportAction featureSet = new SecurityInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), licenseState); - when(licenseState.isAllowed(XPackLicenseState.Feature.SECURITY)).thenReturn(true); + when(licenseState.checkFeature(XPackLicenseState.Feature.SECURITY)).thenReturn(true); assertThat(featureSet.available(), is(true)); - when(licenseState.isAllowed(XPackLicenseState.Feature.SECURITY)).thenReturn(false); + when(licenseState.checkFeature(XPackLicenseState.Feature.SECURITY)).thenReturn(false); assertThat(featureSet.available(), is(false)); } @@ -94,7 +94,7 @@ public void testUsage() throws Exception { final boolean authcAuthzAvailable = randomBoolean(); final boolean explicitlyDisabled = randomBoolean(); final boolean enabled = explicitlyDisabled == false && randomBoolean(); - when(licenseState.isAllowed(XPackLicenseState.Feature.SECURITY)).thenReturn(authcAuthzAvailable); + when(licenseState.checkFeature(XPackLicenseState.Feature.SECURITY)).thenReturn(authcAuthzAvailable); when(licenseState.isSecurityEnabled()).thenReturn(enabled); Settings.Builder settings = Settings.builder().put(this.settings); @@ -248,7 +248,7 @@ public void testUsage() throws Exception { } public void testUsageOnTrialLicenseWithSecurityDisabledByDefault() throws Exception { - when(licenseState.isAllowed(XPackLicenseState.Feature.SECURITY)).thenReturn(true); + when(licenseState.checkFeature(XPackLicenseState.Feature.SECURITY)).thenReturn(true); when(licenseState.isSecurityEnabled()).thenReturn(false); Settings.Builder settings = Settings.builder().put(this.settings); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/AuthorizationServiceTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/AuthorizationServiceTests.java index b036bd941924c..1ddd6faf70b65 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/AuthorizationServiceTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/AuthorizationServiceTests.java @@ -685,7 +685,7 @@ public void testDenialForAnonymousUser() throws IOException { final AnonymousUser anonymousUser = new AnonymousUser(settings); authorizationService = new AuthorizationService(settings, rolesStore, clusterService, auditTrailService, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, anonymousUser, null, Collections.emptySet(), - new XPackLicenseState(settings), new IndexNameExpressionResolver()); + new XPackLicenseState(settings, () -> 0), new IndexNameExpressionResolver()); RoleDescriptor role = new RoleDescriptor("a_all", null, new IndicesPrivileges[] { IndicesPrivileges.builder().indices("a").privileges("all").build() }, null); @@ -713,7 +713,7 @@ public void testDenialForAnonymousUserAuthorizationExceptionDisabled() throws IO final Authentication authentication = createAuthentication(new AnonymousUser(settings)); authorizationService = new AuthorizationService(settings, rolesStore, clusterService, auditTrailService, new DefaultAuthenticationFailureHandler(Collections.emptyMap()), threadPool, new AnonymousUser(settings), null, - Collections.emptySet(), new XPackLicenseState(settings), new IndexNameExpressionResolver()); + Collections.emptySet(), new XPackLicenseState(settings, () -> 0), new IndexNameExpressionResolver()); RoleDescriptor role = new RoleDescriptor("a_all", null, new IndicesPrivileges[]{IndicesPrivileges.builder().indices("a").privileges("all").build()}, null); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java index 6dc0ae4a26441..d599ac349692f 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java @@ -346,7 +346,7 @@ public void testNegativeLookupsCacheDisabled() { final DocumentSubsetBitsetCache documentSubsetBitsetCache = buildBitsetCache(); final CompositeRolesStore compositeRolesStore = new CompositeRolesStore(settings, fileRolesStore, nativeRolesStore, reservedRolesStore, mock(NativePrivilegeStore.class), Collections.emptyList(), new ThreadContext(settings), - new XPackLicenseState(settings), cache, mock(ApiKeyService.class), documentSubsetBitsetCache, + new XPackLicenseState(settings, () -> 0), cache, mock(ApiKeyService.class), documentSubsetBitsetCache, rds -> effectiveRoleDescriptors.set(rds)); verify(fileRolesStore).addListener(any(Consumer.class)); // adds a listener in ctor @@ -385,7 +385,7 @@ public void testNegativeLookupsAreNotCachedWithFailures() { final CompositeRolesStore compositeRolesStore = new CompositeRolesStore(SECURITY_ENABLED_SETTINGS, fileRolesStore, nativeRolesStore, reservedRolesStore, mock(NativePrivilegeStore.class), Collections.emptyList(), new ThreadContext(SECURITY_ENABLED_SETTINGS), - new XPackLicenseState(SECURITY_ENABLED_SETTINGS), cache, mock(ApiKeyService.class), documentSubsetBitsetCache, + new XPackLicenseState(SECURITY_ENABLED_SETTINGS, () -> 0), cache, mock(ApiKeyService.class), documentSubsetBitsetCache, rds -> effectiveRoleDescriptors.set(rds)); verify(fileRolesStore).addListener(any(Consumer.class)); // adds a listener in ctor @@ -472,7 +472,7 @@ public void testCustomRolesProviders() { final CompositeRolesStore compositeRolesStore = new CompositeRolesStore(SECURITY_ENABLED_SETTINGS, fileRolesStore, nativeRolesStore, reservedRolesStore, mock(NativePrivilegeStore.class), Arrays.asList(inMemoryProvider1, inMemoryProvider2), - new ThreadContext(SECURITY_ENABLED_SETTINGS), new XPackLicenseState(SECURITY_ENABLED_SETTINGS), + new ThreadContext(SECURITY_ENABLED_SETTINGS), new XPackLicenseState(SECURITY_ENABLED_SETTINGS, () -> 0), cache, mock(ApiKeyService.class), documentSubsetBitsetCache, rds -> effectiveRoleDescriptors.set(rds)); @@ -701,7 +701,7 @@ public void testCustomRolesProviderFailures() throws Exception { final CompositeRolesStore compositeRolesStore = new CompositeRolesStore(SECURITY_ENABLED_SETTINGS, fileRolesStore, nativeRolesStore, reservedRolesStore, mock(NativePrivilegeStore.class), Arrays.asList(inMemoryProvider1, failingProvider), - new ThreadContext(SECURITY_ENABLED_SETTINGS), new XPackLicenseState(SECURITY_ENABLED_SETTINGS), + new ThreadContext(SECURITY_ENABLED_SETTINGS), new XPackLicenseState(SECURITY_ENABLED_SETTINGS, () -> 0), cache, mock(ApiKeyService.class), documentSubsetBitsetCache, rds -> effectiveRoleDescriptors.set(rds)); final Set roleNames = Sets.newHashSet("roleA", "roleB", "unknown"); @@ -813,7 +813,7 @@ public void testCacheClearOnIndexHealthChange() { CompositeRolesStore compositeRolesStore = new CompositeRolesStore( Settings.EMPTY, fileRolesStore, nativeRolesStore, reservedRolesStore, mock(NativePrivilegeStore.class), Collections.emptyList(), new ThreadContext(Settings.EMPTY), - new XPackLicenseState(SECURITY_ENABLED_SETTINGS), cache, mock(ApiKeyService.class), documentSubsetBitsetCache, + new XPackLicenseState(SECURITY_ENABLED_SETTINGS, () -> 0), cache, mock(ApiKeyService.class), documentSubsetBitsetCache, rds -> {}) { @Override public void invalidateAll() { @@ -867,7 +867,7 @@ public void testCacheClearOnIndexOutOfDateChange() { CompositeRolesStore compositeRolesStore = new CompositeRolesStore(SECURITY_ENABLED_SETTINGS, fileRolesStore, nativeRolesStore, reservedRolesStore, mock(NativePrivilegeStore.class), Collections.emptyList(), new ThreadContext(SECURITY_ENABLED_SETTINGS), - new XPackLicenseState(SECURITY_ENABLED_SETTINGS), cache, mock(ApiKeyService.class), + new XPackLicenseState(SECURITY_ENABLED_SETTINGS, () -> 0), cache, mock(ApiKeyService.class), documentSubsetBitsetCache, rds -> {}) { @Override public void invalidateAll() { @@ -963,7 +963,7 @@ public void testDoesNotUseRolesStoreForXPacAndAsyncSearchUser() { final CompositeRolesStore compositeRolesStore = new CompositeRolesStore(SECURITY_ENABLED_SETTINGS, fileRolesStore, nativeRolesStore, reservedRolesStore, mock(NativePrivilegeStore.class), Collections.emptyList(), new ThreadContext(SECURITY_ENABLED_SETTINGS), - new XPackLicenseState(SECURITY_ENABLED_SETTINGS), cache, mock(ApiKeyService.class), documentSubsetBitsetCache, + new XPackLicenseState(SECURITY_ENABLED_SETTINGS, () -> 0), cache, mock(ApiKeyService.class), documentSubsetBitsetCache, rds -> effectiveRoleDescriptors.set(rds)); verify(fileRolesStore).addListener(any(Consumer.class)); // adds a listener in ctor @@ -1004,7 +1004,7 @@ public void testGetRolesForSystemUserThrowsException() { final CompositeRolesStore compositeRolesStore = new CompositeRolesStore(SECURITY_ENABLED_SETTINGS, fileRolesStore, nativeRolesStore, reservedRolesStore, mock(NativePrivilegeStore.class), Collections.emptyList(), new ThreadContext(SECURITY_ENABLED_SETTINGS), - new XPackLicenseState(SECURITY_ENABLED_SETTINGS), cache, mock(ApiKeyService.class), documentSubsetBitsetCache, + new XPackLicenseState(SECURITY_ENABLED_SETTINGS, () -> 0), cache, mock(ApiKeyService.class), documentSubsetBitsetCache, rds -> effectiveRoleDescriptors.set(rds)); verify(fileRolesStore).addListener(any(Consumer.class)); // adds a listener in ctor IllegalArgumentException iae = expectThrows(IllegalArgumentException.class, @@ -1042,7 +1042,7 @@ public void testApiKeyAuthUsesApiKeyService() throws Exception { final CompositeRolesStore compositeRolesStore = new CompositeRolesStore(SECURITY_ENABLED_SETTINGS, fileRolesStore, nativeRolesStore, reservedRolesStore, nativePrivStore, Collections.emptyList(), new ThreadContext(SECURITY_ENABLED_SETTINGS), - new XPackLicenseState(SECURITY_ENABLED_SETTINGS), cache, apiKeyService, documentSubsetBitsetCache, + new XPackLicenseState(SECURITY_ENABLED_SETTINGS, () -> 0), cache, apiKeyService, documentSubsetBitsetCache, rds -> effectiveRoleDescriptors.set(rds)); AuditUtil.getOrGenerateRequestId(threadContext); @@ -1087,7 +1087,7 @@ public void testApiKeyAuthUsesApiKeyServiceWithScopedRole() throws Exception { final CompositeRolesStore compositeRolesStore = new CompositeRolesStore(SECURITY_ENABLED_SETTINGS, fileRolesStore, nativeRolesStore, reservedRolesStore, nativePrivStore, Collections.emptyList(), new ThreadContext(SECURITY_ENABLED_SETTINGS), - new XPackLicenseState(SECURITY_ENABLED_SETTINGS), cache, apiKeyService, documentSubsetBitsetCache, + new XPackLicenseState(SECURITY_ENABLED_SETTINGS, () -> 0), cache, apiKeyService, documentSubsetBitsetCache, rds -> effectiveRoleDescriptors.set(rds)); AuditUtil.getOrGenerateRequestId(threadContext); @@ -1236,7 +1236,7 @@ private CompositeRolesStore buildCompositeRolesStore(Settings settings, }).when(privilegeStore).getPrivileges(isA(Set.class), isA(Set.class), any(ActionListener.class)); } if (licenseState == null) { - licenseState = new XPackLicenseState(settings); + licenseState = new XPackLicenseState(settings, () -> 0); } if (apiKeyService == null) { apiKeyService = mock(ApiKeyService.class); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/ServerTransportFilterTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/ServerTransportFilterTests.java index e9e80bcf9745d..f8608d94001a7 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/ServerTransportFilterTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/transport/ServerTransportFilterTests.java @@ -197,6 +197,6 @@ private ServerTransportFilter getNodeFilter() { Settings settings = Settings.builder().put("path.home", createTempDir()).build(); ThreadContext threadContext = new ThreadContext(settings); return new ServerTransportFilter(authcService, authzService, threadContext, false, destructiveOperations, - new SecurityContext(settings, threadContext), new XPackLicenseState(settings)); + new SecurityContext(settings, threadContext), new XPackLicenseState(settings, () -> 0)); } } diff --git a/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportAction.java b/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportAction.java index f3fbb31e35b0b..b97f7a69089b2 100644 --- a/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportAction.java +++ b/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportAction.java @@ -32,7 +32,7 @@ public String name() { @Override public boolean available() { - return licenseState.isAllowed(XPackLicenseState.Feature.SPATIAL); + return licenseState.checkFeature(XPackLicenseState.Feature.SPATIAL); } @Override diff --git a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportActionTests.java b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportActionTests.java index dd89a23312464..98b1a8ff5e72d 100644 --- a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportActionTests.java +++ b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportActionTests.java @@ -34,7 +34,7 @@ public void testAvailable() throws Exception { SpatialInfoTransportAction featureSet = new SpatialInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), Settings.EMPTY, licenseState); boolean available = randomBoolean(); - when(licenseState.isAllowed(XPackLicenseState.Feature.SPATIAL)).thenReturn(available); + when(licenseState.checkFeature(XPackLicenseState.Feature.SPATIAL)).thenReturn(available); assertThat(featureSet.available(), is(available)); var usageAction = new SpatialUsageTransportAction(mock(TransportService.class), null, null, diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/SqlInfoTransportAction.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/SqlInfoTransportAction.java index 636a9fb694024..f848c4fcdd8da 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/SqlInfoTransportAction.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/SqlInfoTransportAction.java @@ -31,7 +31,7 @@ public String name() { @Override public boolean available() { - return licenseState.isAllowed(XPackLicenseState.Feature.SQL); + return licenseState.checkFeature(XPackLicenseState.Feature.SQL); } @Override diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/SqlInfoTransportActionTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/SqlInfoTransportActionTests.java index 162ff0d5c964e..ad35b75b446ba 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/SqlInfoTransportActionTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/SqlInfoTransportActionTests.java @@ -59,7 +59,7 @@ public void testAvailable() { SqlInfoTransportAction featureSet = new SqlInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), licenseState); boolean available = randomBoolean(); - when(licenseState.isAllowed(XPackLicenseState.Feature.SQL)).thenReturn(available); + when(licenseState.checkFeature(XPackLicenseState.Feature.SQL)).thenReturn(available); assertThat(featureSet.available(), is(available)); } diff --git a/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/TransformInfoTransportAction.java b/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/TransformInfoTransportAction.java index a72ba93721119..f2ffb83011d63 100644 --- a/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/TransformInfoTransportAction.java +++ b/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/TransformInfoTransportAction.java @@ -75,7 +75,7 @@ public String name() { @Override public boolean available() { - return licenseState.isAllowed(XPackLicenseState.Feature.TRANSFORM); + return licenseState.checkFeature(XPackLicenseState.Feature.TRANSFORM); } @Override diff --git a/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/TransformInfoTransportActionTests.java b/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/TransformInfoTransportActionTests.java index 1751e2f7334b8..39c20f68ea8ff 100644 --- a/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/TransformInfoTransportActionTests.java +++ b/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/TransformInfoTransportActionTests.java @@ -42,7 +42,7 @@ public void testAvailable() { licenseState ); boolean available = randomBoolean(); - when(licenseState.isAllowed(XPackLicenseState.Feature.TRANSFORM)).thenReturn(available); + when(licenseState.checkFeature(XPackLicenseState.Feature.TRANSFORM)).thenReturn(available); assertThat(featureSet.available(), is(available)); } diff --git a/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportAction.java b/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportAction.java index 065c7c3fc493a..50dbcf54520bd 100644 --- a/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportAction.java +++ b/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportAction.java @@ -31,7 +31,7 @@ public String name() { @Override public boolean available() { - return licenseState.isAllowed(XPackLicenseState.Feature.VECTORS); + return licenseState.checkFeature(XPackLicenseState.Feature.VECTORS); } @Override diff --git a/x-pack/plugin/vectors/src/test/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportActionTests.java b/x-pack/plugin/vectors/src/test/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportActionTests.java index 0d4154c8151dc..0582b5fa81863 100644 --- a/x-pack/plugin/vectors/src/test/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportActionTests.java +++ b/x-pack/plugin/vectors/src/test/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportActionTests.java @@ -33,7 +33,7 @@ public void testAvailable() throws Exception { VectorsInfoTransportAction featureSet = new VectorsInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), licenseState); boolean available = randomBoolean(); - when(licenseState.isAllowed(XPackLicenseState.Feature.VECTORS)).thenReturn(available); + when(licenseState.checkFeature(XPackLicenseState.Feature.VECTORS)).thenReturn(available); assertThat(featureSet.available(), is(available)); var usageAction = new VectorsUsageTransportAction(mock(TransportService.class), null, null, diff --git a/x-pack/plugin/voting-only-node/src/main/java/org/elasticsearch/cluster/coordination/VotingOnlyNodeFeatureSet.java b/x-pack/plugin/voting-only-node/src/main/java/org/elasticsearch/cluster/coordination/VotingOnlyNodeFeatureSet.java index aeb87de9c2210..793ec0720c276 100644 --- a/x-pack/plugin/voting-only-node/src/main/java/org/elasticsearch/cluster/coordination/VotingOnlyNodeFeatureSet.java +++ b/x-pack/plugin/voting-only-node/src/main/java/org/elasticsearch/cluster/coordination/VotingOnlyNodeFeatureSet.java @@ -43,7 +43,7 @@ public String name() { @Override public boolean available() { - return licenseState != null && licenseState.isAllowed(Feature.VOTING_ONLY); + return licenseState != null && licenseState.checkFeature(Feature.VOTING_ONLY); } @Override diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportAction.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportAction.java index 13c43b79a5354..e28103cd5b226 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportAction.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportAction.java @@ -35,7 +35,7 @@ public String name() { @Override public boolean available() { - return licenseState.isAllowed(XPackLicenseState.Feature.WATCHER); + return licenseState.checkFeature(XPackLicenseState.Feature.WATCHER); } @Override diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportActionTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportActionTests.java index 5e5f47416695e..3a3dc25b45c14 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportActionTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportActionTests.java @@ -68,7 +68,7 @@ public void testAvailable() { WatcherInfoTransportAction featureSet = new WatcherInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), Settings.EMPTY, licenseState); boolean available = randomBoolean(); - when(licenseState.isAllowed(XPackLicenseState.Feature.WATCHER)).thenReturn(available); + when(licenseState.checkFeature(XPackLicenseState.Feature.WATCHER)).thenReturn(available); assertThat(featureSet.available(), is(available)); } From 9c389b18ffd06f08e8de300d62ed82ebfad02ceb Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Thu, 9 Jul 2020 14:04:01 -0700 Subject: [PATCH 02/11] checkstyle --- .../java/org/elasticsearch/license/GetFeatureUsageResponse.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetFeatureUsageResponse.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetFeatureUsageResponse.java index e1ca01e09061d..335190d6bc4ee 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetFeatureUsageResponse.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/license/GetFeatureUsageResponse.java @@ -15,12 +15,10 @@ import java.io.IOException; import java.time.Instant; -import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.Collections; import java.util.List; -import java.util.Map; public class GetFeatureUsageResponse extends ActionResponse implements ToXContentObject { From bc144235611493d536ce60db1e130087725b69dd Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Thu, 9 Jul 2020 14:26:04 -0700 Subject: [PATCH 03/11] fix compile --- .../security/audit/logfile/LoggingAuditTrailFilterTests.java | 2 +- .../xpack/security/audit/logfile/LoggingAuditTrailTests.java | 2 +- .../xpack/security/authz/store/CompositeRolesStoreTests.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java index a11079f720f65..e704753c294c5 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java @@ -90,7 +90,7 @@ public void init() throws Exception { arg0.updateLocalNodeInfo(localNode); return null; }).when(clusterService).addListener(Mockito.isA(LoggingAuditTrail.class)); - apiKeyService = new ApiKeyService(settings, Clock.systemUTC(), mock(Client.class), new XPackLicenseState(settings), + apiKeyService = new ApiKeyService(settings, Clock.systemUTC(), mock(Client.class), new XPackLicenseState(settings, () -> 0), mock(SecurityIndexManager.class), clusterService, mock(ThreadPool.class)); } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java index 6e252c4cd19bd..6cf1c76b8aebc 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java @@ -220,7 +220,7 @@ public void init() throws Exception { } logger = CapturingLogger.newCapturingLogger(randomFrom(Level.OFF, Level.FATAL, Level.ERROR, Level.WARN, Level.INFO), patternLayout); auditTrail = new LoggingAuditTrail(settings, clusterService, logger, threadContext); - apiKeyService = new ApiKeyService(settings, Clock.systemUTC(), client, new XPackLicenseState(settings), + apiKeyService = new ApiKeyService(settings, Clock.systemUTC(), client, new XPackLicenseState(settings, () -> 0), securityIndexManager, clusterService, mock(ThreadPool.class)); } diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java index d599ac349692f..088ffd7c26d6d 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java @@ -1027,7 +1027,7 @@ public void testApiKeyAuthUsesApiKeyService() throws Exception { final ReservedRolesStore reservedRolesStore = spy(new ReservedRolesStore()); ThreadContext threadContext = new ThreadContext(SECURITY_ENABLED_SETTINGS); ApiKeyService apiKeyService = new ApiKeyService(SECURITY_ENABLED_SETTINGS, Clock.systemUTC(), mock(Client.class), - new XPackLicenseState(SECURITY_ENABLED_SETTINGS), mock(SecurityIndexManager.class), mock(ClusterService.class), + new XPackLicenseState(SECURITY_ENABLED_SETTINGS, () -> 0), mock(SecurityIndexManager.class), mock(ClusterService.class), mock(ThreadPool.class)); NativePrivilegeStore nativePrivStore = mock(NativePrivilegeStore.class); doAnswer(invocationOnMock -> { @@ -1072,7 +1072,7 @@ public void testApiKeyAuthUsesApiKeyServiceWithScopedRole() throws Exception { ThreadContext threadContext = new ThreadContext(SECURITY_ENABLED_SETTINGS); ApiKeyService apiKeyService = new ApiKeyService(SECURITY_ENABLED_SETTINGS, Clock.systemUTC(), mock(Client.class), - new XPackLicenseState(SECURITY_ENABLED_SETTINGS), mock(SecurityIndexManager.class), mock(ClusterService.class), + new XPackLicenseState(SECURITY_ENABLED_SETTINGS, () -> 0), mock(SecurityIndexManager.class), mock(ClusterService.class), mock(ThreadPool.class)); NativePrivilegeStore nativePrivStore = mock(NativePrivilegeStore.class); doAnswer(invocationOnMock -> { From 2f36787e78340d49cafc0c0e4cff439b2695044a Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Thu, 9 Jul 2020 14:55:53 -0700 Subject: [PATCH 04/11] fix local state insanity --- .../action/AnalyticsInfoTransportAction.java | 2 +- .../action/AnalyticsInfoTransportActionTests.java | 2 +- .../org/elasticsearch/xpack/core/XPackPlugin.java | 9 +++++++-- .../xpack/core/LocalStateCompositeXPackPlugin.java | 12 ++++++++++++ .../enrich/action/EnrichInfoTransportAction.java | 2 +- .../xpack/graph/GraphInfoTransportAction.java | 2 +- .../xpack/graph/GraphInfoTransportActionTests.java | 2 +- .../xpack/ilm/IndexLifecycleInfoTransportAction.java | 2 +- .../ilm/IndexLifecycleInfoTransportActionTests.java | 4 ++-- .../xpack/logstash/LogstashInfoTransportAction.java | 2 +- .../logstash/LogstashInfoTransportActionTests.java | 2 +- 11 files changed, 29 insertions(+), 12 deletions(-) diff --git a/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportAction.java b/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportAction.java index 75a1202db90f7..1ceadaab8096c 100644 --- a/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportAction.java +++ b/x-pack/plugin/analytics/src/main/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportAction.java @@ -31,7 +31,7 @@ public String name() { @Override public boolean available() { - return licenseState.checkFeature(XPackLicenseState.Feature.ANALYTICS); + return licenseState.isAllowed(XPackLicenseState.Feature.ANALYTICS); } @Override diff --git a/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportActionTests.java b/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportActionTests.java index 46083f9a53dfb..3aeab48c0c7de 100644 --- a/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportActionTests.java +++ b/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportActionTests.java @@ -63,7 +63,7 @@ public void testAvailable() throws Exception { AnalyticsInfoTransportAction featureSet = new AnalyticsInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), licenseState); boolean available = randomBoolean(); - when(licenseState.checkFeature(XPackLicenseState.Feature.ANALYTICS)).thenReturn(available); + when(licenseState.isAllowed(XPackLicenseState.Feature.ANALYTICS)).thenReturn(available); assertThat(featureSet.available(), is(available)); Client client = mockClient(); AnalyticsUsageTransportAction usageAction = new AnalyticsUsageTransportAction(mock(TransportService.class), clusterService, null, diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java index fc613254da763..67d33803d0c80 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackPlugin.java @@ -142,7 +142,7 @@ public XPackPlugin( // We should only depend on the settings from the Environment object passed to createComponents this.settings = settings; - setLicenseState(new XPackLicenseState(settings, () -> epochMillisSupplier.get().getAsLong())); + setLicenseState(new XPackLicenseState(settings, () -> getEpochMillisSupplier().getAsLong())); this.licensing = new Licensing(settings); } @@ -155,9 +155,13 @@ protected Clock getClock() { protected SSLService getSslService() { return getSharedSslService(); } protected LicenseService getLicenseService() { return getSharedLicenseService(); } protected XPackLicenseState getLicenseState() { return getSharedLicenseState(); } + protected LongSupplier getEpochMillisSupplier() { return getSharedEpochMillisSupplier(); } protected void setSslService(SSLService sslService) { XPackPlugin.sslService.set(sslService); } protected void setLicenseService(LicenseService licenseService) { XPackPlugin.licenseService.set(licenseService); } protected void setLicenseState(XPackLicenseState licenseState) { XPackPlugin.licenseState.set(licenseState); } + protected void setEpochMillisSupplier(LongSupplier epochMillisSupplier) { + XPackPlugin.epochMillisSupplier.set(epochMillisSupplier); + } public static SSLService getSharedSslService() { final SSLService ssl = XPackPlugin.sslService.get(); @@ -168,6 +172,7 @@ public static SSLService getSharedSslService() { } public static LicenseService getSharedLicenseService() { return licenseService.get(); } public static XPackLicenseState getSharedLicenseState() { return licenseState.get(); } + public static LongSupplier getSharedEpochMillisSupplier() { return epochMillisSupplier.get(); } /** * Checks if the cluster state allows this node to add x-pack metadata to the cluster state, @@ -242,7 +247,7 @@ public Collection createComponents(Client client, ClusterService cluster setLicenseService(new LicenseService(settings, clusterService, getClock(), environment, resourceWatcherService, getLicenseState())); - epochMillisSupplier.set(threadPool::absoluteTimeInMillis); + setEpochMillisSupplier(threadPool::absoluteTimeInMillis); // It is useful to override these as they are what guice is injecting into actions components.add(sslService); diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/LocalStateCompositeXPackPlugin.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/LocalStateCompositeXPackPlugin.java index 9bfc18a538249..5f42e058c46b8 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/LocalStateCompositeXPackPlugin.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/LocalStateCompositeXPackPlugin.java @@ -88,6 +88,7 @@ import java.util.Set; import java.util.function.BiConsumer; import java.util.function.Function; +import java.util.function.LongSupplier; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.function.UnaryOperator; @@ -101,6 +102,7 @@ public class LocalStateCompositeXPackPlugin extends XPackPlugin implements Scrip private XPackLicenseState licenseState; private SSLService sslService; private LicenseService licenseService; + private LongSupplier epochMillisSupplier; protected List plugins = new ArrayList<>(); public LocalStateCompositeXPackPlugin(final Settings settings, final Path configPath) { @@ -138,6 +140,16 @@ protected void setLicenseState(XPackLicenseState licenseState) { this.licenseState = licenseState; } + @Override + protected LongSupplier getEpochMillisSupplier() { + return epochMillisSupplier; + } + + @Override + protected void setEpochMillisSupplier(LongSupplier epochMillisSupplier) { + this.epochMillisSupplier = epochMillisSupplier; + } + @Override public Collection createComponents(Client client, ClusterService clusterService, ThreadPool threadPool, ResourceWatcherService resourceWatcherService, ScriptService scriptService, diff --git a/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichInfoTransportAction.java b/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichInfoTransportAction.java index 3804bccfc9f23..44a1befe9e192 100644 --- a/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichInfoTransportAction.java +++ b/x-pack/plugin/enrich/src/main/java/org/elasticsearch/xpack/enrich/action/EnrichInfoTransportAction.java @@ -30,7 +30,7 @@ public String name() { @Override public boolean available() { - return licenseState.checkFeature(XPackLicenseState.Feature.ENRICH); + return licenseState.isAllowed(XPackLicenseState.Feature.ENRICH); } @Override diff --git a/x-pack/plugin/graph/src/main/java/org/elasticsearch/xpack/graph/GraphInfoTransportAction.java b/x-pack/plugin/graph/src/main/java/org/elasticsearch/xpack/graph/GraphInfoTransportAction.java index b8223b64da2e0..ded865f4e2f47 100644 --- a/x-pack/plugin/graph/src/main/java/org/elasticsearch/xpack/graph/GraphInfoTransportAction.java +++ b/x-pack/plugin/graph/src/main/java/org/elasticsearch/xpack/graph/GraphInfoTransportAction.java @@ -35,7 +35,7 @@ public String name() { @Override public boolean available() { - return licenseState != null && licenseState.checkFeature(XPackLicenseState.Feature.GRAPH); + return licenseState != null && licenseState.isAllowed(XPackLicenseState.Feature.GRAPH); } @Override diff --git a/x-pack/plugin/graph/src/test/java/org/elasticsearch/xpack/graph/GraphInfoTransportActionTests.java b/x-pack/plugin/graph/src/test/java/org/elasticsearch/xpack/graph/GraphInfoTransportActionTests.java index b4ace4d4f5bac..0ccbe01e81021 100644 --- a/x-pack/plugin/graph/src/test/java/org/elasticsearch/xpack/graph/GraphInfoTransportActionTests.java +++ b/x-pack/plugin/graph/src/test/java/org/elasticsearch/xpack/graph/GraphInfoTransportActionTests.java @@ -34,7 +34,7 @@ public void testAvailable() throws Exception { GraphInfoTransportAction featureSet = new GraphInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), Settings.EMPTY, licenseState); boolean available = randomBoolean(); - when(licenseState.checkFeature(XPackLicenseState.Feature.GRAPH)).thenReturn(available); + when(licenseState.isAllowed(XPackLicenseState.Feature.GRAPH)).thenReturn(available); assertThat(featureSet.available(), is(available)); var usageAction = new GraphUsageTransportAction(mock(TransportService.class), null, null, diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportAction.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportAction.java index 7a1f704310b5d..ab834b484eaad 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportAction.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportAction.java @@ -31,7 +31,7 @@ public String name() { @Override public boolean available() { - return licenseState.checkFeature(XPackLicenseState.Feature.ILM); + return licenseState.isAllowed(XPackLicenseState.Feature.ILM); } @Override diff --git a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportActionTests.java b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportActionTests.java index 00ef2f7d69d8e..428dab4b6bd46 100644 --- a/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportActionTests.java +++ b/x-pack/plugin/ilm/src/test/java/org/elasticsearch/xpack/ilm/IndexLifecycleInfoTransportActionTests.java @@ -57,10 +57,10 @@ public void testAvailable() { IndexLifecycleInfoTransportAction featureSet = new IndexLifecycleInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), licenseState); - when(licenseState.checkFeature(XPackLicenseState.Feature.ILM)).thenReturn(false); + when(licenseState.isAllowed(XPackLicenseState.Feature.ILM)).thenReturn(false); assertThat(featureSet.available(), equalTo(false)); - when(licenseState.checkFeature(XPackLicenseState.Feature.ILM)).thenReturn(true); + when(licenseState.isAllowed(XPackLicenseState.Feature.ILM)).thenReturn(true); assertThat(featureSet.available(), equalTo(true)); } diff --git a/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportAction.java b/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportAction.java index 016ee32882567..3c130877a84c1 100644 --- a/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportAction.java +++ b/x-pack/plugin/logstash/src/main/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportAction.java @@ -30,7 +30,7 @@ public String name() { @Override public boolean available() { - return licenseState.checkFeature(XPackLicenseState.Feature.LOGSTASH); + return licenseState.isAllowed(XPackLicenseState.Feature.LOGSTASH); } @Override diff --git a/x-pack/plugin/logstash/src/test/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportActionTests.java b/x-pack/plugin/logstash/src/test/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportActionTests.java index 2bed9b26b5b72..2db83434dceb7 100644 --- a/x-pack/plugin/logstash/src/test/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportActionTests.java +++ b/x-pack/plugin/logstash/src/test/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportActionTests.java @@ -61,7 +61,7 @@ public void testAvailable() throws Exception { licenseState ); boolean available = randomBoolean(); - when(licenseState.checkFeature(XPackLicenseState.Feature.LOGSTASH)).thenReturn(available); + when(licenseState.isAllowed(XPackLicenseState.Feature.LOGSTASH)).thenReturn(available); assertThat(featureSet.available(), is(available)); var usageAction = newUsageAction(available); From d54ff1adc8bd2567ccfc145397fb73ab0f63bf27 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Thu, 9 Jul 2020 15:40:44 -0700 Subject: [PATCH 05/11] testing conventions... --- x-pack/plugin/core/build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/plugin/core/build.gradle b/x-pack/plugin/core/build.gradle index cba9aa4117c27..051d5c67e7c5e 100644 --- a/x-pack/plugin/core/build.gradle +++ b/x-pack/plugin/core/build.gradle @@ -160,3 +160,5 @@ testClusters.yamlRestTest { user username: "x_pack_rest_user", password: "x-pack-test-password" } +testingConventions.enabled = false + From 057b83b99d8993b7308f5aeed99a594c2a0e3ff4 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Thu, 9 Jul 2020 16:12:20 -0700 Subject: [PATCH 06/11] unit tests --- .../org/elasticsearch/license/XPackLicenseStateTests.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/license/XPackLicenseStateTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/license/XPackLicenseStateTests.java index 3f5e6982bdb6d..dd521ce4d9ba3 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/license/XPackLicenseStateTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/license/XPackLicenseStateTests.java @@ -572,15 +572,15 @@ public void testTransformInactiveBasic() { public void testLastUsed() { Feature basicFeature = Feature.SECURITY; - Feature goldFeature = Feature.SECURITY_IP_FILTERING; + Feature goldFeature = Feature.SECURITY_DLS_FLS; AtomicInteger currentTime = new AtomicInteger(100); // non zero start time XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY, currentTime::get); assertThat("basic features not tracked", licenseState.getLastUsed(), not(hasKey(basicFeature))); - assertThat("initial epoch time", licenseState.getLastUsed(), hasEntry(goldFeature, 0L)); + assertThat("initial epoch time", licenseState.getLastUsed(), not(hasKey(goldFeature))); licenseState.isAllowed(basicFeature); assertThat("basic features still not tracked", licenseState.getLastUsed(), not(hasKey(basicFeature))); licenseState.isAllowed(goldFeature); - assertThat("isAllowed does not track", licenseState.getLastUsed(), hasEntry(goldFeature, 0L)); + assertThat("isAllowed does not track", licenseState.getLastUsed(), not(hasKey(goldFeature))); licenseState.checkFeature(basicFeature); assertThat("basic features still not tracked", licenseState.getLastUsed(), not(hasKey(basicFeature))); licenseState.checkFeature(goldFeature); From 5bcbfb2fc3f5e52563bccf3865d04b643cf28f7d Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Thu, 9 Jul 2020 16:31:06 -0700 Subject: [PATCH 07/11] iter --- .../analytics/action/AnalyticsInfoTransportActionTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportActionTests.java b/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportActionTests.java index 3aeab48c0c7de..12df855e33e2a 100644 --- a/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportActionTests.java +++ b/x-pack/plugin/analytics/src/test/java/org/elasticsearch/xpack/analytics/action/AnalyticsInfoTransportActionTests.java @@ -89,7 +89,7 @@ public void testEnabled() throws Exception { assertThat(featureSet.enabled(), is(true)); assertTrue(featureSet.enabled()); boolean available = randomBoolean(); - when(licenseState.checkFeature(XPackLicenseState.Feature.ANALYTICS)).thenReturn(available); + when(licenseState.isAllowed(XPackLicenseState.Feature.ANALYTICS)).thenReturn(available); Client client = mockClient(); AnalyticsUsageTransportAction usageAction = new AnalyticsUsageTransportAction(mock(TransportService.class), clusterService, null, mock(ActionFilters.class), null, licenseState, client); From c23c2e78bbdb7c8a74d3f0536cfb2529ebaf0b54 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Fri, 10 Jul 2020 12:09:26 -0700 Subject: [PATCH 08/11] tests iter --- .../ml/MachineLearningInfoTransportActionTests.java | 12 ++++++------ .../org/elasticsearch/xpack/security/Security.java | 3 +++ .../xpack/security/SecurityInfoTransportAction.java | 2 +- .../security/SecurityInfoTransportActionTests.java | 8 ++++---- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/MachineLearningInfoTransportActionTests.java b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/MachineLearningInfoTransportActionTests.java index 0f5a2bdbf3b0c..6ac2d9c17a05a 100644 --- a/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/MachineLearningInfoTransportActionTests.java +++ b/x-pack/plugin/ml/src/test/java/org/elasticsearch/xpack/ml/MachineLearningInfoTransportActionTests.java @@ -131,7 +131,7 @@ public void testAvailable() throws Exception { MachineLearningInfoTransportAction featureSet = new MachineLearningInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), commonSettings, licenseState); boolean available = randomBoolean(); - when(licenseState.checkFeature(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(available); + when(licenseState.isAllowed(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(available); assertThat(featureSet.available(), is(available)); var usageAction = newUsageAction(commonSettings); PlainActionFuture future = new PlainActionFuture<>(); @@ -170,7 +170,7 @@ public void testEnabled() throws Exception { } public void testUsage() throws Exception { - when(licenseState.checkFeature(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); + when(licenseState.isAllowed(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); Settings.Builder settings = Settings.builder().put(commonSettings); settings.put("xpack.ml.enabled", true); @@ -328,7 +328,7 @@ public void testUsage() throws Exception { } public void testUsageWithOrphanedTask() throws Exception { - when(licenseState.checkFeature(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); + when(licenseState.isAllowed(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); Settings.Builder settings = Settings.builder().put(commonSettings); settings.put("xpack.ml.enabled", true); @@ -367,7 +367,7 @@ public void testUsageWithOrphanedTask() throws Exception { } public void testUsageDisabledML() throws Exception { - when(licenseState.checkFeature(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); + when(licenseState.isAllowed(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); Settings.Builder settings = Settings.builder().put(commonSettings); settings.put("xpack.ml.enabled", false); @@ -387,7 +387,7 @@ public void testUsageDisabledML() throws Exception { } public void testNodeCount() throws Exception { - when(licenseState.checkFeature(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); + when(licenseState.isAllowed(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); int nodeCount = randomIntBetween(1, 3); ClusterState clusterState = givenNodeCount(nodeCount); Settings.Builder settings = Settings.builder().put(commonSettings); @@ -414,7 +414,7 @@ public void testNodeCount() throws Exception { } public void testUsageGivenMlMetadataNotInstalled() throws Exception { - when(licenseState.checkFeature(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); + when(licenseState.isAllowed(XPackLicenseState.Feature.MACHINE_LEARNING)).thenReturn(true); Settings.Builder settings = Settings.builder().put(commonSettings); settings.put("xpack.ml.enabled", true); when(clusterService.state()).thenReturn(ClusterState.EMPTY_STATE); diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java index 824dea00f5d7a..d48759439a7d2 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java @@ -1040,6 +1040,9 @@ public Function> getFieldFilter() { } IndicesAccessControl indicesAccessControl = threadContext.get().getTransient( AuthorizationServiceField.INDICES_PERMISSIONS_KEY); + if (indicesAccessControl == null) { + return MapperPlugin.NOOP_FIELD_PREDICATE; + } IndicesAccessControl.IndexAccessControl indexPermissions = indicesAccessControl.getIndexPermissions(index); if (indexPermissions == null) { return MapperPlugin.NOOP_FIELD_PREDICATE; diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/SecurityInfoTransportAction.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/SecurityInfoTransportAction.java index 7605191a9d6da..88a2696450b7e 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/SecurityInfoTransportAction.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/SecurityInfoTransportAction.java @@ -34,7 +34,7 @@ public String name() { @Override public boolean available() { - return licenseState.checkFeature(XPackLicenseState.Feature.SECURITY); + return licenseState.isAllowed(XPackLicenseState.Feature.SECURITY); } @Override diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityInfoTransportActionTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityInfoTransportActionTests.java index 3b653b130d0c7..160163dfa5661 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityInfoTransportActionTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityInfoTransportActionTests.java @@ -71,10 +71,10 @@ public void init() throws Exception { public void testAvailable() { SecurityInfoTransportAction featureSet = new SecurityInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), licenseState); - when(licenseState.checkFeature(XPackLicenseState.Feature.SECURITY)).thenReturn(true); + when(licenseState.isAllowed(XPackLicenseState.Feature.SECURITY)).thenReturn(true); assertThat(featureSet.available(), is(true)); - when(licenseState.checkFeature(XPackLicenseState.Feature.SECURITY)).thenReturn(false); + when(licenseState.isAllowed(XPackLicenseState.Feature.SECURITY)).thenReturn(false); assertThat(featureSet.available(), is(false)); } @@ -94,7 +94,7 @@ public void testUsage() throws Exception { final boolean authcAuthzAvailable = randomBoolean(); final boolean explicitlyDisabled = randomBoolean(); final boolean enabled = explicitlyDisabled == false && randomBoolean(); - when(licenseState.checkFeature(XPackLicenseState.Feature.SECURITY)).thenReturn(authcAuthzAvailable); + when(licenseState.isAllowed(XPackLicenseState.Feature.SECURITY)).thenReturn(authcAuthzAvailable); when(licenseState.isSecurityEnabled()).thenReturn(enabled); Settings.Builder settings = Settings.builder().put(this.settings); @@ -248,7 +248,7 @@ public void testUsage() throws Exception { } public void testUsageOnTrialLicenseWithSecurityDisabledByDefault() throws Exception { - when(licenseState.checkFeature(XPackLicenseState.Feature.SECURITY)).thenReturn(true); + when(licenseState.isAllowed(XPackLicenseState.Feature.SECURITY)).thenReturn(true); when(licenseState.isSecurityEnabled()).thenReturn(false); Settings.Builder settings = Settings.builder().put(this.settings); From 70042a7219d03b3efb76b7a001c20861d5a7e7cf Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Mon, 13 Jul 2020 13:35:50 -0700 Subject: [PATCH 09/11] another test --- .../xpack/logstash/LogstashInfoTransportActionTests.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugin/logstash/src/test/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportActionTests.java b/x-pack/plugin/logstash/src/test/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportActionTests.java index 2db83434dceb7..64fef0069cdd9 100644 --- a/x-pack/plugin/logstash/src/test/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportActionTests.java +++ b/x-pack/plugin/logstash/src/test/java/org/elasticsearch/xpack/logstash/LogstashInfoTransportActionTests.java @@ -78,7 +78,7 @@ public void testAvailable() throws Exception { private LogstashUsageTransportAction newUsageAction(boolean available) { XPackLicenseState licenseState = mock(XPackLicenseState.class); - when(licenseState.checkFeature(XPackLicenseState.Feature.LOGSTASH)).thenReturn(available); + when(licenseState.isAllowed(XPackLicenseState.Feature.LOGSTASH)).thenReturn(available); return new LogstashUsageTransportAction(mock(TransportService.class), null, null, mock(ActionFilters.class), null, licenseState); } } From d95a4ea679c38db714143c23915c95faddc82f30 Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Mon, 13 Jul 2020 14:37:16 -0700 Subject: [PATCH 10/11] fix a bunch of missed checkFeature -> isAllowed for telmetry --- .../elasticsearch/xpack/ccr/CCRInfoTransportActionTests.java | 4 ++-- .../org/elasticsearch/xpack/ccr/CCRInfoTransportAction.java | 2 +- .../org/elasticsearch/xpack/eql/EqlInfoTransportAction.java | 2 +- .../elasticsearch/xpack/eql/EqlInfoTransportActionTests.java | 2 +- .../org/elasticsearch/xpack/slm/SLMInfoTransportAction.java | 2 +- .../xpack/monitoring/MonitoringInfoTransportAction.java | 2 +- .../xpack/monitoring/MonitoringInfoTransportActionTests.java | 2 +- .../elasticsearch/xpack/rollup/RollupInfoTransportAction.java | 2 +- .../xpack/rollup/RollupInfoTransportActionTests.java | 2 +- .../xpack/spatial/SpatialInfoTransportAction.java | 2 +- .../xpack/spatial/SpatialInfoTransportActionTests.java | 2 +- .../org/elasticsearch/xpack/sql/SqlInfoTransportAction.java | 2 +- .../elasticsearch/xpack/sql/SqlInfoTransportActionTests.java | 2 +- .../xpack/transform/TransformInfoTransportAction.java | 2 +- .../xpack/transform/TransformInfoTransportActionTests.java | 2 +- .../xpack/vectors/VectorsInfoTransportAction.java | 2 +- .../xpack/vectors/VectorsInfoTransportActionTests.java | 2 +- .../xpack/watcher/WatcherInfoTransportAction.java | 2 +- .../xpack/watcher/WatcherInfoTransportActionTests.java | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/CCRInfoTransportActionTests.java b/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/CCRInfoTransportActionTests.java index 5b591a12dcf8e..373b437177c19 100644 --- a/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/CCRInfoTransportActionTests.java +++ b/x-pack/plugin/ccr/src/test/java/org/elasticsearch/xpack/ccr/CCRInfoTransportActionTests.java @@ -47,10 +47,10 @@ public void testAvailable() { CCRInfoTransportAction featureSet = new CCRInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), Settings.EMPTY, licenseState); - when(licenseState.checkFeature(XPackLicenseState.Feature.CCR)).thenReturn(false); + when(licenseState.isAllowed(XPackLicenseState.Feature.CCR)).thenReturn(false); assertThat(featureSet.available(), equalTo(false)); - when(licenseState.checkFeature(XPackLicenseState.Feature.CCR)).thenReturn(true); + when(licenseState.isAllowed(XPackLicenseState.Feature.CCR)).thenReturn(true); assertThat(featureSet.available(), equalTo(true)); } diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/ccr/CCRInfoTransportAction.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/ccr/CCRInfoTransportAction.java index 74af5eab1386f..4c15544a52d6d 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/ccr/CCRInfoTransportAction.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/ccr/CCRInfoTransportAction.java @@ -43,7 +43,7 @@ public String name() { @Override public boolean available() { - return licenseState.checkFeature(XPackLicenseState.Feature.CCR); + return licenseState.isAllowed(XPackLicenseState.Feature.CCR); } @Override diff --git a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/EqlInfoTransportAction.java b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/EqlInfoTransportAction.java index 50203a13f3e07..7798e91a6f7b4 100644 --- a/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/EqlInfoTransportAction.java +++ b/x-pack/plugin/eql/src/main/java/org/elasticsearch/xpack/eql/EqlInfoTransportAction.java @@ -35,7 +35,7 @@ public String name() { @Override public boolean available() { - return licenseState.checkFeature(XPackLicenseState.Feature.EQL); + return licenseState.isAllowed(XPackLicenseState.Feature.EQL); } @Override diff --git a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/EqlInfoTransportActionTests.java b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/EqlInfoTransportActionTests.java index 73c010e72077b..887af17db768f 100644 --- a/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/EqlInfoTransportActionTests.java +++ b/x-pack/plugin/eql/src/test/java/org/elasticsearch/xpack/eql/EqlInfoTransportActionTests.java @@ -59,7 +59,7 @@ public void testAvailable() { EqlInfoTransportAction featureSet = new EqlInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), Settings.EMPTY, licenseState); boolean available = randomBoolean(); - when(licenseState.checkFeature(XPackLicenseState.Feature.EQL)).thenReturn(available); + when(licenseState.isAllowed(XPackLicenseState.Feature.EQL)).thenReturn(available); assertThat(featureSet.available(), is(available)); } diff --git a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SLMInfoTransportAction.java b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SLMInfoTransportAction.java index 0886c9b345b5a..2ddd01a53cf0a 100644 --- a/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SLMInfoTransportAction.java +++ b/x-pack/plugin/ilm/src/main/java/org/elasticsearch/xpack/slm/SLMInfoTransportAction.java @@ -31,7 +31,7 @@ public String name() { @Override public boolean available() { - return licenseState.checkFeature(XPackLicenseState.Feature.ILM); + return licenseState.isAllowed(XPackLicenseState.Feature.ILM); } @Override diff --git a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportAction.java b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportAction.java index f491d8e9d9f2e..0ef97311de161 100644 --- a/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportAction.java +++ b/x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportAction.java @@ -31,7 +31,7 @@ public String name() { @Override public boolean available() { - return licenseState.checkFeature(XPackLicenseState.Feature.MONITORING); + return licenseState.isAllowed(XPackLicenseState.Feature.MONITORING); } @Override diff --git a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportActionTests.java b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportActionTests.java index 27707717a0e01..1b6b0a50e89d6 100644 --- a/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportActionTests.java +++ b/x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/MonitoringInfoTransportActionTests.java @@ -47,7 +47,7 @@ public void testAvailable() { MonitoringInfoTransportAction featureSet = new MonitoringInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), licenseState); boolean available = randomBoolean(); - when(licenseState.checkFeature(XPackLicenseState.Feature.MONITORING)).thenReturn(available); + when(licenseState.isAllowed(XPackLicenseState.Feature.MONITORING)).thenReturn(available); assertThat(featureSet.available(), is(available)); } diff --git a/x-pack/plugin/rollup/src/main/java/org/elasticsearch/xpack/rollup/RollupInfoTransportAction.java b/x-pack/plugin/rollup/src/main/java/org/elasticsearch/xpack/rollup/RollupInfoTransportAction.java index bc344a04a0d55..5887dfe794af1 100644 --- a/x-pack/plugin/rollup/src/main/java/org/elasticsearch/xpack/rollup/RollupInfoTransportAction.java +++ b/x-pack/plugin/rollup/src/main/java/org/elasticsearch/xpack/rollup/RollupInfoTransportAction.java @@ -31,7 +31,7 @@ public String name() { @Override public boolean available() { - return licenseState.checkFeature(XPackLicenseState.Feature.ROLLUP); + return licenseState.isAllowed(XPackLicenseState.Feature.ROLLUP); } @Override diff --git a/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupInfoTransportActionTests.java b/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupInfoTransportActionTests.java index 233df50c8420a..69dc1fab5e9db 100644 --- a/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupInfoTransportActionTests.java +++ b/x-pack/plugin/rollup/src/test/java/org/elasticsearch/xpack/rollup/RollupInfoTransportActionTests.java @@ -35,7 +35,7 @@ public void testAvailable() { RollupInfoTransportAction featureSet = new RollupInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), licenseState); boolean available = randomBoolean(); - when(licenseState.checkFeature(XPackLicenseState.Feature.ROLLUP)).thenReturn(available); + when(licenseState.isAllowed(XPackLicenseState.Feature.ROLLUP)).thenReturn(available); assertThat(featureSet.available(), is(available)); } diff --git a/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportAction.java b/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportAction.java index b97f7a69089b2..f3fbb31e35b0b 100644 --- a/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportAction.java +++ b/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportAction.java @@ -32,7 +32,7 @@ public String name() { @Override public boolean available() { - return licenseState.checkFeature(XPackLicenseState.Feature.SPATIAL); + return licenseState.isAllowed(XPackLicenseState.Feature.SPATIAL); } @Override diff --git a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportActionTests.java b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportActionTests.java index 98b1a8ff5e72d..dd89a23312464 100644 --- a/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportActionTests.java +++ b/x-pack/plugin/spatial/src/test/java/org/elasticsearch/xpack/spatial/SpatialInfoTransportActionTests.java @@ -34,7 +34,7 @@ public void testAvailable() throws Exception { SpatialInfoTransportAction featureSet = new SpatialInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), Settings.EMPTY, licenseState); boolean available = randomBoolean(); - when(licenseState.checkFeature(XPackLicenseState.Feature.SPATIAL)).thenReturn(available); + when(licenseState.isAllowed(XPackLicenseState.Feature.SPATIAL)).thenReturn(available); assertThat(featureSet.available(), is(available)); var usageAction = new SpatialUsageTransportAction(mock(TransportService.class), null, null, diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/SqlInfoTransportAction.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/SqlInfoTransportAction.java index f848c4fcdd8da..636a9fb694024 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/SqlInfoTransportAction.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/SqlInfoTransportAction.java @@ -31,7 +31,7 @@ public String name() { @Override public boolean available() { - return licenseState.checkFeature(XPackLicenseState.Feature.SQL); + return licenseState.isAllowed(XPackLicenseState.Feature.SQL); } @Override diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/SqlInfoTransportActionTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/SqlInfoTransportActionTests.java index ad35b75b446ba..162ff0d5c964e 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/SqlInfoTransportActionTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/SqlInfoTransportActionTests.java @@ -59,7 +59,7 @@ public void testAvailable() { SqlInfoTransportAction featureSet = new SqlInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), licenseState); boolean available = randomBoolean(); - when(licenseState.checkFeature(XPackLicenseState.Feature.SQL)).thenReturn(available); + when(licenseState.isAllowed(XPackLicenseState.Feature.SQL)).thenReturn(available); assertThat(featureSet.available(), is(available)); } diff --git a/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/TransformInfoTransportAction.java b/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/TransformInfoTransportAction.java index f2ffb83011d63..a72ba93721119 100644 --- a/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/TransformInfoTransportAction.java +++ b/x-pack/plugin/transform/src/main/java/org/elasticsearch/xpack/transform/TransformInfoTransportAction.java @@ -75,7 +75,7 @@ public String name() { @Override public boolean available() { - return licenseState.checkFeature(XPackLicenseState.Feature.TRANSFORM); + return licenseState.isAllowed(XPackLicenseState.Feature.TRANSFORM); } @Override diff --git a/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/TransformInfoTransportActionTests.java b/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/TransformInfoTransportActionTests.java index 39c20f68ea8ff..1751e2f7334b8 100644 --- a/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/TransformInfoTransportActionTests.java +++ b/x-pack/plugin/transform/src/test/java/org/elasticsearch/xpack/transform/TransformInfoTransportActionTests.java @@ -42,7 +42,7 @@ public void testAvailable() { licenseState ); boolean available = randomBoolean(); - when(licenseState.checkFeature(XPackLicenseState.Feature.TRANSFORM)).thenReturn(available); + when(licenseState.isAllowed(XPackLicenseState.Feature.TRANSFORM)).thenReturn(available); assertThat(featureSet.available(), is(available)); } diff --git a/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportAction.java b/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportAction.java index 50dbcf54520bd..065c7c3fc493a 100644 --- a/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportAction.java +++ b/x-pack/plugin/vectors/src/main/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportAction.java @@ -31,7 +31,7 @@ public String name() { @Override public boolean available() { - return licenseState.checkFeature(XPackLicenseState.Feature.VECTORS); + return licenseState.isAllowed(XPackLicenseState.Feature.VECTORS); } @Override diff --git a/x-pack/plugin/vectors/src/test/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportActionTests.java b/x-pack/plugin/vectors/src/test/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportActionTests.java index 0582b5fa81863..0d4154c8151dc 100644 --- a/x-pack/plugin/vectors/src/test/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportActionTests.java +++ b/x-pack/plugin/vectors/src/test/java/org/elasticsearch/xpack/vectors/VectorsInfoTransportActionTests.java @@ -33,7 +33,7 @@ public void testAvailable() throws Exception { VectorsInfoTransportAction featureSet = new VectorsInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), licenseState); boolean available = randomBoolean(); - when(licenseState.checkFeature(XPackLicenseState.Feature.VECTORS)).thenReturn(available); + when(licenseState.isAllowed(XPackLicenseState.Feature.VECTORS)).thenReturn(available); assertThat(featureSet.available(), is(available)); var usageAction = new VectorsUsageTransportAction(mock(TransportService.class), null, null, diff --git a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportAction.java b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportAction.java index e28103cd5b226..13c43b79a5354 100644 --- a/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportAction.java +++ b/x-pack/plugin/watcher/src/main/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportAction.java @@ -35,7 +35,7 @@ public String name() { @Override public boolean available() { - return licenseState.checkFeature(XPackLicenseState.Feature.WATCHER); + return licenseState.isAllowed(XPackLicenseState.Feature.WATCHER); } @Override diff --git a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportActionTests.java b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportActionTests.java index 3a3dc25b45c14..5e5f47416695e 100644 --- a/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportActionTests.java +++ b/x-pack/plugin/watcher/src/test/java/org/elasticsearch/xpack/watcher/WatcherInfoTransportActionTests.java @@ -68,7 +68,7 @@ public void testAvailable() { WatcherInfoTransportAction featureSet = new WatcherInfoTransportAction( mock(TransportService.class), mock(ActionFilters.class), Settings.EMPTY, licenseState); boolean available = randomBoolean(); - when(licenseState.checkFeature(XPackLicenseState.Feature.WATCHER)).thenReturn(available); + when(licenseState.isAllowed(XPackLicenseState.Feature.WATCHER)).thenReturn(available); assertThat(featureSet.available(), is(available)); } From 228d882756b3234795b651429dd97608433a09cd Mon Sep 17 00:00:00 2001 From: Ryan Ernst Date: Tue, 14 Jul 2020 10:07:08 -0700 Subject: [PATCH 11/11] address more feedback --- .../authz/interceptor/IndicesAliasesRequestInterceptor.java | 2 +- .../security/authz/interceptor/ResizeRequestInterceptor.java | 2 +- .../cluster/coordination/VotingOnlyNodeFeatureSet.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptor.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptor.java index 2f47326dd9167..57333493340cc 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptor.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/IndicesAliasesRequestInterceptor.java @@ -53,7 +53,7 @@ public void intercept(RequestInfo requestInfo, AuthorizationEngine authorization final XPackLicenseState frozenLicenseState = licenseState.copyCurrentLicenseState(); final AuditTrail auditTrail = auditTrailService.get(); if (frozenLicenseState.isSecurityEnabled()) { - var licenseChecker = new MemoizedSupplier<>(() -> licenseState.checkFeature(Feature.SECURITY_DLS_FLS)); + var licenseChecker = new MemoizedSupplier<>(() -> frozenLicenseState.checkFeature(Feature.SECURITY_DLS_FLS)); IndicesAccessControl indicesAccessControl = threadContext.getTransient(AuthorizationServiceField.INDICES_PERMISSIONS_KEY); for (IndicesAliasesRequest.AliasActions aliasAction : request.getAliasActions()) { diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/ResizeRequestInterceptor.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/ResizeRequestInterceptor.java index 9c41a4e075de0..4d6e6161ba027 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/ResizeRequestInterceptor.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/interceptor/ResizeRequestInterceptor.java @@ -49,7 +49,7 @@ public void intercept(RequestInfo requestInfo, AuthorizationEngine authorization final XPackLicenseState frozenLicenseState = licenseState.copyCurrentLicenseState(); final AuditTrail auditTrail = auditTrailService.get(); if (frozenLicenseState.isSecurityEnabled()) { - var licenseChecker = new MemoizedSupplier<>(() -> licenseState.checkFeature(Feature.SECURITY_DLS_FLS)); + var licenseChecker = new MemoizedSupplier<>(() -> frozenLicenseState.checkFeature(Feature.SECURITY_DLS_FLS)); IndicesAccessControl indicesAccessControl = threadContext.getTransient(AuthorizationServiceField.INDICES_PERMISSIONS_KEY); IndicesAccessControl.IndexAccessControl indexAccessControl = diff --git a/x-pack/plugin/voting-only-node/src/main/java/org/elasticsearch/cluster/coordination/VotingOnlyNodeFeatureSet.java b/x-pack/plugin/voting-only-node/src/main/java/org/elasticsearch/cluster/coordination/VotingOnlyNodeFeatureSet.java index 793ec0720c276..8af952f54aa9c 100644 --- a/x-pack/plugin/voting-only-node/src/main/java/org/elasticsearch/cluster/coordination/VotingOnlyNodeFeatureSet.java +++ b/x-pack/plugin/voting-only-node/src/main/java/org/elasticsearch/cluster/coordination/VotingOnlyNodeFeatureSet.java @@ -43,7 +43,7 @@ public String name() { @Override public boolean available() { - return licenseState != null && licenseState.checkFeature(Feature.VOTING_ONLY); + return licenseState != null && licenseState.isAllowed(Feature.VOTING_ONLY); } @Override @@ -92,7 +92,7 @@ protected String name() { @Override protected boolean available() { - return licenseState.checkFeature(Feature.VOTING_ONLY); + return licenseState.isAllowed(Feature.VOTING_ONLY); } @Override