feat(cli): add enterprise external-workspaces CLI command (#19287)

This pull request introduces support for external workspace management, allowing users to register and manage workspaces that are provisioned and managed outside of the Coder.

* coder external-workspaces create - Creates a new external workspace (this command extends coder create)
  * Example: coder external-workspaces create ext-workspace --template=externally-managed-workspace -y
  * Checks if template has coder_external_agent resource before creating a workspace
* coder external-workspaces list - Lists all external workspaces
* coder external-workspaces agent-instructions <workspace name> <agent name> - Retrieves agent connection instruction
  * Example: coder external-workspaces agent-instructions ext-workspace main --output=json
This commit is contained in:
Kacper Sawicki
2025-08-19 10:52:31 +02:00
committed by GitHub
parent 9edceef0bf
commit 7b1dcd9846
25 changed files with 1277 additions and 73 deletions
+21 -1
View File
@@ -29,7 +29,12 @@ const PresetNone = "none"
var ErrNoPresetFound = xerrors.New("no preset found")
func (r *RootCmd) create() *serpent.Command {
type CreateOptions struct {
BeforeCreate func(ctx context.Context, client *codersdk.Client, template codersdk.Template, templateVersionID uuid.UUID) error
AfterCreate func(ctx context.Context, inv *serpent.Invocation, client *codersdk.Client, workspace codersdk.Workspace) error
}
func (r *RootCmd) Create(opts CreateOptions) *serpent.Command {
var (
templateName string
templateVersion string
@@ -305,6 +310,13 @@ func (r *RootCmd) create() *serpent.Command {
_, _ = fmt.Fprintf(inv.Stdout, "%s", cliui.Bold("No preset applied."))
}
if opts.BeforeCreate != nil {
err = opts.BeforeCreate(inv.Context(), client, template, templateVersionID)
if err != nil {
return xerrors.Errorf("before create: %w", err)
}
}
richParameters, err := prepWorkspaceBuild(inv, client, prepWorkspaceBuildArgs{
Action: WorkspaceCreate,
TemplateVersionID: templateVersionID,
@@ -366,6 +378,14 @@ func (r *RootCmd) create() *serpent.Command {
cliui.Keyword(workspace.Name),
cliui.Timestamp(time.Now()),
)
if opts.AfterCreate != nil {
err = opts.AfterCreate(inv.Context(), inv, client, workspace)
if err != nil {
return err
}
}
return nil
},
}