5
5
"fmt"
6
6
"net/http"
7
7
"os"
8
+ "strconv"
9
+ "strings"
8
10
"text/tabwriter"
9
11
10
12
"github.com/spf13/pflag"
@@ -14,36 +16,163 @@ import (
14
16
)
15
17
16
18
type urlsCmd struct {}
19
+ type createSubCmd struct {
20
+ access string
21
+ }
22
+ type delSubCmd struct {}
17
23
24
+ // DevURL is the parsed json response record for a devURL from cemanager
18
25
type DevURL struct {
26
+ ID string `json:"id"`
19
27
URL string `json:"url"`
20
28
Port string `json:"port"`
21
29
Access string `json:"access"`
22
30
}
23
31
24
- func (cmd urlsCmd ) Spec () cli.CommandSpec {
32
+ var urlAccessLevel = map [string ]string {
33
+ //Remote API endpoint requires these in uppercase
34
+ "PRIVATE" : "Only you can access" ,
35
+ "ORG" : "All members of your organization can access" ,
36
+ "AUTHED" : "Authenticated users can access" ,
37
+ "PUBLIC" : "Anyone on the internet can access this link" ,
38
+ }
39
+
40
+ func portIsValid (port string ) bool {
41
+ p , err := strconv .ParseUint (port , 10 , 16 )
42
+ if p < 1 {
43
+ // port 0 means 'any free port', which we don't support
44
+ err = strconv .ErrRange
45
+ }
46
+ if err != nil {
47
+ fmt .Println ("bad port" )
48
+ }
49
+ return err == nil
50
+ }
51
+
52
+ func accessLevelIsValid (level string ) bool {
53
+ _ , ok := urlAccessLevel [level ]
54
+ if ! ok {
55
+ fmt .Println ("Invalid access level" )
56
+ }
57
+ return ok
58
+ }
59
+
60
+ func (sub * createSubCmd ) RegisterFlags (fl * pflag.FlagSet ) {
61
+ fl .StringVar (& sub .access , "a" , "private" , "[private | org | authed | public] set devurl access" )
62
+ }
63
+
64
+ func (sub createSubCmd ) Spec () cli.CommandSpec {
25
65
return cli.CommandSpec {
26
- Name : "urls " ,
27
- Usage : "<env name>" ,
28
- Desc : "get all development urls for external access" ,
66
+ Name : "create " ,
67
+ Usage : "<env name> <port> [--a access] " ,
68
+ Desc : "create/update a devurl for external access" ,
29
69
}
30
70
}
31
71
32
- func (cmd urlsCmd ) Run (fl * pflag.FlagSet ) {
33
- var envName = fl .Arg (0 )
72
+ // Run creates or updates a devURL, specified by env ID and port
73
+ // (fl.Arg(0) and fl.Arg(1)), with access level (fl.Arg(2)) on
74
+ // the cemanager.
75
+ func (sub createSubCmd ) Run (fl * pflag.FlagSet ) {
76
+ envName := fl .Arg (0 )
77
+ port := fl .Arg (1 )
78
+ access := fl .Arg (2 )
34
79
35
80
if envName == "" {
36
81
exitUsage (fl )
37
82
}
38
83
84
+ if ! portIsValid (port ) {
85
+ exitUsage (fl )
86
+ }
87
+
88
+ access = strings .ToUpper (sub .access )
89
+ if ! accessLevelIsValid (access ) {
90
+ exitUsage (fl )
91
+ }
92
+
39
93
entClient := requireAuth ()
40
94
41
95
env := findEnv (entClient , envName )
42
96
97
+ _ , found := devURLID (port , urlList (envName ))
98
+ if found {
99
+ fmt .Printf ("Updating devurl for port %v\n " , port )
100
+ } else {
101
+ fmt .Printf ("Adding devurl for port %v\n " , port )
102
+ }
103
+
104
+ err := entClient .UpsertDevURL (env .ID , port , access )
105
+ if err != nil {
106
+ flog .Error ("upsert devurl: %s" , err .Error ())
107
+ }
108
+ }
109
+
110
+ func (sub delSubCmd ) Spec () cli.CommandSpec {
111
+ return cli.CommandSpec {
112
+ Name : "del" ,
113
+ Usage : "<env name> <port>" ,
114
+ Desc : "delete a devurl" ,
115
+ }
116
+ }
117
+
118
+ // devURLID returns the ID of a devURL, given the env name and port.
119
+ // ("", false) is returned if no match is found.
120
+ func devURLID (port string , urls []DevURL ) (string , bool ) {
121
+ for _ , url := range urls {
122
+ if url .Port == port {
123
+ return url .ID , true
124
+ }
125
+ }
126
+ return "" , false
127
+ }
128
+
129
+ // Run deletes a devURL, specified by env ID and port, from the cemanager.
130
+ func (sub delSubCmd ) Run (fl * pflag.FlagSet ) {
131
+ envName := fl .Arg (0 )
132
+ port := fl .Arg (1 )
133
+
134
+ if envName == "" {
135
+ exitUsage (fl )
136
+ }
137
+
138
+ if ! portIsValid (port ) {
139
+ exitUsage (fl )
140
+ }
141
+
142
+ entClient := requireAuth ()
143
+
144
+ env := findEnv (entClient , envName )
145
+
146
+ urlID , found := devURLID (port , urlList (envName ))
147
+ if found {
148
+ fmt .Printf ("Deleting devurl for port %v\n " , port )
149
+ } else {
150
+ flog .Fatal ("No devurl found for port %v" , port )
151
+ }
152
+
153
+ err := entClient .DelDevURL (env .ID , urlID )
154
+ if err != nil {
155
+ flog .Error ("delete devurl: %s" , err .Error ())
156
+ }
157
+ }
158
+
159
+ func (cmd urlsCmd ) Spec () cli.CommandSpec {
160
+ return cli.CommandSpec {
161
+ Name : "urls" ,
162
+ Usage : "<env name>" ,
163
+ Desc : "get all development urls for external access" ,
164
+ }
165
+ }
166
+
167
+ // urlList returns the list of active devURLs from the cemanager.
168
+ func urlList (envName string ) []DevURL {
169
+ entClient := requireAuth ()
170
+ env := findEnv (entClient , envName )
171
+
43
172
reqString := "%s/api/environments/%s/devurls?session_token=%s"
44
- reqUrl := fmt .Sprintf (reqString , entClient .BaseURL , env .ID , entClient .Token )
173
+ reqURL := fmt .Sprintf (reqString , entClient .BaseURL , env .ID , entClient .Token )
45
174
46
- resp , err := http .Get (reqUrl )
175
+ resp , err := http .Get (reqURL )
47
176
if err != nil {
48
177
flog .Fatal ("%v" , err )
49
178
}
@@ -55,7 +184,7 @@ func (cmd urlsCmd) Run(fl *pflag.FlagSet) {
55
184
56
185
dec := json .NewDecoder (resp .Body )
57
186
58
- var devURLs = make ([]DevURL , 0 )
187
+ devURLs : = make ([]DevURL , 0 )
59
188
err = dec .Decode (& devURLs )
60
189
if err != nil {
61
190
flog .Fatal ("%v" , err )
@@ -65,9 +194,25 @@ func (cmd urlsCmd) Run(fl *pflag.FlagSet) {
65
194
fmt .Printf ("no dev urls were found for environment: %s\n " , envName )
66
195
}
67
196
197
+ return devURLs
198
+ }
199
+
200
+ // Run gets the list of active devURLs from the cemanager for the
201
+ // specified environment and outputs info to stdout.
202
+ func (cmd urlsCmd ) Run (fl * pflag.FlagSet ) {
203
+ envName := fl .Arg (0 )
204
+ devURLs := urlList (envName )
205
+
68
206
w := tabwriter .NewWriter (os .Stdout , 0 , 0 , 1 , ' ' , tabwriter .TabIndent )
69
207
for _ , devURL := range devURLs {
70
208
fmt .Fprintf (w , "%s\t %s\t %s\n " , devURL .URL , devURL .Port , devURL .Access )
71
209
}
72
210
w .Flush ()
73
211
}
212
+
213
+ func (cmd * urlsCmd ) Subcommands () []cli.Command {
214
+ return []cli.Command {
215
+ & createSubCmd {},
216
+ & delSubCmd {},
217
+ }
218
+ }
0 commit comments