Skip to content

Commit 36a72a2

Browse files
aslilacEmyrk
andauthored
chore: loosen static validation when using dynamic parameters (coder#17516)
Co-authored-by: Steven Masley <stevenmasley@gmail.com>
1 parent 3b4343d commit 36a72a2

File tree

10 files changed

+64
-13
lines changed

10 files changed

+64
-13
lines changed

coderd/apidoc/docs.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/workspaces.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,9 @@ func createWorkspace(
676676
if req.TemplateVersionID != uuid.Nil {
677677
builder = builder.VersionID(req.TemplateVersionID)
678678
}
679+
if req.EnableDynamicParameters && api.Experiments.Enabled(codersdk.ExperimentDynamicParameters) {
680+
builder = builder.UsingDynamicParameters()
681+
}
679682

680683
workspaceBuild, provisionerJob, provisionerDaemons, err = builder.Build(
681684
ctx,

coderd/wsbuilder/wsbuilder.go

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,11 @@ type Builder struct {
5151
logLevel string
5252
deploymentValues *codersdk.DeploymentValues
5353

54-
richParameterValues []codersdk.WorkspaceBuildParameter
55-
initiator uuid.UUID
56-
reason database.BuildReason
57-
templateVersionPresetID uuid.UUID
54+
richParameterValues []codersdk.WorkspaceBuildParameter
55+
dynamicParametersEnabled bool
56+
initiator uuid.UUID
57+
reason database.BuildReason
58+
templateVersionPresetID uuid.UUID
5859

5960
// used during build, makes function arguments less verbose
6061
ctx context.Context
@@ -178,6 +179,11 @@ func (b Builder) MarkPrebuild() Builder {
178179
return b
179180
}
180181

182+
func (b Builder) UsingDynamicParameters() Builder {
183+
b.dynamicParametersEnabled = true
184+
return b
185+
}
186+
181187
// SetLastWorkspaceBuildInTx prepopulates the Builder's cache with the last workspace build. This allows us
182188
// to avoid a repeated database query when the Builder's caller also needs the workspace build, e.g. auto-start &
183189
// auto-stop.
@@ -578,6 +584,7 @@ func (b *Builder) getParameters() (names, values []string, err error) {
578584
if err != nil {
579585
return nil, nil, BuildError{http.StatusBadRequest, "Unable to build workspace with unsupported parameters", err}
580586
}
587+
581588
resolver := codersdk.ParameterResolver{
582589
Rich: db2sdk.WorkspaceBuildParameters(lastBuildParameters),
583590
}
@@ -586,16 +593,24 @@ func (b *Builder) getParameters() (names, values []string, err error) {
586593
if err != nil {
587594
return nil, nil, BuildError{http.StatusInternalServerError, "failed to convert template version parameter", err}
588595
}
589-
value, err := resolver.ValidateResolve(
590-
tvp,
591-
b.findNewBuildParameterValue(templateVersionParameter.Name),
592-
)
593-
if err != nil {
594-
// At this point, we've queried all the data we need from the database,
595-
// so the only errors are problems with the request (missing data, failed
596-
// validation, immutable parameters, etc.)
597-
return nil, nil, BuildError{http.StatusBadRequest, fmt.Sprintf("Unable to validate parameter %q", templateVersionParameter.Name), err}
596+
597+
var value string
598+
if !b.dynamicParametersEnabled {
599+
var err error
600+
value, err = resolver.ValidateResolve(
601+
tvp,
602+
b.findNewBuildParameterValue(templateVersionParameter.Name),
603+
)
604+
if err != nil {
605+
// At this point, we've queried all the data we need from the database,
606+
// so the only errors are problems with the request (missing data, failed
607+
// validation, immutable parameters, etc.)
608+
return nil, nil, BuildError{http.StatusBadRequest, fmt.Sprintf("Unable to validate parameter %q", templateVersionParameter.Name), err}
609+
}
610+
} else {
611+
value = resolver.Resolve(tvp, b.findNewBuildParameterValue(templateVersionParameter.Name))
598612
}
613+
599614
names = append(names, templateVersionParameter.Name)
600615
values = append(values, value)
601616
}

codersdk/organizations.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ type CreateWorkspaceRequest struct {
227227
RichParameterValues []WorkspaceBuildParameter `json:"rich_parameter_values,omitempty"`
228228
AutomaticUpdates AutomaticUpdates `json:"automatic_updates,omitempty"`
229229
TemplateVersionPresetID uuid.UUID `json:"template_version_preset_id,omitempty" format:"uuid"`
230+
EnableDynamicParameters bool `json:"enable_dynamic_parameters,omitempty"`
230231
}
231232

232233
func (c *Client) OrganizationByName(ctx context.Context, name string) (Organization, error) {

codersdk/richparameters.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,26 @@ func (r *ParameterResolver) ValidateResolve(p TemplateVersionParameter, v *Works
190190
return resolvedValue.Value, nil
191191
}
192192

193+
// Resolve returns the value of the parameter. It does not do any validation,
194+
// and is meant for use with the new dynamic parameters code path.
195+
func (r *ParameterResolver) Resolve(p TemplateVersionParameter, v *WorkspaceBuildParameter) string {
196+
prevV := r.findLastValue(p)
197+
// First, the provided value
198+
resolvedValue := v
199+
// Second, previous value if not ephemeral
200+
if resolvedValue == nil && !p.Ephemeral {
201+
resolvedValue = prevV
202+
}
203+
// Last, default value
204+
if resolvedValue == nil {
205+
resolvedValue = &WorkspaceBuildParameter{
206+
Name: p.Name,
207+
Value: p.DefaultValue,
208+
}
209+
}
210+
return resolvedValue.Value
211+
}
212+
193213
// findLastValue finds the value from the previous build and returns it, or nil if the parameter had no value in the
194214
// last build.
195215
func (r *ParameterResolver) findLastValue(p TemplateVersionParameter) *WorkspaceBuildParameter {

docs/reference/api/schemas.md

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/reference/api/workspaces.md

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

site/src/api/typesGenerated.ts

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

site/src/pages/CreateWorkspacePage/CreateWorkspacePageExperimental.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ const CreateWorkspacePageExperimental: FC = () => {
282282

283283
const workspace = await createWorkspaceMutation.mutateAsync({
284284
...workspaceRequest,
285+
enable_dynamic_parameters: true,
285286
userId: owner.id,
286287
});
287288
onCreateWorkspace(workspace);

0 commit comments

Comments
 (0)