fix: set preset parameters in the API rather than the frontend (#17403)

Follow-up from a [previous Pull
Request](https://github.com/coder/coder/pull/16965) required some
additional testing of Presets from the API perspective.

In the process of adding the new tests, I updated the API to enforce
preset parameter values based on the selected preset instead of trusting
whichever frontend makes the request. This avoids errors scenarios in
prebuilds where a prebuild might expect a certain preset but find a
different set of actual parameter values.
This commit is contained in:
Sas Swart
2025-04-16 15:54:06 +02:00
committed by GitHub
parent d78215cdcb
commit 64172d374f
4 changed files with 387 additions and 46 deletions
+30 -12
View File
@@ -61,18 +61,19 @@ type Builder struct {
store database.Store
// cache of objects, so we only fetch once
template *database.Template
templateVersion *database.TemplateVersion
templateVersionJob *database.ProvisionerJob
templateVersionParameters *[]database.TemplateVersionParameter
templateVersionVariables *[]database.TemplateVersionVariable
templateVersionWorkspaceTags *[]database.TemplateVersionWorkspaceTag
lastBuild *database.WorkspaceBuild
lastBuildErr *error
lastBuildParameters *[]database.WorkspaceBuildParameter
lastBuildJob *database.ProvisionerJob
parameterNames *[]string
parameterValues *[]string
template *database.Template
templateVersion *database.TemplateVersion
templateVersionJob *database.ProvisionerJob
templateVersionParameters *[]database.TemplateVersionParameter
templateVersionVariables *[]database.TemplateVersionVariable
templateVersionWorkspaceTags *[]database.TemplateVersionWorkspaceTag
lastBuild *database.WorkspaceBuild
lastBuildErr *error
lastBuildParameters *[]database.WorkspaceBuildParameter
lastBuildJob *database.ProvisionerJob
parameterNames *[]string
parameterValues *[]string
templateVersionPresetParameterValues []database.TemplateVersionPresetParameter
prebuild bool
@@ -565,6 +566,14 @@ func (b *Builder) getParameters() (names, values []string, err error) {
if err != nil {
return nil, nil, BuildError{http.StatusInternalServerError, "failed to fetch last build parameters", err}
}
if b.templateVersionPresetID != uuid.Nil {
// Fetch and cache these, since we'll need them to override requested values if a preset was chosen
presetParameters, err := b.store.GetPresetParametersByPresetID(b.ctx, b.templateVersionPresetID)
if err != nil {
return nil, nil, BuildError{http.StatusInternalServerError, "failed to get preset parameters", err}
}
b.templateVersionPresetParameterValues = presetParameters
}
err = b.verifyNoLegacyParameters()
if err != nil {
return nil, nil, BuildError{http.StatusBadRequest, "Unable to build workspace with unsupported parameters", err}
@@ -597,6 +606,15 @@ func (b *Builder) getParameters() (names, values []string, err error) {
}
func (b *Builder) findNewBuildParameterValue(name string) *codersdk.WorkspaceBuildParameter {
for _, v := range b.templateVersionPresetParameterValues {
if v.Name == name {
return &codersdk.WorkspaceBuildParameter{
Name: v.Name,
Value: v.Value,
}
}
}
for _, v := range b.richParameterValues {
if v.Name == name {
return &v
+10
View File
@@ -789,6 +789,10 @@ func TestWorkspaceBuildWithPreset(t *testing.T) {
// Inputs
withTemplate,
withActiveVersion(nil),
// building workspaces using presets with different combinations of parameters
// is tested at the API layer, in TestWorkspace. Here, it is sufficient to
// test that the preset is used when provided.
withTemplateVersionPresetParameters(presetID, nil),
withLastBuildNotFound,
withTemplateVersionVariables(activeVersionID, nil),
withParameterSchemas(activeJobID, nil),
@@ -960,6 +964,12 @@ func withInactiveVersion(params []database.TemplateVersionParameter) func(mTx *d
}
}
func withTemplateVersionPresetParameters(presetID uuid.UUID, params []database.TemplateVersionPresetParameter) func(mTx *dbmock.MockStore) {
return func(mTx *dbmock.MockStore) {
mTx.EXPECT().GetPresetParametersByPresetID(gomock.Any(), presetID).Return(params, nil)
}
}
func withLastBuildFound(mTx *dbmock.MockStore) {
mTx.EXPECT().GetLatestWorkspaceBuildByWorkspaceID(gomock.Any(), workspaceID).
Times(1).