2023-01-24 13:22:00 +00:00
|
|
|
package codersdk
|
|
|
|
|
|
|
|
import (
|
|
|
|
"golang.org/x/xerrors"
|
|
|
|
|
|
|
|
"github.com/coder/terraform-provider-coder/provider"
|
|
|
|
)
|
|
|
|
|
2023-02-07 08:36:13 +00:00
|
|
|
func ValidateNewWorkspaceParameters(richParameters []TemplateVersionParameter, buildParameters []WorkspaceBuildParameter) error {
|
|
|
|
return ValidateWorkspaceBuildParameters(richParameters, buildParameters, nil)
|
|
|
|
}
|
|
|
|
|
|
|
|
func ValidateWorkspaceBuildParameters(richParameters []TemplateVersionParameter, buildParameters, lastBuildParameters []WorkspaceBuildParameter) error {
|
2023-01-24 13:22:00 +00:00
|
|
|
for _, buildParameter := range buildParameters {
|
2023-01-30 14:34:38 +00:00
|
|
|
if buildParameter.Name == "" {
|
|
|
|
return xerrors.Errorf(`workspace build parameter name is missing`)
|
|
|
|
}
|
2023-01-24 13:22:00 +00:00
|
|
|
richParameter, found := findTemplateVersionParameter(richParameters, buildParameter.Name)
|
|
|
|
if !found {
|
|
|
|
return xerrors.Errorf(`workspace build parameter is not defined in the template ("coder_parameter"): %s`, buildParameter.Name)
|
|
|
|
}
|
|
|
|
|
2023-02-07 08:36:13 +00:00
|
|
|
err := ValidateWorkspaceBuildParameter(*richParameter, buildParameter, findLastBuildParameter(lastBuildParameters, buildParameter.Name))
|
2023-01-24 13:22:00 +00:00
|
|
|
if err != nil {
|
|
|
|
return xerrors.Errorf("can't validate build parameter %q: %w", buildParameter.Name, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-02-07 08:36:13 +00:00
|
|
|
func ValidateWorkspaceBuildParameter(richParameter TemplateVersionParameter, buildParameter WorkspaceBuildParameter, lastBuildParameter *WorkspaceBuildParameter) error {
|
2023-01-24 13:22:00 +00:00
|
|
|
value := buildParameter.Value
|
|
|
|
if value == "" {
|
|
|
|
value = richParameter.DefaultValue
|
|
|
|
}
|
|
|
|
|
2023-02-07 08:36:13 +00:00
|
|
|
if lastBuildParameter != nil && richParameter.Type == "number" && len(richParameter.ValidationMonotonic) > 0 {
|
|
|
|
switch richParameter.ValidationMonotonic {
|
|
|
|
case MonotonicOrderIncreasing:
|
|
|
|
if lastBuildParameter.Value > buildParameter.Value {
|
|
|
|
return xerrors.Errorf("parameter value must be equal or greater than previous value: %s", lastBuildParameter.Value)
|
|
|
|
}
|
|
|
|
case MonotonicOrderDecreasing:
|
|
|
|
if lastBuildParameter.Value < buildParameter.Value {
|
|
|
|
return xerrors.Errorf("parameter value must be equal or lower than previous value: %s", lastBuildParameter.Value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-24 13:22:00 +00:00
|
|
|
if len(richParameter.Options) > 0 {
|
|
|
|
var matched bool
|
|
|
|
for _, opt := range richParameter.Options {
|
|
|
|
if opt.Value == value {
|
|
|
|
matched = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !matched {
|
|
|
|
return xerrors.Errorf("parameter value must match one of options: %s", parameterValuesAsArray(richParameter.Options))
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if !validationEnabled(richParameter) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
validation := &provider.Validation{
|
2023-02-07 08:36:13 +00:00
|
|
|
Min: int(richParameter.ValidationMin),
|
|
|
|
Max: int(richParameter.ValidationMax),
|
|
|
|
Regex: richParameter.ValidationRegex,
|
|
|
|
Error: richParameter.ValidationError,
|
|
|
|
Monotonic: string(richParameter.ValidationMonotonic),
|
2023-01-24 13:22:00 +00:00
|
|
|
}
|
|
|
|
return validation.Valid(richParameter.Type, value)
|
|
|
|
}
|
|
|
|
|
|
|
|
func findTemplateVersionParameter(params []TemplateVersionParameter, parameterName string) (*TemplateVersionParameter, bool) {
|
|
|
|
for _, p := range params {
|
|
|
|
if p.Name == parameterName {
|
|
|
|
return &p, true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
|
2023-02-07 08:36:13 +00:00
|
|
|
func findLastBuildParameter(params []WorkspaceBuildParameter, parameterName string) *WorkspaceBuildParameter {
|
|
|
|
for _, p := range params {
|
|
|
|
if p.Name == parameterName {
|
|
|
|
return &p
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-01-24 13:22:00 +00:00
|
|
|
func parameterValuesAsArray(options []TemplateVersionParameterOption) []string {
|
|
|
|
var arr []string
|
|
|
|
for _, opt := range options {
|
|
|
|
arr = append(arr, opt.Value)
|
|
|
|
}
|
|
|
|
return arr
|
|
|
|
}
|
|
|
|
|
|
|
|
func validationEnabled(param TemplateVersionParameter) bool {
|
|
|
|
return len(param.ValidationRegex) > 0 ||
|
|
|
|
(param.ValidationMin != 0 && param.ValidationMax != 0) ||
|
2023-02-07 08:36:13 +00:00
|
|
|
len(param.ValidationMonotonic) > 0 ||
|
2023-01-24 13:22:00 +00:00
|
|
|
param.Type == "bool" // boolean type doesn't have any custom validation rules, but the value must be checked (true/false).
|
|
|
|
}
|