github.com/naphatkrit/deis@v1.12.3/client/cmd/config.go (about) 1 package cmd 2 3 import ( 4 "encoding/base64" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "regexp" 9 "sort" 10 "strings" 11 12 "github.com/deis/deis/pkg/prettyprint" 13 14 "github.com/deis/deis/client/controller/api" 15 "github.com/deis/deis/client/controller/models/config" 16 ) 17 18 // ConfigList lists an app's config. 19 func ConfigList(appID string, oneLine bool) error { 20 c, appID, err := load(appID) 21 22 if err != nil { 23 return err 24 } 25 26 config, err := config.List(c, appID) 27 28 if err != nil { 29 return err 30 } 31 32 var keys []string 33 for k := range config.Values { 34 keys = append(keys, k) 35 } 36 sort.Strings(keys) 37 38 if oneLine { 39 for _, key := range keys { 40 fmt.Printf("%s=%s ", key, config.Values[key]) 41 } 42 fmt.Println() 43 } else { 44 fmt.Printf("=== %s Config\n", appID) 45 46 configMap := make(map[string]string) 47 48 // config.Values is type interface, so it needs to be converted to a string 49 for _, key := range keys { 50 configMap[key] = fmt.Sprintf("%v", config.Values[key]) 51 } 52 53 fmt.Print(prettyprint.PrettyTabs(configMap, 6)) 54 } 55 56 return nil 57 } 58 59 // ConfigSet sets an app's config variables. 60 func ConfigSet(appID string, configVars []string) error { 61 c, appID, err := load(appID) 62 63 if err != nil { 64 return err 65 } 66 67 configMap := parseConfig(configVars) 68 69 value, ok := configMap["SSH_KEY"] 70 71 if ok { 72 sshKey := value.(string) 73 74 if _, err := os.Stat(value.(string)); err == nil { 75 contents, err := ioutil.ReadFile(value.(string)) 76 77 if err != nil { 78 return err 79 } 80 81 sshKey = string(contents) 82 } 83 84 sshRegex := regexp.MustCompile("^-.+ .SA PRIVATE KEY-*") 85 86 if !sshRegex.MatchString(sshKey) { 87 return fmt.Errorf("Could not parse SSH private key:\n %s", sshKey) 88 } 89 90 configMap["SSH_KEY"] = base64.StdEncoding.EncodeToString([]byte(sshKey)) 91 } 92 93 fmt.Print("Creating config... ") 94 95 quit := progress() 96 configObj := api.Config{Values: configMap} 97 configObj, err = config.Set(c, appID, configObj) 98 99 quit <- true 100 <-quit 101 102 if err != nil { 103 return err 104 } 105 106 if release, ok := configObj.Values["DEIS_RELEASE"]; ok { 107 fmt.Printf("done, %s\n\n", release) 108 } else { 109 fmt.Print("done\n\n") 110 } 111 112 return ConfigList(appID, false) 113 } 114 115 // ConfigUnset removes a config variable from an app. 116 func ConfigUnset(appID string, configVars []string) error { 117 c, appID, err := load(appID) 118 119 if err != nil { 120 return err 121 } 122 123 fmt.Print("Removing config... ") 124 125 quit := progress() 126 127 configObj := api.Config{} 128 129 valuesMap := make(map[string]interface{}) 130 131 for _, configVar := range configVars { 132 valuesMap[configVar] = nil 133 } 134 135 configObj.Values = valuesMap 136 137 _, err = config.Set(c, appID, configObj) 138 139 quit <- true 140 <-quit 141 142 if err != nil { 143 return err 144 } 145 146 fmt.Print("done\n\n") 147 148 return ConfigList(appID, false) 149 } 150 151 // ConfigPull pulls an app's config to a file. 152 func ConfigPull(appID string, interactive bool, overwrite bool) error { 153 filename := ".env" 154 155 if !overwrite { 156 if _, err := os.Stat(filename); err == nil { 157 return fmt.Errorf("%s already exists, pass -o to overwrite", filename) 158 } 159 } 160 161 c, appID, err := load(appID) 162 163 if err != nil { 164 return err 165 } 166 167 configVars, err := config.List(c, appID) 168 169 if interactive { 170 contents, err := ioutil.ReadFile(filename) 171 172 if err != nil { 173 return err 174 } 175 localConfigVars := strings.Split(string(contents), "\n") 176 177 configMap := parseConfig(localConfigVars[:len(localConfigVars)-1]) 178 179 for key, value := range configVars.Values { 180 localValue, ok := configMap[key] 181 182 if ok { 183 if value != localValue { 184 var confirm string 185 fmt.Printf("%s: overwrite %s with %s? (y/N) ", key, localValue, value) 186 187 fmt.Scanln(&confirm) 188 189 if strings.ToLower(confirm) == "y" { 190 configMap[key] = value 191 } 192 } 193 } else { 194 configMap[key] = value 195 } 196 } 197 198 return ioutil.WriteFile(filename, []byte(formatConfig(configMap)), 0755) 199 } 200 201 return ioutil.WriteFile(filename, []byte(formatConfig(configVars.Values)), 0755) 202 } 203 204 // ConfigPush pushes an app's config from a file. 205 func ConfigPush(appID string, fileName string) error { 206 contents, err := ioutil.ReadFile(fileName) 207 208 if err != nil { 209 return err 210 } 211 212 config := strings.Split(string(contents), "\n") 213 return ConfigSet(appID, config[:len(config)-1]) 214 } 215 216 func parseConfig(configVars []string) map[string]interface{} { 217 configMap := make(map[string]interface{}) 218 219 regex := regexp.MustCompile(`^([A-z_]+[A-z0-9_]*)=([\s\S]+)$`) 220 for _, config := range configVars { 221 if regex.MatchString(config) { 222 captures := regex.FindStringSubmatch(config) 223 configMap[captures[1]] = captures[2] 224 } else { 225 fmt.Printf("'%s' does not match the pattern 'key=var', ex: MODE=test\n", config) 226 } 227 } 228 229 return configMap 230 } 231 232 func formatConfig(configVars map[string]interface{}) string { 233 var formattedConfig string 234 235 for key, value := range configVars { 236 formattedConfig += fmt.Sprintf("%s=%s\n", key, value) 237 } 238 239 return formattedConfig 240 }