Thanks to visit codestin.com
Credit goes to github.com

Skip to content

refactor: generate application URLs on backend side #9617

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions cli/vscodessh.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ func (r *RootCmd) vscodeSSH() *clibase.Cmd {
cmd := &clibase.Cmd{
// A SSH config entry is added by the VS Code extension that
// passes %h to ProxyCommand. The prefix of `coder-vscode--`
// is a magical string represented in our VS Cod extension.
// is a magical string represented in our VS Code extension.
// It's not important here, only the delimiter `--` is.
Use: "vscodessh <coder-vscode--<owner>-<workspace>-<agent?>>",
Use: "vscodessh <coder-vscode--<owner>--<workspace>--<agent?>>",
Hidden: true,
Middleware: clibase.RequireNArgs(1),
Handler: func(inv *clibase.Invocation) error {
Expand Down Expand Up @@ -93,7 +93,7 @@ func (r *RootCmd) vscodeSSH() *clibase.Cmd {

parts := strings.Split(inv.Args[0], "--")
if len(parts) < 3 {
return xerrors.Errorf("invalid argument format. must be: coder-vscode--<owner>-<name>-<agent?>")
return xerrors.Errorf("invalid argument format. must be: coder-vscode--<owner>--<name>--<agent?>")
}
owner := parts[1]
name := parts[2]
Expand Down
10 changes: 9 additions & 1 deletion coderd/httpapi/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,15 @@ type ApplicationURL struct {
// String returns the application URL hostname without scheme. You will likely
// want to append a period and the base hostname.
func (a ApplicationURL) String() string {
return fmt.Sprintf("%s--%s--%s--%s", a.AppSlugOrPort, a.AgentName, a.WorkspaceName, a.Username)
var appURL strings.Builder
_, _ = appURL.WriteString(a.AppSlugOrPort)
_, _ = appURL.WriteString("--")
_, _ = appURL.WriteString(a.AgentName)
_, _ = appURL.WriteString("--")
_, _ = appURL.WriteString(a.WorkspaceName)
_, _ = appURL.WriteString("--")
_, _ = appURL.WriteString(a.Username)
return appURL.String()
}

// ParseSubdomainAppURL parses an ApplicationURL from the given subdomain. If
Expand Down
15 changes: 8 additions & 7 deletions coderd/workspaceagents.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,14 @@ func (api *API) workspaceAgentManifest(rw http.ResponseWriter, r *http.Request)
return
}

vscodeProxyURI := strings.ReplaceAll(api.AppHostname, "*",
fmt.Sprintf("%s://{{port}}--%s--%s--%s",
api.AccessURL.Scheme,
workspaceAgent.Name,
workspace.Name,
owner.Username,
))
appHost := httpapi.ApplicationURL{
AppSlugOrPort: "{{port}}",
AgentName: workspaceAgent.Name,
WorkspaceName: workspace.Name,
Username: owner.Username,
}
vscodeProxyURI := api.AccessURL.Scheme + "://" + strings.ReplaceAll(api.AppHostname, "*", appHost.String())

if api.AccessURL.Port() != "" {
vscodeProxyURI += fmt.Sprintf(":%s", api.AccessURL.Port())
}
Expand Down
26 changes: 16 additions & 10 deletions coderd/workspaceapps/apptest/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/v2/agent"
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/workspaceapps"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/codersdk/agentsdk"
Expand Down Expand Up @@ -141,10 +142,14 @@ func (d *Details) PathAppURL(app App) *url.URL {

// SubdomainAppURL returns the URL for the given subdomain app.
func (d *Details) SubdomainAppURL(app App) *url.URL {
host := fmt.Sprintf("%s--%s--%s--%s", app.AppSlugOrPort, app.AgentName, app.WorkspaceName, app.Username)

appHost := httpapi.ApplicationURL{
AppSlugOrPort: app.AppSlugOrPort,
AgentName: app.AgentName,
WorkspaceName: app.WorkspaceName,
Username: app.Username,
}
u := *d.PathAppBaseURL
u.Host = strings.Replace(d.Options.AppHost, "*", host, 1)
u.Host = strings.Replace(d.Options.AppHost, "*", appHost.String(), 1)
u.Path = "/"
u.RawQuery = app.Query
return &u
Expand Down Expand Up @@ -355,13 +360,14 @@ func createWorkspaceWithApps(t *testing.T, client *codersdk.Client, orgID uuid.U
if primaryAppHost.Host != "" {
manifest, err := agentClient.Manifest(appHostCtx)
require.NoError(t, err)
proxyURL := fmt.Sprintf(
"http://{{port}}--%s--%s--%s%s",
proxyTestAgentName,
workspace.Name,
me.Username,
strings.ReplaceAll(primaryAppHost.Host, "*", ""),
)

appHost := httpapi.ApplicationURL{
AppSlugOrPort: "{{port}}",
AgentName: proxyTestAgentName,
WorkspaceName: workspace.Name,
Username: me.Username,
}
proxyURL := "http://" + appHost.String() + strings.ReplaceAll(primaryAppHost.Host, "*", "")
require.Equal(t, proxyURL, manifest.VSCodePortProxyURI)
}
agentCloser := agent.New(agent.Options{
Expand Down
10 changes: 8 additions & 2 deletions coderd/workspaceapps/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/v2/agent"
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/workspaceapps"
"github.com/coder/coder/v2/codersdk"
Expand Down Expand Up @@ -760,8 +761,13 @@ func Test_ResolveRequest(t *testing.T) {
redirectURI, err := url.Parse(redirectURIStr)
require.NoError(t, err)

appHost := fmt.Sprintf("%s--%s--%s--%s", req.AppSlugOrPort, req.AgentNameOrID, req.WorkspaceNameOrID, req.UsernameOrID)
host := strings.Replace(api.AppHostname, "*", appHost, 1)
appHost := httpapi.ApplicationURL{
AppSlugOrPort: req.AppSlugOrPort,
AgentName: req.AgentNameOrID,
WorkspaceName: req.WorkspaceNameOrID,
Username: req.UsernameOrID,
}
host := strings.Replace(api.AppHostname, "*", appHost.String(), 1)

require.Equal(t, "http", redirectURI.Scheme)
require.Equal(t, host, redirectURI.Host)
Expand Down
11 changes: 9 additions & 2 deletions coderd/workspaceapps/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/google/uuid"

"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/codersdk"
)

Expand Down Expand Up @@ -61,8 +62,14 @@ func (r IssueTokenRequest) AppBaseURL() (*url.URL, error) {
if r.AppHostname == "" {
return nil, xerrors.New("subdomain app hostname is required to generate subdomain app URL")
}
appHost := fmt.Sprintf("%s--%s--%s--%s", r.AppRequest.AppSlugOrPort, r.AppRequest.AgentNameOrID, r.AppRequest.WorkspaceNameOrID, r.AppRequest.UsernameOrID)
u.Host = strings.Replace(r.AppHostname, "*", appHost, 1)

appHost := httpapi.ApplicationURL{
AppSlugOrPort: r.AppRequest.AppSlugOrPort,
AgentName: r.AppRequest.AgentNameOrID,
WorkspaceName: r.AppRequest.WorkspaceNameOrID,
Username: r.AppRequest.UsernameOrID,
}
u.Host = strings.Replace(r.AppHostname, "*", appHost.String(), 1)
u.Path = r.AppRequest.BasePath
return u, nil
default:
Expand Down