Skip to content

Commit

Permalink
wip: review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam Corbett committed Feb 22, 2017
1 parent 7dcb653 commit 728fb46
Show file tree
Hide file tree
Showing 13 changed files with 544 additions and 431 deletions.
Expand Up @@ -82,16 +82,17 @@ public interface CloudLocationConfig {
"vmNameSaltLength", "Number of characters to use for a random identifier inserted in hostname "
+ "to uniquely identify machines", 4);

public static final ConfigKey<String> POLL_FOR_FIRST_REACHABLE_ADDRESS = ConfigKeys.newStringConfigKey("pollForFirstReachableAddress",
"Whether and how long to wait for reaching the VM's ip:port; "
+ "if 'false', will default to the node's first public IP (or private if no public IPs); "
+ "if 'true' uses default duration; otherwise accepts a time string e.g. '5m' (the default) or a number of milliseconds", "5m");
ConfigKey<String> POLL_FOR_FIRST_REACHABLE_ADDRESS = ConfigKeys.newStringConfigKey("pollForFirstReachableAddress",
"Whether and how long to wait for reaching the VM's ip:port to be accessible over SSH or WinRM; "
+ "if 'false', the location will will choose a public or private IP as appropriate; "
+ "if 'true' uses default duration; otherwise accepts a time string e.g. '5m' (the default) or a number of milliseconds",
"5m");

@SuppressWarnings("serial")
ConfigKey<Predicate<? super HostAndPort>> POLL_FOR_FIRST_REACHABLE_ADDRESS_PREDICATE = ConfigKeys.newConfigKey(
new TypeToken<Predicate<? super HostAndPort>>(){},
"pollForFirstReachableAddress.predicate",
"Predicate<HostAndPort> implementation which checks whether machine is up or not.");
"Predicate<HostAndPort> implementation which checks whether an ip:port is reachable.");

