Search in sources :

Example 1 with Stack

use of com.woorea.openstack.heat.model.Stack in project so by onap.

the class MsoHeatUtils method pollStackForStatus.

public Stack pollStackForStatus(int timeoutMinutes, Stack stack, String stackStatus, String cloudSiteId, String tenantId, boolean notFoundIsSuccess) throws MsoException {
    int pollingFrequency = Integer.parseInt(this.environment.getProperty(createPollIntervalProp, CREATE_POLL_INTERVAL_DEFAULT));
    LocalDateTime stopPolling = LocalDateTime.now().plusMinutes(timeoutMinutes);
    if (pollingFrequency > timeoutMinutes * 60) {
        logger.debug("Will not poll. Poll interval {} sec is greater then timeout {} sec", pollingFrequency, timeoutMinutes * 60);
        stopPolling = LocalDateTime.now().minusMinutes(1);
    }
    Heat heatClient = getHeatClient(cloudSiteId, tenantId);
    while (true) {
        String stackName = stack.getStackName() + "/" + stack.getId();
        if (stack.getId() == null) {
            stackName = stack.getStackName();
        }
        Stack latestStack = queryHeatStack(heatClient, stackName);
        if (latestStack == null && notFoundIsSuccess) {
            return null;
        } else if (latestStack != null) {
            String requestId = MDC.get(ONAPLogConstants.MDCs.REQUEST_ID);
            statusHandler.updateStackStatus(latestStack, requestId);
            if (stackStatus.equals(latestStack.getStackStatus())) {
                if (LocalDateTime.now().isAfter(stopPolling)) {
                    logger.error("Polling of stack timed out with Status: {}", latestStack.getStackStatus());
                    return latestStack;
                }
                logger.debug("Will poll again until {}", stopPolling);
                sleep(pollingFrequency * 1000L);
            } else {
                return latestStack;
            }
        }
    }
}
Also used : LocalDateTime(java.time.LocalDateTime) Heat(com.woorea.openstack.heat.Heat) Stack(com.woorea.openstack.heat.model.Stack)

Example 2 with Stack

use of com.woorea.openstack.heat.model.Stack in project so by onap.

the class MsoHeatUtils method createStack.

/**
 * Create a new Stack in the specified cloud location and tenant. The Heat template and parameter map are passed in
 * as arguments, along with the cloud access credentials. It is expected that parameters have been validated and
 * contain at minimum the required parameters for the given template with no extra (undefined) parameters..
 *
 * The Stack name supplied by the caller must be unique in the scope of this tenant. However, it should also be
 * globally unique, as it will be the identifier for the resource going forward in Inventory. This latter is managed
 * by the higher levels invoking this function.
 *
 * The caller may choose to let this function poll Openstack for completion of the stack creation, or may handle
 * polling itself via separate calls to query the status. In either case, a StackInfo object will be returned
 * containing the current status. When polling is enabled, a status of CREATED is expected. When not polling, a
 * status of BUILDING is expected.
 *
 * An error will be thrown if the requested Stack already exists in the specified Tenant and Cloud.
 *
 * For 1510 - add "environment", "files" (nested templates), and "heatFiles" (get_files) as parameters for
 * createStack. If environment is non-null, it will be added to the stack. The nested templates and get_file entries
 * both end up being added to the "files" on the stack. We must combine them before we add them to the stack if
 * they're both non-null.
 *
 * @param cloudSiteId The cloud (may be a region) in which to create the stack.
 * @param cloudOwner the cloud owner of the cloud site in which to create the stack
 * @param tenantId The Openstack ID of the tenant in which to create the Stack
 * @param stackName The name of the stack to create
 * @param vduModel contains information about the vdu model (added for plugin adapter)
 * @param heatTemplate The Heat template
 * @param stackInputs A map of key/value inputs
 * @param pollForCompletion Indicator that polling should be handled in Java vs. in the client
 * @param environment An optional yaml-format string to specify environmental parameters
 * @param files a Map<String, Object> that lists the child template IDs (file is the string, object is an int of
 *        Template id)
 * @param heatFiles a Map<String, Object> that lists the get_file entries (fileName, fileBody)
 * @param backout Donot delete stack on create Failure - defaulted to True
 * @return A StackInfo object
 * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception.
 */
