5
5
"fmt"
6
6
"net/http"
7
7
"os"
8
+ "regexp"
8
9
"strconv"
9
10
"strings"
10
11
"text/tabwriter"
@@ -21,7 +22,7 @@ type urlsCmd struct{}
21
22
type DevURL struct {
22
23
ID string `json:"id"`
23
24
URL string `json:"url"`
24
- Port string `json:"port"`
25
+ Port int `json:"port"`
25
26
Access string `json:"access"`
26
27
}
27
28
@@ -35,47 +36,52 @@ var urlAccessLevel = map[string]string{
35
36
36
37
func portIsValid (port string ) bool {
37
38
p , err := strconv .ParseUint (port , 10 , 16 )
38
- if p < 1 {
39
+ if p < 1 || p > 65535 {
39
40
// port 0 means 'any free port', which we don't support
40
41
err = strconv .ErrRange
41
42
}
42
43
if err != nil {
43
- fmt . Println ("Invalid port" )
44
+ flog . Error ("Invalid port" )
44
45
}
45
46
return err == nil
46
47
}
47
48
48
49
func accessLevelIsValid (level string ) bool {
49
50
_ , ok := urlAccessLevel [level ]
50
51
if ! ok {
51
- fmt . Println ("Invalid access level" )
52
+ flog . Error ("Invalid access level" )
52
53
}
53
54
return ok
54
55
}
55
56
56
57
type createSubCmd struct {
57
- access string
58
+ access string
59
+ urlname string
58
60
}
59
61
60
62
func (sub * createSubCmd ) RegisterFlags (fl * pflag.FlagSet ) {
61
63
fl .StringVarP (& sub .access , "access" , "a" , "private" , "[private | org | authed | public] set devurl access" )
64
+ fl .StringVarP (& sub .urlname , "name" , "n" , "" , "devurl name" )
62
65
}
63
66
64
67
func (sub createSubCmd ) Spec () cli.CommandSpec {
65
68
return cli.CommandSpec {
66
69
Name : "create" ,
67
- Usage : "<env name> <port> [--access <level>]" ,
70
+ Usage : "<env name> <port> [--access <level>] [--name <name>] " ,
68
71
Desc : "create/update a devurl for external access" ,
69
72
}
70
73
}
71
74
75
+ var devURLNameValidRx = regexp .MustCompile ("^[a-zA-Z][a-zA-Z0-9]{0,63}$" )
76
+
72
77
// Run creates or updates a devURL, specified by env ID and port
73
78
// (fl.Arg(0) and fl.Arg(1)), with access level (fl.Arg(2)) on
74
79
// the cemanager.
75
80
func (sub createSubCmd ) Run (fl * pflag.FlagSet ) {
76
81
envName := fl .Arg (0 )
77
82
port := fl .Arg (1 )
78
- access := fl .Arg (2 )
83
+ name := fl .Arg (2 )
84
+ access := fl .Arg (3 )
79
85
80
86
if envName == "" {
81
87
exitUsage (fl )
@@ -84,26 +90,35 @@ func (sub createSubCmd) Run(fl *pflag.FlagSet) {
84
90
if ! portIsValid (port ) {
85
91
exitUsage (fl )
86
92
}
93
+ portNum , _ := strconv .Atoi (port )
87
94
88
95
access = strings .ToUpper (sub .access )
89
96
if ! accessLevelIsValid (access ) {
90
97
exitUsage (fl )
91
98
}
92
99
100
+ name = sub .urlname
101
+ if name != "" && ! devURLNameValidRx .MatchString (name ) {
102
+ flog .Error ("update devurl: name must be < 64 chars in length, begin with a letter and only contain letters or digits." )
103
+ return
104
+ }
93
105
entClient := requireAuth ()
94
106
95
107
env := findEnv (entClient , envName )
96
108
97
- _ , found := devURLID (port , urlList (envName ))
109
+ found , urlID := devURLID (portNum , urlList (envName ))
98
110
if found {
99
- fmt .Printf ("Updating devurl for port %v\n " , port )
111
+ flog .Info ("Updating devurl for port %v" , port )
112
+ err := entClient .UpdateDevURL (env .ID , urlID , portNum , name , access )
113
+ if err != nil {
114
+ flog .Error ("update devurl: %s" , err .Error ())
115
+ }
100
116
} 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 ())
117
+ flog .Info ("Adding devurl for port %v" , port )
118
+ err := entClient .InsertDevURL (env .ID , portNum , name , access )
119
+ if err != nil {
120
+ flog .Error ("insert devurl: %s" , err .Error ())
121
+ }
107
122
}
108
123
}
109
124
@@ -117,15 +132,16 @@ func (sub delSubCmd) Spec() cli.CommandSpec {
117
132
}
118
133
}
119
134
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 ) {
135
+ // devURLID returns the ID of a devURL, given the env name and port
136
+ // from a list of DevURL records.
137
+ // (false, "") is returned if no match is found.
138
+ func devURLID (port int , urls []DevURL ) (bool , string ) {
123
139
for _ , url := range urls {
124
140
if url .Port == port {
125
- return url .ID , true
141
+ return true , url .ID
126
142
}
127
143
}
128
- return "" , false
144
+ return false , ""
129
145
}
130
146
131
147
// Run deletes a devURL, specified by env ID and port, from the cemanager.
@@ -140,14 +156,14 @@ func (sub delSubCmd) Run(fl *pflag.FlagSet) {
140
156
if ! portIsValid (port ) {
141
157
exitUsage (fl )
142
158
}
159
+ portNum , _ := strconv .Atoi (port )
143
160
144
161
entClient := requireAuth ()
145
-
146
162
env := findEnv (entClient , envName )
147
163
148
- urlID , found := devURLID (port , urlList (envName ))
164
+ found , urlID := devURLID (portNum , urlList (envName ))
149
165
if found {
150
- fmt . Printf ("Deleting devurl for port %v\n " , port )
166
+ flog . Info ("Deleting devurl for port %v" , port )
151
167
} else {
152
168
flog .Fatal ("No devurl found for port %v" , port )
153
169
}
@@ -193,7 +209,7 @@ func urlList(envName string) []DevURL {
193
209
}
194
210
195
211
if len (devURLs ) == 0 {
196
- fmt . Printf ("no dev urls were found for environment: %s\n " , envName )
212
+ flog . Error ("no dev urls were found for environment: %s" , envName )
197
213
}
198
214
199
215
return devURLs
@@ -207,7 +223,7 @@ func (cmd urlsCmd) Run(fl *pflag.FlagSet) {
207
223
208
224
w := tabwriter .NewWriter (os .Stdout , 0 , 0 , 1 , ' ' , tabwriter .TabIndent )
209
225
for _ , devURL := range devURLs {
210
- fmt .Fprintf (w , "%s\t %s \t %s\n " , devURL .URL , devURL .Port , devURL .Access )
226
+ fmt .Fprintf (w , "%s\t %d \t %s\n " , devURL .URL , devURL .Port , devURL .Access )
211
227
}
212
228
w .Flush ()
213
229
}
0 commit comments