feat: handle port forward subdomain conflict
This commit is contained in:
@@ -5,7 +5,7 @@ import "fmt"
|
||||
type APIError struct {
|
||||
StatusCode int `json:"-"`
|
||||
Code string `json:"code"`
|
||||
Message string `json:"error"`
|
||||
Message string `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
func New(status int, code, message string) *APIError {
|
||||
|
5
internal/reverseproxy/errors.go
Normal file
5
internal/reverseproxy/errors.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package reverseproxy
|
||||
|
||||
import "errors"
|
||||
|
||||
var ErrPortMappingConflict = errors.New("port mapping conflict")
|
@@ -43,9 +43,14 @@ func (p *ReverseProxy) Middleware() echo.MiddlewareFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *ReverseProxy) AddEntry(subdomain string, url *url.URL) {
|
||||
func (p *ReverseProxy) AddEntry(subdomain string, url *url.URL) error {
|
||||
_, ok := p.httpProxies[subdomain]
|
||||
if ok {
|
||||
return ErrPortMappingConflict
|
||||
}
|
||||
proxy := httputil.NewSingleHostReverseProxy(url)
|
||||
p.httpProxies[subdomain] = proxy
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *ReverseProxy) RemoveEntry(subdomain string) {
|
||||
|
@@ -1,9 +1,19 @@
|
||||
package workspace
|
||||
|
||||
import "strings"
|
||||
|
||||
type errWorkspaceExists struct {
|
||||
message string
|
||||
}
|
||||
|
||||
type errPortMappingConflicts struct {
|
||||
conflicts []string
|
||||
}
|
||||
|
||||
func (err *errWorkspaceExists) Error() string {
|
||||
return err.message
|
||||
}
|
||||
|
||||
func (err *errPortMappingConflicts) Error() string {
|
||||
return "Subdomain(s) already in use: " + strings.Join(err.conflicts, ", ")
|
||||
}
|
||||
|
@@ -126,6 +126,10 @@ func updateWorkspace(c echo.Context, workspace *workspace) error {
|
||||
|
||||
if len(body.PortMappings) > 0 {
|
||||
if err = mgr.addPortMappings(ctx, workspace, body.PortMappings); err != nil {
|
||||
var errPortMappingConflicts *errPortMappingConflicts
|
||||
if errors.As(err, &errPortMappingConflicts) {
|
||||
return apierror.New(http.StatusConflict, "PORT_MAPPINGS_EXIST", err.Error())
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@@ -347,9 +347,23 @@ func (mgr workspaceManager) addPortMappings(ctx context.Context, workspace *work
|
||||
return err
|
||||
}
|
||||
|
||||
var conflictErr errPortMappingConflicts
|
||||
|
||||
for i := range portMappings {
|
||||
portMappings[i].WorkspaceID = workspace.ID
|
||||
mgr.reverseProxy.AddEntry(portMappings[i].Subdomain, urls[i])
|
||||
err = mgr.reverseProxy.AddEntry(portMappings[i].Subdomain, urls[i])
|
||||
if err != nil {
|
||||
if errors.Is(err, reverseproxy.ErrPortMappingConflict) {
|
||||
conflictErr.conflicts = append(conflictErr.conflicts, portMappings[i].Subdomain)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
portMappings[i].WorkspaceID = workspace.ID
|
||||
}
|
||||
}
|
||||
|
||||
if len(conflictErr.conflicts) > 0 {
|
||||
return &conflictErr
|
||||
}
|
||||
|
||||
_, err = tx.NewInsert().Model(&portMappings).Exec(ctx)
|
||||
|
Reference in New Issue
Block a user