@SuppressWarnings("serial")
ConfigKey<Class<? extends Predicate<? super HostAndPort>>> POLL_FOR_FIRST_REACHABLE_ADDRESS_PREDICATE_TYPE = ConfigKeys.newConfigKey(
Expand All @@ -101,15 +102,19 @@ public interface CloudLocationConfig {
"Other keys prefixed with pollForFirstReachableAddress.predicate.<property> will be passed to the Map constructor of the Predicate<HostAndPort> implementation.",
Networking.IsReachablePredicate.class);

public static final ConfigKey<String> WAIT_FOR_SSHABLE = ConfigKeys.newStringConfigKey("waitForSshable",
/** @deprecated since 0.11.0 use {@link #POLL_FOR_FIRST_REACHABLE_ADDRESS} instead. */
@Deprecated
ConfigKey<String> WAIT_FOR_SSHABLE = ConfigKeys.newStringConfigKey("waitForSshable",
"Whether and how long to wait for a newly provisioned VM to be accessible via ssh; " +
"if 'false', won't check; if 'true' uses default duration; otherwise accepts a time string e.g. '5m' (the default) or a number of milliseconds", "5m");

public static final ConfigKey<String> WAIT_FOR_WINRM_AVAILABLE = ConfigKeys.newStringConfigKey("waitForWinRmAvailable",
/** @deprecated since 0.11.0 use {@link #POLL_FOR_FIRST_REACHABLE_ADDRESS} instead. */
@Deprecated
ConfigKey<String> WAIT_FOR_WINRM_AVAILABLE = ConfigKeys.newStringConfigKey("waitForWinRmAvailable",
"Whether and how long to wait for a newly provisioned VM to be accessible via WinRm; " +
"if 'false', won't check; if 'true' uses default duration; otherwise accepts a time string e.g. '30m' (the default) or a number of milliseconds", "30m");
"if 'false', won't check; if 'true' uses default duration; otherwise accepts a time string e.g. '30m' (the default) or a number of milliseconds", "30m");

public static final ConfigKey<Boolean> LOG_CREDENTIALS = ConfigKeys.newBooleanConfigKey(
ConfigKey<Boolean> LOG_CREDENTIALS = ConfigKeys.newBooleanConfigKey(
"logCredentials",
"Whether to log credentials of a new VM - strongly recommended never be used in production, as it is a big security hole!",
false);
Expand Down
Expand Up @@ -19,28 +19,37 @@

package org.apache.brooklyn.location.jclouds;

import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.core.sensor.Sensors;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.jclouds.compute.domain.NodeMetadata;

import com.google.common.annotations.Beta;
import com.google.common.reflect.TypeToken;

/**
* LocationNetworkInfoCustomizers are used by {@link JcloudsLocation} to determine the host and port
* on which connections to locations should be made and the credentials that should be used.
*
* @see JcloudsLocationConfig#LOCATION_NETWORK_INFO_CUSTOMIZER
* @see JcloudsLocationConfig#CONNECTIVITY_RESOLVER
*/
@Beta
public interface LocationNetworkInfoCustomizer extends JcloudsLocationCustomizer {
public interface ConnectivityResolver {

AttributeSensor<Iterable<String>> PUBLIC_ADDRESSES = Sensors.newSensor(new TypeToken<Iterable<String>>() {},
"host.addresses.public", "Public addresses on an instance");

AttributeSensor<Iterable<String>> PRIVATE_ADDRESSES = Sensors.newSensor(new TypeToken<Iterable<String>>() {},
"host.addresses.private", "Private addresses on an instance");

/**
* @param location The caller
* @param node The node the caller has created
* @param config The configuration the caller used to create the node
* @param location The caller
* @param node The node the caller has created
* @param config The configuration the caller used to create the node
* @param resolveOptions Additional options the caller has chosen when creating the node
* @return The HostAndPort and LoginCredentials to use when connecting to the node.
*/
ManagementAddressResolveResult resolve(
JcloudsLocation location, NodeMetadata node, ConfigBag config, ManagementAddressResolveOptions resolveOptions);
JcloudsLocation location, NodeMetadata node, ConfigBag config, ConnectivityResolverOptions resolveOptions);

}
@@ -0,0 +1,245 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF 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.apache.brooklyn.location.jclouds;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import org.apache.brooklyn.util.time.Duration;
import org.jclouds.domain.LoginCredentials;

import com.google.common.annotations.Beta;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.net.HostAndPort;

/**
* Holds parameters to be used by a {@link ConnectivityResolver}.
*/
@Beta
public class ConnectivityResolverOptions {

public static Builder builder() {
return new Builder();
}

public static class Builder {
private boolean isWindows = false;

private boolean waitForConnectable;
private boolean pollForReachableAddresses;
private Predicate<? super HostAndPort> reachableAddressPredicate;
private Duration reachableAddressTimeout;
private boolean propagatePollForReachableFailure;

private LoginCredentials initialCredentials;
private LoginCredentials userCredentials;

private int defaultLoginPort;
private boolean usePortForwarding;
private HostAndPort portForwardSshOverride;
private boolean isRebinding;
private boolean skipJcloudsSshing;

public Builder pollForReachableAddresses(
@Nonnull Predicate<? super HostAndPort> reachable,
@Nonnull Duration timeout,
boolean propagatePollFailure) {
this.pollForReachableAddresses = true;
this.reachableAddressPredicate = reachable;
this.reachableAddressTimeout = timeout;
this.propagatePollForReachableFailure = propagatePollFailure;
return this;
}

public Builder noPollForReachableAddresses() {
this.pollForReachableAddresses = false;
this.reachableAddressPredicate = null;
this.reachableAddressTimeout = null;
this.propagatePollForReachableFailure = false;
return this;
}

public Builder initialCredentials(@Nullable LoginCredentials initialCredentials) {
this.initialCredentials = initialCredentials;
return this;
}

public Builder userCredentials(@Nullable LoginCredentials userCredentials) {
this.userCredentials = userCredentials;
return this;
}

public Builder isWindows(boolean windows) {
isWindows = windows;
return this;
}

/** Indicate the host and port that should be used over all others. Normally used in tandem with a port forwarder. */
public Builder portForwardSshOverride(@Nullable HostAndPort hostAndPortOverride) {
this.portForwardSshOverride = hostAndPortOverride;
return this;
}

public Builder isRebinding(boolean isRebinding) {
this.isRebinding = isRebinding;
return this;
}

public Builder skipJcloudsSshing(boolean skipJcloudsSshing) {
this.skipJcloudsSshing = skipJcloudsSshing;
return this;
}

public Builder defaultLoginPort(int defaultLoginPort) {
this.defaultLoginPort = defaultLoginPort;
return this;
}

public Builder usePortForwarding(boolean usePortForwarding) {
this.usePortForwarding = usePortForwarding;
return this;
}

public Builder waitForConnectable(boolean waitForConnectable) {
this.waitForConnectable = waitForConnectable;
return this;
}

public ConnectivityResolverOptions build() {
return new ConnectivityResolverOptions(
isWindows, waitForConnectable, pollForReachableAddresses, reachableAddressPredicate,
propagatePollForReachableFailure, reachableAddressTimeout, initialCredentials, userCredentials,
defaultLoginPort, usePortForwarding, portForwardSshOverride, isRebinding, skipJcloudsSshing);
}
}

private final boolean isWindows;

/** Wait for Windows machines to be available over WinRM and other machines over SSH */
// TODO: Merge this with pollForReachable when waitForSshable and waitForWinRmable deleted.
private final boolean waitForConnectable;

/** Wait for a machine's ip:port to be available. */
private final boolean pollForReachableAddresses;
private final Predicate<? super HostAndPort> reachableAddressPredicate;
private final boolean propagatePollForReachableFailure;
private final Duration reachableAddressTimeout;

private final LoginCredentials initialCredentials;
private final LoginCredentials userCredentials;
private final int defaultLoginPort;

// TODO: Can usePortForwarding and portForwardSshOverride be merged?
private final boolean usePortForwarding;
private final HostAndPort portForwardSshOverride;
private final boolean isRebinding;
private final boolean skipJcloudsSshing;


protected ConnectivityResolverOptions(boolean isWindows, boolean waitForConnectable, boolean pollForReachableAddresses, Predicate<? super HostAndPort> reachableAddressPredicate, boolean propagatePollForReachableFailure, Duration reachableAddressTimeout, LoginCredentials initialCredentials, LoginCredentials userCredentials, int defaultLoginPort, boolean usePortForwarding, HostAndPort portForwardSshOverride, boolean isRebinding, boolean skipJcloudsSshing) {
this.isWindows = isWindows;
this.waitForConnectable = waitForConnectable;
this.pollForReachableAddresses = pollForReachableAddresses;
this.reachableAddressPredicate = reachableAddressPredicate;
this.propagatePollForReachableFailure = propagatePollForReachableFailure;
this.reachableAddressTimeout = reachableAddressTimeout;
this.initialCredentials = initialCredentials;
this.userCredentials = userCredentials;
this.defaultLoginPort = defaultLoginPort;
this.usePortForwarding = usePortForwarding;
this.portForwardSshOverride = portForwardSshOverride;
this.isRebinding = isRebinding;
this.skipJcloudsSshing = skipJcloudsSshing;
}

public boolean isWindows() {
return isWindows;
}

public boolean waitForConnectable() {
return waitForConnectable;
}

public boolean pollForReachableAddresses() {
return pollForReachableAddresses;
}

public Predicate<? super HostAndPort> reachableAddressPredicate() {
return reachableAddressPredicate;
}

public Duration reachableAddressTimeout() {
return reachableAddressTimeout;
}

public boolean propagatePollForReachableFailure() {
return propagatePollForReachableFailure;
}

public Optional<LoginCredentials> initialCredentials() {
return Optional.fromNullable(initialCredentials);
}

public Optional<LoginCredentials> userCredentials() {
return Optional.fromNullable(userCredentials);
}

public boolean usePortForwarding() {
return usePortForwarding;
}

public Optional<HostAndPort> portForwardSshOverride() {
return Optional.fromNullable(portForwardSshOverride);
}

public int defaultLoginPort() {
return defaultLoginPort;
}

public boolean skipJcloudsSshing() {
return skipJcloudsSshing;
}

public boolean isRebinding() {
return isRebinding;
}

public Builder toBuilder() {
Builder builder = builder()
.isWindows(isWindows)
.waitForConnectable(waitForConnectable)
.usePortForwarding(usePortForwarding)
.portForwardSshOverride(portForwardSshOverride)
.skipJcloudsSshing(skipJcloudsSshing)
.initialCredentials(initialCredentials)
.userCredentials(userCredentials)
.isRebinding(isRebinding)
.defaultLoginPort(defaultLoginPort)
;
if (pollForReachableAddresses) {
builder.pollForReachableAddresses(reachableAddressPredicate, reachableAddressTimeout, propagatePollForReachableFailure);
} else {
builder.noPollForReachableAddresses();
}
return builder;
}

}

0 comments on commit 728fb46

Please sign in to comment.