use of com.vmware.photon.controller.model.resources.ComputeService.ComputeState in project photon-model by vmware.
the class TestAWSEnumerationTask method testEnumeration.
// Runs the enumeration task on the AWS endpoint to list all the instances on the endpoint.
@Test
public void testEnumeration() throws Throwable {
this.host.log("Running test: " + this.currentTestName.getMethodName());
ComputeState vmState = createAWSVMResource(this.host, this.computeHost, this.endpointState, TestAWSSetupUtils.class, zoneId, regionId, null, this.singleNicSpec, this.awsTestContext);
if (this.isMock) {
// Just make a call to the enumeration service and make sure that the adapter patches
// the parent with completion.
enumerateResources(this.host, this.computeHost, this.endpointState, this.isMock, TEST_CASE_MOCK_MODE);
return;
}
// Overriding the page size to test the pagination logic with limited instances on AWS.
// This is a functional test
// so the latency numbers maybe higher from this test due to low page size.
setQueryPageSize(DEFAULT_TEST_PAGE_SIZE);
setQueryResultLimit(DEFAULT_TEST_PAGE_SIZE);
// Provision a single VM . Check initial state.
vmState = provisionMachine(this.host, vmState, this.isMock, this.instancesToCleanUp);
queryComputeInstances(this.host, count2);
queryDocumentsAndAssertExpectedCount(this.host, count2, ComputeDescriptionService.FACTORY_LINK, false);
if (ENABLE_LOAD_BALANCER_ENUMERATION) {
this.lbToCleanUp = provisionAWSLoadBalancerWithEC2Client(this.host, this.lbClient, null, this.subnetId, this.securityGroupId, Collections.singletonList(vmState.id));
}
// CREATION directly on AWS
List<String> instanceIdsToDeleteFirstTime = provisionAWSVMWithEC2Client(this.client, this.host, count4, T2_MICRO_INSTANCE_TYPE, this.subnetId, this.securityGroupId);
List<String> instanceIds = provisionAWSVMWithEC2Client(this.client, this.host, count1, instanceType, this.subnetId, this.securityGroupId);
instanceIdsToDeleteFirstTime.addAll(instanceIds);
this.instancesToCleanUp.addAll(instanceIdsToDeleteFirstTime);
waitForProvisioningToComplete(instanceIdsToDeleteFirstTime, this.host, this.client, ZERO);
// Xenon does not know about the new instances.
ProvisioningUtils.queryComputeInstances(this.host, count2);
// Create S3 bucket on amazon
Map<String, String> tags = new HashMap<>();
tags.put(S3_TAG_KEY_1, S3_TAG_VALUE_1);
tags.put(S3_TAG_KEY_2, S3_TAG_VALUE_2);
createS3BucketAndTags(tags);
this.bucketToBeDeleted = TEST_BUCKET_NAME;
enumerateResources(this.host, this.computeHost, this.endpointState, this.isMock, TEST_CASE_INITIAL);
// Get a count of how many EBS disks are attached to a VM initially.
ComputeState csForDiskLinkValidation = getComputeStateFromId(this.instancesToCleanUp.get(0));
this.initialEbsDiskLinkCount = csForDiskLinkValidation.diskLinks.size();
// Create a volume to be attached to the VM later.
CreateVolumeRequest createVolumeRequest = new CreateVolumeRequest().withAvailabilityZone(csForDiskLinkValidation.zoneId).withVolumeType(VolumeType.Gp2).withSize(10);
CreateVolumeResult createVolumeResult = this.client.createVolume(createVolumeRequest);
this.testEbsId = createVolumeResult.getVolume().getVolumeId();
// Validate if the S3 bucket is enumerated.
validateS3Enumeration(count1, count3);
// Validate S3 tag state count.
validateS3TagStatesCreated();
if (ENABLE_LOAD_BALANCER_ENUMERATION) {
// Validate Load Balancer State
validateLoadBalancerState(this.lbToCleanUp, vmState.documentSelfLink);
}
// Remove a tag from test S3 bucket.
tags.clear();
tags.put(S3_TAG_KEY_1, S3_TAG_VALUE_1);
createS3BucketAndTags(tags);
// 5 new resources should be discovered. Mapping to 2 new compute description and 5 new
// compute states.
// Even though the "t2.micro" is common to the VM provisioned from Xenon
// service and the one directly provisioned on EC2, there is no Compute description
// linking of discovered resources to user defined compute descriptions. So a new system
// generated compute description will be created for "t2.micro"
queryDocumentsAndAssertExpectedCount(this.host, count4, ComputeDescriptionService.FACTORY_LINK, false);
queryDocumentsAndAssertExpectedCount(this.host, count7, ComputeService.FACTORY_LINK, false);
queryDocumentsAndAssertExpectedCount(this.host, count7, DiskService.FACTORY_LINK, false);
// Validate at least 4 availability zones were enumerated
ProvisioningUtils.queryComputeInstancesByType(this.host, count4, ComputeType.ZONE.toString(), false);
// Update Scenario : Check that the tag information is present for the VM tagged above.
String vpCId = validateTagAndNetworkAndComputeDescriptionInformation(vmState);
validateVPCInformation(vpCId);
// Count should be 1 NICs per discovered VM.
int totalNetworkInterfaceStateCount = count6 * this.singleNicSpec.numberOfNics();
validateNetworkInterfaceCount(totalNetworkInterfaceStateCount);
// One VPC should be discovered in the test.
queryDocumentsAndAssertExpectedCount(this.host, count1, NetworkService.FACTORY_LINK, false);
// Verify that the SecurityGroups of the newly created VM has been enumerated and exists
// locally
validateSecurityGroupsInformation(vmState.groupLinks);
// Verify stop flow
// The first instance of instanceIdsToDeleteFirstTime will be stopped.
String instanceIdsToStop = instanceIdsToDeleteFirstTime.get(0);
tagResourcesWithName(this.client, VM_STOPPED_NAME, instanceIdsToStop);
// Stop one instance
stopVMsUsingEC2Client(this.client, this.host, new ArrayList<>(Arrays.asList(instanceIdsToStop)));
// Create stale resources, that later should be deleted by the enumeration
String staleSubnetDocumentSelfLink = markFirstResourceStateAsStale(host, SubnetState.class, SubnetService.FACTORY_LINK);
String staleNetworkDocumentSelfLink = markFirstResourceStateAsStale(host, NetworkState.class, NetworkService.FACTORY_LINK);
// During the enumeration, if one instance is stopped, its public ip address
// will disappear, then the corresponding link of local ComputeState's public
// network interface and its document will be removed.
enumerateResources(this.host, this.computeHost, this.endpointState, this.isMock, TEST_CASE_STOP_VM);
// Validate that test VM still has same number of diskLinks.
csForDiskLinkValidation = getComputeStateFromId(this.instancesToCleanUp.get(0));
assertEquals(csForDiskLinkValidation.diskLinks.size(), this.initialEbsDiskLinkCount);
// Attach volume to test VM.
AttachVolumeRequest attachVolumeRequest = new AttachVolumeRequest().withVolumeId(createVolumeResult.getVolume().getVolumeId()).withInstanceId(csForDiskLinkValidation.id).withDevice("/dev/sdh");
this.client.attachVolume(attachVolumeRequest);
// Validate stale resources have been deleted
validateStaleResourceStateDeletion(staleSubnetDocumentSelfLink, staleNetworkDocumentSelfLink);
// After two enumeration cycles, validate that we did not create duplicate documents for existing
// S3 bucket and validate that we did not add duplicate tagLink in diskState and removed the tagLink
// for tag deleted from AWS.
validateS3Enumeration(count1, count2);
// Remove region from S3 bucket DiskState.
removeS3BucketRegionFromDiskState();
// Validate that deleted S3 tag's local state is deleted.
validateS3TagStatesCreated();
enumerateResources(this.host, this.computeHost, this.endpointState, this.isMock, TEST_CASE_ADDITIONAL_VM);
// Check that newly attached volume got enumerated and the instance now has 1 more diskLink than before.
csForDiskLinkValidation = getComputeStateFromId(this.instancesToCleanUp.get(0));
assertEquals(csForDiskLinkValidation.diskLinks.size(), this.initialEbsDiskLinkCount + 1);
// Validate that diskState of S3 bucket with null region got deleted
validateBucketStateDeletionForNullRegion();
// Delete the S3 bucket created in the test
this.s3Client.deleteBucket(TEST_BUCKET_NAME);
this.bucketToBeDeleted = null;
// Because one public NIC and its document are removed,
// the totalNetworkInterfaceStateCount should go down by 1
validateRemovalOfPublicNetworkInterface(instanceIdsToStop, totalNetworkInterfaceStateCount - 1);
// Provision an additional VM with a different instance type. It should re-use the
// existing compute description created by the enumeration task above.
List<String> instanceIdsToDeleteSecondTime = provisionAWSVMWithEC2Client(this.client, this.host, count1, TestAWSSetupUtils.instanceType, this.subnetId, this.securityGroupId);
this.instancesToCleanUp.addAll(instanceIdsToDeleteSecondTime);
waitForProvisioningToComplete(instanceIdsToDeleteSecondTime, this.host, this.client, ZERO);
enumerateResources(this.host, this.computeHost, this.endpointState, this.isMock, TEST_CASE_ADDITIONAL_VM);
// Validate that we do not add duplicate diskLinks after multiple enumerations.
csForDiskLinkValidation = getComputeStateFromId(this.instancesToCleanUp.get(0));
assertEquals(csForDiskLinkValidation.diskLinks.size(), this.initialEbsDiskLinkCount + 1);
// Detach and delete test EBS volume.
DetachVolumeRequest detachVolumeRequest = new DetachVolumeRequest().withVolumeId(this.testEbsId);
this.client.detachVolume(detachVolumeRequest);
// One additional compute state and no additional compute description should be
// created. 1) compute host CD 2) t2.nano-system generated 3) t2.micro-system generated
// 4) t2.micro-created from test code.
queryDocumentsAndAssertExpectedCount(this.host, count4, ComputeDescriptionService.FACTORY_LINK, false);
ServiceDocumentQueryResult computesResult1 = queryDocumentsAndAssertExpectedCount(this.host, count8, ComputeService.FACTORY_LINK, false);
// validate the internal tag tor type=ec2_instance is set
// query for the existing internal tag state for type=ec2_instance.
// There should be only one internal tag.
validateTagInEntity(computesResult1, ComputeState.class, ec2_instance.toString());
ServiceDocumentQueryResult networkInterfaceResult = queryDocumentsAndAssertExpectedCount(this.host, totalNetworkInterfaceStateCount - 1, NetworkInterfaceService.FACTORY_LINK, false);
validateTagInEntity(networkInterfaceResult, NetworkInterfaceState.class, ec2_net_interface.toString());
ServiceDocumentQueryResult networkStateResult = queryDocumentsAndAssertExpectedCount(this.host, count1, NetworkService.FACTORY_LINK, false);
validateTagInEntity(networkStateResult, NetworkState.class, ec2_vpc.toString());
ServiceDocumentQueryResult subnetStateResult = queryDocumentsAndAssertExpectedCount(this.host, count1, SubnetService.FACTORY_LINK, false);
// TODO Remove. This is to help debug an intermittent test failure.
host.log(Level.INFO, "The subnet result state that I am working with is " + Utils.toJsonHtml(subnetStateResult));
validateTagInEntity(subnetStateResult, SubnetState.class, ec2_subnet.toString());
queryDocumentsAndAssertExpectedCount(this.host, count8, DiskService.FACTORY_LINK, false);
// Verify Deletion flow
// Delete 5 VMs spawned above of type T2_NANO
deleteVMsUsingEC2Client(this.client, this.host, instanceIdsToDeleteFirstTime);
enumerateResources(this.host, this.computeHost, this.endpointState, this.isMock, TEST_CASE_DELETE_VMS);
// Counts should go down. 5 compute states and 5 disk states.
ServiceDocumentQueryResult computesResult2 = queryDocumentsAndAssertExpectedCount(this.host, count3, ComputeService.FACTORY_LINK, false);
queryDocumentsAndAssertExpectedCount(this.host, count3, DiskService.FACTORY_LINK, false);
// Validate that detached test EBS is removed from diskLinks of test instance.
csForDiskLinkValidation = getComputeStateFromId(this.instancesToCleanUp.get(0));
assertEquals(csForDiskLinkValidation.diskLinks.size(), this.initialEbsDiskLinkCount);
// validate the internal tag tor type=ec2_instance is set
// query for the existing internal tag state for type=ec2_instance.
// There should be only one internal tag.
validateTagInEntity(computesResult2, ComputeState.class, ec2_instance.toString());
// Delete 1 VMs spawned above of type T2_Micro
deleteVMsUsingEC2Client(this.client, this.host, instanceIdsToDeleteSecondTime);
enumerateResources(this.host, this.computeHost, this.endpointState, this.isMock, TEST_CASE_DELETE_VM);
// Compute state and disk state count should go down by 1
ServiceDocumentQueryResult computesResult3 = queryDocumentsAndAssertExpectedCount(this.host, count2, ComputeService.FACTORY_LINK, false);
queryDocumentsAndAssertExpectedCount(this.host, count2, DiskService.FACTORY_LINK, false);
// validate the internal tag tor type=ec2_instance is set
// query for the existing internal tag state for type=ec2_instance.
// There should be only one internal tag.
validateTagInEntity(computesResult3, ComputeState.class, ec2_instance.toString());
// Validate that the document for the deleted S3 bucket is deleted after enumeration.
validateS3Enumeration(ZERO, ZERO);
// Delete test EBS volume.
DeleteVolumeRequest deleteVolumeRequest = new DeleteVolumeRequest().withVolumeId(this.testEbsId);
this.client.deleteVolume(deleteVolumeRequest);
this.testEbsId = null;
}
use of com.vmware.photon.controller.model.resources.ComputeService.ComputeState in project photon-model by vmware.
the class TestAWSEnumerationTask method validateHostName.
/**
* Validates the hostname on a compute state is present and not null.
*/
private ComputeState validateHostName(String awsId) throws Throwable {
if (this.isAwsClientMock) {
return null;
}
ComputeState computeState = getComputeByAWSId(this.host, awsId);
String hostName = computeState.hostName;
assertNotNull("'hostname' property should be present", hostName);
return computeState;
}
use of com.vmware.photon.controller.model.resources.ComputeService.ComputeState in project photon-model by vmware.
the class TestAWSEnumerationTask method validateTagAndNetworkAndComputeDescriptionInformation.
/**
* Verifies if the tag information exists for a given resource. And that private and public IP
* addresses are mapped to separate NICs.Also, checks that the compute description mapping is
* not changed in an updated scenario. Currently, this method is being invoked for a VM
* provisioned from Xenon, so the check is to make sure that during discovery it is not
* re-mapped to a system generated compute description.
*
* @throws Throwable
*/
private String validateTagAndNetworkAndComputeDescriptionInformation(ComputeState computeState) throws Throwable {
if (this.isAwsClientMock) {
return null;
}
ComputeState taggedComputeState = getComputeByAWSId(this.host, computeState.id);
assertEquals(taggedComputeState.descriptionLink, computeState.descriptionLink);
assertTrue(taggedComputeState.networkInterfaceLinks != null);
assertEquals(this.singleNicSpec.numberOfNics(), taggedComputeState.networkInterfaceLinks.size());
List<URI> networkLinkURIs = new ArrayList<>();
for (int i = 0; i < taggedComputeState.networkInterfaceLinks.size(); i++) {
networkLinkURIs.add(UriUtils.buildUri(this.host, taggedComputeState.networkInterfaceLinks.get(i)));
}
// Assert that both the public and private IP addresses have been mapped to separated NICs
Map<URI, NetworkInterfaceState> NICMap = this.host.getServiceState(null, NetworkInterfaceState.class, networkLinkURIs);
for (URI uri : networkLinkURIs) {
assertNotNull(NICMap.get(uri).address);
}
// get the VPC information for the provisioned VM
assertTrue(taggedComputeState.customProperties.get(AWS_VPC_ID) != null);
return taggedComputeState.customProperties.get(AWS_VPC_ID);
}
use of com.vmware.photon.controller.model.resources.ComputeService.ComputeState in project photon-model by vmware.
the class VSphereAdapterInstanceService method createUpdateIPOperationsForComputeAndNics.
private List<Operation> createUpdateIPOperationsForComputeAndNics(String computeLink, String ip, Map<String, List<String>> ipV4Addresses, ProvisionContext ctx) {
List<Operation> updateIpAddressOperations = new ArrayList<>();
if (ip != null) {
ComputeState state = new ComputeState();
state.address = ip;
// update compute
Operation updateIpAddress = Operation.createPatch(PhotonModelUriUtils.createInventoryUri(getHost(), computeLink)).setBody(state);
updateIpAddressOperations.add(updateIpAddress);
}
if (ipV4Addresses != null) {
int sizeIpV4Addresses = ipV4Addresses.size();
for (NetworkInterfaceStateWithDetails nic : ctx.nics) {
String deviceKey = null;
deviceKey = VmOverlay.getDeviceKey(nic);
if (deviceKey == null && nic.deviceIndex < sizeIpV4Addresses) {
deviceKey = Integer.toString(nic.deviceIndex);
}
if (deviceKey != null) {
List<String> ipsV4 = ipV4Addresses.containsKey(deviceKey) ? ipV4Addresses.get(deviceKey) : Collections.emptyList();
if (ipsV4.size() > 0) {
NetworkInterfaceState patchNic = new NetworkInterfaceState();
// if nic has multiple ip addresses for ipv4 only pick 1st ip address
patchNic.address = ipsV4.get(0);
Operation updateAddressNetWorkInterface = Operation.createPatch(PhotonModelUriUtils.createInventoryUri(getHost(), nic.documentSelfLink)).setBody(patchNic);
updateIpAddressOperations.add(updateAddressNetWorkInterface);
} else {
log(Level.WARNING, "Address is not going to be updated in network " + "interface state: [%], deviceKey: [%s] was not " + "found in " + "ipV4Addresses: " + "[%s]", nic.documentSelfLink, deviceKey, ipV4Addresses.keySet());
}
} else {
log(Level.WARNING, "Address is not going to be updated in network interface " + "state: [%s] deviceKey is null", nic.documentSelfLink);
}
}
}
return updateIpAddressOperations;
}
use of com.vmware.photon.controller.model.resources.ComputeService.ComputeState in project photon-model by vmware.
the class VSphereAdapterInstanceService method handleCreateInstance.
private void handleCreateInstance(ProvisionContext ctx) {
ctx.pool.submit(ctx.getAdapterManagementReference(), ctx.vSphereCredentials, (connection, ce) -> {
if (ctx.fail(ce)) {
return;
}
try {
InstanceClient client = new InstanceClient(connection, ctx);
ComputeState state;
if (ctx.templateMoRef != null) {
state = client.createInstanceFromTemplate(ctx.templateMoRef);
} else if (ctx.image != null) {
ManagedObjectReference moRef = CustomProperties.of(ctx.image).getMoRef(CustomProperties.MOREF);
if (moRef != null) {
// the image is backed by a template VM
state = client.createInstanceFromTemplate(moRef);
} else {
// library item
state = client.createInstanceFromLibraryItem(ctx.image);
}
} else if (ctx.snapshotMoRef != null) {
state = client.createInstanceFromSnapshot();
} else {
state = client.createInstance();
}
if (state == null) {
// assume they will patch the task if they have provisioned the vm
return;
}
// populate state, MAC address being very important
VmOverlay vmOverlay = client.enrichStateFromVm(state);
Operation[] finishTask = new Operation[1];
for (NetworkInterfaceStateWithDetails nic : ctx.nics) {
// request guest customization while vm of powered off
SubnetState subnet = nic.subnet;
if (subnet != null && nic.description != null && nic.description.assignment == IpAssignment.STATIC) {
CustomizationClient cc = new CustomizationClient(connection, ctx.child, vmOverlay.getGuestId());
CustomizationSpec template = new CustomizationSpec();
cc.customizeNic(vmOverlay.getPrimaryMac(), ctx.child.hostName, nic.address, subnet, template);
cc.customizeDns(subnet.dnsServerAddresses, subnet.dnsSearchDomains, template);
ManagedObjectReference task = cc.customizeGuest(client.getVm(), template);
TaskInfo taskInfo = VimUtils.waitTaskEnd(connection, task);
if (taskInfo.getState() == TaskInfoState.ERROR) {
VimUtils.rethrow(taskInfo.getError());
}
}
}
// power on machine before enrichment
if (ctx.child.powerState == PowerState.ON) {
new PowerStateClient(connection).changePowerState(client.getVm(), PowerState.ON, null, 0);
state.powerState = PowerState.ON;
Operation op = ctx.mgr.createTaskPatch(TaskStage.FINISHED);
Boolean awaitIp = CustomProperties.of(ctx.child).getBoolean(ComputeProperties.CUSTOM_PROP_COMPUTE_AWAIT_IP, true);
if (awaitIp) {
Runnable runnable = createCheckForIpTask(ctx.pool, op, client.getVm(), connection.createUnmanagedCopy(), ctx.child.documentSelfLink, ctx);
ctx.pool.schedule(runnable, IP_CHECK_INTERVAL_SECONDS, TimeUnit.SECONDS);
} else {
finishTask[0] = op;
}
} else {
// only finish the task without waiting for IP
finishTask[0] = ctx.mgr.createTaskPatch(TaskStage.FINISHED);
}
updateNicsAfterProvisionSuccess(vmOverlay.getNics(), ctx);
updateDiskLinksAfterProvisionSuccess(state, vmOverlay.getDisks(), ctx);
state.lifecycleState = LifecycleState.READY;
// Find the host link where the computed is provisioned and patch the
// compute state.
queryHostDocumentAndUpdateCompute(ctx, vmOverlay.getHost()).thenCompose(computeState -> {
ComputeState hostState = computeState.iterator().next();
CustomProperties.of(state).put(VC_UUID, CustomProperties.of(hostState).getString(VC_UUID)).put(DATACENTER_SELF_LINK, CustomProperties.of(hostState).getString(DATACENTER_SELF_LINK)).put(COMPUTE_HOST_LINK_PROP_NAME, hostState.documentSelfLink);
return createComputeResourcePatch(state, ctx.computeReference);
}).whenComplete((o, e) -> {
if (e != null) {
ctx.fail(e);
return;
}
if (finishTask.length > 0) {
finishTask[0].sendWith(this);
}
});
} catch (Exception e) {
ctx.fail(e);
}
});
}
Aggregations