You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by sj...@apache.org on 2016/12/20 16:11:51 UTC
[5/7] brooklyn-server git commit: Extract CustomizeTemplateOptions
and its implementations from JcloudsLocation
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 <sa...@cloudsoftcorp.com>
Authored: Fri Dec 9 16:46:46 2016 +0000
Committer: Sam Corbett <sa...@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() : ""));
+ }
+ }
+}