Skip to content

Commit

Permalink
Enable Universal Profiling as Enterprise feature (#100333)
Browse files Browse the repository at this point in the history
With this commit we ensure that Universal Profiling can only be used
with an Enterprise license.
  • Loading branch information
danielmitterdorfer committed Oct 9, 2023
1 parent db4f92f commit dfaec0d
Show file tree
Hide file tree
Showing 18 changed files with 310 additions and 10 deletions.
5 changes: 5 additions & 0 deletions docs/changelog/100333.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 100333
summary: Enable Universal Profiling as Enterprise feature
area: Application
type: enhancement
issues: []
4 changes: 4 additions & 0 deletions docs/reference/rest-api/info.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ Example response:
"enterprise_search": {
"available": true,
"enabled": true
},
"universal_profiling": {
"available": true,
"enabled": true
}
},
"tagline" : "You know, for X"
Expand Down
4 changes: 4 additions & 0 deletions docs/reference/rest-api/usage.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,10 @@ GET /_xpack/usage
"min_rule_count": 0,
"max_rule_count": 0
}
},
"universal_profiling" : {
"available" : true,
"enabled" : true
}
}
------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions server/src/main/java/org/elasticsearch/TransportVersions.java
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ static TransportVersion def(int id) {
public static final TransportVersion NESTED_KNN_VECTOR_QUERY_V = def(8_511_00_0);
public static final TransportVersion ML_PACKAGE_LOADER_PLATFORM_ADDED = def(8_512_00_0);
public static final TransportVersion PLUGIN_DESCRIPTOR_OPTIONAL_CLASSNAME = def(8_513_00_0);
public static final TransportVersion UNIVERSAL_PROFILING_LICENSE_ADDED = def(8_514_00_0);

/*
* STOP! READ THIS FIRST! No, really,
* ____ _____ ___ ____ _ ____ _____ _ ____ _____ _ _ ___ ____ _____ ___ ____ ____ _____ _
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.elasticsearch.xpack.core.aggregatemetric.AggregateMetricFeatureSetUsage;
import org.elasticsearch.xpack.core.analytics.AnalyticsFeatureSetUsage;
import org.elasticsearch.xpack.core.application.EnterpriseSearchFeatureSetUsage;
import org.elasticsearch.xpack.core.application.ProfilingUsage;
import org.elasticsearch.xpack.core.archive.ArchiveFeatureSetUsage;
import org.elasticsearch.xpack.core.ccr.AutoFollowMetadata;
import org.elasticsearch.xpack.core.datastreams.DataStreamFeatureSetUsage;
Expand Down Expand Up @@ -277,7 +278,8 @@ public List<NamedWriteableRegistry.Entry> getNamedWriteables() {
XPackFeatureSet.Usage.class,
XPackField.ENTERPRISE_SEARCH,
EnterpriseSearchFeatureSetUsage::new
)
),
new NamedWriteableRegistry.Entry(XPackFeatureSet.Usage.class, XPackField.UNIVERSAL_PROFILING, ProfilingUsage::new)
).filter(Objects::nonNull).toList();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ public final class XPackField {

/** Name constant for the redact processor feature. */
public static final String REDACT_PROCESSOR = "redact_processor";
/* Name for Universal Profiling. */
public static final String UNIVERSAL_PROFILING = "universal_profiling";

private XPackField() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public class XPackInfoFeatureAction extends ActionType<XPackInfoFeatureResponse>
public static final XPackInfoFeatureAction AGGREGATE_METRIC = new XPackInfoFeatureAction(XPackField.AGGREGATE_METRIC);
public static final XPackInfoFeatureAction ARCHIVE = new XPackInfoFeatureAction(XPackField.ARCHIVE);
public static final XPackInfoFeatureAction ENTERPRISE_SEARCH = new XPackInfoFeatureAction(XPackField.ENTERPRISE_SEARCH);
public static final XPackInfoFeatureAction UNIVERSAL_PROFILING = new XPackInfoFeatureAction(XPackField.UNIVERSAL_PROFILING);

public static final List<XPackInfoFeatureAction> ALL;
static {
Expand Down Expand Up @@ -80,7 +81,8 @@ public class XPackInfoFeatureAction extends ActionType<XPackInfoFeatureResponse>
DATA_TIERS,
AGGREGATE_METRIC,
ARCHIVE,
ENTERPRISE_SEARCH
ENTERPRISE_SEARCH,
UNIVERSAL_PROFILING
)
);
ALL = Collections.unmodifiableList(actions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public class XPackUsageFeatureAction extends ActionType<XPackUsageFeatureRespons
public static final XPackUsageFeatureAction HEALTH = new XPackUsageFeatureAction(XPackField.HEALTH_API);
public static final XPackUsageFeatureAction REMOTE_CLUSTERS = new XPackUsageFeatureAction(XPackField.REMOTE_CLUSTERS);
public static final XPackUsageFeatureAction ENTERPRISE_SEARCH = new XPackUsageFeatureAction(XPackField.ENTERPRISE_SEARCH);
public static final XPackUsageFeatureAction UNIVERSAL_PROFILING = new XPackUsageFeatureAction(XPackField.UNIVERSAL_PROFILING);

static final List<XPackUsageFeatureAction> ALL = List.of(
AGGREGATE_METRIC,
Expand Down Expand Up @@ -78,7 +79,8 @@ public class XPackUsageFeatureAction extends ActionType<XPackUsageFeatureRespons
ARCHIVE,
HEALTH,
REMOTE_CLUSTERS,
ENTERPRISE_SEARCH
ENTERPRISE_SEARCH,
UNIVERSAL_PROFILING
);

// public for testing
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.core.application;

import org.elasticsearch.TransportVersion;
import org.elasticsearch.TransportVersions;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.xpack.core.XPackFeatureSet;
import org.elasticsearch.xpack.core.XPackField;

import java.io.IOException;

public class ProfilingUsage extends XPackFeatureSet.Usage {
public ProfilingUsage(StreamInput input) throws IOException {
super(input);
}

public ProfilingUsage(boolean available, boolean enabled) {
super(XPackField.UNIVERSAL_PROFILING, available, enabled);
}

@Override
public TransportVersion getMinimalSupportedVersion() {
return TransportVersions.UNIVERSAL_PROFILING_LICENSE_ADDED;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.profiling;

import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.xpack.core.LocalStateCompositeXPackPlugin;

import java.nio.file.Path;

public class LocalStateProfilingXPackPlugin extends LocalStateCompositeXPackPlugin {
public LocalStateProfilingXPackPlugin(final Settings settings, final Path configPath) {
super(settings, configPath);
plugins.add(new ProfilingPlugin(settings) {
@Override
protected ProfilingLicenseChecker createLicenseChecker() {
return new ProfilingLicenseChecker(LocalStateProfilingXPackPlugin.this::getLicenseState);
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
import org.elasticsearch.common.network.NetworkModule;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.datastreams.DataStreamsPlugin;
import org.elasticsearch.license.LicenseSettings;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.transport.netty4.Netty4Plugin;
import org.elasticsearch.xpack.core.LocalStateCompositeXPackPlugin;
import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.ilm.LifecycleSettings;
import org.elasticsearch.xpack.ilm.IndexLifecycle;
Expand All @@ -37,9 +37,8 @@ public abstract class ProfilingTestCase extends ESIntegTestCase {
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return List.of(
LocalStateCompositeXPackPlugin.class,
DataStreamsPlugin.class,
ProfilingPlugin.class,
LocalStateProfilingXPackPlugin.class,
IndexLifecycle.class,
UnsignedLongMapperPlugin.class,
VersionFieldPlugin.class,
Expand All @@ -58,6 +57,7 @@ protected Settings nodeSettings(int nodeOrdinal, Settings otherSettings) {
// .put(LicenseSettings.SELF_GENERATED_LICENSE_TYPE.getKey(), "trial")
// Disable ILM history index so that the tests don't have to clean it up
.put(LifecycleSettings.LIFECYCLE_HISTORY_INDEX_ENABLED_SETTING.getKey(), false)
.put(LicenseSettings.SELF_GENERATED_LICENSE_TYPE.getKey(), "trial")
.build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.profiling;

import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.xpack.core.XPackField;
import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.action.XPackInfoFeatureAction;
import org.elasticsearch.xpack.core.action.XPackInfoFeatureTransportAction;

public class ProfilingInfoTransportAction extends XPackInfoFeatureTransportAction {
private final boolean enabled;
private final ProfilingLicenseChecker licenseChecker;

@Inject
public ProfilingInfoTransportAction(
TransportService transportService,
ActionFilters actionFilters,
Settings settings,
ProfilingLicenseChecker licenseChecker
) {
super(XPackInfoFeatureAction.UNIVERSAL_PROFILING.name(), transportService, actionFilters);
this.enabled = XPackSettings.PROFILING_ENABLED.get(settings);
this.licenseChecker = licenseChecker;
}

@Override
public String name() {
return XPackField.UNIVERSAL_PROFILING;
}

@Override
public boolean available() {
return licenseChecker.isSupportedLicense();
}

@Override
public boolean enabled() {
return enabled;
}
}
Original file line number Diff line number Diff line change
@@ -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
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.profiling;

import org.elasticsearch.license.License;
import org.elasticsearch.license.LicenseUtils;
import org.elasticsearch.license.LicensedFeature;
import org.elasticsearch.license.XPackLicenseState;

import java.util.function.Supplier;

public final class ProfilingLicenseChecker {
private static final LicensedFeature.Momentary UNIVERSAL_PROFILING_FEATURE = LicensedFeature.momentary(
null,
"universal_profiling",
License.OperationMode.ENTERPRISE
);

private final Supplier<XPackLicenseState> licenseStateResolver;

public ProfilingLicenseChecker(Supplier<XPackLicenseState> licenseStateResolver) {
this.licenseStateResolver = licenseStateResolver;
}

public boolean isSupportedLicense() {
return UNIVERSAL_PROFILING_FEATURE.checkWithoutTracking(licenseStateResolver.get());
}

public void requireSupportedLicense() {
if (UNIVERSAL_PROFILING_FEATURE.check(licenseStateResolver.get()) == false) {
throw LicenseUtils.newComplianceException(UNIVERSAL_PROFILING_FEATURE.getName());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.watcher.ResourceWatcherService;
import org.elasticsearch.xcontent.NamedXContentRegistry;
import org.elasticsearch.xpack.core.XPackPlugin;
import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.action.XPackInfoFeatureAction;
import org.elasticsearch.xpack.core.action.XPackUsageFeatureAction;

import java.util.ArrayList;
import java.util.Collection;
Expand Down Expand Up @@ -108,10 +111,12 @@ public Collection<Object> createComponents(
registry.get().initialize();
indexManager.get().initialize();
dataStreamManager.get().initialize();
return List.of(registry.get(), indexManager.get(), dataStreamManager.get());
} else {
return Collections.emptyList();
}
return Collections.singletonList(createLicenseChecker());
}

protected ProfilingLicenseChecker createLicenseChecker() {
return new ProfilingLicenseChecker(XPackPlugin::getSharedLicenseState);
}

public void updateCheckOutdatedIndices(boolean newValue) {
Expand Down Expand Up @@ -179,7 +184,9 @@ public static ExecutorBuilder<?> responseExecutorBuilder() {
return List.of(
new ActionHandler<>(GetStackTracesAction.INSTANCE, TransportGetStackTracesAction.class),
new ActionHandler<>(GetFlamegraphAction.INSTANCE, TransportGetFlamegraphAction.class),
new ActionHandler<>(GetStatusAction.INSTANCE, TransportGetStatusAction.class)
new ActionHandler<>(GetStatusAction.INSTANCE, TransportGetStatusAction.class),
new ActionHandler<>(XPackUsageFeatureAction.UNIVERSAL_PROFILING, ProfilingUsageTransportAction.class),
new ActionHandler<>(XPackInfoFeatureAction.UNIVERSAL_PROFILING, ProfilingInfoTransportAction.class)
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.profiling;

import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.support.ActionFilters;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.protocol.xpack.XPackUsageRequest;
import org.elasticsearch.tasks.Task;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.action.XPackUsageFeatureAction;
import org.elasticsearch.xpack.core.action.XPackUsageFeatureResponse;
import org.elasticsearch.xpack.core.action.XPackUsageFeatureTransportAction;
import org.elasticsearch.xpack.core.application.ProfilingUsage;

public class ProfilingUsageTransportAction extends XPackUsageFeatureTransportAction {
private final ProfilingLicenseChecker licenseChecker;

private final boolean enabled;

@Inject
public ProfilingUsageTransportAction(
TransportService transportService,
ClusterService clusterService,
ThreadPool threadPool,
ActionFilters actionFilters,
IndexNameExpressionResolver indexNameExpressionResolver,
ProfilingLicenseChecker licenseChecker,
Settings settings
) {
super(
XPackUsageFeatureAction.UNIVERSAL_PROFILING.name(),
transportService,
clusterService,
threadPool,
actionFilters,
indexNameExpressionResolver
);
this.licenseChecker = licenseChecker;
this.enabled = XPackSettings.PROFILING_ENABLED.get(settings);
}

@Override
protected void masterOperation(
Task task,
XPackUsageRequest request,
ClusterState state,
ActionListener<XPackUsageFeatureResponse> listener
) {
ProfilingUsage profilingUsage = new ProfilingUsage(licenseChecker.isSupportedLicense(), enabled);
listener.onResponse(new XPackUsageFeatureResponse(profilingUsage));
}
}
Loading

0 comments on commit dfaec0d

Please sign in to comment.