github.com/jcarley/cli@v0.0.0-20180201210820-966d90434c30/commands/init/init.go (about)

     1  package init
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"strconv"
     8  
     9  	"golang.org/x/crypto/ssh"
    10  
    11  	"github.com/Sirupsen/logrus"
    12  	"github.com/daticahealth/cli/commands/deploykeys"
    13  	"github.com/daticahealth/cli/commands/environments"
    14  	"github.com/daticahealth/cli/commands/git"
    15  	"github.com/daticahealth/cli/commands/keys"
    16  	"github.com/daticahealth/cli/commands/services"
    17  	"github.com/daticahealth/cli/config"
    18  	"github.com/daticahealth/cli/lib/prompts"
    19  	"github.com/daticahealth/cli/models"
    20  	homedir "github.com/mitchellh/go-homedir"
    21  )
    22  
    23  func CmdInit(settings *models.Settings, p prompts.IPrompts) error {
    24  	logrus.Println("To set up your local repository, we need to know what environment and service you want to push your code to.")
    25  
    26  	ie := environments.New(settings)
    27  	envs, errs := ie.List()
    28  	if errs != nil && len(errs) > 0 {
    29  		logrus.Debugf("Error listing environments: %+v", errs)
    30  	}
    31  	if envs == nil || len(*envs) == 0 {
    32  		logrus.Println("You don't currently have any environments")
    33  		return nil
    34  	}
    35  
    36  	config.StoreEnvironments(envs, settings)
    37  
    38  	logrus.Printf("%d environment(s) found:", len(*envs))
    39  	for i, env := range *envs {
    40  		logrus.Printf("\t%d) %s", i+1, env.Name)
    41  	}
    42  	env := (*envs)[0]
    43  	if len(*envs) > 1 {
    44  		for {
    45  			choice := p.CaptureInput("Enter your choice as a number: ")
    46  			i, err := strconv.ParseUint(choice, 10, 64)
    47  			if err != nil || i == 0 || i > uint64(len(*envs)) {
    48  				logrus.Printf("%s is not a valid number", choice)
    49  				continue
    50  			}
    51  			env = (*envs)[i-1]
    52  			break
    53  		}
    54  	}
    55  	settings.EnvironmentID = env.ID
    56  	settings.Pod = env.Pod
    57  	settings.EnvironmentName = env.Name
    58  	settings.OrgID = env.OrgID
    59  	logrus.Printf("Initializing %s...", env.Name)
    60  
    61  	is := services.New(settings)
    62  	svcs, err := is.ListByEnvID(env.ID, env.Pod)
    63  	if err != nil {
    64  		return err
    65  	}
    66  	codeServices := []models.Service{}
    67  	for _, svc := range *svcs {
    68  		if svc.Type == "code" {
    69  			codeServices = append(codeServices, svc)
    70  		}
    71  	}
    72  	if len(codeServices) == 0 {
    73  		logrus.Println("You don't have any code services. Visit the dashboard to add one")
    74  		return nil
    75  	}
    76  	logrus.Printf("%d code service(s) found for %s:", len(codeServices), env.Name)
    77  	for i, svc := range codeServices {
    78  		logrus.Printf("\t%d) %s", i+1, svc.Label)
    79  	}
    80  	svc := codeServices[0]
    81  	if len(codeServices) > 1 {
    82  		for {
    83  			choice := p.CaptureInput("Enter your choice as a number: ")
    84  			i, err := strconv.ParseUint(choice, 10, 64)
    85  			if err != nil || i == 0 || i > uint64(len(codeServices)) {
    86  				logrus.Printf("%s is not a valid number", choice)
    87  				continue
    88  			}
    89  			svc = codeServices[i-1]
    90  			break
    91  		}
    92  	}
    93  
    94  	ig := git.New()
    95  	if !ig.Exists() {
    96  		logrus.Println("Initializing a local git repo...")
    97  		ig.Create()
    98  	}
    99  
   100  	logrus.Printf("Adding git remote for %s...", svc.Label)
   101  	remoteName := "datica"
   102  	remotes, err := ig.List()
   103  	if err != nil {
   104  		return err
   105  	}
   106  	exists := false
   107  	for _, r := range remotes {
   108  		if r == remoteName {
   109  			exists = true
   110  			break
   111  		}
   112  	}
   113  	if exists {
   114  		if err := p.YesNo(fmt.Sprintf("A git remote named \"%s\" already exists.", remoteName), "Would you like to overwrite it? (y/n) "); err != nil {
   115  			return err
   116  		}
   117  		err = ig.SetURL(remoteName, svc.Source)
   118  	} else {
   119  		err = ig.Add(remoteName, svc.Source)
   120  	}
   121  	if err != nil {
   122  		return fmt.Errorf("Failed to setup the git remote: %s", err)
   123  	}
   124  
   125  	// TODO insert lets encrypt setup here once ready
   126  	logrus.Println("Creating certificates...")
   127  
   128  	ik := keys.New(settings)
   129  	userKeys, err := ik.List()
   130  	if err != nil {
   131  		return err
   132  	}
   133  	if userKeys == nil || len(*userKeys) == 0 {
   134  		logrus.Println("You'll need to add an SSH key in order to push code.")
   135  		for {
   136  			keyPath := p.CaptureInput("Enter the path to your public SSH key (leave empty to skip): ")
   137  			if keyPath == "" {
   138  				break
   139  			} else if _, err = os.Stat(keyPath); os.IsNotExist(err) {
   140  				keyPath, _ = homedir.Expand(keyPath)
   141  				if _, err = os.Stat(keyPath); os.IsNotExist(err) {
   142  					logrus.Printf("A file does not exist at %s", keyPath)
   143  					continue
   144  				}
   145  			}
   146  
   147  			keyBytes, err := ioutil.ReadFile(keyPath)
   148  			if err != nil {
   149  				logrus.Printf("Could not read file at %s", keyPath)
   150  				continue
   151  			}
   152  			k, err := deploykeys.New(settings).ParsePublicKey(keyBytes)
   153  			if err != nil {
   154  				logrus.Printf("A valid public SSH key does not exist at %s", keyPath)
   155  				continue
   156  			}
   157  			err = ik.Add("my-key", string(ssh.MarshalAuthorizedKey(k)))
   158  			if err != nil {
   159  				return err
   160  			}
   161  			logrus.Println("Successfully added your SSH key.")
   162  			break
   163  		}
   164  	}
   165  
   166  	logrus.Println("All set! Next, you'll need to make sure you have an SSH key to push code using the \"datica keys\" command. Once your key is set up, run \"git push datica master\" to push your code.")
   167  	return nil
   168  }