Skip to content

Commit

Permalink
Refactor enclave setup implementation
Browse files Browse the repository at this point in the history
Project/config selection is moved to separate functions to make the top-level logic easier to follow.
  • Loading branch information
Piccirello committed May 8, 2020
1 parent e47d2a0 commit 72e8822
Showing 1 changed file with 92 additions and 69 deletions.
161 changes: 92 additions & 69 deletions pkg/cmd/enclave_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,17 @@ var setupCmd = &cobra.Command{

utils.RequireValue("token", localConfig.Token.Value)

flagsFromEnvironment := []string{}

originalProject := localConfig.EnclaveProject.Value
currentProject := localConfig.EnclaveProject.Value
selectedProject := ""

switch localConfig.EnclaveProject.Source {
case models.FlagSource.String():
selectedProject = localConfig.EnclaveProject.Value
case models.EnvironmentSource.String():
flagsFromEnvironment = append(flagsFromEnvironment, "ENCLAVE_PROJECT")
utils.Log(valueFromEnvironmentNotice("ENCLAVE_PROJECT"))
selectedProject = localConfig.EnclaveProject.Value
default:
if !promptUser {
utils.HandleError(errors.New("project must be specified via --project flag or ENCLAVE_PROJECT environment variable when using --no-prompt"))
}

projects, httpErr := http.GetProjects(localConfig.APIHost.Value, utils.GetBool(localConfig.VerifyTLS.Value, true), localConfig.Token.Value)
if !httpErr.IsNil() {
utils.HandleError(httpErr.Unwrap(), httpErr.Message)
Expand All @@ -65,51 +61,22 @@ var setupCmd = &cobra.Command{
utils.HandleError(errors.New("you do not have access to any projects"))
}

var options []string
var defaultOption string
for _, val := range projects {
option := val.Name + " (" + val.ID + ")"
options = append(options, option)

// reselect previously-configured value
if val.ID == scopedConfig.EnclaveProject.Value {
defaultOption = option
}
}

prompt := &survey.Select{
Message: "Select a project:",
Options: options,
}
if defaultOption != "" {
prompt.Default = defaultOption
}
err := survey.AskOne(prompt, &selectedProject)
if err != nil {
utils.HandleError(err)
}

for _, val := range projects {
if strings.HasSuffix(selectedProject, "("+val.ID+")") {
selectedProject = val.ID
break
}
selectedProject = selectProject(projects, scopedConfig.EnclaveProject.Value, promptUser)
if selectedProject == "" {
utils.HandleError(errors.New("Invalid project"))
}
}

selectedConfiguredProject := selectedProject == currentProject
selectedConfig := ""

switch localConfig.EnclaveConfig.Source {
case models.FlagSource.String():
selectedConfig = localConfig.EnclaveConfig.Value
case models.EnvironmentSource.String():
flagsFromEnvironment = append(flagsFromEnvironment, "ENCLAVE_CONFIG")
utils.Log(valueFromEnvironmentNotice("ENCLAVE_CONFIG"))
selectedConfig = localConfig.EnclaveConfig.Value
default:
if !promptUser {
utils.HandleError(errors.New("config must be specified via --config flag or ENCLAVE_CONFIG environment variable when using --no-prompt"))
}

// Get Configs
configs, apiError := http.GetConfigs(localConfig.APIHost.Value, utils.GetBool(localConfig.VerifyTLS.Value, true), localConfig.Token.Value, selectedProject)
if !apiError.IsNil() {
utils.HandleError(apiError.Unwrap(), apiError.Message)
Expand All @@ -118,40 +85,19 @@ var setupCmd = &cobra.Command{
utils.HandleError(errors.New("your project does not have any configs"))
}

var options []string
var defaultOption string
for _, val := range configs {
option := val.Name
options = append(options, option)
// reselect previously-configured value
if selectedProject == originalProject && val.Name == scopedConfig.EnclaveConfig.Value {
defaultOption = val.Name
}
}

prompt := &survey.Select{
Message: "Select a config:",
Options: options,
}
if defaultOption != "" {
prompt.Default = defaultOption
}
err := survey.AskOne(prompt, &selectedConfig)
if err != nil {
utils.HandleError(err)
selectedConfig = selectConfig(configs, selectedConfiguredProject, scopedConfig.EnclaveConfig.Value, promptUser)
if selectedConfig == "" {
utils.HandleError(errors.New("Invalid config"))
}
}

configuration.Set(scope, map[string]string{
configToSave := map[string]string{
models.ConfigEnclaveProject.String(): selectedProject,
models.ConfigEnclaveConfig.String(): selectedConfig,
})
}
configuration.Set(scope, configToSave)

if !silent {
if len(flagsFromEnvironment) > 0 {
fmt.Println("Using " + strings.Join(flagsFromEnvironment, " and ") + " from the environment. To disable this, use --no-read-env.")
}

// do not fetch the LocalConfig since we do not care about env variables or cmd flags
conf := configuration.Get(scope)
valuesToPrint := []string{models.ConfigEnclaveConfig.String(), models.ConfigEnclaveProject.String()}
Expand All @@ -160,6 +106,83 @@ var setupCmd = &cobra.Command{
},
}

func selectProject(projects []models.ProjectInfo, prevConfiguredProject string, promptUser bool) string {
var options []string
var defaultOption string
for _, val := range projects {
option := val.Name + " (" + val.ID + ")"
options = append(options, option)

if val.ID == prevConfiguredProject {
defaultOption = option
}
}

if !promptUser {
utils.HandleError(errors.New("project must be specified via --project flag or ENCLAVE_PROJECT environment variable when using --no-prompt"))
}

prompt := &survey.Select{
Message: "Select a project:",
Options: options,
}
if defaultOption != "" {
prompt.Default = defaultOption
}

selectedProject := ""
err := survey.AskOne(prompt, &selectedProject)
if err != nil {
utils.HandleError(err)
}

for _, val := range projects {
if strings.HasSuffix(selectedProject, "("+val.ID+")") {
return val.ID
}
}

return ""
}

func selectConfig(configs []models.ConfigInfo, selectedConfiguredProject bool, prevConfiguredConfig string, promptUser bool) string {
var options []string
var defaultOption string
for _, val := range configs {
option := val.Name
options = append(options, option)

// make previously selected config the default when re-using the previously selected project
if selectedConfiguredProject && val.Name == prevConfiguredConfig {
defaultOption = val.Name
}
}

if !promptUser {
utils.HandleError(errors.New("config must be specified via --config flag or ENCLAVE_CONFIG environment variable when using --no-prompt"))
}

prompt := &survey.Select{
Message: "Select a config:",
Options: options,
}
if defaultOption != "" {
prompt.Default = defaultOption
}

selectedConfig := ""
err := survey.AskOne(prompt, &selectedConfig)
if err != nil {
utils.HandleError(err)
}

return selectedConfig
}

func valueFromEnvironmentNotice(name string) string {
return fmt.Sprintf("Using %s from the environment. To disable this, use --no-read-env.", name)
}

func init() {
setupCmd.Flags().StringP("project", "p", "", "enclave project (e.g. backend)")
setupCmd.Flags().StringP("config", "c", "", "enclave config (e.g. dev)")
Expand Down

0 comments on commit 72e8822

Please sign in to comment.