Skip to content
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

Fix proto resource 153 marshalling for autoupdate_* resources #50688

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

hugoShaka
Copy link
Contributor

@hugoShaka hugoShaka commented Jan 2, 2025

This PR adds types.Resource153ToLegacyV2() which acts exactly like types.Resource153ToLegacy() but detects if the underlying resource153 implementation is a proto struct and uses protojson instead of regular json marshaling.

This fixes improper marshaling for resources autoupdate_config, autoupdate_version, and autoupdate_agent_rollout.

This is a band-aid solution, the proper way to address this would be to have the proto structs implement json.Marshaler.

This PR does not change types.Resource153ToLegacy() because:

  • I have no idea what implications this will have for other resources, this might change how the resource is written on disk, exported audit logs, ...
  • Automatic updates will need to be backported, we cannot retroactively change how teleport marshals resources.

Goal (internal): https://github.com/gravitational/cloud/issues/10289

@github-actions github-actions bot added size/sm tctl tctl - Teleport admin tool labels Jan 2, 2025
@github-actions github-actions bot requested review from avatus and tcsc January 2, 2025 15:49
@hugoShaka hugoShaka added the no-changelog Indicates that a PR does not require a changelog entry label Jan 2, 2025
api/types/resource_153.go Outdated Show resolved Hide resolved
Copy link
Contributor

@codingllama codingllama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by as requested by Tim.

//
// Note that CheckAndSetDefaults is a noop for the returned resource and
// SetSubKind is not implemented and panics on use.
func Resource153ToLegacyV2(r Resource153) Resource {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we supposed to favor Resource153ToLegacyV2 over Resource153ToLegacy, or should it be decided case-by-case?

Should we update Resource153ToLegacy to mention Resource153ToLegacyV2?

Could we choose a method name clearer than V2?

Alternatively, should we use the options pattern along with Resource153ToLegacy and keep it as a single method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we update Resource153ToLegacy to mention Resource153ToLegacyV2?

I don't know in which context other resource153ToLegacy.MarshalJSON is used. This might break schemas and compatibility.

At least for resource manifests, yes we should always use protojson, else all the timestamps/durations and other google magical proto types are wrong.

Could we choose a method name clearer than V2?

I'm open to any suggestion. Maybe Resource153ToLegacyWithOptions if we chose the options pattern?

Alternatively, should we use the options pattern along with Resource153ToLegacy and keep it as a single method?

Sounds good to me, but this is a breaking change, this code is in api, and we're going to backport this at least up to v15. So this would break the semver-like versioning we have.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO adding variadic options is fine even for older api/ versions, but I'd also be OK with a non-breaking variant for release branches if you think it's worth it.

I do think that keeping it to a single method is worth doing for master, as we'll carry this forward for a long time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO we should either have a separate method for "adapt this types.Resource153 that's also a proto.Message that should get marshaled with protojson into a types.Resource" or - the worst option of all but maybe the pragmatic option - we add an explicit list of concrete types that should be protojsoned in there. 😢

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(outside of other pretty fringe options like setting a protobuf extension on the message and checking that at runtime or using that extension for a custom codegen that defines MarshalJSON/UnmarshalJSON as needed)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather avoid custom codegen, the more we can rely on vanilla protoc generators the less ongoing work needs to be done (and the less weird the project gets for developers).

A custom extension or a list of types could be a solution, although I guess it depends on how much code repetition it actually saves. The list is handy in some ways, but also somewhat obscure in others (particularly if it changes the behavior of what looks to be a "simple" function).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the controversial V2 into types.ProtoResource153ToLegacy which explains more clearly the difference with the original one and doesn't have to check if the underlying resource implements proto.Message every time.

api/types/resource_153.go Show resolved Hide resolved
api/types/resource_153.go Outdated Show resolved Hide resolved
api/types/resource_153.go Outdated Show resolved Hide resolved
tool/tctl/common/collection_test.go Show resolved Hide resolved
tool/tctl/common/collection_test.go Show resolved Hide resolved
tool/tctl/common/collection_test.go Outdated Show resolved Hide resolved
tool/tctl/common/collection_test.go Outdated Show resolved Hide resolved
@public-teleport-github-review-bot public-teleport-github-review-bot bot removed the request for review from espadolini January 7, 2025 13:45
@hugoShaka hugoShaka requested a review from codingllama January 7, 2025 21:37
Copy link
Contributor

@codingllama codingllama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hugoShaka you requested a review but there are still plenty of open/unaddressed comments. I don't see significant changes in the PR either (apart from a couple of accepted suggestions). Maybe you forgot to push some commits?

hugoShaka and others added 4 commits January 8, 2025 15:04
- Change from Resource153AdapterV2 to ProtoResource153Adapter
- fix test failures and unmarshal proto resources properly
- add a failing round-trip proto 153 test case
- bonus: fix the table tesst reosurce create that did not support
  running a single row
@hugoShaka hugoShaka force-pushed the hugo/proto-resource153-marshalling branch from 80136b4 to db3eb75 Compare January 8, 2025 20:04
Comment on lines 1375 to 1379
// tctlGetAllValidations allows tests to register post-test validations to validate
// that their resource is present in "ttcl get all" output.
// This allows running test rows instead of the whole test table.
var tctlGetAllValidations []func(t *testing.T, out string)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the noisy changes in the table test but I got fed up by the test failing if I only ran a single row. Now the individual rows can be ran.

Copy link
Contributor

@codingllama codingllama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

api/types/resource_153.go Outdated Show resolved Hide resolved
tool/tctl/common/resource_command_test.go Outdated Show resolved Hide resolved
@hugoShaka hugoShaka enabled auto-merge January 8, 2025 22:57
@hugoShaka hugoShaka added this pull request to the merge queue Jan 8, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jan 8, 2025
@hugoShaka hugoShaka added this pull request to the merge queue Jan 8, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jan 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-changelog Indicates that a PR does not require a changelog entry size/sm tctl tctl - Teleport admin tool
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants