Skip to content

[Connect] Add SuggestedReviewers and RequestableRoles to LoggedInUser #19466

Merged
avatus merged 16 commits intomasterfrom
michaelmyers/connect/suggested_reviewers
Jan 3, 2023
Merged

[Connect] Add SuggestedReviewers and RequestableRoles to LoggedInUser #19466
avatus merged 16 commits intomasterfrom
michaelmyers/connect/suggested_reviewers

Conversation

@avatus
Copy link
Copy Markdown
Contributor

@avatus avatus commented Dec 17, 2022

Closes https://github.com/gravitational/webapps.e/issues/410

I want to draft this first to make sure I'm going down the right path. A couple notes on the implementation.

My original idea was to pass around the auth client to a bunch of discrete methods but that was a bit weird as the defer to close the auth client was in an unintuitive spot (the daemon service). So it made a bit more sense to just open up the connection in one method and get everything we needed, which is just two methods authClient.Ping and authClient.GetAccessCapabilities.

I will be adding more comments to the new methods and fields before the pull request is finalized.

The frontend changes won't be too substantial but I wanted this side in a good spot before I PR that. The main thing is when creating a role based Access Request now, we no longer need to make a network request, as the roles are already present in the LoggedInUser. "But Michael, doesn't that mean we can remove the GetRequestableRoles handler in the backend?" Actually, we still need it as it's also used to get the minimum required roles in the new roles selection dropdown for Resource Access Requests. Although, I should probably rename it from GetRequestableRoles to GetMinimumRequireRoles or something that makes more sense for its only purpose now.

@avatus avatus requested review from gzdunek and ravicious December 17, 2022 00:06
@gzdunek
Copy link
Copy Markdown
Contributor

gzdunek commented Dec 19, 2022

I recall the discussion about the cluster.Features field that sometimes holds value and sometimes not.
With this PR we will have another two. Also, for reporting purposes I'm going to add authClusterId to Cluster that will behave the same way.
I'm wondering what we should do about it, are we okay with having so many optional fields?

Maybe we could just return GetClusterDetailsResponse in the API response? (but then it should not contain LoggedInUser, rather RequestableRoles and SuggestedReviewers)
OTOH a field like RequestableRoles fits better to the LoggedInUser, not GetClusterDetailsResponse, so I'm not sure if it is even a good idea.

@avatus
Copy link
Copy Markdown
Contributor Author

avatus commented Dec 19, 2022

I think that the decision made in that discussion is still relevant. We just document and move on. The reasoning is that the caller knows what information is available, and if documentation is written well, and future caller with know how to get that information as well.

To add on to this with a look to the future, once we keep open the clients, this will be available at anytime anyway so it might not be worth agonizing over much more.

Also, for reporting purposes I'm going to add authClusterId to Cluster that will behave the same way.

I think this is a good place for this too. ResolveFullCluster basically means "get everything we need here" and and ResolveCluster is just pulling information from disk, so adding more to ResolveFullCluster is fine when needed. IMO

Copy link
Copy Markdown
Member

@ravicious ravicious left a comment

Choose a reason for hiding this comment

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

The overall approach looks good, I left some minor questions and suggestions.

To add on to this with a look to the future, once we keep open the clients, this will be available at anytime anyway so it might not be worth agonizing over much more.

What do you mean by "available at anytime"? Wouldn't it still require a network request (and being logged in, depending on the answer to my last question)?

