-
Notifications
You must be signed in to change notification settings - Fork 22
feat: 2 parameter validation modes for create & import #381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@johnstcn @matifali should this pass a template import? Before this PR, this would pass a data "coder_parameter" "region" {
name = "region"
description = "Which region would you like to deploy to?"
type = "string"
order = 1
option {
name = "Europe"
value = "eu"
}
option {
name = "United States"
value = "us"
}
} EDIT: Test case here
This PR sets the error to:
To fix this, either the value must be passed via an env var:
Or with a default:
I feel like we should reject it? But that is a breaking change. |
There are use cases where an admin may not want to set a default to force the user to choose an option. At least it was possible before this PR. I am not sure how many users were actually using it. But I have seen requests to support |
This behaviour is problematic because you could end up with a plan that does not correspond to the apply, depending on how the value of the parameter is used. Would marking the parameter as EDIT: marking a parameter as ephemeral requires it to be mutable and to also have a default set. This may not suit certain use-cases. |
Do we require a user input if the parameters are ephemeral? Do we not allow setting a default value for such parameters? If the answers are yes, then we just need better docs on how to fulfill this use case. So that people don't try to use the existing non ephemeral parameters. |
How I see it is the relaxed validation on template import is incorrect. If a parameter has 0 values, but will have some value at workspace create, then the However, I understand the use case. The provider SDK we are using does not indicate anywhere if My gut thought is that we need to effectively have 2 modes of validation. 1 for template import, 1 for workspace create, where the latter is strict. The strict validation is the most correct. What if we pass through an env var a relaxed validation mode? |
I think this approach could work, but we'd want to perhaps tie its behaviour specifically to what "operation" we're doing in Coder. We might also want to be wary of folks just setting this env var on the provisioner to work around null values entirely. |
Yes, template import would have to pass some env var to change the behavior. As for folks setting this env var at home, I think that would just be on them. By default the validation should be handled correctly in coder (when to be relaxed, and when not) |
a61664c
to
5e19e2a
Compare
Some validation changes: - Invalid options rejected (not in option set)
If provisionerd always sets the environment variable before exec'ing terraform, then I don't think we need to worry about users setting it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems very odd to me that in this PR, template-import mode, which is supposedly being created for back-compatibility is more strict than what you're calling default mode.
Shouldn't it be the other way around? That template-import mode skips some checks that would break backward compatibility?
}, | ||
} | ||
} | ||
} | ||
} | ||
|
||
if len(v.Validation) == 1 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there somewhere we enforce that there can only be a max of one Validation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is here in the schema:
MaxItems: 1, |
You get this error:
│ Error: Too many validation blocks
│
│ on main.tf line 38, in data "coder_parameter" "project":
│ 38: validation {
│
│ No more than 1 "validation" blocks are allowed
return "", diags | ||
} | ||
|
||
if mode == ValidationModeTemplateImport && v.Default != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a weird case where template import is more strict than default. What is the justification for that? I thought we were only making template import less strict so that we don't break people.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are correct. When we turn this on in coderd, new templates imported will be subject to a stricter validation. There is 2 reasons.
Strict options
You can currently add option
s to your parameters that are invalid. That is a bit confusing on the UI, when options exist, but if you select them, it would fail to build.
At create
time, the options are ignored, since they are not used.
Strict Default
This was actually done before too iff no input value was given (which is usually the case for template-import). I made this more explicit, where the Default
has to be valid if set. Even if you passed in an input value at import time.
I enforce this, because if you do not, then a user who leaves a default value for a form has an invalid value and cannot build.
Sidenote, but if you want to place a value in the UI without it being valid, we are adding styling
:
data "coder_parameter" "numbers" {
name = "numebrs"
type = "number"
order = 1
styling = jsonencode({
placeholder = "Enter a number"
})
}
provider/parameter.go
Outdated
//if value == nil && mode == ValidationModeDefault { | ||
// var empty string | ||
// value = &empty | ||
//} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This business wouldn't be necessary if the provider assumes the "looser" validation mode if unset. That is, there are 2 modes: WorkspaceCreate and TemplateImport, which in future we will explicitly set via environment variable. If unset, we assume TemplateImport, which has no breaking changes from current behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed this and did the early return
instead as you suggested.
TemplateImport
actually has more breaking changes than create
in the end. create
is backwards compatible because imported templates already exist and must still work.
Newly imported templates (once coderd switches), is going to require every option
to also be valid. By doing this, the workspace create form will only present valid options to the user.
Eventually I would like to disallow an empty input value at create
entirely.
Maybe I should have broken this into 2 PRs. My goal is to make existing imported templates backwards compatible. They will function as they used to. Future imported templates I am closing some of the validation holes. And the backwards feature I am keeping, is allowing empty an data "coder_parameter" "region" {
name = "region"
description = "Which region would you like to deploy to?"
type = "string"
order = 1
option {
name = "Europe"
value = "eu"
}
} The other changes I made are fixing validation bugs. Meaning validation used to be skipped on present values. Validating input values is in the option setThis is in This is now invalid except at # Using input value 3
# CODER_PARAMETER_f3c7807d475073ba009bf4801b2d934e9f0126cb96dd19a27dbffcae23a7f5a3=3 terraform plan
data "coder_parameter" "numbers" {
name = "numebrs"
type = "number"
order = 1
option {
name = "Five"
value = "5"
}
} Validating option valuesThis used to pass, and it will continue to pass For future data "coder_parameter" "numbers" {
name = "numebrs"
type = "number"
order = 1
default = 7
validation {
min = 6
max = 10
error = "The number must be between 6 and 10"
}
option {
name = "Seven"
value = "7"
}
option {
name = "Four"
value = "4"
}
}
|
I agree, I was asked this in a voice chat. It can be set by users, but I don't imagine they will. |
What this PR does
Parameter validation is now split into 2 modes:
CODER_VALIDATION_MODE
parameter.value
template-import
used for importing a templateparameter.value
. Will enforce validation ondefault
andoption.value
.Validation changes
See diff from
main
. Left side is the tests passing onmain
.https://www.diffchecker.com/GaUlaTze/
coder/coder
coder/coder
Future work
terraform-provider-coder/provider/parameter.go
Lines 421 to 427 in 247df4e
monotonic
in the provider, passing in the old value via env var