http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationConfig.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationConfig.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationConfig.java deleted file mode 100644 index 2d570ae..0000000 --- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationConfig.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * 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 brooklyn.location.jclouds; - -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Semaphore; - -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 brooklyn.config.ConfigKey; -import brooklyn.entity.basic.ConfigKeys; -import brooklyn.event.basic.BasicConfigKey; -import brooklyn.location.access.BrooklynAccessUtils; -import brooklyn.location.access.PortForwardManager; -import brooklyn.location.basic.LocationConfigKeys; -import brooklyn.location.cloud.CloudLocationConfig; -import brooklyn.location.jclouds.networking.JcloudsPortForwarderExtension; -import brooklyn.util.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 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); - public static final ConfigKey<String> KEY_PAIR = ConfigKeys.newStringConfigKey("keyPair", - "Custom keypair name to be re-used", null); - public static final ConfigKey<Boolean> AUTO_GENERATE_KEYPAIRS = ConfigKeys.newBooleanConfigKey("jclouds.openstack-nova.auto-generate-keypairs", - "Whether to generate keypairs for Nova"); - /** - * @deprecated since 0.7.0 Use {@link #AUTO_ASSIGN_FLOATING_IP} instead - */ - 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)"); - // 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", 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<Boolean> DONT_CREATE_USER = ConfigKeys.newBooleanConfigKey("dontCreateUser", - "Whether to skip creation of 'user' when provisioning machines (default false)", 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", false); - - /** - * @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<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); - - 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); - - /** @deprecated since 0.7.0; use {@link #JCLOUDS_LOCATION_CUSTOMIZERS} instead */ - @Deprecated - public static final ConfigKey<JcloudsLocationCustomizer> JCLOUDS_LOCATION_CUSTOMIZER = ConfigKeys.newConfigKey(JcloudsLocationCustomizer.class, - "customizer", "Optional location customizer"); - - @SuppressWarnings("serial") - public static final ConfigKey<Collection<JcloudsLocationCustomizer>> JCLOUDS_LOCATION_CUSTOMIZERS = ConfigKeys.newConfigKey( - new TypeToken<Collection<JcloudsLocationCustomizer>>() {}, - "customizers", "Optional location customizers"); - - /** @deprecated since 0.7.0; use {@link #JCLOUDS_LOCATION_CUSTOMIZERS} instead */ - @Deprecated - public static final ConfigKey<String> JCLOUDS_LOCATION_CUSTOMIZER_TYPE = ConfigKeys.newStringConfigKey( - "customizerType", "Optional location customizer type (to be class-loaded and constructed with no-arg constructor)"); - - /** @deprecated since 0.7.0; use {@link #JCLOUDS_LOCATION_CUSTOMIZERS} instead */ - @Deprecated - public static final ConfigKey<String> JCLOUDS_LOCATION_CUSTOMIZERS_SUPPLIER_TYPE = ConfigKeys.newStringConfigKey( - "customizersSupplierType", "Optional type of a Supplier<Collection<JcloudsLocationCustomizer>> " + - "(to be class-loaded and constructed with ConfigBag or no-arg constructor)"); - - 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/sample/script/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); - - 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", 1); - - 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<Function<Iterable<? extends Image>,Image>> IMAGE_CHOOSER = ConfigKeys.newConfigKey( - new TypeToken<Function<Iterable<? extends Image>,Image>>() {}, - "imageChooser", "An image chooser function to control which images are preferred", - new BrooklynImageChooser().chooser()); - - public static final ConfigKey<OsFamily> OS_FAMILY = ConfigKeys.newConfigKey(OsFamily.class, "osFamily", - "OS family, e.g. CentOS, Debian, RHEL, Ubuntu"); - public static final ConfigKey<String> OS_VERSION_REGEX = ConfigKeys.newStringConfigKey("osVersionRegex", - "Regular expression for the OS version to load"); - - public static final ConfigKey<OsFamily> OS_FAMILY_OVERRIDE = ConfigKeys.newConfigKey(OsFamily.class, "osFamilyOverride", - "OS family of VMs (ignores VM metadata from jclouds, and assumes this value)"); - - public static final ConfigKey<ComputeServiceRegistry> COMPUTE_SERVICE_REGISTRY = ConfigKeys.newConfigKey( - ComputeServiceRegistry.class, - "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"); - - // TODO - -// "noDefaultSshKeys" - hints that local ssh keys should not be read as defaults - // this would be useful when we need to indicate a password - -}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationCustomizer.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationCustomizer.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationCustomizer.java deleted file mode 100644 index a21891c..0000000 --- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationCustomizer.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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 brooklyn.location.jclouds; - -import org.jclouds.compute.ComputeService; -import org.jclouds.compute.domain.Template; -import org.jclouds.compute.domain.TemplateBuilder; -import org.jclouds.compute.options.TemplateOptions; - -import com.google.common.annotations.Beta; - -import brooklyn.util.config.ConfigBag; - -/** - * Customization hooks to allow apps to perform specific customisation at each stage of jclouds machine provisioning. - * For example, an app could attach an EBS volume to an EC2 node, or configure a desired availability zone. - * <p/> - * Instances will be invoked with the {@link ConfigBag} being used to obtain a machine by the - * {@link JcloudsLocation }if such a constructor exists. If not, the default no argument constructor - * will be invoked. - */ -@Beta -public interface JcloudsLocationCustomizer { - - /** - * Override to configure {@link org.jclouds.compute.domain.TemplateBuilder templateBuilder} - * before it is built and immutable. - */ - void customize(JcloudsLocation location, ComputeService computeService, TemplateBuilder templateBuilder); - - /** - * Override to configure a subclass of this with the built template, or to configure the built - * template's {@link org.jclouds.compute.options.TemplateOptions}. - * <p/> - * This method will be called before {@link #customize(JcloudsLocation, ComputeService, TemplateOptions)}. - */ - void customize(JcloudsLocation location, ComputeService computeService, Template template); - - /** - * Override to configure the {@link org.jclouds.compute.options.TemplateOptions} that will - * be used by {@link brooklyn.location.jclouds.JcloudsLocation} to obtain machines. - */ - void customize(JcloudsLocation location, ComputeService computeService, TemplateOptions templateOptions); - - /** - * Override to configure the given machine once it has been created and started by Jclouds. - * <p/> - * If {@link brooklyn.location.jclouds.JcloudsLocationConfig#WAIT_FOR_SSHABLE} is true the - * machine is guaranteed to be SSHable when this method is called. - * - * @since 0.7.0; use {@link #customize(JcloudsLocation, ComputeService, JcloudsMachineLocation)} - */ - @Deprecated - void customize(JcloudsLocation location, ComputeService computeService, JcloudsSshMachineLocation machine); - - /** - * Override to handle machine-related cleanup before Jclouds is called to release (destroy) the machine. - * - * @since 0.7.0; use {@link #preRelease(JcloudsMachineLocation)} - */ - @Deprecated - void preRelease(JcloudsSshMachineLocation machine); - - /** - * Override to handle machine-related cleanup after Jclouds is called to release (destroy) the machine. - * - * @since 0.7.0; use {@link #postRelesae(JcloudsMachineLocation)} - */ - @Deprecated - void postRelease(JcloudsSshMachineLocation machine); - - /** - * Override to configure the given machine once it has been created and started by Jclouds. - * <p/> - * If {@link brooklyn.location.jclouds.JcloudsLocationConfig#WAIT_FOR_SSHABLE} is true the - * machine is guaranteed to be SSHable when this method is called. - */ - void customize(JcloudsLocation location, ComputeService computeService, JcloudsMachineLocation machine); - - /** - * Override to handle machine-related cleanup before Jclouds is called to release (destroy) the machine. - */ - void preRelease(JcloudsMachineLocation machine); - - /** - * Override to handle machine-related cleanup after Jclouds is called to release (destroy) the machine. - */ - void postRelease(JcloudsMachineLocation machine); -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationResolver.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationResolver.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationResolver.java deleted file mode 100644 index 0a07898..0000000 --- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsLocationResolver.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * 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 brooklyn.location.jclouds; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Map; -import java.util.NoSuchElementException; - -import org.apache.brooklyn.api.management.ManagementContext; -import org.jclouds.apis.ApiMetadata; -import org.jclouds.apis.Apis; -import org.jclouds.providers.ProviderMetadata; -import org.jclouds.providers.Providers; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.location.LocationRegistry; -import brooklyn.location.LocationResolver; -import brooklyn.location.LocationSpec; -import brooklyn.location.basic.BasicLocationRegistry; -import brooklyn.location.basic.LocationConfigKeys; -import brooklyn.location.basic.LocationConfigUtils; -import brooklyn.location.basic.LocationInternal; -import brooklyn.util.text.Strings; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Maps; - -@SuppressWarnings("rawtypes") -public class JcloudsLocationResolver implements LocationResolver { - - public static final Logger log = LoggerFactory.getLogger(JcloudsLocationResolver.class); - - private static final String JCLOUDS = "jclouds"; - - public static final Map<String,ProviderMetadata> PROVIDERS = getProvidersMap(); - public static final Map<String,ApiMetadata> APIS = getApisMap(); - - private static Map<String,ProviderMetadata> getProvidersMap() { - Map<String,ProviderMetadata> result = Maps.newLinkedHashMap(); - for (ProviderMetadata p: Providers.all()) { - result.put(p.getId(), p); - } - return ImmutableMap.copyOf(result); - } - - private static Map<String,ApiMetadata> getApisMap() { - Map<String,ApiMetadata> result = Maps.newLinkedHashMap(); - for (ApiMetadata api: Apis.all()) { - result.put(api.getId(), api); - } - return ImmutableMap.copyOf(result); - } - - public static final Collection<String> AWS_REGIONS = Arrays.asList( - // from http://docs.amazonwebservices.com/general/latest/gr/rande.html as of Apr 2012. - // it is suggested not to maintain this list here, instead to require aws-ec2 explicitly named. - "eu-west-1","us-east-1","us-west-1","us-west-2","ap-southeast-1","ap-northeast-1","sa-east-1"); - - private ManagementContext managementContext; - - @Override - public void init(ManagementContext managementContext) { - this.managementContext = checkNotNull(managementContext, "managementContext"); - } - - protected class JcloudsSpecParser { - String providerOrApi; - String parameter; - - public JcloudsSpecParser parse(String spec, boolean dryrun) { - JcloudsSpecParser result = new JcloudsSpecParser(); - int split = spec.indexOf(':'); - if (split<0) { - if (spec.equalsIgnoreCase(getPrefix())) { - if (dryrun) return null; - throw new IllegalArgumentException("Cannot use '"+spec+"' as a location ID; it is insufficient. "+ - "Try jclouds:aws-ec2 (for example)."); - } - result.providerOrApi = spec; - result.parameter = null; - } else { - result.providerOrApi = spec.substring(0, split); - result.parameter = spec.substring(split+1); - int numJcloudsPrefixes = 0; - while (result.providerOrApi.equalsIgnoreCase(getPrefix())) { - //strip any number of jclouds: prefixes, for use by static "resolve" method - numJcloudsPrefixes++; - result.providerOrApi = result.parameter; - result.parameter = null; - split = result.providerOrApi.indexOf(':'); - if (split>=0) { - result.parameter = result.providerOrApi.substring(split+1); - result.providerOrApi = result.providerOrApi.substring(0, split); - } - } - if (!dryrun && numJcloudsPrefixes > 1) { - log.warn("Use of deprecated location spec '"+spec+"'; in future use a single \"jclouds\" prefix"); - } - } - - if (result.parameter==null && AWS_REGIONS.contains(result.providerOrApi)) { - // treat amazon as a default - result.parameter = result.providerOrApi; - result.providerOrApi = "aws-ec2"; - if (!dryrun) - log.warn("Use of deprecated location '"+result.parameter+"'; in future refer to with explicit " + - "provider '"+result.providerOrApi+":"+result.parameter+"'"); - } - - return result; - } - - public boolean isProvider() { - return PROVIDERS.containsKey(providerOrApi); - } - - public boolean isApi() { - return APIS.containsKey(providerOrApi); - } - - public String getProviderOrApi() { - return providerOrApi; - } - - public String getParameter() { - return parameter; - } - } - - @Override - @SuppressWarnings("unchecked") - public JcloudsLocation newLocationFromString(Map locationFlags, String spec, brooklyn.location.LocationRegistry registry) { - Map globalProperties = registry.getProperties(); - - JcloudsSpecParser details = new JcloudsSpecParser().parse(spec, false); - String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName()); - - boolean isProvider = details.isProvider(); - String providerOrApi = details.providerOrApi; - // gce claims to be an api ... perhaps just a bug? email sent to jclouds dev list, 28 mar 2014 - isProvider = isProvider || "google-compute-engine".equals(providerOrApi); - - if (Strings.isEmpty(providerOrApi)) { - throw new IllegalArgumentException("Cloud provider/API type not specified in spec \""+spec+"\""); - } - if (!isProvider && !details.isApi()) { - throw new NoSuchElementException("Cloud provider/API type "+providerOrApi+" is not supported by jclouds"); - } - - // For everything in brooklyn.properties, only use things with correct prefix (and remove that prefix). - // But for everything passed in via locationFlags, pass those as-is. - // TODO Should revisit the locationFlags: where are these actually used? Reason accepting properties without - // full prefix is that the map's context is explicitly this location, rather than being generic properties. - Map allProperties = getAllProperties(registry, globalProperties); - String regionOrEndpoint = details.parameter; - if (regionOrEndpoint==null && isProvider) regionOrEndpoint = (String)locationFlags.get(LocationConfigKeys.CLOUD_REGION_ID.getName()); - Map jcloudsProperties = new JcloudsPropertiesFromBrooklynProperties().getJcloudsProperties(providerOrApi, regionOrEndpoint, namedLocation, allProperties); - jcloudsProperties.putAll(locationFlags); - - if (regionOrEndpoint!=null) { - // apply the regionOrEndpoint (e.g. from the parameter) as appropriate -- but only if it has not been overridden - if (isProvider) { - // providers from ServiceLoader take a location (endpoint already configured), and optionally a region name - // NB blank might be supplied if spec string is "mycloud:" -- that should be respected, - // whereas no parameter/regionName ie null value -- "mycloud" -- means don't set - if (Strings.isBlank(Strings.toString(jcloudsProperties.get(JcloudsLocationConfig.CLOUD_REGION_ID.getName())))) - jcloudsProperties.put(JcloudsLocationConfig.CLOUD_REGION_ID.getName(), regionOrEndpoint); - } else { - // other "providers" are APIs so take an _endpoint_ (but not a location); - // see note above re null here - if (Strings.isBlank(Strings.toString(jcloudsProperties.get(JcloudsLocationConfig.CLOUD_ENDPOINT.getName())))) - jcloudsProperties.put(JcloudsLocationConfig.CLOUD_ENDPOINT.getName(), regionOrEndpoint); - } - } - - return managementContext.getLocationManager().createLocation(LocationSpec.create(getLocationClass()) - .configure(LocationConfigUtils.finalAndOriginalSpecs(spec, jcloudsProperties, globalProperties, namedLocation)) - .configure(jcloudsProperties) ); - } - - @SuppressWarnings("unchecked") - private Map getAllProperties(brooklyn.location.LocationRegistry registry, Map<?,?> properties) { - Map<Object,Object> allProperties = Maps.newHashMap(); - if (registry!=null) allProperties.putAll(registry.getProperties()); - allProperties.putAll(properties); - return allProperties; - } - - @Override - public String getPrefix() { - return JCLOUDS; - } - - protected Class<? extends JcloudsLocation> getLocationClass() { - return JcloudsLocation.class; - } - - @Override - public boolean accepts(String spec, LocationRegistry registry) { - if (BasicLocationRegistry.isResolverPrefixForSpec(this, spec, true)) return true; - JcloudsSpecParser details = new JcloudsSpecParser().parse(spec, true); - if (details==null) return false; - if (details.isProvider() || details.isApi()) return true; - return false; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineLocation.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineLocation.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineLocation.java deleted file mode 100644 index accda93..0000000 --- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineLocation.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 brooklyn.location.jclouds; - -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.domain.Template; - -import brooklyn.location.MachineLocation; -import brooklyn.location.basic.HasSubnetHostname; - -public interface JcloudsMachineLocation extends MachineLocation, HasSubnetHostname { - - @Override - public JcloudsLocation getParent(); - - public NodeMetadata getNode(); - - 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/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineNamer.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineNamer.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineNamer.java deleted file mode 100644 index 301ed43..0000000 --- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsMachineNamer.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 brooklyn.location.jclouds; - -import brooklyn.location.cloud.names.BasicCloudMachineNamer; -import brooklyn.util.config.ConfigBag; - -public class JcloudsMachineNamer extends BasicCloudMachineNamer { - - @Override - /** returns the max length of a VM name for the cloud specified in setup; - * this value is typically decremented by 9 to make room for jclouds labels */ - public Integer getCustomMaxNameLength(ConfigBag setup) { - // otherwise, for some known clouds which only allow a short name, use that length - if ("vcloud".equals( setup.peek(JcloudsLocationConfig.CLOUD_PROVIDER) )) - return 24; - if ("abiquo".equals( setup.peek(JcloudsLocationConfig.CLOUD_PROVIDER) )) - return 39; - if ("google-compute-engine".equals( setup.peek(JcloudsLocationConfig.CLOUD_PROVIDER) )) - return 39; - if ("softlayer".equals( setup.peek(JcloudsLocationConfig.CLOUD_PROVIDER) )) - return 55; - // TODO other cloud max length rules - - return null; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPredicates.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPredicates.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPredicates.java deleted file mode 100644 index 9220a28..0000000 --- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPredicates.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 brooklyn.location.jclouds; - -import org.jclouds.compute.domain.ComputeMetadata; -import org.jclouds.domain.Location; - -import com.google.common.base.Predicate; - -public class JcloudsPredicates { - - public static class NodeInLocation implements Predicate<ComputeMetadata> { - private String regionId; - private boolean matchNullLocations; - public NodeInLocation(String regionId, boolean matchNullLocations) { - this.regionId = regionId; - this.matchNullLocations = matchNullLocations; - } - @Override - public boolean apply(ComputeMetadata input) { - boolean exclude; - Location nodeLocation = input.getLocation(); - if (nodeLocation==null) return matchNullLocations; - - exclude = true; - while (nodeLocation!=null && exclude) { - if (nodeLocation.getId().equals(regionId)) { - // matching location info found - exclude = false; - } - nodeLocation = nodeLocation.getParent(); - } - return !exclude; - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynProperties.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynProperties.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynProperties.java deleted file mode 100644 index 19b6c7a..0000000 --- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsPropertiesFromBrooklynProperties.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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 brooklyn.location.jclouds; - -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.config.ConfigUtils; -import brooklyn.location.basic.DeprecatedKeysMappingBuilder; -import brooklyn.location.basic.LocationConfigKeys; -import brooklyn.location.basic.LocationPropertiesFromBrooklynProperties; -import brooklyn.util.config.ConfigBag; -import brooklyn.util.javalang.JavaClassNames; - -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; - -/** - * <p> - * The properties to use for a jclouds location, loaded from brooklyn.properties file - * </p> - * - * Preferred format is: - * - * <ul> - * <li> - * brooklyn.location.named.NAME.key - * </li> - * <li> - * brooklyn.location.jclouds.PROVIDER.key - * </li> - * </ul> - * - * <p> - * A number of properties are also supported, listed in the {@code JcloudsLocationConfig} - * </p> - * - * @author andrea - **/ -public class JcloudsPropertiesFromBrooklynProperties extends LocationPropertiesFromBrooklynProperties { - - private static final Logger LOG = LoggerFactory.getLogger(JcloudsPropertiesFromBrooklynProperties.class); - - @SuppressWarnings("deprecation") - private static final Map<String, String> DEPRECATED_JCLOUDS_KEYS_MAPPING = new DeprecatedKeysMappingBuilder(LOG) - .putAll(LocationPropertiesFromBrooklynProperties.DEPRECATED_KEYS_MAPPING) - .camelToHyphen(JcloudsLocation.IMAGE_ID) - .camelToHyphen(JcloudsLocation.IMAGE_NAME_REGEX) - .camelToHyphen(JcloudsLocation.IMAGE_DESCRIPTION_REGEX) - .camelToHyphen(JcloudsLocation.HARDWARE_ID) - .build(); - - @Override - public Map<String, Object> getLocationProperties(String provider, String namedLocation, Map<String, ?> properties) { - throw new UnsupportedOperationException("Instead use getJcloudsProperties(String,String,String,Map)"); - } - - /** - * @see LocationPropertiesFromBrooklynProperties#getLocationProperties(String, String, Map) - */ - public Map<String, Object> getJcloudsProperties(String providerOrApi, String regionOrEndpoint, String namedLocation, Map<String, ?> properties) { - if(Strings.isNullOrEmpty(namedLocation) && Strings.isNullOrEmpty(providerOrApi)) { - throw new IllegalArgumentException("Neither cloud provider/API nor location name have been specified correctly"); - } - - ConfigBag jcloudsProperties = ConfigBag.newInstance(); - String provider = getProviderName(providerOrApi, namedLocation, properties); - - // named properties are preferred over providerOrApi properties - jcloudsProperties.put(LocationConfigKeys.CLOUD_PROVIDER, provider); - jcloudsProperties.putAll(transformDeprecated(getGenericLocationSingleWordProperties(properties))); - jcloudsProperties.putAll(transformDeprecated(getGenericJcloudsSingleWordProperties(providerOrApi, properties))); - jcloudsProperties.putAll(transformDeprecated(getProviderOrApiJcloudsProperties(providerOrApi, properties))); - jcloudsProperties.putAll(transformDeprecated(getRegionJcloudsProperties(providerOrApi, regionOrEndpoint, properties))); - if (!Strings.isNullOrEmpty(namedLocation)) jcloudsProperties.putAll(transformDeprecated(getNamedJcloudsProperties(namedLocation, properties))); - setLocalTempDir(properties, jcloudsProperties); - - return jcloudsProperties.getAllConfigRaw(); - } - - protected String getProviderName(String providerOrApi, String namedLocationName, Map<String, ?> properties) { - String provider = providerOrApi; - if (!Strings.isNullOrEmpty(namedLocationName)) { - String providerDefinition = (String) properties.get(String.format("brooklyn.location.named.%s", namedLocationName)); - if (providerDefinition!=null) { - String provider2 = getProviderFromDefinition(providerDefinition); - if (provider==null) { - // 0.7.0 25 Feb -- is this even needed? - LOG.warn(JavaClassNames.niceClassAndMethod()+" NOT set with provider, inferring from locationName "+namedLocationName+" as "+provider2); - provider = provider2; - } else if (!provider.equals(provider2)) { - // 0.7.0 25 Feb -- previously we switched to provider2 in this case, but that was wrong when - // working with chains of names; not sure why this case would ever occur (apart from tests which have been changed) - // 28 Mar seen this warning many times but only in cases when NOT changing is the right behaviour - LOG.debug(JavaClassNames.niceClassAndMethod()+" NOT changing provider from "+provider+" to candidate "+provider2); - } - } - } - return provider; - } - - protected String getProviderFromDefinition(String definition) { - return Iterables.get(Splitter.on(":").split(definition), 1); - } - - protected Map<String, Object> getGenericJcloudsSingleWordProperties(String providerOrApi, Map<String, ?> properties) { - if (Strings.isNullOrEmpty(providerOrApi)) return Maps.newHashMap(); - String deprecatedPrefix = "brooklyn.jclouds."; - String preferredPrefix = "brooklyn.location.jclouds."; - return getMatchingSingleWordProperties(preferredPrefix, deprecatedPrefix, properties); - } - - protected Map<String, Object> getProviderOrApiJcloudsProperties(String providerOrApi, Map<String, ?> properties) { - if (Strings.isNullOrEmpty(providerOrApi)) return Maps.newHashMap(); - String preferredPrefix = String.format("brooklyn.location.jclouds.%s.", providerOrApi); - String deprecatedPrefix = String.format("brooklyn.jclouds.%s.", providerOrApi); - - return getMatchingProperties(preferredPrefix, deprecatedPrefix, properties); - } - - protected Map<String, Object> getRegionJcloudsProperties(String providerOrApi, String regionName, Map<String, ?> properties) { - if (Strings.isNullOrEmpty(providerOrApi) || Strings.isNullOrEmpty(regionName)) return Maps.newHashMap(); - String preferredPrefix = String.format("brooklyn.location.jclouds.%s@%s.", providerOrApi, regionName); - String deprecatedPrefix = String.format("brooklyn.jclouds.%s@%s.", providerOrApi, regionName); - - return getMatchingProperties(preferredPrefix, deprecatedPrefix, properties); - } - - protected Map<String, Object> getNamedJcloudsProperties(String locationName, Map<String, ?> properties) { - if(locationName == null) return Maps.newHashMap(); - String prefix = String.format("brooklyn.location.named.%s.", locationName); - return ConfigUtils.filterForPrefixAndStrip(properties, prefix).asMapWithStringKeys(); - } - - @Override - protected Map<String, String> getDeprecatedKeysMapping() { - return DEPRECATED_JCLOUDS_KEYS_MAPPING; - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java deleted file mode 100644 index 205771a..0000000 --- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsSshMachineLocation.java +++ /dev/null @@ -1,340 +0,0 @@ -/* - * 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 brooklyn.location.jclouds; - -import static brooklyn.util.JavaGroovyEquivalents.groovyTruth; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import javax.annotation.Nullable; - -import org.jclouds.compute.ComputeServiceContext; -import org.jclouds.compute.callables.RunScriptOnNode; -import org.jclouds.compute.domain.ExecResponse; -import org.jclouds.compute.domain.Hardware; -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.domain.OperatingSystem; -import org.jclouds.compute.domain.OsFamily; -import org.jclouds.compute.domain.Processor; -import org.jclouds.compute.domain.Template; -import org.jclouds.compute.options.RunScriptOptions; -import org.jclouds.domain.LoginCredentials; -import org.jclouds.scriptbuilder.domain.InterpretableStatement; -import org.jclouds.scriptbuilder.domain.Statement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.location.HardwareDetails; -import brooklyn.location.MachineDetails; -import brooklyn.location.OsDetails; -import brooklyn.location.basic.BasicHardwareDetails; -import brooklyn.location.basic.BasicMachineDetails; -import brooklyn.location.basic.BasicOsDetails; -import brooklyn.location.basic.HasSubnetHostname; -import brooklyn.location.basic.SshMachineLocation; -import brooklyn.util.exceptions.Exceptions; -import brooklyn.util.flags.SetFromFlag; -import brooklyn.util.net.Networking; -import brooklyn.util.text.Strings; - -import com.google.common.base.Objects; -import com.google.common.base.Optional; -import com.google.common.base.Throwables; -import com.google.common.collect.ImmutableMap; -import com.google.common.net.HostAndPort; -import com.google.common.util.concurrent.ListenableFuture; - -public class JcloudsSshMachineLocation extends SshMachineLocation implements JcloudsMachineLocation { - - private static final Logger LOG = LoggerFactory.getLogger(JcloudsSshMachineLocation.class); - private static final long serialVersionUID = -443866395634771659L; - - @SetFromFlag - JcloudsLocation jcloudsParent; - - @SetFromFlag - NodeMetadata node; - - @SetFromFlag - Template template; - - private RunScriptOnNode.Factory runScriptFactory; - - public JcloudsSshMachineLocation() { - } - - /** - * @deprecated since 0.6; use LocationSpec (which calls no-arg constructor) - */ - @Deprecated - public JcloudsSshMachineLocation(Map<?,?> flags, JcloudsLocation jcloudsParent, NodeMetadata node) { - super(flags); - this.jcloudsParent = jcloudsParent; - this.node = node; - - init(); - } - - @Override - public void init() { - if (jcloudsParent != null) { - super.init(); - ComputeServiceContext context = jcloudsParent.getComputeService().getContext(); - runScriptFactory = context.utils().injector().getInstance(RunScriptOnNode.Factory.class); - } else { - // TODO Need to fix the rebind-detection, and not call init() on rebind. - // This will all change when locations become entities. - if (LOG.isDebugEnabled()) LOG.debug("Not doing init() of {} because parent not set; presuming rebinding", this); - } - } - - @Override - public void rebind() { - super.rebind(); - ComputeServiceContext context = jcloudsParent.getComputeService().getContext(); - runScriptFactory = context.utils().injector().getInstance(RunScriptOnNode.Factory.class); - } - - @Override - public String toVerboseString() { - return Objects.toStringHelper(this).omitNullValues() - .add("id", getId()).add("name", getDisplayName()) - .add("user", getUser()).add("address", getAddress()).add("port", getConfig(SSH_PORT)) - .add("node", getNode()) - .add("jcloudsId", getJcloudsId()) - .add("privateAddresses", node.getPrivateAddresses()) - .add("publicAddresses", node.getPublicAddresses()) - .add("parentLocation", getParent()) - .add("osDetails", getOsDetails()) - .toString(); - } - - @Override - public NodeMetadata getNode() { - return node; - } - - @Override - public Template getTemplate() { - return template; - } - - @Override - public JcloudsLocation getParent() { - return jcloudsParent; - } - - @Override - public String getHostname() { - return node.getHostname(); - } - - /** In most clouds, the public hostname is the only way to ensure VMs in different zones can access each other. */ - @Override - public Set<String> getPublicAddresses() { - return node.getPublicAddresses(); - } - - @Override - public Set<String> getPrivateAddresses() { - return node.getPrivateAddresses(); - } - - @Override - public String getSubnetHostname() { - String privateHostname = jcloudsParent.getPrivateHostname(node, Optional.<HostAndPort>absent(), config().getBag()); - return privateHostname; - } - - @Override - public String getSubnetIp() { - Optional<String> privateAddress = getPrivateAddress(); - if (privateAddress.isPresent()) { - return privateAddress.get(); - } - - String hostname = jcloudsParent.getPublicHostname(node, Optional.<HostAndPort>absent(), config().getBag()); - if (hostname != null && !Networking.isValidIp4(hostname)) { - try { - return InetAddress.getByName(hostname).getHostAddress(); - } catch (UnknownHostException e) { - LOG.debug("Cannot resolve IP for hostname {} of machine {} (so returning hostname): {}", new Object[] {hostname, this, e}); - } - } - return hostname; - } - - protected Optional<String> getPrivateAddress() { - if (groovyTruth(node.getPrivateAddresses())) { - for (String p : node.getPrivateAddresses()) { - // disallow local only addresses - if (Networking.isLocalOnly(p)) continue; - // other things may be public or private, but either way, return it - return Optional.of(p); - } - } - return Optional.absent(); - } - - @Override - public String getJcloudsId() { - return node.getId(); - } - - /** executes the given statements on the server using jclouds ScriptBuilder, - * wrapping in a script which is polled periodically. - * the output is returned once the script completes (disadvantage compared to other methods) - * but the process is nohupped and the SSH session is not kept, - * so very useful for long-running processes - */ - public ListenableFuture<ExecResponse> submitRunScript(String ...statements) { - return submitRunScript(new InterpretableStatement(statements)); - } - public ListenableFuture<ExecResponse> submitRunScript(Statement script) { - return submitRunScript(script, new RunScriptOptions()); - } - public ListenableFuture<ExecResponse> submitRunScript(Statement script, RunScriptOptions options) { - return runScriptFactory.submit(node, script, options); - } - /** uses submitRunScript to execute the commands, and throws error if it fails or returns non-zero */ - public void execRemoteScript(String ...commands) { - try { - ExecResponse result = submitRunScript(commands).get(); - if (result.getExitStatus()!=0) - throw new IllegalStateException("Error running remote commands (code "+result.getExitStatus()+"): "+commands); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - throw Throwables.propagate(e); - } catch (ExecutionException e) { - throw Throwables.propagate(e); - } - } - - /** - * Retrieves the password for this VM, if one exists. The behaviour/implementation is different for different clouds. - * e.g. on Rackspace, the password for a windows VM is available immediately; on AWS-EC2, for a Windows VM you need - * to poll repeatedly until the password is available which can take up to 15 minutes. - */ - public String waitForPassword() { - // TODO Hacky; don't want aws specific stuff here but what to do?! - if (jcloudsParent.getProvider().equals("aws-ec2")) { - try { - return JcloudsUtil.waitForPasswordOnAws(jcloudsParent.getComputeService(), node, 15, TimeUnit.MINUTES); - } catch (TimeoutException e) { - throw Throwables.propagate(e); - } - } else { - LoginCredentials credentials = node.getCredentials(); - return (credentials != null) ? credentials.getPassword() : null; - } - } - - @Override - protected MachineDetails inferMachineDetails() { - Optional<String> name = Optional.absent(); - Optional<String> version = Optional.absent(); - Optional<String> architecture = Optional.absent(); - - OperatingSystem os = node.getOperatingSystem(); - if (os == null && getTemplate() != null && getTemplate().getImage() != null) - // some nodes (eg cloudstack, gce) might not get OS available on the node, - // so also try taking it from the template if available - os = getTemplate().getImage().getOperatingSystem(); - - if (os != null) { - // Note using family rather than name. Name is often unset. - name = Optional.fromNullable(os.getFamily() != null && !OsFamily.UNRECOGNIZED.equals(os.getFamily()) ? os.getFamily().toString() : null); - version = Optional.fromNullable(!Strings.isBlank(os.getVersion()) ? os.getVersion() : null); - // Using is64Bit rather then getArch because getArch often returns "paravirtual" - architecture = Optional.fromNullable(os.is64Bit() ? BasicOsDetails.OsArchs.X_86_64 : BasicOsDetails.OsArchs.I386); - } - - Hardware hardware = node.getHardware(); - Optional<Integer> ram = hardware==null ? Optional.<Integer>absent() : Optional.fromNullable(hardware.getRam()); - Optional<Integer> cpus = hardware==null ? Optional.<Integer>absent() : Optional.fromNullable(hardware.getProcessors() != null ? hardware.getProcessors().size() : null); - - // Skip superclass' SSH to machine if all data is present, otherwise defer to super - if (name.isPresent() && version.isPresent() && architecture.isPresent() && ram.isPresent() && cpus.isPresent()) { - if (LOG.isTraceEnabled()) { - LOG.trace("Gathered machine details from Jclouds, skipping SSH test on {}", this); - } - OsDetails osD = new BasicOsDetails(name.get(), architecture.get(), version.get()); - HardwareDetails hwD = new BasicHardwareDetails(cpus.get(), ram.get()); - return new BasicMachineDetails(hwD, osD); - } else if ("false".equalsIgnoreCase(getConfig(JcloudsLocation.WAIT_FOR_SSHABLE))) { - if (LOG.isTraceEnabled()) { - LOG.trace("Machine details for {} missing from Jclouds, but skipping SSH test because waitForSshable=false. name={}, version={}, " + - "arch={}, ram={}, #cpus={}", - new Object[]{this, name, version, architecture, ram, cpus}); - } - OsDetails osD = new BasicOsDetails(name.orNull(), architecture.orNull(), version.orNull()); - HardwareDetails hwD = new BasicHardwareDetails(cpus.orNull(), ram.orNull()); - return new BasicMachineDetails(hwD, osD); - } else { - if (LOG.isTraceEnabled()) { - LOG.trace("Machine details for {} missing from Jclouds, using SSH test instead. name={}, version={}, " + - "arch={}, ram={}, #cpus={}", - new Object[]{this, name, version, architecture, ram, cpus}); - } - return super.inferMachineDetails(); - } - } - - @Override - public Map<String, String> toMetadataRecord() { - Hardware hardware = node.getHardware(); - List<? extends Processor> processors = (hardware != null) ? hardware.getProcessors() : null; - - ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); - builder.putAll(super.toMetadataRecord()); - putIfNotNull(builder, "provider", getParent().getProvider()); - putIfNotNull(builder, "account", getParent().getIdentity()); - putIfNotNull(builder, "serverId", node.getProviderId()); - putIfNotNull(builder, "imageId", node.getImageId()); - putIfNotNull(builder, "instanceTypeName", (hardware != null ? hardware.getName() : null)); - putIfNotNull(builder, "instanceTypeId", (hardware != null ? hardware.getProviderId() : null)); - putIfNotNull(builder, "ram", "" + (hardware != null ? hardware.getRam() : null)); - putIfNotNull(builder, "cpus", "" + (processors != null ? processors.size() : null)); - - try { - OsDetails osDetails = getOsDetails(); - putIfNotNull(builder, "osName", osDetails.getName()); - putIfNotNull(builder, "osArch", osDetails.getArch()); - putIfNotNull(builder, "is64bit", osDetails.is64bit() ? "true" : "false"); - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - LOG.warn("Unable to get OS Details for "+node+"; continuing", e); - } - - return builder.build(); - } - - private void putIfNotNull(ImmutableMap.Builder<String, String> builder, String key, @Nullable String value) { - if (value != null) builder.put(key, value); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/e2c57058/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsUtil.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsUtil.java b/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsUtil.java deleted file mode 100644 index 90c6035..0000000 --- a/locations/jclouds/src/main/java/brooklyn/location/jclouds/JcloudsUtil.java +++ /dev/null @@ -1,448 +0,0 @@ -/* - * 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 brooklyn.location.jclouds; - -import static org.jclouds.compute.options.RunScriptOptions.Builder.overrideLoginCredentials; -import static org.jclouds.compute.util.ComputeServiceUtils.execHttpResponse; -import static org.jclouds.scriptbuilder.domain.Statements.appendFile; -import static org.jclouds.scriptbuilder.domain.Statements.exec; -import static org.jclouds.scriptbuilder.domain.Statements.interpret; -import static org.jclouds.scriptbuilder.domain.Statements.newStatementList; - -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import javax.annotation.Nullable; - -import org.jclouds.Constants; -import org.jclouds.ContextBuilder; -import org.jclouds.aws.ec2.AWSEC2Api; -import org.jclouds.blobstore.BlobStoreContext; -import org.jclouds.compute.ComputeService; -import org.jclouds.compute.ComputeServiceContext; -import org.jclouds.compute.RunScriptOnNodesException; -import org.jclouds.compute.domain.ExecResponse; -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.domain.OperatingSystem; -import org.jclouds.compute.options.RunScriptOptions; -import org.jclouds.compute.predicates.OperatingSystemPredicates; -import org.jclouds.docker.DockerApi; -import org.jclouds.docker.domain.Container; -import org.jclouds.domain.LoginCredentials; -import org.jclouds.ec2.compute.domain.PasswordDataAndPrivateKey; -import org.jclouds.ec2.compute.functions.WindowsLoginCredentialsFromEncryptedData; -import org.jclouds.ec2.domain.PasswordData; -import org.jclouds.ec2.features.WindowsApi; -import org.jclouds.encryption.bouncycastle.config.BouncyCastleCryptoModule; -import org.jclouds.logging.slf4j.config.SLF4JLoggingModule; -import org.jclouds.scriptbuilder.domain.Statement; -import org.jclouds.scriptbuilder.domain.Statements; -import org.jclouds.ssh.SshClient; -import org.jclouds.sshj.config.SshjSshClientModule; -import org.jclouds.util.Predicates2; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.annotations.Beta; -import com.google.common.base.Charsets; -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; -import com.google.common.io.Files; -import com.google.inject.Module; - -import brooklyn.entity.basic.Sanitizer; -import brooklyn.util.collections.MutableList; -import brooklyn.util.config.ConfigBag; -import brooklyn.util.exceptions.Exceptions; -import brooklyn.util.net.Protocol; -import brooklyn.util.ssh.BashCommands; -import brooklyn.util.ssh.IptablesCommands; -import brooklyn.util.ssh.IptablesCommands.Chain; -import brooklyn.util.ssh.IptablesCommands.Policy; - -public class JcloudsUtil implements JcloudsLocationConfig { - - // TODO Review what utility methods are needed, and what is now supported in jclouds 1.1 - - private static final Logger LOG = LoggerFactory.getLogger(JcloudsUtil.class); - - /** - * @deprecated since 0.7; see {@link BashCommands} - */ - @Deprecated - public static String APT_INSTALL = "apt-get install -f -y -qq --force-yes"; - - /** - * @deprecated since 0.7; see {@link BashCommands} - */ - @Deprecated - public static String installAfterUpdatingIfNotPresent(String cmd) { - String aptInstallCmd = APT_INSTALL + " " + cmd; - return String.format("which %s || (%s || (apt-get update && %s))", cmd, aptInstallCmd, aptInstallCmd); - } - - /** - * @deprecated since 0.7 - */ - @Deprecated - public static Predicate<NodeMetadata> predicateMatchingById(final NodeMetadata node) { - return predicateMatchingById(node.getId()); - } - - /** - * @deprecated since 0.7 - */ - @Deprecated - public static Predicate<NodeMetadata> predicateMatchingById(final String id) { - Predicate<NodeMetadata> nodePredicate = new Predicate<NodeMetadata>() { - @Override public boolean apply(NodeMetadata arg0) { - return id.equals(arg0.getId()); - } - @Override public String toString() { - return "node.id=="+id; - } - }; - return nodePredicate; - } - - /** - * @deprecated since 0.7; see {@link IptablesCommands} - */ - @Deprecated - public static Statement authorizePortInIpTables(int port) { - // TODO gogrid rules only allow ports 22, 3389, 80 and 443. - // the first rule will be ignored, so we have to apply this - // directly - return Statements.newStatementList(// just in case iptables are being used, try to open 8080 - exec("iptables -I INPUT 1 -p tcp --dport " + port + " -j ACCEPT"),// - exec("iptables -I RH-Firewall-1-INPUT 1 -p tcp --dport " + port + " -j ACCEPT"),// - exec("iptables-save")); - } - - /** - * @throws RunScriptOnNodesException - * @throws IllegalStateException If do not find exactly one matching node - * - * @deprecated since 0.7 - */ - @Deprecated - public static ExecResponse runScriptOnNode(ComputeService computeService, NodeMetadata node, Statement statement, String scriptName) throws RunScriptOnNodesException { - // TODO Includes workaround for NodeMetadata's equals/hashcode method being wrong. - - Map<? extends NodeMetadata, ExecResponse> scriptResults = computeService.runScriptOnNodesMatching( - JcloudsUtil.predicateMatchingById(node), - statement, - new RunScriptOptions().nameTask(scriptName)); - if (scriptResults.isEmpty()) { - throw new IllegalStateException("No matching node found when executing script "+scriptName+": expected="+node); - } else if (scriptResults.size() > 1) { - throw new IllegalStateException("Multiple nodes matched predicate: id="+node.getId()+"; expected="+node+"; actual="+scriptResults.keySet()); - } else { - return Iterables.getOnlyElement(scriptResults.values()); - } - } - - /** - * @deprecated since 0.7; {@see #installJavaAndCurl(OperatingSystem)} - */ - @Deprecated - public static final Statement APT_RUN_SCRIPT = newStatementList(// - exec(installAfterUpdatingIfNotPresent("curl")),// - exec("(which java && java -fullversion 2>&1|egrep -q 1.6 ) ||"),// - execHttpResponse(URI.create("http://whirr.s3.amazonaws.com/0.2.0-incubating-SNAPSHOT/sun/java/install")),// - exec(new StringBuilder()// - .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")// - // jeos hasn't enough room! - .append("rm -rf /var/cache/apt /usr/lib/vmware-tools\n")// - .append("echo \"export PATH=\\\"$JAVA_HOME/bin/:$PATH\\\"\" >> /root/.bashrc")// - .toString())); - - /** - * @deprecated since 0.7; {@see #installJavaAndCurl(OperatingSystem)} - */ - @Deprecated - public static final Statement YUM_RUN_SCRIPT = newStatementList( - exec("which curl ||yum --nogpgcheck -y install curl"),// - exec("(which java && java -fullversion 2>&1|egrep -q 1.6 ) ||"),// - execHttpResponse(URI.create("http://whirr.s3.amazonaws.com/0.2.0-incubating-SNAPSHOT/sun/java/install")),// - exec(new StringBuilder()// - .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n") // - .append("echo \"export PATH=\\\"$JAVA_HOME/bin/:$PATH\\\"\" >> /root/.bashrc")// - .toString())); - - /** - * @deprecated since 0.7; {@see #installJavaAndCurl(OperatingSystem)} - */ - @Deprecated - public static final Statement ZYPPER_RUN_SCRIPT = exec(new StringBuilder()// - .append("echo nameserver 208.67.222.222 >> /etc/resolv.conf\n")// - .append("which curl || zypper install curl\n")// - .append("(which java && java -fullversion 2>&1|egrep -q 1.6 ) || zypper install java-1.6.0-openjdk\n")// - .toString()); - - // Code taken from RunScriptData - /** - * @deprecated since 0.7; see {@link BashCommands#installJava7()} and {@link BashCommands#INSTALL_CURL} - */ - @Deprecated - public static Statement installJavaAndCurl(OperatingSystem os) { - if (os == null || OperatingSystemPredicates.supportsApt().apply(os)) - return APT_RUN_SCRIPT; - else if (OperatingSystemPredicates.supportsYum().apply(os)) - return YUM_RUN_SCRIPT; - else if (OperatingSystemPredicates.supportsZypper().apply(os)) - return ZYPPER_RUN_SCRIPT; - else - throw new IllegalArgumentException("don't know how to handle" + os.toString()); - } - - /** - * @deprecated since 0.7; see {@link ComputeServiceRegistry#findComputeService(ConfigBag, boolean)} - */ - @Deprecated - public static ComputeService findComputeService(ConfigBag conf) { - return ComputeServiceRegistryImpl.INSTANCE.findComputeService(conf, true); - } - - /** - * @deprecated since 0.7; see {@link ComputeServiceRegistry#findComputeService(ConfigBag, boolean)} - */ - @Deprecated - public static ComputeService findComputeService(ConfigBag conf, boolean allowReuse) { - return ComputeServiceRegistryImpl.INSTANCE.findComputeService(conf, allowReuse); - } - - /** - * Returns the jclouds modules we typically install - * - * @deprecated since 0.7; see {@link ComputeServiceRegistry} - */ - @Deprecated - public static ImmutableSet<Module> getCommonModules() { - return ImmutableSet.<Module> of( - new SshjSshClientModule(), - new SLF4JLoggingModule(), - new BouncyCastleCryptoModule()); - } - - /** - * Temporary constructor to address https://issues.apache.org/jira/browse/JCLOUDS-615. - * <p> - * See https://issues.apache.org/jira/browse/BROOKLYN-6 . - * When https://issues.apache.org/jira/browse/JCLOUDS-615 is fixed in the jclouds we use, - * we can remove the useSoftlayerFix argument. - * <p> - * (Marked Beta as that argument will likely be removed.) - * - * @since 0.7.0 */ - @Beta - public static BlobStoreContext newBlobstoreContext(String provider, @Nullable String endpoint, String identity, String credential) { - Properties overrides = new Properties(); - // * Java 7,8 bug workaround - sockets closed by GC break the internal bookkeeping - // of HttpUrlConnection, leading to invalid handling of the "HTTP/1.1 100 Continue" - // response. Coupled with a bug when using SSL sockets reads will block - // indefinitely even though a read timeout is explicitly set. - // * Java 6 ignores the header anyways as it is included in its restricted headers black list. - // * Also there's a bug in SL object store which still expects Content-Length bytes - // even when it responds with a 408 timeout response, leading to incorrectly - // interpreting the next request (triggered by above problem). - overrides.setProperty(Constants.PROPERTY_STRIP_EXPECT_HEADER, "true"); - - ContextBuilder contextBuilder = ContextBuilder.newBuilder(provider).credentials(identity, credential); - contextBuilder.modules(MutableList.copyOf(JcloudsUtil.getCommonModules())); - if (!brooklyn.util.text.Strings.isBlank(endpoint)) { - contextBuilder.endpoint(endpoint); - } - contextBuilder.overrides(overrides); - BlobStoreContext context = contextBuilder.buildView(BlobStoreContext.class); - return context; - } - - /** - * @deprecated since 0.7 - */ - @Deprecated - protected static String getDeprecatedProperty(ConfigBag conf, String key) { - if (conf.containsKey(key)) { - LOG.warn("Jclouds using deprecated brooklyn-jclouds property "+key+": "+Sanitizer.sanitize(conf.getAllConfig())); - return (String) conf.getStringKey(key); - } else { - return null; - } - } - - /** - * @deprecated since 0.7 - */ - @Deprecated - // Do this so that if there's a problem with our USERNAME's ssh key, we can still get in to check - // TODO Once we're really confident there are not going to be regular problems, then delete this - public static Statement addAuthorizedKeysToRoot(File publicKeyFile) throws IOException { - String publicKey = Files.toString(publicKeyFile, Charsets.UTF_8); - return addAuthorizedKeysToRoot(publicKey); - } - - /** - * @deprecated since 0.7 - */ - @Deprecated - public static Statement addAuthorizedKeysToRoot(String publicKey) { - return newStatementList( - appendFile("/root/.ssh/authorized_keys", Splitter.on('\n').split(publicKey)), - interpret("chmod 600 /root/.ssh/authorized_keys")); - } - - public static String getFirstReachableAddress(ComputeServiceContext context, NodeMetadata node) { - // To pick the address, it relies on jclouds `sshForNode().apply(Node)` to check all IPs of node (private+public), - // to find one that is reachable. It does `openSocketFinder.findOpenSocketOnNode(node, node.getLoginPort(), ...)`. - // This keeps trying for time org.jclouds.compute.reference.ComputeServiceConstants.Timeouts.portOpen. - // TODO Want to configure this timeout here. - // - // TODO We could perhaps instead just set `templateOptions.blockOnPort(loginPort, 120)`, but need - // to be careful to only set that if config WAIT_FOR_SSHABLE is true. For some advanced networking examples - // (e.g. using DNAT on CloudStack), the brooklyn machine won't be able to reach the VM until some additional - // setup steps have been done. See links from Andrea: - // https://github.com/jclouds/jclouds/pull/895 - // https://issues.apache.org/jira/browse/WHIRR-420 - // jclouds.ssh.max-retries - // jclouds.ssh.retry-auth - - SshClient client; - try { - client = context.utils().sshForNode().apply(node); - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - /* i've seen: java.lang.IllegalStateException: Optional.get() cannot be called on an absent value - * from org.jclouds.crypto.ASN1Codec.createASN1Sequence(ASN1Codec.java:86), if the ssh key has a passphrase, against AWS. - * - * others have reported: java.lang.IllegalArgumentException: DER length more than 4 bytes - * when using a key with a passphrase (perhaps from other clouds?); not sure if that's this callpath or a different one. - */ - throw new IllegalStateException("Unable to connect SshClient to "+node+"; check that the node is accessible and that the SSH key exists and is correctly configured, including any passphrase defined", e); - } - return client.getHostAddress(); - } - - // Suggest at least 15 minutes for timeout - public static String waitForPasswordOnAws(ComputeService computeService, final NodeMetadata node, long timeout, TimeUnit timeUnit) throws TimeoutException { - ComputeServiceContext computeServiceContext = computeService.getContext(); - AWSEC2Api ec2Client = computeServiceContext.unwrapApi(AWSEC2Api.class); - final WindowsApi client = ec2Client.getWindowsApi().get(); - final String region = node.getLocation().getParent().getId(); - - // The Administrator password will take some time before it is ready - Amazon says sometimes 15 minutes. - // So we create a predicate that tests if the password is ready, and wrap it in a retryable predicate. - Predicate<String> passwordReady = new Predicate<String>() { - @Override public boolean apply(String s) { - if (Strings.isNullOrEmpty(s)) return false; - PasswordData data = client.getPasswordDataInRegion(region, s); - if (data == null) return false; - return !Strings.isNullOrEmpty(data.getPasswordData()); - } - }; - - LOG.info("Waiting for password, for "+node.getProviderId()+":"+node.getId()); - Predicate<String> passwordReadyRetryable = Predicates2.retry(passwordReady, timeUnit.toMillis(timeout), 10*1000, TimeUnit.MILLISECONDS); - boolean ready = passwordReadyRetryable.apply(node.getProviderId()); - if (!ready) throw new TimeoutException("Password not available for "+node+" in region "+region+" after "+timeout+" "+timeUnit.name()); - - // Now pull together Amazon's encrypted password blob, and the private key that jclouds generated - PasswordDataAndPrivateKey dataAndKey = new PasswordDataAndPrivateKey( - client.getPasswordDataInRegion(region, node.getProviderId()), - node.getCredentials().getPrivateKey()); - - // And apply it to the decryption function - WindowsLoginCredentialsFromEncryptedData f = computeServiceContext.utils().injector().getInstance(WindowsLoginCredentialsFromEncryptedData.class); - LoginCredentials credentials = f.apply(dataAndKey); - - return credentials.getPassword(); - } - - public static Map<Integer, Integer> dockerPortMappingsFor(JcloudsLocation docker, String containerId) { - ComputeServiceContext context = null; - try { - Properties properties = new Properties(); - properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, Boolean.toString(true)); - properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, Boolean.toString(true)); - context = ContextBuilder.newBuilder("docker") - .endpoint(docker.getEndpoint()) - .credentials(docker.getIdentity(), docker.getCredential()) - .overrides(properties) - .modules(ImmutableSet.<Module>of(new SLF4JLoggingModule(), new SshjSshClientModule())) - .build(ComputeServiceContext.class); - DockerApi api = context.unwrapApi(DockerApi.class); - Container container = api.getContainerApi().inspectContainer(containerId); - Map<Integer, Integer> portMappings = Maps.newLinkedHashMap(); - Map<String, List<Map<String, String>>> ports = container.networkSettings().ports(); - if (ports == null) ports = ImmutableMap.<String, List<Map<String,String>>>of(); - - LOG.debug("Docker will forward these ports {}", ports); - for (Map.Entry<String, List<Map<String, String>>> entrySet : ports.entrySet()) { - String containerPort = Iterables.get(Splitter.on("/").split(entrySet.getKey()), 0); - String hostPort = Iterables.getOnlyElement(Iterables.transform(entrySet.getValue(), - new Function<Map<String, String>, String>() { - @Override - public String apply(Map<String, String> hostIpAndPort) { - return hostIpAndPort.get("HostPort"); - } - })); - portMappings.put(Integer.parseInt(containerPort), Integer.parseInt(hostPort)); - } - return portMappings; - } finally { - if (context != null) { - context.close(); - } - } - } - - /** - * @deprecated since 0.7 - */ - @Deprecated - public static void mapSecurityGroupRuleToIpTables(ComputeService computeService, NodeMetadata node, - LoginCredentials credentials, String networkInterface, Iterable<Integer> ports) { - for (Integer port : ports) { - String insertIptableRule = IptablesCommands.insertIptablesRule(Chain.INPUT, networkInterface, - Protocol.TCP, port, Policy.ACCEPT); - Statement statement = Statements.newStatementList(exec(insertIptableRule)); - ExecResponse response = computeService.runScriptOnNode(node.getId(), statement, - overrideLoginCredentials(credentials).runAsRoot(false)); - if (response.getExitStatus() != 0) { - String msg = String.format("Cannot insert the iptables rule for port %d. Error: %s", port, - response.getError()); - LOG.error(msg); - throw new RuntimeException(msg); - } - } - } - -}
