-
Notifications
You must be signed in to change notification settings - Fork 43
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
Allow full profile updates through the PATCH handler #2990
Conversation
if err != nil { | ||
return nil, util.UserVisibleError(codes.Internal, "error updating profile: %v", err) | ||
} | ||
for _, attr := range updateMask.Paths { |
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 explicitly disallow patching some fields here? I think it's OK to leave that to the Update but wanted to check explicitly...
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.
Subscription ID is one which we do not want to allow to be changed.
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.
Leaving this as "Request changes" until the question around editing bundle profiles is settled.
After talking to @jhrozek offline, I understand why that check can be deleted. I would like to see a test added for the bundled subscription ID case though. |
I forgot to issue a profile update message on patching a profile. Since the profile update message is currently nicely encapsulated in `sendNewProfileEvent` which is a private method of the Profile service and we already have PR mindersec#2990 that would move all of the Patch functionality to that service and remove the current Patch handler implementation, I decided to create a bespoke message for now. This code will be removed once we merge PR mindersec#2990.
I forgot to issue a profile update message on patching a profile. Since the profile update message is currently nicely encapsulated in `sendNewProfileEvent` which is a private method of the Profile service and we already have PR mindersec#2990 that would move all of the Patch functionality to that service and remove the current Patch handler implementation, I decided to create a bespoke message for now. This code will be removed once we merge PR mindersec#2990.
I forgot to issue a profile update message on patching a profile. Since the profile update message is currently nicely encapsulated in `sendNewProfileEvent` which is a private method of the Profile service and we already have PR #2990 that would move all of the Patch functionality to that service and remove the current Patch handler implementation, I decided to create a bespoke message for now. This code will be removed once we merge PR #2990.
I added a test and moved a bunch of the patch handler to profile service. btw this PR is NOT important to merge at this moment |
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.
Only nits; I like the new code much better! Thanks!
internal/profiles/service.go
Outdated
ctx context.Context, | ||
projectID uuid.UUID, | ||
profileID uuid.UUID, | ||
subscriptionID uuid.UUID, |
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.
Do we want to allow PATCH
with subscriptions? If not, could we drop this argument?
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 looks like we pass uuid.Nil
as the argument to UpdateProfile
from the other gRPC endpoint, so it looks like we the PATCH-on-Subscription codepath is effectively dead...)
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.
probably not, you're right. We'll likely to only update subscription profiles through a replace, not patch.
internal/profiles/service.go
Outdated
oldReflect := oldProfilePb.ProtoReflect() | ||
patchReflect := patchPb.ProtoReflect() |
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.
Do you want to do these inside the for
loop?
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, fixed
internal/profiles/service.go
Outdated
updateMask *fieldmaskpb.FieldMask, | ||
qtx db.Querier, | ||
) (*minderv1.Profile, error) { | ||
oldProfilePb, err := getProfilePBFromDB(ctx, profileID, projectID, qtx) |
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.
Do you want to call old
"base" here? It's slightly confusing, because we go through the steps and then pass old
to the Update method.
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, renamed
internal/profiles/service.go
Outdated
} | ||
|
||
func patchProfilePb(oldProfilePb, patchPb *minderv1.Profile, updateMask *fieldmaskpb.FieldMask) { | ||
// if there is no update mask, return the old profile. The grpc-rest gateway always sets the update mask |
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.
This is confusing, as it says "return", but there's no return value. Maybe you mean "an empty field mask means apply no changes"?
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 think the original version of the code was trying to return a modified profile instead and I didn't update the comment.
Thanks, fixed.
We used to use a bespoke PATCH handler to update profiles but the PATCH method only allowed changing alert and remediate. We can make the code simpler and allow more updates by modifying the existing profile using the UpdateMask and then just relaying the update to the existing UpdateProfile method of the Profile service. Examples: Adding a rule to a profile: ``` curl -XPATCH -H "Authorization: Bearer $MINDER_BEARER_TOKEN" 'http://localhost:8080/api/v1/profile/ce746798-c30c-46f3-8a12-0654747b49ec?context.project=1900c9f6-ef0f-43e4-8af7-108beb72de0e&context.provider=github' -d '{"name":"dependabot-enabled-profile", "labels":[], "buildEnvironment":[], "repository":[{"type":"dependabot_configured","params":null,"def":{"apply_if_file":"requirements.txt","package_ecosystem":"pypi","schedule_interval":"weekly"},"name":"dependabot_configured"},{"type":"dependabot_configured","params":null,"def":{"apply_if_file":"go.mod","package_ecosystem":"gomod","schedule_interval":"weekly"},"name":"dependabot_configured_go"}], "pullRequest":[], "remediate ":"on", "alert":"off", "type":"", "version":"", "displayName":"gah" } ``` Remove the rule back: ``` curl -XPATCH -H "Authorization: Bearer $MINDER_BEARER_TOKEN" 'http://localhost:8080/api/v1/profile/ce746798-c30c-46f3-8a12-0654747b49ec?context.project=1900c9f6-ef0f-43e4-8af7-108beb72de0e&context.provider=github' -d '{"name":"dependabot-enabled-profile", "labels":[], "buildEnvironment":[], "repository":[{"type":"dependabot_configured","params":null,"def":{"apply_if_file":"requirements.txt","package_ecosystem":"pypi","schedule_interval":"weekly"},"name":"dependabot_configured"}], "pullRequest":[], "remediate":"on", "alert":"off", "type":"", "version":"", "displayName":"gah"}}' ``` Fixes: mindersec#2971
@evankanderson thanks for the review, I fixed your comments in separate patches for easier review. |
Summary
We used to use a bespoke PATCH handler to update profiles but the PATCH
method only allowed changing alert and remediate. We can make the code
simpler and allow more updates by modifying the existing profile using
the UpdateMask and then just relaying the update to the existing
UpdateProfile method of the Profile service.
Fixes: #2971
Change Type
Mark the type of change your PR introduces:
Testing
There are unit tests but you can also test with curl:
Adding a rule to a profile:
Remove the rule back:
Review Checklist: