feat: validate presets on template import (#18844)

Typos and other errors often result in invalid presets in a template.
Coder would import these broken templates and present them to users when
they create workspaces. An unsuspecting user who chooses a broken preset
would then experience a failed workspace build with no obvious error
message.

This PR adds additional validation beyond what is possible in the
Terraform provider schema. Coder will now present a more helpful error
message to template authors when they upload a new template version:

<img width="1316" height="286" alt="Screenshot 2025-07-14 at 12 22 49"
src="https://github.com/user-attachments/assets/7f5f778f-d9ae-487a-95e2-f6f1ca604a9c"
/>

The frontend warning is less helpful right now, but I'd like to address
that in a follow-up since I need frontend help:

<img width="1102" height="616" alt="image"
src="https://github.com/user-attachments/assets/e838ffc8-ef4f-428d-9280-74fa0c491666"
/>

closes https://github.com/coder/coder/issues/17333


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Improved validation and error reporting for template presets,
providing clearer feedback when presets cannot be parsed or reference
undefined parameters.

* **Bug Fixes**
* Enhanced error handling during template version creation to better
detect and report issues with presets.

* **Tests**
* Added new tests to verify validation of both valid and invalid
Terraform presets during template version creation.
* Improved test reliability by enabling dynamic control over error
injection in database-related tests.

* **Chores**
* Updated a dependency to the latest version for improved stability and
features.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Sas Swart
2025-07-30 15:28:56 +02:00
committed by GitHub
parent 26d232da6f
commit f256a23a77
5 changed files with 161 additions and 0 deletions
+8
View File
@@ -26,6 +26,14 @@ func tagValidationError(diags hcl.Diagnostics) *DiagnosticError {
}
}
func presetValidationError(diags hcl.Diagnostics) *DiagnosticError {
return &DiagnosticError{
Message: "Unable to validate presets",
Diagnostics: diags,
KeyedDiagnostics: make(map[string]hcl.Diagnostics),
}
}
type DiagnosticError struct {
// Message is the human-readable message that will be returned to the user.
Message string
+28
View File
@@ -0,0 +1,28 @@
package dynamicparameters
import (
"github.com/hashicorp/hcl/v2"
"github.com/coder/preview"
)
// CheckPresets extracts the preset related diagnostics from a template version preset
func CheckPresets(output *preview.Output, diags hcl.Diagnostics) *DiagnosticError {
de := presetValidationError(diags)
if output == nil {
return de
}
presets := output.Presets
for _, preset := range presets {
if hcl.Diagnostics(preset.Diagnostics).HasErrors() {
de.Extend(preset.Name, hcl.Diagnostics(preset.Diagnostics))
}
}
if de.HasError() {
return de
}
return nil
}
+4
View File
@@ -11,6 +11,10 @@ import (
func CheckTags(output *preview.Output, diags hcl.Diagnostics) *DiagnosticError {
de := tagValidationError(diags)
if output == nil {
return de
}
failedTags := output.WorkspaceTags.UnusableTags()
if len(failedTags) == 0 && !de.HasError() {
return nil // No errors, all is good!