Skip to content

Commit 3bc6fd7

Browse files
authored
Allow license installation in dev mode without TLS (elastic/x-pack-elasticsearch#4155)
This commit allows license installation without TLS being enabled when the cluster is in dev mode. The main difference this change enables is the ability to install a production license on a single node cluster that is bound to localhost and does not have the single-node discovery enabled. relates elastic/x-pack-elasticsearch#4123 Original commit: elastic/x-pack-elasticsearch@04ebcc0
1 parent f0be979 commit 3bc6fd7

File tree

5 files changed

+117
-96
lines changed

5 files changed

+117
-96
lines changed

plugin/core/src/main/java/org/elasticsearch/license/LicenseService.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.elasticsearch.cluster.ClusterStateListener;
1515
import org.elasticsearch.cluster.ack.ClusterStateUpdateResponse;
1616
import org.elasticsearch.cluster.metadata.MetaData;
17+
import org.elasticsearch.cluster.node.DiscoveryNode;
1718
import org.elasticsearch.cluster.service.ClusterService;
1819
import org.elasticsearch.common.component.AbstractLifecycleComponent;
1920
import org.elasticsearch.common.component.Lifecycle;
@@ -206,7 +207,7 @@ public void registerLicense(final PutLicenseRequest request, final ActionListene
206207
if (newLicense.isProductionLicense()
207208
&& XPackSettings.SECURITY_ENABLED.get(settings)
208209
&& XPackSettings.TRANSPORT_SSL_ENABLED.get(settings) == false
209-
&& "single-node".equals(DiscoveryModule.DISCOVERY_TYPE_SETTING.get(settings)) == false) {
210+
&& isProductionMode(settings, clusterService.localNode())) {
210211
// security is on but TLS is not configured we gonna fail the entire request and throw an exception
211212
throw new IllegalStateException("Cannot install a [" + newLicense.operationMode() +
212213
"] license unless TLS is configured or security is disabled");
@@ -512,4 +513,13 @@ static License getLicense(final LicensesMetaData metaData) {
512513
}
513514
return null;
514515
}
515-
}
516+
517+
private static boolean isProductionMode(Settings settings, DiscoveryNode localNode) {
518+
final boolean singleNodeDisco = "single-node".equals(DiscoveryModule.DISCOVERY_TYPE_SETTING.get(settings));
519+
return singleNodeDisco == false && isBoundToLoopback(localNode) == false;
520+
}
521+
522+
private static boolean isBoundToLoopback(DiscoveryNode localNode) {
523+
return localNode.getAddress().address().getAddress().isLoopbackAddress();
524+
}
525+
}

plugin/core/src/test/java/org/elasticsearch/license/AbstractLicenseServiceTestCase.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,19 @@ protected void setInitialState(License license, XPackLicenseState licenseState,
6464
MetaData metaData = mock(MetaData.class);
6565
when(metaData.custom(LicensesMetaData.TYPE)).thenReturn(new LicensesMetaData(license, null));
6666
when(state.metaData()).thenReturn(metaData);
67-
final DiscoveryNode mockNode = new DiscoveryNode("b", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT);
67+
final DiscoveryNode mockNode = getLocalNode();
6868
when(discoveryNodes.getMasterNode()).thenReturn(mockNode);
6969
when(discoveryNodes.isLocalNodeElectedMaster()).thenReturn(false);
7070
when(state.nodes()).thenReturn(discoveryNodes);
7171
when(state.getNodes()).thenReturn(discoveryNodes); // it is really ridiculous we have nodes() and getNodes()...
7272
when(clusterService.state()).thenReturn(state);
7373
when(clusterService.lifecycleState()).thenReturn(Lifecycle.State.STARTED);
7474
when(clusterService.getClusterName()).thenReturn(new ClusterName("a"));
75+
when(clusterService.localNode()).thenReturn(mockNode);
76+
}
77+
78+
protected DiscoveryNode getLocalNode() {
79+
return new DiscoveryNode("b", buildNewFakeTransportAddress(), emptyMap(), emptySet(), Version.CURRENT);
7580
}
7681

