Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ public class XPackLicenseState {
messages.put(XPackField.LOGSTASH, new String[] {
"Logstash will continue to poll centrally-managed pipelines"
});
messages.put(XPackField.BEATS, new String[] {
"Beats will continue to poll centrally-managed configuration"
});
messages.put(XPackField.DEPRECATION, new String[] {
"Deprecation APIs are disabled"
});
Expand Down Expand Up @@ -84,6 +87,7 @@ public class XPackLicenseState {
messages.put(XPackField.GRAPH, XPackLicenseState::graphAcknowledgementMessages);
messages.put(XPackField.MACHINE_LEARNING, XPackLicenseState::machineLearningAcknowledgementMessages);
messages.put(XPackField.LOGSTASH, XPackLicenseState::logstashAcknowledgementMessages);
messages.put(XPackField.BEATS, XPackLicenseState::beatsAcknowledgementMessages);
messages.put(XPackField.SQL, XPackLicenseState::sqlAcknowledgementMessages);
ACKNOWLEDGMENT_MESSAGES = Collections.unmodifiableMap(messages);
}
Expand Down Expand Up @@ -208,12 +212,19 @@ private static String[] machineLearningAcknowledgementMessages(OperationMode cur
private static String[] logstashAcknowledgementMessages(OperationMode currentMode, OperationMode newMode) {
switch (newMode) {
case BASIC:
switch (currentMode) {
case TRIAL:
case STANDARD:
case GOLD:
case PLATINUM:
return new String[] { "Logstash will no longer poll for centrally-managed pipelines" };
if (isBasic(currentMode) == false) {
return new String[] { "Logstash will no longer poll for centrally-managed pipelines" };
}
break;
}
return Strings.EMPTY_ARRAY;
}

private static String[] beatsAcknowledgementMessages(OperationMode currentMode, OperationMode newMode) {
switch (newMode) {
case BASIC:
if (isBasic(currentMode) == false) {
return new String[] { "Beats will no longer be able to use centrally-managed configuration" };
}
break;
}
Expand All @@ -235,6 +246,10 @@ private static String[] sqlAcknowledgementMessages(OperationMode currentMode, Op
return Strings.EMPTY_ARRAY;
}

private static boolean isBasic(OperationMode mode) {
return mode == OperationMode.BASIC;
}

/** A wrapper for the license mode and state, to allow atomically swapping. */
private static class Status {

Expand Down Expand Up @@ -555,20 +570,17 @@ public synchronized boolean isRollupAllowed() {
*/
public synchronized boolean isLogstashAllowed() {
Status localStatus = status;
return localStatus.active && (isBasic(localStatus.mode) == false);
}

if (localStatus.active == false) {
return false;
}
/**
* Beats is allowed as long as there is an active license of type TRIAL, STANDARD, GOLD or PLATINUM
* @return {@code true} as long as there is a valid license
*/
public boolean isBeatsAllowed() {
Status localStatus = status;
return localStatus.active && (isBasic(localStatus.mode) == false);

switch (localStatus.mode) {
case TRIAL:
case GOLD:
case PLATINUM:
case STANDARD:
return true;
default:
return false;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.elasticsearch.xpack.core.graph.GraphFeatureSetUsage;
import org.elasticsearch.xpack.core.graph.action.GraphExploreAction;
import org.elasticsearch.xpack.core.logstash.LogstashFeatureSetUsage;
import org.elasticsearch.xpack.core.beats.BeatsFeatureSetUsage;
import org.elasticsearch.xpack.core.ml.MachineLearningFeatureSetUsage;
import org.elasticsearch.xpack.core.ml.MlMetadata;
import org.elasticsearch.xpack.core.ml.action.CloseJobAction;
Expand Down Expand Up @@ -327,6 +328,8 @@ public List<NamedWriteableRegistry.Entry> getNamedWriteables() {
new NamedWriteableRegistry.Entry(XPackFeatureSet.Usage.class, XPackField.GRAPH, GraphFeatureSetUsage::new),
// logstash
new NamedWriteableRegistry.Entry(XPackFeatureSet.Usage.class, XPackField.LOGSTASH, LogstashFeatureSetUsage::new),
// beats
new NamedWriteableRegistry.Entry(XPackFeatureSet.Usage.class, XPackField.BEATS, BeatsFeatureSetUsage::new),
// ML - Custom metadata
new NamedWriteableRegistry.Entry(MetaData.Custom.class, "ml", MlMetadata::new),
new NamedWriteableRegistry.Entry(NamedDiff.class, "ml", MlMetadata.MlMetadataDiff::new),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public final class XPackField {
public static final String MACHINE_LEARNING = "ml";
/** Name constant for the Logstash feature. */
public static final String LOGSTASH = "logstash";
/** Name constant for the Beats feature. */
public static final String BEATS = "beats";
/** Name constant for the Deprecation API feature. */
public static final String DEPRECATION = "deprecation";
/** Name constant for the upgrade feature. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ private XPackSettings() {
public static final Setting<Boolean> LOGSTASH_ENABLED = Setting.boolSetting("xpack.logstash.enabled", true,
Setting.Property.NodeScope);

/** Setting for enabling or disabling Beats extensions. Defaults to true. */
public static final Setting<Boolean> BEATS_ENABLED = Setting.boolSetting("xpack.beats.enabled", true,
Setting.Property.NodeScope);

/** Setting for enabling or disabling TLS. Defaults to false. */
public static final Setting<Boolean> TRANSPORT_SSL_ENABLED = Setting.boolSetting("xpack.security.transport.ssl.enabled", false,
Property.NodeScope);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.core.beats;

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

import java.io.IOException;

public final class BeatsFeatureSetUsage extends XPackFeatureSet.Usage {

public BeatsFeatureSetUsage(StreamInput in) throws IOException {
super(in);
}

public BeatsFeatureSetUsage(boolean available, boolean enabled) {
super(XPackField.BEATS, available, enabled);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,21 @@ private static Map<String, RoleDescriptor> initializeReservedRoles() {
new RoleDescriptor.IndicesPrivileges[] {
RoleDescriptor.IndicesPrivileges.builder().indices(".kibana*", ".reporting-*").privileges("all").build(),
RoleDescriptor.IndicesPrivileges.builder()
.indices(".monitoring-*").privileges("read", "read_cross_cluster").build()
.indices(".monitoring-*").privileges("read", "read_cross_cluster").build(),
RoleDescriptor.IndicesPrivileges.builder()
.indices(".management-beats").privileges("create_index", "read", "write").build()
},
null,
new ConditionalClusterPrivilege[] { new ManageApplicationPrivileges(Collections.singleton("kibana-*")) },
null, MetadataUtils.DEFAULT_RESERVED_METADATA, null))
.put("logstash_system", new RoleDescriptor("logstash_system", new String[] { "monitor", MonitoringBulkAction.NAME},
null, null, MetadataUtils.DEFAULT_RESERVED_METADATA))
.put("beats_admin", new RoleDescriptor("beats_admin",
null,
new RoleDescriptor.IndicesPrivileges[] {
RoleDescriptor.IndicesPrivileges.builder().indices(".management-beats").privileges("all").build()
},
null, MetadataUtils.DEFAULT_RESERVED_METADATA))
.put(UsernamesField.BEATS_ROLE, new RoleDescriptor(UsernamesField.BEATS_ROLE,
new String[] { "monitor", MonitoringBulkAction.NAME}, null, null, MetadataUtils.DEFAULT_RESERVED_METADATA))
.put(UsernamesField.APM_ROLE, new RoleDescriptor(UsernamesField.APM_ROLE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ public void testIsReserved() {
assertThat(ReservedRolesStore.isReserved("watcher_user"), is(true));
assertThat(ReservedRolesStore.isReserved("watcher_admin"), is(true));
assertThat(ReservedRolesStore.isReserved("kibana_dashboard_only_user"), is(true));
assertThat(ReservedRolesStore.isReserved("beats_admin"), is(true));
assertThat(ReservedRolesStore.isReserved(XPackUser.ROLE_NAME), is(true));
assertThat(ReservedRolesStore.isReserved(LogstashSystemUser.ROLE_NAME), is(true));
assertThat(ReservedRolesStore.isReserved(BeatsSystemUser.ROLE_NAME), is(true));
Expand Down Expand Up @@ -259,6 +260,20 @@ public void testKibanaSystemRole() {
assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(index), is(true));
assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(index), is(true));
});

// Beats management index
final String index = ".management-beats";
assertThat(kibanaRole.indices().allowedIndicesMatcher("indices:foo").test(index), is(false));
assertThat(kibanaRole.indices().allowedIndicesMatcher("indices:bar").test(index), is(false));
assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(index), is(false));
assertThat(kibanaRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(index), is(true));
assertThat(kibanaRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(index), is(true));
assertThat(kibanaRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(true));
assertThat(kibanaRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(index), is(false));
assertThat(kibanaRole.indices().allowedIndicesMatcher(SearchAction.NAME).test(index), is(true));
assertThat(kibanaRole.indices().allowedIndicesMatcher(MultiSearchAction.NAME).test(index), is(true));
assertThat(kibanaRole.indices().allowedIndicesMatcher(GetAction.NAME).test(index), is(true));
assertThat(kibanaRole.indices().allowedIndicesMatcher(READ_CROSS_CLUSTER_NAME).test(index), is(false));
}

public void testKibanaUserRole() {
Expand Down Expand Up @@ -555,6 +570,41 @@ public void testLogstashSystemRole() {
is(false));
}

public void testBeatsAdminRole() {
final TransportRequest request = mock(TransportRequest.class);

final RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("beats_admin");
assertNotNull(roleDescriptor);
assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true));

final Role beatsAdminRole = Role.builder(roleDescriptor, null).build();
assertThat(beatsAdminRole.cluster().check(ClusterHealthAction.NAME, request), is(false));
assertThat(beatsAdminRole.cluster().check(ClusterStateAction.NAME, request), is(false));
assertThat(beatsAdminRole.cluster().check(ClusterStatsAction.NAME, request), is(false));
assertThat(beatsAdminRole.cluster().check(PutIndexTemplateAction.NAME, request), is(false));
assertThat(beatsAdminRole.cluster().check(ClusterRerouteAction.NAME, request), is(false));
assertThat(beatsAdminRole.cluster().check(ClusterUpdateSettingsAction.NAME, request), is(false));
assertThat(beatsAdminRole.cluster().check(MonitoringBulkAction.NAME, request), is(false));

assertThat(beatsAdminRole.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false));

assertThat(beatsAdminRole.indices().allowedIndicesMatcher("indices:foo").test(randomAlphaOfLengthBetween(8, 24)),
is(false));

final String index = ".management-beats";
logger.info("index name [{}]", index);
assertThat(beatsAdminRole.indices().allowedIndicesMatcher("indices:foo").test(index), is(true));
assertThat(beatsAdminRole.indices().allowedIndicesMatcher("indices:bar").test(index), is(true));
assertThat(beatsAdminRole.indices().allowedIndicesMatcher(DeleteIndexAction.NAME).test(index), is(true));
assertThat(beatsAdminRole.indices().allowedIndicesMatcher(CreateIndexAction.NAME).test(index), is(true));
assertThat(beatsAdminRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(index), is(true));
assertThat(beatsAdminRole.indices().allowedIndicesMatcher(DeleteAction.NAME).test(index), is(true));
assertThat(beatsAdminRole.indices().allowedIndicesMatcher(UpdateSettingsAction.NAME).test(index), is(true));
assertThat(beatsAdminRole.indices().allowedIndicesMatcher(SearchAction.NAME).test(index), is(true));
assertThat(beatsAdminRole.indices().allowedIndicesMatcher(MultiSearchAction.NAME).test(index), is(true));
assertThat(beatsAdminRole.indices().allowedIndicesMatcher(GetAction.NAME).test(index), is(true));
}

public void testBeatsSystemRole() {
final TransportRequest request = mock(TransportRequest.class);

Expand Down