Skip to content

Commit bc6c788

Browse files
committed
Begin to integrate parameter validation
1 parent a414314 commit bc6c788

12 files changed

+170
-14
lines changed

cli/create.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,11 @@ func create() *cobra.Command {
141141

142142
after := time.Now()
143143
workspace, err := client.CreateWorkspace(cmd.Context(), organization.ID, codersdk.Me, codersdk.CreateWorkspaceRequest{
144-
TemplateID: template.ID,
145-
Name: workspaceName,
146-
AutostartSchedule: schedSpec,
147-
TTLMillis: ptr.Ref(stopAfter.Milliseconds()),
148-
ParameterValues: parameters,
144+
TemplateID: template.ID,
145+
Name: workspaceName,
146+
AutostartSchedule: schedSpec,
147+
TTLMillis: ptr.Ref(stopAfter.Milliseconds()),
148+
DeprecatedParameterValues: parameters,
149149
})
150150
if err != nil {
151151
return err

cli/update.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ func update() *cobra.Command {
5959

6060
before := time.Now()
6161
build, err := client.CreateWorkspaceBuild(cmd.Context(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{
62-
TemplateVersionID: template.ActiveVersionID,
63-
Transition: workspace.LatestBuild.Transition,
64-
ParameterValues: parameters,
62+
TemplateVersionID: template.ActiveVersionID,
63+
Transition: workspace.LatestBuild.Transition,
64+
DeprecatedParameterValues: parameters,
6565
})
6666
if err != nil {
6767
return err

coderd/database/databasefake/databasefake.go

+30
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ func New() database.Store {
4444
templateVersionParameters: make([]database.TemplateVersionParameter, 0),
4545
templates: make([]database.Template, 0),
4646
workspaceBuilds: make([]database.WorkspaceBuild, 0),
47+
workspaceBuildParameters: make([]database.WorkspaceBuildParameter, 0),
4748
workspaceApps: make([]database.WorkspaceApp, 0),
4849
workspaces: make([]database.Workspace, 0),
4950
licenses: make([]database.License, 0),
@@ -97,6 +98,7 @@ type data struct {
9798
templateVersionParameters []database.TemplateVersionParameter
9899
templates []database.Template
99100
workspaceBuilds []database.WorkspaceBuild
101+
workspaceBuildParameters []database.WorkspaceBuildParameter
100102
workspaceApps []database.WorkspaceApp
101103
workspaces []database.Workspace
102104
licenses []database.License
@@ -855,6 +857,20 @@ func (q *fakeQuerier) GetWorkspaceBuildByWorkspaceIDAndBuildNumber(_ context.Con
855857
return database.WorkspaceBuild{}, sql.ErrNoRows
856858
}
857859

860+
func (q *fakeQuerier) GetWorkspaceBuildParameters(ctx context.Context, workspaceBuildID uuid.UUID) ([]database.WorkspaceBuildParameter, error) {
861+
q.mutex.RLock()
862+
defer q.mutex.RUnlock()
863+
864+
params := make([]database.WorkspaceBuildParameter, 0)
865+
for _, param := range params {
866+
if param.WorkspaceBuildID != workspaceBuildID {
867+
continue
868+
}
869+
params = append(params, param)
870+
}
871+
return params, nil
872+
}
873+
858874
func (q *fakeQuerier) GetWorkspaceBuildsCreatedAfter(_ context.Context, after time.Time) ([]database.WorkspaceBuild, error) {
859875
q.mutex.RLock()
860876
defer q.mutex.RUnlock()
@@ -2066,6 +2082,20 @@ func (q *fakeQuerier) InsertWorkspaceBuild(_ context.Context, arg database.Inser
20662082
return workspaceBuild, nil
20672083
}
20682084

2085+
func (q *fakeQuerier) InsertWorkspaceBuildParameters(ctx context.Context, arg database.InsertWorkspaceBuildParametersParams) error {
2086+
q.mutex.Lock()
2087+
defer q.mutex.Unlock()
2088+
2089+
for index, name := range arg.Name {
2090+
q.workspaceBuildParameters = append(q.workspaceBuildParameters, database.WorkspaceBuildParameter{
2091+
WorkspaceBuildID: arg.WorkspaceBuildID,
2092+
Name: name,
2093+
Value: arg.Value[index],
2094+
})
2095+
}
2096+
return nil
2097+
}
2098+
20692099
func (q *fakeQuerier) InsertWorkspaceApp(_ context.Context, arg database.InsertWorkspaceAppParams) (database.WorkspaceApp, error) {
20702100
q.mutex.Lock()
20712101
defer q.mutex.Unlock()

coderd/database/querier.go

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

+53
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
-- name: InsertWorkspaceBuildParameters :exec
2+
INSERT INTO
3+
workspace_build_parameters (workspace_build_id, name, value)
4+
SELECT
5+
@workspace_build_id :: uuid AS workspace_build_id,
6+
unnset(@name :: text[]) AS name,
7+
unnset(@value :: text[]) AS value
8+
RETURNING *;
9+
10+
-- name: GetWorkspaceBuildParameters :many
11+
SELECT
12+
*
13+
FROM
14+
workspace_build_parameters
15+
WHERE
16+
workspace_build_id = $1;

coderd/workspacebuilds.go

+37-1
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
300300
return
301301
}
302302

303+
var parameters []codersdk.WorkspaceBuildParameter
303304
var state []byte
304305
// If custom state, deny request since user could be corrupting or leaking
305306
// cloud state.
@@ -312,6 +313,9 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
312313
}
313314
state = createBuild.ProvisionerState
314315
}
316+
if createBuild.Parameters != nil {
317+
parameters = createBuild.Parameters
318+
}
315319

316320
if createBuild.Orphan {
317321
if createBuild.Transition != codersdk.WorkspaceTransitionDelete {
@@ -382,6 +386,23 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
382386
if state == nil {
383387
state = priorHistory.ProvisionerState
384388
}
389+
if parameters == nil {
390+
buildParameters, err := api.Database.GetWorkspaceBuildParameters(ctx, priorHistory.ID)
391+
if err != nil {
392+
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
393+
Message: "Internal error fetching prior workspace build parameters.",
394+
Detail: err.Error(),
395+
})
396+
return
397+
}
398+
parameters = make([]codersdk.WorkspaceBuildParameter, 0, len(buildParameters))
399+
for _, param := range buildParameters {
400+
parameters = append(parameters, codersdk.WorkspaceBuildParameter{
401+
Name: param.Name,
402+
Value: param.Value,
403+
})
404+
}
405+
}
385406

386407
var workspaceBuild database.WorkspaceBuild
387408
var provisionerJob database.ProvisionerJob
@@ -398,7 +419,7 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
398419

399420
// Write/Update any new params
400421
now := database.Now()
401-
for _, param := range createBuild.ParameterValues {
422+
for _, param := range createBuild.DeprecatedParameterValues {
402423
for _, exists := range existing {
403424
// If the param exists, delete the old param before inserting the new one
404425
if exists.Name == param.Name {
@@ -426,6 +447,21 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
426447
}
427448

428449
workspaceBuildID := uuid.New()
450+
names := make([]string, 0, len(parameters))
451+
values := make([]string, 0, len(parameters))
452+
for _, param := range parameters {
453+
names = append(names, param.Name)
454+
values = append(values, param.Value)
455+
}
456+
err = db.InsertWorkspaceBuildParameters(ctx, database.InsertWorkspaceBuildParametersParams{
457+
WorkspaceBuildID: workspaceBuildID,
458+
Name: names,
459+
Value: values,
460+
})
461+
if err != nil {
462+
return xerrors.Errorf("insert workspace build parameter: %w", err)
463+
}
464+
429465
input, err := json.Marshal(workspaceProvisionJob{
430466
WorkspaceBuildID: workspaceBuildID,
431467
})

coderd/workspaces.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
372372
if err != nil {
373373
return xerrors.Errorf("insert workspace: %w", err)
374374
}
375-
for _, parameterValue := range createWorkspace.ParameterValues {
375+
for _, parameterValue := range createWorkspace.DeprecatedParameterValues {
376376
// If the value is empty, we don't want to save it on database so
377377
// Terraform can use the default value
378378
if parameterValue.SourceValue == "" {

codersdk/organizations.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ type CreateWorkspaceRequest struct {
8282
Name string `json:"name" validate:"workspace_name,required"`
8383
AutostartSchedule *string `json:"autostart_schedule"`
8484
TTLMillis *int64 `json:"ttl_ms,omitempty"`
85-
// ParameterValues allows for additional parameters to be provided
85+
// DeprecatedParameterValues allows for additional parameters to be provided
8686
// during the initial provision.
87-
ParameterValues []DeprecatedCreateParameterRequest `json:"parameter_values,omitempty"`
87+
DeprecatedParameterValues []DeprecatedCreateParameterRequest `json:"parameter_values,omitempty"`
8888
}
8989

9090
func (c *Client) Organization(ctx context.Context, id uuid.UUID) (Organization, error) {

codersdk/workspacebuilds.go

+6
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ type WorkspaceBuild struct {
5454
Deadline NullTime `json:"deadline,omitempty"`
5555
}
5656

57+
// WorkspaceBuildParameter represents a parameter specific for a workspace build.
58+
type WorkspaceBuildParameter struct {
59+
Name string `json:"name"`
60+
Value string `json:"value"`
61+
}
62+
5763
// WorkspaceBuild returns a single workspace build for a workspace.
5864
// If history is "", the latest version is returned.
5965
func (c *Client) WorkspaceBuild(ctx context.Context, id uuid.UUID) (WorkspaceBuild, error) {

codersdk/workspaces.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,18 @@ type CreateWorkspaceBuildRequest struct {
3737
Transition WorkspaceTransition `json:"transition" validate:"oneof=create start stop delete,required"`
3838
DryRun bool `json:"dry_run,omitempty"`
3939
ProvisionerState []byte `json:"state,omitempty"`
40+
// Parameters are an optional list of parameters to use for the workspace build.
41+
// If not provided, the prior build parameter list will be used.
42+
//
43+
// A build will fail to create if the template defines parameters that are invalid or missing.
44+
Parameters []WorkspaceBuildParameter `json:"parameters,omitempty"`
4045
// Orphan may be set for the Destroy transition.
4146
Orphan bool `json:"orphan,omitempty"`
42-
// ParameterValues are optional. It will write params to the 'workspace' scope.
47+
48+
// DeprecatedParameterValues are optional. It will write params to the 'workspace' scope.
4349
// This will overwrite any existing parameters with the same name.
4450
// This will not delete old params not included in this list.
45-
ParameterValues []DeprecatedCreateParameterRequest `json:"parameter_values,omitempty"`
51+
DeprecatedParameterValues []DeprecatedCreateParameterRequest `json:"parameter_values,omitempty"`
4652
}
4753

4854
type WorkspaceOptions struct {

site/src/api/typesGenerated.ts

+7
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ export interface CreateWorkspaceBuildRequest {
198198
readonly transition: WorkspaceTransition
199199
readonly dry_run?: boolean
200200
readonly state?: string
201+
readonly parameters?: WorkspaceBuildParameter[]
201202
readonly orphan?: boolean
202203
readonly parameter_values?: DeprecatedCreateParameterRequest[]
203204
}
@@ -648,6 +649,12 @@ export interface WorkspaceBuild {
648649
readonly deadline?: string
649650
}
650651

652+
// From codersdk/workspacebuilds.go
653+
export interface WorkspaceBuildParameter {
654+
readonly name: string
655+
readonly value: string
656+
}
657+
651658
// From codersdk/workspaces.go
652659
export interface WorkspaceBuildsRequest extends Pagination {
653660
readonly WorkspaceID: string

0 commit comments

Comments
 (0)