[Monitoring] Add Data to Warn on lack of Transport TLS (elastic/x-pack-elasticsearch#2820)

This adds the data necessary to add a warning to the alerts UI representing each cluster when xpack.security.transport.tls.enabled is not set to true for a trial licensed cluster running with
xpack.security.enabled.

Original commit: elastic/x-pack-elasticsearch@28fe8bad76
This commit is contained in:
Chris Earle 2017-11-02 15:26:04 +00:00 committed by GitHub
parent 2bc0d8698d
commit 2acd0afdd5
5 changed files with 72 additions and 8 deletions

View File

@ -30,6 +30,9 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static org.elasticsearch.xpack.XPackSettings.SECURITY_ENABLED;
import static org.elasticsearch.xpack.XPackSettings.TRANSPORT_SSL_ENABLED;
/**
* Collector for cluster stats.
* <p>
@ -80,11 +83,15 @@ public class ClusterStatsCollector extends Collector {
final ClusterState clusterState = clusterService.state();
final License license = licenseService.getLicense();
final List<XPackFeatureSet.Usage> usage = collect(usageSupplier);
// if they have any other type of license, then they are either okay or already know
final boolean clusterNeedsTLSEnabled = license.operationMode() == License.OperationMode.TRIAL &&
SECURITY_ENABLED.get(settings) &&
TRANSPORT_SSL_ENABLED.get(settings) == false;
// Adds a cluster stats document
return Collections.singleton(
new ClusterStatsMonitoringDoc(clusterUUID(), timestamp(), interval, node, clusterName, version, clusterStats.getStatus(),
license, usage, clusterStats, clusterState));
license, usage, clusterStats, clusterState, clusterNeedsTLSEnabled));
}
@Nullable

View File

@ -55,6 +55,7 @@ public class ClusterStatsMonitoringDoc extends MonitoringDoc {
private final ClusterStatsResponse clusterStats;
private final ClusterState clusterState;
private final ClusterHealthStatus status;
private final boolean clusterNeedsTLSEnabled;
ClusterStatsMonitoringDoc(final String cluster,
final long timestamp,
@ -66,7 +67,8 @@ public class ClusterStatsMonitoringDoc extends MonitoringDoc {
@Nullable final License license,
@Nullable final List<XPackFeatureSet.Usage> usages,
@Nullable final ClusterStatsResponse clusterStats,
@Nullable final ClusterState clusterState) {
@Nullable final ClusterState clusterState,
final boolean clusterNeedsTLSEnabled) {
super(cluster, timestamp, intervalMillis, node, MonitoredSystem.ES, TYPE, null);
this.clusterName = Objects.requireNonNull(clusterName);
@ -76,6 +78,7 @@ public class ClusterStatsMonitoringDoc extends MonitoringDoc {
this.usages = usages;
this.clusterStats = clusterStats;
this.clusterState = clusterState;
this.clusterNeedsTLSEnabled = clusterNeedsTLSEnabled;
}
String getClusterName() {
@ -106,6 +109,10 @@ public class ClusterStatsMonitoringDoc extends MonitoringDoc {
return status;
}
boolean getClusterNeedsTLSEnabled() {
return clusterNeedsTLSEnabled;
}
@Override
protected void innerToXContent(XContentBuilder builder, Params params) throws IOException {
builder.field("cluster_name", clusterName);
@ -119,6 +126,9 @@ public class ClusterStatsMonitoringDoc extends MonitoringDoc {
params = new ToXContent.DelegatingMapParams(extraParams, params);
license.toInnerXContent(builder, params);
builder.field("hkey", hash(license, getCluster()));
if (clusterNeedsTLSEnabled) {
builder.field("cluster_needs_tls", true);
}
builder.endObject();
}

View File

@ -29,9 +29,12 @@ import org.elasticsearch.xpack.monitoring.collector.BaseCollectorTestCase;
import org.elasticsearch.xpack.monitoring.exporter.MonitoringDoc;
import java.util.Collection;
import java.util.Locale;
import java.util.UUID;
import static java.util.Collections.singletonList;
import static org.elasticsearch.xpack.XPackSettings.SECURITY_ENABLED;
import static org.elasticsearch.xpack.XPackSettings.TRANSPORT_SSL_ENABLED;
import static org.elasticsearch.xpack.monitoring.MonitoringTestUtils.randomMonitoringNode;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
@ -80,6 +83,36 @@ public class ClusterStatsCollectorTests extends BaseCollectorTestCase {
}
public void testDoCollect() throws Exception {
final Settings.Builder settings = Settings.builder();
final License.OperationMode mode =
randomValueOtherThan(License.OperationMode.MISSING, () -> randomFrom(License.OperationMode.values()));
final boolean securityEnabled = randomBoolean();
final boolean transportTLSEnabled;
if (securityEnabled) {
switch (mode) {
case TRIAL:
transportTLSEnabled = randomBoolean();
break;
case BASIC:
transportTLSEnabled = false;
break;
case STANDARD:
case GOLD:
case PLATINUM:
transportTLSEnabled = true;
break;
default:
throw new AssertionError("Unknown mode [" + mode + "]");
}
settings.put(TRANSPORT_SSL_ENABLED.getKey(), transportTLSEnabled);
} else {
transportTLSEnabled = false;
settings.put(SECURITY_ENABLED.getKey(), false);
}
final TimeValue timeout = TimeValue.timeValueSeconds(randomIntBetween(1, 120));
withCollectionTimeout(ClusterStatsCollector.CLUSTER_STATS_TIMEOUT, timeout);
@ -95,7 +128,7 @@ public class ClusterStatsCollectorTests extends BaseCollectorTestCase {
final License license = License.builder()
.uid(UUID.randomUUID().toString())
.type("trial")
.type(mode.name().toLowerCase(Locale.ROOT))
.issuer("elasticsearch")
.issuedTo("elastic")
.issueDate(System.currentTimeMillis())
@ -161,6 +194,9 @@ public class ClusterStatsCollectorTests extends BaseCollectorTestCase {
assertThat(document.getLicense(), equalTo(license));
assertThat(document.getStatus(), equalTo(clusterStatus));
assertThat(document.getClusterNeedsTLSEnabled(),
equalTo(mode == License.OperationMode.TRIAL && securityEnabled && transportTLSEnabled == false));
assertThat(document.getClusterStats(), notNullValue());
assertThat(document.getClusterStats().getStatus(), equalTo(clusterStatus));
assertThat(document.getClusterStats().getIndicesStats().getIndexCount(), equalTo(nbIndices));

View File

@ -76,6 +76,7 @@ public class ClusterStatsMonitoringDocTests extends BaseMonitoringDocTestCase<Cl
private ClusterStatsResponse clusterStats;
private ClusterState clusterState;
private License license;
private final boolean needToEnableTLS = randomBoolean();
@Override
@Before
@ -111,7 +112,8 @@ public class ClusterStatsMonitoringDocTests extends BaseMonitoringDocTestCase<Cl
protected ClusterStatsMonitoringDoc createMonitoringDoc(String cluster, long timestamp, long interval, MonitoringDoc.Node node,
MonitoredSystem system, String type, String id) {
return new ClusterStatsMonitoringDoc(cluster, timestamp, interval, node,
clusterName, version, clusterStatus, license, usages, clusterStats, clusterState);
clusterName, version, clusterStatus, license, usages, clusterStats, clusterState,
needToEnableTLS);
}
@Override
@ -132,19 +134,22 @@ public class ClusterStatsMonitoringDocTests extends BaseMonitoringDocTestCase<Cl
public void testConstructorClusterNameMustNotBeNull() {
expectThrows(NullPointerException.class,
() -> new ClusterStatsMonitoringDoc(cluster, timestamp, interval, node,
null, version, clusterStatus, license, usages, clusterStats, clusterState));
null, version, clusterStatus, license, usages, clusterStats, clusterState,
needToEnableTLS));
}
public void testConstructorVersionMustNotBeNull() {
expectThrows(NullPointerException.class,
() -> new ClusterStatsMonitoringDoc(cluster, timestamp, interval, node,
clusterName, null, clusterStatus, license, usages, clusterStats, clusterState));
clusterName, null, clusterStatus, license, usages, clusterStats, clusterState,
needToEnableTLS));
}
public void testConstructorClusterHealthStatusMustNotBeNull() {
expectThrows(NullPointerException.class,
() -> new ClusterStatsMonitoringDoc(cluster, timestamp, interval, node,
clusterName, version, null, license, usages, clusterStats, clusterState));
clusterName, version, null, license, usages, clusterStats, clusterState,
needToEnableTLS));
}
public void testNodesHash() {
@ -339,7 +344,8 @@ public class ClusterStatsMonitoringDocTests extends BaseMonitoringDocTestCase<Cl
license,
usages,
clusterStats,
clusterState);
clusterState,
needToEnableTLS);
final BytesReference xContent = XContentHelper.toXContent(doc, XContentType.JSON, false);
assertEquals("{"
@ -370,6 +376,7 @@ public class ClusterStatsMonitoringDocTests extends BaseMonitoringDocTestCase<Cl
+ "\"issuer\":\"elasticsearch\","
+ "\"start_date_in_millis\":-1,"
+ "\"hkey\":\"e05627254d639cf36346bf99934dc4a4ac9f37bdc9100cee450c10fa6322a6dd\""
+ (needToEnableTLS ? ",\"cluster_needs_tls\":true" : "")
+ "},"
+ "\"cluster_stats\":{"
+ "\"timestamp\":1451606400000,"

View File

@ -60,6 +60,7 @@ import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isEmptyOrNullString;
import static org.hamcrest.Matchers.isOneOf;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
@ -321,6 +322,9 @@ public class MonitoringIT extends ESRestTestCase {
Long expiryDate = (Long) license.get(License.Fields.EXPIRY_DATE_IN_MILLIS);
assertThat(expiryDate, greaterThan(0L));
Boolean clusterNeedsTLS = (Boolean) license.get("cluster_needs_tls");
assertThat(clusterNeedsTLS, isOneOf(true, null));
// We basically recompute the hash here
assertThat("Hash key should be the same",
license.get("hkey"), equalTo(hash(status, uid, type, String.valueOf(expiryDate), (String) source.get("cluster_uuid"))));