diff --git a/cli/cmd/lib_cli_config.go b/cli/cmd/lib_cli_config.go index ead82f1758..57147565b3 100644 --- a/cli/cmd/lib_cli_config.go +++ b/cli/cmd/lib_cli_config.go @@ -414,7 +414,9 @@ func promptLocalEnv(env *cliconfig.Environment, defaults cliconfig.Environment) } func promptAWSEnv(env *cliconfig.Environment, defaults cliconfig.Environment) error { - fmt.Print("you can get your cortex operator endpoint using `cortex cluster info` if you already have a cortex cluster running, otherwise run `cortex cluster up` to create a cortex cluster\n\n") + if env.OperatorEndpoint == nil { + fmt.Print("you can get your cortex operator endpoint using `cortex cluster info` if you already have a cortex cluster running, otherwise run `cortex cluster up` to create a cortex cluster\n\n") + } for true { err := cr.ReadPrompt(env, &cr.PromptValidation{ SkipNonEmptyFields: true, diff --git a/pkg/lib/configreader/int32_ptr.go b/pkg/lib/configreader/int32_ptr.go index b8411cdfba..0f8a8656db 100644 --- a/pkg/lib/configreader/int32_ptr.go +++ b/pkg/lib/configreader/int32_ptr.go @@ -50,13 +50,13 @@ func makeInt32ValValidation(v *Int32PtrValidation) *Int32Validation { func Int32Ptr(inter interface{}, v *Int32PtrValidation) (*int32, error) { if inter == nil { - return ValidateInt32PtrProvdied(nil, v) + return ValidateInt32PtrProvided(nil, v) } casted, castOk := cast.InterfaceToInt32(inter) if !castOk { return nil, ErrorInvalidPrimitiveType(inter, PrimTypeInt) } - return ValidateInt32PtrProvdied(&casted, v) + return ValidateInt32PtrProvided(&casted, v) } func Int32PtrFromInterfaceMap(key string, iMap map[string]interface{}, v *Int32PtrValidation) (*int32, error) { @@ -99,7 +99,7 @@ func Int32PtrFromStr(valStr string, v *Int32PtrValidation) (*int32, error) { if !castOk { return nil, ErrorInvalidPrimitiveType(valStr, PrimTypeInt) } - return ValidateInt32PtrProvdied(&casted, v) + return ValidateInt32PtrProvided(&casted, v) } func Int32PtrFromEnv(envVarName string, v *Int32PtrValidation) (*int32, error) { @@ -172,7 +172,7 @@ func ValidateInt32PtrMissing(v *Int32PtrValidation) (*int32, error) { return validateInt32Ptr(v.Default, v) } -func ValidateInt32PtrProvdied(val *int32, v *Int32PtrValidation) (*int32, error) { +func ValidateInt32PtrProvided(val *int32, v *Int32PtrValidation) (*int32, error) { if !v.AllowExplicitNull && val == nil { return nil, ErrorCannotBeNull(v.Required) } diff --git a/pkg/lib/configreader/reader.go b/pkg/lib/configreader/reader.go index 7f05e4ecbe..53f3421e6d 100644 --- a/pkg/lib/configreader/reader.go +++ b/pkg/lib/configreader/reader.go @@ -585,6 +585,72 @@ func ReadPrompt(dest interface{}, promptValidation *PromptValidation) error { var err error shouldPrintTrailingNewLine := false + // Validate any skipped fields first, so that any errors are returned before prompting + if promptValidation.SkipNonEmptyFields { + for _, promptItemValidation := range promptValidation.PromptItemValidations { + v := reflect.ValueOf(dest).Elem().FieldByName(promptItemValidation.StructField) + if !v.IsZero() { + if promptItemValidation.StringValidation != nil && promptItemValidation.Parser == nil { + if _, err := ValidateString(v.Interface().(string), promptItemValidation.StringValidation); err != nil { + return errors.Wrap(err, inferPromptFieldName(reflect.TypeOf(dest), promptItemValidation.StructField)) + } + } else if promptItemValidation.StringPtrValidation != nil && promptItemValidation.Parser == nil { + if _, err := ValidateStringPtrProvided(v.Interface().(*string), promptItemValidation.StringPtrValidation); err != nil { + return errors.Wrap(err, inferPromptFieldName(reflect.TypeOf(dest), promptItemValidation.StructField)) + } + } else if promptItemValidation.BoolValidation != nil { + if _, err := ValidateBool(v.Interface().(bool), promptItemValidation.BoolValidation); err != nil { + return errors.Wrap(err, inferPromptFieldName(reflect.TypeOf(dest), promptItemValidation.StructField)) + } + } else if promptItemValidation.BoolPtrValidation != nil { + if _, err := ValidateBoolPtrProvided(v.Interface().(*bool), promptItemValidation.BoolPtrValidation); err != nil { + return errors.Wrap(err, inferPromptFieldName(reflect.TypeOf(dest), promptItemValidation.StructField)) + } + } else if promptItemValidation.IntValidation != nil { + if _, err := ValidateInt(v.Interface().(int), promptItemValidation.IntValidation); err != nil { + return errors.Wrap(err, inferPromptFieldName(reflect.TypeOf(dest), promptItemValidation.StructField)) + } + } else if promptItemValidation.IntPtrValidation != nil { + if _, err := ValidateIntPtrProvided(v.Interface().(*int), promptItemValidation.IntPtrValidation); err != nil { + return errors.Wrap(err, inferPromptFieldName(reflect.TypeOf(dest), promptItemValidation.StructField)) + } + } else if promptItemValidation.Int32Validation != nil { + if _, err := ValidateInt32(v.Interface().(int32), promptItemValidation.Int32Validation); err != nil { + return errors.Wrap(err, inferPromptFieldName(reflect.TypeOf(dest), promptItemValidation.StructField)) + } + } else if promptItemValidation.Int32PtrValidation != nil { + if _, err := ValidateInt32PtrProvided(v.Interface().(*int32), promptItemValidation.Int32PtrValidation); err != nil { + return errors.Wrap(err, inferPromptFieldName(reflect.TypeOf(dest), promptItemValidation.StructField)) + } + } else if promptItemValidation.Int64Validation != nil { + if _, err := ValidateInt64(v.Interface().(int64), promptItemValidation.Int64Validation); err != nil { + return errors.Wrap(err, inferPromptFieldName(reflect.TypeOf(dest), promptItemValidation.StructField)) + } + } else if promptItemValidation.Int64PtrValidation != nil { + if _, err := ValidateInt64PtrProvided(v.Interface().(*int64), promptItemValidation.Int64PtrValidation); err != nil { + return errors.Wrap(err, inferPromptFieldName(reflect.TypeOf(dest), promptItemValidation.StructField)) + } + } else if promptItemValidation.Float32Validation != nil { + if _, err := ValidateFloat32(v.Interface().(float32), promptItemValidation.Float32Validation); err != nil { + return errors.Wrap(err, inferPromptFieldName(reflect.TypeOf(dest), promptItemValidation.StructField)) + } + } else if promptItemValidation.Float32PtrValidation != nil { + if _, err := ValidateFloat32PtrProvided(v.Interface().(*float32), promptItemValidation.Float32PtrValidation); err != nil { + return errors.Wrap(err, inferPromptFieldName(reflect.TypeOf(dest), promptItemValidation.StructField)) + } + } else if promptItemValidation.Float64Validation != nil { + if _, err := ValidateFloat64(v.Interface().(float64), promptItemValidation.Float64Validation); err != nil { + return errors.Wrap(err, inferPromptFieldName(reflect.TypeOf(dest), promptItemValidation.StructField)) + } + } else if promptItemValidation.Float64PtrValidation != nil { + if _, err := ValidateFloat64PtrProvided(v.Interface().(*float64), promptItemValidation.Float64PtrValidation); err != nil { + return errors.Wrap(err, inferPromptFieldName(reflect.TypeOf(dest), promptItemValidation.StructField)) + } + } + } + } + } + for _, promptItemValidation := range promptValidation.PromptItemValidations { if promptValidation.SkipNonEmptyFields { v := reflect.ValueOf(dest).Elem().FieldByName(promptItemValidation.StructField) @@ -1090,6 +1156,15 @@ func inferKey(structType reflect.Type, typeStructField string, typeKey string) s return typeStructField } +func inferPromptFieldName(structType reflect.Type, typeStructField string) string { + field, _ := structType.Elem().FieldByName(typeStructField) + tag, ok := getTagFieldName(field) + if ok { + return tag + } + return typeStructField +} + func getTagFieldName(field reflect.StructField) (string, bool) { tag, ok := field.Tag.Lookup("json") if ok {