Skip to content

Commit 94cdf0c

Browse files
NETWORKING: http.publish_host Should Contain CNAME (#32806)
* NETWORKING: http.publish_host Should Contain CNAME * Closes #22029
1 parent 9752540 commit 94cdf0c

File tree

5 files changed

+142
-8
lines changed

5 files changed

+142
-8
lines changed

buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,9 @@ class BuildPlugin implements Plugin<Project> {
831831
// TODO: remove this once ctx isn't added to update script params in 7.0
832832
systemProperty 'es.scripting.update.ctx_in_params', 'false'
833833

834+
//TODO: remove this once the cname is prepended to the address by default in 7.0
835+
systemProperty 'es.http.cname_in_publish_address', 'true'
836+
834837
// Set the system keystore/truststore password if we're running tests in a FIPS-140 JVM
835838
if (project.inFipsJvm) {
836839
systemProperty 'javax.net.ssl.trustStorePassword', 'password'

docs/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ integTestCluster {
5757
// TODO: remove this for 7.0, this exists to allow the doc examples in 6.x to continue using the defaults
5858
systemProperty 'es.scripting.use_java_time', 'false'
5959
systemProperty 'es.scripting.update.ctx_in_params', 'false'
60+
//TODO: remove this once the cname is prepended to the address by default in 7.0
61+
systemProperty 'es.http.cname_in_publish_address', 'true'
6062
}
6163

6264
// remove when https://github.com/elastic/elasticsearch/issues/31305 is fixed

modules/lang-painless/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ integTestCluster {
2626
module project.project(':modules:mapper-extras')
2727
systemProperty 'es.scripting.use_java_time', 'true'
2828
systemProperty 'es.scripting.update.ctx_in_params', 'false'
29+
systemProperty 'es.http.cname_in_publish_address', 'true'
2930
}
3031

3132
dependencies {

server/src/main/java/org/elasticsearch/http/HttpInfo.java

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,35 +19,52 @@
1919

2020
package org.elasticsearch.http;
2121

22+
import org.apache.logging.log4j.LogManager;
2223
import org.elasticsearch.common.io.stream.StreamInput;
2324
import org.elasticsearch.common.io.stream.StreamOutput;
2425
import org.elasticsearch.common.io.stream.Writeable;
26+
import org.elasticsearch.common.logging.DeprecationLogger;
27+
import org.elasticsearch.common.network.InetAddresses;
2528
import org.elasticsearch.common.transport.BoundTransportAddress;
29+
import org.elasticsearch.common.transport.TransportAddress;
2630
import org.elasticsearch.common.unit.ByteSizeValue;
2731
import org.elasticsearch.common.xcontent.ToXContentFragment;
2832
import org.elasticsearch.common.xcontent.XContentBuilder;
2933

3034
import java.io.IOException;
3135

36+
import static org.elasticsearch.common.Booleans.parseBoolean;
37+
3238
public class HttpInfo implements Writeable, ToXContentFragment {
3339

40+
private static final DeprecationLogger DEPRECATION_LOGGER = new DeprecationLogger(LogManager.getLogger(HttpInfo.class));
41+
42+
/** Whether to add hostname to publish host field when serializing. */
43+
private static final boolean CNAME_IN_PUBLISH_HOST =
44+
parseBoolean(System.getProperty("es.http.cname_in_publish_address"), false);
45+
3446
private final BoundTransportAddress address;
3547
private final long maxContentLength;
48+
private final boolean cnameInPublishHost;
3649

3750
public HttpInfo(StreamInput in) throws IOException {
38-
address = BoundTransportAddress.readBoundTransportAddress(in);
39-
maxContentLength = in.readLong();
51+
this(BoundTransportAddress.readBoundTransportAddress(in), in.readLong(), CNAME_IN_PUBLISH_HOST);
4052
}
4153

42-
@Override
43-
public void writeTo(StreamOutput out) throws IOException {
44-
address.writeTo(out);
45-
out.writeLong(maxContentLength);
54+
public HttpInfo(BoundTransportAddress address, long maxContentLength) {
55+
this(address, maxContentLength, CNAME_IN_PUBLISH_HOST);
4656
}
4757

48-
public HttpInfo(BoundTransportAddress address, long maxContentLength) {
58+
HttpInfo(BoundTransportAddress address, long maxContentLength, boolean cnameInPublishHost) {
4959
this.address = address;
5060
this.maxContentLength = maxContentLength;
61+
this.cnameInPublishHost = cnameInPublishHost;
62+
}
63+
64+
@Override
65+
public void writeTo(StreamOutput out) throws IOException {
66+
address.writeTo(out);
67+
out.writeLong(maxContentLength);
5168
}
5269

5370
static final class Fields {
@@ -62,7 +79,21 @@ static final class Fields {
6279
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
6380
builder.startObject(Fields.HTTP);
6481
builder.array(Fields.BOUND_ADDRESS, (Object[]) address.boundAddresses());
65-
builder.field(Fields.PUBLISH_ADDRESS, address.publishAddress().toString());
82+
TransportAddress publishAddress = address.publishAddress();
83+
String publishAddressString = publishAddress.toString();
84+
String hostString = publishAddress.address().getHostString();
85+
if (InetAddresses.isInetAddress(hostString) == false) {
86+
if (cnameInPublishHost) {
87+
publishAddressString = hostString + '/' + publishAddress.toString();
88+
} else {
89+
DEPRECATION_LOGGER.deprecated(
90+
"[http.publish_host] was printed as [ip:port] instead of [hostname/ip:port]. "
91+
+ "This format is deprecated and will change to [hostname/ip:port] in a future version. "
92+
+ "Use -Des.http.cname_in_publish_address=true to enforce non-deprecated formatting."
93+
);
94+
}
95+
}
96+
builder.field(Fields.PUBLISH_ADDRESS, publishAddressString);
6697
builder.humanReadableField(Fields.MAX_CONTENT_LENGTH_IN_BYTES, Fields.MAX_CONTENT_LENGTH, maxContentLength());
6798
builder.endObject();
6899
return builder;
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Licensed to Elasticsearch under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.elasticsearch.http;
21+
22+
import java.io.IOException;
23+
import java.net.InetAddress;
24+
import java.util.Map;
25+
import org.elasticsearch.common.network.NetworkAddress;
26+
import org.elasticsearch.common.transport.BoundTransportAddress;
27+
import org.elasticsearch.common.transport.TransportAddress;
28+
import org.elasticsearch.common.xcontent.ToXContent;
29+
import org.elasticsearch.common.xcontent.XContentBuilder;
30+
import org.elasticsearch.common.xcontent.XContentFactory;
31+
import org.elasticsearch.test.ESTestCase;
32+
33+
public class HttpInfoTests extends ESTestCase {
34+
35+
public void testCorrectlyDisplayPublishedCname() throws Exception {
36+
InetAddress localhost = InetAddress.getByName("localhost");
37+
int port = 9200;
38+
assertPublishAddress(
39+
new HttpInfo(
40+
new BoundTransportAddress(
41+
new TransportAddress[]{new TransportAddress(localhost, port)},
42+
new TransportAddress(localhost, port)
43+
), 0L, true
44+
), "localhost/" + NetworkAddress.format(localhost) + ':' + port
45+
);
46+
}
47+
48+
public void hideCnameIfDeprecatedFormat() throws Exception {
49+
InetAddress localhost = InetAddress.getByName("localhost");
50+
int port = 9200;
51+
assertPublishAddress(
52+
new HttpInfo(
53+
new BoundTransportAddress(
54+
new TransportAddress[]{new TransportAddress(localhost, port)},
55+
new TransportAddress(localhost, port)
56+
), 0L, false
57+
), NetworkAddress.format(localhost) + ':' + port
58+
);
59+
}
60+
61+
public void testCorrectDisplayPublishedIp() throws Exception {
62+
InetAddress localhost = InetAddress.getByName(NetworkAddress.format(InetAddress.getByName("localhost")));
63+
int port = 9200;
64+
assertPublishAddress(
65+
new HttpInfo(
66+
new BoundTransportAddress(
67+
new TransportAddress[]{new TransportAddress(localhost, port)},
68+
new TransportAddress(localhost, port)
69+
), 0L, true
70+
), NetworkAddress.format(localhost) + ':' + port
71+
);
72+
}
73+
74+
public void testCorrectDisplayPublishedIpv6() throws Exception {
75+
int port = 9200;
76+
TransportAddress localhost =
77+
new TransportAddress(InetAddress.getByName(NetworkAddress.format(InetAddress.getByName("0:0:0:0:0:0:0:1"))), port);
78+
assertPublishAddress(
79+
new HttpInfo(
80+
new BoundTransportAddress(new TransportAddress[]{localhost}, localhost), 0L, true
81+
), localhost.toString()
82+
);
83+
}
84+
85+
@SuppressWarnings("unchecked")
86+
private void assertPublishAddress(HttpInfo httpInfo, String expected) throws IOException {
87+
XContentBuilder builder = XContentFactory.jsonBuilder();
88+
builder.startObject();
89+
httpInfo.toXContent(builder, ToXContent.EMPTY_PARAMS);
90+
builder.endObject();
91+
assertEquals(
92+
expected,
93+
((Map<String, Object>) createParser(builder).map().get(HttpInfo.Fields.HTTP))
94+
.get(HttpInfo.Fields.PUBLISH_ADDRESS)
95+
);
96+
}
97+
}

0 commit comments

Comments
 (0)