forked from toolshed/abra
		
	
		
			
				
	
	
		
			197 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			197 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package internal
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"path"
 | |
| 
 | |
| 	"coopcloud.tech/abra/pkg/app"
 | |
| 	"coopcloud.tech/abra/pkg/config"
 | |
| 	"coopcloud.tech/abra/pkg/formatter"
 | |
| 	"coopcloud.tech/abra/pkg/recipe"
 | |
| 	recipePkg "coopcloud.tech/abra/pkg/recipe"
 | |
| 	"coopcloud.tech/abra/pkg/secret"
 | |
| 	"coopcloud.tech/abra/pkg/ssh"
 | |
| 	"github.com/AlecAivazis/survey/v2"
 | |
| 	"github.com/olekukonko/tablewriter"
 | |
| 	"github.com/sirupsen/logrus"
 | |
| 	"github.com/urfave/cli"
 | |
| )
 | |
| 
 | |
| // AppSecrets represents all app secrest
 | |
| type AppSecrets map[string]string
 | |
| 
 | |
| // RecipeName is used for configuring recipe name programmatically
 | |
| var RecipeName string
 | |
| 
 | |
| // createSecrets creates all secrets for a new app.
 | |
| func createSecrets(sanitisedAppName string) (AppSecrets, error) {
 | |
| 	appEnvPath := path.Join(config.ABRA_DIR, "servers", NewAppServer, fmt.Sprintf("%s.env", Domain))
 | |
| 	appEnv, err := config.ReadEnv(appEnvPath)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	secretEnvVars := secret.ReadSecretEnvVars(appEnv)
 | |
| 	secrets, err := secret.GenerateSecrets(secretEnvVars, sanitisedAppName, NewAppServer)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	if Pass {
 | |
| 		for secretName := range secrets {
 | |
| 			secretValue := secrets[secretName]
 | |
| 			if err := secret.PassInsertSecret(secretValue, secretName, Domain, NewAppServer); err != nil {
 | |
| 				return nil, err
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return secrets, nil
 | |
| }
 | |
| 
 | |
| // ensureDomainFlag checks if the domain flag was used. if not, asks the user for it/
 | |
| func ensureDomainFlag(recipe recipe.Recipe, server string) error {
 | |
| 	if Domain == "" && !NoInput {
 | |
| 		prompt := &survey.Input{
 | |
| 			Message: "Specify app domain",
 | |
| 			Default: fmt.Sprintf("%s.%s", recipe.Name, server),
 | |
| 		}
 | |
| 		if err := survey.AskOne(prompt, &Domain); err != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if Domain == "" {
 | |
| 		return fmt.Errorf("no domain provided")
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // promptForSecrets asks if we should generate secrets for a new app.
 | |
| func promptForSecrets(appName string) error {
 | |
| 	app, err := app.Get(appName)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	secretEnvVars := secret.ReadSecretEnvVars(app.Env)
 | |
| 	if len(secretEnvVars) == 0 {
 | |
| 		logrus.Debugf("%s has no secrets to generate, skipping...", app.Recipe)
 | |
| 		return nil
 | |
| 	}
 | |
| 
 | |
| 	if !Secrets && !NoInput {
 | |
| 		prompt := &survey.Confirm{
 | |
| 			Message: "Generate app secrets?",
 | |
| 		}
 | |
| 		if err := survey.AskOne(prompt, &Secrets); err != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // ensureServerFlag checks if the server flag was used. if not, asks the user for it.
 | |
| func ensureServerFlag() error {
 | |
| 	servers, err := config.GetServers()
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	if NewAppServer == "" && !NoInput {
 | |
| 		prompt := &survey.Select{
 | |
| 			Message: "Select app server:",
 | |
| 			Options: servers,
 | |
| 		}
 | |
| 		if err := survey.AskOne(prompt, &NewAppServer); err != nil {
 | |
| 			return err
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if NewAppServer == "" {
 | |
| 		return fmt.Errorf("no server provided")
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // NewAction is the new app creation logic
 | |
| func NewAction(c *cli.Context) error {
 | |
| 	recipe := ValidateRecipeWithPrompt(c, false)
 | |
| 
 | |
| 	if err := recipePkg.EnsureUpToDate(recipe.Name); err != nil {
 | |
| 		logrus.Fatal(err)
 | |
| 	}
 | |
| 
 | |
| 	if err := ensureServerFlag(); err != nil {
 | |
| 		logrus.Fatal(err)
 | |
| 	}
 | |
| 
 | |
| 	if err := ensureDomainFlag(recipe, NewAppServer); err != nil {
 | |
| 		logrus.Fatal(err)
 | |
| 	}
 | |
| 
 | |
| 	sanitisedAppName := config.SanitiseAppName(Domain)
 | |
| 	logrus.Debugf("%s sanitised as %s for new app", Domain, sanitisedAppName)
 | |
| 
 | |
| 	if err := config.TemplateAppEnvSample(recipe.Name, Domain, NewAppServer, Domain); err != nil {
 | |
| 		logrus.Fatal(err)
 | |
| 	}
 | |
| 
 | |
| 	if err := promptForSecrets(Domain); err != nil {
 | |
| 		logrus.Fatal(err)
 | |
| 	}
 | |
| 
 | |
| 	var secrets AppSecrets
 | |
| 	var secretTable *tablewriter.Table
 | |
| 	if Secrets {
 | |
| 		if err := ssh.EnsureHostKey(NewAppServer); err != nil {
 | |
| 			logrus.Fatal(err)
 | |
| 		}
 | |
| 
 | |
| 		var err error
 | |
| 		secrets, err = createSecrets(sanitisedAppName)
 | |
| 		if err != nil {
 | |
| 			logrus.Fatal(err)
 | |
| 		}
 | |
| 
 | |
| 		secretCols := []string{"Name", "Value"}
 | |
| 		secretTable = formatter.CreateTable(secretCols)
 | |
| 		for secret := range secrets {
 | |
| 			secretTable.Append([]string{secret, secrets[secret]})
 | |
| 		}
 | |
| 
 | |
| 	}
 | |
| 
 | |
| 	if NewAppServer == "default" {
 | |
| 		NewAppServer = "local"
 | |
| 	}
 | |
| 
 | |
| 	tableCol := []string{"server", "recipe", "domain"}
 | |
| 	table := formatter.CreateTable(tableCol)
 | |
| 	table.Append([]string{NewAppServer, recipe.Name, Domain})
 | |
| 
 | |
| 	fmt.Println("")
 | |
| 	fmt.Println(fmt.Sprintf("A new %s app has been created! Here is an overview:", recipe.Name))
 | |
| 	fmt.Println("")
 | |
| 	table.Render()
 | |
| 	fmt.Println("")
 | |
| 	fmt.Println("You can configure this app by running the following:")
 | |
| 	fmt.Println(fmt.Sprintf("\n    abra app config %s", Domain))
 | |
| 	fmt.Println("")
 | |
| 	fmt.Println("You can deploy this app by running the following:")
 | |
| 	fmt.Println(fmt.Sprintf("\n    abra app deploy %s", Domain))
 | |
| 	fmt.Println("")
 | |
| 
 | |
| 	if len(secrets) > 0 {
 | |
| 		fmt.Println("Here are your generated secrets:")
 | |
| 		fmt.Println("")
 | |
| 		secretTable.Render()
 | |
| 		fmt.Println("")
 | |
| 		logrus.Warn("generated secrets are not shown again, please take note of them *now*")
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 |