Merge pull request #161 from andreisavu/specify-ip-address

Allow user the specify the ip address for a cloudstack vm
This commit is contained in:
Adrian Cole 2011-11-16 09:52:33 -08:00
commit 9b432304f5
3 changed files with 191 additions and 6 deletions

View File

@ -29,6 +29,8 @@ import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import java.util.Map;
/** /**
* Options used to control what disk offerings are returned * Options used to control what disk offerings are returned
* *
@ -50,7 +52,7 @@ public class DeployVirtualMachineOptions extends AccountInDomainOptions {
* parameter passed is from an ISO object, the diskOfferingId refers to a * parameter passed is from an ISO object, the diskOfferingId refers to a
* ROOT Disk Volume created. * ROOT Disk Volume created.
* *
* @param id * @param diskofferingid
* the ID of the disk offering * the ID of the disk offering
*/ */
public DeployVirtualMachineOptions diskOfferingId(long diskofferingid) { public DeployVirtualMachineOptions diskOfferingId(long diskofferingid) {
@ -104,6 +106,35 @@ public class DeployVirtualMachineOptions extends AccountInDomainOptions {
return this; return this;
} }
/**
* @param ipAddress
* the requested ip address (2.2.12 only option)
*/
public DeployVirtualMachineOptions ipAddress(String ipAddress) {
this.queryParameters.replaceValues("ipaddress", ImmutableSet.of(ipAddress));
return this;
}
/**
* @param ipToNetworkList
* mapping ip addresses to network ids (2.2.12 only option)
*/
public DeployVirtualMachineOptions ipToNetworkList(Map<String, Long> ipToNetworkList) {
int count = 0;
for(String ip : ipToNetworkList.keySet()) {
this.queryParameters.replaceValues(
String.format("ipnetworklist[%d].ip", count),
ImmutableSet.of(ip)
);
this.queryParameters.replaceValues(
String.format("ipnetworklist[%d].networkid", count),
ImmutableSet.of("" + ipToNetworkList.get(ip))
);
count += 1;
}
return this;
}
/** /**
* @param networkId * @param networkId
* network id used by virtual machine * network id used by virtual machine
@ -236,6 +267,22 @@ public class DeployVirtualMachineOptions extends AccountInDomainOptions {
return options.name(name); return options.name(name);
} }
/**
* @see DeployVirtualMachineOptions#ipAddress
*/
public static DeployVirtualMachineOptions ipAddress(String ipAddress) {
DeployVirtualMachineOptions options = new DeployVirtualMachineOptions();
return options.ipAddress(ipAddress);
}
/**
* @see DeployVirtualMachineOptions#ipToNetworkList
*/
public static DeployVirtualMachineOptions ipToNetworkList(Map<String, Long> ipToNetworkList) {
DeployVirtualMachineOptions options = new DeployVirtualMachineOptions();
return options.ipToNetworkList(ipToNetworkList);
}
/** /**
* @see DeployVirtualMachineOptions#networkId * @see DeployVirtualMachineOptions#networkId
*/ */

View File

@ -136,8 +136,10 @@ public class BaseCloudStackClientLiveTest extends BaseVersionedServiceLiveTest {
protected RetryablePredicate<Long> jobComplete; protected RetryablePredicate<Long> jobComplete;
protected RetryablePredicate<Long> adminJobComplete; protected RetryablePredicate<Long> adminJobComplete;
protected RetryablePredicate<VirtualMachine> virtualMachineRunning; protected RetryablePredicate<VirtualMachine> virtualMachineRunning;
protected RetryablePredicate<VirtualMachine> adminVirtualMachineRunning;
protected RetryablePredicate<VirtualMachine> virtualMachineDestroyed; protected RetryablePredicate<VirtualMachine> virtualMachineDestroyed;
protected SshClient.Factory sshFactory; protected RetryablePredicate<VirtualMachine> adminVirtualMachineDestroyed;
protected SshClient.Factory sshFactory;
protected String password = "password"; protected String password = "password";
protected Injector injector; protected Injector injector;
@ -196,9 +198,15 @@ public class BaseCloudStackClientLiveTest extends BaseVersionedServiceLiveTest {
virtualMachineRunning = new RetryablePredicate<VirtualMachine>(new VirtualMachineRunning(client), 600, 5, 5, virtualMachineRunning = new RetryablePredicate<VirtualMachine>(new VirtualMachineRunning(client), 600, 5, 5,
TimeUnit.SECONDS); TimeUnit.SECONDS);
injector.injectMembers(virtualMachineRunning); injector.injectMembers(virtualMachineRunning);
adminVirtualMachineRunning = new RetryablePredicate<VirtualMachine>(new VirtualMachineRunning(adminClient), 600, 5, 5,
TimeUnit.SECONDS);
injector.injectMembers(adminVirtualMachineRunning);
virtualMachineDestroyed = new RetryablePredicate<VirtualMachine>(new VirtualMachineDestroyed(client), 600, 5, 5, virtualMachineDestroyed = new RetryablePredicate<VirtualMachine>(new VirtualMachineDestroyed(client), 600, 5, 5,
TimeUnit.SECONDS); TimeUnit.SECONDS);
injector.injectMembers(virtualMachineDestroyed); injector.injectMembers(virtualMachineDestroyed);
adminVirtualMachineDestroyed = new RetryablePredicate<VirtualMachine>(new VirtualMachineDestroyed(adminClient), 600, 5, 5,
TimeUnit.SECONDS);
injector.injectMembers(adminVirtualMachineDestroyed);
reuseOrAssociate = new ReuseOrAssociateNewPublicIPAddress(client, jobComplete); reuseOrAssociate = new ReuseOrAssociateNewPublicIPAddress(client, jobComplete);
injector.injectMembers(reuseOrAssociate); injector.injectMembers(reuseOrAssociate);
} }

View File

@ -18,28 +18,44 @@
*/ */
package org.jclouds.cloudstack.features; package org.jclouds.cloudstack.features;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.equalTo; import static com.google.common.base.Predicates.equalTo;
import static com.google.common.base.Predicates.in; import static com.google.common.base.Predicates.in;
import static com.google.common.base.Predicates.or; import static com.google.common.base.Predicates.or;
import static com.google.common.collect.Iterables.find; import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Iterables.get; import static com.google.common.collect.Iterables.get;
import static com.google.common.collect.Iterables.getFirst;
import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.collect.Sets.filter;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue; import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.logging.Logger;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import org.jclouds.cloudstack.CloudStackClient; import org.jclouds.cloudstack.CloudStackClient;
import org.jclouds.cloudstack.domain.AsyncCreateResponse; import org.jclouds.cloudstack.domain.AsyncCreateResponse;
import org.jclouds.cloudstack.domain.AsyncJob; import org.jclouds.cloudstack.domain.AsyncJob;
import org.jclouds.cloudstack.domain.GuestIPType;
import org.jclouds.cloudstack.domain.NIC; import org.jclouds.cloudstack.domain.NIC;
import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.domain.Network;
import org.jclouds.cloudstack.domain.NetworkOffering;
import org.jclouds.cloudstack.domain.ServiceOffering; import org.jclouds.cloudstack.domain.ServiceOffering;
import org.jclouds.cloudstack.domain.Template;
import org.jclouds.cloudstack.domain.VirtualMachine; import org.jclouds.cloudstack.domain.VirtualMachine;
import org.jclouds.cloudstack.domain.Zone; import org.jclouds.cloudstack.domain.Zone;
import org.jclouds.cloudstack.options.CreateNetworkOptions;
import org.jclouds.cloudstack.options.DeployVirtualMachineOptions; import org.jclouds.cloudstack.options.DeployVirtualMachineOptions;
import org.jclouds.cloudstack.options.ListNetworkOfferingsOptions;
import org.jclouds.cloudstack.options.ListNetworksOptions;
import org.jclouds.cloudstack.options.ListTemplatesOptions;
import org.jclouds.cloudstack.options.ListVirtualMachinesOptions; import org.jclouds.cloudstack.options.ListVirtualMachinesOptions;
import org.jclouds.net.IPSocket; import org.jclouds.net.IPSocket;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
@ -52,7 +68,8 @@ import com.google.common.base.Throwables;
import com.google.common.collect.ComparisonChain; import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Ordering; import com.google.common.collect.Ordering;
import com.google.common.net.HostSpecifier; import com.google.common.net.HostSpecifier;
import org.testng.collections.Sets;
import javax.annotation.Nullable;
/** /**
* Tests behavior of {@code VirtualMachineClientLiveTest} * Tests behavior of {@code VirtualMachineClientLiveTest}
@ -61,6 +78,8 @@ import org.testng.collections.Sets;
*/ */
@Test(groups = "live", singleThreaded = true, testName = "VirtualMachineClientLiveTest") @Test(groups = "live", singleThreaded = true, testName = "VirtualMachineClientLiveTest")
public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest { public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest {
private final static Logger logger = Logger.getAnonymousLogger();
private VirtualMachine vm = null; private VirtualMachine vm = null;
static final Ordering<ServiceOffering> DEFAULT_SIZE_ORDERING = new Ordering<ServiceOffering>() { static final Ordering<ServiceOffering> DEFAULT_SIZE_ORDERING = new Ordering<ServiceOffering>() {
@ -111,6 +130,25 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest {
virtualMachineRunning); virtualMachineRunning);
} }
public static VirtualMachine createVirtualMachineInNetworkWithIp(
CloudStackClient client, long templateId, Set<Network> networks, Map<String, Long> ipToNetwork,
RetryablePredicate<Long> jobComplete, RetryablePredicate<VirtualMachine> virtualMachineRunning) {
DeployVirtualMachineOptions options = new DeployVirtualMachineOptions();
long zoneId = getFirst(networks, null).getZoneId();
options.networkIds(Iterables.transform(networks, new Function<Network, Long>() {
@Override
public Long apply(@Nullable Network network) {
return network.getId();
}
}));
options.ipToNetworkList(ipToNetwork);
return createVirtualMachineWithOptionsInZone(options, zoneId, templateId,
client, jobComplete, virtualMachineRunning);
}
public static VirtualMachine createVirtualMachineWithOptionsInZone(DeployVirtualMachineOptions options, long zoneId, public static VirtualMachine createVirtualMachineWithOptionsInZone(DeployVirtualMachineOptions options, long zoneId,
long templateId, CloudStackClient client, RetryablePredicate<Long> jobComplete, long templateId, CloudStackClient client, RetryablePredicate<Long> jobComplete,
RetryablePredicate<VirtualMachine> virtualMachineRunning) { RetryablePredicate<VirtualMachine> virtualMachineRunning) {
@ -150,6 +188,99 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest {
checkVm(vm); checkVm(vm);
} }
public void testCreateVirtualMachineWithSpecificIp() throws Exception {
Long templateId = (imageId != null && !"".equals(imageId)) ? new Long(imageId) : null;
Network network = null;
try {
Template template = getOnlyElement(
client.getTemplateClient().listTemplates(ListTemplatesOptions.Builder.id(templateId)));
logger.info("Using template: " + template);
Set<Network> allSafeNetworksInZone = adminClient.getNetworkClient().listNetworks(
ListNetworksOptions.Builder.zoneId(template.getZoneId()).isSystem(false));
for(Network net : allSafeNetworksInZone) {
if(net.getName().equals(prefix + "-ip-network")) {
logger.info("Deleting VMs in network: " + net);
Set<VirtualMachine> machinesInNetwork = adminClient.getVirtualMachineClient().listVirtualMachines(
ListVirtualMachinesOptions.Builder.networkId(net.getId()));
for(VirtualMachine machine : machinesInNetwork) {
if (machine.getState().equals(VirtualMachine.State.RUNNING)) {
logger.info("Deleting VM: " + machine);
destroyMachine(machine);
}
}
assert adminJobComplete.apply(
adminClient.getNetworkClient().deleteNetwork(net.getId())) : net;
}
}
NetworkOffering offering = getFirst(
client.getOfferingClient().listNetworkOfferings(
ListNetworkOfferingsOptions.Builder.zoneId(template.getZoneId()).specifyVLAN(true)), null);
checkNotNull(offering, "No network offering found");
logger.info("Using network offering: " + offering);
network = adminClient.getNetworkClient().createNetworkInZone(
template.getZoneId(), offering.getId(), prefix + "-ip-network", "",
CreateNetworkOptions.Builder.startIP("192.168.0.1").endIP("192.168.0.5")
.netmask("255.255.255.0").gateway("192.168.0.1").vlan("21"));
logger.info("Created network: " + network);
Network requiredNetwork = getOnlyElement(filter(adminClient.getNetworkClient().listNetworks(
ListNetworksOptions.Builder.zoneId(template.getZoneId())), new Predicate<Network>() {
@Override
public boolean apply(@Nullable Network network) {
return network.isDefault() &&
network.getGuestIPType() == GuestIPType.VIRTUAL &&
network.getNetworkOfferingId() == 6 &&
network.getId() == 204;
}
}));
logger.info("Required network: " + requiredNetwork);
String ipAddress = "192.168.0.4";
Map<String, Long> ipToNetwork = Maps.newHashMap();
ipToNetwork.put(ipAddress, network.getId());
vm = createVirtualMachineInNetworkWithIp(
adminClient, templateId, ImmutableSet.of(requiredNetwork, network),
ipToNetwork, adminJobComplete, adminVirtualMachineRunning);
logger.info("Created VM: " + vm);
boolean hasStaticIpNic = false;
for(NIC nic : vm.getNICs()) {
if (nic.getNetworkId() == network.getId()) {
hasStaticIpNic = true;
assertEquals(nic.getIPAddress(), ipAddress);
}
}
assert hasStaticIpNic;
checkVm(vm);
} finally {
if (vm != null) {
destroyMachine(vm);
vm = null;
}
if (network != null) {
long jobId = adminClient.getNetworkClient().deleteNetwork(network.getId());
adminJobComplete.apply(jobId);
network = null;
}
}
}
private void destroyMachine(VirtualMachine virtualMachine) {
assert adminJobComplete.apply(
adminClient.getVirtualMachineClient().destroyVirtualMachine(virtualMachine.getId())) : virtualMachine;
assert adminVirtualMachineDestroyed.apply(virtualMachine);
}
private void conditionallyCheckSSH() { private void conditionallyCheckSSH() {
password = vm.getPassword(); password = vm.getPassword();
assert HostSpecifier.isValid(vm.getIPAddress()); assert HostSpecifier.isValid(vm.getIPAddress());
@ -194,9 +325,8 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest {
@AfterGroups(groups = "live") @AfterGroups(groups = "live")
protected void tearDown() { protected void tearDown() {
if (vm != null) { if (vm != null) {
assert jobComplete.apply(client.getVirtualMachineClient().stopVirtualMachine(vm.getId())) : vm; destroyMachine(vm);
assert jobComplete.apply(client.getVirtualMachineClient().destroyVirtualMachine(vm.getId())) : vm; vm = null;
assert virtualMachineDestroyed.apply(vm);
} }
super.tearDown(); super.tearDown();
} }