forked from toolshed/abra
WIP: make "abra app new" callable by code
Part of coop-cloud/organising#212.
This commit is contained in:
189
cli/internal/app.go
Normal file
189
cli/internal/app.go
Normal file
@ -0,0 +1,189 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
abraFormatter "coopcloud.tech/abra/cli/formatter"
|
||||
"coopcloud.tech/abra/pkg/config"
|
||||
"coopcloud.tech/abra/pkg/recipe"
|
||||
"coopcloud.tech/abra/pkg/secret"
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
type AppSecrets map[string]string
|
||||
|
||||
var Domain string
|
||||
var DomainFlag = &cli.StringFlag{
|
||||
Name: "domain",
|
||||
Aliases: []string{"d"},
|
||||
Value: "",
|
||||
Usage: "Choose a domain name",
|
||||
Destination: &Domain,
|
||||
}
|
||||
|
||||
var NewAppServer string
|
||||
var NewAppServerFlag = &cli.StringFlag{
|
||||
Name: "server",
|
||||
Aliases: []string{"s"},
|
||||
Value: "",
|
||||
Usage: "Show apps of a specific server",
|
||||
Destination: &NewAppServer,
|
||||
}
|
||||
|
||||
var NewAppName string
|
||||
var NewAppNameFlag = &cli.StringFlag{
|
||||
Name: "app-name",
|
||||
Aliases: []string{"a"},
|
||||
Value: "",
|
||||
Usage: "Choose an app name",
|
||||
Destination: &NewAppName,
|
||||
}
|
||||
|
||||
// RecipeName is used for configuring NewAction 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", sanitisedAppName))
|
||||
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, sanitisedAppName, 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 == "" {
|
||||
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
|
||||
}
|
||||
}
|
||||
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 == "" {
|
||||
prompt := &survey.Select{
|
||||
Message: "Select app server:",
|
||||
Options: servers,
|
||||
}
|
||||
if err := survey.AskOne(prompt, &NewAppServer); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ensureServerFlag checks if the AppName flag was used. if not, asks the user for it.
|
||||
func ensureAppNameFlag() error {
|
||||
if NewAppName == "" {
|
||||
prompt := &survey.Input{
|
||||
Message: "Specify app name:",
|
||||
Default: config.SanitiseAppName(Domain),
|
||||
}
|
||||
if err := survey.AskOne(prompt, &NewAppName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewAction is the new app creation logic
|
||||
func NewAction(c *cli.Context) error {
|
||||
recipe := ValidateRecipeWithPrompt(c)
|
||||
|
||||
if err := config.EnsureAbraDirExists(); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
if err := ensureServerFlag(); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
if err := ensureDomainFlag(recipe, NewAppServer); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
if err := ensureAppNameFlag(); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
sanitisedAppName := config.SanitiseAppName(NewAppName)
|
||||
if len(sanitisedAppName) > 45 {
|
||||
logrus.Fatalf("'%s' cannot be longer than 45 characters", sanitisedAppName)
|
||||
}
|
||||
logrus.Debugf("'%s' sanitised as '%s' for new app", NewAppName, sanitisedAppName)
|
||||
|
||||
if err := config.TemplateAppEnvSample(recipe.Name, NewAppName, NewAppServer, Domain, recipe.Name); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
if Secrets {
|
||||
secrets, err := createSecrets(sanitisedAppName)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
secretCols := []string{"Name", "Value"}
|
||||
secretTable := abraFormatter.CreateTable(secretCols)
|
||||
for secret := range secrets {
|
||||
secretTable.Append([]string{secret, secrets[secret]})
|
||||
}
|
||||
|
||||
if len(secrets) > 0 {
|
||||
defer secretTable.Render()
|
||||
}
|
||||
}
|
||||
|
||||
if NewAppServer == "default" {
|
||||
NewAppServer = "local"
|
||||
}
|
||||
|
||||
tableCol := []string{"Name", "Domain", "Type", "Server"}
|
||||
table := abraFormatter.CreateTable(tableCol)
|
||||
table.Append([]string{sanitisedAppName, Domain, recipe.Name, NewAppServer})
|
||||
|
||||
fmt.Println("")
|
||||
fmt.Println(fmt.Sprintf("New '%s' created! Here is your new app 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", sanitisedAppName))
|
||||
fmt.Println("")
|
||||
fmt.Println("You can deploy this app by running the following:")
|
||||
fmt.Println(fmt.Sprintf("\n abra app deploy %s", sanitisedAppName))
|
||||
fmt.Println("")
|
||||
|
||||
return nil
|
||||
}
|
@ -54,7 +54,12 @@ func ValidateRecipeWithPrompt(c *cli.Context) recipe.Recipe {
|
||||
}
|
||||
}
|
||||
|
||||
if recipeName == "" {
|
||||
if recipeName == "" && RecipeName != "" {
|
||||
recipeName = RecipeName
|
||||
logrus.Debugf("programmatically setting recipe name to %s", recipeName)
|
||||
}
|
||||
|
||||
if recipeName == "" && RecipeName == "" {
|
||||
ShowSubcommandHelpAndError(c, errors.New("no recipe provided"))
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user