public StackInfo createStack(String cloudSiteId, String cloudOwner, String tenantId, String stackName, VduModelInfo vduModel, String heatTemplate, Map<String, ?> stackInputs, boolean pollForCompletion, int timeoutMinutes, String environment, Map<String, Object> nestedTemplates, Map<String, Object> heatFiles, boolean backout, boolean failIfExists) throws MsoException {
    stripMultiCloudInputs(stackInputs);
    CreateStackParam createStack = createStackParam(stackName, heatTemplate, stackInputs, timeoutMinutes, environment, nestedTemplates, heatFiles);
    Stack currentStack = queryHeatStack(stackName, cloudSiteId, tenantId);
    boolean operationPerformed = false;
    if (currentStack != null) {
        logger.debug("Existing Stack found with Status: {} ", currentStack.getStackStatus());
        if (CREATE_COMPLETE.equals(currentStack.getStackStatus())) {
            new StackInfoMapper(currentStack).map();
        } else if (CREATE_IN_PROGRESS.equals(currentStack.getStackStatus())) {
            // TODO should check poll for completion right here
            currentStack = processCreateStack(cloudSiteId, tenantId, timeoutMinutes, backout, currentStack, createStack, true);
        } else if (CREATE_FAILED.equals(currentStack.getStackStatus()) || DELETE_FAILED.equals(currentStack.getStackStatus())) {
            try {
                if (pollForCompletion) {
                    processCreateStack(cloudSiteId, tenantId, timeoutMinutes, backout, currentStack, createStack, true);
                }
            } catch (MsoException e) {
                if (e instanceof StackCreationException) {
                    logger.warn("Error during Stack will attempt to recreate stack");
                    currentStack = createStack(createStack, cloudSiteId, tenantId);
                    currentStack.setStackName(stackName);
                    if (pollForCompletion) {
                        currentStack = processCreateStack(cloudSiteId, tenantId, timeoutMinutes, backout, currentStack, createStack, true);
                    }
                } else {
                    throw e;
                }
            }
        }
    } else {
        currentStack = createStack(createStack, cloudSiteId, tenantId);
        currentStack.setStackName(stackName);
        if (pollForCompletion) {
            currentStack = processCreateStack(cloudSiteId, tenantId, timeoutMinutes, backout, currentStack, createStack, true);
        }
        operationPerformed = true;
    }
    StackInfo stackInfo = new StackInfoMapper(currentStack).map();
    stackInfo.setOperationPerformed(operationPerformed);
    return stackInfo;
}
Also used : StackInfoMapper(org.onap.so.openstack.mappers.StackInfoMapper) MsoException(org.onap.so.openstack.exceptions.MsoException) CreateStackParam(com.woorea.openstack.heat.model.CreateStackParam) StackInfo(org.onap.so.openstack.beans.StackInfo) Stack(com.woorea.openstack.heat.model.Stack)

Example 3 with Stack

use of com.woorea.openstack.heat.model.Stack in project so by onap.

the class MsoHeatUtils method deleteStack.

private Stack deleteStack(Stack stack, int timeoutMinutes, String cloudSiteId, String tenantId, boolean pollForCompletion) throws MsoException {
    OpenStackRequest<Void> request = getHeatClient(cloudSiteId, tenantId).getStacks().deleteByName(stack.getStackName() + "/" + stack.getId());
    executeAndRecordOpenstackRequest(request);
    logger.debug("Completed Executing executeAndRecordOpenstackRequest");
    if (pollForCompletion == true) {
        Stack currentStack = pollStackForStatus(timeoutMinutes, stack, DELETE_IN_PROGRESS, cloudSiteId, tenantId, true);
        if (currentStack == null) {
            return currentStack;
        }
        postProcessStackDelete(currentStack);
        return currentStack;
    } else {
        logger.debug("Returning the stack");
        return stack;
    }
}
Also used : Stack(com.woorea.openstack.heat.model.Stack)

Example 4 with Stack

use of com.woorea.openstack.heat.model.Stack in project so by onap.

the class MsoHeatUtils method handleKeyPairConflict.

protected Stack handleKeyPairConflict(String cloudSiteId, String tenantId, CreateStackParam stackCreate, int timeoutMinutes, boolean backout, Stack stack) throws MsoException {
    logger.info("Keypair conflict found on stack, attempting to clean up");
    try {
        Matcher m = Pattern.compile("'([^']+?)'").matcher(stack.getStackStatusReason());
        if (m.find()) {
            novaClient.deleteKeyPair(cloudSiteId, tenantId, m.group(1));
        }
    } catch (NovaClientException e) {
        logger.warn("Could not delete keypair", e);
    }
    handleUnknownCreateStackFailure(stack, timeoutMinutes, cloudSiteId, tenantId);
    Stack newStack = createStack(stackCreate, cloudSiteId, tenantId);
    newStack.setStackName(stackCreate.getStackName());
    return processCreateStack(cloudSiteId, tenantId, timeoutMinutes, backout, newStack, stackCreate, false);
}
Also used : Matcher(java.util.regex.Matcher) Stack(com.woorea.openstack.heat.model.Stack)

Example 5 with Stack

use of com.woorea.openstack.heat.model.Stack in project so by onap.

the class MsoMulticloudUtils method queryStack.

/**
 * Query for a single stack (by ID) in a tenant. This call will always return a StackInfo object. If the stack does
 * not exist, an "empty" StackInfo will be returned - containing only the stack name and a status of NOTFOUND.
 *
 * @param tenantId The Openstack ID of the tenant in which to query
 * @param cloudSiteId The cloud identifier (may be a region) in which to query
 * @param cloudOwner cloud owner of the cloud site in which to query
 * @param stackId The ID of the stack to query
 * @return A StackInfo object
 * @throws MsoOpenstackException Thrown if the Openstack API call returns an exception.
 */