Comment thread lib/teleterm/clusters/cluster.go Outdated
Comment thread lib/teleterm/clusters/cluster.go Outdated
Comment thread lib/teleterm/clusters/cluster.go Outdated
// GetClusterFeatures returns a list of features enabled/disabled by the auth server
func (c *Cluster) GetClusterFeatures(ctx context.Context) (*proto.Features, error) {
var authPingResponse proto.PingResponse
func (c *Cluster) GetClusterDetails(ctx context.Context) (*GetClusterDetailsResponse, error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Could you add a comment to this method? It could note how this method grabs details that cannot be read from disk (as they are not stored on disk).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Also, could you document how this method behaves with regards to authentication? I don't remember if it's needed here or not and how the new changes affect that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Sure!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, when I said "document how this method behaves with regards to authentication" I meant documenting whether this requires the user to have a valid cert or if it's going to return some default data if the user is not logged in.

Comment thread lib/teleterm/daemon/daemon.go Outdated
Comment on lines +142 to +143
cluster.LoggedInUser = clusterDetails.LoggedInUser
cluster.Features = clusterDetails.Features
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How do you feel about setting those in cluster.GetClusterDetails?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I wouldn't mind but my reasoning is, because the name cluster.GetClusterDetails, it seems like it should return details. This can be reused elsewhere. If we chose to set them in cluster.GetClusterDetails then it would have to return a Cluster instead and should probably change the name to like... AddClusterDetails or something and that seems a bit weirder to me.

I won't die on any hill, I opt for the way it is, but I'm open to any debate on the matter.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If we chose to set them in cluster.GetClusterDetails then it would have to return a Cluster instead and should probably change the name to like... AddClusterDetails or something and that seems a bit weirder to me.

Yeah, I'm not sure what the convention for this is; the only thing which comes to my mind is something like uhhhh Enrich…?

My argument for this would consist of two points. First, since we set those fields on Cluster anyway, we could let the struct itself set them rather than doing it from outside.

Second, I generally try to avoid doing things that might be useful later unless I have reasons to believe that there will be a place to use them. So far I haven't heard about reusing those cluster details elsewhere and if we ever ended up needing them elsewhere, we could always refactor the existing code.

Ultimately this particular usage is also not something super important for me. What I care about more than that is what patterns we establish and avoiding adding stuff for which we don't have use at the moment. We can have a nuanced discussion under this PR but the next person who's going to need a similar object which requires "enriching" is going to copy what's already in the project.

Comment thread lib/teleterm/clusters/cluster.go Outdated
Comment thread lib/teleterm/clusters/cluster.go Outdated
// GetClusterFeatures returns a list of features enabled/disabled by the auth server
func (c *Cluster) GetClusterFeatures(ctx context.Context) (*proto.Features, error) {
var authPingResponse proto.PingResponse
func (c *Cluster) GetClusterDetails(ctx context.Context) (*GetClusterDetailsResponse, error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, when I said "document how this method behaves with regards to authentication" I meant documenting whether this requires the user to have a valid cert or if it's going to return some default data if the user is not logged in.

Comment thread lib/teleterm/daemon/daemon.go Outdated
Comment on lines +142 to +143
cluster.LoggedInUser = clusterDetails.LoggedInUser
cluster.Features = clusterDetails.Features
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If we chose to set them in cluster.GetClusterDetails then it would have to return a Cluster instead and should probably change the name to like... AddClusterDetails or something and that seems a bit weirder to me.

Yeah, I'm not sure what the convention for this is; the only thing which comes to my mind is something like uhhhh Enrich…?

My argument for this would consist of two points. First, since we set those fields on Cluster anyway, we could let the struct itself set them rather than doing it from outside.

Second, I generally try to avoid doing things that might be useful later unless I have reasons to believe that there will be a place to use them. So far I haven't heard about reusing those cluster details elsewhere and if we ever ended up needing them elsewhere, we could always refactor the existing code.

Ultimately this particular usage is also not something super important for me. What I care about more than that is what patterns we establish and avoiding adding stuff for which we don't have use at the moment. We can have a nuanced discussion under this PR but the next person who's going to need a similar object which requires "enriching" is going to copy what's already in the project.

@avatus avatus marked this pull request as ready for review December 20, 2022 22:13
Comment thread lib/teleterm/clusters/cluster.go Outdated
// EnrichCluster will make a network request to the auth server and add details to the
// current Cluster that cannot be found on the disk only, including details about the LoggedInUser
// and enabled enterprise features. This method requires a valid cert.
func (c *Cluster) EnrichCluster(ctx context.Context) (*Cluster, error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: since we're already in the clusters package and this is a method on the Cluster struct, to avoid repetition it might be good to drop Cluster from the name of this method and rename it to something like EnrichWithDetails.

See the third paragraph here https://go.dev/doc/effective_go#package-names

Comment thread lib/teleterm/clusters/cluster.go Outdated
Comment thread lib/teleterm/clusters/cluster.go
@github-actions github-actions Bot removed the request for review from mdwn December 21, 2022 19:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants