DefaultConnectivityResolver extends InitializerPatternForConfigurable implements ConnectivityResolver, EntityInitializer { @Override public ManagementAddressResolveResult resolve( JcloudsLocation location, NodeMetadata node, ConfigBag config, ConnectivityResolverOptions options) { LOG.debug("{} resolving management parameters for {}, node={}, config={}, options={}", new Object[]{this, location, node, config, options}); final Stopwatch timer = Stopwatch.createStarted(); final Entity contextEntity = getContextEntity(config); if (shouldPublishNetworks() && !options.isRebinding() && contextEntity != null) { publishNetworks(node, contextEntity); } HostAndPort hapChoice = null; LoginCredentials credChoice = null; final Iterable<HostAndPort> managementCandidates = getManagementCandidates(location, node, config, options); Iterable<LoginCredentials> credentialCandidates = Collections.emptyList(); if (!Iterables.isEmpty(managementCandidates)) { credentialCandidates = getCredentialCandidates(location, node, options, config); if (shouldCheckCredentials() && options.pollForReachableAddresses()) { for (HostAndPort hap : managementCandidates) { for (LoginCredentials cred : credentialCandidates) { LOG.trace("Testing host={} with credential={}", hap, cred); if (checkCredential(location, hap, cred, config, options.isWindows())) { hapChoice = hap; credChoice = cred; break; } } if (hapChoice != null) break; } } else if (shouldCheckCredentials()) { LOG.debug("{} set on {} but pollForFirstReachableAddress={}", new Object[]{CHECK_CREDENTIALS.getName(), this, options.pollForReachableAddresses()}); } } if (hapChoice == null) { LOG.trace("Choosing first management candidate given node={} and mode={}", node, getNetworkMode()); hapChoice = Iterables.getFirst(managementCandidates, null); } if (hapChoice == null) { LOG.trace("Choosing first address of node={} in mode={}", node, getNetworkMode()); final Iterator<String> hit = getResolvableAddressesWithMode(node).iterator(); if (hit.hasNext()) HostAndPort.fromHost(hit.next()); } if (hapChoice == null) { LOG.error("None of the addresses of node {} are reachable in mode {}", new Object[]{node, getNetworkMode()}); throw new IllegalStateException("Could not determine management address for node: " + node + " in mode: " + getNetworkMode()); } if (credChoice == null) { credChoice = Iterables.getFirst(credentialCandidates, null); if (credChoice == null) { throw new IllegalStateException("No credentials configured for " + location); } } if (contextEntity != null) { contextEntity.sensors().set(Attributes.ADDRESS, hapChoice.getHostText()); } if (!isNetworkModeSet() && !options.isWindows()) { final boolean lookupAwsHostname = Boolean.TRUE.equals(config.get(JcloudsLocationConfig.LOOKUP_AWS_HOSTNAME)); String provider = config.get(JcloudsLocationConfig.CLOUD_PROVIDER); if (provider == null) { provider = location.getProvider(); } if (options.waitForConnectable() && "aws-ec2".equals(provider) && lookupAwsHostname) { try { LOG.debug("Resolving AWS hostname of {}", location); String result = location.getHostnameAws(hapChoice, credChoice, config); hapChoice = HostAndPort.fromParts(result, hapChoice.getPort()); LOG.debug("Resolved AWS hostname of {}: {}", location, result); } catch (Exception e) { LOG.debug("Failed to resolve AWS hostname of " + location, e); } } } ManagementAddressResolveResult result = new ManagementAddressResolveResult(hapChoice, credChoice); LOG.debug("{} resolved management parameters for {} in {}: {}", new Object[]{this, location, Duration.of(timer), result}); return result; } DefaultConnectivityResolver();  DefaultConnectivityResolver(Map<?, ?> params);  DefaultConnectivityResolver(final ConfigBag params); @Override void apply(EntityLocal entity); @Override ManagementAddressResolveResult resolve(
            JcloudsLocation location, NodeMetadata node, ConfigBag config, ConnectivityResolverOptions options); @Override String toString(); static final ConfigKey<NetworkMode> NETWORK_MODE; @Beta
    static final ConfigKey<Boolean> CHECK_CREDENTIALS; static final ConfigKey<Boolean> PUBLISH_NETWORKS; }
