Allow `_gce_` network when not using discovery gce
For now we support `_gce_` only if discovery is set to `gce` and all information about GCE is provided (project_id and zone). But in some cases, people would like to only bind to `_gce_` on a single node (without any elasticsearch cluster). They could access the machine then from other machines running inside the same project. This commit adds a new GceMetadataService which is started as soon as the plugin is started so GceNameResolver can use it to resolve `_gce`. Closes #15724.
This commit is contained in:
parent
2232a7cdf3
commit
c16d309c8c
|
@ -76,19 +76,4 @@ public interface GceComputeService extends LifecycleComponent<GceComputeService>
|
||||||
* @return a collection of running instances within the same GCE project
|
* @return a collection of running instances within the same GCE project
|
||||||
*/
|
*/
|
||||||
Collection<Instance> instances();
|
Collection<Instance> instances();
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>Gets metadata on the current running machine (call to
|
|
||||||
* http://metadata.google.internal/computeMetadata/v1/instance/xxx).</p>
|
|
||||||
* <p>For example, you can retrieve network information by replacing xxx with:</p>
|
|
||||||
* <ul>
|
|
||||||
* <li>`hostname` when we need to resolve the host name</li>
|
|
||||||
* <li>`network-interfaces/0/ip` when we need to resolve private IP</li>
|
|
||||||
* </ul>
|
|
||||||
* @see org.elasticsearch.cloud.gce.network.GceNameResolver for bindings
|
|
||||||
* @param metadataPath path to metadata information
|
|
||||||
* @return extracted information (for example a hostname or an IP address)
|
|
||||||
* @throws IOException in case metadata URL is not accessible
|
|
||||||
*/
|
|
||||||
String metadata(String metadataPath) throws IOException;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,47 +116,6 @@ public class GceComputeServiceImpl extends AbstractLifecycleComponent<GceCompute
|
||||||
return instances;
|
return instances;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String metadata(String metadataPath) throws IOException {
|
|
||||||
String urlMetadataNetwork = this.metaDataUrl + "/" + metadataPath;
|
|
||||||
logger.debug("get metadata from [{}]", urlMetadataNetwork);
|
|
||||||
final URL url = new URL(urlMetadataNetwork);
|
|
||||||
HttpHeaders headers;
|
|
||||||
try {
|
|
||||||
// hack around code messiness in GCE code
|
|
||||||
// TODO: get this fixed
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
sm.checkPermission(new SpecialPermission());
|
|
||||||
}
|
|
||||||
headers = AccessController.doPrivileged(new PrivilegedExceptionAction<HttpHeaders>() {
|
|
||||||
@Override
|
|
||||||
public HttpHeaders run() throws IOException {
|
|
||||||
return new HttpHeaders();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
GenericUrl genericUrl = AccessController.doPrivileged(new PrivilegedAction<GenericUrl>() {
|
|
||||||
@Override
|
|
||||||
public GenericUrl run() {
|
|
||||||
return new GenericUrl(url);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// This is needed to query meta data: https://cloud.google.com/compute/docs/metadata
|
|
||||||
headers.put("Metadata-Flavor", "Google");
|
|
||||||
HttpResponse response;
|
|
||||||
response = getGceHttpTransport().createRequestFactory()
|
|
||||||
.buildGetRequest(genericUrl)
|
|
||||||
.setHeaders(headers)
|
|
||||||
.execute();
|
|
||||||
String metadata = response.parseAsString();
|
|
||||||
logger.debug("metadata found [{}]", metadata);
|
|
||||||
return metadata;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new IOException("failed to fetch metadata from [" + urlMetadataNetwork + "]", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Compute client;
|
private Compute client;
|
||||||
private TimeValue refreshInterval = null;
|
private TimeValue refreshInterval = null;
|
||||||
private long lastRefresh;
|
private long lastRefresh;
|
||||||
|
@ -168,17 +127,17 @@ public class GceComputeServiceImpl extends AbstractLifecycleComponent<GceCompute
|
||||||
private JsonFactory gceJsonFactory;
|
private JsonFactory gceJsonFactory;
|
||||||
|
|
||||||
private final boolean validateCerts;
|
private final boolean validateCerts;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public GceComputeServiceImpl(Settings settings, NetworkService networkService) {
|
public GceComputeServiceImpl(Settings settings) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.project = PROJECT_SETTING.get(settings);
|
this.project = PROJECT_SETTING.get(settings);
|
||||||
this.zones = ZONE_SETTING.get(settings);
|
this.zones = ZONE_SETTING.get(settings);
|
||||||
this.gceHost = GCE_HOST.get(settings);
|
this.gceHost = GCE_HOST.get(settings);
|
||||||
this.metaDataUrl = gceHost + "/computeMetadata/v1/instance";
|
this.metaDataUrl = gceHost + "/computeMetadata/v1/instance";
|
||||||
this.gceRootUrl = GCE_ROOT_URL.get(settings);
|
this.gceRootUrl = GCE_ROOT_URL.get(settings);
|
||||||
tokenServerEncodedUrl = metaDataUrl + "/service-accounts/default/token";
|
this.tokenServerEncodedUrl = metaDataUrl + "/service-accounts/default/token";
|
||||||
this.validateCerts = GCE_VALIDATE_CERTIFICATES.get(settings);
|
this.validateCerts = GCE_VALIDATE_CERTIFICATES.get(settings);
|
||||||
networkService.addCustomNameResolver(new GceNameResolver(settings, this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected synchronized HttpTransport getGceHttpTransport() throws GeneralSecurityException, IOException {
|
protected synchronized HttpTransport getGceHttpTransport() throws GeneralSecurityException, IOException {
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* 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.cloud.gce;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.component.LifecycleComponent;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access Google Compute Engine metadata
|
||||||
|
*/
|
||||||
|
public interface GceMetadataService extends LifecycleComponent<GceMetadataService> {
|
||||||
|
/**
|
||||||
|
* <p>Gets metadata on the current running machine (call to
|
||||||
|
* http://metadata.google.internal/computeMetadata/v1/instance/xxx).</p>
|
||||||
|
* <p>For example, you can retrieve network information by replacing xxx with:</p>
|
||||||
|
* <ul>
|
||||||
|
* <li>`hostname` when we need to resolve the host name</li>
|
||||||
|
* <li>`network-interfaces/0/ip` when we need to resolve private IP</li>
|
||||||
|
* </ul>
|
||||||
|
* @see org.elasticsearch.cloud.gce.network.GceNameResolver for bindings
|
||||||
|
* @param metadataPath path to metadata information
|
||||||
|
* @return extracted information (for example a hostname or an IP address)
|
||||||
|
* @throws IOException in case metadata URL is not accessible
|
||||||
|
*/
|
||||||
|
String metadata(String metadataPath) throws IOException;
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* 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.cloud.gce;
|
||||||
|
|
||||||
|
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
|
||||||
|
import com.google.api.client.http.GenericUrl;
|
||||||
|
import com.google.api.client.http.HttpHeaders;
|
||||||
|
import com.google.api.client.http.HttpResponse;
|
||||||
|
import com.google.api.client.http.HttpTransport;
|
||||||
|
import com.google.api.client.json.JsonFactory;
|
||||||
|
import org.elasticsearch.SpecialPermission;
|
||||||
|
import org.elasticsearch.cloud.gce.network.GceNameResolver;
|
||||||
|
import org.elasticsearch.common.component.AbstractLifecycleComponent;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.network.NetworkService;
|
||||||
|
import org.elasticsearch.common.settings.Setting;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.security.AccessController;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.security.PrivilegedAction;
|
||||||
|
import java.security.PrivilegedExceptionAction;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class GceMetadataServiceImpl extends AbstractLifecycleComponent<GceMetadataService> implements GceMetadataService {
|
||||||
|
|
||||||
|
// Forcing Google Token API URL as set in GCE SDK to
|
||||||
|
// http://metadata/computeMetadata/v1/instance/service-accounts/default/token
|
||||||
|
// See https://developers.google.com/compute/docs/metadata#metadataserver
|
||||||
|
// all settings just used for testing - not registered by default
|
||||||
|
public static final Setting<String> GCE_HOST =
|
||||||
|
new Setting<>("cloud.gce.host", "http://metadata.google.internal", Function.identity(), Setting.Property.NodeScope);
|
||||||
|
|
||||||
|
/** Global instance of the HTTP transport. */
|
||||||
|
private HttpTransport gceHttpTransport;
|
||||||
|
|
||||||
|
// Forcing Google Token API URL as set in GCE SDK to
|
||||||
|
// http://metadata/computeMetadata/v1/instance/service-accounts/default/token
|
||||||
|
// See https://developers.google.com/compute/docs/metadata#metadataserver
|
||||||
|
private final String gceHost;
|
||||||
|
private final String metaDataUrl;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public GceMetadataServiceImpl(Settings settings, NetworkService networkService) {
|
||||||
|
super(settings);
|
||||||
|
networkService.addCustomNameResolver(new GceNameResolver(settings, this));
|
||||||
|
this.gceHost = GCE_HOST.get(settings);
|
||||||
|
this.metaDataUrl = gceHost + "/computeMetadata/v1/instance";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected synchronized HttpTransport getGceHttpTransport() throws GeneralSecurityException, IOException {
|
||||||
|
if (gceHttpTransport == null) {
|
||||||
|
gceHttpTransport = GoogleNetHttpTransport.newTrustedTransport();
|
||||||
|
}
|
||||||
|
return gceHttpTransport;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String metadata(String metadataPath) throws IOException {
|
||||||
|
String urlMetadataNetwork = this.metaDataUrl + "/" + metadataPath;
|
||||||
|
logger.debug("get metadata from [{}]", urlMetadataNetwork);
|
||||||
|
final URL url = new URL(urlMetadataNetwork);
|
||||||
|
HttpHeaders headers;
|
||||||
|
try {
|
||||||
|
// hack around code messiness in GCE code
|
||||||
|
// TODO: get this fixed
|
||||||
|
SecurityManager sm = System.getSecurityManager();
|
||||||
|
if (sm != null) {
|
||||||
|
sm.checkPermission(new SpecialPermission());
|
||||||
|
}
|
||||||
|
headers = AccessController.doPrivileged(new PrivilegedExceptionAction<HttpHeaders>() {
|
||||||
|
@Override
|
||||||
|
public HttpHeaders run() throws IOException {
|
||||||
|
return new HttpHeaders();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
GenericUrl genericUrl = AccessController.doPrivileged(new PrivilegedAction<GenericUrl>() {
|
||||||
|
@Override
|
||||||
|
public GenericUrl run() {
|
||||||
|
return new GenericUrl(url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// This is needed to query meta data: https://cloud.google.com/compute/docs/metadata
|
||||||
|
headers.put("Metadata-Flavor", "Google");
|
||||||
|
HttpResponse response;
|
||||||
|
response = getGceHttpTransport().createRequestFactory()
|
||||||
|
.buildGetRequest(genericUrl)
|
||||||
|
.setHeaders(headers)
|
||||||
|
.execute();
|
||||||
|
String metadata = response.parseAsString();
|
||||||
|
logger.debug("metadata found [{}]", metadata);
|
||||||
|
return metadata;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException("failed to fetch metadata from [" + urlMetadataNetwork + "]", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doStart() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doStop() {
|
||||||
|
if (gceHttpTransport != null) {
|
||||||
|
try {
|
||||||
|
gceHttpTransport.shutdown();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.warn("unable to shutdown GCE Http Transport", e);
|
||||||
|
}
|
||||||
|
gceHttpTransport = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doClose() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,17 +20,34 @@
|
||||||
package org.elasticsearch.cloud.gce;
|
package org.elasticsearch.cloud.gce;
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
import org.elasticsearch.common.inject.AbstractModule;
|
||||||
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
|
||||||
public class GceModule extends AbstractModule {
|
public class GceModule extends AbstractModule {
|
||||||
// pkg private so tests can override with mock
|
// pkg private so tests can override with mock
|
||||||
static Class<? extends GceComputeService> computeServiceImpl = GceComputeServiceImpl.class;
|
static Class<? extends GceComputeService> computeServiceImpl = GceComputeServiceImpl.class;
|
||||||
|
static Class<? extends GceMetadataService> metadataServiceImpl = GceMetadataServiceImpl.class;
|
||||||
|
|
||||||
|
protected final Settings settings;
|
||||||
|
protected final ESLogger logger = Loggers.getLogger(GceModule.class);
|
||||||
|
|
||||||
|
public GceModule(Settings settings) {
|
||||||
|
this.settings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
public static Class<? extends GceComputeService> getComputeServiceImpl() {
|
public static Class<? extends GceComputeService> getComputeServiceImpl() {
|
||||||
return computeServiceImpl;
|
return computeServiceImpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Class<? extends GceMetadataService> getMetadataServiceImpl() {
|
||||||
|
return metadataServiceImpl;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
|
logger.debug("configure GceModule (bind compute and metadata services)");
|
||||||
bind(GceComputeService.class).to(computeServiceImpl).asEagerSingleton();
|
bind(GceComputeService.class).to(computeServiceImpl).asEagerSingleton();
|
||||||
|
bind(GceMetadataService.class).to(metadataServiceImpl).asEagerSingleton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.elasticsearch.cloud.gce.network;
|
package org.elasticsearch.cloud.gce.network;
|
||||||
|
|
||||||
import org.elasticsearch.cloud.gce.GceComputeService;
|
import org.elasticsearch.cloud.gce.GceComputeService;
|
||||||
|
import org.elasticsearch.cloud.gce.GceMetadataService;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
import org.elasticsearch.common.component.AbstractComponent;
|
||||||
import org.elasticsearch.common.network.NetworkService.CustomNameResolver;
|
import org.elasticsearch.common.network.NetworkService.CustomNameResolver;
|
||||||
|
@ -40,7 +41,7 @@ import java.net.InetAddress;
|
||||||
*/
|
*/
|
||||||
public class GceNameResolver extends AbstractComponent implements CustomNameResolver {
|
public class GceNameResolver extends AbstractComponent implements CustomNameResolver {
|
||||||
|
|
||||||
private final GceComputeService gceComputeService;
|
private final GceMetadataService gceMetadataService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum that can be added to over time with more meta-data types
|
* enum that can be added to over time with more meta-data types
|
||||||
|
@ -72,9 +73,9 @@ public class GceNameResolver extends AbstractComponent implements CustomNameReso
|
||||||
/**
|
/**
|
||||||
* Construct a {@link CustomNameResolver}.
|
* Construct a {@link CustomNameResolver}.
|
||||||
*/
|
*/
|
||||||
public GceNameResolver(Settings settings, GceComputeService gceComputeService) {
|
public GceNameResolver(Settings settings, GceMetadataService gceMetadataService) {
|
||||||
super(settings);
|
super(settings);
|
||||||
this.gceComputeService = gceComputeService;
|
this.gceMetadataService = gceMetadataService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -105,7 +106,7 @@ public class GceNameResolver extends AbstractComponent implements CustomNameReso
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String metadataResult = gceComputeService.metadata(gceMetadataPath);
|
String metadataResult = gceMetadataService.metadata(gceMetadataPath);
|
||||||
if (metadataResult == null || metadataResult.length() == 0) {
|
if (metadataResult == null || metadataResult.length() == 0) {
|
||||||
throw new IOException("no gce metadata returned from [" + gceMetadataPath + "] for [" + value + "]");
|
throw new IOException("no gce metadata returned from [" + gceMetadataPath + "] for [" + value + "]");
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.elasticsearch.plugins.Plugin;
|
||||||
|
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
|
@ -85,22 +86,27 @@ public class GceDiscoveryPlugin extends Plugin {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<Module> nodeModules() {
|
public Collection<Module> nodeModules() {
|
||||||
return Collections.singletonList(new GceModule());
|
return Collections.singletonList(new GceModule(settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("rawtypes") // Supertype uses raw type
|
@SuppressWarnings("rawtypes") // Supertype uses raw type
|
||||||
public Collection<Class<? extends LifecycleComponent>> nodeServices() {
|
public Collection<Class<? extends LifecycleComponent>> nodeServices() {
|
||||||
return Collections.singletonList(GceModule.getComputeServiceImpl());
|
logger.debug("Register gce compute and metadata services");
|
||||||
|
Collection<Class<? extends LifecycleComponent>> services = new ArrayList<>();
|
||||||
|
services.add(GceModule.getComputeServiceImpl());
|
||||||
|
services.add(GceModule.getMetadataServiceImpl());
|
||||||
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onModule(DiscoveryModule discoveryModule) {
|
public void onModule(DiscoveryModule discoveryModule) {
|
||||||
|
logger.debug("Register gce discovery type and gce unicast provider");
|
||||||
discoveryModule.addDiscoveryType(GCE, ZenDiscovery.class);
|
discoveryModule.addDiscoveryType(GCE, ZenDiscovery.class);
|
||||||
// If discovery.type: gce, we add Gce as a unicast provider
|
|
||||||
discoveryModule.addUnicastHostProvider(GCE, GceUnicastHostsProvider.class);
|
discoveryModule.addUnicastHostProvider(GCE, GceUnicastHostsProvider.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onModule(SettingsModule settingsModule) {
|
public void onModule(SettingsModule settingsModule) {
|
||||||
|
logger.debug("registering GCE Settings");
|
||||||
// Register GCE settings
|
// Register GCE settings
|
||||||
settingsModule.registerSetting(GceComputeService.PROJECT_SETTING);
|
settingsModule.registerSetting(GceComputeService.PROJECT_SETTING);
|
||||||
settingsModule.registerSetting(GceComputeService.ZONE_SETTING);
|
settingsModule.registerSetting(GceComputeService.ZONE_SETTING);
|
||||||
|
|
|
@ -45,69 +45,13 @@ public class GceComputeServiceMock extends GceComputeServiceImpl {
|
||||||
|
|
||||||
protected HttpTransport mockHttpTransport;
|
protected HttpTransport mockHttpTransport;
|
||||||
|
|
||||||
public GceComputeServiceMock(Settings settings, NetworkService networkService) {
|
public GceComputeServiceMock(Settings settings) {
|
||||||
super(settings, networkService);
|
super(settings);
|
||||||
this.mockHttpTransport = configureMock();
|
this.mockHttpTransport = GceMockUtils.configureMock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected HttpTransport getGceHttpTransport() throws GeneralSecurityException, IOException {
|
protected HttpTransport getGceHttpTransport() throws GeneralSecurityException, IOException {
|
||||||
return this.mockHttpTransport;
|
return this.mockHttpTransport;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String GCE_METADATA_URL = "http://metadata.google.internal/computeMetadata/v1/instance";
|
|
||||||
|
|
||||||
protected HttpTransport configureMock() {
|
|
||||||
return new MockHttpTransport() {
|
|
||||||
@Override
|
|
||||||
public LowLevelHttpRequest buildRequest(String method, final String url) throws IOException {
|
|
||||||
return new MockLowLevelHttpRequest() {
|
|
||||||
@Override
|
|
||||||
public LowLevelHttpResponse execute() throws IOException {
|
|
||||||
MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
|
|
||||||
response.setStatusCode(200);
|
|
||||||
response.setContentType(Json.MEDIA_TYPE);
|
|
||||||
if (url.startsWith(GCE_METADATA_URL)) {
|
|
||||||
logger.info("--> Simulate GCE Auth/Metadata response for [{}]", url);
|
|
||||||
response.setContent(readGoogleInternalJsonResponse(url));
|
|
||||||
} else {
|
|
||||||
logger.info("--> Simulate GCE API response for [{}]", url);
|
|
||||||
response.setContent(readGoogleApiJsonResponse(url));
|
|
||||||
}
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String readGoogleInternalJsonResponse(String url) throws IOException {
|
|
||||||
return readJsonResponse(url, "http://metadata.google.internal/");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String readGoogleApiJsonResponse(String url) throws IOException {
|
|
||||||
return readJsonResponse(url, "https://www.googleapis.com/");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String readJsonResponse(String url, String urlRoot) throws IOException {
|
|
||||||
// We extract from the url the mock file path we want to use
|
|
||||||
String mockFileName = Strings.replace(url, urlRoot, "");
|
|
||||||
|
|
||||||
URL resource = GceComputeServiceMock.class.getResource(mockFileName);
|
|
||||||
if (resource == null) {
|
|
||||||
throw new IOException("can't read [" + url + "] in src/test/resources/org/elasticsearch/discovery/gce");
|
|
||||||
}
|
|
||||||
try (InputStream is = resource.openStream()) {
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
Streams.readAllLines(is, new Callback<String>() {
|
|
||||||
@Override
|
|
||||||
public void handle(String s) {
|
|
||||||
sb.append(s);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
String response = sb.toString();
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ public class GceDiscoverTests extends ESIntegTestCase {
|
||||||
httpServer = HttpServer.create(new InetSocketAddress(InetAddress.getLoopbackAddress().getHostAddress(), 0), 0);
|
httpServer = HttpServer.create(new InetSocketAddress(InetAddress.getLoopbackAddress().getHostAddress(), 0), 0);
|
||||||
httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext));
|
httpsServer.setHttpsConfigurator(new HttpsConfigurator(sslContext));
|
||||||
httpServer.createContext("/computeMetadata/v1/instance/service-accounts/default/token", (s) -> {
|
httpServer.createContext("/computeMetadata/v1/instance/service-accounts/default/token", (s) -> {
|
||||||
String response = GceComputeServiceMock.readGoogleInternalJsonResponse(
|
String response = GceMockUtils.readGoogleInternalJsonResponse(
|
||||||
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token");
|
"http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token");
|
||||||
byte[] responseAsBytes = response.getBytes(StandardCharsets.UTF_8);
|
byte[] responseAsBytes = response.getBytes(StandardCharsets.UTF_8);
|
||||||
s.sendResponseHeaders(200, responseAsBytes.length);
|
s.sendResponseHeaders(200, responseAsBytes.length);
|
||||||
|
|
|
@ -65,7 +65,6 @@ public class GceDiscoveryTests extends ESTestCase {
|
||||||
|
|
||||||
protected static ThreadPool threadPool;
|
protected static ThreadPool threadPool;
|
||||||
protected MockTransportService transportService;
|
protected MockTransportService transportService;
|
||||||
protected NetworkService networkService;
|
|
||||||
protected GceComputeService mock;
|
protected GceComputeService mock;
|
||||||
protected String projectName;
|
protected String projectName;
|
||||||
|
|
||||||
|
@ -96,11 +95,6 @@ public class GceDiscoveryTests extends ESTestCase {
|
||||||
transportService = MockTransportService.local(Settings.EMPTY, Version.CURRENT, threadPool);
|
transportService = MockTransportService.local(Settings.EMPTY, Version.CURRENT, threadPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
|
||||||
public void createNetworkService() {
|
|
||||||
networkService = new NetworkService(Settings.EMPTY);
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void stopGceComputeService() {
|
public void stopGceComputeService() {
|
||||||
if (mock != null) {
|
if (mock != null) {
|
||||||
|
@ -122,7 +116,7 @@ public class GceDiscoveryTests extends ESTestCase {
|
||||||
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
|
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
|
||||||
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
|
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
|
||||||
.build();
|
.build();
|
||||||
mock = new GceComputeServiceMock(nodeSettings, networkService);
|
mock = new GceComputeServiceMock(nodeSettings);
|
||||||
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
||||||
assertThat(discoveryNodes, hasSize(2));
|
assertThat(discoveryNodes, hasSize(2));
|
||||||
}
|
}
|
||||||
|
@ -133,7 +127,7 @@ public class GceDiscoveryTests extends ESTestCase {
|
||||||
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
|
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
|
||||||
.putArray(GceUnicastHostsProvider.TAGS_SETTING.getKey(), "elasticsearch")
|
.putArray(GceUnicastHostsProvider.TAGS_SETTING.getKey(), "elasticsearch")
|
||||||
.build();
|
.build();
|
||||||
mock = new GceComputeServiceMock(nodeSettings, networkService);
|
mock = new GceComputeServiceMock(nodeSettings);
|
||||||
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
||||||
assertThat(discoveryNodes, hasSize(1));
|
assertThat(discoveryNodes, hasSize(1));
|
||||||
assertThat(discoveryNodes.get(0).getId(), is("#cloud-test2-0"));
|
assertThat(discoveryNodes.get(0).getId(), is("#cloud-test2-0"));
|
||||||
|
@ -145,7 +139,7 @@ public class GceDiscoveryTests extends ESTestCase {
|
||||||
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
|
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
|
||||||
.putArray(GceUnicastHostsProvider.TAGS_SETTING.getKey(), "elasticsearch", "dev")
|
.putArray(GceUnicastHostsProvider.TAGS_SETTING.getKey(), "elasticsearch", "dev")
|
||||||
.build();
|
.build();
|
||||||
mock = new GceComputeServiceMock(nodeSettings, networkService);
|
mock = new GceComputeServiceMock(nodeSettings);
|
||||||
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
||||||
assertThat(discoveryNodes, hasSize(1));
|
assertThat(discoveryNodes, hasSize(1));
|
||||||
assertThat(discoveryNodes.get(0).getId(), is("#cloud-test2-0"));
|
assertThat(discoveryNodes.get(0).getId(), is("#cloud-test2-0"));
|
||||||
|
@ -156,7 +150,7 @@ public class GceDiscoveryTests extends ESTestCase {
|
||||||
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
|
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
|
||||||
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
|
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
|
||||||
.build();
|
.build();
|
||||||
mock = new GceComputeServiceMock(nodeSettings, networkService);
|
mock = new GceComputeServiceMock(nodeSettings);
|
||||||
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
||||||
assertThat(discoveryNodes, hasSize(2));
|
assertThat(discoveryNodes, hasSize(2));
|
||||||
}
|
}
|
||||||
|
@ -167,7 +161,7 @@ public class GceDiscoveryTests extends ESTestCase {
|
||||||
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
|
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
|
||||||
.putArray(GceUnicastHostsProvider.TAGS_SETTING.getKey(), "elasticsearch")
|
.putArray(GceUnicastHostsProvider.TAGS_SETTING.getKey(), "elasticsearch")
|
||||||
.build();
|
.build();
|
||||||
mock = new GceComputeServiceMock(nodeSettings, networkService);
|
mock = new GceComputeServiceMock(nodeSettings);
|
||||||
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
||||||
assertThat(discoveryNodes, hasSize(2));
|
assertThat(discoveryNodes, hasSize(2));
|
||||||
}
|
}
|
||||||
|
@ -178,7 +172,7 @@ public class GceDiscoveryTests extends ESTestCase {
|
||||||
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
|
.put(GceComputeService.ZONE_SETTING.getKey(), "europe-west1-b")
|
||||||
.putArray(GceUnicastHostsProvider.TAGS_SETTING.getKey(), "elasticsearch", "dev")
|
.putArray(GceUnicastHostsProvider.TAGS_SETTING.getKey(), "elasticsearch", "dev")
|
||||||
.build();
|
.build();
|
||||||
mock = new GceComputeServiceMock(nodeSettings, networkService);
|
mock = new GceComputeServiceMock(nodeSettings);
|
||||||
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
||||||
assertThat(discoveryNodes, hasSize(2));
|
assertThat(discoveryNodes, hasSize(2));
|
||||||
}
|
}
|
||||||
|
@ -188,7 +182,7 @@ public class GceDiscoveryTests extends ESTestCase {
|
||||||
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
|
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
|
||||||
.putArray(GceComputeService.ZONE_SETTING.getKey(), "us-central1-a", "europe-west1-b")
|
.putArray(GceComputeService.ZONE_SETTING.getKey(), "us-central1-a", "europe-west1-b")
|
||||||
.build();
|
.build();
|
||||||
mock = new GceComputeServiceMock(nodeSettings, networkService);
|
mock = new GceComputeServiceMock(nodeSettings);
|
||||||
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
||||||
assertThat(discoveryNodes, hasSize(2));
|
assertThat(discoveryNodes, hasSize(2));
|
||||||
}
|
}
|
||||||
|
@ -198,7 +192,7 @@ public class GceDiscoveryTests extends ESTestCase {
|
||||||
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
|
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
|
||||||
.putArray(GceComputeService.ZONE_SETTING.getKey(), "us-central1-a", "europe-west1-b")
|
.putArray(GceComputeService.ZONE_SETTING.getKey(), "us-central1-a", "europe-west1-b")
|
||||||
.build();
|
.build();
|
||||||
mock = new GceComputeServiceMock(nodeSettings, networkService);
|
mock = new GceComputeServiceMock(nodeSettings);
|
||||||
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
||||||
assertThat(discoveryNodes, hasSize(2));
|
assertThat(discoveryNodes, hasSize(2));
|
||||||
}
|
}
|
||||||
|
@ -211,14 +205,14 @@ public class GceDiscoveryTests extends ESTestCase {
|
||||||
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
|
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
|
||||||
.putArray(GceComputeService.ZONE_SETTING.getKey(), "us-central1-a", "us-central1-b")
|
.putArray(GceComputeService.ZONE_SETTING.getKey(), "us-central1-a", "us-central1-b")
|
||||||
.build();
|
.build();
|
||||||
mock = new GceComputeServiceMock(nodeSettings, networkService);
|
mock = new GceComputeServiceMock(nodeSettings);
|
||||||
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
List<DiscoveryNode> discoveryNodes = buildDynamicNodes(mock, nodeSettings);
|
||||||
assertThat(discoveryNodes, hasSize(0));
|
assertThat(discoveryNodes, hasSize(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIllegalSettingsMissingAllRequired() {
|
public void testIllegalSettingsMissingAllRequired() {
|
||||||
Settings nodeSettings = Settings.EMPTY;
|
Settings nodeSettings = Settings.EMPTY;
|
||||||
mock = new GceComputeServiceMock(Settings.EMPTY, networkService);
|
mock = new GceComputeServiceMock(nodeSettings);
|
||||||
try {
|
try {
|
||||||
buildDynamicNodes(mock, nodeSettings);
|
buildDynamicNodes(mock, nodeSettings);
|
||||||
fail("We expect an IllegalArgumentException for incomplete settings");
|
fail("We expect an IllegalArgumentException for incomplete settings");
|
||||||
|
@ -231,7 +225,7 @@ public class GceDiscoveryTests extends ESTestCase {
|
||||||
Settings nodeSettings = Settings.builder()
|
Settings nodeSettings = Settings.builder()
|
||||||
.putArray(GceComputeService.ZONE_SETTING.getKey(), "us-central1-a", "us-central1-b")
|
.putArray(GceComputeService.ZONE_SETTING.getKey(), "us-central1-a", "us-central1-b")
|
||||||
.build();
|
.build();
|
||||||
mock = new GceComputeServiceMock(nodeSettings, networkService);
|
mock = new GceComputeServiceMock(nodeSettings);
|
||||||
try {
|
try {
|
||||||
buildDynamicNodes(mock, nodeSettings);
|
buildDynamicNodes(mock, nodeSettings);
|
||||||
fail("We expect an IllegalArgumentException for incomplete settings");
|
fail("We expect an IllegalArgumentException for incomplete settings");
|
||||||
|
@ -244,7 +238,7 @@ public class GceDiscoveryTests extends ESTestCase {
|
||||||
Settings nodeSettings = Settings.builder()
|
Settings nodeSettings = Settings.builder()
|
||||||
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
|
.put(GceComputeService.PROJECT_SETTING.getKey(), projectName)
|
||||||
.build();
|
.build();
|
||||||
mock = new GceComputeServiceMock(nodeSettings, networkService);
|
mock = new GceComputeServiceMock(nodeSettings);
|
||||||
try {
|
try {
|
||||||
buildDynamicNodes(mock, nodeSettings);
|
buildDynamicNodes(mock, nodeSettings);
|
||||||
fail("We expect an IllegalArgumentException for incomplete settings");
|
fail("We expect an IllegalArgumentException for incomplete settings");
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* 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.discovery.gce;
|
||||||
|
|
||||||
|
import com.google.api.client.http.HttpTransport;
|
||||||
|
import org.elasticsearch.cloud.gce.GceComputeServiceImpl;
|
||||||
|
import org.elasticsearch.cloud.gce.GceMetadataServiceImpl;
|
||||||
|
import org.elasticsearch.common.network.NetworkService;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mock for GCE Metadata Service
|
||||||
|
*/
|
||||||
|
public class GceMetadataServiceMock extends GceMetadataServiceImpl {
|
||||||
|
|
||||||
|
protected HttpTransport mockHttpTransport;
|
||||||
|
|
||||||
|
public GceMetadataServiceMock(Settings settings, NetworkService networkService) {
|
||||||
|
super(settings, networkService);
|
||||||
|
this.mockHttpTransport = GceMockUtils.configureMock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected HttpTransport getGceHttpTransport() throws GeneralSecurityException, IOException {
|
||||||
|
return this.mockHttpTransport;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* 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.discovery.gce;
|
||||||
|
|
||||||
|
import com.google.api.client.http.HttpTransport;
|
||||||
|
import com.google.api.client.http.LowLevelHttpRequest;
|
||||||
|
import com.google.api.client.http.LowLevelHttpResponse;
|
||||||
|
import com.google.api.client.json.Json;
|
||||||
|
import com.google.api.client.testing.http.MockHttpTransport;
|
||||||
|
import com.google.api.client.testing.http.MockLowLevelHttpRequest;
|
||||||
|
import com.google.api.client.testing.http.MockLowLevelHttpResponse;
|
||||||
|
import org.elasticsearch.cloud.gce.GceMetadataServiceImpl;
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
|
import org.elasticsearch.common.io.Streams;
|
||||||
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
|
import org.elasticsearch.common.util.Callback;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
public class GceMockUtils {
|
||||||
|
protected final static ESLogger logger = Loggers.getLogger(GceMockUtils.class);
|
||||||
|
|
||||||
|
public static final String GCE_METADATA_URL = "http://metadata.google.internal/computeMetadata/v1/instance";
|
||||||
|
|
||||||
|
protected static HttpTransport configureMock() {
|
||||||
|
return new MockHttpTransport() {
|
||||||
|
@Override
|
||||||
|
public LowLevelHttpRequest buildRequest(String method, final String url) throws IOException {
|
||||||
|
return new MockLowLevelHttpRequest() {
|
||||||
|
@Override
|
||||||
|
public LowLevelHttpResponse execute() throws IOException {
|
||||||
|
MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
|
||||||
|
response.setStatusCode(200);
|
||||||
|
response.setContentType(Json.MEDIA_TYPE);
|
||||||
|
if (url.startsWith(GCE_METADATA_URL)) {
|
||||||
|
logger.info("--> Simulate GCE Auth/Metadata response for [{}]", url);
|
||||||
|
response.setContent(readGoogleInternalJsonResponse(url));
|
||||||
|
} else {
|
||||||
|
logger.info("--> Simulate GCE API response for [{}]", url);
|
||||||
|
response.setContent(readGoogleApiJsonResponse(url));
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String readGoogleInternalJsonResponse(String url) throws IOException {
|
||||||
|
return readJsonResponse(url, "http://metadata.google.internal/");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String readGoogleApiJsonResponse(String url) throws IOException {
|
||||||
|
return readJsonResponse(url, "https://www.googleapis.com/");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String readJsonResponse(String url, String urlRoot) throws IOException {
|
||||||
|
// We extract from the url the mock file path we want to use
|
||||||
|
String mockFileName = Strings.replace(url, urlRoot, "");
|
||||||
|
|
||||||
|
URL resource = GceComputeServiceMock.class.getResource(mockFileName);
|
||||||
|
if (resource == null) {
|
||||||
|
throw new IOException("can't read [" + url + "] in src/test/resources/org/elasticsearch/discovery/gce");
|
||||||
|
}
|
||||||
|
try (InputStream is = resource.openStream()) {
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
Streams.readAllLines(is, new Callback<String>() {
|
||||||
|
@Override
|
||||||
|
public void handle(String s) {
|
||||||
|
sb.append(s);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
String response = sb.toString();
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -104,7 +104,7 @@ public class GceNetworkTests extends ESTestCase {
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
NetworkService networkService = new NetworkService(nodeSettings);
|
NetworkService networkService = new NetworkService(nodeSettings);
|
||||||
GceComputeServiceMock mock = new GceComputeServiceMock(nodeSettings, networkService);
|
GceMetadataServiceMock mock = new GceMetadataServiceMock(nodeSettings, networkService);
|
||||||
networkService.addCustomNameResolver(new GceNameResolver(nodeSettings, mock));
|
networkService.addCustomNameResolver(new GceNameResolver(nodeSettings, mock));
|
||||||
try {
|
try {
|
||||||
InetAddress[] addresses = networkService.resolveBindHostAddresses(null);
|
InetAddress[] addresses = networkService.resolveBindHostAddresses(null);
|
||||||
|
|
Loading…
Reference in New Issue