You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by dr...@apache.org on 2017/05/03 11:13:06 UTC

[2/4] brooklyn-server git commit: extract many API methods to an api package so osgi projects can access much functionality without needing to pull in an exported jclouds dependency

extract many API methods to an api package so osgi projects can access much functionality
without needing to pull in an exported jclouds dependency

(because JcloudsLocation has methods which access jclouds objects in the signature,
use of the jclouds package _exports_ a bunch of jclouds osgi deps which is rarely wanted)

this has been done in a backwards compatible way; the classes in the package look the same,
there are just now intermediate interfaces which are jclouds-free


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/e2319e5e
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/e2319e5e
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/e2319e5e

Branch: refs/heads/master
Commit: e2319e5e1ebf13551a414182965034440c6b40ff
Parents: bfbcddd
Author: Alex Heneveld <al...@cloudsoftcorp.com>
Authored: Tue Feb 28 14:11:08 2017 +0000
Committer: Alex Heneveld <al...@cloudsoftcorp.com>
Committed: Tue Feb 28 16:00:40 2017 +0000

----------------------------------------------------------------------
 .../location/jclouds/ConnectivityResolver.java  |   2 +
 .../jclouds/DefaultConnectivityResolver.java    |   1 +
 .../location/jclouds/JcloudsLocation.java       |  20 +-
 .../location/jclouds/JcloudsLocationConfig.java | 228 +----------------
 .../jclouds/JcloudsMachineLocation.java         |  14 +-
 .../jclouds/JcloudsSshMachineLocation.java      |   6 +-
 .../api/JcloudsLocationConfigPublic.java        | 250 +++++++++++++++++++
 .../jclouds/api/JcloudsLocationPublic.java      |  57 +++++
 .../api/JcloudsMachineLocationPublic.java       |  40 +++
 9 files changed, 370 insertions(+), 248 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e2319e5e/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/ConnectivityResolver.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/ConnectivityResolver.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/ConnectivityResolver.java
index 30ae603..0527f36 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/ConnectivityResolver.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/ConnectivityResolver.java
@@ -36,9 +36,11 @@ import com.google.common.reflect.TypeToken;
 @Beta
 public interface ConnectivityResolver {
 
+    @SuppressWarnings("serial")
     AttributeSensor<Iterable<String>> PUBLIC_ADDRESSES = Sensors.newSensor(new TypeToken<Iterable<String>>() {},
             "host.addresses.public", "Public addresses on an instance");
 
+    @SuppressWarnings("serial")
     AttributeSensor<Iterable<String>> PRIVATE_ADDRESSES = Sensors.newSensor(new TypeToken<Iterable<String>>() {},
             "host.addresses.private", "Private addresses on an instance");
 

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e2319e5e/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/DefaultConnectivityResolver.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/DefaultConnectivityResolver.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/DefaultConnectivityResolver.java
index b7c90eb..ce9b6cc 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/DefaultConnectivityResolver.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/DefaultConnectivityResolver.java
@@ -21,6 +21,7 @@ package org.apache.brooklyn.location.jclouds;
 
 import java.util.Iterator;
 import java.util.Map;
+
 import javax.annotation.Nullable;
 
 import org.apache.brooklyn.api.entity.Entity;

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e2319e5e/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
index 8e25d64..d0a5fb4 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java
@@ -43,6 +43,7 @@ import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
+
 import javax.annotation.Nullable;
 import javax.xml.ws.WebServiceException;
 
@@ -74,9 +75,9 @@ import org.apache.brooklyn.core.location.cloud.names.AbstractCloudMachineNamer;
 import org.apache.brooklyn.core.location.cloud.names.CloudMachineNamer;
 import org.apache.brooklyn.core.location.internal.LocationInternal;
 import org.apache.brooklyn.core.mgmt.internal.LocalLocationManager;
-import org.apache.brooklyn.core.mgmt.persist.LocationWithObjectStore;
 import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
 import org.apache.brooklyn.core.mgmt.persist.jclouds.JcloudsBlobStoreBasedObjectStore;
+import org.apache.brooklyn.location.jclouds.api.JcloudsLocationPublic;
 import org.apache.brooklyn.location.jclouds.networking.JcloudsPortForwarderExtension;
 import org.apache.brooklyn.location.jclouds.templates.PortableTemplateBuilder;
 import org.apache.brooklyn.location.jclouds.templates.customize.TemplateBuilderCustomizer;
@@ -183,8 +184,7 @@ import com.google.common.net.HostAndPort;
  * Configuration flags are defined in {@link JcloudsLocationConfig}.
  */
 public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation implements
-        JcloudsLocationConfig, MachineManagementMixins.RichMachineProvisioningLocation<MachineLocation>,
-        LocationWithObjectStore, MachineManagementMixins.SuspendResumeLocation {
+        JcloudsLocationPublic {
 
     // TODO After converting from Groovy to Java, this is now very bad code! It relies entirely on putting
     // things into and taking them out of maps; it's not type-safe, and it's thus very error-prone.
@@ -198,12 +198,6 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im
 
     public static final Logger LOG = LoggerFactory.getLogger(JcloudsLocation.class);
 
-    public static final String ROOT_USERNAME = "root";
-    /** these userNames are known to be the preferred/required logins in some common/default images
-     *  where root@ is not allowed to log in */
-    public static final List<String> ROOT_ALIASES = ImmutableList.of("ubuntu", "centos", "ec2-user");
-    public static final List<String> COMMON_USER_NAMES_TO_TRY = ImmutableList.<String>builder().add(ROOT_USERNAME).addAll(ROOT_ALIASES).add("admin").build();
-
     private static final int NOTES_MAX_LENGTH = 1000;
 
     @VisibleForTesting
@@ -296,23 +290,28 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im
                 .toString();
     }
 
+    @Override
     public String getProvider() {
         return getConfig(CLOUD_PROVIDER);
     }
 
+    @Override
     public String getIdentity() {
         return getConfig(ACCESS_IDENTITY);
     }
 
+    @Override
     public String getCredential() {
         return getConfig(ACCESS_CREDENTIAL);
     }
 
     /** returns the location ID used by the provider, if set, e.g. us-west-1 */
+    @Override
     public String getRegion() {
         return getConfig(CLOUD_REGION_ID);
     }
 
+    @Override
     public String getEndpoint() {
         return (String) config().getBag().getWithDeprecation(CLOUD_ENDPOINT, JCLOUDS_KEY_ENDPOINT);
     }
@@ -1542,7 +1541,8 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im
         }
     }
 
