blob: f9f4fb52f2a22cfebc7a25c89e454391e6d1da01 [file] [log] [blame]
/*
* 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.jclouds.openstack.nova.v2_0.compute.options;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.emptyToNull;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.openstack.nova.v2_0.NovaApi;
import org.jclouds.openstack.nova.v2_0.domain.BlockDeviceMapping;
import org.jclouds.openstack.nova.v2_0.domain.Network;
import org.jclouds.openstack.nova.v2_0.options.CreateServerOptions;
import org.jclouds.scriptbuilder.domain.Statement;
import com.google.common.base.Objects;
import com.google.common.base.MoreObjects.ToStringHelper;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
/**
* Contains options supported in the {@code ComputeService#runNode} operation on the
* "openstack-nova" provider. <h2>Usage</h2> The recommended way to instantiate a
* NovaTemplateOptions object is to statically import NovaTemplateOptions.* and invoke a static
* creation method followed by an instance mutator (if needed):
* <p/>
* <code>
* import static org.jclouds.aws.ec2.compute.options.NovaTemplateOptions.Builder.*;
* <p/>
* ComputeService api = // get connection
* templateBuilder.options(inboundPorts(22, 80, 8080, 443));
* Set<? extends NodeMetadata> set = api.createNodesInGroup(tag, 2, templateBuilder.build());
* <code>
*/
public class NovaTemplateOptions extends TemplateOptions implements Cloneable {
@Override
public NovaTemplateOptions clone() {
NovaTemplateOptions options = new NovaTemplateOptions();
copyTo(options);
return options;
}
@Override
public void copyTo(TemplateOptions to) {
super.copyTo(to);
if (to instanceof NovaTemplateOptions) {
NovaTemplateOptions eTo = NovaTemplateOptions.class.cast(to);
eTo.autoAssignFloatingIp(shouldAutoAssignFloatingIp());
if (getFloatingIpPoolNames().isPresent())
eTo.floatingIpPoolNames(getFloatingIpPoolNames().get());
eTo.generateKeyPair(shouldGenerateKeyPair());
eTo.keyPairName(getKeyPairName());
if (getUserData() != null) {
eTo.userData(getUserData());
}
if (getDiskConfig() != null) {
eTo.diskConfig(getDiskConfig());
}
eTo.configDrive(getConfigDrive());
eTo.novaNetworks(getNovaNetworks());
eTo.availabilityZone(getAvailabilityZone());
eTo.blockDeviceMappings(getBlockDeviceMappings());
}
}
protected boolean autoAssignFloatingIp = false;
protected Optional<Set<String>> floatingIpPoolNames = Optional.absent();
protected boolean generateKeyPair = false;
protected String keyPairName;
protected byte[] userData;
protected String diskConfig;
protected boolean configDrive;
protected Set<Network> novaNetworks;
protected String availabilityZone;
// TODO move up to TemplateOptions as SoftLayer also have something similar?
protected Set<BlockDeviceMapping> blockDeviceMappings = ImmutableSet.of();
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
NovaTemplateOptions that = NovaTemplateOptions.class.cast(o);
return super.equals(that) && equal(this.autoAssignFloatingIp, that.autoAssignFloatingIp)
&& equal(this.floatingIpPoolNames, that.floatingIpPoolNames)
&& equal(this.generateKeyPair, that.generateKeyPair)
&& equal(this.keyPairName, that.keyPairName)
&& Arrays.equals(this.userData, that.userData)
&& equal(this.diskConfig, that.diskConfig)
&& equal(this.configDrive, that.configDrive)
&& equal(this.novaNetworks, that.novaNetworks)
&& equal(this.availabilityZone, that.availabilityZone)
&& equal(this.blockDeviceMappings, that.blockDeviceMappings);
}
@Override
public int hashCode() {
return Objects.hashCode(super.hashCode(), autoAssignFloatingIp, floatingIpPoolNames, generateKeyPair, keyPairName,
Arrays.hashCode(userData), diskConfig, configDrive, novaNetworks, availabilityZone, blockDeviceMappings);
}
@Override
public ToStringHelper string() {
ToStringHelper toString = super.string();
if (!autoAssignFloatingIp)
toString.add("autoAssignFloatingIp", autoAssignFloatingIp);
if (floatingIpPoolNames.isPresent())
toString.add("floatingIpPoolNames", floatingIpPoolNames.get());
if (generateKeyPair)
toString.add("generateKeyPair", generateKeyPair);
toString.add("keyPairName", keyPairName);
toString.add("userData", userData);
toString.add("diskConfig", diskConfig);
toString.add("configDrive", configDrive);
toString.add("novaNetworks", novaNetworks);
toString.add("availabilityZone", availabilityZone);
toString.add("blockDeviceMappings", blockDeviceMappings);
return toString;
}
/**
* @see #getFloatingIpPoolNames()
*/
public NovaTemplateOptions autoAssignFloatingIp(boolean enable) {
this.autoAssignFloatingIp = enable;
return this;
}
/**
* @see #getFloatingIpPoolNames()
*/
public NovaTemplateOptions floatingIpPoolNames(String... floatingIpPoolNames) {
return floatingIpPoolNames(ImmutableSet.copyOf(checkNotNull(floatingIpPoolNames, "floatingIpPoolNames")));
}
/**
* @see #getFloatingIpPoolNames()
*/
public NovaTemplateOptions floatingIpPoolNames(Iterable<String> floatingIpPoolNames) {
for (String groupName : checkNotNull(floatingIpPoolNames, "floatingIpPoolNames"))
checkNotNull(emptyToNull(groupName), "all floating-ip-pool-names must be non-empty");
this.floatingIpPoolNames = Optional.<Set<String>> of(ImmutableSet.copyOf(floatingIpPoolNames));
return this;
}
/**
* @see #shouldGenerateKeyPair()
*/
public NovaTemplateOptions generateKeyPair(boolean enable) {
this.generateKeyPair = enable;
return this;
}
/**
* @see #shouldGenerateKeyPair()
*/
public NovaTemplateOptions keyPairName(String keyPairName) {
this.keyPairName = keyPairName;
return this;
}
/**
* <h3>Note</h3>
*
* This requires that {@link NovaApi#getExtensionApi(String)} to return
* {@link Optional#isPresent present}
*
* @return true if auto assignment of a floating ip to each vm is enabled
*/
public boolean shouldAutoAssignFloatingIp() {
return autoAssignFloatingIp;
}
/**
* @see CreateServerOptions#getAvailabilityZone()
*/
public NovaTemplateOptions availabilityZone(String availabilityZone) {
this.availabilityZone = availabilityZone;
return this;
}
/**
* @see #getBlockDeviceMappings()
*/
public NovaTemplateOptions blockDeviceMappings(BlockDeviceMapping... blockDeviceMappings) {
return blockDeviceMappings(ImmutableSet.copyOf(checkNotNull(blockDeviceMappings, "blockDeviceMappings")));
}
/**
* @see #getBlockDeviceMappings()
*/
public NovaTemplateOptions blockDeviceMappings(Iterable<BlockDeviceMapping> blockDeviceMappings) {
this.blockDeviceMappings = ImmutableSet.copyOf(blockDeviceMappings);
return this;
}
/**
* The floating IP pool name(s) to use when allocating a FloatingIP. Applicable
* only if #shouldAutoAssignFloatingIp() returns true. If not set will attempt to
* use whatever FloatingIP(s) can be found regardless of which pool they originated
* from
*
* @return floating-ip-pool names to use
*/
public Optional<Set<String>> getFloatingIpPoolNames() {
return floatingIpPoolNames;
}
/**
* Specifies the keypair used to run instances with
* @return the keypair to be used
*/
public String getKeyPairName() {
return keyPairName;
}
/**
* <h3>Note</h3>
*
* This requires that {@link NovaApi#getKeyPairApi(String)} to return
* {@link Optional#isPresent present}
*
* @return true if auto generation of keypairs is enabled
*/
public boolean shouldGenerateKeyPair() {
return generateKeyPair;
}
public byte[] getUserData() {
return userData;
}
/**
* @see CreateServerOptions#getDiskConfig()
*/
public String getDiskConfig() {
return diskConfig;
}
/**
* @see CreateServerOptions#getConfigDrive()
*/
public boolean getConfigDrive() {
return configDrive;
}
/**
* @see CreateServerOptions#getNetworks()
*/
public Set<Network> getNovaNetworks() {
return novaNetworks;
}
/**
* @see CreateServerOptions#getAvailabilityZone()
*/
public String getAvailabilityZone() {
return availabilityZone;
}
public Set<BlockDeviceMapping> getBlockDeviceMappings() {
return blockDeviceMappings;
}
public static class Builder {
/**
* @see NovaTemplateOptions#shouldAutoAssignFloatingIp()
*/
public static NovaTemplateOptions autoAssignFloatingIp(boolean enable) {
return new NovaTemplateOptions().autoAssignFloatingIp(enable);
}
/**
* @see #getFloatingIpPoolNames()
*/
public NovaTemplateOptions floatingIpPoolNames(String... floatingIpPoolNames) {
NovaTemplateOptions options = new NovaTemplateOptions();
return NovaTemplateOptions.class.cast(options.floatingIpPoolNames(floatingIpPoolNames));
}
/**
* @see #getFloatingIpPoolNames()
*/
public NovaTemplateOptions floatingIpPoolNames(Iterable<String> floatingIpPoolNames) {
NovaTemplateOptions options = new NovaTemplateOptions();
return NovaTemplateOptions.class.cast(options.floatingIpPoolNames(floatingIpPoolNames));
}
/**
* @see NovaTemplateOptions#shouldGenerateKeyPair()
*/
public static NovaTemplateOptions generateKeyPair(boolean enable) {
return new NovaTemplateOptions().generateKeyPair(enable);
}
/**
* @see NovaTemplateOptions#getKeyPairName()
*/
public static NovaTemplateOptions keyPairName(String keyPairName) {
return new NovaTemplateOptions().keyPairName(keyPairName);
}
// methods that only facilitate returning the correct object type
/**
* @see TemplateOptions#inboundPorts
*/
public static NovaTemplateOptions inboundPorts(int... ports) {
NovaTemplateOptions options = new NovaTemplateOptions();
return NovaTemplateOptions.class.cast(options.inboundPorts(ports));
}
/**
* @see TemplateOptions#port
*/
public static NovaTemplateOptions blockOnPort(int port, int seconds) {
NovaTemplateOptions options = new NovaTemplateOptions();
return NovaTemplateOptions.class.cast(options.blockOnPort(port, seconds));
}
/**
* @see TemplateOptions#installPrivateKey
*/
public static NovaTemplateOptions installPrivateKey(String rsaKey) {
NovaTemplateOptions options = new NovaTemplateOptions();
return NovaTemplateOptions.class.cast(options.installPrivateKey(rsaKey));
}
/**
* @see TemplateOptions#authorizePublicKey
*/
public static NovaTemplateOptions authorizePublicKey(String rsaKey) {
NovaTemplateOptions options = new NovaTemplateOptions();
return NovaTemplateOptions.class.cast(options.authorizePublicKey(rsaKey));
}
/**
* @see TemplateOptions#userMetadata
*/
public static NovaTemplateOptions userMetadata(Map<String, String> userMetadata) {
NovaTemplateOptions options = new NovaTemplateOptions();
return NovaTemplateOptions.class.cast(options.userMetadata(userMetadata));
}
/**
* @see TemplateOptions#nodeNames(Iterable)
*/
public static NovaTemplateOptions nodeNames(Iterable<String> nodeNames) {
NovaTemplateOptions options = new NovaTemplateOptions();
return NovaTemplateOptions.class.cast(options.nodeNames(nodeNames));
}
/**
* @see TemplateOptions#networks(Iterable)
*/
public static NovaTemplateOptions networks(Iterable<String> networks) {
NovaTemplateOptions options = new NovaTemplateOptions();
return NovaTemplateOptions.class.cast(options.networks(networks));
}
/**
* @see TemplateOptions#overrideLoginUser
*/
public static NovaTemplateOptions overrideLoginUser(String user) {
NovaTemplateOptions options = new NovaTemplateOptions();
return options.overrideLoginUser(user);
}
/**
* @see TemplateOptions#overrideLoginPassword
*/
public static NovaTemplateOptions overrideLoginPassword(String password) {
NovaTemplateOptions options = new NovaTemplateOptions();
return options.overrideLoginPassword(password);
}
/**
* @see TemplateOptions#overrideLoginPrivateKey
*/
public static NovaTemplateOptions overrideLoginPrivateKey(String privateKey) {
NovaTemplateOptions options = new NovaTemplateOptions();
return options.overrideLoginPrivateKey(privateKey);
}
/**
* @see TemplateOptions#overrideAuthenticateSudo
*/
public static NovaTemplateOptions overrideAuthenticateSudo(boolean authenticateSudo) {
NovaTemplateOptions options = new NovaTemplateOptions();
return options.overrideAuthenticateSudo(authenticateSudo);
}
/**
* @see TemplateOptions#overrideLoginCredentials
*/
public static NovaTemplateOptions overrideLoginCredentials(LoginCredentials credentials) {
NovaTemplateOptions options = new NovaTemplateOptions();
return options.overrideLoginCredentials(credentials);
}
/**
* @see TemplateOptions#blockUntilRunning
*/
public static NovaTemplateOptions blockUntilRunning(boolean blockUntilRunning) {
NovaTemplateOptions options = new NovaTemplateOptions();
return options.blockUntilRunning(blockUntilRunning);
}
/**
* @see NovaTemplateOptions#userData
*/
public static NovaTemplateOptions userData(byte[] userData) {
NovaTemplateOptions options = new NovaTemplateOptions();
return NovaTemplateOptions.class.cast(options.userData(userData));
}
/**
* @see org.jclouds.openstack.nova.v2_0.options.CreateServerOptions#getDiskConfig()
*/
public static NovaTemplateOptions diskConfig(String diskConfig) {
NovaTemplateOptions options = new NovaTemplateOptions();
return NovaTemplateOptions.class.cast(options.diskConfig(diskConfig));
}
/**
* @see org.jclouds.openstack.nova.v2_0.options.CreateServerOptions#getConfigDrive()
*/
public static NovaTemplateOptions configDrive(boolean configDrive) {
NovaTemplateOptions options = new NovaTemplateOptions();
return NovaTemplateOptions.class.cast(options.configDrive(configDrive));
}
/**
* @see org.jclouds.openstack.nova.v2_0.options.CreateServerOptions#getNetworks()
*/
public static NovaTemplateOptions novaNetworks(Set<Network> novaNetworks) {
NovaTemplateOptions options = new NovaTemplateOptions();
return NovaTemplateOptions.class.cast(options.novaNetworks(novaNetworks));
}
/**
* @see NovaTemplateOptions#getAvailabilityZone()
*/
public static NovaTemplateOptions availabilityZone(String availabilityZone) {
NovaTemplateOptions options = new NovaTemplateOptions();
return options.availabilityZone(availabilityZone);
}
}
// methods that only facilitate returning the correct object type
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions blockOnPort(int port, int seconds) {
return NovaTemplateOptions.class.cast(super.blockOnPort(port, seconds));
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions inboundPorts(int... ports) {
return NovaTemplateOptions.class.cast(super.inboundPorts(ports));
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions authorizePublicKey(String publicKey) {
return NovaTemplateOptions.class.cast(super.authorizePublicKey(publicKey));
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions installPrivateKey(String privateKey) {
return NovaTemplateOptions.class.cast(super.installPrivateKey(privateKey));
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions blockUntilRunning(boolean blockUntilRunning) {
return NovaTemplateOptions.class.cast(super.blockUntilRunning(blockUntilRunning));
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions dontAuthorizePublicKey() {
return NovaTemplateOptions.class.cast(super.dontAuthorizePublicKey());
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions nameTask(String name) {
return NovaTemplateOptions.class.cast(super.nameTask(name));
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions runAsRoot(boolean runAsRoot) {
return NovaTemplateOptions.class.cast(super.runAsRoot(runAsRoot));
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions runScript(Statement script) {
return NovaTemplateOptions.class.cast(super.runScript(script));
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions overrideLoginCredentials(LoginCredentials overridingCredentials) {
return NovaTemplateOptions.class.cast(super.overrideLoginCredentials(overridingCredentials));
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions overrideLoginPassword(String password) {
return NovaTemplateOptions.class.cast(super.overrideLoginPassword(password));
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions overrideLoginPrivateKey(String privateKey) {
return NovaTemplateOptions.class.cast(super.overrideLoginPrivateKey(privateKey));
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions overrideLoginUser(String loginUser) {
return NovaTemplateOptions.class.cast(super.overrideLoginUser(loginUser));
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions overrideAuthenticateSudo(boolean authenticateSudo) {
return NovaTemplateOptions.class.cast(super.overrideAuthenticateSudo(authenticateSudo));
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions userMetadata(Map<String, String> userMetadata) {
return NovaTemplateOptions.class.cast(super.userMetadata(userMetadata));
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions userMetadata(String key, String value) {
return NovaTemplateOptions.class.cast(super.userMetadata(key, value));
}
/**
* {@inheritDoc}
*/
@Override
public NovaTemplateOptions nodeNames(Iterable<String> nodeNames) {
return NovaTemplateOptions.class.cast(super.nodeNames(nodeNames));
}
/**
* <br>Ensures NovaTemplateOptions can work with networks specified as Strings.
* Also provides for compatibility with the abstraction layer.
*/
@Override
public NovaTemplateOptions networks(Iterable<String> networks) {
return NovaTemplateOptions.class.cast(super.networks(networks));
}
/**
* <br>Ensures NovaTemplateOptions can work with networks specified as Strings.
* Also provides for compatibility with the abstraction layer.
*/
@Override
public NovaTemplateOptions networks(String... networks) {
return NovaTemplateOptions.class.cast(super.networks(networks));
}
/**
* User data as bytes (not base64-encoded)
*/
public NovaTemplateOptions userData(byte[] userData) {
// This limit may not be needed for nova
checkArgument(checkNotNull(userData, "userData").length <= 16 * 1024,
"userData cannot be larger than 16kb");
this.userData = userData;
return this;
}
/**
* @see CreateServerOptions#getDiskConfig()
*/
public NovaTemplateOptions diskConfig(String diskConfig) {
this.diskConfig = diskConfig;
return this;
}
/**
* OpenStack can be configured to write metadata to a special configuration drive that will be
* attached to the instance when it boots. The instance can retrieve any information that would
* normally be available through the metadata service by mounting this disk and reading files from it.
* To enable the config drive, set this parameter to "true".
* This has to be enabled for user data cases.
* @see CreateServerOptions#getConfigDrive()
*/
public NovaTemplateOptions configDrive(boolean configDrive) {
this.configDrive = configDrive;
return this;
}
/**
* @param novaNetworks The list of network declarations.
* Nova-specific network declarations allow for specifying network UUIDs, port UUIDs, and fixed IPs.
* Unline {@link #networks(Iterable)} this supports setting additional network parameters and not just network UUIDs.
* @see CreateServerOptions#getNetworks()
*/
public NovaTemplateOptions novaNetworks(Set<Network> novaNetworks) {
this.novaNetworks = novaNetworks;
return this;
}
}