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

Updating provider config #3468

Merged
merged 4 commits into from
Jun 18, 2024
Merged

Updating provider config #3468

merged 4 commits into from
Jun 18, 2024

Conversation

jhrozek
Copy link
Contributor

@jhrozek jhrozek commented May 30, 2024

Summary

  • Protobuf changes for providers update - just adds the protobufs, nothing else

  • Extend the ProviderStore with an Update method, so far only allows updating config - we used to have a database-level Update, but not exposed through the provider store interface

  • Add a PatchProvider server handler, currently just updating the config - this is the main part of the PR. Adds a new method PatchProviderConfig to the ProviderService interface.
    This method uses the mergo library to merge the provided config with the currently stored config and then update the provider record in the DB.

  • Treat the provider config as an override, keep the defaults in the code - Since storing the whole config in the database is problematic for a number of reasons, like hard patching or worse ability to change defaults, let's change the way we treat the provider configuration in the database. Instead of storing the full config, we treat the provider config as an override. To that end, we store a structure with defaults in the code and make all the fields in the protobuf messages optional which causes the resulting Go structures to have pointers to fields instead of direct attributes.

We store the config override verbatim, after just having unmarshalled and marshalled back to get rid of any extra keys. Then we merge with the default config on retrieving the provider configuration from the database.

Fixes: #3265
Fixes: #3511

Change Type

Mark the type of change your PR introduces:

  • Bug fix (resolves an issue without affecting existing features)
  • Feature (adds new functionality without breaking changes)
  • Breaking change (may impact existing functionalities or require documentation updates)
  • Documentation (updates or additions to documentation)
  • Refactoring or test improvements (no bug fixes or new functionality)

Testing

curl -XPATCH -H "Authorization: Bearer $MINDER_BEARER_TOKEN" 'http://localhost:8080/api/v1/providers?context.project=d2f78a70-96eb-45fa-868d-d48391508e4d&context.provider=github-app-jakubtestorg' -d '{ "config": { "auto_registration": { "entities": { "repository": {"enabled": true} } }}}'

Review Checklist:

  • Reviewed my own code for quality and clarity.
  • Added comments to complex or tricky code sections.
  • Updated any affected documentation.
  • Included tests that validate the fix or feature.
  • Checked that related changes are merged.

@jhrozek
Copy link
Contributor Author

jhrozek commented May 30, 2024

@kd @peppescg would you mind adding your opinion on the API?

@evankanderson you have the most experience with protobuf, could you check the patches to the proto file and the mergo usage? Is there a nicer way?

Thank you all for taking a look.

@coveralls
Copy link

coveralls commented May 30, 2024

Coverage Status

coverage: 53.322% (-0.1%) from 53.417%
when pulling 18dfdbf on jhrozek:update_prov_cfg
into 5d33ee6 on stacklok:main.

Context context = 1;
ProviderPatch patch = 2;

google.protobuf.FieldMask update_mask = 3;
Copy link
Member

Choose a reason for hiding this comment

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

I don't recall exactly how good the library support is for update_mask. It's real handy as a client, but make sure it won't get you into too much trouble in the implementation.

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 actually don't use it now in the implementation. We might want to reconsider later, but yeah, it seems like a lot of trouble for very questionable gain (Unless the FE devs disgree, going to ping them now for API review)

},
"parameters": [
{
"name": "patch",
Copy link
Member

Choose a reason for hiding this comment

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

I'm assuming this name doesn't show up anywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does not, e.g. one calls the endpoint as:

 curl -XPATCH -H "Authorization: Bearer $MINDER_BEARER_TOKEN" 'http://localhost:8080/api/v1/providers?context.project=bcf5bc68-aa81-4f59-96ae-7dceb5c3663f&context.provider=github-app-jakubtestorg' -d '{ "config": { "auto_registration": { "enabled": ["repository"] }} }'

in other words, the body already contains the provider attributes.

pkg/api/openapi/minder/v1/minder.swagger.json Outdated Show resolved Hide resolved
return nil, status.Errorf(codes.InvalidArgument, "provider name is required")
}

err := s.providerManager.PatchProviderConfig(ctx, providerName, projectID, req.GetPatch().GetConfig().AsMap())
Copy link
Member

Choose a reason for hiding this comment

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

Should this be getting a provider instance and then calling PatchConfig on the provider instance? I'm okay with having this on providerManager, I just don't have a feel for when we create an instance and when we don't.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, me neither. Getting a provider instance and then patching it is pretty much what the implementation of PatchProviderConfig does now.

@dmjb do you have an opinion since you created the ProviderManager interface?

@jhrozek jhrozek force-pushed the update_prov_cfg branch 3 times, most recently from 1ba11d6 to 614f0d7 Compare June 3, 2024 12:03
@jhrozek jhrozek force-pushed the update_prov_cfg branch 2 times, most recently from 8438157 to 3dde870 Compare June 13, 2024 07:59
@evankanderson
Copy link
Member

evankanderson commented Jun 13, 2024

(let me know if you want further reviews)

@evankanderson I think yes at this point. There's an alternative approach in PR #3588 that's pure-proto based, but after discussions with @blkt and @dmjb we lean towards going with this simple approach for now and then @blkt would instead try to extend the code with go-generated code that would allow us to use the fieldMask on individual config fields. But in the interest of time, let's do this approach of get-modify-put config.

@jhrozek jhrozek changed the title WIP: Updating provider config rpc Updating provider config Jun 14, 2024
@jhrozek jhrozek marked this pull request as ready for review June 14, 2024 14:32
@jhrozek jhrozek requested a review from a team as a code owner June 14, 2024 14:32
blkt
blkt previously approved these changes Jun 17, 2024
This merely adds the PatchProvider rpc changes to keep the other patches
in the same PR minimal and don't mix the RPC changes with the logic
changes.
…dating config

The providerStore.Update method only exposes the new config as a
parameter to change. Others might be added as we have a use-case for
them - this is not public API.
Building atop the providerStore.Update method, we add a PatchProvider
handler that so far only allows updating the config.
Since storing the whole config in the database is problematic for a
number of reasons, like hard patching or worse ability to change
defaults, let's change the way we treat the provider configuration in
the database. Instead of storing the full config, we treat the provider
config as an override. To that end, we store a structure with defaults
in the code and make all the fields in the protobuf messages optional
which causes the resulting Go structures to have pointers to fields
instead of direct attributes.

We store the config override verbatim, after just having unmarshalled
and marshalled back to get rid of any extra keys. Then we merge with the
default config on retrieving the provider configuration from the
database.
@jhrozek jhrozek merged commit 67208c5 into mindersec:main Jun 18, 2024
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants