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