package codersdk import ( "context" "encoding/json" "fmt" "net/http" "time" "github.com/google/uuid" "golang.org/x/xerrors" "github.com/coder/coder/coderd/database" ) // Workspace is a deployment of a template. It references a specific // version and can be updated. type Workspace struct { ID uuid.UUID `json:"id"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` OwnerID uuid.UUID `json:"owner_id"` TemplateID uuid.UUID `json:"template_id"` TemplateName string `json:"template_name"` LatestBuild WorkspaceBuild `json:"latest_build"` Outdated bool `json:"outdated"` Name string `json:"name"` AutostartSchedule string `json:"autostart_schedule"` AutostopSchedule string `json:"autostop_schedule"` } // CreateWorkspaceBuildRequest provides options to update the latest workspace build. type CreateWorkspaceBuildRequest struct { TemplateVersionID uuid.UUID `json:"template_version_id"` Transition database.WorkspaceTransition `json:"transition" validate:"oneof=create start stop delete,required"` DryRun bool `json:"dry_run"` } // Workspace returns a single workspace. func (c *Client) Workspace(ctx context.Context, id uuid.UUID) (Workspace, error) { res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaces/%s", id), nil) if err != nil { return Workspace{}, err } defer res.Body.Close() if res.StatusCode != http.StatusOK { return Workspace{}, readBodyAsError(res) } var workspace Workspace return workspace, json.NewDecoder(res.Body).Decode(&workspace) } func (c *Client) WorkspaceBuilds(ctx context.Context, workspace uuid.UUID) ([]WorkspaceBuild, error) { res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaces/%s/builds", workspace), nil) if err != nil { return nil, err } defer res.Body.Close() if res.StatusCode != http.StatusOK { return nil, readBodyAsError(res) } var workspaceBuild []WorkspaceBuild return workspaceBuild, json.NewDecoder(res.Body).Decode(&workspaceBuild) } // CreateWorkspaceBuild queues a new build to occur for a workspace. func (c *Client) CreateWorkspaceBuild(ctx context.Context, workspace uuid.UUID, request CreateWorkspaceBuildRequest) (WorkspaceBuild, error) { res, err := c.request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/workspaces/%s/builds", workspace), request) if err != nil { return WorkspaceBuild{}, err } defer res.Body.Close() if res.StatusCode != http.StatusCreated { return WorkspaceBuild{}, readBodyAsError(res) } var workspaceBuild WorkspaceBuild return workspaceBuild, json.NewDecoder(res.Body).Decode(&workspaceBuild) } func (c *Client) WorkspaceBuildByName(ctx context.Context, workspace uuid.UUID, name string) (WorkspaceBuild, error) { res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaces/%s/builds/%s", workspace, name), nil) if err != nil { return WorkspaceBuild{}, err } defer res.Body.Close() if res.StatusCode != http.StatusOK { return WorkspaceBuild{}, readBodyAsError(res) } var workspaceBuild WorkspaceBuild return workspaceBuild, json.NewDecoder(res.Body).Decode(&workspaceBuild) } // UpdateWorkspaceAutostartRequest is a request to update a workspace's autostart schedule. type UpdateWorkspaceAutostartRequest struct { Schedule string `json:"schedule"` } // UpdateWorkspaceAutostart sets the autostart schedule for workspace by id. // If the provided schedule is empty, autostart is disabled for the workspace. func (c *Client) UpdateWorkspaceAutostart(ctx context.Context, id uuid.UUID, req UpdateWorkspaceAutostartRequest) error { path := fmt.Sprintf("/api/v2/workspaces/%s/autostart", id.String()) res, err := c.request(ctx, http.MethodPut, path, req) if err != nil { return xerrors.Errorf("update workspace autostart: %w", err) } defer res.Body.Close() if res.StatusCode != http.StatusOK { return readBodyAsError(res) } return nil } // UpdateWorkspaceAutostopRequest is a request to update a workspace's autostop schedule. type UpdateWorkspaceAutostopRequest struct { Schedule string `json:"schedule"` } // UpdateWorkspaceAutostop sets the autostop schedule for workspace by id. // If the provided schedule is empty, autostop is disabled for the workspace. func (c *Client) UpdateWorkspaceAutostop(ctx context.Context, id uuid.UUID, req UpdateWorkspaceAutostopRequest) error { path := fmt.Sprintf("/api/v2/workspaces/%s/autostop", id.String()) res, err := c.request(ctx, http.MethodPut, path, req) if err != nil { return xerrors.Errorf("update workspace autostop: %w", err) } defer res.Body.Close() if res.StatusCode != http.StatusOK { return readBodyAsError(res) } return nil }