[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:
parent
2bc0d8698d
commit
2acd0afdd5
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,"
|
||||
|
|
|
@ -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"))));
|
||||
|
|
Loading…
Reference in New Issue