Skip to content

Commit 0c9662c

Browse files
jbaieraprobakowski
andauthored
[7.x] Add setting to decommission legacy monitoring cluster alerts (#62668) (#64443)
Adds a setting that, when enabled, directs any currently running exporters in monitoring will treat any cluster alert definition as excluded from the list of allowed cluster alert watches. This is the first step to adding a migration path away from using cluster alerts configured by the monitoring plugin and toward those managed by the stack monitoring solutions on the new alerting feature. Co-authored-by: Przemko Robakowski <[email protected]>
1 parent 9830222 commit 0c9662c

File tree

9 files changed

+345
-20
lines changed

9 files changed

+345
-20
lines changed

x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/Monitoring.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ public class Monitoring extends Plugin implements ActionPlugin, ReloadablePlugin
8282
public static final Setting<Boolean> CLEAN_WATCHER_HISTORY = boolSetting("xpack.watcher.history.cleaner_service.enabled",
8383
true, Setting.Property.Dynamic, Setting.Property.NodeScope, Setting.Property.Deprecated);
8484

85+
public static final Setting<Boolean> MIGRATION_DECOMMISSION_ALERTS = boolSetting("xpack.monitoring.migration.decommission_alerts",
86+
false, Setting.Property.Dynamic, Setting.Property.NodeScope);
87+
8588
protected final Settings settings;
8689
private final boolean transportClientMode;
8790

@@ -164,6 +167,7 @@ public List<Setting<?>> getSettings() {
164167
List<Setting<?>> settings = new ArrayList<>();
165168
settings.add(MonitoringField.HISTORY_DURATION);
166169
settings.add(CLEAN_WATCHER_HISTORY);
170+
settings.add(MIGRATION_DECOMMISSION_ALERTS);
167171
settings.add(MonitoringService.ENABLED);
168172
settings.add(MonitoringService.ELASTICSEARCH_COLLECTION_ENABLED);
169173
settings.add(MonitoringService.INTERVAL);

x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/Exporters.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.elasticsearch.gateway.GatewayService;
2424
import org.elasticsearch.license.XPackLicenseState;
2525
import org.elasticsearch.xpack.core.ssl.SSLService;
26+
import org.elasticsearch.xpack.monitoring.Monitoring;
2627
import org.elasticsearch.xpack.monitoring.exporter.http.HttpExporter;
2728
import org.elasticsearch.xpack.core.monitoring.exporter.MonitoringDoc;
2829
import org.elasticsearch.xpack.monitoring.exporter.local.LocalExporter;
@@ -62,7 +63,9 @@ public Exporters(Settings settings, Map<String, Exporter.Factory> factories,
6263

6364
final List<Setting.AffixSetting<?>> dynamicSettings =
6465
getSettings().stream().filter(Setting::isDynamic).collect(Collectors.toList());
65-
clusterService.getClusterSettings().addSettingsUpdateConsumer(this::setExportersSetting, dynamicSettings);
66+
final List<Setting<?>> updateSettings = new ArrayList<Setting<?>>(dynamicSettings);
67+
updateSettings.add(Monitoring.MIGRATION_DECOMMISSION_ALERTS);
68+
clusterService.getClusterSettings().addSettingsUpdateConsumer(this::setExportersSetting, updateSettings);
6669
HttpExporter.registerSettingValidators(clusterService, sslService);
6770
// this ensures that logging is happening by adding an empty consumer per affix setting
6871
for (Setting.AffixSetting<?> affixSetting : dynamicSettings) {

x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.elasticsearch.xpack.core.ssl.SSLConfiguration;
4444
import org.elasticsearch.xpack.core.ssl.SSLConfigurationSettings;
4545
import org.elasticsearch.xpack.core.ssl.SSLService;
46+
import org.elasticsearch.xpack.monitoring.Monitoring;
4647
import org.elasticsearch.xpack.monitoring.exporter.ClusterAlertsUtil;
4748
import org.elasticsearch.xpack.monitoring.exporter.ExportBulk;
4849
import org.elasticsearch.xpack.monitoring.exporter.Exporter;
@@ -908,7 +909,7 @@ private static void configureClusterAlertsResources(final Config config, final S
908909

909910
// add a resource per watch
910911
for (final String watchId : ClusterAlertsUtil.WATCH_IDS) {
911-
final boolean blacklisted = blacklist.contains(watchId);
912+
final boolean blacklisted = blacklist.contains(watchId) || Monitoring.MIGRATION_DECOMMISSION_ALERTS.get(config.settings());
912913
// lazily load the cluster state to fetch the cluster UUID once it's loaded
913914
final Supplier<String> uniqueWatchId = () -> ClusterAlertsUtil.createUniqueWatchId(clusterService, watchId);
914915
final Supplier<String> watch = blacklisted ? null : () -> ClusterAlertsUtil.loadWatch(clusterService, watchId);

x-pack/plugin/monitoring/src/main/java/org/elasticsearch/xpack/monitoring/exporter/local/LocalExporter.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.elasticsearch.xpack.core.watcher.transport.actions.get.GetWatchRequest;
5252
import org.elasticsearch.xpack.core.watcher.transport.actions.get.GetWatchResponse;
5353
import org.elasticsearch.xpack.core.watcher.watch.Watch;
54+
import org.elasticsearch.xpack.monitoring.Monitoring;
5455
import org.elasticsearch.xpack.monitoring.cleaner.CleanerService;
5556
import org.elasticsearch.xpack.monitoring.exporter.ClusterAlertsUtil;
5657
import org.elasticsearch.xpack.monitoring.exporter.ExportBulk;
@@ -105,6 +106,7 @@ public class LocalExporter extends Exporter implements ClusterStateListener, Cle
105106
private final boolean useIngest;
106107
private final DateFormatter dateTimeFormatter;
107108
private final List<String> clusterAlertBlacklist;
109+
private final boolean decommissionClusterAlerts;
108110

109111
private final AtomicReference<State> state = new AtomicReference<>(State.INITIALIZED);
110112
private final AtomicBoolean installingSomething = new AtomicBoolean(false);
@@ -120,6 +122,7 @@ public LocalExporter(Exporter.Config config, Client client, CleanerService clean
120122
this.licenseState = config.licenseState();
121123
this.useIngest = USE_INGEST_PIPELINE_SETTING.getConcreteSettingForNamespace(config.name()).get(config.settings());
122124
this.clusterAlertBlacklist = ClusterAlertsUtil.getClusterAlertsBlacklist(config);
125+
this.decommissionClusterAlerts = Monitoring.MIGRATION_DECOMMISSION_ALERTS.get(config.settings());
123126
this.cleanerService = cleanerService;
124127
this.dateTimeFormatter = dateTimeFormatter(config);
125128
// if additional listeners are added here, adjust LocalExporterTests#testLocalExporterRemovesListenersOnClose accordingly
@@ -158,8 +161,10 @@ public void licenseStateChanged() {
158161
boolean isExporterReady() {
159162
// forces the setup to occur if it hasn't already
160163
final boolean running = resolveBulk(clusterService.state(), false) != null;
164+
// Report on watcher readiness
165+
boolean alertsProcessed = canUseWatcher() == false || watcherSetup.get();
161166

162-
return running && installingSomething.get() == false;
167+
return running && installingSomething.get() == false && alertsProcessed;
163168
}
164169

165170
@Override
@@ -455,7 +460,8 @@ private void getClusterAlertsInstallationAsyncActions(final boolean indexExists,
455460

456461
for (final String watchId : ClusterAlertsUtil.WATCH_IDS) {
457462
final String uniqueWatchId = ClusterAlertsUtil.createUniqueWatchId(clusterService, watchId);
458-
final boolean addWatch = canAddWatches && clusterAlertBlacklist.contains(watchId) == false;
463+
final boolean addWatch = canAddWatches && clusterAlertBlacklist.contains(watchId) == false &&
464+
decommissionClusterAlerts == false;
459465

460466
// we aren't sure if no watches exist yet, so add them
461467
if (indexExists) {

x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/exporter/http/HttpExporterResourceTests.java

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,11 @@ public void setupResources() {
102102
}
103103

104104
public void awaitCheckAndPublish(final Boolean expected) {
105-
resources.checkAndPublish(client, listener);
105+
awaitCheckAndPublish(resources, expected);
106+
}
107+
108+
public void awaitCheckAndPublish(HttpResource resource, final Boolean expected) {
109+
resource.checkAndPublish(client, listener);
106110

107111
verifyListener(expected);
108112
}
@@ -484,6 +488,56 @@ public void testWatchPublishBlocksAfterSuccessfulWatcherCheck() {
484488
verifyNoMoreInteractions(client);
485489
}
486490

491+
public void testDeployClusterAlerts() {
492+
final int successfulGetTemplates = randomIntBetween(0, EXPECTED_TEMPLATES);
493+
final int unsuccessfulGetTemplates = EXPECTED_TEMPLATES - successfulGetTemplates;
494+
final int successfulGetPipelines = randomIntBetween(0, EXPECTED_PIPELINES);
495+
final int unsuccessfulGetPipelines = EXPECTED_PIPELINES - successfulGetPipelines;
496+
final Exception exception = failurePutException();
497+
498+
whenValidVersionResponse();
499+
whenGetTemplates(successfulGetTemplates, unsuccessfulGetTemplates);
500+
whenSuccessfulPutTemplates(unsuccessfulGetTemplates);
501+
whenGetPipelines(successfulGetPipelines, unsuccessfulGetPipelines);
502+
whenSuccessfulPutPipelines(unsuccessfulGetPipelines);
503+
// license needs to be valid, otherwise we'll do DELETEs, which are tested earlier
504+
whenWatcherCanBeUsed(true);
505+
506+
// a number of watches are mocked as present
507+
final int existingWatches = randomIntBetween(0, EXPECTED_WATCHES);
508+
509+
// For completeness's sake. GET/PUT watches wont be called by the resources.
510+
// Instead it tries to DELETE the watches ignoring them not existing.
511+
whenGetWatches(existingWatches, EXPECTED_WATCHES - existingWatches);
512+
whenPerformRequestAsyncWith(client, new RequestMatcher(is("PUT"), startsWith("/_watcher/watch/")), exception);
513+
whenPerformRequestAsyncWith(client, new RequestMatcher(is("DELETE"), startsWith("/_watcher/watch/")),
514+
successfulDeleteResponses(EXPECTED_WATCHES));
515+
516+
// Create resources that are configured to remove all watches
517+
Settings removalExporterSettings = Settings.builder()
518+
.put(exporterSettings)
519+
.put("xpack.monitoring.migration.decommission_alerts", true)
520+
.build();
521+
MultiHttpResource overrideResource = HttpExporter.createResources(
522+
new Exporter.Config("_http", "http", removalExporterSettings, clusterService, licenseState));
523+
524+
assertTrue(overrideResource.isDirty());
525+
awaitCheckAndPublish(overrideResource, true);
526+
// Should proceed
527+
assertFalse(overrideResource.isDirty());
528+
529+
verifyVersionCheck();
530+
verifyGetTemplates(EXPECTED_TEMPLATES);
531+
verifyPutTemplates(unsuccessfulGetTemplates);
532+
verifyGetPipelines(EXPECTED_PIPELINES);
533+
verifyPutPipelines(unsuccessfulGetPipelines);
534+
verifyWatcherCheck();
535+
verifyGetWatches(0);
536+
verifyPutWatches(0);
537+
verifyDeleteWatches(EXPECTED_WATCHES);
538+
verifyNoMoreInteractions(client);
539+
}
540+
487541
public void testSuccessfulChecksOnElectedMasterNode() {
488542
final int successfulGetTemplates = randomIntBetween(0, EXPECTED_TEMPLATES);
489543
final int unsuccessfulGetTemplates = EXPECTED_TEMPLATES - successfulGetTemplates;

x-pack/plugin/monitoring/src/test/java/org/elasticsearch/xpack/monitoring/exporter/local/LocalExporterIntegTestCase.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public static void setupThreadPool() {
3232
}
3333

3434
@AfterClass
35-
public static void cleanUpStatic() throws Exception {
35+
public static void cleanUpStatic() {
3636
if (THREADPOOL != null) {
3737
terminate(THREADPOOL);
3838
}
@@ -57,6 +57,15 @@ protected Settings nodeSettings(int nodeOrdinal) {
5757
.build();
5858
}
5959

60+
/**
61+
* Create a new {@link LocalExporter} with the default exporter settings and name.
62+
*
63+
* @return Never {@code null}.
64+
*/
65+
protected LocalExporter createLocalExporter() {
66+
return createLocalExporter(exporterName, null);
67+
}
68+
6069
/**
6170
* Create a new {@link LocalExporter}. Expected usage:
6271
* <pre><code>
@@ -68,12 +77,11 @@ protected Settings nodeSettings(int nodeOrdinal) {
6877
*
6978
* @return Never {@code null}.
7079
*/
71-
protected LocalExporter createLocalExporter() {
72-
final Settings settings = localExporterSettings();
80+
protected LocalExporter createLocalExporter(String exporterName, Settings exporterSettings) {
7381
final XPackLicenseState licenseState = TestUtils.newTestLicenseState();
74-
final Exporter.Config config = new Exporter.Config(exporterName, "local", settings, clusterService(), licenseState);
82+
final Exporter.Config config = new Exporter.Config(exporterName, "local", exporterSettings, clusterService(), licenseState);
7583
final CleanerService cleanerService =
76-
new CleanerService(settings, clusterService().getClusterSettings(), THREADPOOL, licenseState);
84+
new CleanerService(exporterSettings, clusterService().getClusterSettings(), THREADPOOL, licenseState);
7785

7886
return new LocalExporter(config, client(), cleanerService);
7987
}

0 commit comments

Comments
 (0)