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

Add data sources protobuf #4962

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Conversation

JAORMX
Copy link
Contributor

@JAORMX JAORMX commented Nov 13, 2024

Summary

This adds the protobuf definition of data sources. We'll re-use this
protobuf around Minder to create the CRUD interface and reason about the
rest of the implementation.

This implements https://docs.google.com/document/d/1x8ZXs81e2vB16_vnunV4eRMOklH4Dv9vP30zKYSIKMI/edit?usp=sharing

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

Outline how the changes were tested, including steps to reproduce and any relevant configurations.
Attach screenshots if helpful.

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.

@JAORMX JAORMX requested a review from a team as a code owner November 13, 2024 12:14
@JAORMX JAORMX force-pushed the datasource-pb branch 2 times, most recently from 626835b to 46d02b6 Compare November 13, 2024 12:41
@coveralls
Copy link

coveralls commented Nov 13, 2024

Coverage Status

coverage: 54.758% (-0.007%) from 54.765%
when pulling 03ad165 on JAORMX:datasource-pb
into 84d517a on mindersec:main.

@JAORMX JAORMX force-pushed the datasource-pb branch 3 times, most recently from e4e6bc3 to 0d2d439 Compare November 13, 2024 13:49
@JAORMX JAORMX self-assigned this Nov 13, 2024
Copy link
Member

@evankanderson evankanderson left a comment

Choose a reason for hiding this comment

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

This is looking good! Since this will be a public API, I gave more-detailed feedback than I might otherwise.

