Package io.fathom.cloud.install

Source Code of io.fathom.cloud.install.InstanceBootstrapCmdlet

package io.fathom.cloud.install;

import io.fathom.cloud.CloudException;
import io.fathom.cloud.commands.TypedCmdlet;
import io.fathom.cloud.compute.actions.StartInstancesAction;
import io.fathom.cloud.compute.services.DerivedMetadata;
import io.fathom.cloud.compute.services.SecurityGroups;
import io.fathom.cloud.compute.services.SshKeyPairs;
import io.fathom.cloud.protobuf.CloudModel.InstanceData;
import io.fathom.cloud.protobuf.CloudModel.KeyPairData;
import io.fathom.cloud.protobuf.CloudModel.MetadataData;
import io.fathom.cloud.protobuf.CloudModel.MetadataEntryData;
import io.fathom.cloud.protobuf.CloudModel.ReservationData;
import io.fathom.cloud.protobuf.CloudModel.SecurityGroupData;
import io.fathom.cloud.protobuf.CloudModel.SecurityGroupRuleData;
import io.fathom.cloud.server.auth.Auth;
import io.fathom.cloud.server.model.Project;
import io.fathom.cloud.services.AuthService;
import io.fathom.cloud.services.ImageImports;
import io.fathom.cloud.services.ImageService;
import io.fathom.cloud.services.ImageService.Image;
import io.fathom.cloud.ssh.SshContext;

import java.io.IOException;
import java.security.PublicKey;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Provider;

import org.kohsuke.args4j.Option;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;

public class InstanceBootstrapCmdlet extends TypedCmdlet {

    private static final Logger log = LoggerFactory.getLogger(InstanceBootstrapCmdlet.class);

    @Option(name = "-u", usage = "username", required = true)
    public String username;

    @Option(name = "-p", usage = "password", required = true)
    public String password;

    @Option(name = "-url", usage = "image url", required = true)
    public String imageUrl;

    // @Option(name = "-ip", usage = "ip", required = true)
    // public String ip;

    @Option(name = "-name", usage = "name", required = true)
    public String name;

    @Option(name = "-host", usage = "host")
    public String host;

    public InstanceBootstrapCmdlet() {
        super("compute-instance-bootstrap");
    }

    @Inject
    Provider<StartInstancesAction> startInstancesActionProvider;

    @Inject
    AuthService authService;

    @Inject
    SshKeyPairs keypairs;

    @Inject
    SecurityGroups securityGroups;

    @Inject
    ImageService imageService;

    @Inject
    ImageImports imageImports;

    @Inject
    SshContext sshContext;

    private Auth auth;
    private Project project;

    @Override
    protected InstanceData run0() throws Exception {
        authenticate();

        KeyPairData keyPair = buildKeypair();

        List<Long> securityGroupIds = buildSecurityGroups();

        Image image = buildImage();

        return startInstance(image, securityGroupIds, keyPair);
    }

    private void authenticate() throws CloudException {
        auth = authService.authenticate(null, username, password);
        if (auth == null) {
            throw new IllegalStateException();
        }
        log.info("Authenticated as: {}", username);

        String projectName = "__system__";
        List<Long> projectIds = authService.resolveProjectName(auth, projectName);
        Long projectId;
        if (projectIds.isEmpty()) {
            log.info("Creating project: {}", projectName);
            projectId = authService.createProject(auth, projectName);
        } else {
            if (projectIds.size() != 1) {
                throw new IllegalStateException("Found multiple projects with name: " + projectName);
            }
            projectId = projectIds.get(0);
            log.info("Found project: {}", projectName);
        }

        auth = authService.authenticate(projectId, username, password);
        if (auth == null) {
            throw new IllegalStateException("Error authenticating to project");
        }
        log.info("Authenticated to project");

        project = auth.getProject();
    }

    private KeyPairData buildKeypair() throws CloudException, IOException {
        PublicKey sshPublicKey = sshContext.getPublicKey();

        String keypairName = "__system__";
        KeyPairData keyPair = keypairs.findKeyPair(project, keypairName);
        if (keyPair == null) {
            log.info("Creating keypair: {}", keypairName);
            keypairs.create(project, keypairName, sshPublicKey);
        } else {
            log.info("Found keypair: {}", keypairName);
        }
        return keyPair;
    }

    private List<Long> buildSecurityGroups() throws CloudException {
        List<Long> securityGroupIds = Lists.newArrayList();

        String securityGroupName = "__system__";
        SecurityGroupData securityGroup = securityGroups.find(project, securityGroupName);
        if (securityGroup == null) {
            log.info("Creating security group: {}", securityGroupName);

            SecurityGroupData.Builder b = SecurityGroupData.newBuilder();
            b.setName(securityGroupName);
            b.setProjectId(project.getId());
            securityGroup = securityGroups.create(project, b);
        } else {
            log.info("Found security group: {}", securityGroupName);
        }

        if (securityGroup.getRulesCount() == 0) {
            SecurityGroupRuleData.Builder sgb = SecurityGroupRuleData.newBuilder();
            sgb.setFromSecurityGroup(securityGroup.getId());
            securityGroups.addRule(auth, project, securityGroup.getId(), sgb);
        }

        securityGroupIds.add(securityGroup.getId());
        return securityGroupIds;
    }

    private Image buildImage() throws Exception, CloudException {
        ImageImports.Metadata metadata = imageImports.getImageMetadata(imageUrl);

        List<Image> images = imageService.listImages(project);
        Image image = null;
        for (Image i : images) {
            String imageChecksum = i.getChecksum();
            if (imageChecksum.equalsIgnoreCase(metadata.getChecksum())) {
                image = i;
                break;
            }
        }

        if (image == null) {
            log.info("Importing image from: {}", imageUrl);
            image = imageImports.importImage(project.getId(), imageUrl);
        } else {
            log.info("Found image: {}", image.getName());
        }
        return image;
    }

    private InstanceData startInstance(Image image, List<Long> securityGroupIds, KeyPairData keyPair)
            throws CloudException {
        StartInstancesAction action = startInstancesActionProvider.get();

        action.project = project;
        action.auth = auth;

        action.minCount = 1;
        action.maxCount = 1;

        {
            ReservationData.Builder reservation = ReservationData.newBuilder();

            reservation.setImageId(image.getId());

            action.reservationTemplate = reservation.build();
        }

        {
            InstanceData.Builder instance = InstanceData.newBuilder();
            instance.setName(name);

            if (keyPair != null) {
                instance.setKeyPair(keyPair);
            }

            {
                MetadataData.Builder metadataBuilder = instance.getMetadataBuilder();

                if (host != null) {
                    MetadataEntryData.Builder entryBuilder = metadataBuilder.addEntryBuilder();
                    entryBuilder.setKey(DerivedMetadata.KEY_DNS_HOST);
                    entryBuilder.setValue(host);
                }
            }

            instance.setImageId(image.getId());

            for (Long securityGroupId : securityGroupIds) {
                instance.addSecurityGroupId(securityGroupId);
            }

            action.instanceTemplate = instance.build();
        }

        // action.ip = this.ip;

        log.info("Starting instance");

        StartInstancesAction.Result result = action.go();

        if (result.instances.size() != 1) {
            throw new IllegalStateException();
        }

        return result.instances.get(0);
    }

}
TOP

Related Classes of io.fathom.cloud.install.InstanceBootstrapCmdlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.