Skip to content

Commit 053779d

Browse files
committed
Detect old trial licenses and mimic behaviour (#32209)
Prior to 6.3 a trial license default to security enabled. Since 6.3 they default to security disabled. If a cluster is upgraded from <6.3 to >6.3, then we detect this and mimic the old behaviour with respect to security.
1 parent 8d41d4d commit 053779d

File tree

9 files changed

+111
-43
lines changed

9 files changed

+111
-43
lines changed

x-pack/plugin/core/src/main/java/org/elasticsearch/license/LicenseService.java

+18-7
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ public LicenseService(Settings settings, ClusterService clusterService, Clock cl
118118
this.scheduler = new SchedulerEngine(clock);
119119
this.licenseState = licenseState;
120120
this.operationModeFileWatcher = new OperationModeFileWatcher(resourceWatcherService,
121-
XPackPlugin.resolveConfigFile(env, "license_mode"), logger, () -> updateLicenseState(getLicense()));
121+
XPackPlugin.resolveConfigFile(env, "license_mode"), logger,
122+
() -> updateLicenseState(getLicensesMetaData()));
122123
this.scheduler.register(this);
123124
populateExpirationCallbacks();
124125
}
@@ -263,11 +264,11 @@ private static TimeValue days(int days) {
263264

264265
@Override
265266
public void triggered(SchedulerEngine.Event event) {
266-
final LicensesMetaData licensesMetaData = clusterService.state().metaData().custom(LicensesMetaData.TYPE);
267+
final LicensesMetaData licensesMetaData = getLicensesMetaData();
267268
if (licensesMetaData != null) {
268269
final License license = licensesMetaData.getLicense();
269270
if (event.getJobName().equals(LICENSE_JOB)) {
270-
updateLicenseState(license);
271+
updateLicenseState(license, licensesMetaData.getMostRecentTrialVersion());
271272
} else if (event.getJobName().startsWith(ExpirationCallback.EXPIRATION_JOB_PREFIX)) {
272273
expirationCallbacks.stream()
273274
.filter(expirationCallback -> expirationCallback.getId().equals(event.getJobName()))
@@ -309,6 +310,10 @@ public License getLicense() {
309310
return license == LicensesMetaData.LICENSE_TOMBSTONE ? null : license;
310311
}
311312

313+
private LicensesMetaData getLicensesMetaData() {
314+
return this.clusterService.state().metaData().custom(LicensesMetaData.TYPE);
315+
}
316+
312317
void startTrialLicense(PostStartTrialRequest request, final ActionListener<PostStartTrialResponse> listener) {
313318
if (VALID_TRIAL_TYPES.contains(request.getType()) == false) {
314319
throw new IllegalArgumentException("Cannot start trial of type [" + request.getType() + "]. Valid trial types are "
@@ -419,10 +424,16 @@ public void clusterChanged(ClusterChangedEvent event) {
419424
}
420425
}
421426

422-
protected void updateLicenseState(final License license) {
427+
private void updateLicenseState(LicensesMetaData licensesMetaData) {
428+
if (licensesMetaData != null) {
429+
updateLicenseState(getLicense(licensesMetaData), licensesMetaData.getMostRecentTrialVersion());
430+
}
431+
}
432+
433+
protected void updateLicenseState(final License license, Version mostRecentTrialVersion) {
423434
if (license == LicensesMetaData.LICENSE_TOMBSTONE) {
424435
// implies license has been explicitly deleted
425-
licenseState.update(License.OperationMode.MISSING, false);
436+
licenseState.update(License.OperationMode.MISSING, false, mostRecentTrialVersion);
426437
return;
427438
}
428439
if (license != null) {
@@ -435,7 +446,7 @@ protected void updateLicenseState(final License license) {
435446
// date that is near Long.MAX_VALUE
436447
active = time >= license.issueDate() && time - GRACE_PERIOD_DURATION.getMillis() < license.expiryDate();
437448
}
438-
licenseState.update(license.operationMode(), active);
449+
licenseState.update(license.operationMode(), active, mostRecentTrialVersion);
439450

440451
if (active) {
441452
if (time < license.expiryDate()) {
@@ -477,7 +488,7 @@ private void onUpdate(final LicensesMetaData currentLicensesMetaData) {
477488
logger.info("license [{}] mode [{}] - valid", license.uid(),
478489
license.operationMode().name().toLowerCase(Locale.ROOT));
479490
}
480-
updateLicenseState(license);
491+
updateLicenseState(license, currentLicensesMetaData.getMostRecentTrialVersion());
481492
}
482493
}
483494

x-pack/plugin/core/src/main/java/org/elasticsearch/license/XPackLicenseState.java

+26-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
*/
66
package org.elasticsearch.license;
77

8+
import org.elasticsearch.Version;
9+
import org.elasticsearch.common.Nullable;
810
import org.elasticsearch.common.Strings;
911
import org.elasticsearch.common.logging.LoggerMessageFormat;
12+
import org.elasticsearch.common.logging.Loggers;
1013
import org.elasticsearch.common.settings.Settings;
1114
import org.elasticsearch.license.License.OperationMode;
1215
import org.elasticsearch.xpack.core.XPackField;
@@ -251,6 +254,7 @@ private static class Status {
251254
private final List<Runnable> listeners = new CopyOnWriteArrayList<>();
252255
private final boolean isSecurityEnabled;
253256
private final boolean isSecurityExplicitlyEnabled;
257+
private volatile boolean isSecurityEnabledByTrialVersion;
254258

255259
public XPackLicenseState(Settings settings) {
256260
this.isSecurityEnabled = XPackSettings.SECURITY_ENABLED.get(settings);
@@ -259,11 +263,30 @@ public XPackLicenseState(Settings settings) {
259263
// setting is not explicitly set
260264
this.isSecurityExplicitlyEnabled = isSecurityEnabled &&
261265
(settings.hasValue(XPackSettings.SECURITY_ENABLED.getKey()) || XPackSettings.TRANSPORT_SSL_ENABLED.get(settings));
266+
this.isSecurityEnabledByTrialVersion = false;
262267
}
263268

264-
/** Updates the current state of the license, which will change what features are available. */
265-
void update(OperationMode mode, boolean active) {
269+
/**
270+
* Updates the current state of the license, which will change what features are available.
271+
*
272+
* @param mode The mode (type) of the current license.
273+
* @param active True if the current license exists and is within its allowed usage period; false if it is expired or missing.
274+
* @param mostRecentTrialVersion If this cluster has, at some point commenced a trial, the most recent version on which they did that.
275+
* May be {@code null} if they have never generated a trial license on this cluster, or the most recent
276+
* trial was prior to this metadata being tracked (6.1)
277+
*/
278+
void update(OperationMode mode, boolean active, @Nullable Version mostRecentTrialVersion) {
266279
status = new Status(mode, active);
280+
if (isSecurityEnabled == true && isSecurityExplicitlyEnabled == false && mode == OperationMode.TRIAL
281+
&& isSecurityEnabledByTrialVersion == false) {
282+
// Before 6.3, Trial licenses would default having security enabled.
283+
// If this license was generated before that version, then treat it as if security is explicitly enabled
284+
if (mostRecentTrialVersion == null || mostRecentTrialVersion.before(Version.V_6_3_0)) {
285+
Loggers.getLogger(getClass()).info("Automatically enabling security for older trial license ({})",
286+
mostRecentTrialVersion == null ? "[pre 6.1.0]" : mostRecentTrialVersion.toString());
287+
isSecurityEnabledByTrialVersion = true;
288+
}
289+
}
267290
listeners.forEach(Runnable::run);
268291
}
269292

@@ -575,6 +598,6 @@ public boolean isSecurityAvailable() {
575598

576599
public boolean isSecurityEnabled() {
577600
final OperationMode mode = status.mode;
578-
return mode == OperationMode.TRIAL ? isSecurityExplicitlyEnabled : isSecurityEnabled;
601+
return mode == OperationMode.TRIAL ? (isSecurityExplicitlyEnabled || isSecurityEnabledByTrialVersion) : isSecurityEnabled;
579602
}
580603
}

x-pack/plugin/core/src/test/java/org/elasticsearch/license/TestUtils.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package org.elasticsearch.license;
77

88
import com.carrotsearch.randomizedtesting.RandomizedTest;
9+
import org.elasticsearch.Version;
910
import org.elasticsearch.action.ActionListener;
1011
import org.elasticsearch.cluster.metadata.MetaData;
1112
import org.elasticsearch.common.Strings;
@@ -341,20 +342,22 @@ public void onFailure(Exception e) {
341342
public static class AssertingLicenseState extends XPackLicenseState {
342343
public final List<License.OperationMode> modeUpdates = new ArrayList<>();
343344
public final List<Boolean> activeUpdates = new ArrayList<>();
345+
public final List<Version> trialVersionUpdates = new ArrayList<>();
344346

345347
public AssertingLicenseState() {
346348
super(Settings.EMPTY);
347349
}
348350

349351
@Override
350-
void update(License.OperationMode mode, boolean active) {
352+
void update(License.OperationMode mode, boolean active, Version mostRecentTrialVersion) {
351353
modeUpdates.add(mode);
352354
activeUpdates.add(active);
355+
trialVersionUpdates.add(mostRecentTrialVersion);
353356
}
354357
}
355358

356359
/**
357-
* A license state that makes the {@link #update(License.OperationMode, boolean)}
360+
* A license state that makes the {@link #update(License.OperationMode, boolean, Version)}
358361
* method public for use in tests.
359362
*/
360363
public static class UpdatableLicenseState extends XPackLicenseState {
@@ -367,8 +370,8 @@ public UpdatableLicenseState(Settings settings) {
367370
}
368371

369372
@Override
370-
public void update(License.OperationMode mode, boolean active) {
371-
super.update(mode, active);
373+
public void update(License.OperationMode mode, boolean active, Version mostRecentTrialVersion) {
374+
super.update(mode, active, mostRecentTrialVersion);
372375
}
373376
}
374377

x-pack/plugin/core/src/test/java/org/elasticsearch/license/XPackLicenseStateTests.java

+47-17
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
*/
66
package org.elasticsearch.license;
77

8+
import org.elasticsearch.Version;
89
import org.elasticsearch.common.settings.Settings;
910
import org.elasticsearch.license.License.OperationMode;
1011
import org.elasticsearch.test.ESTestCase;
12+
import org.elasticsearch.test.VersionUtils;
1113
import org.elasticsearch.xpack.core.XPackField;
1214
import org.elasticsearch.xpack.core.XPackSettings;
1315

@@ -31,7 +33,7 @@ public class XPackLicenseStateTests extends ESTestCase {
3133
/** Creates a license state with the given license type and active state, and checks the given method returns expected. */
3234
void assertAllowed(OperationMode mode, boolean active, Predicate<XPackLicenseState> predicate, boolean expected) {
3335
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
34-
licenseState.update(mode, active);
36+
licenseState.update(mode, active, null);
3537
assertEquals(expected, predicate.test(licenseState));
3638
}
3739

@@ -102,7 +104,7 @@ public void testSecurityDefaults() {
102104
public void testSecurityBasic() {
103105
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
104106
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
105-
licenseState.update(BASIC, true);
107+
licenseState.update(BASIC, true, null);
106108

107109
assertThat(licenseState.isAuthAllowed(), is(false));
108110
assertThat(licenseState.isIpFilteringAllowed(), is(false));
@@ -116,7 +118,7 @@ public void testSecurityBasic() {
116118
public void testSecurityBasicExpired() {
117119
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
118120
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
119-
licenseState.update(BASIC, false);
121+
licenseState.update(BASIC, false, null);
120122

121123
assertThat(licenseState.isAuthAllowed(), is(false));
122124
assertThat(licenseState.isIpFilteringAllowed(), is(false));
@@ -130,7 +132,7 @@ public void testSecurityBasicExpired() {
130132
public void testSecurityStandard() {
131133
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
132134
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
133-
licenseState.update(STANDARD, true);
135+
licenseState.update(STANDARD, true, null);
134136

135137
assertThat(licenseState.isAuthAllowed(), is(true));
136138
assertThat(licenseState.isIpFilteringAllowed(), is(false));
@@ -144,7 +146,7 @@ public void testSecurityStandard() {
144146
public void testSecurityStandardExpired() {
145147
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
146148
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
147-
licenseState.update(STANDARD, false);
149+
licenseState.update(STANDARD, false, null);
148150

149151
assertThat(licenseState.isAuthAllowed(), is(true));
150152
assertThat(licenseState.isIpFilteringAllowed(), is(false));
@@ -158,7 +160,7 @@ public void testSecurityStandardExpired() {
158160
public void testSecurityGold() {
159161
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
160162
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
161-
licenseState.update(GOLD, true);
163+
licenseState.update(GOLD, true, null);
162164

163165
assertThat(licenseState.isAuthAllowed(), is(true));
164166
assertThat(licenseState.isIpFilteringAllowed(), is(true));
@@ -172,7 +174,7 @@ public void testSecurityGold() {
172174
public void testSecurityGoldExpired() {
173175
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
174176
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
175-
licenseState.update(GOLD, false);
177+
licenseState.update(GOLD, false, null);
176178

177179
assertThat(licenseState.isAuthAllowed(), is(true));
178180
assertThat(licenseState.isIpFilteringAllowed(), is(true));
@@ -186,7 +188,7 @@ public void testSecurityGoldExpired() {
186188
public void testSecurityPlatinum() {
187189
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
188190
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
189-
licenseState.update(PLATINUM, true);
191+
licenseState.update(PLATINUM, true, null);
190192

191193
assertThat(licenseState.isAuthAllowed(), is(true));
192194
assertThat(licenseState.isIpFilteringAllowed(), is(true));
@@ -200,7 +202,7 @@ public void testSecurityPlatinum() {
200202
public void testSecurityPlatinumExpired() {
201203
XPackLicenseState licenseState = new XPackLicenseState(randomFrom(Settings.EMPTY,
202204
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build()));
203-
licenseState.update(PLATINUM, false);
205+
licenseState.update(PLATINUM, false, null);
204206

205207
assertThat(licenseState.isAuthAllowed(), is(true));
206208
assertThat(licenseState.isIpFilteringAllowed(), is(true));
@@ -211,6 +213,34 @@ public void testSecurityPlatinumExpired() {
211213
assertThat(licenseState.isCustomRoleProvidersAllowed(), is(false));
212214
}
213215

216+
public void testNewTrialDefaultsSecurityOff() {
217+
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
218+
licenseState.update(TRIAL, true, VersionUtils.randomVersionBetween(random(), Version.V_6_3_0, Version.CURRENT));
219+
220+
assertThat(licenseState.isSecurityEnabled(), is(false));
221+
assertThat(licenseState.isAuthAllowed(), is(true));
222+
assertThat(licenseState.isIpFilteringAllowed(), is(true));
223+
assertThat(licenseState.isAuditingAllowed(), is(true));
224+
assertThat(licenseState.isStatsAndHealthAllowed(), is(true));
225+
assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(true));
226+
assertThat(licenseState.allowedRealmType(), is(XPackLicenseState.AllowedRealmType.ALL));
227+
assertThat(licenseState.isCustomRoleProvidersAllowed(), is(true));
228+
}
229+
230+
public void testOldTrialDefaultsSecurityOn() {
231+
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
232+
licenseState.update(TRIAL, true, rarely() ? null : VersionUtils.randomVersionBetween(random(), Version.V_5_6_0, Version.V_6_2_4));
233+
234+
assertThat(licenseState.isSecurityEnabled(), is(true));
235+
assertThat(licenseState.isAuthAllowed(), is(true));
236+
assertThat(licenseState.isIpFilteringAllowed(), is(true));
237+
assertThat(licenseState.isAuditingAllowed(), is(true));
238+
assertThat(licenseState.isStatsAndHealthAllowed(), is(true));
239+
assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(true));
240+
assertThat(licenseState.allowedRealmType(), is(XPackLicenseState.AllowedRealmType.ALL));
241+
assertThat(licenseState.isCustomRoleProvidersAllowed(), is(true));
242+
}
243+
214244
public void testSecurityAckBasicToNotGoldOrStandard() {
215245
OperationMode toMode = randomFrom(OperationMode.values(), mode -> mode != GOLD && mode != STANDARD);
216246
assertAckMesssages(XPackField.SECURITY, BASIC, toMode, 0);
@@ -354,63 +384,63 @@ public void testSqlDefaults() {
354384

355385
public void testSqlBasic() {
356386
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
357-
licenseState.update(BASIC, true);
387+
licenseState.update(BASIC, true, null);
358388

359389
assertThat(licenseState.isSqlAllowed(), is(true));
360390
assertThat(licenseState.isJdbcAllowed(), is(false));
361391
}
362392

363393
public void testSqlBasicExpired() {
364394
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
365-
licenseState.update(BASIC, false);
395+
licenseState.update(BASIC, false, null);
366396

367397
assertThat(licenseState.isSqlAllowed(), is(false));
368398
assertThat(licenseState.isJdbcAllowed(), is(false));
369399
}
370400

371401
public void testSqlStandard() {
372402
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
373-
licenseState.update(STANDARD, true);
403+
licenseState.update(STANDARD, true, null);
374404

375405
assertThat(licenseState.isSqlAllowed(), is(true));
376406
assertThat(licenseState.isJdbcAllowed(), is(false));
377407
}
378408

379409
public void testSqlStandardExpired() {
380410
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
381-
licenseState.update(STANDARD, false);
411+
licenseState.update(STANDARD, false, null);
382412

383413
assertThat(licenseState.isSqlAllowed(), is(false));
384414
assertThat(licenseState.isJdbcAllowed(), is(false));
385415
}
386416

387417
public void testSqlGold() {
388418
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
389-
licenseState.update(GOLD, true);
419+
licenseState.update(GOLD, true, null);
390420

391421
assertThat(licenseState.isSqlAllowed(), is(true));
392422
assertThat(licenseState.isJdbcAllowed(), is(false));
393423
}
394424

395425
public void testSqlGoldExpired() {
396426
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
397-
licenseState.update(GOLD, false);
427+
licenseState.update(GOLD, false, null);
398428

399429
assertThat(licenseState.isSqlAllowed(), is(false));
400430
assertThat(licenseState.isJdbcAllowed(), is(false));
401431
}
402432

403433
public void testSqlPlatinum() {
404434
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
405-
licenseState.update(PLATINUM, true);
435+
licenseState.update(PLATINUM, true, null);
406436

407437
assertThat(licenseState.isSqlAllowed(), is(true));
408438
assertThat(licenseState.isJdbcAllowed(), is(true));
409439
}
410440

411441
public void testSqlPlatinumExpired() {
412442
XPackLicenseState licenseState = new XPackLicenseState(Settings.EMPTY);
413-
licenseState.update(PLATINUM, false);
443+
licenseState.update(PLATINUM, false, null);
414444

415445
assertThat(licenseState.isSqlAllowed(), is(false));
416446
assertThat(licenseState.isJdbcAllowed(), is(false));

0 commit comments

Comments
 (0)