Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.

Commit 3ced5b2

Browse files
author
Russtopia
committed
Add custom prefix devurl
1 parent 65fce15 commit 3ced5b2

File tree

6 files changed

+120
-53
lines changed

6 files changed

+120
-53
lines changed

cmd/coder/envs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ type envsCmd struct {
1414
func (cmd envsCmd) Spec() cli.CommandSpec {
1515
return cli.CommandSpec{
1616
Name: "envs",
17-
Desc: "get a list of active environment",
17+
Desc: "get a list of active environments",
1818
}
1919
}
2020

cmd/coder/sync.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func (cmd *syncCmd) RegisterFlags(fl *pflag.FlagSet) {
3434
}
3535

3636
// version returns local rsync protocol version as a string.
37-
func (_ *syncCmd) version() string {
37+
func (*syncCmd) version() string {
3838
cmd := exec.Command("rsync", "--version")
3939
out, err := cmd.CombinedOutput()
4040
if err != nil {
@@ -99,7 +99,7 @@ func (cmd *syncCmd) Run(fl *pflag.FlagSet) {
9999
if rsyncErr != nil {
100100
flog.Info("Unable to determine remote rsync version. Proceeding cautiously.")
101101
} else if localVersion != remoteVersion {
102-
flog.Fatal(fmt.Sprintf("rsync protocol mismatch. %s.", localVersion, rsyncErr))
102+
flog.Fatal(fmt.Sprintf("rsync protocol mismatch. %s (%v).", localVersion, rsyncErr))
103103
}
104104

105105
for err == nil || err == sync.ErrRestartSync {

cmd/coder/urls.go

Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"net/http"
77
"os"
8+
"regexp"
89
"strconv"
910
"strings"
1011
"text/tabwriter"
@@ -21,7 +22,7 @@ type urlsCmd struct{}
2122
type DevURL struct {
2223
ID string `json:"id"`
2324
URL string `json:"url"`
24-
Port string `json:"port"`
25+
Port int `json:"port"`
2526
Access string `json:"access"`
2627
}
2728

@@ -33,55 +34,68 @@ var urlAccessLevel = map[string]string{
3334
"PUBLIC": "Anyone on the internet can access this link",
3435
}
3536

36-
func portIsValid(port string) bool {
37+
func validatePort(port string) (int, error) {
3738
p, err := strconv.ParseUint(port, 10, 16)
39+
if err != nil {
40+
flog.Error("Invalid port")
41+
return 0, err
42+
}
3843
if p < 1 {
3944
// port 0 means 'any free port', which we don't support
4045
err = strconv.ErrRange
46+
flog.Error("Port must be > 0")
47+
return 0, err
4148
}
42-
if err != nil {
43-
fmt.Println("Invalid port")
44-
}
45-
return err == nil
49+
return int(p), nil
4650
}
4751

4852
func accessLevelIsValid(level string) bool {
4953
_, ok := urlAccessLevel[level]
5054
if !ok {
51-
fmt.Println("Invalid access level")
55+
flog.Error("Invalid access level")
5256
}
5357
return ok
5458
}
5559

5660
type createSubCmd struct {
57-
access string
61+
access string
62+
urlname string
5863
}
5964

6065
func (sub *createSubCmd) RegisterFlags(fl *pflag.FlagSet) {
6166
fl.StringVarP(&sub.access, "access", "a", "private", "[private | org | authed | public] set devurl access")
67+
fl.StringVarP(&sub.urlname, "name", "n", "", "devurl name")
6268
}
6369

6470
func (sub createSubCmd) Spec() cli.CommandSpec {
6571
return cli.CommandSpec{
66-
Name: "create",
67-
Usage: "<env name> <port> [--access <level>]",
68-
Desc: "create/update a devurl for external access",
72+
Name: "create",
73+
Usage: "<env name> <port> [--access <level>] [--name <name>]",
74+
Aliases: []string{"edit"},
75+
Desc: "create or update a devurl for external access",
6976
}
7077
}
7178

79+
// devURLNameValidRx is the regex used to validate devurl names specified
80+
// via the --name subcommand. Named devurls must begin with a letter, and
81+
// consist solely of letters and digits, with a max length of 64 chars.
82+
var devURLNameValidRx = regexp.MustCompile("^[a-zA-Z][a-zA-Z0-9]{0,63}$")
83+
7284
// Run creates or updates a devURL, specified by env ID and port
7385
// (fl.Arg(0) and fl.Arg(1)), with access level (fl.Arg(2)) on
7486
// the cemanager.
7587
func (sub createSubCmd) Run(fl *pflag.FlagSet) {
7688
envName := fl.Arg(0)
7789
port := fl.Arg(1)
78-
access := fl.Arg(2)
90+
name := fl.Arg(2)
91+
access := fl.Arg(3)
7992

8093
if envName == "" {
8194
exitUsage(fl)
8295
}
8396

84-
if !portIsValid(port) {
97+
portNum, err := validatePort(port)
98+
if err != nil {
8599
exitUsage(fl)
86100
}
87101

@@ -90,20 +104,28 @@ func (sub createSubCmd) Run(fl *pflag.FlagSet) {
90104
exitUsage(fl)
91105
}
92106

107+
name = sub.urlname
108+
if name != "" && !devURLNameValidRx.MatchString(name) {
109+
flog.Error("update devurl: name must be < 64 chars in length, begin with a letter and only contain letters or digits.")
110+
return
111+
}
93112
entClient := requireAuth()
94113

95114
env := findEnv(entClient, envName)
96115

97-
_, found := devURLID(port, urlList(envName))
116+
found, urlID := devURLID(portNum, urlList(envName))
98117
if found {
99-
fmt.Printf("Updating devurl for port %v\n", port)
118+
flog.Info("Updating devurl for port %v", port)
119+
err := entClient.UpdateDevURL(env.ID, urlID, portNum, name, access)
120+
if err != nil {
121+
flog.Error("update devurl: %s", err.Error())
122+
}
100123
} 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())
124+
flog.Info("Adding devurl for port %v", port)
125+
err := entClient.InsertDevURL(env.ID, portNum, name, access)
126+
if err != nil {
127+
flog.Error("insert devurl: %s", err.Error())
128+
}
107129
}
108130
}
109131

@@ -117,15 +139,16 @@ func (sub delSubCmd) Spec() cli.CommandSpec {
117139
}
118140
}
119141

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) {
142+
// devURLID returns the ID of a devURL, given the env name and port
143+
// from a list of DevURL records.
144+
// (false, "") is returned if no match is found.
145+
func devURLID(port int, urls []DevURL) (bool, string) {
123146
for _, url := range urls {
124147
if url.Port == port {
125-
return url.ID, true
148+
return true, url.ID
126149
}
127150
}
128-
return "", false
151+
return false, ""
129152
}
130153

131154
// Run deletes a devURL, specified by env ID and port, from the cemanager.
@@ -137,22 +160,22 @@ func (sub delSubCmd) Run(fl *pflag.FlagSet) {
137160
exitUsage(fl)
138161
}
139162

140-
if !portIsValid(port) {
163+
portNum, err := validatePort(port)
164+
if err != nil {
141165
exitUsage(fl)
142166
}
143167

144168
entClient := requireAuth()
145-
146169
env := findEnv(entClient, envName)
147170

148-
urlID, found := devURLID(port, urlList(envName))
171+
found, urlID := devURLID(portNum, urlList(envName))
149172
if found {
150-
fmt.Printf("Deleting devurl for port %v\n", port)
173+
flog.Info("Deleting devurl for port %v", port)
151174
} else {
152175
flog.Fatal("No devurl found for port %v", port)
153176
}
154177

155-
err := entClient.DelDevURL(env.ID, urlID)
178+
err = entClient.DelDevURL(env.ID, urlID)
156179
if err != nil {
157180
flog.Error("delete devurl: %s", err.Error())
158181
}
@@ -192,10 +215,6 @@ func urlList(envName string) []DevURL {
192215
flog.Fatal("%v", err)
193216
}
194217

195-
if len(devURLs) == 0 {
196-
fmt.Printf("no dev urls were found for environment: %s\n", envName)
197-
}
198-
199218
return devURLs
200219
}
201220

@@ -207,7 +226,7 @@ func (cmd urlsCmd) Run(fl *pflag.FlagSet) {
207226

208227
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', tabwriter.TabIndent)
209228
for _, devURL := range devURLs {
210-
fmt.Fprintf(w, "%s\t%s\t%s\n", devURL.URL, devURL.Port, devURL.Access)
229+
fmt.Fprintf(w, "%s\t%d\t%s\n", devURL.URL, devURL.Port, devURL.Access)
211230
}
212231
w.Flush()
213232
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ require (
1212
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4
1313
github.com/rjeczalik/notify v0.9.2
1414
github.com/spf13/pflag v1.0.5
15-
go.coder.com/cli v0.4.0
15+
go.coder.com/cli v0.5.0
1616
go.coder.com/flog v0.0.0-20190906214207-47dd47ea0512
1717
golang.org/x/crypto v0.0.0-20200422194213-44a606286825
1818
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
163163
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
164164
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
165165
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
166+
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
167+
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
166168
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
167169
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
168170
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
@@ -171,6 +173,8 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
171173
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
172174
go.coder.com/cli v0.4.0 h1:PruDGwm/CPFndyK/eMowZG3vzg5CgohRWeXWCTr3zi8=
173175
go.coder.com/cli v0.4.0/go.mod h1:hRTOURCR3LJF1FRW9arecgrzX+AHG7mfYMwThPIgq+w=
176+
go.coder.com/cli v0.5.0 h1:7W9ECtZdVKaAc0Oe2uk5J/c0LCtsWufQz4NeX6YwP0g=
177+
go.coder.com/cli v0.5.0/go.mod h1:h6091Eox0VdgJw2CDBvTyx7SnhduTm8qYM2bR2pewls=
174178
go.coder.com/flog v0.0.0-20190906214207-47dd47ea0512 h1:DjCS6dRQh+1PlfiBmnabxfdrzenb0tAwJqFxDEH/s9g=
175179
go.coder.com/flog v0.0.0-20190906214207-47dd47ea0512/go.mod h1:83JsYgXYv0EOaXjIMnaZ1Fl6ddNB3fJnDZ/8845mUJ8=
176180
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@@ -300,6 +304,8 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
300304
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
301305
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
302306
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
307+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
308+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
303309
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
304310
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
305311
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

internal/entclient/devurl.go

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,23 @@ package entclient
33
import (
44
"fmt"
55
"net/http"
6+
7+
"golang.org/x/xerrors"
68
)
79

10+
type delDevURLRequest struct {
11+
EnvID string `json:"environment_id"`
12+
DevURLID string `json:"url_id"`
13+
}
14+
15+
// DelDevURL deletes a devurl from the specified environment.
816
func (c Client) DelDevURL(envID, urlID string) error {
917
reqString := "/api/environments/%s/devurls/%s"
10-
reqUrl := fmt.Sprintf(reqString, envID, urlID)
18+
reqURL := fmt.Sprintf(reqString, envID, urlID)
1119

12-
res, err := c.request("DELETE", reqUrl, map[string]string{
13-
"environment_id": envID,
14-
"url_id": urlID,
20+
res, err := c.request("DELETE", reqURL, delDevURLRequest{
21+
EnvID: envID,
22+
DevURLID: urlID,
1523
})
1624
if err != nil {
1725
return err
@@ -24,22 +32,56 @@ func (c Client) DelDevURL(envID, urlID string) error {
2432
return nil
2533
}
2634

27-
func (c Client) UpsertDevURL(envID, port, access string) error {
35+
type createDevURLRequest struct {
36+
EnvID string `json:"environment_id"`
37+
Port int `json:"port"`
38+
Access string `json:"access"`
39+
Name string `json:"name"`
40+
}
41+
42+
// InsertDevURL inserts a new devurl into the specified environment.
43+
func (c Client) InsertDevURL(envID string, port int, name, access string) error {
2844
reqString := "/api/environments/%s/devurls"
29-
reqUrl := fmt.Sprintf(reqString, envID)
45+
reqURL := fmt.Sprintf(reqString, envID)
3046

31-
res, err := c.request("POST", reqUrl, map[string]string{
32-
"environment_id": envID,
33-
"port": port,
34-
"access": access,
47+
res, err := c.request("POST", reqURL, createDevURLRequest{
48+
EnvID: envID,
49+
Port: port,
50+
Access: access,
51+
Name: name,
3552
})
53+
if res != nil && res.StatusCode == http.StatusConflict {
54+
return xerrors.Errorf("Failed to create devurl. Check that the port and name are unique.")
55+
}
3656
if err != nil {
3757
return err
3858
}
59+
return nil
60+
}
3961

40-
if res.StatusCode != http.StatusOK {
41-
return bodyError(res)
42-
}
62+
type updateDevURLRequest struct {
63+
EnvID string `json:"environment_id"`
64+
Port int `json:"port"`
65+
Access string `json:"access"`
66+
Name string `json:"name"`
67+
}
4368

69+
// UpdateDevURL updates an existing devurl in the specified environment.
70+
func (c Client) UpdateDevURL(envID, urlID string, port int, name, access string) error {
71+
reqString := "/api/environments/%s/devurls/%s"
72+
reqURL := fmt.Sprintf(reqString, envID, urlID)
73+
74+
res, err := c.request("PUT", reqURL, updateDevURLRequest{
75+
EnvID: envID,
76+
Port: port,
77+
Access: access,
78+
Name: name,
79+
})
80+
if res != nil && res.StatusCode == http.StatusConflict {
81+
return xerrors.Errorf("Failed to update devurl. Check that the port and name are unique.")
82+
}
83+
if err != nil {
84+
return err
85+
}
4486
return nil
4587
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy