This repository was archived by the owner on Aug 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
Add custom prefix devurl #74
Merged
Merged
Changes from 1 commit
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
5d92778
Add custom prefix devurl
11f797a
Reverted err response
362ddc7
Enabled error response JSON body output
c71c3c9
Add urls ls subcmd; add -o [human | json] support matching users cmd
cc55a4a
Add future support for integration devurl tests
f50cfc0
Merge branch 'master' into 4411-coder-cli-named-devurls
1dc6c3b
use requireSuccess(); log.Fatal() where appropriate; change 'del' to …
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ import ( | |
"fmt" | ||
"net/http" | ||
"os" | ||
"regexp" | ||
"strconv" | ||
"strings" | ||
"text/tabwriter" | ||
|
@@ -21,7 +22,7 @@ type urlsCmd struct{} | |
type DevURL struct { | ||
ID string `json:"id"` | ||
URL string `json:"url"` | ||
Port string `json:"port"` | ||
Port int `json:"port"` | ||
Access string `json:"access"` | ||
} | ||
|
||
|
@@ -33,55 +34,68 @@ var urlAccessLevel = map[string]string{ | |
"PUBLIC": "Anyone on the internet can access this link", | ||
} | ||
|
||
func portIsValid(port string) bool { | ||
func validatePort(port string) (int, error) { | ||
p, err := strconv.ParseUint(port, 10, 16) | ||
if err != nil { | ||
flog.Error("Invalid port") | ||
return 0, err | ||
} | ||
if p < 1 { | ||
// port 0 means 'any free port', which we don't support | ||
err = strconv.ErrRange | ||
flog.Error("Port must be > 0") | ||
return 0, err | ||
} | ||
if err != nil { | ||
fmt.Println("Invalid port") | ||
} | ||
return err == nil | ||
return int(p), nil | ||
} | ||
|
||
func accessLevelIsValid(level string) bool { | ||
_, ok := urlAccessLevel[level] | ||
if !ok { | ||
fmt.Println("Invalid access level") | ||
flog.Error("Invalid access level") | ||
} | ||
return ok | ||
} | ||
|
||
type createSubCmd struct { | ||
access string | ||
access string | ||
urlname string | ||
} | ||
|
||
func (sub *createSubCmd) RegisterFlags(fl *pflag.FlagSet) { | ||
fl.StringVarP(&sub.access, "access", "a", "private", "[private | org | authed | public] set devurl access") | ||
fl.StringVarP(&sub.urlname, "name", "n", "", "devurl name") | ||
} | ||
|
||
func (sub createSubCmd) Spec() cli.CommandSpec { | ||
return cli.CommandSpec{ | ||
Name: "create", | ||
Usage: "<env name> <port> [--access <level>]", | ||
Desc: "create/update a devurl for external access", | ||
Name: "create", | ||
Usage: "<env name> <port> [--access <level>] [--name <name>]", | ||
Aliases: []string{"edit"}, | ||
Desc: "create or update a devurl for external access", | ||
} | ||
} | ||
|
||
// devURLNameValidRx is the regex used to validate devurl names specified | ||
// via the --name subcommand. Named devurls must begin with a letter, and | ||
// consist solely of letters and digits, with a max length of 64 chars. | ||
var devURLNameValidRx = regexp.MustCompile("^[a-zA-Z][a-zA-Z0-9]{0,63}$") | ||
Russtopia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Run creates or updates a devURL, specified by env ID and port | ||
// (fl.Arg(0) and fl.Arg(1)), with access level (fl.Arg(2)) on | ||
// the cemanager. | ||
func (sub createSubCmd) Run(fl *pflag.FlagSet) { | ||
envName := fl.Arg(0) | ||
port := fl.Arg(1) | ||
access := fl.Arg(2) | ||
name := fl.Arg(2) | ||
access := fl.Arg(3) | ||
|
||
if envName == "" { | ||
exitUsage(fl) | ||
} | ||
|
||
if !portIsValid(port) { | ||
portNum, err := validatePort(port) | ||
if err != nil { | ||
exitUsage(fl) | ||
} | ||
|
||
|
@@ -90,20 +104,28 @@ func (sub createSubCmd) Run(fl *pflag.FlagSet) { | |
exitUsage(fl) | ||
} | ||
|
||
name = sub.urlname | ||
if name != "" && !devURLNameValidRx.MatchString(name) { | ||
flog.Error("update devurl: name must be < 64 chars in length, begin with a letter and only contain letters or digits.") | ||
return | ||
Russtopia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
entClient := requireAuth() | ||
|
||
env := findEnv(entClient, envName) | ||
|
||
_, found := devURLID(port, urlList(envName)) | ||
urlID, found := devURLID(portNum, urlList(envName)) | ||
if found { | ||
fmt.Printf("Updating devurl for port %v\n", port) | ||
flog.Info("Updating devurl for port %v", port) | ||
err := entClient.UpdateDevURL(env.ID, urlID, portNum, name, access) | ||
if err != nil { | ||
flog.Error("update devurl: %s", err.Error()) | ||
Russtopia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} else { | ||
fmt.Printf("Adding devurl for port %v\n", port) | ||
} | ||
|
||
err := entClient.UpsertDevURL(env.ID, port, access) | ||
if err != nil { | ||
flog.Error("upsert devurl: %s", err.Error()) | ||
flog.Info("Adding devurl for port %v", port) | ||
err := entClient.InsertDevURL(env.ID, portNum, name, access) | ||
if err != nil { | ||
flog.Error("insert devurl: %s", err.Error()) | ||
Russtopia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
} | ||
|
||
|
@@ -117,9 +139,10 @@ func (sub delSubCmd) Spec() cli.CommandSpec { | |
} | ||
} | ||
|
||
// devURLID returns the ID of a devURL, given the env name and port. | ||
// devURLID returns the ID of a devURL, given the env name and port | ||
// from a list of DevURL records. | ||
// ("", false) is returned if no match is found. | ||
func devURLID(port string, urls []DevURL) (string, bool) { | ||
func devURLID(port int, urls []DevURL) (string, bool) { | ||
for _, url := range urls { | ||
if url.Port == port { | ||
return url.ID, true | ||
|
@@ -137,22 +160,22 @@ func (sub delSubCmd) Run(fl *pflag.FlagSet) { | |
exitUsage(fl) | ||
} | ||
|
||
if !portIsValid(port) { | ||
portNum, err := validatePort(port) | ||
if err != nil { | ||
exitUsage(fl) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's your preference on exit/fatal from 'helper' funcs? Current way here prints out usage and exits with nonzero status which is what we'd want, I guess. If I tucked in the |
||
|
||
entClient := requireAuth() | ||
|
||
env := findEnv(entClient, envName) | ||
|
||
urlID, found := devURLID(port, urlList(envName)) | ||
urlID, found := devURLID(portNum, urlList(envName)) | ||
if found { | ||
fmt.Printf("Deleting devurl for port %v\n", port) | ||
flog.Info("Deleting devurl for port %v", port) | ||
} else { | ||
flog.Fatal("No devurl found for port %v", port) | ||
} | ||
|
||
err := entClient.DelDevURL(env.ID, urlID) | ||
err = entClient.DelDevURL(env.ID, urlID) | ||
if err != nil { | ||
flog.Error("delete devurl: %s", err.Error()) | ||
Russtopia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
@@ -192,10 +215,6 @@ func urlList(envName string) []DevURL { | |
flog.Fatal("%v", err) | ||
} | ||
|
||
if len(devURLs) == 0 { | ||
fmt.Printf("no dev urls were found for environment: %s\n", envName) | ||
} | ||
|
||
Russtopia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return devURLs | ||
} | ||
|
||
|
@@ -207,7 +226,7 @@ func (cmd urlsCmd) Run(fl *pflag.FlagSet) { | |
|
||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', tabwriter.TabIndent) | ||
for _, devURL := range devURLs { | ||
fmt.Fprintf(w, "%s\t%s\t%s\n", devURL.URL, devURL.Port, devURL.Access) | ||
fmt.Fprintf(w, "%s\t%d\t%s\n", devURL.URL, devURL.Port, devURL.Access) | ||
} | ||
w.Flush() | ||
} | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.