@Override public List<CloudVmInstanceStatus> check(AuthenticatedContext ac, List<CloudInstance> vms) { List<CloudVmInstanceStatus> statuses = new ArrayList<>(); AzureRMClient azureRMClient = armClient.getClient(ac.getCloudCredential()); String stackName = armTemplateUtils.getStackName(ac.getCloudContext()); for (CloudInstance vm : vms) { try { Map<String, Object> virtualMachine = azureRMClient.getVirtualMachineInstanceView(stackName, vm.getInstanceId()); List<Map<String, Object>> vmStatuses = (List) virtualMachine.get("statuses"); for (Map<String, Object> vmStatuse : vmStatuses) { String statusCode = vmStatuse.get("code").toString(); if (statusCode.startsWith("PowerState")) { statusCode = statusCode.replace("PowerState/", ""); statuses.add(new CloudVmInstanceStatus(vm, ArmInstanceStatus.get(statusCode))); break; } } } catch (Exception e) { statuses.add(new CloudVmInstanceStatus(vm, InstanceStatus.TERMINATED)); } } return statuses; }
@SuppressWarnings("unchecked") @Override public List<CloudResourceStatus> launch( AuthenticatedContext authenticatedContext, CloudStack stack, PersistenceNotifier notifier, AdjustmentType adjustmentType, Long threshold) { String stackName = authenticatedContext.getCloudContext().getName(); boolean existingNetwork = isExistingNetwork(stack); boolean assignFloatingIp = assignFloatingIp(stack); String existingSubnetCidr = getExistingSubnetCidr(authenticatedContext, stack); String heatTemplate = heatTemplateBuilder.build( stackName, stack.getGroups(), stack.getSecurity(), stack.getImage(), existingNetwork, existingSubnetCidr != null, assignFloatingIp); Map<String, String> parameters = heatTemplateBuilder.buildParameters( authenticatedContext, stack.getNetwork(), stack.getImage(), existingNetwork, existingSubnetCidr); OSClient client = openStackClient.createOSClient(authenticatedContext); Stack heatStack = client .heat() .stacks() .create( Builders.stack() .name(stackName) .template(heatTemplate) .disableRollback(false) .parameters(parameters) .timeoutMins(OPERATION_TIMEOUT) .build()); CloudResource cloudResource = new CloudResource.Builder().type(ResourceType.HEAT_STACK).name(heatStack.getId()).build(); try { notifier.notifyAllocation(cloudResource, authenticatedContext.getCloudContext()); } catch (Exception e) { // Rollback terminate(authenticatedContext, stack, Lists.newArrayList(cloudResource)); } List<CloudResourceStatus> resources = check(authenticatedContext, Lists.newArrayList(cloudResource)); LOGGER.debug("Launched resources: {}", resources); return resources; }
@Override public List<CloudResourceStatus> update( AuthenticatedContext authenticatedContext, CloudStack stack, List<CloudResource> resources) { String stackName = authenticatedContext.getCloudContext().getName(); boolean existingNetwork = isExistingNetwork(stack); boolean assignFloatingIp = assignFloatingIp(stack); String existingSubnetCidr = getExistingSubnetCidr(authenticatedContext, stack); String heatTemplate = heatTemplateBuilder.build( stackName, stack.getGroups(), stack.getSecurity(), stack.getImage(), existingNetwork, existingSubnetCidr != null, assignFloatingIp); Map<String, String> parameters = heatTemplateBuilder.buildParameters( authenticatedContext, stack.getNetwork(), stack.getImage(), existingNetwork, existingSubnetCidr); return updateHeatStack(authenticatedContext, resources, heatTemplate, parameters); }
@Override public List<CloudVmInstanceStatus> stop( AuthenticatedContext ac, List<CloudResource> resources, List<CloudInstance> vms) { AzureRMClient azureRMClient = armClient.getClient(ac.getCloudCredential()); String stackName = armTemplateUtils.getStackName(ac.getCloudContext()); List<CloudVmInstanceStatus> statuses = new ArrayList<>(); for (CloudInstance vm : vms) { try { azureRMClient.stopVirtualMachine(stackName, vm.getInstanceId()); statuses.add(new CloudVmInstanceStatus(vm, InstanceStatus.IN_PROGRESS)); } catch (HttpResponseException e) { statuses.add( new CloudVmInstanceStatus( vm, InstanceStatus.FAILED, e.getResponse().getData().toString())); } catch (Exception e) { statuses.add(new CloudVmInstanceStatus(vm, InstanceStatus.FAILED, e.getMessage())); } } return statuses; }
private void doRollbackAndDecreaseNodeCount( AuthenticatedContext auth, List<CloudResourceStatus> statuses, Set<Long> ids, Group group, ResourceBuilderContext ctx, ResourceBuilders resourceBuilders, Boolean upscale) { List<ComputeResourceBuilder> compute = resourceBuilders.compute(auth.getCloudContext().getPlatform()); List<Future<ResourceRequestResult<List<CloudResourceStatus>>>> futures = new ArrayList<>(); LOGGER.info( String.format( "InstanceGroup %s node count decreased with one so the new node size is: %s", group.getName(), group.getInstances().size())); if (getRemovableInstanceTemplates(group, ids).size() <= 0 && !upscale) { LOGGER.info("InstanceGroup node count lower than 1 which is incorrect so error will throw"); throwError(statuses); } else { for (int i = compute.size() - 1; i >= 0; i--) { for (CloudResourceStatus cloudResourceStatus : statuses) { try { if (compute .get(i) .resourceType() .equals(cloudResourceStatus.getCloudResource().getType())) { ResourceDeleteThread thread = createThread( ResourceDeleteThread.NAME, ctx, auth, cloudResourceStatus.getCloudResource(), compute.get(i), false); Future<ResourceRequestResult<List<CloudResourceStatus>>> future = resourceBuilderExecutor.submit(thread); futures.add(future); for (Future<ResourceRequestResult<List<CloudResourceStatus>>> future1 : futures) { future1.get(); } futures.clear(); } } catch (Exception e) { LOGGER.info("Resource can not be deleted. Reason: {} ", e.getMessage()); } } } } }
private void doRollback( AuthenticatedContext auth, List<CloudResourceStatus> failuresList, Group group, Integer fullNodeCount, ResourceBuilderContext ctx, ResourceBuilders resourceBuilders, ScaleContext stx) { CloudContext localStack = auth.getCloudContext(); Set<Long> failures = failureCount(failuresList); if (stx.getAdjustmentType() == null && failures.size() > 0) { LOGGER.info("Failure policy is null so error will throw"); throwError(failuresList); } switch (stx.getAdjustmentType()) { case EXACT: if (stx.getThreshold() > fullNodeCount - failures.size()) { LOGGER.info("Number of failures is more than the threshold so error will throw"); throwError(failuresList); } else if (failures.size() != 0) { LOGGER.info("Decrease node counts because threshold was higher"); handleExceptions( auth, failuresList, group, ctx, resourceBuilders, failures, stx.getUpscale()); } break; case PERCENTAGE: if (Double.valueOf(stx.getThreshold()) > calculatePercentage(failures.size(), fullNodeCount)) { LOGGER.info("Number of failures is more than the threshold so error will throw"); throwError(failuresList); } else if (failures.size() != 0) { LOGGER.info("Decrease node counts because threshold was higher"); handleExceptions( auth, failuresList, group, ctx, resourceBuilders, failures, stx.getUpscale()); } break; case BEST_EFFORT: LOGGER.info("Decrease node counts because threshold was higher"); handleExceptions( auth, failuresList, group, ctx, resourceBuilders, failures, stx.getUpscale()); break; default: LOGGER.info("Unsupported adjustment type so error will throw"); throwError(failuresList); break; } }
private List<CloudResourceStatus> updateHeatStack( AuthenticatedContext authenticatedContext, List<CloudResource> resources, String heatTemplate, Map<String, String> parameters) { CloudResource resource = utils.getHeatResource(resources); String stackName = authenticatedContext.getCloudContext().getName(); String heatStackId = resource.getName(); OSClient client = openStackClient.createOSClient(authenticatedContext); StackUpdate updateRequest = Builders.stackUpdate() .template(heatTemplate) .parameters(parameters) .timeoutMins(OPERATION_TIMEOUT) .build(); client.heat().stacks().update(stackName, heatStackId, updateRequest); LOGGER.info( "Heat stack update request sent with stack name: '{}' for Heat stack: '{}'", stackName, heatStackId); return check(authenticatedContext, resources); }
@Override public List<CloudResourceStatus> terminate( AuthenticatedContext authenticatedContext, CloudStack cloudStack, List<CloudResource> resources) { for (CloudResource resource : resources) { switch (resource.getType()) { case HEAT_STACK: String heatStackId = resource.getName(); String stackName = authenticatedContext.getCloudContext().getName(); LOGGER.info("Terminate stack: {}", stackName); OSClient client = openStackClient.createOSClient(authenticatedContext); client.heat().stacks().delete(stackName, heatStackId); break; default: throw new CloudConnectorException( String.format("Invalid resource type: %s", resource.getType())); } } return check(authenticatedContext, resources); }
@Override public List<CloudResourceStatus> check( AuthenticatedContext authenticatedContext, List<CloudResource> resources) { List<CloudResourceStatus> result = new ArrayList<>(); OSClient client = openStackClient.createOSClient(authenticatedContext); for (CloudResource resource : resources) { switch (resource.getType()) { case HEAT_STACK: String heatStackId = resource.getName(); String stackName = authenticatedContext.getCloudContext().getName(); LOGGER.info("Checking OpenStack Heat stack status of: {}", stackName); Stack heatStack = client.heat().stacks().getDetails(stackName, heatStackId); CloudResourceStatus heatResourceStatus = utils.heatStatus(resource, heatStack); result.add(heatResourceStatus); break; default: throw new CloudConnectorException( String.format("Invalid resource type: %s", resource.getType())); } } return result; }