mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
chore: refactor dynamic parameters into dedicated package (#18420)
This PR extracts dynamic parameter rendering logic from coderd/parameters.go into a new coderd/dynamicparameters package. Partly for organization and maintainability, but primarily to be reused in `wsbuilder` to be leveraged as validation.
This commit is contained in:
143
coderd/dynamicparameters/static.go
Normal file
143
coderd/dynamicparameters/static.go
Normal file
@ -0,0 +1,143 @@
|
||||
package dynamicparameters
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
"github.com/coder/coder/v2/coderd/database/db2sdk"
|
||||
"github.com/coder/coder/v2/coderd/util/ptr"
|
||||
sdkproto "github.com/coder/coder/v2/provisionersdk/proto"
|
||||
"github.com/coder/preview"
|
||||
previewtypes "github.com/coder/preview/types"
|
||||
"github.com/coder/terraform-provider-coder/v2/provider"
|
||||
)
|
||||
|
||||
type staticRender struct {
|
||||
staticParams []previewtypes.Parameter
|
||||
}
|
||||
|
||||
func (r *loader) staticRender(ctx context.Context, db database.Store) (*staticRender, error) {
|
||||
dbTemplateVersionParameters, err := db.GetTemplateVersionParameters(ctx, r.templateVersionID)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("template version parameters: %w", err)
|
||||
}
|
||||
|
||||
params := db2sdk.List(dbTemplateVersionParameters, TemplateVersionParameter)
|
||||
return &staticRender{
|
||||
staticParams: params,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *staticRender) Render(_ context.Context, _ uuid.UUID, values map[string]string) (*preview.Output, hcl.Diagnostics) {
|
||||
params := r.staticParams
|
||||
for i := range params {
|
||||
param := ¶ms[i]
|
||||
paramValue, ok := values[param.Name]
|
||||
if ok {
|
||||
param.Value = previewtypes.StringLiteral(paramValue)
|
||||
} else {
|
||||
param.Value = param.DefaultValue
|
||||
}
|
||||
param.Diagnostics = previewtypes.Diagnostics(param.Valid(param.Value))
|
||||
}
|
||||
|
||||
return &preview.Output{
|
||||
Parameters: params,
|
||||
}, hcl.Diagnostics{
|
||||
{
|
||||
// Only a warning because the form does still work.
|
||||
Severity: hcl.DiagWarning,
|
||||
Summary: "This template version is missing required metadata to support dynamic parameters.",
|
||||
Detail: "To restore full functionality, please re-import the terraform as a new template version.",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (*staticRender) Close() {}
|
||||
|
||||
func TemplateVersionParameter(it database.TemplateVersionParameter) previewtypes.Parameter {
|
||||
param := previewtypes.Parameter{
|
||||
ParameterData: previewtypes.ParameterData{
|
||||
Name: it.Name,
|
||||
DisplayName: it.DisplayName,
|
||||
Description: it.Description,
|
||||
Type: previewtypes.ParameterType(it.Type),
|
||||
FormType: provider.ParameterFormType(it.FormType),
|
||||
Styling: previewtypes.ParameterStyling{},
|
||||
Mutable: it.Mutable,
|
||||
DefaultValue: previewtypes.StringLiteral(it.DefaultValue),
|
||||
Icon: it.Icon,
|
||||
Options: make([]*previewtypes.ParameterOption, 0),
|
||||
Validations: make([]*previewtypes.ParameterValidation, 0),
|
||||
Required: it.Required,
|
||||
Order: int64(it.DisplayOrder),
|
||||
Ephemeral: it.Ephemeral,
|
||||
Source: nil,
|
||||
},
|
||||
// Always use the default, since we used to assume the empty string
|
||||
Value: previewtypes.StringLiteral(it.DefaultValue),
|
||||
Diagnostics: make(previewtypes.Diagnostics, 0),
|
||||
}
|
||||
|
||||
if it.ValidationError != "" || it.ValidationRegex != "" || it.ValidationMonotonic != "" {
|
||||
var reg *string
|
||||
if it.ValidationRegex != "" {
|
||||
reg = ptr.Ref(it.ValidationRegex)
|
||||
}
|
||||
|
||||
var vMin *int64
|
||||
if it.ValidationMin.Valid {
|
||||
vMin = ptr.Ref(int64(it.ValidationMin.Int32))
|
||||
}
|
||||
|
||||
var vMax *int64
|
||||
if it.ValidationMax.Valid {
|
||||
vMax = ptr.Ref(int64(it.ValidationMax.Int32))
|
||||
}
|
||||
|
||||
var monotonic *string
|
||||
if it.ValidationMonotonic != "" {
|
||||
monotonic = ptr.Ref(it.ValidationMonotonic)
|
||||
}
|
||||
|
||||
param.Validations = append(param.Validations, &previewtypes.ParameterValidation{
|
||||
Error: it.ValidationError,
|
||||
Regex: reg,
|
||||
Min: vMin,
|
||||
Max: vMax,
|
||||
Monotonic: monotonic,
|
||||
})
|
||||
}
|
||||
|
||||
var protoOptions []*sdkproto.RichParameterOption
|
||||
err := json.Unmarshal(it.Options, &protoOptions)
|
||||
if err != nil {
|
||||
param.Diagnostics = append(param.Diagnostics, &hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Failed to parse json parameter options",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
}
|
||||
|
||||
for _, opt := range protoOptions {
|
||||
param.Options = append(param.Options, &previewtypes.ParameterOption{
|
||||
Name: opt.Name,
|
||||
Description: opt.Description,
|
||||
Value: previewtypes.StringLiteral(opt.Value),
|
||||
Icon: opt.Icon,
|
||||
})
|
||||
}
|
||||
|
||||
// Take the form type from the ValidateFormType function. This is a bit
|
||||
// unfortunate we have to do this, but it will return the default form_type
|
||||
// for a given set of conditions.
|
||||
_, param.FormType, _ = provider.ValidateFormType(provider.OptionType(param.Type), len(param.Options), param.FormType)
|
||||
|
||||
param.Diagnostics = append(param.Diagnostics, previewtypes.Diagnostics(param.Valid(param.Value))...)
|
||||
return param
|
||||
}
|
Reference in New Issue
Block a user