feat: show listening ports in port forward popup (#4389)

* feat: show listening ports in port forward popup

* Move fetch logic to a machine

* feat: don't show  app ports and common non-HTTP ports

Co-authored-by: Bruno Quaresma <bruno@coder.com>
This commit is contained in:
Dean Sheather
2022-10-12 01:10:02 +10:00
committed by GitHub
co-authored by Bruno Quaresma
parent a64731eea5
commit b1a095e486
7 changed files with 458 additions and 96 deletions
+54
View File
@@ -9,6 +9,7 @@ import (
"net"
"net/http"
"net/netip"
"net/url"
"reflect"
"strconv"
"strings"
@@ -262,6 +263,59 @@ func (api *API) workspaceAgentListeningPorts(rw http.ResponseWriter, r *http.Req
return
}
// Get a list of ports that are in-use by applications.
apps, err := api.Database.GetWorkspaceAppsByAgentID(ctx, workspaceAgent.ID)
if xerrors.Is(err, sql.ErrNoRows) {
apps = []database.WorkspaceApp{}
err = nil
}
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error fetching workspace apps.",
Detail: err.Error(),
})
return
}
appPorts := make(map[uint16]struct{}, len(apps))
for _, app := range apps {
if !app.Url.Valid || app.Url.String == "" {
continue
}
u, err := url.Parse(app.Url.String)
if err != nil {
continue
}
port := u.Port()
if port == "" {
continue
}
portNum, err := strconv.Atoi(port)
if err != nil {
continue
}
if portNum < 1 || portNum > 65535 {
continue
}
appPorts[uint16(portNum)] = struct{}{}
}
// Filter out ports that are globally blocked, in-use by applications, or
// common non-HTTP ports such as databases, FTP, SSH, etc.
filteredPorts := make([]codersdk.ListeningPort, 0, len(portsResponse.Ports))
for _, port := range portsResponse.Ports {
if port.Port < uint16(codersdk.MinimumListeningPort) {
continue
}
if _, ok := appPorts[port.Port]; ok {
continue
}
if _, ok := codersdk.IgnoredListeningPorts[port.Port]; ok {
continue
}
filteredPorts = append(filteredPorts, port)
}
portsResponse.Ports = filteredPorts
httpapi.Write(ctx, rw, http.StatusOK, portsResponse)
}