You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@stratos.apache.org by imesh <gi...@git.apache.org> on 2014/11/09 19:47:07 UTC

[GitHub] stratos pull request: Apache cloudstack integration for Stratos

Github user imesh commented on a diff in the pull request:

    https://github.com/apache/stratos/pull/97#discussion_r20060533
  
    --- Diff: components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/CloudstackIaas.java ---
    @@ -0,0 +1,539 @@
    +package org.apache.stratos.cloud.controller.iaases;
    +
    +
    +import org.apache.commons.lang.StringUtils;
    +import org.apache.commons.logging.Log;
    +import org.apache.commons.logging.LogFactory;
    +import org.apache.stratos.cloud.controller.exception.CloudControllerException;
    +import org.apache.stratos.cloud.controller.exception.InvalidHostException;
    +import org.apache.stratos.cloud.controller.exception.InvalidRegionException;
    +import org.apache.stratos.cloud.controller.exception.InvalidZoneException;
    +import org.apache.stratos.cloud.controller.interfaces.Iaas;
    +import org.apache.stratos.cloud.controller.jcloud.ComputeServiceBuilderUtil;
    +import org.apache.stratos.cloud.controller.pojo.IaasProvider;
    +import org.apache.stratos.cloud.controller.util.CloudControllerConstants;
    +import org.apache.stratos.cloud.controller.validate.CloudstackPartitionValidator;
    +import org.apache.stratos.cloud.controller.validate.interfaces.PartitionValidator;
    +import org.jclouds.cloudstack.CloudStackApi;
    +import org.jclouds.cloudstack.compute.options.CloudStackTemplateOptions;
    +import org.jclouds.cloudstack.domain.*;
    +import org.jclouds.cloudstack.features.VolumeApi;
    +import org.jclouds.cloudstack.options.ListPublicIPAddressesOptions;
    +import org.jclouds.cloudstack.options.ListZonesOptions;
    +import org.jclouds.compute.ComputeServiceContext;
    +import org.jclouds.compute.domain.NodeMetadata;
    +import org.jclouds.compute.domain.Template;
    +import org.jclouds.compute.domain.TemplateBuilder;
    +import org.jclouds.compute.options.TemplateOptions;
    +import org.jclouds.domain.Location;
    +
    +import java.util.Arrays;
    +import java.util.HashMap;
    +import java.util.Map;
    +import java.util.Set;
    +import java.util.concurrent.TimeoutException;
    +
    +public class CloudstackIaas extends Iaas {
    +
    +    private static final Log log = LogFactory.getLog(CloudstackIaas.class);
    +
    +    public CloudstackIaas(IaasProvider iaasProvider) {
    +        super(iaasProvider);
    +    }
    +
    +    @Override
    +    public void buildComputeServiceAndTemplate() {
    +        // builds and sets Compute Service
    +        ComputeServiceBuilderUtil.buildDefaultComputeService(getIaasProvider());
    +        // builds and sets Template
    +        buildTemplate();
    +    }
    +
    +    @Override
    +    public void buildTemplate() {
    +
    +        IaasProvider iaasInfo = getIaasProvider();
    +
    +        //if compute service is not available
    +        if (iaasInfo.getComputeService() == null) {
    +            String msg = "Compute service is null for IaaS provider: "
    +                    + iaasInfo.getName();
    +            log.error(msg);
    +            throw new CloudControllerException(msg);
    +        }
    +
    +        //create templateBuilder
    +        TemplateBuilder templateBuilder = iaasInfo.getComputeService()
    +                .templateBuilder();
    +
    +        //**SET PROPERTIES TO templateBuilder OBJECT**//
    +
    +        /**
    +         * PROPERTY - 1
    +         * set image id specified
    +         */
    +        templateBuilder.imageId(iaasInfo.getImage());
    +
    +        /**
    +         *  PROPERTY-2
    +         *  if user has specified a zone in cloud-controller.xml, set the zone into templateBuilder object
    +         *  (user should provide the zone id for this, because zone name is not unique in cloudstack)
    +         */
    +        if (iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE) != null) {
    +            Set<? extends Location> locations = iaasInfo.getComputeService().listAssignableLocations();
    +            for (Location location : locations) {
    +                if (location.getId().equals(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE))) {
    +                    //if the zone is valid set the zone to templateBuilder Object
    +                    templateBuilder.locationId(location.getId());
    +                    log.info("Zone has been set as " + iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE)
    +                            + " with id: " + location.getId());
    +                    break;
    +                }
    +            }
    +        }
    +
    +        /**
    +         * PROPERTY-3
    +         * if user has specified an instance type in cloud-controller.xml, set the instance type into templateBuilder
    +         * object.(service offering)
    +         *Important:Specify the Service Offering type ID. Not the name. Because the name is not unique in cloudstack.
    +         */
    +        if (iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE) != null) {
    +            templateBuilder.hardwareId(iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE));
    +        }
    +
    +        //build the template
    +        Template template = templateBuilder.build();
    +
    +        /**if you wish to auto assign IPs, instance spawning call should be
    +         * blocking, but if you
    +         * wish to assign IPs manually, it can be non-blocking.
    +         * is auto-assign-ip mode or manual-assign-ip mode?
    +         */
    +        boolean blockUntilRunning = Boolean.parseBoolean(iaasInfo
    +                .getProperty(CloudControllerConstants.AUTO_ASSIGN_IP));
    +        template.getOptions().as(TemplateOptions.class)
    +                .blockUntilRunning(blockUntilRunning);
    +
    +        // this is required in order to avoid creation of additional security
    +        // groups by Jclouds.
    +        template.getOptions().as(TemplateOptions.class)
    +                .inboundPorts(new int[]{});
    +
    +
    +        //**SET CLOUDSTACK SPECIFIC PROPERTIES TO TEMPLATE OBJECT**//
    +
    +        //set security group - If you are using basic zone
    +        if (iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS) != null) {
    +            template.getOptions()
    +                    .as(CloudStackTemplateOptions.class)
    +                    .securityGroupIds(Arrays.asList(iaasInfo.getProperty(CloudControllerConstants.SECURITY_GROUP_IDS)
    +                            .split(CloudControllerConstants.ENTRY_SEPARATOR)));
    +        }
    +
    +
    +        /**
    +         * set network ID - If you are using advanced zone
    +         * in cloudstack sometimes we get unautorized exception if we didn't specify the
    +         * domain ID and user name
    +         */
    +        if (iaasInfo.getProperty(CloudControllerConstants.NETWORK_IDS) != null) {
    +            template.getOptions()
    +                    .as(CloudStackTemplateOptions.class)
    +                    .networks(Arrays.asList(iaasInfo.getProperty(CloudControllerConstants.NETWORK_IDS)
    +                            .split(CloudControllerConstants.ENTRY_SEPARATOR)));
    +        }
    +
    +        //set user name
    +        if (iaasInfo.getProperty(CloudControllerConstants.USER_NAME) != null) {
    +            template.getOptions().as(CloudStackTemplateOptions.class)
    +                    .account(iaasInfo.getProperty(CloudControllerConstants.USER_NAME));
    +        }
    +        //set domain ID
    +        if (iaasInfo.getProperty(CloudControllerConstants.DOMAIN_ID) != null) {
    +            template.getOptions().as(CloudStackTemplateOptions.class)
    +                    .domainId(iaasInfo.getProperty(CloudControllerConstants.DOMAIN_ID));
    +        }
    +
    +        /**
    +         *Set key pair
    +         * in cloudstack sometimes we get unauthorized exception if we didn't specify the
    +         * domain ID and user name
    +         */
    +        if (iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR) != null) {
    +            template.getOptions().as(CloudStackTemplateOptions.class)
    +                    .keyPair(iaasInfo.getProperty(CloudControllerConstants.KEY_PAIR));
    +        }
    +
    +        // ability to define tags
    +        if (iaasInfo.getProperty(CloudControllerConstants.TAGS) != null) {
    +            template.getOptions()
    +                    .as(CloudStackTemplateOptions.class)
    +                    .tags(Arrays.asList(iaasInfo.getProperty(CloudControllerConstants.TAGS)
    +                            .split(CloudControllerConstants.ENTRY_SEPARATOR)));
    +        }
    +        //set disk offering to the instance
    +        if (iaasInfo.getProperty(CloudControllerConstants.DISK_OFFERING) != null) {
    +            template.getOptions()
    +                    .as(CloudStackTemplateOptions.class)
    +                    .diskOfferingId(iaasInfo.getProperty(CloudControllerConstants.DISK_OFFERING));
    +        }
    +
    +        // set Template
    +        iaasInfo.setTemplate(template);
    +    }
    +
    +    @Override
    +    public void setDynamicPayload() {
    +        IaasProvider iaasInfo = getIaasProvider();
    +        if (iaasInfo.getTemplate() != null && iaasInfo.getPayload() != null) {
    +            iaasInfo.getTemplate().getOptions().as(CloudStackTemplateOptions.class)
    +                    .userMetadata(convertByteArrayToHashMap(iaasInfo.getPayload()));
    +        }
    +    }
    +
    +    /**
    +     * IMPORTANT
    +     * In cloudstack we can assign public IPs, if we are using an advanced zone only. If we are using a basic zone
    +     * we cannot assign public ips.
    +     * <p/>
    +     * When we use an advanced zone, a public IP address will get automatically assigned to the vm. So we don't need
    +     * to find an unallocated IP address and assign that address to the vm (Not like in ec2 and openstack).
    +     * <p/>
    +     * So  this method will find the IP that has been assigned to the vm and return it.
    +     */
    +    @Override
    +    public String associateAddress(NodeMetadata node) {
    +
    +        IaasProvider iaasInfo = getIaasProvider();
    +        ComputeServiceContext context = iaasInfo.getComputeService().getContext();
    +        CloudStackApi cloudStackApi = context.unwrapApi(CloudStackApi.class);
    +        String ip = null;
    +
    +        // get all allocated IPs
    +        ListPublicIPAddressesOptions listPublicIPAddressesOptions = new ListPublicIPAddressesOptions();
    +        listPublicIPAddressesOptions.zoneId(iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE));
    +
    +        Set<PublicIPAddress> publicIPAddresses = cloudStackApi.getAddressApi()
    +                .listPublicIPAddresses(listPublicIPAddressesOptions);
    +
    +        String id = node.getProviderId(); //vm ID
    +
    +        for (PublicIPAddress publicIPAddress : publicIPAddresses) {
    +            if (publicIPAddress.getVirtualMachineId().equals(id)) { //check whether this instance has
    +                // already got an public ip or not
    +                ip = publicIPAddress.getIPAddress(); //A public ip has been successfully assigned to the vm
    +                log.debug("Successfully associated an IP address " + ip
    +                        + " for node with id: " + node.getId());
    +                break;
    +            }
    +
    +        }
    +
    +        if (ip == null || ip.isEmpty()) { //IP has not been successfully assigned to VM(That means there are
    +            //  no more IPs  available for the VM)
    +            String msg = "No address associated for node with id: " + node.getId();
    +            log.debug(msg);
    --- End diff --
    
    May be we could make this a warning. Asanka can you please update?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---