-    protected String toStringNice() {
+    @Override
+    public String toStringNice() {
         String s = config().get(ORIGINAL_SPEC);
         if (Strings.isBlank(s)) s = config().get(NAMED_SPEC_NAME);
         if (Strings.isBlank(s)) s = config().get(FINAL_SPEC);

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e2319e5e/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationConfig.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationConfig.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationConfig.java
index d06f7cc..0b9aded 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationConfig.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocationConfig.java
@@ -19,176 +19,27 @@
 package org.apache.brooklyn.location.jclouds;
 
 import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Semaphore;
 
 import org.apache.brooklyn.config.ConfigKey;
 import org.apache.brooklyn.core.config.BasicConfigKey;
 import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.location.LocationConfigKeys;
-import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
-import org.apache.brooklyn.core.location.access.PortForwardManager;
-import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.location.jclouds.api.JcloudsLocationConfigPublic;
 import org.apache.brooklyn.location.jclouds.networking.JcloudsPortForwarderExtension;
-import org.jclouds.Constants;
 import org.jclouds.compute.domain.Image;
 import org.jclouds.compute.domain.OsFamily;
 import org.jclouds.compute.domain.TemplateBuilder;
 import org.jclouds.domain.LoginCredentials;
-import org.apache.brooklyn.util.core.internal.ssh.SshTool;
 
-import com.google.common.annotations.Beta;
 import com.google.common.base.Function;
 import com.google.common.reflect.TypeToken;
 
-public interface JcloudsLocationConfig extends CloudLocationConfig {
+public interface JcloudsLocationConfig extends JcloudsLocationConfigPublic {
 
-    public static final ConfigKey<String> CLOUD_PROVIDER = LocationConfigKeys.CLOUD_PROVIDER;
-
-    public static final ConfigKey<Boolean> RUN_AS_ROOT = ConfigKeys.newBooleanConfigKey("runAsRoot", 
-            "Whether to run initial setup as root (default true)", null);
-    public static final ConfigKey<String> LOGIN_USER = ConfigKeys.newStringConfigKey("loginUser",
-            "Override the user who logs in initially to perform setup " +
-            "(otherwise it is detected from the cloud or known defaults in cloud or VM OS)", null);
-    public static final ConfigKey<String> LOGIN_USER_PASSWORD = ConfigKeys.newStringConfigKey("loginUser.password",
-            "Custom password for the user who logs in initially", null);
-    public static final ConfigKey<String> LOGIN_USER_PRIVATE_KEY_DATA = ConfigKeys.newStringConfigKey("loginUser.privateKeyData",
-            "Custom private key for the user who logs in initially", null);   
-    // not supported in jclouds
-//    public static final ConfigKey<String> LOGIN_USER_PRIVATE_KEY_PASSPHRASE = ConfigKeys.newStringKey("loginUser.privateKeyPassphrase", 
-//            "Passphrase for the custom private key for the user who logs in initially", null);
-    public static final ConfigKey<String> LOGIN_USER_PRIVATE_KEY_FILE = ConfigKeys.newStringConfigKey("loginUser.privateKeyFile",
-            "Custom private key for the user who logs in initially", null); 
-    public static final ConfigKey<String> EXTRA_PUBLIC_KEY_DATA_TO_AUTH = ConfigKeys.newStringConfigKey("extraSshPublicKeyData",
-        "Additional public key data to add to authorized_keys (multi-line string supported, with one key per line)", null);
-    @SuppressWarnings("serial")
-    public static final ConfigKey<List<String>> EXTRA_PUBLIC_KEY_URLS_TO_AUTH = ConfigKeys.newConfigKey(new TypeToken<List<String>>() {}, 
-        "extraSshPublicKeyUrls", "Additional public keys (files or URLs, in SSH2/RFC4716/id_rsa.pub format) to add to authorized_keys", null);
-
-    public static final ConfigKey<String> KEY_PAIR = ConfigKeys.newStringConfigKey("keyPair",
-        "Custom keypair (name) known at the cloud to be installed on machines for initial login (selected clouds only); "
-        + "you may also need to set "+LOGIN_USER_PRIVATE_KEY_FILE.getName(), null);
-    public static final ConfigKey<Boolean> AUTO_GENERATE_KEYPAIRS = ConfigKeys.newBooleanConfigKey("jclouds.openstack-nova.auto-generate-keypairs",
-        "Whether to generate keypairs automatically (OpenStack Nova)");
-
-    /** @deprecated since 0.9.0 Use {@link #AUTO_ASSIGN_FLOATING_IP} instead (deprecated in 0.7.0 but warning not given until 0.9.0) */
-    @Deprecated
-    public static final ConfigKey<Boolean> AUTO_CREATE_FLOATING_IPS = ConfigKeys.newBooleanConfigKey("jclouds.openstack-nova.auto-create-floating-ips",
-            "Whether to generate floating ips for Nova");
-    public static final ConfigKey<Boolean> AUTO_ASSIGN_FLOATING_IP = ConfigKeys.newBooleanConfigKey("autoAssignFloatingIp",
-            "Whether to generate floating ips (in Nova paralance), or elastic IPs (in CloudStack parlance)");
-
-    public static final ConfigKey<Boolean> DONT_CREATE_USER = ConfigKeys.newBooleanConfigKey("dontCreateUser",
-            "Whether to skip creation of 'user' when provisioning machines (default false). " +
-            "Note that setting this will prevent jclouds from overwriting /etc/sudoers which might be " +
-            "configured incorrectly by default. See 'dontRequireTtyForSudo' for details.",
-            false);
-    public static final ConfigKey<Boolean> GRANT_USER_SUDO = ConfigKeys.newBooleanConfigKey("grantUserSudo",
-            "Whether to grant the created user sudo privileges. Irrelevant if dontCreateUser is true. Default: true.", true);
-    public static final ConfigKey<Boolean> DISABLE_ROOT_AND_PASSWORD_SSH = ConfigKeys.newBooleanConfigKey("disableRootAndPasswordSsh",
-        "Whether to disable direct SSH access for root and disable password-based SSH, "
-        + "if creating a user with a key-based login; "
-        + "defaults to true (set false to leave root users alone)", true);
-    public static final ConfigKey<String> CUSTOM_TEMPLATE_OPTIONS_SCRIPT_CONTENTS = ConfigKeys.newStringConfigKey("customTemplateOptionsScriptContents",
-        "A custom script to pass to jclouds as part of template options, run after AdminAccess, "
-        + "for use primarily where a command which must run as root on first login before switching to the admin user, "
-        + "e.g. to customize sudoers; may start in an odd location (e.g. /tmp/bootstrap); "
-        + "NB: most commands should be run by entities, or if VM-specific but sudo is okay, then via setup.script, not via this");
-    
     public static final ConfigKey<LoginCredentials> CUSTOM_CREDENTIALS = new BasicConfigKey<LoginCredentials>(LoginCredentials.class,
-            "customCredentials", "Custom jclouds LoginCredentials object to be used to connect to the VM", null);
-    
-    public static final ConfigKey<String> GROUP_ID = ConfigKeys.newStringConfigKey("groupId",
-            "The Jclouds group provisioned machines should be members of. " +
-            "Users of this config key are also responsible for configuring security groups.");
-    
-    // jclouds compatibility
-    public static final ConfigKey<String> JCLOUDS_KEY_USERNAME = ConfigKeys.newStringConfigKey(
-            "userName", "Equivalent to 'user'; provided for jclouds compatibility", null);
-    public static final ConfigKey<String> JCLOUDS_KEY_ENDPOINT = ConfigKeys.newStringConfigKey(
-            Constants.PROPERTY_ENDPOINT, "Equivalent to 'endpoint'; provided for jclouds compatibility", null);
-    
-    // note causing problems on centos due to use of `sudo -n`; but required for default RHEL VM
-    /**
-     * @deprecated since 0.8.0; instead configure this on the entity. See SoftwareProcess.OPEN_IPTABLES.
-     */
-    @Deprecated
-    public static final ConfigKey<Boolean> OPEN_IPTABLES = ConfigKeys.newBooleanConfigKey("openIptables", 
-            "[DEPRECATED - use openIptables on SoftwareProcess entity] Whether to open the INBOUND_PORTS via iptables rules; " +
-            "if true then ssh in to run iptables commands, as part of machine provisioning", true);
-
-    /**
-     * @deprecated since 0.8.0; instead configure this on the entity. See SoftwareProcess.STOP_IPTABLES.
-     */
-    @Deprecated
-    public static final ConfigKey<Boolean> STOP_IPTABLES = ConfigKeys.newBooleanConfigKey("stopIptables", 
-            "[DEPRECATED - use stopIptables on SoftwareProcess entity] Whether to stop iptables entirely; " +
-            "if true then ssh in to stop the iptables service, as part of machine provisioning", false);
-
-    public static final ConfigKey<String> HARDWARE_ID = ConfigKeys.newStringConfigKey("hardwareId",
-            "A system-specific identifier for the hardware profile or machine type to be used when creating a VM", null);
-    
-    public static final ConfigKey<String> IMAGE_ID = ConfigKeys.newStringConfigKey("imageId", 
-            "A system-specific identifier for the VM image to be used when creating a VM", null);
-    public static final ConfigKey<String> IMAGE_NAME_REGEX = ConfigKeys.newStringConfigKey("imageNameRegex", 
-            "A regular expression to be compared against the 'name' when selecting the VM image to be used when creating a VM", null);
-    public static final ConfigKey<String> IMAGE_DESCRIPTION_REGEX = ConfigKeys.newStringConfigKey("imageDescriptionRegex", 
-            "A regular expression to be compared against the 'description' when selecting the VM image to be used when creating a VM", null);
-
-    public static final ConfigKey<String> TEMPLATE_SPEC = ConfigKeys.newStringConfigKey("templateSpec", 
-            "A jclouds 'spec' string consisting of properties and values to be used when creating a VM " +
-            "(in most cases the properties can, and should, be specified individually using other Brooklyn location config keys)", null);
-
-    public static final ConfigKey<String> DEFAULT_IMAGE_ID = ConfigKeys.newStringConfigKey("defaultImageId", 
-            "A system-specific identifier for the VM image to be used by default when creating a VM " +
-            "(if no other VM image selection criteria are supplied)", null);
+        "customCredentials", "Custom jclouds LoginCredentials object to be used to connect to the VM", null);
 
     public static final ConfigKey<TemplateBuilder> TEMPLATE_BUILDER = ConfigKeys.newConfigKey(TemplateBuilder.class,
-            "templateBuilder", "A TemplateBuilder instance provided programmatically, to be used when creating a VM");
-
-    public static final ConfigKey<Object> SECURITY_GROUPS = new BasicConfigKey<Object>(Object.class, "securityGroups",
-            "Security groups to be applied when creating a VM, on supported clouds " +
-            "(either a single group identifier as a String, or an Iterable<String> or String[])", null);
-
-    public static final ConfigKey<String> USER_METADATA_STRING = ConfigKeys.newStringConfigKey("userMetadataString", 
-        "Arbitrary user data, as a single string, on supported clouds (AWS)", null);
-
-    @Deprecated /** @deprecated since 0.7.0 even AWS (the only one where this was supported) does not seem to want this uuencoded;
-      use #USER_METADATA_STRING */
-    public static final ConfigKey<String> USER_DATA_UUENCODED = ConfigKeys.newStringConfigKey("userData", 
-        "Arbitrary user data, as a single string in uuencoded format, on supported clouds (AWS)", null);
-
-    public static final ConfigKey<Object> STRING_TAGS = new BasicConfigKey<Object>(Object.class, "tags", 
-            "Tags to be applied when creating a VM, on supported clouds " +
-            "(either a single tag as a String, or an Iterable<String> or String[];" +
-            "note this is not key-value pairs (e.g. what AWS calls 'tags'), for that see userMetadata)", null);
-
-    @Deprecated /** @deprecated since 0.7.0 use #STRING_TAGS */
-    public static final ConfigKey<Object> TAGS = STRING_TAGS;
-
-    public static final ConfigKey<Object> USER_METADATA_MAP = new BasicConfigKey<Object>(Object.class, "userMetadata", 
-            "Arbitrary user metadata, as a map (or String of comma-separated key=value pairs), on supported clouds; " +
-            "note often values cannot be null", null);
-    @Deprecated /** @deprecated since 0.7.0 use #USER_METADATA_MAP */
-    public static final ConfigKey<Object> USER_METADATA = USER_METADATA_MAP;
-
-    public static final ConfigKey<Boolean> INCLUDE_BROOKLYN_USER_METADATA = ConfigKeys.newBooleanConfigKey("includeBrooklynUserMetadata", 
-        "Whether to set metadata about the context of a machine, e.g. brooklyn-entity-id, brooklyn-app-name (default true)", true);
-
-    // See also SoftwareProcess.DONT_REQUIRE_TTY_FOR_SUDO
-    public static final ConfigKey<Boolean> DONT_REQUIRE_TTY_FOR_SUDO = ConfigKeys.newBooleanConfigKey("dontRequireTtyForSudo",
-            "Whether to explicitly set /etc/sudoers, so don't need tty (will leave unchanged if 'false'); " +
-            "some machines require a tty for sudo; brooklyn by default does not use a tty " +
-            "(so that it can get separate error+stdout streams); you can enable a tty as an " +
-            "option to every ssh command, or you can do it once and " +
-            "modify the machine so that a tty is not subsequently required. " +
-            "Usually used in conjunction with 'dontCreateUser' since it will prevent " +
-            "jclouds from overwriting /etc/sudoers and overriding the system default. " +
-            "When not explicitly set will be applied if 'dontCreateUser' is set.");
-
-    public static final ConfigKey<Boolean> MAP_DEV_RANDOM_TO_DEV_URANDOM = ConfigKeys.newBooleanConfigKey(
-            "installDevUrandom", "Map /dev/random to /dev/urandom to prevent halting on insufficient entropy", true);
+        "templateBuilder", "A TemplateBuilder instance provided programmatically, to be used when creating a VM");
 
     /** @deprecated since 0.7.0; use {@link #JCLOUDS_LOCATION_CUSTOMIZERS} instead */
     @Deprecated
@@ -215,62 +66,8 @@ public interface JcloudsLocationConfig extends CloudLocationConfig {
             "connectivityResolver",
             "Optional instance of a ConnectivityResolver that the location will use in favour of " + DefaultConnectivityResolver.class.getSimpleName());
 
-    public static final ConfigKey<String> LOCAL_TEMP_DIR = SshTool.PROP_LOCAL_TEMP_DIR;
-    
-    public static final ConfigKey<Integer> OVERRIDE_RAM = ConfigKeys.newIntegerConfigKey("overrideRam", "Custom ram value");    
-    
-    public static final ConfigKey<String> NETWORK_NAME = ConfigKeys.newStringConfigKey(
-        "networkName", "Network name or ID where the instance should be created (e.g. the subnet ID in AWS");
-
-    /**
-     * CUSTOM_MACHINE_SETUP_SCRIPT_URL accepts a URL location that points to a shell script. 
-     * Please have a look at locations/jclouds/src/main/resources/org/apache/brooklyn/location/jclouds/sample/setup-server.sh as an example
-     */
-    public static final ConfigKey<String> CUSTOM_MACHINE_SETUP_SCRIPT_URL = ConfigKeys.newStringConfigKey(
-            "setup.script", "Custom script to customize a node");
-    
-    @SuppressWarnings("serial")
-    public static final ConfigKey<List<String>> CUSTOM_MACHINE_SETUP_SCRIPT_URL_LIST = ConfigKeys.newConfigKey(new TypeToken<List<String>>() {},
-            "setup.scripts", "A list of scripts to customize a node");
-    
-    public static final ConfigKey<String> CUSTOM_MACHINE_SETUP_SCRIPT_VARS = ConfigKeys.newStringConfigKey(
-            "setup.script.vars", "vars to customize a setup.script i.e.: key1:value1,key2:value2");
-    
-    public static final ConfigKey<Boolean> GENERATE_HOSTNAME = ConfigKeys.newBooleanConfigKey(
-            "generate.hostname", "Use the nodename generated by jclouds", false);
-
-    public static final ConfigKey<Boolean> USE_PORT_FORWARDING = ConfigKeys.newBooleanConfigKey(
-            "portforwarding.enabled", 
-            "Whether to setup port-forwarding to subsequently access the VM (over the ssh port)",
-            false);
-    
-    @Beta
-    public static final ConfigKey<Boolean> USE_JCLOUDS_SSH_INIT = ConfigKeys.newBooleanConfigKey(
-            "useJcloudsSshInit", 
-            "Whether to use jclouds for initial ssh-based setup (i.e. as part of the 'TemplateOptions'); "
-                    + "if false will use core brooklyn ssh utilities. "
-                    + "This config is beta; its default could be changed and/or the option removed in an upcoming release.", 
-            true);
-    
-    @Beta
-    public static final ConfigKey<Boolean> LOOKUP_AWS_HOSTNAME = ConfigKeys.newBooleanConfigKey(
-            "lookupAwsHostname", 
-            "Whether to lookup the AWS hostname (via a command on the VM), or to just use the IP.", 
-            true);
-    
     public static final ConfigKey<JcloudsPortForwarderExtension> PORT_FORWARDER = ConfigKeys.newConfigKey(
-            JcloudsPortForwarderExtension.class, "portforwarding.forwarder", "The port-forwarder to use");
-    
-    public static final ConfigKey<PortForwardManager> PORT_FORWARDING_MANAGER = BrooklynAccessUtils.PORT_FORWARDING_MANAGER;
-
-    public static final ConfigKey<Integer> MACHINE_CREATE_ATTEMPTS = ConfigKeys.newIntegerConfigKey(
-            "machineCreateAttempts", "Number of times to retry if jclouds fails to create a VM", 2);
-
-    public static final ConfigKey<Integer> MAX_CONCURRENT_MACHINE_CREATIONS = ConfigKeys.newIntegerConfigKey(
-            "maxConcurrentMachineCreations", "Maximum number of concurrent machine-creations", Integer.MAX_VALUE);
-
-    public static final ConfigKey<Semaphore> MACHINE_CREATION_SEMAPHORE = ConfigKeys.newConfigKey(
-            Semaphore.class, "machineCreationSemaphore", "Semaphore for controlling concurrent machine creation", null);
+        JcloudsPortForwarderExtension.class, "portforwarding.forwarder", "The port-forwarder to use");
 
     @SuppressWarnings("serial")
     public static final ConfigKey<Function<Iterable<? extends Image>,Image>> IMAGE_CHOOSER = ConfigKeys.newConfigKey(
@@ -291,20 +88,5 @@ public interface JcloudsLocationConfig extends CloudLocationConfig {
             "jclouds.computeServiceRegistry",
             "Registry/Factory for creating jclouds ComputeService; default is almost always fine, except where tests want to customize behaviour",
             ComputeServiceRegistryImpl.INSTANCE);
-    
-    @SuppressWarnings("serial")
-    public static final ConfigKey<Map<String,Object>> TEMPLATE_OPTIONS = ConfigKeys.newConfigKey(
-            new TypeToken<Map<String, Object>>() {}, "templateOptions", "Additional jclouds template options");
-
-    /**
-     * The purpose of this config is to aid deployment of blueprints to clouds where it is difficult to get nodes to
-     * communicate via private IPs. This config allows a user to overwrite private IPs as public IPs, thus ensuring
-     * that any blueprints they wish to deploy which may use private IPs still work in these clouds.
-     */
-    @Beta
-    public static final ConfigKey<Boolean> USE_MACHINE_PUBLIC_ADDRESS_AS_PRIVATE_ADDRESS = ConfigKeys.newBooleanConfigKey(
-            "useMachinePublicAddressAsPrivateAddress",
-            "When true we will use the public IP/Hostname of a JClouds Location as the private IP/Hostname",
-            false);
 
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e2319e5e/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineLocation.java
index a0fa874..fc93745 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineLocation.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsMachineLocation.java
@@ -18,14 +18,13 @@
  */
 package org.apache.brooklyn.location.jclouds;
 
-import org.apache.brooklyn.api.location.MachineLocation;
-import org.apache.brooklyn.core.location.HasSubnetHostname;
+import org.apache.brooklyn.location.jclouds.api.JcloudsMachineLocationPublic;
 import org.jclouds.compute.domain.NodeMetadata;
 import org.jclouds.compute.domain.Template;
 
 import com.google.common.base.Optional;
 
-public interface JcloudsMachineLocation extends MachineLocation, HasSubnetHostname {
+public interface JcloudsMachineLocation extends JcloudsMachineLocationPublic {
     
     @Override
     public JcloudsLocation getParent();
@@ -49,13 +48,4 @@ public interface JcloudsMachineLocation extends MachineLocation, HasSubnetHostna
     @Deprecated
     public Template getTemplate();
 
-    public String getJcloudsId();
-
-    /** In most clouds, the public hostname is the only way to ensure VMs in different zones can access each other. */
-    @Override
-    public String getSubnetHostname();
-
-    String getUser();
-
-    int getPort();
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e2319e5e/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocation.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
index f69361e..82b873a 100644
--- a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsSshMachineLocation.java
@@ -18,7 +18,7 @@
  */
 package org.apache.brooklyn.location.jclouds;
 
-import static org.apache.brooklyn.location.jclouds.JcloudsLocationConfig.USE_MACHINE_PUBLIC_ADDRESS_AS_PRIVATE_ADDRESS;
+import static org.apache.brooklyn.location.jclouds.api.JcloudsLocationConfigPublic.USE_MACHINE_PUBLIC_ADDRESS_AS_PRIVATE_ADDRESS;
 import static org.apache.brooklyn.util.JavaGroovyEquivalents.groovyTruth;
 
 import java.util.List;
@@ -63,7 +63,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Optional;
 import com.google.common.base.Supplier;
 import com.google.common.base.Throwables;
@@ -184,7 +184,7 @@ public class JcloudsSshMachineLocation extends SshMachineLocation implements Jcl
     
     @Override
     public String toVerboseString() {
-        return Objects.toStringHelper(this).omitNullValues()
+        return MoreObjects.toStringHelper(this).omitNullValues()
                 .add("id", getId()).add("name", getDisplayName())
                 .add("user", getUser()).add("address", getAddress()).add("port", getConfig(SSH_PORT))
                 .add("node", _node)

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e2319e5e/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/api/JcloudsLocationConfigPublic.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/api/JcloudsLocationConfigPublic.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/api/JcloudsLocationConfigPublic.java
new file mode 100644
index 0000000..55b0e64
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/api/JcloudsLocationConfigPublic.java
@@ -0,0 +1,250 @@
+/*
+ * 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.api;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.BasicConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.location.LocationConfigKeys;
+import org.apache.brooklyn.core.location.access.BrooklynAccessUtils;
+import org.apache.brooklyn.core.location.access.PortForwardManager;
+import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
+import org.apache.brooklyn.util.core.internal.ssh.SshTool;
+import org.jclouds.Constants;
+
+import com.google.common.annotations.Beta;
+import com.google.common.reflect.TypeToken;
+
+public interface JcloudsLocationConfigPublic extends CloudLocationConfig {
+
+    public static final ConfigKey<String> CLOUD_PROVIDER = LocationConfigKeys.CLOUD_PROVIDER;
+
+    public static final ConfigKey<Boolean> RUN_AS_ROOT = ConfigKeys.newBooleanConfigKey("runAsRoot", 
+            "Whether to run initial setup as root (default true)", null);
+    public static final ConfigKey<String> LOGIN_USER = ConfigKeys.newStringConfigKey("loginUser",
+            "Override the user who logs in initially to perform setup " +
+            "(otherwise it is detected from the cloud or known defaults in cloud or VM OS)", null);
+    public static final ConfigKey<String> LOGIN_USER_PASSWORD = ConfigKeys.newStringConfigKey("loginUser.password",
+            "Custom password for the user who logs in initially", null);
+    public static final ConfigKey<String> LOGIN_USER_PRIVATE_KEY_DATA = ConfigKeys.newStringConfigKey("loginUser.privateKeyData",
+            "Custom private key for the user who logs in initially", null);   
+    // not supported in jclouds
+//    public static final ConfigKey<String> LOGIN_USER_PRIVATE_KEY_PASSPHRASE = ConfigKeys.newStringKey("loginUser.privateKeyPassphrase", 
+//            "Passphrase for the custom private key for the user who logs in initially", null);
+    public static final ConfigKey<String> LOGIN_USER_PRIVATE_KEY_FILE = ConfigKeys.newStringConfigKey("loginUser.privateKeyFile",
+            "Custom private key for the user who logs in initially", null); 
+    public static final ConfigKey<String> EXTRA_PUBLIC_KEY_DATA_TO_AUTH = ConfigKeys.newStringConfigKey("extraSshPublicKeyData",
+        "Additional public key data to add to authorized_keys (multi-line string supported, with one key per line)", null);
+    @SuppressWarnings("serial")
+    public static final ConfigKey<List<String>> EXTRA_PUBLIC_KEY_URLS_TO_AUTH = ConfigKeys.newConfigKey(new TypeToken<List<String>>() {}, 
+        "extraSshPublicKeyUrls", "Additional public keys (files or URLs, in SSH2/RFC4716/id_rsa.pub format) to add to authorized_keys", null);
+
+    public static final ConfigKey<String> KEY_PAIR = ConfigKeys.newStringConfigKey("keyPair",
+        "Custom keypair (name) known at the cloud to be installed on machines for initial login (selected clouds only); "
+        + "you may also need to set "+LOGIN_USER_PRIVATE_KEY_FILE.getName(), null);
+    public static final ConfigKey<Boolean> AUTO_GENERATE_KEYPAIRS = ConfigKeys.newBooleanConfigKey("jclouds.openstack-nova.auto-generate-keypairs",
+        "Whether to generate keypairs automatically (OpenStack Nova)");
+
+    /** @deprecated since 0.9.0 Use {@link #AUTO_ASSIGN_FLOATING_IP} instead (deprecated in 0.7.0 but warning not given until 0.9.0) */
+    @Deprecated
+    public static final ConfigKey<Boolean> AUTO_CREATE_FLOATING_IPS = ConfigKeys.newBooleanConfigKey("jclouds.openstack-nova.auto-create-floating-ips",
+            "Whether to generate floating ips for Nova");
+    public static final ConfigKey<Boolean> AUTO_ASSIGN_FLOATING_IP = ConfigKeys.newBooleanConfigKey("autoAssignFloatingIp",
+            "Whether to generate floating ips (in Nova paralance), or elastic IPs (in CloudStack parlance)");
+
+    public static final ConfigKey<Boolean> DONT_CREATE_USER = ConfigKeys.newBooleanConfigKey("dontCreateUser",
+            "Whether to skip creation of 'user' when provisioning machines (default false). " +
+            "Note that setting this will prevent jclouds from overwriting /etc/sudoers which might be " +
+            "configured incorrectly by default. See 'dontRequireTtyForSudo' for details.",
+            false);
+    public static final ConfigKey<Boolean> GRANT_USER_SUDO = ConfigKeys.newBooleanConfigKey("grantUserSudo",
+            "Whether to grant the created user sudo privileges. Irrelevant if dontCreateUser is true. Default: true.", true);
+    public static final ConfigKey<Boolean> DISABLE_ROOT_AND_PASSWORD_SSH = ConfigKeys.newBooleanConfigKey("disableRootAndPasswordSsh",
+        "Whether to disable direct SSH access for root and disable password-based SSH, "
+        + "if creating a user with a key-based login; "
+        + "defaults to true (set false to leave root users alone)", true);
+    public static final ConfigKey<String> CUSTOM_TEMPLATE_OPTIONS_SCRIPT_CONTENTS = ConfigKeys.newStringConfigKey("customTemplateOptionsScriptContents",
+        "A custom script to pass to jclouds as part of template options, run after AdminAccess, "
+        + "for use primarily where a command which must run as root on first login before switching to the admin user, "
+        + "e.g. to customize sudoers; may start in an odd location (e.g. /tmp/bootstrap); "
+        + "NB: most commands should be run by entities, or if VM-specific but sudo is okay, then via setup.script, not via this");
+    
+    public static final ConfigKey<String> GROUP_ID = ConfigKeys.newStringConfigKey("groupId",
+            "The Jclouds group provisioned machines should be members of. " +
+            "Users of this config key are also responsible for configuring security groups.");
+    
+    // jclouds compatibility
+    public static final ConfigKey<String> JCLOUDS_KEY_USERNAME = ConfigKeys.newStringConfigKey(
+            "userName", "Equivalent to 'user'; provided for jclouds compatibility", null);
+    public static final ConfigKey<String> JCLOUDS_KEY_ENDPOINT = ConfigKeys.newStringConfigKey(
+            Constants.PROPERTY_ENDPOINT, "Equivalent to 'endpoint'; provided for jclouds compatibility", null);
+    
+    // note causing problems on centos due to use of `sudo -n`; but required for default RHEL VM
+    /**
+     * @deprecated since 0.8.0; instead configure this on the entity. See SoftwareProcess.OPEN_IPTABLES.
+     */
+    @Deprecated
+    public static final ConfigKey<Boolean> OPEN_IPTABLES = ConfigKeys.newBooleanConfigKey("openIptables", 
+            "[DEPRECATED - use openIptables on SoftwareProcess entity] Whether to open the INBOUND_PORTS via iptables rules; " +
+            "if true then ssh in to run iptables commands, as part of machine provisioning", true);
+
+    /**
+     * @deprecated since 0.8.0; instead configure this on the entity. See SoftwareProcess.STOP_IPTABLES.
+     */
+    @Deprecated
+    public static final ConfigKey<Boolean> STOP_IPTABLES = ConfigKeys.newBooleanConfigKey("stopIptables", 
+            "[DEPRECATED - use stopIptables on SoftwareProcess entity] Whether to stop iptables entirely; " +
+            "if true then ssh in to stop the iptables service, as part of machine provisioning", false);
+
+    public static final ConfigKey<String> HARDWARE_ID = ConfigKeys.newStringConfigKey("hardwareId",
+            "A system-specific identifier for the hardware profile or machine type to be used when creating a VM", null);
+    
+    public static final ConfigKey<String> IMAGE_ID = ConfigKeys.newStringConfigKey("imageId", 
+            "A system-specific identifier for the VM image to be used when creating a VM", null);
+    public static final ConfigKey<String> IMAGE_NAME_REGEX = ConfigKeys.newStringConfigKey("imageNameRegex", 
+            "A regular expression to be compared against the 'name' when selecting the VM image to be used when creating a VM", null);
+    public static final ConfigKey<String> IMAGE_DESCRIPTION_REGEX = ConfigKeys.newStringConfigKey("imageDescriptionRegex", 
+            "A regular expression to be compared against the 'description' when selecting the VM image to be used when creating a VM", null);
+
+    public static final ConfigKey<String> TEMPLATE_SPEC = ConfigKeys.newStringConfigKey("templateSpec", 
+            "A jclouds 'spec' string consisting of properties and values to be used when creating a VM " +
+            "(in most cases the properties can, and should, be specified individually using other Brooklyn location config keys)", null);
+
+    public static final ConfigKey<String> DEFAULT_IMAGE_ID = ConfigKeys.newStringConfigKey("defaultImageId", 
+            "A system-specific identifier for the VM image to be used by default when creating a VM " +
+            "(if no other VM image selection criteria are supplied)", null);
+
+    public static final ConfigKey<Object> SECURITY_GROUPS = new BasicConfigKey<Object>(Object.class, "securityGroups",
+            "Security groups to be applied when creating a VM, on supported clouds " +
+            "(either a single group identifier as a String, or an Iterable<String> or String[])", null);
+
+    public static final ConfigKey<String> USER_METADATA_STRING = ConfigKeys.newStringConfigKey("userMetadataString", 
+        "Arbitrary user data, as a single string, on supported clouds (AWS)", null);
+
+    @Deprecated /** @deprecated since 0.7.0 even AWS (the only one where this was supported) does not seem to want this uuencoded;
+      use #USER_METADATA_STRING */
+    public static final ConfigKey<String> USER_DATA_UUENCODED = ConfigKeys.newStringConfigKey("userData", 
+        "Arbitrary user data, as a single string in uuencoded format, on supported clouds (AWS)", null);
+
+    public static final ConfigKey<Object> STRING_TAGS = new BasicConfigKey<Object>(Object.class, "tags", 
+            "Tags to be applied when creating a VM, on supported clouds " +
+            "(either a single tag as a String, or an Iterable<String> or String[];" +
+            "note this is not key-value pairs (e.g. what AWS calls 'tags'), for that see userMetadata)", null);
+
+    @Deprecated /** @deprecated since 0.7.0 use #STRING_TAGS */
+    public static final ConfigKey<Object> TAGS = STRING_TAGS;
+
+    public static final ConfigKey<Object> USER_METADATA_MAP = new BasicConfigKey<Object>(Object.class, "userMetadata", 
+            "Arbitrary user metadata, as a map (or String of comma-separated key=value pairs), on supported clouds; " +
+            "note often values cannot be null", null);
+    @Deprecated /** @deprecated since 0.7.0 use #USER_METADATA_MAP */
+    public static final ConfigKey<Object> USER_METADATA = USER_METADATA_MAP;
+
+    public static final ConfigKey<Boolean> INCLUDE_BROOKLYN_USER_METADATA = ConfigKeys.newBooleanConfigKey("includeBrooklynUserMetadata", 
+        "Whether to set metadata about the context of a machine, e.g. brooklyn-entity-id, brooklyn-app-name (default true)", true);
+
+    // See also SoftwareProcess.DONT_REQUIRE_TTY_FOR_SUDO
+    public static final ConfigKey<Boolean> DONT_REQUIRE_TTY_FOR_SUDO = ConfigKeys.newBooleanConfigKey("dontRequireTtyForSudo",
+            "Whether to explicitly set /etc/sudoers, so don't need tty (will leave unchanged if 'false'); " +
+            "some machines require a tty for sudo; brooklyn by default does not use a tty " +
+            "(so that it can get separate error+stdout streams); you can enable a tty as an " +
+            "option to every ssh command, or you can do it once and " +
+            "modify the machine so that a tty is not subsequently required. " +
+            "Usually used in conjunction with 'dontCreateUser' since it will prevent " +
+            "jclouds from overwriting /etc/sudoers and overriding the system default. " +
+            "When not explicitly set will be applied if 'dontCreateUser' is set.");
+
+    public static final ConfigKey<Boolean> MAP_DEV_RANDOM_TO_DEV_URANDOM = ConfigKeys.newBooleanConfigKey(
+            "installDevUrandom", "Map /dev/random to /dev/urandom to prevent halting on insufficient entropy", true);
+
+    public static final ConfigKey<String> LOCAL_TEMP_DIR = SshTool.PROP_LOCAL_TEMP_DIR;
+    
+    public static final ConfigKey<Integer> OVERRIDE_RAM = ConfigKeys.newIntegerConfigKey("overrideRam", "Custom ram value");    
+    
+    public static final ConfigKey<String> NETWORK_NAME = ConfigKeys.newStringConfigKey(
+        "networkName", "Network name or ID where the instance should be created (e.g. the subnet ID in AWS");
+
+    /**
+     * CUSTOM_MACHINE_SETUP_SCRIPT_URL accepts a URL location that points to a shell script. 
+     * Please have a look at locations/jclouds/src/main/resources/org/apache/brooklyn/location/jclouds/sample/setup-server.sh as an example
+     */
+    public static final ConfigKey<String> CUSTOM_MACHINE_SETUP_SCRIPT_URL = ConfigKeys.newStringConfigKey(
+            "setup.script", "Custom script to customize a node");
+    
+    @SuppressWarnings("serial")
+    public static final ConfigKey<List<String>> CUSTOM_MACHINE_SETUP_SCRIPT_URL_LIST = ConfigKeys.newConfigKey(new TypeToken<List<String>>() {},
+            "setup.scripts", "A list of scripts to customize a node");
+    
+    public static final ConfigKey<String> CUSTOM_MACHINE_SETUP_SCRIPT_VARS = ConfigKeys.newStringConfigKey(
+            "setup.script.vars", "vars to customize a setup.script i.e.: key1:value1,key2:value2");
+    
+    public static final ConfigKey<Boolean> GENERATE_HOSTNAME = ConfigKeys.newBooleanConfigKey(
+            "generate.hostname", "Use the nodename generated by jclouds", false);
+
+    public static final ConfigKey<Boolean> USE_PORT_FORWARDING = ConfigKeys.newBooleanConfigKey(
+            "portforwarding.enabled", 
+            "Whether to setup port-forwarding to subsequently access the VM (over the ssh port)",
+            false);
+    
+    @Beta
+    public static final ConfigKey<Boolean> USE_JCLOUDS_SSH_INIT = ConfigKeys.newBooleanConfigKey(
+            "useJcloudsSshInit", 
+            "Whether to use jclouds for initial ssh-based setup (i.e. as part of the 'TemplateOptions'); "
+                    + "if false will use core brooklyn ssh utilities. "
+                    + "This config is beta; its default could be changed and/or the option removed in an upcoming release.", 
+            true);
+    
+    @Beta
+    public static final ConfigKey<Boolean> LOOKUP_AWS_HOSTNAME = ConfigKeys.newBooleanConfigKey(
+            "lookupAwsHostname", 
+            "Whether to lookup the AWS hostname (via a command on the VM), or to just use the IP.", 
+            true);
+    
+    public static final ConfigKey<PortForwardManager> PORT_FORWARDING_MANAGER = BrooklynAccessUtils.PORT_FORWARDING_MANAGER;
+
+    public static final ConfigKey<Integer> MACHINE_CREATE_ATTEMPTS = ConfigKeys.newIntegerConfigKey(
+            "machineCreateAttempts", "Number of times to retry if jclouds fails to create a VM", 2);
+
+    public static final ConfigKey<Integer> MAX_CONCURRENT_MACHINE_CREATIONS = ConfigKeys.newIntegerConfigKey(
+            "maxConcurrentMachineCreations", "Maximum number of concurrent machine-creations", Integer.MAX_VALUE);
+
+    public static final ConfigKey<Semaphore> MACHINE_CREATION_SEMAPHORE = ConfigKeys.newConfigKey(
+            Semaphore.class, "machineCreationSemaphore", "Semaphore for controlling concurrent machine creation", null);
+    
+    @SuppressWarnings("serial")
+    public static final ConfigKey<Map<String,Object>> TEMPLATE_OPTIONS = ConfigKeys.newConfigKey(
+            new TypeToken<Map<String, Object>>() {}, "templateOptions", "Additional jclouds template options");
+
+    /**
+     * The purpose of this config is to aid deployment of blueprints to clouds where it is difficult to get nodes to
+     * communicate via private IPs. This config allows a user to overwrite private IPs as public IPs, thus ensuring
+     * that any blueprints they wish to deploy which may use private IPs still work in these clouds.
+     */
+    @Beta
+    public static final ConfigKey<Boolean> USE_MACHINE_PUBLIC_ADDRESS_AS_PRIVATE_ADDRESS = ConfigKeys.newBooleanConfigKey(
+            "useMachinePublicAddressAsPrivateAddress",
+            "When true we will use the public IP/Hostname of a JClouds Location as the private IP/Hostname",
+            false);
+
+}
+

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e2319e5e/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/api/JcloudsLocationPublic.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/api/JcloudsLocationPublic.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/api/JcloudsLocationPublic.java
new file mode 100644
index 0000000..464ac44
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/api/JcloudsLocationPublic.java
@@ -0,0 +1,57 @@
+/*
+ * 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.api;
+
+import java.util.List;
+
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineManagementMixins;
+import org.apache.brooklyn.core.mgmt.persist.LocationWithObjectStore;
+import org.apache.brooklyn.location.jclouds.JcloudsLocationConfig;
+
+import com.google.common.collect.ImmutableList;
+
+/** A public interface in front of Jclouds Location for use from downstream projects which wish
+ * to reference JcloudsLocation but not have a package-dependency on org.apache.brooklyn.location.jclouds
+ * (which pulls in many of the jclouds bundles) */
+public interface JcloudsLocationPublic extends 
+    JcloudsLocationConfig, MachineManagementMixins.RichMachineProvisioningLocation<MachineLocation>,
+    LocationWithObjectStore, MachineManagementMixins.SuspendResumeLocation 
+{
+
+    public static final String ROOT_USERNAME = "root";
+    /** these userNames are known to be the preferred/required logins in some common/default images
+     *  where root@ is not allowed to log in */
+    public static final List<String> ROOT_ALIASES = ImmutableList.of("ubuntu", "centos", "ec2-user");
+    public static final List<String> COMMON_USER_NAMES_TO_TRY = ImmutableList.<String>builder().add(ROOT_USERNAME).addAll(ROOT_ALIASES).add("admin").build();
+
+    public String getProvider();
+    
+    public String getIdentity();
+    public String getCredential();
+    
+    /** returns the location ID used by the provider, if set, e.g. us-west-1 */
+    public String getRegion();
+
+    public String getEndpoint();
+    
+    /** return a nice string suitable for display messages */
+    public String toStringNice();
+    
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/e2319e5e/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/api/JcloudsMachineLocationPublic.java
----------------------------------------------------------------------
diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/api/JcloudsMachineLocationPublic.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/api/JcloudsMachineLocationPublic.java
new file mode 100644
index 0000000..785ddb3
--- /dev/null
+++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/api/JcloudsMachineLocationPublic.java
@@ -0,0 +1,40 @@
+/*
+ * 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.api;
+
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.core.location.HasSubnetHostname;
+
+public interface JcloudsMachineLocationPublic extends MachineLocation, HasSubnetHostname {
+    
+    @Override
+    public JcloudsLocationPublic getParent();
+
+    /** Returns the node ID as known at the cloud provider. */
+    public String getJcloudsId();
+
+    /** In most clouds, the public hostname is the only way to ensure VMs in different zones can access each other. */
+    @Override
+    public String getSubnetHostname();
+
+    String getUser();
+
+    int getPort();
+    
+}