@Test public void testRespectsHostAndPortOverride() throws Exception { initNodeCreatorAndJcloudsLocation(newNodeCreator(), ImmutableMap.of()); ConnectivityResolverOptions options = newResolveOptions() .portForwardSshOverride(HostAndPort.fromParts("10.1.1.4", 4361)) .build(); DefaultConnectivityResolver customizer = new DefaultConnectivityResolver(); ConfigBag configBag = jcloudsLocation.config().getBag(); ManagementAddressResolveResult result = customizer.resolve(jcloudsLocation, newNodeMetadata(), configBag, options); assertEquals(result.hostAndPort().getHostText(), "10.1.1.4"); assertEquals(result.hostAndPort().getPort(), 4361); }
@Test public void testObtainsHostnameFromAwsMachine() throws Exception { final String expectedHostname = "ec2-awshostname"; RecordingSshTool.setCustomResponse(".*curl.*169.254.169.254.*", new RecordingSshTool.CustomResponse(0, expectedHostname, "")); initNodeCreatorAndJcloudsLocation(newNodeCreator(), ImmutableMap.of( JcloudsLocationConfig.LOOKUP_AWS_HOSTNAME, true)); ConnectivityResolverOptions options = newResolveOptions() .waitForConnectable(true) .pollForReachableAddresses(Predicates.<HostAndPort>alwaysTrue(), Duration.millis(1), true) .userCredentials(credential) .build(); DefaultConnectivityResolver customizer = new DefaultConnectivityResolver(); ConfigBag configBag = jcloudsLocation.config().getBag(); ManagementAddressResolveResult result = customizer.resolve( jcloudsLocation, newNodeMetadata(), configBag, options); assertEquals(result.hostAndPort().getHostText(), expectedHostname); }
@Test(dataProvider = "testModeDataProvider") public void testMode(NetworkMode mode, Set<HostAndPort> reachableIps, String expectedIp) throws Exception { final DefaultConnectivityResolver customizer = new DefaultConnectivityResolver(ImmutableMap.of( DefaultConnectivityResolver.NETWORK_MODE, mode, DefaultConnectivityResolver.CHECK_CREDENTIALS, false)); initNodeCreatorAndJcloudsLocation(newNodeCreator(), ImmutableMap.of( JcloudsLocationConfig.CONNECTIVITY_RESOLVER, customizer)); ConnectivityResolverOptions options = newResolveOptionsForIps(reachableIps, Duration.millis(100)).build(); ConfigBag configBag = jcloudsLocation.config().getBag(); ManagementAddressResolveResult result = customizer.resolve(jcloudsLocation, newNodeMetadata(), configBag, options); assertEquals(result.hostAndPort().getHostText(), expectedIp); }
@Test(dataProvider = "fallibleModes", expectedExceptions = IllegalStateException.class) public void testModeUnavailable(NetworkMode mode, Set<HostAndPort> reachableIps) throws Exception { final DefaultConnectivityResolver customizer = new DefaultConnectivityResolver(ImmutableMap.of( DefaultConnectivityResolver.NETWORK_MODE, mode, DefaultConnectivityResolver.CHECK_CREDENTIALS, false)); initNodeCreatorAndJcloudsLocation(newNodeCreator(), ImmutableMap.of( JcloudsLocationConfig.CONNECTIVITY_RESOLVER, customizer)); ConnectivityResolverOptions options = newResolveOptionsForIps(reachableIps, Duration.ONE_MILLISECOND).build(); ConfigBag configBag = jcloudsLocation.config().getBag(); customizer.resolve(jcloudsLocation, newNodeMetadata(), configBag, options); }