-
Notifications
You must be signed in to change notification settings - Fork 558
add validate tag for the purpose of required field #886
Conversation
@@ -18,7 +32,7 @@ type ResourcePurchasePlan struct { | |||
// resource definition in a JSON template. | |||
type ContainerService struct { | |||
ID string `json:"id,omitempty"` |
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.
Please also help check if i missed any required field.
@acs-bot test this please |
Any plans to enforce this in validation? |
is it an experiment on 2017-07-01? |
what go validator package do you plan to use? Is there anything more than "required/optional" we could add to tag? |
@weinong , could be an experiment. |
pkg/api/v20170701/types.go
Outdated
} | ||
|
||
// CustomProfile specifies custom properties that are used for | ||
// cluster instantiation. Should not be used by most users. | ||
type CustomProfile struct { | ||
Orchestrator string `json:"orchestrator,omitempty"` | ||
Orchestrator string `json:"orchestrator,omitempty" validate:"required"` |
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 this a required field?
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 mark it as required, in the sense, CustomProfile is there.
However CustomProfile itself is not required.
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.
Take a closer look, CustomProfile doesn't have any validate function. I don't want to add required here anymore.
pkg/api/v20170701/types.go
Outdated
Count int `json:"count"` | ||
DNSPrefix string `json:"dnsPrefix"` | ||
VMSize string `json:"vmSize"` | ||
Count int `json:"count" validate:"required"` |
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.
Doesn't master count have a default value? Same goes for VMSize, I.e. its not a required field
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.
Master Count has a default value in the implementation of az cli
.
You can think of az cli
is the helper for user to put together the api model. This is the validation tag for this api model.
It works, after az cli
generate the api model. We validate if it provide the required fields.
Keep in mind, this validate tag only works on validate the generated api model.
pkg/api/v20170701/types.go
Outdated
// Current it is not used in any logic yet | ||
// TODO, we could possibly use this tag in all the Validate functions | ||
const ( | ||
ValidateTag = "validate" |
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.
Instead of calling it "validate" , why not "required" or "isrequired"?
E.g.:
Location string `json:"location,omitempty" isrequired:"true"
or
Location string `json:"location,omitempty" required:"true"
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 will use whatever the validator package specified. My other comment has the options. Pick one that you favor more. They have different syntax.
I have looked a few popular validator package. https://github.com/asaskevich/govalidator |
@rjtsdl I haven't tried but just looked at its README. I think if the package can meet our container service validation, such as range, set, or even regex, that should be fine. |
I will pick this one. https://github.com/go-playground/validator |
289fc38
to
ea8e93c
Compare
@JackQuincy @amanohar @JiangtianLi @weinong , i have imported and applied https://github.com/go-playground/validator.v9. I don't expect any behavior change. I only did minimal change in v20170701/validate.go file. It proves the concept that, by introducing the package, things get clear and easier to do validation. We should be able to leverage this package further, when we get more and more familiar with it. |
DNSPrefix string `json:"dnsPrefix"` | ||
VMSize string `json:"vmSize"` | ||
OSDiskSizeGB int `json:"osDiskSizeGB,omitempty"` | ||
Count int `json:"count" validate:"required,eq=1|eq=3|eq=5"` |
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.
If we specify count
with tags like this. It will be automatically validated. No need to write functions to handle it. TAL this file, and compare with what i have removed in the validate.go file. You will get the idea here.
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'm curious about the error message. any example?
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, when i specify count=2
FATA[0000] error parsing the api model: Key: 'MasterProfile.Count' Error:Field validation for 'Count' failed on the 'eq=
1|eq=3|eq=5' tag
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.
Was that a fatal error log or a error message returned? if it is a fatal error log we can't use this framework
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 is from the cmd below. The package itself doesn't panic or fatal.
./cmd/deploy.go: log.Fatalf("error parsing the api model: %s", err.Error())
./cmd/generate.go: log.Fatalf("error parsing the api model: %s", err.Error())
./cmd/upgrade.go: log.Fatalf("error parsing the api model: %s", err.Error())
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.
the error msg at current form is not possible to be localized. So i'm strongly against doing this.
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.
The returned error points out the struct/field/tag that failed so we could take that info than use it to generate a localized error message. But it would require us to make a bunch of if statements or a big switch case that works like an if else chain.
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, that is exactly what i am doing. @JackQuincy , i should look at your comment earlier :(
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.
@weinong , localization is handled now. It is not the blocker anymore. PTAL
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.
The error message for the same MasterProfile.Count=2, would be like
FATA[0000] error parsing the api model: MasterProfile count needs to be 1, 3, or 5
@rjtsdl From the end-user perspective, what changes? |
} | ||
return nil | ||
} | ||
|
||
func validatePoolName(poolName string) error { | ||
// we will cap at length of 12 and all lowercase letters since this makes up the VMName | ||
poolNameRegex := `^([a-z][a-z0-9]{0,11})$` |
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.
We can take a look at regex later, when this package get more mature. This is the current state for regex.
regex
a regex validator won't be added because commas and = signs can be part
of a regex which conflict with the validation definitions. Although
workarounds can be made, they take away from using pure regex's.
Furthermore it's quick and dirty but the regex's become harder to
maintain and are not reusable, so it's as much a programming philosiphy
as anything.
In place of this new validator functions should be created; a regex can
be used within the validator function and even be precompiled for better
efficiency within regexes.go.
And the best reason, you can submit a pull request and we can keep on
adding to the validation library of this package!
@seanknox , Should be no behavior change for end user. |
ea8e93c
to
b7cae2d
Compare
pkg/api/v20170701/types.go
Outdated
DNSPrefix string `json:"dnsPrefix"` | ||
FQDN string `json:"fqdn"` | ||
Ports []int `json:"ports,omitempty"` | ||
StorageProfile string `json:"storageProfile"` | ||
StorageProfile string `json:"storageProfile" validate:"StorageAccount|ManagedDisks|len=0` | ||
VnetSubnetID string `json:"vnetSubnetID,omitempty"` |
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.
Add 'eq' condition to the tag
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.
Fixed, thx
b7cae2d
to
0275c3b
Compare
0275c3b
to
2e4ceca
Compare
2e4ceca
to
bd44bf9
Compare
0dfec88
to
2d114e7
Compare
} | ||
return nil | ||
} | ||
|
||
func handleValidationErrors(e validator.ValidationErrors) error { |
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.
@JackQuincy @JiangtianLi @weinong
Now, this function will be called to handle the validator.ValidationErrors
, it is called only in one place.
I noticed, I have a few hard coded strings here. However, it will be no difference with before, when we call
validateName(l.AdminUsername, "LinuxProfile.AdminUsername")
We also need to pass a hard coded string as a parameter.
This function is better in the sense, it has all hard-code strings in one place.
37f6751
to
19d4760
Compare
Outside of the scope of this PR but discussed with @rjtsdl that some of the fields like count, vmSize that were not required before in the ACS service are not required. This impacts the model of asking the users for minimal set of inputs to stand up a cluster (an issue was opened to track discussion around this). |
@acs-bot test this please |
Reviewed 1654 of 1656 files at r2, 1 of 2 files at r5, 1 of 1 files at r6. pkg/api/v20170701/validate.go, line 105 at r5 (raw file): Previously, rjtsdl (Jingtao Ren) wrote…
this is pretty cool pkg/api/v20170701/validate.go, line 107 at r6 (raw file):
err.Namespace() can be called once and re-used throughout this function. Comments from Reviewable |
19d4760
to
88291e3
Compare
@weinong , address err.Namespace() suggestion. Thx. Btw, don't know how to reply a comment from Reviewable :( |
don't overwrite the commits please. |
Ah, sure, will add new commits. |
checked with everybody offline. I will merge this. |
What this PR does / why we need it:
Currently in the versioned api definition, no way to know whether a field is required from user's input. The omitempty is mainly used for marshal. We need another tag for validation. By doing this, we could give user(the developer) a clear view of our api model definition without checking lines of validation code.
Which issue this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close that issue when PR gets merged): fixes #884Special notes for your reviewer:
I propose to add the tag. Check this
I picked this validator package https://github.com/go-playground/validator.
Release note:
This change is