forked from pkallberg/cx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
env-vars.go
158 lines (137 loc) · 3.85 KB
/
env-vars.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package main
import (
"io"
"os"
"sort"
"text/tabwriter"
"github.com/cloud66/cloud66"
"github.com/cloud66/cli"
)
var cmdEnvVars = &Command{
Name: "env-vars",
Build: buildEnvVars,
Run: runEnvVars,
Short: "commands to work with environment variables",
NeedsStack: true,
}
func buildEnvVars() cli.Command {
base := buildBasicCommand()
base.Subcommands = []cli.Command{
cli.Command{
Name: "list",
Usage: "lists environement variables",
Action: runEnvVars,
Flags: []cli.Flag{
cli.BoolFlag{
Name: "history",
Usage: "show environment variable history",
},
},
Description: `Lists all the environement variables of the given stack.
The environment_variables options can be a list of multiple environment_variables as separate parameters.
To change environement variable values, use the env-vars-set command.
Examples:
$ cx env-vars list -s mystack
RAILS_ENV production
STACK_BASE /abc/def
STACK_PATH /abc/def/current
etc..
$ cx env-vars list -s mystack RAILS_ENV
RAILS_ENV production
$ cx env-vars list -s mystack RAILS_ENV STACK_BASE
RAILS_ENV production
STACK_BASE /abc/def
$ cx env-vars list -s mystack -history
RAILS_ENV production
STACK_BASE /abc/def
--> 2015-02-24 12:32:11 /xyz/123
--> 2015-03-12 15:54:08 /xyz/456
STACK_PATH /abc/def/current
$ cx env-vars list -s mystack -history STACK_BASE
STACK_BASE /abc/def
--> 2015-02-24 12:32:11 /xyz/123
--> 2015-03-12 15:54:08 /xyz/456
`,
},
cli.Command{
Name: "set",
Usage: "sets the value of an environment variable on a stack",
Action: runEnvVarsSet,
Description: `This sets and applies the value of an environment variable on a stack.
This work happens in the background, therefore this command will return immediately after the operation has started.
Warning! Applying environment variable changes to your stack will result in all your stack environment variables
being sent to your stack servers, and your processes being restarted immediately.
Examples:
$ cx env-vars set -s mystack FIRST_VAR=123
$ cx env-vars set -s mystack SECOND_ONE='this value has a space in it'
`,
},
}
return base
}
func runEnvVars(c *cli.Context) {
w := tabwriter.NewWriter(os.Stdout, 1, 2, 2, ' ', 0)
defer w.Flush()
var envVars []cloud66.StackEnvVar
var err error
stack := mustStack(c)
envVars, err = client.StackEnvVars(stack.Uid)
must(err)
envVarKeys := c.Args()
flagShowHistory := c.Bool("history")
sort.Strings(envVarKeys)
if len(envVarKeys) == 0 {
printEnvVarsList(w, envVars, flagShowHistory)
} else {
// filter out the unwanted env_vars
var filteredEnvVars []cloud66.StackEnvVar
for _, i := range envVars {
sorted := sort.SearchStrings(envVarKeys, i.Key)
if sorted < len(envVarKeys) && envVarKeys[sorted] == i.Key {
filteredEnvVars = append(filteredEnvVars, i)
}
}
printEnvVarsList(w, filteredEnvVars, flagShowHistory)
}
}
func printEnvVarsList(w io.Writer, envVars []cloud66.StackEnvVar, showHistory bool) {
sort.Sort(envVarsByName(envVars))
for _, a := range envVars {
if a.Key != "" {
listEnvVar(w, a, showHistory)
}
}
}
func listEnvVar(w io.Writer, a cloud66.StackEnvVar, showHistory bool) {
var readonly string
if a.Readonly {
readonly = "readonly"
} else {
readonly = "read/write"
}
listRec(w,
a.Key,
a.Value,
readonly,
)
if showHistory {
for _, h := range a.History {
listRec(w, "----->", h.Value, h.UpdatedAt)
}
}
}
type envVarsByName []cloud66.StackEnvVar
func (a envVarsByName) Len() int { return len(a) }
func (a envVarsByName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a envVarsByName) Less(i, j int) bool {
if a[i].Readonly == a[j].Readonly {
return a[i].Key < a[j].Key
}
return boolToInt(a[i].Readonly) > boolToInt(a[j].Readonly)
}
func boolToInt(b bool) int {
if b {
return 1
}
return 0
}