package internal import ( "fmt" "path" "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/sirupsen/logrus" "github.com/urfave/cli/v2" ) // 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", 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: 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 := 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) } 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); err != nil { logrus.Fatal(err) } if Secrets { if err := ssh.EnsureHostKey(NewAppServer); err != nil { logrus.Fatal(err) } 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 len(secrets) > 0 { defer secretTable.Render() } } if NewAppServer == "default" { NewAppServer = "local" } tableCol := []string{"server", "type", "domain", "app name"} table := formatter.CreateTable(tableCol) table.Append([]string{NewAppServer, recipe.Name, Domain, NewAppName}) 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", NewAppName)) fmt.Println("") fmt.Println("You can deploy this app by running the following:") fmt.Println(fmt.Sprintf("\n abra app deploy %s", NewAppName)) fmt.Println("") return nil }