github.com/awslabs/clencli@v0.0.0-20210514234156-7ecf17182a20/cobra/aid/configure.go (about) 1 /* 2 Copyright © 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 */ 15 16 package aid 17 18 import ( 19 "bufio" 20 "encoding/json" 21 "fmt" 22 "io/ioutil" 23 "os" 24 "runtime" 25 "strconv" 26 "strings" 27 28 "github.com/awslabs/clencli/helper" 29 "github.com/sirupsen/logrus" 30 "github.com/spf13/cobra" 31 "github.com/spf13/viper" 32 "gopkg.in/yaml.v2" 33 ) 34 35 // ConfigurationsDirectoryExist returns `true` if the configuration directory exist, `false` otherwise 36 func ConfigurationsDirectoryExist() bool { 37 return helper.DirOrFileExists(GetAppInfo().ConfigurationsDir) 38 } 39 40 // ConfigurationsFileExist returns `true` if the configuration file exist, `false` otherwise 41 func ConfigurationsFileExist() bool { 42 return helper.DirOrFileExists(GetAppInfo().ConfigurationsPath) 43 } 44 45 // CreateConfigurationsDirectory creates the configuration directory, returns `true` if the configuration directory exist, `false` otherwise 46 func CreateConfigurationsDirectory() (bool, string) { 47 dir := GetAppInfo().ConfigurationsDir 48 return helper.MkDirsIfNotExist(dir), dir 49 } 50 51 // CredentialsFileExist returns `true` if the credentials file exist, `false` otherwise 52 func CredentialsFileExist() bool { 53 return helper.DirOrFileExists(GetAppInfo().CredentialsPath) 54 } 55 56 // ReadConfig returns the viper instance of the given configuration `name` 57 func ReadConfig(name string) (*viper.Viper, error) { 58 v := viper.New() 59 app := GetAppInfo() 60 61 v.SetConfigName(name) 62 v.SetConfigType("yaml") 63 v.AddConfigPath(app.ConfigurationsDir) 64 65 err := v.ReadInConfig() 66 if err != nil { 67 return v, fmt.Errorf("unable to read configuration:%s\n%v", name, err) 68 } 69 return v, err 70 } 71 72 // ReadConfigAsViper returns... 73 func ReadConfigAsViper(configPath string, configName string, configType string) (*viper.Viper, error) { 74 v := viper.New() 75 76 v.AddConfigPath(configPath) 77 v.SetConfigName(configName) 78 v.SetConfigType(configType) 79 80 err := v.ReadInConfig() 81 if err != nil { 82 return v, fmt.Errorf("unable to read configuration as viper\n%v", err) 83 } 84 return v, err 85 } 86 87 // ReadTemplate read the given template under clencli/*.yaml 88 func ReadTemplate(fileName string) (*viper.Viper, error) { 89 c := viper.New() 90 c.AddConfigPath("clencli") 91 c.SetConfigName(fileName) 92 c.SetConfigType("yaml") 93 c.SetConfigPermissions(os.ModePerm) 94 95 err := c.ReadInConfig() // Find and read the c file 96 if err != nil { // Handle errors reading the c file 97 return c, fmt.Errorf("Unable to read "+fileName+" via Viper"+"\n%v", err) 98 } 99 100 return c, nil 101 } 102 103 // WriteInterfaceToFile write the given interface into a file 104 func WriteInterfaceToFile(in interface{}, path string) error { 105 b, err := yaml.Marshal(&in) 106 if err != nil { 107 _, ok := err.(*json.UnsupportedTypeError) 108 if ok { 109 return fmt.Errorf("json unsupported type error") 110 } 111 } 112 113 err = ioutil.WriteFile(path, b, os.ModePerm) 114 if err != nil { 115 return fmt.Errorf("unable to update:%s\n%v", path, err) 116 } 117 118 return err 119 } 120 121 // DeleteCredentialFile delete the credentials file 122 func DeleteCredentialFile() error { 123 return helper.DeleteFile(GetAppInfo().CredentialsPath) 124 } 125 126 // DeleteConfigurationFile delete the credentials file 127 func DeleteConfigurationFile() error { 128 return helper.DeleteFile(GetAppInfo().ConfigurationsPath) 129 } 130 131 // DeleteConfigurationsDirectory delete the configurations directory 132 func DeleteConfigurationsDirectory() error { 133 return os.RemoveAll(GetAppInfo().ConfigurationsDir) 134 } 135 136 // GetSensitiveUserInput get sensitive input as string 137 func GetSensitiveUserInput(cmd *cobra.Command, text string, info string) (string, error) { 138 return getUserInput(cmd, text+" ["+maskString(info, 3)+"]", "") 139 } 140 141 func maskString(s string, showLastChars int) string { 142 maskSize := len(s) - showLastChars 143 if maskSize <= 0 { 144 return s 145 } 146 147 return strings.Repeat("*", maskSize) + s[maskSize:] 148 } 149 150 // GetSensitiveUserInputAsString get sensitive input as string 151 func GetSensitiveUserInputAsString(cmd *cobra.Command, text string, info string) string { 152 answer, err := GetSensitiveUserInput(cmd, text, info) 153 if err != nil { 154 logrus.Fatalf("unable to get user input about profile's name\n%v", err) 155 } 156 157 // if user typed ENTER, keep the current value 158 if answer != "" { 159 return answer 160 } 161 162 return info 163 } 164 165 func getInput() (string, error) { 166 167 reader := bufio.NewReader(os.Stdin) 168 169 text, err := reader.ReadString('\n') 170 if err != nil { 171 return "", err 172 } 173 174 if runtime.GOOS == "windows" { 175 // convert LF to CRLF 176 text = strings.Replace(text, "\r\n", "", -1) 177 } else { 178 // convert CRLF to LF 179 text = strings.Replace(text, "\n", "", -1) 180 } 181 182 return text, nil 183 } 184 185 func getUserInput(cmd *cobra.Command, text string, info string) (string, error) { 186 if info == "" { 187 cmd.Print(text + ": ") 188 } else { 189 cmd.Print(text + " [" + info + "]: ") 190 } 191 192 input, err := getInput() 193 194 return input, err 195 } 196 197 // GetUserInputAsBool prints `text` on console and return answer as `boolean` 198 func GetUserInputAsBool(cmd *cobra.Command, text string, info bool) bool { 199 answer, err := getUserInput(cmd, text, strconv.FormatBool(info)) 200 if err != nil { 201 logrus.Fatalf("unable to get user input as boolean\n%s", err) 202 } 203 204 if answer == "true" { 205 return true 206 } else if answer == "false" { 207 return false 208 } 209 210 return info 211 } 212 213 // GetUserInputAsString prints `text` on console and return answer as `string` 214 func GetUserInputAsString(cmd *cobra.Command, text string, info string) string { 215 answer, err := getUserInput(cmd, text, info) 216 if err != nil { 217 logrus.Fatalf("unable to get user input about profile's name\n%v", err) 218 } 219 220 // if user typed ENTER, keep the current value 221 if answer != "" { 222 return answer 223 } 224 225 return info 226 }