Files
coder/enterprise/coderd/workspaceagents.go
T
Kacper Sawicki c7cfa65961 fix(enterprise): correct order for external agent init cmd (#19408)
### Description

`CODER_AGENT_TOKEN` env variable was incorrectly being passed to the
curl command instead of the executed script during agent initialization.

Fixed the command order to ensure `CODER_AGENT_TOKEN` is properly passed
to the script execution context rather than the download command.
2025-08-19 11:00:40 +00:00

99 lines
3.0 KiB
Go

package coderd
import (
"context"
"fmt"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk"
)
func (api *API) shouldBlockNonBrowserConnections(rw http.ResponseWriter) bool {
if api.Entitlements.Enabled(codersdk.FeatureBrowserOnly) {
httpapi.Write(context.Background(), rw, http.StatusConflict, codersdk.Response{
Message: "Non-browser connections are disabled for your deployment.",
})
return true
}
return false
}
// @Summary Get workspace external agent credentials
// @ID get-workspace-external-agent-credentials
// @Security CoderSessionToken
// @Produce json
// @Tags Enterprise
// @Param workspace path string true "Workspace ID" format(uuid)
// @Param agent path string true "Agent name"
// @Success 200 {object} codersdk.ExternalAgentCredentials
// @Router /workspaces/{workspace}/external-agent/{agent}/credentials [get]
func (api *API) workspaceExternalAgentCredentials(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
workspace := httpmw.WorkspaceParam(r)
agentName := chi.URLParam(r, "agent")
build, err := api.Database.GetLatestWorkspaceBuildByWorkspaceID(ctx, workspace.ID)
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Failed to get latest workspace build.",
Detail: err.Error(),
})
return
}
if !build.HasExternalAgent.Bool {
httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{
Message: "Workspace does not have an external agent.",
})
return
}
agents, err := api.Database.GetWorkspaceAgentsByWorkspaceAndBuildNumber(ctx, database.GetWorkspaceAgentsByWorkspaceAndBuildNumberParams{
WorkspaceID: workspace.ID,
BuildNumber: build.BuildNumber,
})
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Failed to get workspace agents.",
Detail: err.Error(),
})
return
}
var agent *database.WorkspaceAgent
for i := range agents {
if agents[i].Name == agentName {
agent = &agents[i]
break
}
}
if agent == nil {
httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{
Message: fmt.Sprintf("External agent '%s' not found in workspace.", agentName),
})
return
}
if agent.AuthInstanceID.Valid {
httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{
Message: "External agent is authenticated with an instance ID.",
})
return
}
initScriptURL := fmt.Sprintf("%s/api/v2/init-script/%s/%s", api.AccessURL.String(), agent.OperatingSystem, agent.Architecture)
command := fmt.Sprintf("curl -fsSL %q | CODER_AGENT_TOKEN=%q sh", initScriptURL, agent.AuthToken.String())
if agent.OperatingSystem == "windows" {
command = fmt.Sprintf("$env:CODER_AGENT_TOKEN=%q; iwr -useb %q | iex", agent.AuthToken.String(), initScriptURL)
}
httpapi.Write(ctx, rw, http.StatusOK, codersdk.ExternalAgentCredentials{
AgentToken: agent.AuthToken.String(),
Command: command,
})
}