-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
protobuf changes in preparation for buf breaking
#26792
Conversation
138b92c
to
97df3f1
Compare
This touches every test that refers to |
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.
Thanks for tackling this, your effort is very much appreciated.
// RoleV6 represents role resource specification | ||
message RoleV6 { | ||
// RoleImpl represents role resource specification | ||
message RoleImpl { |
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 talked about this before, but I'm not a fan of this rename. There's nothing "Impl" about the protos, they are the definition of the role. This introduces a poor name to our API surface and preserves less-relevant impl details.
I would rather:
- Leave names as-is (RoleVx, RoleSpecVx). It's not great but at least it's in keeping with other types.
- Rename Role(interface)->RoleI, RoleVx->Role, RoleSpecVx->RoleSpec. Better naming overall, and a better pattern for other types to follow.
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 issue with the name with the V
in it is that we should pick a name that works across teleport versions even if newer versions support a higher resource version; case in point, if we left RoleV6
in place we'd be looking at bumping the struct name to RoleV6
even in teleport 11, which only supports role
resources between v3 and v5.
Calling it Role
with an additional rename of the Role
to RoleI
works and I like it, but what are we going to call the next incompatible protobuf message for RoleI
? Role2
? And if we're never going to have another implementation of RoleI
(and I suspect we might not), why even have an interface for 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.
Should we be versioning types
instead of versioning the resources within it, i.e. typesv1.Role
vs typesv2.Role
?
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 don't think that works, we actively want to support multiple resource versions with a single protobuf type. Also, versioning "all the types" is kind of counterproductive, you'd need to copy everything when you need a new version of a single resource.
Maybe each group of related messages should be in its own package, probably together with a dedicated service, but that doesn't help the fact that we also need to be able to refer and unmarshal any of those from storage as necessary.
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 issue with the name with the V in it is that we should pick a name that works across teleport versions even if newer versions support a higher resource version; case in point, if we left RoleV6 in place we'd be looking at bumping the struct name to RoleV6 even in teleport 11, which only supports role resources between v3 and v5.
Keeping the resource "version numbers" stable, starting from v13, wouldn't be a bad way to "fix" our chronic habit of breaking name changes. We'd have to live with multiple role versions while v12 and v11 are active, but over time it stabilizes.
Calling it Role with an additional rename of the Role to RoleI works and I like it, but what are we going to call the next incompatible protobuf message for RoleI? Role2? And if we're never going to have another implementation of RoleI (and I suspect we might not), why even have an interface for it?
The idea here is to stop with the needless renames, so we wouldn't have new Role/RoleSpec/RoleI unless it is a true breaking change.
As for the purpose of the interfaces, let's not get on that in this thread. :)
Should we be versioning types instead of versioning the resources within it, i.e. typesv1.Role vs typesv2.Role?
My 2c is no - bumping the package version is akin to saying everything changed, or enough changed in the API that we are calling it a new major entirely. The "ideal" proto API versioning scheme is that you release v1, do incremental, backwards-compatible changes and never ever release v2 (think of how much trouble we get with breaking changes in our dependencies, mostly for no benefit to us).
The proper way to evolve protos is to keep the name do backwards-compatible changes. Fields like api_version
exist to do what we do by renaming the protos (that would be a better way to go about this, btw). A message name change should only happen if the representations are truly incompatible; eg, Role
and Role2
are radically different, and that's why the name change would be necessary.
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.
Either way, I was really hoping for this PR to only deal with naming changes that are guaranteed to not affect anything functionally, so maybe that's for a future step we can deal with later, especially since we're gonna have a few more safeguards on not breaking the protobuf wire compat in place.
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.
As a side note, I'd say that this is one of the main benefits of the change detector: making it painfully clear what our bad habits are.
97df3f1
to
2ebab3d
Compare
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.
LGTM.
Sidestepping the RoleVx
question is a good call for now, better to have this land as-is. Don't forget to update the PR description.
This PR, together with the PRs on v11, v12 and v13:
buf breaking
configuration toWIRE_JSON
(which, sadly, won't prevent us from breakingencoding/json
encoding as specified bygogoproto.jsontag
, but that doesn't seem to be happening anyway)proto.WatchKind
intotypes.WatchKind
)Contributes to #26688
With this PR it should be possible to get a clean
buf breaking
betweenmaster
and the release branches, with the exception of errors pertaining to field 17 ofUserCertsRequest
in v11'sauthservice.proto
(as described in #24817) and to errors pertaining to the renaming ofRoleV5
toRoleV6
between v11 and later versions.How to address backwards compatibility checking in v11 (maybe ignoring those specific errors, and accepting the lack of backwards compatibility check for the
RoleV5
message?), and how to handle future resource versioning in general is out of scope for these PRs.