7782
@After
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
package org.elasticsearch.license;
7+
8+
import org.elasticsearch.Version;
9+
import org.elasticsearch.action.support.PlainActionFuture;
10+
import org.elasticsearch.cluster.ClusterStateUpdateTask;
11+
import org.elasticsearch.cluster.node.DiscoveryNode;
12+
import org.elasticsearch.common.settings.Settings;
13+
import org.elasticsearch.common.transport.TransportAddress;
14+
import org.elasticsearch.common.unit.TimeValue;
15+
16+
import java.net.InetAddress;
17+
18+
import static java.util.Collections.emptyMap;
19+
import static java.util.Collections.emptySet;
20+
import static org.hamcrest.Matchers.containsString;
21+
import static org.mockito.Matchers.any;
22+
import static org.mockito.Mockito.times;
23+
import static org.mockito.Mockito.verify;
24+
25+
public class LicenseTLSTests extends AbstractLicenseServiceTestCase {
26+
27+
private InetAddress inetAddress;
28+
29+
public void testApplyLicenseInDevMode() throws Exception {
30+
License newLicense = TestUtils.generateSignedLicense(randomFrom("gold", "platinum"), TimeValue.timeValueHours(24L));
31+
PutLicenseRequest request = new PutLicenseRequest();
32+
request.acknowledge(true);
33+
request.license(newLicense);
34+
Settings settings = Settings.builder().put("xpack.security.enabled", true).build();
35+
XPackLicenseState licenseState = new XPackLicenseState(settings);
36+
inetAddress = InetAddress.getLoopbackAddress();
37+
38+
setInitialState(null, licenseState, settings);
39+
licenseService.start();
40+
PlainActionFuture<PutLicenseResponse> responseFuture = new PlainActionFuture<>();
41+
licenseService.registerLicense(request, responseFuture);
42+
verify(clusterService).submitStateUpdateTask(any(String.class), any(ClusterStateUpdateTask.class));
43+
44+
inetAddress = TransportAddress.META_ADDRESS;
45+
settings = Settings.builder()
46+
.put("xpack.security.enabled", true)
47+
.put("discovery.type", "single-node")
48+
.build();
49+
licenseService.stop();
50+
licenseState = new XPackLicenseState(settings);
51+
setInitialState(null, licenseState, settings);
52+
licenseService.start();
53+
licenseService.registerLicense(request, responseFuture);
54+
verify(clusterService, times(2)).submitStateUpdateTask(any(String.class), any(ClusterStateUpdateTask.class));
55+
}
56+
57+
public void testApplyLicenseInProdMode() throws Exception {
58+
final String licenseType = randomFrom("GOLD", "PLATINUM");
59+
License newLicense = TestUtils.generateSignedLicense(licenseType, TimeValue.timeValueHours(24L));
60+
PutLicenseRequest request = new PutLicenseRequest();
61+
request.acknowledge(true);
62+
request.license(newLicense);
63+
Settings settings = Settings.builder().put("xpack.security.enabled", true).build();
64+
XPackLicenseState licenseState = new XPackLicenseState(settings);
65+
inetAddress = TransportAddress.META_ADDRESS;
66+
67+
setInitialState(null, licenseState, settings);
68+
licenseService.start();
69+
PlainActionFuture<PutLicenseResponse> responseFuture = new PlainActionFuture<>();
70+
IllegalStateException e = expectThrows(IllegalStateException.class, () -> licenseService.registerLicense(request, responseFuture));
71+
assertThat(e.getMessage(),
72+
containsString("Cannot install a [" + licenseType + "] license unless TLS is configured or security is disabled"));
73+
74+
settings = Settings.builder().put("xpack.security.enabled", false).build();
75+
licenseService.stop();
76+
licenseState = new XPackLicenseState(settings);
77+
setInitialState(null, licenseState, settings);
78+
licenseService.start();
79+
licenseService.registerLicense(request, responseFuture);
80+
verify(clusterService).submitStateUpdateTask(any(String.class), any(ClusterStateUpdateTask.class));
81+
82+
settings = Settings.builder()
83+
.put("xpack.security.enabled", true)
84+
.put("xpack.security.transport.ssl.enabled", true)
85+
.build();
86+
licenseService.stop();
87+
licenseState = new XPackLicenseState(settings);
88+
setInitialState(null, licenseState, settings);
89+
licenseService.start();
90+
licenseService.registerLicense(request, responseFuture);
91+
verify(clusterService, times(2)).submitStateUpdateTask(any(String.class), any(ClusterStateUpdateTask.class));
92+
}
93+
94+
@Override
95+
protected DiscoveryNode getLocalNode() {
96+
return new DiscoveryNode("localnode", new TransportAddress(inetAddress, randomIntBetween(9300, 9399)),
97+
emptyMap(), emptySet(), Version.CURRENT);
98+
}
99+
}

plugin/security/src/test/java/org/elasticsearch/license/LicenseServiceSingleNodeSecurityTests.java

Lines changed: 0 additions & 40 deletions
This file was deleted.

plugin/security/src/test/java/org/elasticsearch/license/LicenseServiceWithSecurityTests.java

Lines changed: 0 additions & 53 deletions
This file was deleted.

0 commit comments

Comments
 (0)