-
Notifications
You must be signed in to change notification settings - Fork 58
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
Enforce visibility struct tags #89
Conversation
This enforces property visibility when creating or updating ARO-HCP resource types to comply with the OpenAPI spec. The implementation encodes property visibility as struct tags. The autorest-generated API models have the useful characteristic of all struct fields being pointers. This allows us to identify which properties were explicitly provided in a create or update request. However the generated models do not have property metadata encoded into struct tags, and we can't (or shouldn't) modify the generated models to add such information. To get around this limitation, struct tags for property visibiility are encoded into the INTERNAL API models, which are not generated. The internal API models are of different Go types than the generated API models and are therefore not compatible, however the field names in each set of models are identical where property visibility is explicit (as opposed to implicitly inherited from parent types). We can therefore build a lookup table of visibility struct tags by field name to use when evaluating create and update requests using the generated API models. We call this table a StructTagMap: type StructTagMap map[string]reflect.StructTag where the map keys are dotted struct field names (e.g. "A.B.C.D"). Then, while recursing over a generated API model type, we keep track of struct field names in order to build lookup keys for the table. This effectively allows struct tags from one Go type to be grafted on to another similar but incompatible Go type.
1c2e992
to
8307aaf
Compare
@bennerv asked me (on Slack) about how we'd handle a potential field visibility change in future APIs out of concern that the metadata is on the internal structs. I wanted to address that here. It's worth noting this type of change has never occurred on ARO Classic, so it's likely to be rare here too. But we can't discount it. Suppose API versions v1-v4 (simplifying the version IDs for the sake of discussion) all had some field "foo" that was tagged Then v5 comes along and changes field "foo" to be Here's how I would handle that:
|
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 proposed mitigation for api visibility changes makes sense to me as well.
Too many single-letter variables make for poor readability, turns out.
f6b8f3f
to
cf19516
Compare
What this PR does
This enforces property visibility when creating or updating ARO-HCP resource types to comply with the OpenAPI spec. The implementation encodes property visibility as struct tags.
The autorest-generated API models have the useful characteristic of all struct fields being pointers. This allows us to identify which properties were explicitly provided in a create or update request.
However the generated models do not have property metadata encoded into struct tags, and we can't (or shouldn't) modify the generated models to add such information.
To get around this limitation, struct tags for property visibiility are encoded into the internal API models, which are not generated. The internal API models are of different Go types than the generated API models and are therefore not compatible, however the field names in each set of models are identical where property visibility is explicit (as opposed to implicitly inherited from parent types).
We can therefore build a lookup table of visibility struct tags by field name to use when evaluating create and update requests using the generated API models. We call this table a StructTagMap:
where the map keys are dotted struct field names (e.g. "A.B.C.D").
Then, while recursing over a generated API model type, we keep track of struct field names in order to build lookup keys for the table. This effectively allows struct tags from one Go type to be grafted on to another similar but incompatible Go type.
Jira: ARO-6347 : Validate metadata from api structs
Link to demo recording:
Special notes for your reviewer
Supporting documentation:
Checklist
This checklist is not enforcing, but it's a reminder of items that could be relevant to every PR.
Approvers are expected to review this list.