github.com/henvic/wedeploycli@v1.7.6-0.20200319005353-3630f582f284/command/env-var/internal/commands/commands.go (about) 1 package commands 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "os" 8 "sort" 9 "strconv" 10 "strings" 11 12 "github.com/hashicorp/errwrap" 13 "github.com/henvic/wedeploycli/cmdflagsfromhost" 14 "github.com/henvic/wedeploycli/color" 15 "github.com/henvic/wedeploycli/command/internal/we" 16 "github.com/henvic/wedeploycli/fancy" 17 "github.com/henvic/wedeploycli/isterm" 18 "github.com/henvic/wedeploycli/list" 19 "github.com/henvic/wedeploycli/services" 20 ) 21 22 // ErrNoEnvToAdd is used when there is no environment varaible to add 23 var ErrNoEnvToAdd = errors.New("no environment variable to add") 24 25 // Command for environment variables 26 type Command struct { 27 SetupHost cmdflagsfromhost.SetupHost 28 ServicesClient *services.Client 29 30 Envs []services.EnvironmentVariable 31 32 SkipPrompt bool 33 } 34 35 func has(filterEnvKeys []string, key string) bool { 36 if len(filterEnvKeys) == 0 { 37 return true 38 } 39 40 for _, f := range filterEnvKeys { 41 if f == key { 42 return true 43 } 44 } 45 46 return false 47 } 48 49 // Show environment variables 50 func (c *Command) Show(ctx context.Context, filterEnvKeys ...string) error { 51 c.Envs = []services.EnvironmentVariable{} 52 53 var l = list.New(list.Filter{ 54 Project: c.SetupHost.Project(), 55 Services: []string{c.SetupHost.Service()}, 56 }) 57 58 if err := l.Once(ctx, we.Context()); err != nil { 59 return err 60 } 61 62 var envs, err = c.ServicesClient.GetEnvironmentVariables(ctx, 63 c.SetupHost.Project(), 64 c.SetupHost.Service()) 65 66 if err != nil { 67 return err 68 } 69 70 for _, e := range envs { 71 if !has(filterEnvKeys, e.Name) { 72 continue 73 } 74 75 c.Envs = append(c.Envs, services.EnvironmentVariable{ 76 Name: e.Name, 77 Value: e.Value, 78 }) 79 } 80 81 if len(c.Envs) == 0 { 82 _, _ = fmt.Fprintf(os.Stderr, "No environment variable found.\n") 83 return nil 84 } 85 86 sort.Slice(c.Envs, func(i, j int) bool { 87 return c.Envs[i].Name < c.Envs[j].Name 88 }) 89 90 fmt.Printf("%s\t%s\t%s\n", 91 color.Format(color.FgHiBlack, "#"), 92 color.Format(color.FgHiBlack, "Key"), 93 color.Format(color.FgHiBlack, "Value")) 94 95 for c, v := range c.Envs { 96 fmt.Printf("%d\t%s\t%s\n", c+1, v.Name, v.Value) 97 } 98 99 return nil 100 } 101 102 // Add environment variables 103 func (c *Command) Add(ctx context.Context, args []string) error { 104 var envs, err = c.getAddEnvs(args) 105 106 if err != nil { 107 return err 108 } 109 110 for _, env := range envs { 111 err = c.ServicesClient.SetEnvironmentVariable(ctx, c.SetupHost.Project(), c.SetupHost.Service(), env.Name, env.Value) 112 113 if err != nil { 114 return errwrap.Wrapf("can't add \""+env.Name+"\": {{err}}", err) 115 } 116 117 fmt.Printf("Environment variable \"%v\" added.\n", env.Name) 118 } 119 120 return nil 121 } 122 123 // Replace environment variables 124 func (c *Command) Replace(ctx context.Context, args []string) error { 125 var envs, err = c.getAddEnvs(args) 126 127 if err != nil && err != ErrNoEnvToAdd { 128 return err 129 } 130 131 if err = c.ServicesClient.SetEnvironmentVariables(ctx, c.SetupHost.Project(), c.SetupHost.Service(), envs); err != nil { 132 return err 133 } 134 135 for _, env := range envs { 136 fmt.Printf("Environment variable \"%v\" added.\n", env.Name) 137 } 138 139 return nil 140 } 141 142 func (c *Command) getAddEnvs(args []string) (envs []services.EnvironmentVariable, err error) { 143 args = filterEmptyEnvValues(args) 144 145 if len(args) == 0 && !c.SkipPrompt && isterm.Check() { 146 fmt.Println(fancy.Question("Type environment variables for \"" + c.SetupHost.Host() + "\" (e.g., A=1 B=2 C=3)")) 147 var argss string 148 argss, err = fancy.Prompt() 149 150 if err != nil { 151 return nil, err 152 } 153 154 args = strings.Split(argss, " ") 155 } 156 157 if strings.Join(args, "") == "" { 158 return envs, ErrNoEnvToAdd 159 } 160 161 return splitEnvKeyValueParameters(args) 162 } 163 164 func splitEnvKeyValueParameters(args []string) (envs []services.EnvironmentVariable, err error) { 165 if len(args) == 2 && !strings.Contains(args[0], "=") && !strings.Contains(args[1], "=") { 166 envs = append(envs, services.EnvironmentVariable{ 167 Name: args[0], 168 Value: args[1], 169 }) 170 171 return envs, nil 172 } 173 174 for _, v := range args { 175 var kv = strings.SplitN(v, "=", 2) 176 177 if len(kv) != 2 { 178 return nil, fmt.Errorf("invalid environment variable key/value pair: \"%s\"", v) 179 } 180 181 envs = append(envs, services.EnvironmentVariable{ 182 Name: kv[0], 183 Value: kv[1], 184 }) 185 } 186 187 return envs, nil 188 } 189 190 // Delete environment variables 191 func (c *Command) Delete(ctx context.Context, args []string) error { 192 var envs, err = c.getDeleteEnvKeys(args) 193 194 if err != nil { 195 return err 196 } 197 198 for _, env := range envs { 199 err := c.ServicesClient.UnsetEnvironmentVariable(ctx, c.SetupHost.Project(), c.SetupHost.Service(), env) 200 201 if err != nil { 202 return err 203 } 204 205 fmt.Printf("Environment variable \"%s\" deleted.\n", env) 206 } 207 208 return nil 209 } 210 211 func (c *Command) getDeleteEnvKeys(args []string) ([]string, error) { 212 if len(args) != 0 { 213 return args, nil 214 } 215 216 fmt.Println(fancy.Question("Select a environment variable # or name to delete from \"" + c.SetupHost.Host() + "\"")) 217 var envss, err = fancy.Prompt() 218 219 if err != nil { 220 return []string{}, err 221 } 222 223 var envs = strings.Split(envss, " ") 224 225 for index, env := range envs { 226 e := c.getEnvKeyOrOption(env) 227 228 if e != env { 229 envs[index] = e 230 } 231 } 232 233 return filterEmptyEnvValues(envs), nil 234 } 235 236 func (c *Command) getEnvKeyOrOption(answer string) string { 237 for _, e := range c.Envs { 238 if answer == e.Name { 239 return e.Name 240 } 241 } 242 243 switch num, err := strconv.Atoi(answer); { 244 case err != nil || num < 1 || num > len(c.Envs): 245 return answer 246 default: 247 return c.Envs[num-1].Name 248 } 249 } 250 251 func filterEmptyEnvValues(envKeys []string) []string { 252 var filtered []string 253 254 for _, e := range envKeys { 255 if e != "" { 256 filtered = append(filtered, e) 257 } 258 } 259 260 return filtered 261 }