proto/minder/v1/minder.proto Outdated Show resolved Hide resolved
// type is the data source type
string type = 2 [
(buf.validate.field).string = {
pattern: "^data-source$",
Copy link
Member

Choose a reason for hiding this comment

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

Do you want to use in instead of a pattern here?

Copy link
Member

Choose a reason for hiding this comment

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

Also, do we need this field now, or can we back-fill this later?

Copy link
Member

Choose a reason for hiding this comment

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

(The same could be true for version, but I'm willing to leave that one in.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't trully need it now, but it does make it work with our parsing primitives.

Copy link
Member

Choose a reason for hiding this comment

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

You mean our YAML-to-foo apply methods?

Hmm -- I'd almost prefer that those dropped the type field after parsing, particularly if type must be set by all clients.

For rule types, Charlie Egan pointed me to Rego metadata yesterday, which feels like it might enhance the rego rule authoring experience by allowing you to use e.g. Rego mode in VSCode.

proto/minder/v1/minder.proto Outdated Show resolved Hide resolved
// name is the name of the data source.
string name = 4 [
(buf.validate.field).string = {
pattern: "^[A-Za-z][-[:word:]]*$",
Copy link
Member

Choose a reason for hiding this comment

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

I assume that names are case-insensitively unique within a project?

Copy link
Member

Choose a reason for hiding this comment

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

How do data source names resolve in descendant projects?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They are case insensitive within a project. I'm thinking they'd have the same mechanics as profiles. That is, they apply and trickle down to subprojects, but are not modifiable by child projects. That allows for child projects to leverage data sources in profiles targetted at those child projects.

I suspect data sources will be more nuanced that this, so we may want to make this configurable in the future.

Copy link
Member

Choose a reason for hiding this comment

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

Not sure if you want to leave a note that these are case-insensitive and must be unique in a project and all parents

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right, I'll add a comment here.

proto/minder/v1/minder.proto Outdated Show resolved Hide resolved
proto/minder/v1/minder.proto Outdated Show resolved Hide resolved
// headers is a map of headers to send with the request.
google.protobuf.Struct headers = 3;

oneof body {
Copy link
Member

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 a message-level CEL expression to allow body only for POST/PUT/PATCH requests?

Copy link
Member

Choose a reason for hiding this comment

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

(Later is a fine answer)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How does one do that?

Copy link
Member

Choose a reason for hiding this comment

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

https://github.com/bufbuild/protovalidate/blob/main/docs/custom-constraints.md#message-level-constraints

Note, I don't consider this required, but I'm looking to seed the knowledge of this capability.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That sounds handy, though I'm still not quite sure how to use it. Mind adding this in a subsequent PR?

proto/minder/v1/minder.proto Outdated Show resolved Hide resolved
proto/minder/v1/minder.proto Outdated Show resolved Hide resolved
proto/minder/v1/minder.proto Outdated Show resolved Hide resolved
(buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE
];

message Fallback {
Copy link
Contributor

Choose a reason for hiding this comment

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

question: is embedding these structs a good idea? I remember @evankanderson having concerns on this approach.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can stop embedding these. But it's highly specific to the Rest driver, and would end up looking like RestFallback

Copy link
Contributor

Choose a reason for hiding this comment

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

It's ok for me, just raising awareness.

Copy link
Member

Choose a reason for hiding this comment

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

Embedding the structs has a few consequences on the naming:

  1. In go, the struct will be called RestDataSource_Fallback, which is slighly long. We have some worse offenders that take up about half a line...
  2. If we end up with other places where a fallback should be used, we end up needing to duplicate the message, its validation, etc. I think there are a couple places where we ended up making second messages because the first was embedded in an unrelated message.

I don't think it's a major problems, so I didn't bother to raise it here.

Embedding enums inside message definitions or nested message definitions also tends to lead to unreadably-long names in Go.

proto/minder/v1/minder.proto Show resolved Hide resolved
@JAORMX JAORMX requested a review from jhrozek November 14, 2024 11:35
evankanderson
evankanderson previously approved these changes Nov 15, 2024
Copy link
Member

@evankanderson evankanderson left a comment

Choose a reason for hiding this comment

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

LGTM, a couple comments, but nothing that needs to block.

I would prefer that the server be able to ignore the type field rather than requiring all clients to set it to a static value, but I don't feel super strongly.

// name is the name of the data source.
string name = 4 [
(buf.validate.field).string = {
pattern: "^[A-Za-z][-[:word:]]*$",
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if you want to leave a note that these are case-insensitive and must be unique in a project and all parents

// headers is a map of headers to send with the request.
google.protobuf.Struct headers = 3;

oneof body {
Copy link
Member

Choose a reason for hiding this comment

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

https://github.com/bufbuild/protovalidate/blob/main/docs/custom-constraints.md#message-level-constraints

Note, I don't consider this required, but I'm looking to seed the knowledge of this capability.

(buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE
];

message Fallback {
Copy link
Member

Choose a reason for hiding this comment

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

Embedding the structs has a few consequences on the naming:

  1. In go, the struct will be called RestDataSource_Fallback, which is slighly long. We have some worse offenders that take up about half a line...
  2. If we end up with other places where a fallback should be used, we end up needing to duplicate the message, its validation, etc. I think there are a couple places where we ended up making second messages because the first was embedded in an unrelated message.

I don't think it's a major problems, so I didn't bother to raise it here.

Embedding enums inside message definitions or nested message definitions also tends to lead to unreadably-long names in Go.

// type is the data source type
string type = 2 [
(buf.validate.field).string = {
pattern: "^data-source$",
Copy link
Member

Choose a reason for hiding this comment

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

You mean our YAML-to-foo apply methods?

Hmm -- I'd almost prefer that those dropped the type field after parsing, particularly if type must be set by all clients.

For rule types, Charlie Egan pointed me to Rego metadata yesterday, which feels like it might enhance the rego rule authoring experience by allowing you to use e.g. Rego mode in VSCode.

This adds the protobuf definition of data sources. We'll re-use this
protobuf around Minder to create the CRUD interface and reason about the
rest of the implementation.

Signed-off-by: Juan Antonio Osorio <[email protected]>
Signed-off-by: Juan Antonio Osorio <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants