-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
tooling: generate JSON schemas from protobuf definitions #27640
tooling: generate JSON schemas from protobuf definitions #27640
Conversation
…n-jsonschema repo Signed-off-by: norbjd <[email protected]>
Signed-off-by: norbjd <[email protected]>
bazel/jsonschema/com_github_chrusty_protoc_gen_jsonschema_deps.bzl
Outdated
Show resolved
Hide resolved
Signed-off-by: norbjd <[email protected]>
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.
hi @norbjd thanks for working on this
i worked on it previously and almost got it working at that time, but other priorities took over
it was quite a while ago, so i dont rem exactly, but i think it was not implemented optimally
i think probably this requires use of a bazel aspect
bazel/jsonschema/BUILD
Outdated
# may be generated by tools/proto_format/proto_sync.py (like proto_library's deps in api/BUILD)? | ||
PROTOS = [ | ||
"@envoy_api//contrib/envoy/extensions/filters/http/dynamo/v3:pkg", | ||
"@envoy_api//contrib/envoy/extensions/filters/http/golang/v3alpha:pkg", |
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.
we dont want to do this
its possible that this list could be derived by using a genquery
but almost certainly this should be implemented using an aspect, which allows you to traverse dependencies, and visit individual targets
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.
👍 done with the aspect, see tools/protojsonschema_with_aspects
(and slight modification on tools/api_proto_plugin/plugin.bzl
).
i would suggest a first step to just focus on getting a working |
Cool. This is awesome. |
Signed-off-by: norbjd <[email protected]>
Signed-off-by: norbjd <[email protected]>
CC @envoyproxy/dependency-shepherds: Your approval is needed for changes made to |
Hello @phlax 👋 and thanks for your useful comments!
I'm not sure to understand sorry 😕 There is already a $ ls -1 bazel-out/*/bin/external/com_github_chrusty_protoc_gen_jsonschema/cmd/protoc-gen-jsonschema/protoc-gen-jsonschema_/protoc-gen-jsonschema
bazel-out/k8-opt-exec-2B5CBBC6/bin/external/com_github_chrusty_protoc_gen_jsonschema/cmd/protoc-gen-jsonschema/protoc-gen-jsonschema_/protoc-gen-jsonschema
# check it works by just displaying version
$(!!) -version
v1.4.0 This is the binary used to generate the JSON schemas I've shown in my PR description. Have I misunderstood something, do you have something else in mind for "getting a working |
could you separate out adding protoc-gen-jsonschema to its own PR please - we can then ensure everything is working with that before looking at adding an aspect |
Signed-off-by: norbjd <[email protected]>
… + jq + write_source_files Signed-off-by: norbjd <[email protected]>
Signed-off-by: norbjd <[email protected]>
Hello @phlax, done 👍 #27661 I've put About aspects, I have played a little with them, based on your work on Anyway, for now, even if it's not the right solution, and as an experiment to try to better understand bazel (please bear with me, I'm still a beginner in bazel 🙏), I have considered using |
/wait for #27661 |
so, @norbjd once #27661 lands we can figure out the next step im also trying to think of the overall plan - im thinking the final outcome we want is that CI is automatically publishing the schemas somewhere re use of an aspect - my niggling doubt is that im wondering if we ran i think when i tried this before i did it using an aspect, and then merged the files that it created (with various fixes/cleanups) - im wondering if that is necessary and whether this could actually be a lot simpler |
Signed-off-by: norbjd <[email protected]>
Signed-off-by: norbjd <[email protected]>
Hello @phlax, sorry for the late reply, I've been busy this week 🥵 I've rebased that branch and made a few changes to make
You're right. To take a concrete example, if we generate all JSON schemas from all existing protos, and if we take a look at the generated "envoy.config.cluster.v3.CircuitBreakers.Thresholds.RetryBudget": {
"properties": {
"budget_percent": {
"$ref": "#/definitions/envoy.type.v3.Percent",
"additionalProperties": true
},
"min_retry_concurrency": {
"additionalProperties": true,
"type": "integer"
}
},
"additionalProperties": true,
"type": "object"
} But, this exact same definition is also found in other generated JSON schemas:
However, this may not be something generalizable to all protos, for example for specific filters definition that don't appear in the |
/wait @phlax is on vacation at the moment so may be less responsive for a while. |
apologies @norbjd ive been a bit busy - ill look through this again as soon as i get chance |
Sorry, I didn't even notice this was assigned to me until right now. I don't think I'd be particularly helpful anyway though, I'm not familiar with IDE json-based validation, nor with bazel aspects (my earlier comment was just because I was on-call and sweeping through the things that were stuck - I guess at least I managed to help move it along a little!) I'm going to unassign me to avoid causing confusion. |
@phlax friendly ping on next steps for this PR. |
friendly ping @phlax |
huge apology for delayed response - it just that this will take some time to review/test and ive been quite busy ill try and look at this before the end of the week /wait-any |
Signed-off-by: norbjd <[email protected]>
Hello 👋 Kindly bumping this PR as it has been two months without activity 😇 As a quick summary, this PR is "blocked" right now because I'm defining two ways to generate JSON schemas, and we need to decide on the best one:
Personally, I'm not sure which one is the best solution as (1.) is potentially impacting the existing, because we have to import As soon as we decide on a solution, I just need to remove the files related to the other one, and it should be good to go 👍 Thank you! |
again a huge apology - entirely my fault - the delay is that this takes some testing/iteration and i have been v busy we have a batch of releases about to go out - once these are out of the way i will priroritize this - apologies again @norbjd |
/wait-any pending project release and further review |
@phlax, Do you have an timeframe on when you might have free cycles to tackle this review? I'm excited to be able to have some autocomplete support in VSCode for the yaml files, even if it's minimal at first! Thanks in advance. |
apologies it again slipped my mind and the holiday season kicked in no promises - but ill try and look at this next week |
@phlax ping? |
@phlax has been pinged again through back channels more aggressively, so be assured this is still in the pipeline for attention, it's just a big thing and time is hard to find. |
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.
@norbjd apologies for taking so long to review this
lets land this and iterate, i think its a great step forward, lgtm
Thanks @phlax! Just to remind, this PR showed 2 solutions because I was really unsure of the best one:
I'm not sure we needed both solutions to be merged to be fair. But, if you prefer one, tell me and I'll gladly make another PR to keep only one ;) |
thanks @norbjd i vaguely remembered that to be the case - my preference is for the aspect approach - that was kinda what delayed me - wanting to test it |
Thank you for all of the work! I tried to catch up on the latest progress and how to use the artifacts of this, but I only had partial luck when trying to use it with the VSCode YAML extension. Roughly speaking, I:
When in the root of a envoy yaml file, I indeed do see that autocomplete is working and provides pop up info. 🎉 As soon as I enter a field that uses a typed_config, the autocomplete can only suggests ie:
Again, thank you for all the effort! I'm not sure if I'm jumping in early and we're knowingly not yet at a stage where this is supposed to work- or if I'm perhaps doing something wrong. As an aside, it would be nice to generate these JSON artifacts as part of the release process so that others do not need to repeat the build steps. |
Hello @davidfiala 👋 I remember that the generated JSON schema was not perfect for some fields (namely the filters). This is because we can't easily express in the JSON schema that fields in Anyway first, just to explain why auto-completion on "filters": {
"items": {
"$ref": "#/definitions/envoy.config.cluster.v3.Filter"
},
"type": "array"
} And the "envoy.config.cluster.v3.Filter": {
"properties": {
"name": {
"minLength": 1,
"type": "string"
},
"typed_config": {
"properties": {
"type_url": {
"type": "string"
},
"value": {
"type": "string",
"format": "binary",
"binaryEncoding": "base64"
}
},
"additionalProperties": true,
"type": "object"
}
},
"additionalProperties": true,
"type": "object",
"title": "[#protodoc-title: Upstream filters]\n Upstream filters apply to the connections to the upstream cluster hosts."
} As you can see, in
Note that this is just theoretical and might not be as easy as it seems! The library used here to convert protos to JSON schema probably lacks support for this.
Completely agree on this. As said in this comment, "the final outcome we want is that CI is automatically publishing the schemas somewhere". But, alas, this has not been done yet. Merging this PR was just a first step to introduce JSON schemas, so there is still a lot of things to do! Unfortunately, I'm not sure if this is a priority today. |
hi @norbjd @davidfiala just to clarify that the name is not so important wrt extensions - its more the trying to rem whether i got this working when i first tried it - i thought i had - either way, i think it should be possible if non-trivial would be great to get this working good enough to be usable, at that point we can think about publishing somewhere |
Commit Message
Generate JSON schemas from protobuf definitions. This is mostly useful to validate syntax when writing the config, using for example IDE extensions (the most well known is probably redhat's vscode-yaml one).
Additional Description
The process to write correct envoy YAML configuration files feels inefficient. As of now, there is no way to validate the syntax while editing the config - except raw YAML validation - so the process (at least for me) is basically always: 1) write config file and 2) run
validate
command using an Envoy Docker image (with the version I want). As a result, the developer feedback loop is slow.This PR is an attempt to generate JSON schemas from protobuf definitions, so that they could be included in our favorite IDEs for validation. There might be other use cases I have not in mind right now that could now be possible with these.
Some examples of what it looks like after generating and using the JSON schemas (in vscode).
Autocompletion
Fields:
Values (interestingly, autocompletion for enums like the following also gives numerical values, but it works!):
Syntax validation (here, typing)
Note that there are already a few issues mentioning this:
envoyconf
linting/validation tool #13233And some attempts to solve them:
There is even one draft PR on Envoy:
However, there is no activity on these ones for at least one year (and often more) as of today.
The main reason and the main blocker for this was, I think, the fact that it was not really easy to integrate the actual plugin to generate JSON schemas from protobuf files (https://github.com/chrusty/protoc-gen-jsonschema). This is mostly because this external repository was not "bazelified". So, in order to reduce the amount of code in Envoy codebase and to simplify, I've decided to first add Bazel support to that plugin: chrusty/protoc-gen-jsonschema@master...norbjd:add-bazel, just for Envoy. If everything works here with my PR on Envoy, then I'll create the PR to merge upstream and contribute to chrusty's repository.
Once done, it's now "pretty" easy to generate JSON schemas from Envoy protobuf files. I'm putting "pretty" between quotes because I'm not a Bazel expert, and it looks like there are many conventions for Bazel in Envoy that I don't fully master. But since I had some bandwidth to work on that, I'm happy to be able to contribute! I still have a few questions, and will open a comment in this PR for everyone of them, so that Bazel masters could give me some advice. I'm also available on Slack (my username is
norbjd
).Finally, there is still one remaining question about the expected output. Ideally, we'd like to have a single JSON schema file (or two maybe, one for v2 and one for v3), but the protoc plugin does not handle this, so some work may need to be done in Envoy repository to merge all generated JSON schemas together. This/these final JSON files could be exposed on Envoy website, or in a first step, just downloadable from Github releases artifacts. I guess it's something that could be done in a second step to not overload this PR and avoid scope creep.
Below you can find commands to test the feature.
1. Setup a clean environment with docker
2. Prepare the environment
All commands from here are run inside the docker container.
3. List new rules
There are two ways to generate JSON schemas: using
rules_proto_grpc
or an aspect.I don't know which one to use yet, so I've done both ways and let Envoy people decide.
4. Build
4.1. Using
rules_proto_grpc
4.2. Using an aspect
Risk Level
Low
Testing
I'm not really sure how to test this, other than just building the JSON schemas.
Docs Changes
/
Release Notes
Generate JSON schemas from proto files.
Platform Specific Features
/
Fixes
#13078, #13233, #13254.