1// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2// See LICENSE.txt for license information. 3 4package commands 5 6import ( 7 "bytes" 8 "encoding/json" 9 "fmt" 10 "os" 11 "reflect" 12 "sort" 13 "strings" 14 15 "github.com/spf13/cobra" 16 17 "github.com/mattermost/mattermost-server/v6/model" 18) 19 20const CustomDefaultsEnvVar = "MM_CUSTOM_DEFAULTS_PATH" 21 22// printStringMap takes a reflect.Value and prints it out alphabetically based on key values, which must be strings. 23// This is done recursively if it's a map, and uses the given tab settings. 24func printStringMap(value reflect.Value, tabVal int) string { 25 out := &bytes.Buffer{} 26 27 var sortedKeys []string 28 stringToKeyMap := make(map[string]reflect.Value) 29 for _, k := range value.MapKeys() { 30 sortedKeys = append(sortedKeys, k.String()) 31 stringToKeyMap[k.String()] = k 32 } 33 34 sort.Strings(sortedKeys) 35 36 for _, keyString := range sortedKeys { 37 key := stringToKeyMap[keyString] 38 val := value.MapIndex(key) 39 if newVal, ok := val.Interface().(map[string]interface{}); !ok { 40 fmt.Fprintf(out, "%s", strings.Repeat("\t", tabVal)) 41 fmt.Fprintf(out, "%v: \"%v\"\n", key.Interface(), val.Interface()) 42 } else { 43 fmt.Fprintf(out, "%s", strings.Repeat("\t", tabVal)) 44 fmt.Fprintf(out, "%v:\n", key.Interface()) 45 // going one level in, increase the tab 46 tabVal++ 47 fmt.Fprintf(out, "%s", printStringMap(reflect.ValueOf(newVal), tabVal)) 48 // coming back one level, decrease the tab 49 tabVal-- 50 } 51 } 52 53 return out.String() 54} 55 56func getConfigDSN(command *cobra.Command, env map[string]string) string { 57 configDSN, _ := command.Flags().GetString("config") 58 59 // Config not supplied in flag, check env 60 if configDSN == "" { 61 configDSN = env["MM_CONFIG"] 62 } 63 64 // Config not supplied in env or flag use default 65 if configDSN == "" { 66 configDSN = "config.json" 67 } 68 69 return configDSN 70} 71 72func loadCustomDefaults() (*model.Config, error) { 73 customDefaultsPath := os.Getenv(CustomDefaultsEnvVar) 74 if customDefaultsPath == "" { 75 return nil, nil 76 } 77 78 file, err := os.Open(customDefaultsPath) 79 if err != nil { 80 return nil, fmt.Errorf("unable to open custom defaults file at %q: %w", customDefaultsPath, err) 81 } 82 defer file.Close() 83 84 var customDefaults *model.Config 85 err = json.NewDecoder(file).Decode(&customDefaults) 86 if err != nil { 87 return nil, fmt.Errorf("unable to decode custom defaults configuration: %w", err) 88 } 89 90 return customDefaults, nil 91} 92