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 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", 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 == "" && !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 } // 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 } // ensureServerFlag checks if the AppName flag was used. if not, asks the user for it. func ensureAppNameFlag() error { if NewAppName == "" && !NoInput { prompt := &survey.Input{ Message: "Specify app name:", Default: config.SanitiseAppName(Domain), } if err := survey.AskOne(prompt, &NewAppName); err != nil { return err } } if NewAppName == "" { return fmt.Errorf("no app name provided") } 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("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", 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 }