Extract CustomizeTemplateOptions and its implementations from JcloudsLocation
Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/7582ebeb Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/7582ebeb Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/7582ebeb Branch: refs/heads/master Commit: 7582ebeb7881478a04f82b1788c0a890a1261838 Parents: e0c6e7e Author: Sam Corbett <sam.corb...@cloudsoftcorp.com> Authored: Fri Dec 9 16:46:46 2016 +0000 Committer: Sam Corbett <sam.corb...@cloudsoftcorp.com> Committed: Tue Dec 20 15:39:01 2016 +0000 ---------------------------------------------------------------------- .../location/jclouds/JcloudsLocation.java | 348 +++---------------- .../customize/AutoAssignFloatingIpOption.java | 41 +++ .../customize/AutoCreateFloatingIpsOption.java | 41 +++ .../customize/AutoGenerateKeypairsOption.java | 41 +++ .../templates/customize/DomainNameOption.java | 39 +++ .../ExtraPublicKeyDataToAuthOption.java | 52 +++ .../templates/customize/InboundPortsOption.java | 49 +++ .../templates/customize/KeyPairOption.java | 44 +++ .../templates/customize/LoginUserOption.java | 31 ++ .../customize/LoginUserPasswordOption.java | 31 ++ .../LoginUserPrivateKeyDataOption.java | 31 ++ .../LoginUserPrivateKeyFileOption.java | 51 +++ .../templates/customize/NetworkNameOption.java | 65 ++++ .../templates/customize/RunAsRootOption.java | 29 ++ .../customize/SecurityGroupOption.java | 63 ++++ .../templates/customize/StringTagsOption.java | 40 +++ .../customize/TemplateOptionCustomizer.java | 29 ++ .../customize/TemplateOptionCustomizers.java | 103 ++++++ .../customize/TemplateOptionsOption.java | 55 +++ .../customize/UserDataUuencodedOption.java | 53 +++ .../customize/UserMetadataMapOption.java | 52 +++ .../customize/UserMetadataStringOption.java | 80 +++++ ...ationTemplateOptionsCustomisersLiveTest.java | 3 +- .../MachineLifecycleEffectorTasks.java | 2 + .../org/apache/brooklyn/util/text/Strings.java | 30 +- 25 files changed, 1108 insertions(+), 295 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/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 7b7e458..fd06a9a 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 @@ -29,7 +29,6 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -79,6 +78,8 @@ import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore; import org.apache.brooklyn.core.mgmt.persist.jclouds.JcloudsBlobStoreBasedObjectStore; import org.apache.brooklyn.location.jclouds.networking.JcloudsPortForwarderExtension; import org.apache.brooklyn.location.jclouds.templates.PortableTemplateBuilder; +import org.apache.brooklyn.location.jclouds.templates.customize.TemplateOptionCustomizer; +import org.apache.brooklyn.location.jclouds.templates.customize.TemplateOptionCustomizers; import org.apache.brooklyn.location.jclouds.zone.AwsAvailabilityZoneExtension; import org.apache.brooklyn.location.ssh.SshMachineLocation; import org.apache.brooklyn.location.winrm.WinRmMachineLocation; @@ -90,7 +91,6 @@ import org.apache.brooklyn.util.core.ClassLoaderUtils; import org.apache.brooklyn.util.core.ResourceUtils; import org.apache.brooklyn.util.core.config.ConfigBag; import org.apache.brooklyn.util.core.config.ResolvingConfigBag; -import org.apache.brooklyn.util.core.flags.MethodCoercions; import org.apache.brooklyn.util.core.flags.SetFromFlag; import org.apache.brooklyn.util.core.flags.TypeCoercions; import org.apache.brooklyn.util.core.internal.ssh.ShellTool; @@ -114,7 +114,6 @@ import org.apache.brooklyn.util.javalang.Reflections; import org.apache.brooklyn.util.net.Cidr; import org.apache.brooklyn.util.net.Networking; import org.apache.brooklyn.util.net.Protocol; -import org.apache.brooklyn.util.os.Os; import org.apache.brooklyn.util.repeat.Repeater; import org.apache.brooklyn.util.ssh.BashCommands; import org.apache.brooklyn.util.ssh.IptablesCommands; @@ -129,8 +128,6 @@ import org.apache.brooklyn.util.time.Duration; import org.apache.brooklyn.util.time.Time; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; -import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions; -import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions; import org.jclouds.compute.ComputeService; import org.jclouds.compute.RunNodesException; import org.jclouds.compute.config.AdminAccessConfiguration; @@ -149,8 +146,6 @@ import org.jclouds.compute.options.TemplateOptions; import org.jclouds.domain.Credentials; import org.jclouds.domain.LocationScope; import org.jclouds.domain.LoginCredentials; -import org.jclouds.ec2.compute.options.EC2TemplateOptions; -import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions; import org.jclouds.rest.AuthorizationException; import org.jclouds.scriptbuilder.domain.Statement; import org.jclouds.scriptbuilder.domain.StatementList; @@ -162,7 +157,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Charsets; import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.base.Objects; @@ -183,7 +177,6 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.collect.Sets.SetView; -import com.google.common.io.Files; import com.google.common.net.HostAndPort; /** @@ -1243,12 +1236,13 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im void apply(TemplateBuilder tb, ConfigBag props, Object v); } - public interface CustomizeTemplateOptions { - void apply(TemplateOptions tb, ConfigBag props, Object v); + /** @deprecated since 0.11.0 use {@link TemplateOptionCustomizer} instead */ + @Deprecated + public interface CustomizeTemplateOptions extends TemplateOptionCustomizer { } /** properties which cause customization of the TemplateBuilder */ - public static final Map<ConfigKey<?>,CustomizeTemplateBuilder> SUPPORTED_TEMPLATE_BUILDER_PROPERTIES = ImmutableMap.<ConfigKey<?>,CustomizeTemplateBuilder>builder() + public static final Map<ConfigKey<?>, CustomizeTemplateBuilder> SUPPORTED_TEMPLATE_BUILDER_PROPERTIES = ImmutableMap.<ConfigKey<?>,CustomizeTemplateBuilder>builder() .put(OS_64_BIT, new CustomizeTemplateBuilder() { public void apply(TemplateBuilder tb, ConfigBag props, Object v) { Boolean os64Bit = TypeCoercions.coerce(v, Boolean.class); @@ -1309,261 +1303,28 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im .build(); /** properties which cause customization of the TemplateOptions */ - public static final Map<ConfigKey<?>,CustomizeTemplateOptions> SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES = ImmutableMap.<ConfigKey<?>,CustomizeTemplateOptions>builder() - .put(SECURITY_GROUPS, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - if (t instanceof EC2TemplateOptions) { - String[] securityGroups = toStringArray(v); - ((EC2TemplateOptions)t).securityGroups(securityGroups); - } else if (t instanceof NovaTemplateOptions) { - String[] securityGroups = toStringArray(v); - ((NovaTemplateOptions)t).securityGroups(securityGroups); - } else if (t instanceof SoftLayerTemplateOptions) { - String[] securityGroups = toStringArray(v); - ((SoftLayerTemplateOptions)t).securityGroups(securityGroups); - } else if (isGoogleComputeTemplateOptions(t)) { - String[] securityGroups = toStringArray(v); - t.securityGroups(securityGroups); - } else { - LOG.info("ignoring securityGroups({}) in VM creation because not supported for cloud/type ({})", v, t.getClass()); - } - }}) - .put(INBOUND_PORTS, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - int[] inboundPorts = toIntPortArray(v); - if (LOG.isDebugEnabled()) LOG.debug("opening inbound ports {} for cloud/type {}", Arrays.toString(inboundPorts), t.getClass()); - t.inboundPorts(inboundPorts); - }}) - .put(USER_METADATA_STRING, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - if (t instanceof EC2TemplateOptions) { - // See AWS docs: http://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/UsingConfig_WinAMI.html#user-data-execution - if (v==null) return; - String data = v.toString(); - if (!(data.startsWith("<script>") || data.startsWith("<powershell>"))) { - data = "<script> " + data + " </script>"; - } - ((EC2TemplateOptions)t).userData(data.getBytes()); - } else if (t instanceof SoftLayerTemplateOptions) { - ((SoftLayerTemplateOptions)t).userData(Strings.toString(v)); - } else { - // Try reflection: userData(String), or guestCustomizationScript(String); - // the latter is used by vCloud Director. - Class<? extends TemplateOptions> clazz = t.getClass(); - Method userDataMethod = null; - try { - userDataMethod = clazz.getMethod("userData", String.class); - } catch (SecurityException e) { - LOG.info("Problem reflectively inspecting methods of "+t.getClass()+" for setting userData", e); - } catch (NoSuchMethodException e) { - try { - // For vCloud Director - userDataMethod = clazz.getMethod("guestCustomizationScript", String.class); - } catch (NoSuchMethodException e2) { - // expected on various other clouds - } - } - if (userDataMethod != null) { - try { - userDataMethod.invoke(t, Strings.toString(v)); - } catch (InvocationTargetException e) { - LOG.info("Problem invoking "+userDataMethod.getName()+" of "+t.getClass()+", for setting userData (rethrowing)", e); - throw Exceptions.propagate(e); - } catch (IllegalAccessException e) { - LOG.debug("Unable to reflectively invoke "+userDataMethod.getName()+" of "+t.getClass()+", for setting userData (rethrowing)", e); - throw Exceptions.propagate(e); - } - } else { - LOG.info("ignoring userDataString({}) in VM creation because not supported for cloud/type ({})", v, t.getClass()); - } - } - }}) - .put(USER_DATA_UUENCODED, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - if (t instanceof EC2TemplateOptions) { - byte[] bytes = toByteArray(v); - ((EC2TemplateOptions)t).userData(bytes); - } else if (t instanceof SoftLayerTemplateOptions) { - ((SoftLayerTemplateOptions)t).userData(Strings.toString(v)); - } else { - LOG.info("ignoring userData({}) in VM creation because not supported for cloud/type ({})", v, t.getClass()); - } - }}) - .put(STRING_TAGS, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - List<String> tags = toListOfStrings(v); - if (LOG.isDebugEnabled()) LOG.debug("setting VM tags {} for {}", tags, t); - t.tags(tags); - }}) - .put(USER_METADATA_MAP, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - if (v != null) { - t.userMetadata(toMapStringString(v)); - } - }}) - .put(EXTRA_PUBLIC_KEY_DATA_TO_AUTH, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - // this is unreliable: - // * seems now (Aug 2016) to be run *before* the TO.runScript which creates the user, - // so is installed for the initial login user not the created user - // * not supported in GCE (it uses it as the login public key, see email to jclouds list, 29 Aug 2015) - // so only works if you also overrideLoginPrivateKey - // -- - // for this reason we also inspect these ourselves - // along with EXTRA_PUBLIC_KEY_URLS_TO_AUTH - // and install after creation; - // -- - // we also do it here for legacy reasons though i (alex) can't think of any situations it's needed - // -- - // also we warn on exceptions in case someone is dumping comments or something else - try { - t.authorizePublicKey(((CharSequence)v).toString()); - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - LOG.warn("Error trying jclouds authorizePublicKey; will run later: "+e, e); - } - }}) - .put(RUN_AS_ROOT, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - t.runAsRoot((Boolean)v); - }}) - .put(LOGIN_USER, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - if (v != null) { - t.overrideLoginUser(((CharSequence)v).toString()); - } - }}) - .put(LOGIN_USER_PASSWORD, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - if (v != null) { - t.overrideLoginPassword(((CharSequence)v).toString()); - } - }}) - .put(LOGIN_USER_PRIVATE_KEY_FILE, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - if (v != null) { - String privateKeyFileName = ((CharSequence)v).toString(); - String privateKey; - try { - privateKey = Files.toString(new File(Os.tidyPath(privateKeyFileName)), Charsets.UTF_8); - } catch (IOException e) { - LOG.error(privateKeyFileName + "not found", e); - throw Exceptions.propagate(e); - } - t.overrideLoginPrivateKey(privateKey); - } - }}) - .put(LOGIN_USER_PRIVATE_KEY_DATA, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - if (v != null) { - t.overrideLoginPrivateKey(((CharSequence)v).toString()); - } - }}) - .put(KEY_PAIR, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - if (t instanceof EC2TemplateOptions) { - ((EC2TemplateOptions)t).keyPair(((CharSequence)v).toString()); - } else if (t instanceof NovaTemplateOptions) { - ((NovaTemplateOptions)t).keyPairName(((CharSequence)v).toString()); - } else if (t instanceof CloudStackTemplateOptions) { - ((CloudStackTemplateOptions) t).keyPair(((CharSequence) v).toString()); - } else { - LOG.info("ignoring keyPair({}) in VM creation because not supported for cloud/type ({})", v, t); - } - }}) - .put(AUTO_GENERATE_KEYPAIRS, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - if (t instanceof NovaTemplateOptions) { - ((NovaTemplateOptions)t).generateKeyPair((Boolean)v); - } else if (t instanceof CloudStackTemplateOptions) { - ((CloudStackTemplateOptions) t).generateKeyPair((Boolean) v); - } else { - LOG.info("ignoring auto-generate-keypairs({}) in VM creation because not supported for cloud/type ({})", v, t); - } - }}) - .put(AUTO_CREATE_FLOATING_IPS, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - LOG.warn("Using deprecated "+AUTO_CREATE_FLOATING_IPS+"; use "+AUTO_ASSIGN_FLOATING_IP+" instead"); - if (t instanceof NovaTemplateOptions) { - ((NovaTemplateOptions)t).autoAssignFloatingIp((Boolean)v); - } else { - LOG.info("ignoring auto-generate-floating-ips({}) in VM creation because not supported for cloud/type ({})", v, t); - } - }}) - .put(AUTO_ASSIGN_FLOATING_IP, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - if (t instanceof NovaTemplateOptions) { - ((NovaTemplateOptions)t).autoAssignFloatingIp((Boolean)v); - } else if (t instanceof CloudStackTemplateOptions) { - ((CloudStackTemplateOptions)t).setupStaticNat((Boolean)v); - } else { - LOG.info("ignoring auto-assign-floating-ip({}) in VM creation because not supported for cloud/type ({})", v, t); - } - }}) - .put(NETWORK_NAME, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - if (t instanceof AWSEC2TemplateOptions) { - // subnet ID is the sensible interpretation of network name in EC2 - ((AWSEC2TemplateOptions)t).subnetId((String)v); - - } else { - if (isGoogleComputeTemplateOptions(t)) { - // no warning needed - // we think this is the only jclouds endpoint which supports this option - - } else if (t instanceof SoftLayerTemplateOptions) { - LOG.warn("networkName is not be supported in SoftLayer; use `templateOptions` with `primaryNetworkComponentNetworkVlanId` or `primaryNetworkBackendComponentNetworkVlanId`"); - } else if (!(t instanceof CloudStackTemplateOptions) && !(t instanceof NovaTemplateOptions)) { - LOG.warn("networkName is experimental in many jclouds endpoints may not be supported in this cloud"); - // NB, from @andreaturli -// Cloudstack uses custom securityGroupIds and networkIds not the generic networks -// Openstack Nova uses securityGroupNames which is marked as @deprecated (suggests to use groups which is maybe even more confusing) -// Azure supports the custom networkSecurityGroupName - } - - t.networks((String)v); - } - }}) - .put(DOMAIN_NAME, new CustomizeTemplateOptions() { - public void apply(TemplateOptions t, ConfigBag props, Object v) { - if (t instanceof SoftLayerTemplateOptions) { - ((SoftLayerTemplateOptions)t).domainName(TypeCoercions.coerce(v, String.class)); - } else { - LOG.info("ignoring domain-name({}) in VM creation because not supported for cloud/type ({})", v, t); - } - }}) - .put(TEMPLATE_OPTIONS, new CustomizeTemplateOptions() { - @Override - public void apply(TemplateOptions options, ConfigBag config, Object v) { - if (v == null) return; - @SuppressWarnings("unchecked") Map<String, Object> optionsMap = (Map<String, Object>) v; - if (optionsMap.isEmpty()) return; - - Class<? extends TemplateOptions> clazz = options.getClass(); - for(final Map.Entry<String, Object> option : optionsMap.entrySet()) { - if (option.getValue() != null) { - Maybe<?> result = MethodCoercions.tryFindAndInvokeBestMatchingMethod(options, option.getKey(), option.getValue()); - if(result.isAbsent()) { - LOG.warn("Ignoring request to set template option {} because this is not supported by {}", new Object[] { option.getKey(), clazz.getCanonicalName() }); - } - } else { - // jclouds really doesn't like you to pass nulls; don't do it! For us, - // null is the only way to remove an inherited value when the templateOptions - // map is being merged. - LOG.debug("Ignoring request to set template option {} because value is null", new Object[] { option.getKey(), clazz.getCanonicalName() }); - } - } - }}) + public static final Map<ConfigKey<?>, ? extends TemplateOptionCustomizer>SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES = ImmutableMap.<ConfigKey<?>, TemplateOptionCustomizer>builder() + .put(AUTO_ASSIGN_FLOATING_IP, TemplateOptionCustomizers.autoAssignFloatingIp()) + .put(AUTO_CREATE_FLOATING_IPS, TemplateOptionCustomizers.autoCreateFloatingIps()) + .put(AUTO_GENERATE_KEYPAIRS, TemplateOptionCustomizers.autoGenerateKeypairs()) + .put(DOMAIN_NAME, TemplateOptionCustomizers.domainName()) + .put(EXTRA_PUBLIC_KEY_DATA_TO_AUTH, TemplateOptionCustomizers.extraPublicKeyDataToAuth()) + .put(INBOUND_PORTS, TemplateOptionCustomizers.inboundPorts()) + .put(KEY_PAIR, TemplateOptionCustomizers.keyPair()) + .put(LOGIN_USER, TemplateOptionCustomizers.loginUser()) + .put(LOGIN_USER_PASSWORD, TemplateOptionCustomizers.loginUserPassword()) + .put(LOGIN_USER_PRIVATE_KEY_DATA, TemplateOptionCustomizers.loginUserPrivateKeyData()) + .put(LOGIN_USER_PRIVATE_KEY_FILE, TemplateOptionCustomizers.loginUserPrivateKeyFile()) + .put(NETWORK_NAME, TemplateOptionCustomizers.networkName()) + .put(RUN_AS_ROOT, TemplateOptionCustomizers.runAsRoot()) + .put(SECURITY_GROUPS, TemplateOptionCustomizers.securityGroups()) + .put(STRING_TAGS, TemplateOptionCustomizers.stringTags()) + .put(TEMPLATE_OPTIONS, TemplateOptionCustomizers.templateOptions()) + .put(USER_DATA_UUENCODED, TemplateOptionCustomizers.userDataUuencoded()) + .put(USER_METADATA_MAP, TemplateOptionCustomizers.userMetadataMap()) + .put(USER_METADATA_STRING, TemplateOptionCustomizers.userMetadataString()) .build(); - /** - * Avoid having a dependency on googlecompute because it doesn't have an OSGi bundle yet. - * Fixed in jclouds 2.0.0-SNAPSHOT - */ - private static boolean isGoogleComputeTemplateOptions(TemplateOptions t) { - return t.getClass().getName().equals("org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions"); - } - /** hook whereby template customizations can be made for various clouds */ protected void customizeTemplate(ComputeService computeService, Template template, Collection<JcloudsLocationCustomizer> customizers) { for (JcloudsLocationCustomizer customizer : customizers) { @@ -1761,9 +1522,9 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im } } - for (Map.Entry<ConfigKey<?>, CustomizeTemplateOptions> entry : SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES.entrySet()) { + for (Map.Entry<ConfigKey<?>, ? extends TemplateOptionCustomizer> entry : SUPPORTED_TEMPLATE_OPTIONS_PROPERTIES.entrySet()) { ConfigKey<?> key = entry.getKey(); - CustomizeTemplateOptions code = entry.getValue(); + TemplateOptionCustomizer code = entry.getValue(); if (config.containsKey(key) && config.get(key) != null) { code.apply(options, config, config.get(key)); } @@ -3236,14 +2997,23 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im } } + @Override + public PersistenceObjectStore newPersistenceObjectStore(String container) { + return new JcloudsBlobStoreBasedObjectStore(this, container); + } + // ------------ static converters (could go to a new file) ------------------ + /** @deprecated since 0.11.0 without replacement */ + @Deprecated public static File asFile(Object o) { if (o instanceof File) return (File)o; if (o == null) return null; return new File(o.toString()); } + /** @deprecated since 0.11.0 without replacement */ + @Deprecated public static String fileAsString(Object o) { if (o instanceof String) return (String)o; if (o instanceof File) return ((File)o).getAbsolutePath(); @@ -3251,6 +3021,8 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im return o.toString(); } + /** @deprecated since 0.11.0 without replacement */ + @Deprecated protected static double toDouble(Object v) { if (v instanceof Number) { return ((Number)v).doubleValue(); @@ -3259,28 +3031,20 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im } } + /** @deprecated since 0.11.0 without replacement */ + @Deprecated protected static String[] toStringArray(Object v) { - return toListOfStrings(v).toArray(new String[0]); + return Strings.toStringList(v).toArray(new String[0]); } + /** @deprecated since 0.11.0 use {@link Strings#toStringList(Object)} instead */ + @Deprecated protected static List<String> toListOfStrings(Object v) { - List<String> result = Lists.newArrayList(); - if (v instanceof Iterable) { - for (Object o : (Iterable<?>)v) { - result.add(o.toString()); - } - } else if (v instanceof Object[]) { - for (int i = 0; i < ((Object[])v).length; i++) { - result.add(((Object[])v)[i].toString()); - } - } else if (v instanceof String) { - result.add((String) v); - } else { - throw new IllegalArgumentException("Invalid type for List<String>: "+v+" of type "+v.getClass()); - } - return result; + return Strings.toStringList(v); } + /** @deprecated since 0.11.0 without replacement */ + @Deprecated protected static byte[] toByteArray(Object v) { if (v instanceof byte[]) { return (byte[]) v; @@ -3291,21 +3055,24 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im } } + /** @deprecated since 0.11.0 without replacement */ + @Deprecated @VisibleForTesting static int[] toIntPortArray(Object v) { PortRange portRange = PortRanges.fromIterable(Collections.singletonList(v)); - int[] portArray = ArrayUtils.toPrimitive(Iterables.toArray(portRange, Integer.class)); - - return portArray; + return ArrayUtils.toPrimitive(Iterables.toArray(portRange, Integer.class)); } + + /** @deprecated since 0.11.0 without replacement */ + @Deprecated // Handles GString protected static Map<String,String> toMapStringString(Object v) { if (v instanceof Map<?,?>) { Map<String,String> result = Maps.newLinkedHashMap(); for (Map.Entry<?,?> entry : ((Map<?,?>)v).entrySet()) { - String key = ((CharSequence)entry.getKey()).toString(); - String value = ((CharSequence)entry.getValue()).toString(); + String key = entry.getKey().toString(); + String value = entry.getValue().toString(); result.put(key, value); } return result; @@ -3317,11 +3084,6 @@ public class JcloudsLocation extends AbstractCloudMachineProvisioningLocation im } } - @Override - public PersistenceObjectStore newPersistenceObjectStore(String container) { - return new JcloudsBlobStoreBasedObjectStore(this, container); - } - // TODO Very similar to EntityConfigMap.deepMerge private <T> Maybe<?> shallowMerge(Maybe<? extends T> val1, Maybe<? extends T> val2, ConfigKey<?> keyForLogging) { if (val2.isAbsent() || val2.isNull()) { http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/AutoAssignFloatingIpOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/AutoAssignFloatingIpOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/AutoAssignFloatingIpOption.java new file mode 100644 index 0000000..0996222 --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/AutoAssignFloatingIpOption.java @@ -0,0 +1,41 @@ +/* + * 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.templates.customize; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class AutoAssignFloatingIpOption implements TemplateOptionCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(AutoAssignFloatingIpOption.class); + + public void apply(TemplateOptions t, ConfigBag props, Object v) { + if (t instanceof NovaTemplateOptions) { + ((NovaTemplateOptions) t).autoAssignFloatingIp((Boolean) v); + } else if (t instanceof CloudStackTemplateOptions) { + ((CloudStackTemplateOptions) t).setupStaticNat((Boolean) v); + } else { + LOG.info("ignoring auto-assign-floating-ip({}) in VM creation because not supported for cloud/type ({})", v, t); + } + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/AutoCreateFloatingIpsOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/AutoCreateFloatingIpsOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/AutoCreateFloatingIpsOption.java new file mode 100644 index 0000000..4f91a8e --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/AutoCreateFloatingIpsOption.java @@ -0,0 +1,41 @@ +/* + * 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.templates.customize; + +import org.apache.brooklyn.location.jclouds.JcloudsLocationConfig; +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class AutoCreateFloatingIpsOption implements TemplateOptionCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(AutoCreateFloatingIpsOption.class); + + public void apply(TemplateOptions t, ConfigBag props, Object v) { + LOG.warn("Using deprecated " + JcloudsLocationConfig.AUTO_CREATE_FLOATING_IPS + "; use " + JcloudsLocationConfig.AUTO_ASSIGN_FLOATING_IP + " instead"); + if (t instanceof NovaTemplateOptions) { + ((NovaTemplateOptions) t).autoAssignFloatingIp((Boolean) v); + } else { + LOG.info("ignoring auto-generate-floating-ips({}) in VM creation because not supported for cloud/type ({})", v, t); + } + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/AutoGenerateKeypairsOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/AutoGenerateKeypairsOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/AutoGenerateKeypairsOption.java new file mode 100644 index 0000000..8d1601f --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/AutoGenerateKeypairsOption.java @@ -0,0 +1,41 @@ +/* + * 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.templates.customize; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class AutoGenerateKeypairsOption implements TemplateOptionCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(AutoGenerateKeypairsOption.class); + + public void apply(TemplateOptions t, ConfigBag props, Object v) { + if (t instanceof NovaTemplateOptions) { + ((NovaTemplateOptions) t).generateKeyPair((Boolean) v); + } else if (t instanceof CloudStackTemplateOptions) { + ((CloudStackTemplateOptions) t).generateKeyPair((Boolean) v); + } else { + LOG.info("ignoring auto-generate-keypairs({}) in VM creation because not supported for cloud/type ({})", v, t); + } + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/DomainNameOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/DomainNameOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/DomainNameOption.java new file mode 100644 index 0000000..54f67f2 --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/DomainNameOption.java @@ -0,0 +1,39 @@ +/* + * 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.templates.customize; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.apache.brooklyn.util.core.flags.TypeCoercions; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class DomainNameOption implements TemplateOptionCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(DomainNameOption.class); + + public void apply(TemplateOptions t, ConfigBag props, Object v) { + if (t instanceof SoftLayerTemplateOptions) { + ((SoftLayerTemplateOptions) t).domainName(TypeCoercions.coerce(v, String.class)); + } else { + LOG.info("ignoring domain-name({}) in VM creation because not supported for cloud/type ({})", v, t); + } + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/ExtraPublicKeyDataToAuthOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/ExtraPublicKeyDataToAuthOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/ExtraPublicKeyDataToAuthOption.java new file mode 100644 index 0000000..15ffd27 --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/ExtraPublicKeyDataToAuthOption.java @@ -0,0 +1,52 @@ +/* + * 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.templates.customize; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.apache.brooklyn.util.exceptions.Exceptions; +import org.jclouds.compute.options.TemplateOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class ExtraPublicKeyDataToAuthOption implements TemplateOptionCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(ExtraPublicKeyDataToAuthOption.class); + + public void apply(TemplateOptions t, ConfigBag props, Object v) { + // this is unreliable: + // * seems now (Aug 2016) to be run *before* the TO.runScript which creates the user, + // so is installed for the initial login user not the created user + // * not supported in GCE (it uses it as the login public key, see email to jclouds list, 29 Aug 2015) + // so only works if you also overrideLoginPrivateKey + // -- + // for this reason we also inspect these ourselves + // along with EXTRA_PUBLIC_KEY_URLS_TO_AUTH + // and install after creation; + // -- + // we also do it here for legacy reasons though i (alex) can't think of any situations it's needed + // -- + // also we warn on exceptions in case someone is dumping comments or something else + try { + t.authorizePublicKey(v.toString()); + } catch (Exception e) { + Exceptions.propagateIfFatal(e); + LOG.warn("Error trying jclouds authorizePublicKey; will run later: " + e, e); + } + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/InboundPortsOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/InboundPortsOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/InboundPortsOption.java new file mode 100644 index 0000000..8d233bc --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/InboundPortsOption.java @@ -0,0 +1,49 @@ +/* + * 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.templates.customize; + +import java.util.Arrays; +import java.util.Collections; + +import org.apache.brooklyn.api.location.PortRange; +import org.apache.brooklyn.core.location.PortRanges; +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.apache.commons.lang3.ArrayUtils; +import org.jclouds.compute.options.TemplateOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Iterables; + +class InboundPortsOption implements TemplateOptionCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(InboundPortsOption.class); + + public void apply(TemplateOptions t, ConfigBag props, Object v) { + int[] inboundPorts = toIntPortArray(v); + if (LOG.isDebugEnabled()) + LOG.debug("opening inbound ports {} for cloud/type {}", Arrays.toString(inboundPorts), t.getClass()); + t.inboundPorts(inboundPorts); + } + + private int[] toIntPortArray(Object v) { + PortRange portRange = PortRanges.fromIterable(Collections.singletonList(v)); + return ArrayUtils.toPrimitive(Iterables.toArray(portRange, Integer.class)); + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/KeyPairOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/KeyPairOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/KeyPairOption.java new file mode 100644 index 0000000..1edeaf2 --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/KeyPairOption.java @@ -0,0 +1,44 @@ +/* + * 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.templates.customize; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class KeyPairOption implements TemplateOptionCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(KeyPairOption.class); + + public void apply(TemplateOptions t, ConfigBag props, Object v) { + if (t instanceof EC2TemplateOptions) { + ((EC2TemplateOptions) t).keyPair(v.toString()); + } else if (t instanceof NovaTemplateOptions) { + ((NovaTemplateOptions) t).keyPairName(v.toString()); + } else if (t instanceof CloudStackTemplateOptions) { + ((CloudStackTemplateOptions) t).keyPair(v.toString()); + } else { + LOG.info("ignoring keyPair({}) in VM creation because not supported for cloud/type ({})", v, t); + } + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserOption.java new file mode 100644 index 0000000..695f544 --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserOption.java @@ -0,0 +1,31 @@ +/* + * 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.templates.customize; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.jclouds.compute.options.TemplateOptions; + +class LoginUserOption implements TemplateOptionCustomizer { + public void apply(TemplateOptions t, ConfigBag props, Object v) { + if (v != null) { + t.overrideLoginUser(v.toString()); + } + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserPasswordOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserPasswordOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserPasswordOption.java new file mode 100644 index 0000000..9ee2b11 --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserPasswordOption.java @@ -0,0 +1,31 @@ +/* + * 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.templates.customize; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.jclouds.compute.options.TemplateOptions; + +class LoginUserPasswordOption implements TemplateOptionCustomizer { + public void apply(TemplateOptions t, ConfigBag props, Object v) { + if (v != null) { + t.overrideLoginPassword(v.toString()); + } + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserPrivateKeyDataOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserPrivateKeyDataOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserPrivateKeyDataOption.java new file mode 100644 index 0000000..403ca86 --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserPrivateKeyDataOption.java @@ -0,0 +1,31 @@ +/* + * 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.templates.customize; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.jclouds.compute.options.TemplateOptions; + +class LoginUserPrivateKeyDataOption implements TemplateOptionCustomizer { + public void apply(TemplateOptions t, ConfigBag props, Object v) { + if (v != null) { + t.overrideLoginPrivateKey(v.toString()); + } + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserPrivateKeyFileOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserPrivateKeyFileOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserPrivateKeyFileOption.java new file mode 100644 index 0000000..b18ef7f --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/LoginUserPrivateKeyFileOption.java @@ -0,0 +1,51 @@ +/* + * 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.templates.customize; + +import java.io.File; +import java.io.IOException; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.apache.brooklyn.util.exceptions.Exceptions; +import org.apache.brooklyn.util.os.Os; +import org.jclouds.compute.options.TemplateOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; + +class LoginUserPrivateKeyFileOption implements TemplateOptionCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(LoginUserPrivateKeyFileOption.class); + + public void apply(TemplateOptions t, ConfigBag props, Object v) { + if (v != null) { + String privateKeyFileName = v.toString(); + String privateKey; + try { + privateKey = Files.toString(new File(Os.tidyPath(privateKeyFileName)), Charsets.UTF_8); + } catch (IOException e) { + LOG.error(privateKeyFileName + "not found", e); + throw Exceptions.propagate(e); + } + t.overrideLoginPrivateKey(privateKey); + } + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/NetworkNameOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/NetworkNameOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/NetworkNameOption.java new file mode 100644 index 0000000..e4bf045 --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/NetworkNameOption.java @@ -0,0 +1,65 @@ +/* + * 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.templates.customize; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions; +import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions; +import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class NetworkNameOption implements TemplateOptionCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(NetworkNameOption.class); + + public void apply(TemplateOptions t, ConfigBag props, Object v) { + if (t instanceof AWSEC2TemplateOptions) { + // subnet ID is the sensible interpretation of network name in EC2 + ((AWSEC2TemplateOptions) t).subnetId((String) v); + + } else { + if (isGoogleComputeTemplateOptions(t)) { + // no warning needed + // we think this is the only jclouds endpoint which supports this option + + } else if (t instanceof SoftLayerTemplateOptions) { + LOG.warn("networkName is not be supported in SoftLayer; use `templateOptions` with `primaryNetworkComponentNetworkVlanId` or `primaryNetworkBackendComponentNetworkVlanId`"); + } else if (!(t instanceof CloudStackTemplateOptions) && !(t instanceof NovaTemplateOptions)) { + LOG.warn("networkName is experimental in many jclouds endpoints may not be supported in this cloud"); + // NB, from @andreaturli +// Cloudstack uses custom securityGroupIds and networkIds not the generic networks +// Openstack Nova uses securityGroupNames which is marked as @deprecated (suggests to use groups which is maybe even more confusing) +// Azure supports the custom networkSecurityGroupName + } + + t.networks((String) v); + } + } + + /** + * Avoid having a dependency on googlecompute because it doesn't have an OSGi bundle yet. + * Fixed in jclouds 2.0.0-SNAPSHOT + */ + private static boolean isGoogleComputeTemplateOptions(TemplateOptions t) { + return t.getClass().getName().equals("org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions"); + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/RunAsRootOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/RunAsRootOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/RunAsRootOption.java new file mode 100644 index 0000000..326b883 --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/RunAsRootOption.java @@ -0,0 +1,29 @@ +/* + * 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.templates.customize; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.jclouds.compute.options.TemplateOptions; + +class RunAsRootOption implements TemplateOptionCustomizer { + public void apply(TemplateOptions t, ConfigBag props, Object v) { + t.runAsRoot((Boolean)v); + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/SecurityGroupOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/SecurityGroupOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/SecurityGroupOption.java new file mode 100644 index 0000000..ee1040d --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/SecurityGroupOption.java @@ -0,0 +1,63 @@ +/* + * 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.templates.customize; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.apache.brooklyn.util.text.Strings; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions; +import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class SecurityGroupOption implements TemplateOptionCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(SecurityGroupOption.class); + + public void apply(TemplateOptions t, ConfigBag props, Object v) { + if (t instanceof EC2TemplateOptions) { + String[] securityGroups = toStringArray(v); + ((EC2TemplateOptions) t).securityGroups(securityGroups); + } else if (t instanceof NovaTemplateOptions) { + String[] securityGroups = toStringArray(v); + t.securityGroups(securityGroups); + } else if (t instanceof SoftLayerTemplateOptions) { + String[] securityGroups = toStringArray(v); + t.securityGroups(securityGroups); + } else if (isGoogleComputeTemplateOptions(t)) { + String[] securityGroups = toStringArray(v); + t.securityGroups(securityGroups); + } else { + LOG.info("ignoring securityGroups({}) in VM creation because not supported for cloud/type ({})", v, t.getClass()); + } + } + + private String[] toStringArray(Object v) { + return Strings.toStringList(v).toArray(new String[0]); + } + + /** + * Avoid having a dependency on googlecompute because it doesn't have an OSGi bundle yet. + * Fixed in jclouds 2.0.0-SNAPSHOT + */ + private static boolean isGoogleComputeTemplateOptions(TemplateOptions t) { + return t.getClass().getName().equals("org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions"); + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/StringTagsOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/StringTagsOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/StringTagsOption.java new file mode 100644 index 0000000..153577c --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/StringTagsOption.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.templates.customize; + +import java.util.List; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.apache.brooklyn.util.text.Strings; +import org.jclouds.compute.options.TemplateOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class StringTagsOption implements TemplateOptionCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(StringTagsOption.class); + + public void apply(TemplateOptions t, ConfigBag props, Object v) { + List<String> tags = Strings.toStringList(v); + if (LOG.isDebugEnabled()) { + LOG.debug("setting VM tags {} for {}", tags, t); + } + t.tags(tags); + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/TemplateOptionCustomizer.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/TemplateOptionCustomizer.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/TemplateOptionCustomizer.java new file mode 100644 index 0000000..99346a7 --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/TemplateOptionCustomizer.java @@ -0,0 +1,29 @@ +/* + * 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.templates.customize; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.jclouds.compute.options.TemplateOptions; + +public interface TemplateOptionCustomizer { + + void apply(TemplateOptions tb, ConfigBag props, Object v); + +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/TemplateOptionCustomizers.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/TemplateOptionCustomizers.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/TemplateOptionCustomizers.java new file mode 100644 index 0000000..3cc7807 --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/TemplateOptionCustomizers.java @@ -0,0 +1,103 @@ +/* + * 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.templates.customize; + +// Has "2" in its name so JcloudsLocation can use it without having to use a fully qualified reference. +public class TemplateOptionCustomizers { + + private TemplateOptionCustomizers() {} + + public static TemplateOptionCustomizer autoAssignFloatingIp() { + return new AutoAssignFloatingIpOption(); + } + + public static TemplateOptionCustomizer autoCreateFloatingIps() { + return new AutoCreateFloatingIpsOption(); + } + + public static TemplateOptionCustomizer autoGenerateKeypairs() { + return new AutoGenerateKeypairsOption(); + } + + public static TemplateOptionCustomizer domainName() { + return new DomainNameOption(); + } + + public static TemplateOptionCustomizer extraPublicKeyDataToAuth() { + return new ExtraPublicKeyDataToAuthOption(); + } + + public static TemplateOptionCustomizer inboundPorts() { + return new InboundPortsOption(); + } + + public static TemplateOptionCustomizer keyPair() { + return new KeyPairOption(); + } + + public static TemplateOptionCustomizer loginUser() { + return new LoginUserOption(); + } + + public static TemplateOptionCustomizer loginUserPassword() { + return new LoginUserPasswordOption(); + } + + public static TemplateOptionCustomizer loginUserPrivateKeyData() { + return new LoginUserPrivateKeyDataOption(); + } + + public static TemplateOptionCustomizer loginUserPrivateKeyFile() { + return new LoginUserPrivateKeyFileOption(); + } + + public static TemplateOptionCustomizer networkName() { + return new NetworkNameOption(); + } + + public static TemplateOptionCustomizer runAsRoot() { + return new RunAsRootOption(); + } + + public static TemplateOptionCustomizer securityGroups() { + return new SecurityGroupOption(); + } + + public static TemplateOptionCustomizer stringTags() { + return new StringTagsOption(); + } + + public static TemplateOptionCustomizer templateOptions() { + return new TemplateOptionsOption(); + } + + public static TemplateOptionCustomizer userDataUuencoded() { + return new UserDataUuencodedOption(); + } + + public static TemplateOptionCustomizer userMetadataMap() { + return new UserMetadataMapOption(); + } + + public static TemplateOptionCustomizer userMetadataString() { + return new UserMetadataStringOption(); + } + +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/TemplateOptionsOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/TemplateOptionsOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/TemplateOptionsOption.java new file mode 100644 index 0000000..cd26535 --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/TemplateOptionsOption.java @@ -0,0 +1,55 @@ +/* + * 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.templates.customize; + +import java.util.Map; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.apache.brooklyn.util.core.flags.MethodCoercions; +import org.apache.brooklyn.util.guava.Maybe; +import org.jclouds.compute.options.TemplateOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class TemplateOptionsOption implements TemplateOptionCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(TemplateOptionsOption.class); + + @Override + public void apply(TemplateOptions options, ConfigBag config, Object v) { + if (v == null) return; + @SuppressWarnings("unchecked") Map<String, Object> optionsMap = (Map<String, Object>) v; + if (optionsMap.isEmpty()) return; + + Class<? extends TemplateOptions> clazz = options.getClass(); + for (final Map.Entry<String, Object> option : optionsMap.entrySet()) { + if (option.getValue() != null) { + Maybe<?> result = MethodCoercions.tryFindAndInvokeBestMatchingMethod(options, option.getKey(), option.getValue()); + if (result.isAbsent()) { + LOG.warn("Ignoring request to set template option {} because this is not supported by {}", new Object[]{option.getKey(), clazz.getCanonicalName()}); + } + } else { + // jclouds really doesn't like you to pass nulls; don't do it! For us, + // null is the only way to remove an inherited value when the templateOptions + // map is being merged. + LOG.debug("Ignoring request to set template option {} because value is null", new Object[]{option.getKey(), clazz.getCanonicalName()}); + } + } + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/UserDataUuencodedOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/UserDataUuencodedOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/UserDataUuencodedOption.java new file mode 100644 index 0000000..18fdb38 --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/UserDataUuencodedOption.java @@ -0,0 +1,53 @@ +/* + * 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.templates.customize; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.apache.brooklyn.util.text.Strings; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +class UserDataUuencodedOption implements TemplateOptionCustomizer { + private static final Logger LOG = LoggerFactory.getLogger(UserDataUuencodedOption.class); + + public void apply(TemplateOptions t, ConfigBag props, Object v) { + if (t instanceof EC2TemplateOptions) { + byte[] bytes = toByteArray(v); + ((EC2TemplateOptions) t).userData(bytes); + } else if (t instanceof SoftLayerTemplateOptions) { + ((SoftLayerTemplateOptions) t).userData(Strings.toString(v)); + } else { + LOG.info("ignoring userData({}) in VM creation because not supported for cloud/type ({})", v, t.getClass()); + } + } + + private byte[] toByteArray(Object v) { + if (v instanceof byte[]) { + return (byte[]) v; + } else if (v instanceof CharSequence) { + return v.toString().getBytes(); + } else { + throw new IllegalArgumentException("Invalid type for byte[]: " + v + " of type " + v.getClass()); + } + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/7582ebeb/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/UserMetadataMapOption.java ---------------------------------------------------------------------- diff --git a/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/UserMetadataMapOption.java b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/UserMetadataMapOption.java new file mode 100644 index 0000000..8650e9b --- /dev/null +++ b/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/templates/customize/UserMetadataMapOption.java @@ -0,0 +1,52 @@ +/* + * 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.templates.customize; + +import java.util.Map; + +import org.apache.brooklyn.util.core.config.ConfigBag; +import org.apache.brooklyn.util.text.KeyValueParser; +import org.jclouds.compute.options.TemplateOptions; + +import com.google.common.collect.Maps; + +class UserMetadataMapOption implements TemplateOptionCustomizer { + public void apply(TemplateOptions t, ConfigBag props, Object v) { + if (v != null) { + t.userMetadata(toMapStringString(v)); + } + } + private Map<String,String> toMapStringString(Object v) { + if (v instanceof Map<?,?>) { + Map<String,String> result = Maps.newLinkedHashMap(); + for (Map.Entry<?,?> entry : ((Map<?,?>)v).entrySet()) { + String key = entry.getKey().toString(); + String value = entry.getValue().toString(); + result.put(key, value); + } + return result; + } else if (v instanceof CharSequence) { + return KeyValueParser.parseMap(v.toString()); + } else { + throw new IllegalArgumentException("Invalid type for Map<String,String>: " + v + + (v != null ? " of type "+v.getClass() : "")); + } + } +}