NETWORKING: http.publish_host Should Contain CNAME (#32806)

* NETWORKING: http.publish_host Should Contain CNAME

* Closes #22029
This commit is contained in:
Armin Braun 2018-09-12 06:15:36 +02:00 committed by GitHub
parent 9752540866
commit 94cdf0ceba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 142 additions and 8 deletions

View File

@ -831,6 +831,9 @@ class BuildPlugin implements Plugin<Project> {
// TODO: remove this once ctx isn't added to update script params in 7.0
systemProperty 'es.scripting.update.ctx_in_params', 'false'
//TODO: remove this once the cname is prepended to the address by default in 7.0
systemProperty 'es.http.cname_in_publish_address', 'true'
// Set the system keystore/truststore password if we're running tests in a FIPS-140 JVM
if (project.inFipsJvm) {
systemProperty 'javax.net.ssl.trustStorePassword', 'password'

View File

@ -57,6 +57,8 @@ integTestCluster {
// TODO: remove this for 7.0, this exists to allow the doc examples in 6.x to continue using the defaults
systemProperty 'es.scripting.use_java_time', 'false'
systemProperty 'es.scripting.update.ctx_in_params', 'false'
//TODO: remove this once the cname is prepended to the address by default in 7.0
systemProperty 'es.http.cname_in_publish_address', 'true'
}
// remove when https://github.com/elastic/elasticsearch/issues/31305 is fixed

View File

@ -26,6 +26,7 @@ integTestCluster {
module project.project(':modules:mapper-extras')
systemProperty 'es.scripting.use_java_time', 'true'
systemProperty 'es.scripting.update.ctx_in_params', 'false'
systemProperty 'es.http.cname_in_publish_address', 'true'
}
dependencies {

View File

@ -19,24 +19,46 @@
package org.elasticsearch.http;
import org.apache.logging.log4j.LogManager;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.network.InetAddresses;
import org.elasticsearch.common.transport.BoundTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.xcontent.ToXContentFragment;
import org.elasticsearch.common.xcontent.XContentBuilder;
import java.io.IOException;
import static org.elasticsearch.common.Booleans.parseBoolean;
public class HttpInfo implements Writeable, ToXContentFragment {
private static final DeprecationLogger DEPRECATION_LOGGER = new DeprecationLogger(LogManager.getLogger(HttpInfo.class));
/** Whether to add hostname to publish host field when serializing. */
private static final boolean CNAME_IN_PUBLISH_HOST =
parseBoolean(System.getProperty("es.http.cname_in_publish_address"), false);
private final BoundTransportAddress address;
private final long maxContentLength;
private final boolean cnameInPublishHost;
public HttpInfo(StreamInput in) throws IOException {
address = BoundTransportAddress.readBoundTransportAddress(in);
maxContentLength = in.readLong();
this(BoundTransportAddress.readBoundTransportAddress(in), in.readLong(), CNAME_IN_PUBLISH_HOST);
}
public HttpInfo(BoundTransportAddress address, long maxContentLength) {
this(address, maxContentLength, CNAME_IN_PUBLISH_HOST);
}
HttpInfo(BoundTransportAddress address, long maxContentLength, boolean cnameInPublishHost) {
this.address = address;
this.maxContentLength = maxContentLength;
this.cnameInPublishHost = cnameInPublishHost;
}
@Override
@ -45,11 +67,6 @@ public class HttpInfo implements Writeable, ToXContentFragment {
out.writeLong(maxContentLength);
}
public HttpInfo(BoundTransportAddress address, long maxContentLength) {
this.address = address;
this.maxContentLength = maxContentLength;
}
static final class Fields {
static final String HTTP = "http";
static final String BOUND_ADDRESS = "bound_address";
@ -62,7 +79,21 @@ public class HttpInfo implements Writeable, ToXContentFragment {
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(Fields.HTTP);
builder.array(Fields.BOUND_ADDRESS, (Object[]) address.boundAddresses());
builder.field(Fields.PUBLISH_ADDRESS, address.publishAddress().toString());
TransportAddress publishAddress = address.publishAddress();
String publishAddressString = publishAddress.toString();
String hostString = publishAddress.address().getHostString();
if (InetAddresses.isInetAddress(hostString) == false) {
if (cnameInPublishHost) {
publishAddressString = hostString + '/' + publishAddress.toString();
} else {
DEPRECATION_LOGGER.deprecated(
"[http.publish_host] was printed as [ip:port] instead of [hostname/ip:port]. "
+ "This format is deprecated and will change to [hostname/ip:port] in a future version. "
+ "Use -Des.http.cname_in_publish_address=true to enforce non-deprecated formatting."
);
}
}
builder.field(Fields.PUBLISH_ADDRESS, publishAddressString);
builder.humanReadableField(Fields.MAX_CONTENT_LENGTH_IN_BYTES, Fields.MAX_CONTENT_LENGTH, maxContentLength());
builder.endObject();
return builder;

View File

@ -0,0 +1,97 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.http;
import java.io.IOException;
import java.net.InetAddress;
import java.util.Map;
import org.elasticsearch.common.network.NetworkAddress;
import org.elasticsearch.common.transport.BoundTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.test.ESTestCase;
public class HttpInfoTests extends ESTestCase {
public void testCorrectlyDisplayPublishedCname() throws Exception {
InetAddress localhost = InetAddress.getByName("localhost");
int port = 9200;
assertPublishAddress(
new HttpInfo(
new BoundTransportAddress(
new TransportAddress[]{new TransportAddress(localhost, port)},
new TransportAddress(localhost, port)
), 0L, true
), "localhost/" + NetworkAddress.format(localhost) + ':' + port
);
}
public void hideCnameIfDeprecatedFormat() throws Exception {
InetAddress localhost = InetAddress.getByName("localhost");
int port = 9200;
assertPublishAddress(
new HttpInfo(
new BoundTransportAddress(
new TransportAddress[]{new TransportAddress(localhost, port)},
new TransportAddress(localhost, port)
), 0L, false
), NetworkAddress.format(localhost) + ':' + port
);
}
public void testCorrectDisplayPublishedIp() throws Exception {
InetAddress localhost = InetAddress.getByName(NetworkAddress.format(InetAddress.getByName("localhost")));
int port = 9200;
assertPublishAddress(
new HttpInfo(
new BoundTransportAddress(
new TransportAddress[]{new TransportAddress(localhost, port)},
new TransportAddress(localhost, port)
), 0L, true
), NetworkAddress.format(localhost) + ':' + port
);
}
public void testCorrectDisplayPublishedIpv6() throws Exception {
int port = 9200;
TransportAddress localhost =
new TransportAddress(InetAddress.getByName(NetworkAddress.format(InetAddress.getByName("0:0:0:0:0:0:0:1"))), port);
assertPublishAddress(
new HttpInfo(
new BoundTransportAddress(new TransportAddress[]{localhost}, localhost), 0L, true
), localhost.toString()
);
}
@SuppressWarnings("unchecked")
private void assertPublishAddress(HttpInfo httpInfo, String expected) throws IOException {
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
httpInfo.toXContent(builder, ToXContent.EMPTY_PARAMS);
builder.endObject();
assertEquals(
expected,
((Map<String, Object>) createParser(builder).map().get(HttpInfo.Fields.HTTP))
.get(HttpInfo.Fields.PUBLISH_ADDRESS)
);
}
}