@Override
public StackInfo queryStack(String cloudSiteId, String cloudOwner, String tenantId, String instanceId) throws MsoException {
    if (logger.isDebugEnabled()) {
        logger.debug(String.format("Query multicloud HEAT stack: %s in tenant %s", instanceId, tenantId));
    }
    String stackName = null;
    String stackId = null;
    boolean byName = false;
    int offset = instanceId.indexOf('/');
    if (offset > 0 && offset < (instanceId.length() - 1)) {
        stackName = instanceId.substring(0, offset);
        stackId = instanceId.substring(offset + 1);
    } else {
        stackName = instanceId;
        stackId = instanceId;
        byName = true;
    }
    StackInfo returnInfo = new StackInfo();
    returnInfo.setName(stackName);
    String multicloudEndpoint = getMulticloudEndpoint(cloudSiteId, cloudOwner, stackId, byName);
    RestClient multicloudClient = getMulticloudClient(multicloudEndpoint, tenantId);
    if (multicloudClient != null) {
        Response response = multicloudClient.get();
        if (logger.isDebugEnabled()) {
            logger.debug(String.format("Multicloud GET Response: %s", response.toString()));
        }
        MulticloudQueryResponse responseBody = null;
        if (response.getStatus() == Response.Status.NOT_FOUND.getStatusCode()) {
            returnInfo.setStatus(HeatStatus.NOTFOUND);
            returnInfo.setStatusMessage(response.getStatusInfo().getReasonPhrase());
        } else if (response.getStatus() == Response.Status.OK.getStatusCode() && response.hasEntity()) {
            responseBody = getQueryBody((java.io.InputStream) response.getEntity());
            if (responseBody != null) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Multicloud Create Response Body: {}", responseBody);
                }
                Stack workloadStack = getWorkloadStack(responseBody.getWorkloadStatusReason());
                if (workloadStack != null && !responseBody.getWorkloadStatus().equals("GET_FAILED") && !responseBody.getWorkloadStatus().contains("UPDATE")) {
                    returnInfo = new StackInfoMapper(workloadStack).map();
                } else {
                    returnInfo.setCanonicalName(stackName + "/" + responseBody.getWorkloadId());
                    returnInfo.setStatus(getHeatStatus(responseBody.getWorkloadStatus()));
                    returnInfo.setStatusMessage(responseBody.getWorkloadStatus());
                }
            } else {
                returnInfo.setName(stackName);
                if (!byName)
                    returnInfo.setCanonicalName(instanceId);
                returnInfo.setStatus(HeatStatus.FAILED);
                returnInfo.setStatusMessage(MULTICLOUD_QUERY_BODY_NULL);
            }
        } else {
            returnInfo.setName(stackName);
            if (!byName)
                returnInfo.setCanonicalName(instanceId);
            returnInfo.setStatus(HeatStatus.FAILED);
            returnInfo.setStatusMessage(response.getStatusInfo().getReasonPhrase());
        }
    }
    return returnInfo;
}
Also used : Response(javax.ws.rs.core.Response) StackInfoMapper(org.onap.so.openstack.mappers.StackInfoMapper) RestClient(org.onap.so.client.RestClient) StackInfo(org.onap.so.openstack.beans.StackInfo) Stack(com.woorea.openstack.heat.model.Stack)

Aggregations

Stack (com.woorea.openstack.heat.model.Stack)41 Test (org.junit.Test)26 CreateStack (com.woorea.openstack.heat.StackResource.CreateStack)15 DeleteStack (com.woorea.openstack.heat.StackResource.DeleteStack)15 CreateStackParam (com.woorea.openstack.heat.model.CreateStackParam)10 Heat (com.woorea.openstack.heat.Heat)9 StackInfo (org.onap.so.openstack.beans.StackInfo)9 StackInfoMapper (org.onap.so.openstack.mappers.StackInfoMapper)7 MsoException (org.onap.so.openstack.exceptions.MsoException)5 OpenStackRequest (com.woorea.openstack.base.client.OpenStackRequest)3 File (java.io.File)3 HashMap (java.util.HashMap)3 CloudSite (org.onap.so.db.catalog.beans.CloudSite)3 MsoOpenstackException (org.onap.so.openstack.exceptions.MsoOpenstackException)3 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2 RequestProcessingData (org.onap.so.db.request.beans.RequestProcessingData)2 TypeReference (com.fasterxml.jackson.core.type.TypeReference)1 OpenStackBaseException (com.woorea.openstack.base.client.OpenStackBaseException)1 OpenStackConnectException (com.woorea.openstack.base.client.OpenStackConnectException)1 OpenStackResponseException (com.woorea.openstack.base.client.OpenStackResponseException)1