blob: 49030f67d75627e1279fa250cf0cd6c45a42f03b [file] [log] [blame]
/*
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
*(Link.builder().regarding copyright ownership. jclouds 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(Link.builder().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.vcloud.director.v1_5.features;
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.CONDITION_FMT;
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.CORRECT_VALUE_OBJECT_FMT;
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.ENTITY_EQUAL;
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.MATCHES_STRING_FMT;
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.NOT_EMPTY_OBJECT_FMT;
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_FIELD_EQ;
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.TASK_COMPLETE_TIMELY;
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorMediaType.ADMIN_USER;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkControlAccessParams;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkLeaseSettingsSection;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkMetadata;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkMetadataFor;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkMetadataKeyAbsentFor;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkMetadataValue;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkMetadataValueFor;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkNetworkConfigSection;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkNetworkSection;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkOwner;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkProductSectionList;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkStartupSection;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkVApp;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.jclouds.dmtf.ovf.MsgType;
import org.jclouds.dmtf.ovf.NetworkSection;
import org.jclouds.dmtf.ovf.ProductSection;
import org.jclouds.dmtf.ovf.StartupSection;
import org.jclouds.vcloud.director.v1_5.AbstractVAppApiLiveTest;
import org.jclouds.vcloud.director.v1_5.domain.AccessSetting;
import org.jclouds.vcloud.director.v1_5.domain.Checks;
import org.jclouds.vcloud.director.v1_5.domain.Metadata;
import org.jclouds.vcloud.director.v1_5.domain.MetadataEntry;
import org.jclouds.vcloud.director.v1_5.domain.MetadataValue;
import org.jclouds.vcloud.director.v1_5.domain.Owner;
import org.jclouds.vcloud.director.v1_5.domain.ProductSectionList;
import org.jclouds.vcloud.director.v1_5.domain.Reference;
import org.jclouds.vcloud.director.v1_5.domain.ResourceEntity.Status;
import org.jclouds.vcloud.director.v1_5.domain.Task;
import org.jclouds.vcloud.director.v1_5.domain.User;
import org.jclouds.vcloud.director.v1_5.domain.VApp;
import org.jclouds.vcloud.director.v1_5.domain.VAppTemplate;
import org.jclouds.vcloud.director.v1_5.domain.Vm;
import org.jclouds.vcloud.director.v1_5.domain.network.DhcpService;
import org.jclouds.vcloud.director.v1_5.domain.network.FirewallService;
import org.jclouds.vcloud.director.v1_5.domain.network.IpRange;
import org.jclouds.vcloud.director.v1_5.domain.network.IpRanges;
import org.jclouds.vcloud.director.v1_5.domain.network.IpScope;
import org.jclouds.vcloud.director.v1_5.domain.network.NatService;
import org.jclouds.vcloud.director.v1_5.domain.network.Network;
import org.jclouds.vcloud.director.v1_5.domain.network.Network.FenceMode;
import org.jclouds.vcloud.director.v1_5.domain.network.NetworkAssignment;
import org.jclouds.vcloud.director.v1_5.domain.network.NetworkConfiguration;
import org.jclouds.vcloud.director.v1_5.domain.network.NetworkConnection;
import org.jclouds.vcloud.director.v1_5.domain.network.NetworkConnection.IpAddressAllocationMode;
import org.jclouds.vcloud.director.v1_5.domain.network.NetworkFeatures;
import org.jclouds.vcloud.director.v1_5.domain.network.SyslogServerSettings;
import org.jclouds.vcloud.director.v1_5.domain.network.VAppNetworkConfiguration;
import org.jclouds.vcloud.director.v1_5.domain.params.ComposeVAppParams;
import org.jclouds.vcloud.director.v1_5.domain.params.ControlAccessParams;
import org.jclouds.vcloud.director.v1_5.domain.params.DeployVAppParams;
import org.jclouds.vcloud.director.v1_5.domain.params.InstantiationParams;
import org.jclouds.vcloud.director.v1_5.domain.params.RecomposeVAppParams;
import org.jclouds.vcloud.director.v1_5.domain.params.SourcedCompositionItemParam;
import org.jclouds.vcloud.director.v1_5.domain.params.UndeployVAppParams;
import org.jclouds.vcloud.director.v1_5.domain.section.GuestCustomizationSection;
import org.jclouds.vcloud.director.v1_5.domain.section.LeaseSettingsSection;
import org.jclouds.vcloud.director.v1_5.domain.section.NetworkConfigSection;
import org.jclouds.vcloud.director.v1_5.domain.section.NetworkConnectionSection;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.base.CharMatcher;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
/**
* Tests behavior of the {@link VAppApi}.
*
* @author grkvlt@apache.org
*/
@Test(groups = { "live", "user" }, singleThreaded = true, testName = "VAppApiLiveTest")
public class VAppApiLiveTest extends AbstractVAppApiLiveTest {
private MetadataValue metadataValue;
private String key;
private boolean testUserCreated = false;
private User user;
@BeforeClass(alwaysRun = true)
protected void setupRequiredEntities() {
if (adminContext != null) {
userUrn = adminContext.getApi().getUserApi().addUserToOrg(randomTestUser("VAppAccessTest"), org.getId())
.getId();
}
user = lazyGetUser();
}
@AfterClass(alwaysRun = true, dependsOnMethods = { "cleanUpEnvironment" })
public void cleanUp() {
if (adminContext != null && testUserCreated && userUrn != null) {
try {
adminContext.getApi().getUserApi().remove(userUrn);
} catch (Exception e) {
logger.warn(e, "Error when deleting user");
}
}
}
/**
* @see VAppApi#get(URI)
*/
@Test(description = "GET /vApp/{id}")
public void testGetVApp() {
// The method under test
vApp = vAppApi.get(vAppUrn);
// Check the retrieved object is well formed
checkVApp(vApp);
// Check the required fields are set
assertEquals(vApp.isDeployed(), Boolean.FALSE,
String.format(OBJ_FIELD_EQ, VAPP, "deployed", "FALSE", vApp.isDeployed().toString()));
assertTrue(vApp.getName().startsWith("test-vapp-"),
String.format(MATCHES_STRING_FMT, "name", "test-vapp-*", vApp.getName()));
assertEquals(vApp.getDescription(), "Test VApp",
String.format(OBJ_FIELD_EQ, VAPP, "Description", "Test VApp", vApp.getDescription()));
// TODO instantiationParams instantiationParams()
// TODO source.href vAppTemplateURI
// Check status
assertVAppStatus(vAppUrn, Status.POWERED_OFF);
}
@Test(description = "POST /vApp/{id}/action/recomposeVApp")
public void testRecomposeVApp() {
VApp composedVApp = vdcApi.composeVApp(vdcUrn, ComposeVAppParams.builder()
.name(name("composed-"))
.instantiationParams(instantiationParams())
.build());
Set<Vm> vms = getAvailableVMsFromVAppTemplate(vAppTemplate);
// get the first vm to be added to vApp
Vm toAddVm = Iterables.get(vms, 0);
// TODO clean up network config of the vm
//cleanUpNetworkConnectionSection(toAddVm);
RecomposeVAppParams params = addRecomposeParams(composedVApp, toAddVm);
// The method under test
Task recomposeVApp = vAppApi.recompose(composedVApp.getId(), params);
assertTaskSucceedsLong(recomposeVApp);
// remove a vm
VApp configured = vAppApi.get(composedVApp.getId());
List<Vm> vmsToBeDeleted = configured.getChildren().getVms();
Vm toBeDeleted = Iterables.find(vmsToBeDeleted, new Predicate<Vm>() {
@Override
public boolean apply(Vm vm) {
return vm.getName().startsWith("vm-");
}
});
Task removeVm = vmApi.remove(toBeDeleted.getId());
assertTaskSucceedsLong(removeVm);
Task deleteVApp = vAppApi.remove(composedVApp.getHref());
assertTaskSucceedsLong(deleteVApp);
}
private Set<Vm> getAvailableVMsFromVAppTemplate(VAppTemplate vAppTemplate) {
return ImmutableSet.copyOf(Iterables.filter(vAppTemplate.getChildren(), new Predicate<Vm>() {
// filter out vms in the vApp template with computer name that contains underscores, dots,
// or both.
@Override
public boolean apply(Vm input) {
GuestCustomizationSection guestCustomizationSection = vmApi.getGuestCustomizationSection(input.getId());
String computerName = guestCustomizationSection.getComputerName();
String retainComputerName = CharMatcher.inRange('0', '9').or(CharMatcher.inRange('a', 'z'))
.or(CharMatcher.inRange('A', 'Z')).or(CharMatcher.is('-')).retainFrom(computerName);
return computerName.equals(retainComputerName);
}
}));
}
/**
* @see VAppApi#edit(URI, VApp)
*/
@Test(description = "PUT /vApp/{id}", dependsOnMethods = { "testGetVApp" })
public void testEditVApp() {
VApp newVApp = VApp.builder().name(name("new-name-")).description("New Description").build();
vAppNames.add(newVApp.getName());
// The method under test
Task editVApp = vAppApi.edit(vAppUrn, newVApp);
assertTrue(retryTaskSuccess.apply(editVApp), String.format(TASK_COMPLETE_TIMELY, "editVApp"));
// Get the edited VApp
vApp = vAppApi.get(vAppUrn);
// Check the required fields are set
assertEquals(vApp.getName(), newVApp.getName(),
String.format(OBJ_FIELD_EQ, VAPP, "Name", newVApp.getName(), vApp.getName()));
assertEquals(vApp.getDescription(), newVApp.getDescription(),
String.format(OBJ_FIELD_EQ, VAPP, "Description", newVApp.getDescription(), vApp.getDescription()));
}
@Test(description = "POST /vApp/{id}/action/deploy", dependsOnMethods = { "testGetVApp" })
public void testDeployVApp() {
DeployVAppParams params = DeployVAppParams.builder()
.deploymentLeaseSeconds((int) TimeUnit.SECONDS.convert(1L, TimeUnit.HOURS)).notForceCustomization()
.notPowerOn().build();
// The method under test
Task deployVApp = vAppApi.deploy(vAppUrn, params);
assertTrue(retryTaskSuccessLong.apply(deployVApp), String.format(TASK_COMPLETE_TIMELY, "deployVApp"));
// Get the edited VApp
vApp = vAppApi.get(vAppUrn);
// Check the required fields are set
assertTrue(vApp.isDeployed(), String.format(OBJ_FIELD_EQ, VAPP, "deployed", "TRUE", vApp.isDeployed().toString()));
// Check status
assertVAppStatus(vAppUrn, Status.POWERED_OFF);
}
@Test(description = "POST /vApp/{id}/power/action/powerOn", dependsOnMethods = { "testDeployVApp" })
public void testPowerOnVApp() {
// Power off VApp
vApp = powerOffVApp(vAppUrn);
// The method under test
Task powerOnVApp = vAppApi.powerOn(vAppUrn);
assertTaskSucceedsLong(powerOnVApp);
// Get the edited VApp
vApp = vAppApi.get(vAppUrn);
// Check status
assertVAppStatus(vAppUrn, Status.POWERED_ON);
}
@Test(description = "POST /vApp/{id}/power/action/reboot", dependsOnMethods = { "testDeployVApp" })
public void testReboot() {
// Power on VApp
vApp = powerOnVApp(vAppUrn);
// The method under test
Task reboot = vAppApi.reboot(vAppUrn);
assertTaskSucceedsLong(reboot);
// Get the edited VApp
vApp = vAppApi.get(vAppUrn);
// Check status
assertVAppStatus(vAppUrn, Status.POWERED_OFF);
}
@Test(description = "POST /vApp/{id}/power/action/shutdown", dependsOnMethods = { "testDeployVApp" })
public void testShutdown() {
// Power on VApp
vApp = powerOnVApp(vAppUrn);
vApp = vAppApi.get(vAppUrn);
// The method under test
Task shutdown = vAppApi.shutdown(vAppUrn);
assertTaskSucceedsLong(shutdown);
// Get the edited VApp
vApp = vAppApi.get(vAppUrn);
// Check status
assertVAppStatus(vAppUrn, Status.POWERED_OFF);
// Power on the VApp again
vApp = powerOnVApp(vAppUrn);
}
@Test(description = "POST /vApp/{id}/power/action/suspend", dependsOnMethods = { "testDeployVApp" })
public void testSuspend() {
// Power on VApp
vApp = powerOnVApp(vAppUrn);
// The method under test
Task suspend = vAppApi.suspend(vAppUrn);
assertTaskSucceedsLong(suspend);
// Get the edited VApp
vApp = vAppApi.get(vAppUrn);
// Check status
assertVAppStatus(vAppUrn, Status.SUSPENDED);
// Power on the VApp again
vApp = powerOnVApp(vAppUrn);
}
@Test(description = "POST /vApp/{id}/power/action/reset", dependsOnMethods = { "testDeployVApp" })
public void testReset() {
// Power on VApp
vApp = powerOnVApp(vAppUrn);
// The method under test
Task reset = vAppApi.reset(vAppUrn);
assertTaskSucceedsLong(reset);
// Get the edited VApp
vApp = vAppApi.get(vAppUrn);
// Check status
assertVAppStatus(vAppUrn, Status.POWERED_ON);
}
@Test(description = "POST /vApp/{id}/action/undeploy", dependsOnMethods = { "testDeployVApp" })
public void testUndeployVApp() {
// Power on VApp
vApp = powerOnVApp(vAppUrn);
UndeployVAppParams params = UndeployVAppParams.builder().build();
// The method under test
Task undeploy = vAppApi.undeploy(vAppUrn, params);
assertTrue(retryTaskSuccess.apply(undeploy), String.format(TASK_COMPLETE_TIMELY, "undeploy"));
// Get the edited VApp
vApp = vAppApi.get(vAppUrn);
// Check status
assertFalse(vApp.isDeployed(),
String.format(OBJ_FIELD_EQ, VAPP, "deployed", "FALSE", vApp.isDeployed().toString()));
assertVAppStatus(vAppUrn, Status.POWERED_OFF);
}
@Test(description = "POST /vApp/{id}/power/action/powerOff", dependsOnMethods = { "testUndeployVApp" })
public void testPowerOffVApp() {
// Power on VApp
vApp = powerOnVApp(vAppUrn);
// The method under test
Task powerOffVApp = vAppApi.powerOff(vAppUrn);
assertTrue(retryTaskSuccess.apply(powerOffVApp), String.format(TASK_COMPLETE_TIMELY, "powerOffVApp"));
// Get the edited VApp
vApp = vAppApi.get(vAppUrn);
// Check status
assertVAppStatus(vAppUrn, Status.POWERED_OFF);
}
@Test(description = "POST /vApp/{id}/action/controlAccess", dependsOnMethods = { "testGetVApp" })
public void testControlAccessUser() {
ControlAccessParams params = ControlAccessParams
.builder()
.notSharedToEveryone()
.accessSetting(
AccessSetting.builder()
.subject(Reference.builder().href(user.getHref()).type(ADMIN_USER).build())
.accessLevel("ReadOnly").build()).build();
// The method under test
ControlAccessParams modified = vAppApi.editControlAccess(vAppUrn, params);
// Check the retrieved object is well formed
checkControlAccessParams(modified);
// Check the required fields are set
assertEquals(modified, params, String.format(ENTITY_EQUAL, "ControlAccessParams"));
}
@Test(description = "POST /vApp/{id}/action/controlAccess", dependsOnMethods = { "testControlAccessUser" })
public void testControlAccessEveryone() {
ControlAccessParams params = ControlAccessParams.builder().sharedToEveryone().everyoneAccessLevel("FullControl")
.build();
// The method under test
ControlAccessParams modified = vAppApi.editControlAccess(vAppUrn, params);
// Check the retrieved object is well formed
checkControlAccessParams(modified);
// Check entities are equal
assertEquals(modified, params, String.format(ENTITY_EQUAL, "ControlAccessParams"));
}
@Test(description = "POST /vApp/{id}/action/discardSuspendedState", dependsOnMethods = { "testDeployVApp" })
public void testDiscardSuspendedState() {
// Power on, then suspend the VApp
vApp = powerOnVApp(vAppUrn);
vApp = suspendVApp(vAppUrn);
// The method under test
Task discardSuspendedState = vAppApi.discardSuspendedState(vAppUrn);
assertTrue(retryTaskSuccess.apply(discardSuspendedState),
String.format(TASK_COMPLETE_TIMELY, "discardSuspendedState"));
}
@Test(description = "POST /vApp/{id}/action/enterMaintenanceMode", groups = { "systemAdmin" })
public void testEnterMaintenanceMode() {
// Do this to a new vApp, so don't mess up subsequent tests by making the vApp read-only
VApp temp = instantiateVApp();
DeployVAppParams params = DeployVAppParams.builder()
.deploymentLeaseSeconds((int) TimeUnit.SECONDS.convert(1L, TimeUnit.HOURS)).notForceCustomization()
.notPowerOn().build();
Task deployVApp = vAppApi.deploy(temp.getId(), params);
assertTaskSucceedsLong(deployVApp);
try {
// Method under test
vAppApi.enterMaintenanceMode(temp.getId());
temp = vAppApi.get(temp.getId());
assertTrue(temp.isInMaintenanceMode(),
String.format(CONDITION_FMT, "InMaintenanceMode", "TRUE", temp.isInMaintenanceMode()));
// Exit maintenance mode
vAppApi.exitMaintenanceMode(temp.getId());
} finally {
cleanUpVApp(temp);
}
}
@Test(description = "POST /vApp/{id}/action/exitMaintenanceMode", dependsOnMethods = { "testEnterMaintenanceMode" }, groups = { "systemAdmin" })
public void testExitMaintenanceMode() {
// Do this to a new vApp, so don't mess up subsequent tests by making the vApp read-only
VApp temp = instantiateVApp();
DeployVAppParams params = DeployVAppParams.builder()
.deploymentLeaseSeconds((int) TimeUnit.SECONDS.convert(1L, TimeUnit.HOURS)).notForceCustomization()
.notPowerOn().build();
Task deployVApp = vAppApi.deploy(temp.getId(), params);
assertTaskSucceedsLong(deployVApp);
try {
// Enter maintenance mode
vAppApi.enterMaintenanceMode(temp.getId());
// Method under test
vAppApi.exitMaintenanceMode(temp.getId());
temp = vAppApi.get(temp.getId());
assertFalse(temp.isInMaintenanceMode(),
String.format(CONDITION_FMT, "InMaintenanceMode", "FALSE", temp.isInMaintenanceMode()));
} finally {
cleanUpVApp(temp);
}
}
@Test(description = "GET /vApp/{id}/controlAccess", dependsOnMethods = { "testGetVApp" })
public void testGetControlAccess() {
// The method under test
ControlAccessParams controlAccess = vAppApi.getAccessControl(vAppUrn);
// Check the retrieved object is well formed
checkControlAccessParams(controlAccess);
}
@Test(description = "GET /vApp/{id}/leaseSettingsSection", dependsOnMethods = { "testGetVApp" })
public void testGetLeaseSettingsSection() {
// The method under test
LeaseSettingsSection section = vAppApi.getLeaseSettingsSection(vAppUrn);
// Check the retrieved object is well formed
checkLeaseSettingsSection(section);
}
@Test(description = "PUT /vApp/{id}/leaseSettingsSection", dependsOnMethods = { "testGetLeaseSettingsSection" })
public void testEditLeaseSettingsSection() {
// Copy existing section
LeaseSettingsSection oldSection = vAppApi.getLeaseSettingsSection(vAppUrn);
Integer twoHours = (int) TimeUnit.SECONDS.convert(2L, TimeUnit.HOURS);
LeaseSettingsSection newSection = oldSection.toBuilder().deploymentLeaseInSeconds(twoHours).build();
// The method under test
Task editLeaseSettingsSection = vAppApi.editLeaseSettingsSection(vAppUrn, newSection);
assertTrue(retryTaskSuccess.apply(editLeaseSettingsSection),
String.format(TASK_COMPLETE_TIMELY, "editLeaseSettingsSection"));
// Retrieve the modified section
LeaseSettingsSection modified = vAppApi.getLeaseSettingsSection(vAppUrn);
// Check the retrieved object is well formed
checkLeaseSettingsSection(modified);
// Check the date fields
if (modified.getDeploymentLeaseExpiration() != null && newSection.getDeploymentLeaseExpiration() != null) {
assertTrue(modified.getDeploymentLeaseExpiration().after(newSection.getDeploymentLeaseExpiration()),
String.format("The new deploymentLeaseExpiration timestamp must be later than the original: %s > %s",
dateService.iso8601DateFormat(modified.getDeploymentLeaseExpiration()),
dateService.iso8601DateFormat(newSection.getDeploymentLeaseExpiration())));
}
if (modified.getStorageLeaseExpiration() != null && newSection.getStorageLeaseExpiration() != null) {
assertTrue(modified.getStorageLeaseExpiration().after(newSection.getStorageLeaseExpiration()), String.format(
"The new storageLeaseExpiration timestamp must be later than the original: %s > %s",
dateService.iso8601DateFormat(modified.getStorageLeaseExpiration()),
dateService.iso8601DateFormat(newSection.getStorageLeaseExpiration())));
}
// Reset the date fields
modified = modified.toBuilder().deploymentLeaseExpiration(null).storageLeaseExpiration(null).build();
newSection = newSection.toBuilder().deploymentLeaseExpiration(null).storageLeaseExpiration(null).build();
// Check the section was modified correctly
assertEquals(
modified.getDeploymentLeaseInSeconds(),
twoHours,
String.format(OBJ_FIELD_EQ, "LeaseSettingsSection", "DeploymentLeaseInSeconds",
Integer.toString(twoHours), modified.getDeploymentLeaseInSeconds().toString()));
assertEquals(modified, newSection, String.format(ENTITY_EQUAL, "LeaseSettingsSection"));
}
@Test(description = "GET /vApp/{id}/networkConfigSection", dependsOnMethods = { "testGetVApp" })
public void testGetNetworkConfigSection() {
// The method under test
NetworkConfigSection section = vAppApi.getNetworkConfigSection(vAppUrn);
// Check the retrieved object is well formed
checkNetworkConfigSection(section);
}
@Test(description = "PUT /vApp/{id}/networkConfigSection", dependsOnMethods = { "testGetNetworkConfigSection" })
public void testEditNetworkConfigSection() {
// Copy existing section and update fields
NetworkConfigSection oldSection = vAppApi.getNetworkConfigSection(vAppUrn);
Network network = lazyGetNetwork();
tryFindBridgedNetworkInOrg();
IpRange ipRange = ipRange();
NetworkConfiguration newConfiguration = NetworkConfiguration.builder()
.ipScope(ipScope(ipRange))
.parentNetwork(Reference.builder().fromEntity(network).build())
.fenceMode(FenceMode.NAT_ROUTED)
.retainNetInfoAcrossDeployments(false)
.syslogServerSettings(SyslogServerSettings.builder().syslogServerIp1("192.168.14.27").build())
.features(NetworkFeatures.builder()
.service(DhcpService.builder()
.ipRange(ipRange)
.build())
.service(FirewallService.builder()
.logDefaultAction(false)
.defaultAction("drop")
.build())
.service(NatService.builder()
.natType("portForwarding")
.enabled(false)
.build())
.build())
.build();
final String networkName = name("vAppNetwork-");
VAppNetworkConfiguration newVAppNetworkConfiguration = VAppNetworkConfiguration.builder()
.networkName(networkName)
.description(name("description-"))
.configuration(newConfiguration)
.build();
NetworkConfigSection newSection = oldSection.toBuilder().networkConfigs(ImmutableSet.of(newVAppNetworkConfiguration)).build();
// The method under test
Task editNetworkConfigSection = vAppApi.editNetworkConfigSection(vAppUrn, newSection);
assertTrue(retryTaskSuccess.apply(editNetworkConfigSection),
String.format(TASK_COMPLETE_TIMELY, "editNetworkConfigSection"));
// Retrieve the modified section
NetworkConfigSection modified = vAppApi.getNetworkConfigSection(vAppUrn);
// Check the retrieved object is well formed
checkNetworkConfigSection(modified);
Optional<VAppNetworkConfiguration> modifiedOptionalVAppNetwork = Iterables.tryFind(modified.getNetworkConfigs(), new IsVAppNetworkNamed(networkName));
if(!modifiedOptionalVAppNetwork.isPresent())
fail(String.format("Could not find vApp network named %s", networkName));
Optional<VAppNetworkConfiguration> newOptionalVAppNetwork = Iterables.tryFind(newSection.getNetworkConfigs(), new IsVAppNetworkNamed(networkName));
if(!newOptionalVAppNetwork.isPresent())
fail(String.format("Could not find vApp network named %s", networkName));
assertEquals(modifiedOptionalVAppNetwork.get().getNetworkName(), newOptionalVAppNetwork.get().getNetworkName(), String.format(ENTITY_EQUAL, "NetworkName"));
assertEquals(modifiedOptionalVAppNetwork.get().getConfiguration().getFenceMode(), newOptionalVAppNetwork.get().getConfiguration().getFenceMode(), String.format(ENTITY_EQUAL, "FenceMode"));
assertEquals(modifiedOptionalVAppNetwork.get().getConfiguration().getIpScope(), newOptionalVAppNetwork.get().getConfiguration().getIpScope(), String.format(ENTITY_EQUAL, "IpScope"));
assertEquals(modifiedOptionalVAppNetwork.get().getConfiguration().getNetworkFeatures(), newOptionalVAppNetwork.get().getConfiguration().getNetworkFeatures(), String.format(ENTITY_EQUAL, "NetworkFeatures"));
}
private IpRange ipRange() {
return IpRange.builder()
.startAddress("192.168.2.100")
.endAddress("192.168.2.199")
.build();
}
private IpScope ipScope(IpRange ipRange) {
IpRanges newIpRanges = IpRanges.builder()
.ipRange(ipRange)
.build();
return IpScope.builder()
.isInherited(false)
.gateway("192.168.2.1")
.netmask("255.255.0.0")
.ipRanges(newIpRanges).build();
}
@Test(description = "GET /vApp/{id}/networkSection", dependsOnMethods = { "testGetVApp" })
public void testGetNetworkSection() {
// The method under test
NetworkSection section = vAppApi.getNetworkSection(vAppUrn);
// Check the retrieved object is well formed
checkNetworkSection(section);
}
@Test(description = "GET /vApp/{id}/owner", dependsOnMethods = { "testGetVApp" })
public void testGetOwner() {
// The method under test
Owner owner = vAppApi.getOwner(vAppUrn);
// Check the retrieved object is well formed
checkOwner(owner);
}
@Test(description = "PUT /vApp/{id}/owner", dependsOnMethods = { "testGetOwner" })
public void testEditOwner() {
Owner newOwner = Owner.builder().user(Reference.builder().href(user.getHref()).type(ADMIN_USER).build()).build();
// The method under test
vAppApi.editOwner(vAppUrn, newOwner);
// Get the new VApp owner
Owner modified = vAppApi.getOwner(vAppUrn);
// Check the retrieved object is well formed
checkOwner(modified);
// Check the href fields match
assertEquals(modified.getUser().getHref(), newOwner.getUser().getHref());
}
@Test(description = "GET /vApp/{id}/productSections", dependsOnMethods = { "testGetVApp" })
public void testGetProductSections() {
// The method under test
ProductSectionList sectionList = vAppApi.getProductSections(vAppUrn);
// Check the retrieved object is well formed
checkProductSectionList(sectionList);
}
@Test(description = "PUT /vApp/{id}/productSections", dependsOnMethods = { "testGetProductSections" })
public void testEditProductSections() {
// Copy existing section and edit fields
ProductSectionList oldSections = vAppApi.getProductSections(vAppUrn);
ProductSectionList newSections = oldSections
.toBuilder()
.productSection(
ProductSection.builder().info("Information about the installed software")
// Default ovf:Info text
.required().product(MsgType.builder().value("jclouds").build())
.vendor(MsgType.builder().value("jclouds Inc.").build())
// NOTE other ProductSection elements not returned by vCloud
.build()).build();
// The method under test
Task editProductSections = vAppApi.editProductSections(vAppUrn, newSections);
assertTrue(retryTaskSuccess.apply(editProductSections),
String.format(TASK_COMPLETE_TIMELY, "editProductSections"));
// Retrieve the modified section
ProductSectionList modified = vAppApi.getProductSections(vAppUrn);
// Check the retrieved object is well formed
checkProductSectionList(modified);
// Check the modified object has an extra ProductSection
assertEquals(modified.getProductSections().size(), oldSections.getProductSections().size() + 1);
// Check the section was modified correctly
assertEquals(modified, newSections);
}
@Test(description = "GET /vApp/{id}/startupSection", dependsOnMethods = { "testGetVApp" })
public void testGetStartupSection() {
// The method under test
StartupSection section = vAppApi.getStartupSection(vAppUrn);
// Check the retrieved object is well formed
checkStartupSection(section);
}
@Test(description = "PUT /vApp/{id}/startupSection", dependsOnMethods = { "testGetStartupSection" })
public void testEditStartupSection() {
// Copy existing section and edit fields
StartupSection oldSection = vAppApi.getStartupSection(vAppUrn);
StartupSection newSection = oldSection.toBuilder().build();
// The method under test
Task editStartupSection = vAppApi.editStartupSection(vAppUrn, newSection);
assertTrue(retryTaskSuccess.apply(editStartupSection), String.format(TASK_COMPLETE_TIMELY, "editStartupSection"));
// Retrieve the modified section
StartupSection modified = vAppApi.getStartupSection(vAppUrn);
// Check the retrieved object is well formed
checkStartupSection(modified);
// Check the modified section fields are set correctly
assertEquals(modified, newSection);
}
@Test(description = "PUT /vApp/{id}/metadata", dependsOnMethods = { "testGetVApp" })
public void testSetMetadataValue() {
key = name("key-");
String value = name("value-");
metadataValue = MetadataValue.builder().value(value).build();
vAppApi.getMetadataApi(vAppUrn).putEntry(key, metadataValue);
// Retrieve the value, and assert it was set correctly
MetadataValue newMetadataValue = vAppApi.getMetadataApi(vAppUrn).getValue(key);
// Check the retrieved object is well formed
checkMetadataValueFor(VAPP, newMetadataValue, value);
}
@Test(description = "GET /vApp/{id}/metadata", dependsOnMethods = { "testSetMetadataValue" })
public void testGetMetadata() {
key = name("key-");
String value = name("value-");
metadataValue = MetadataValue.builder().value(value).build();
vAppApi.getMetadataApi(vAppUrn).putEntry(key, metadataValue);
// Call the method being tested
Metadata metadata = vAppApi.getMetadataApi(vAppUrn).get();
checkMetadata(metadata);
// Check requirements for this test
assertFalse(Iterables.isEmpty(metadata.getMetadataEntries()),
String.format(NOT_EMPTY_OBJECT_FMT, "MetadataEntry", "vApp"));
}
@Test(description = "GET /vApp/{id}/metadata/{key}", dependsOnMethods = { "testGetMetadata" })
public void testGetOrgMetadataValue() {
key = name("key-");
String value = name("value-");
metadataValue = MetadataValue.builder().value(value).build();
vAppApi.getMetadataApi(vAppUrn).putEntry(key, metadataValue);
// Call the method being tested
MetadataValue newValue = vAppApi.getMetadataApi(vAppUrn).getValue(key);
String expected = metadataValue.getValue();
checkMetadataValue(newValue);
assertEquals(newValue.getValue(), expected,
String.format(CORRECT_VALUE_OBJECT_FMT, "Value", "MetadataValue", expected, newValue.getValue()));
}
@Test(description = "DELETE /vApp/{id}/metadata/{key}", dependsOnMethods = { "testSetMetadataValue" })
public void testRemoveMetadataEntry() {
// Delete the entry
Task task = vAppApi.getMetadataApi(vAppUrn).removeEntry(key);
retryTaskSuccess.apply(task);
// Confirm the entry has been removed
Metadata newMetadata = vAppApi.getMetadataApi(vAppUrn).get();
// Check the retrieved object is well formed
checkMetadataKeyAbsentFor(VAPP, newMetadata, key);
}
@Test(description = "POST /vApp/{id}/metadata", dependsOnMethods = { "testGetMetadata" })
public void testMergeMetadata() {
Metadata oldMetadata = vAppApi.getMetadataApi(vAppUrn).get();
Map<String, String> oldMetadataMap = Checks.metadataToMap(oldMetadata);
// Store a value, to be removed
String key = name("key-");
String value = name("value-");
Metadata addedMetadata = Metadata.builder().entry(MetadataEntry.builder().key(key).value(value).build()).build();
Task task = vAppApi.getMetadataApi(vAppUrn).merge(addedMetadata);
retryTaskSuccess.apply(task);
// Confirm the entry contains everything that was there, and everything that was being added
Metadata newMetadata = vAppApi.getMetadataApi(vAppUrn).get();
Map<String, String> expectedMetadataMap = ImmutableMap.<String, String> builder().putAll(oldMetadataMap)
.put(key, value).build();
// Check the retrieved object is well formed
checkMetadataFor(VAPP, newMetadata, expectedMetadataMap);
}
/**
* @see VAppApi#remove(URI)
*/
@Test(description = "DELETE /vApp/{id}")
public void testRemoveVApp() {
// Create a temporary VApp to remove
VApp temp = instantiateVApp();
// The method under test
Task removeVApp = vAppApi.remove(temp.getId());
assertTrue(retryTaskSuccess.apply(removeVApp), String.format(TASK_COMPLETE_TIMELY, "removeVApp"));
VApp removed = vAppApi.get(temp.getId());
assertNull(removed, "The VApp " + temp.getName() + " should have been removed");
}
/**
* Create the recompose vapp params.
*
* @param vappTemplateRef
* @param vdc
* @return
* @throws VCloudException
*/
public RecomposeVAppParams addRecomposeParams(VApp vApp, Vm vm) {
// creating an item element. this item will contain the vm which should be added to the vapp.
Reference reference = Reference.builder().name(name("vm-")).href(vm.getHref()).type(vm.getType()).build();
SourcedCompositionItemParam vmItem = SourcedCompositionItemParam.builder().source(reference).build();
InstantiationParams vmInstantiationParams = null;
Set<NetworkAssignment> networkAssignments = Sets.newLinkedHashSet();
// if the vm contains a network connection and the vApp does not contain any configured
// network
if (vmHasNetworkConnectionConfigured(vm)) {
if (!vAppHasNetworkConfigured(vApp)) {
// add a new network connection section for the vm.
NetworkConnectionSection networkConnectionSection = NetworkConnectionSection.builder()
.info("Empty network configuration parameters").build();
// adding the network connection section to the instantiation params of the vapp.
vmInstantiationParams = InstantiationParams.builder().sections(ImmutableSet.of(networkConnectionSection))
.build();
}
// if the vm already contains a network connection section and if the vapp contains a
// configured network -> vm could be mapped to that network.
else {
Set<VAppNetworkConfiguration> vAppNetworkConfigurations = listVappNetworkConfigurations(vApp);
for (VAppNetworkConfiguration vAppNetworkConfiguration : vAppNetworkConfigurations) {
NetworkAssignment networkAssignment = NetworkAssignment.builder()
.innerNetwork(vAppNetworkConfiguration.getNetworkName())
.containerNetwork(vAppNetworkConfiguration.getNetworkName()).build();
networkAssignments.add(networkAssignment);
}
}
}
// if the vm does not contain any network connection sections and if the
// vapp contains a network configuration. we should add the vm to this
// vapp network
else {
if (vAppHasNetworkConfigured(vApp)) {
VAppNetworkConfiguration vAppNetworkConfiguration = getVAppNetworkConfig(vApp);
NetworkConnection networkConnection = NetworkConnection.builder()
.network(vAppNetworkConfiguration.getNetworkName())
.ipAddressAllocationMode(IpAddressAllocationMode.DHCP).build();
NetworkConnectionSection networkConnectionSection = NetworkConnectionSection.builder().info("networkInfo")
.primaryNetworkConnectionIndex(0).networkConnection(networkConnection).build();
// adding the network connection section to the instantiation params of the vapp.
vmInstantiationParams = InstantiationParams.builder().sections(ImmutableSet.of(networkConnectionSection))
.build();
}
}
if (vmInstantiationParams != null)
vmItem = SourcedCompositionItemParam.builder().fromSourcedCompositionItemParam(vmItem)
.instantiationParams(vmInstantiationParams).build();
if (networkAssignments != null)
vmItem = SourcedCompositionItemParam.builder().fromSourcedCompositionItemParam(vmItem)
.networkAssignment(networkAssignments).build();
return RecomposeVAppParams.builder().name(name("recompose-"))
// adding the vm item.
.sourcedItems(ImmutableList.of(vmItem)).build();
}
private final class IsVAppNetworkNamed implements Predicate<VAppNetworkConfiguration> {
private final String networkName;
private IsVAppNetworkNamed(String networkName) {
this.networkName = networkName;
}
@Override
public boolean apply(VAppNetworkConfiguration input) {
return input.getNetworkName().equals(networkName);
}
}
private void cleanUpNetworkConnectionSection(Vm toAddVm) {
NetworkConnectionSection networkConnectionSection = vmApi.getNetworkConnectionSection(toAddVm.getId());
Set<NetworkConnection> networkConnections = networkConnectionSection.getNetworkConnections();
for (NetworkConnection networkConnection : networkConnections) {
NetworkConnection newNetworkConnection = networkConnection.toBuilder().isConnected(false).build();
networkConnectionSection = networkConnectionSection.toBuilder().networkConnection(newNetworkConnection)
.build();
}
Task configureNetwork = vmApi.editNetworkConnectionSection(toAddVm.getId(), networkConnectionSection);
assertTaskSucceedsLong(configureNetwork);
}
}