Conversation
|
Welcome @guicassolato! |
|
Hi @guicassolato. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
@arkodg @youngnick @LiorLieberman et al Sharing this as a draft for some initial feedback. Quite a few TODOs ahead still, including:
Apart from more testing of course. Please check out the test cases already covered under |
LiorLieberman
left a comment
There was a problem hiding this comment.
Thanks @guicassolato, that a very useful contribution! left some comments
| ## Known limitations | ||
|
|
||
| * Only offline translation supported – i.e. `--input_file` required | ||
| * All API operation [paths](https://swagger.io/specification/v3/#paths-object) treated as `Exact` type – i.e. no support for [path templating](https://swagger.io/specification/v3/#path-templating), therefore no `PathPrefix`, nor `RegularExpression` path types output |
There was a problem hiding this comment.
Curious to know why no support for path templating? a limitation you encountered ?
There was a problem hiding this comment.
I'm afraid there aren't many good options for that. At least, not that I could think of.
- Delete the part in each path from the first variable placeholder, all the way to the end of the path, and use
PathPrefixtype → some nasty stuff could happen with the ordering of the route rules - Use
RegularExpressiontype → not core; what flavour of regex would we use?
Path templates are not like server variables that in some case give us at least a closed set of possible values (enum.)
| spec, err := loader.LoadFromFile(filename) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to load OpenAPI spec: %w", err) | ||
| } | ||
|
|
||
| if err := spec.Validate(ctx); err != nil { | ||
| return nil, fmt.Errorf("invalid OpenAPI 3.x spec: %w", err) | ||
| } | ||
|
|
There was a problem hiding this comment.
@levikobi @mlavacca I think we should think about whether we want to preserve this all supported providers by default functionality.
For example here, if we merge this PR, if someone provides --input-file but doesn't provide provider this will always fail (because a regular yaml/json input file would never be a valid openapi spec.
@guicassolato, regardless to the above, I think running openapi provider should always be mutually exclusive to other providers.
There was a problem hiding this comment.
What's the use case for converting to all supported providers anyway?
There was a problem hiding this comment.
thats how we started, I think we need to change it, but will have a separate issue for that
| s.mu.Lock() | ||
| defer s.mu.Unlock() |
There was a problem hiding this comment.
why do we need a lock? couldn't find a place where you run addResource or getResource concurrently
There was a problem hiding this comment.
It's a good practice in general. Since the dependency is injected, the converter cannot prevent external usage of the storage.
In fact, I now realise my implementation is poor. A concurrent call to ReadResourcesFromFile would cause the entire storage to be invalidated while completely bypassing the lock, when arguably the right thing to do would be to use the context to infer whether reading a resource should be additive to the storage or clear it first. At the very least, do the latter, but not forcibly recreate the storage. I will fix that.
From the perspective of the openapi package, there is no way to tell what a client will do with those two competing processes.
Signed-off-by: Guilherme Cassolato <guicassolato@gmail.com>
a70bfe9 to
acc95e9
Compare
8df08c1 to
f9d8d13
Compare
|
/cc @mlavacca |
|
I want to mark this as ready for review, but not before coming to a decision about how to proceed for It was suggested to use command-line args for those. I would like to know how people feel about that? A few questions to drive the conversation next should we say this indeed is the desired approach:
|
|
/cc @arkodg |
+1 on this approach. having access to generic
+1 on introducing a |
mlavacca
left a comment
There was a problem hiding this comment.
Thanks for this PR! I left some initial generic comments in the review
| } | ||
|
|
||
| type storage struct { | ||
| mu sync.RWMutex |
There was a problem hiding this comment.
Why do we need thread safety here? I haven't seen any concurrency in the code, did I miss something?
There was a problem hiding this comment.
I tried to answer it here: #157 (comment)
TL;DR - I think not having it is a road to problems in the future.
Not supposed to sound unnecessarily ominous here... I do believe things change, such as – I'm making stuff up here, ok? – start supporting multiple input files (or an input directory equivalently) and, if so, why not calling ReadResourcesFromFile concurrently?
It's a small price to pay IMO, but if more people believe we're better off without the mutex, I can remove it – even if I don't understand why.
| gatewayResources := i2gw.GatewayResources{ | ||
| Gateways: make(map[types.NamespacedName]gatewayv1.Gateway), | ||
| HTTPRoutes: make(map[types.NamespacedName]gatewayv1.HTTPRoute), | ||
| TLSRoutes: make(map[types.NamespacedName]gatewayv1alpha2.TLSRoute), | ||
| TCPRoutes: make(map[types.NamespacedName]gatewayv1alpha2.TCPRoute), | ||
| ReferenceGrants: make(map[types.NamespacedName]gatewayv1beta1.ReferenceGrant), | ||
| } |
There was a problem hiding this comment.
Do we really need to perform this initialization here?
There was a problem hiding this comment.
For TLSRoutes, TCPRoutes and ReferenceGrants probably not.
Nil maps are safe to read and it kinds of make sense to me that the caller will not try to write back on the GatewayResources struct without checking first. Well, if it does, it's the caller's problem anyway.
Besides, returning nil for TLSRoutes, TCPRoutes and ReferenceGrants seems semantically the right thing to do, I reckon. I'll fix it.
Thanks!
… (mapping, filtering), instead of custom implementation
* provider-specific conf renamed as provided-specific flags * mutex to read/write provider-specific flag definitions wrapped within a type along with the definitions themselves * minor string handling enhancements (concatenation, trim prefix) * additional comments explaining logics and reasoning throughout the code (thread-safety, helper funcs and expressions, etc)
LiorLieberman
left a comment
There was a problem hiding this comment.
I think I answered all the open comments.
This looks good to me, going to approve it and I asked @mlavacca to review and leave final lgtm.
Thanks Gui!
/approve
mlavacca
left a comment
There was a problem hiding this comment.
Looks great to me, thanks @guicassolato!
/ok-to-test
/approve
/lgtm
|
/hold for implementing the requested changes from last review. |
33f49b0 to
b6d703e
Compare
b6d703e to
b174c23
Compare
mlavacca
left a comment
There was a problem hiding this comment.
/lgtm
I'll let @LiorLieberman take a final look and remove the unhold the PR
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: guicassolato, LiorLieberman, mlavacca The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/unhold |
|
@guicassolato can you change the release notes to be slightly more detailed? It will make my life easier when releasing a new version |
It was merged before I could address this, @LiorLieberman 😞 |
* Base openapi provider implementation Signed-off-by: Guilherme Cassolato <guicassolato@gmail.com> * Return without error from unimplemented ReadResourcesFromCluster func * Move slice helper functions Map nd Filter into the providers/common package * openapi package renamed openapi3 * thread-safe storage of specs * refactor: resource reader simplified as part of Provider and removing converter's unused fields * make provider resilient to invalid input openapi specs * Gateway and parentRefs * Declare github.com/getkin/kin-openapi as a direct dependency * Use github.com/samber/lo for handling slices based on common patterns (mapping, filtering), instead of custom implementation * Remove initialization of non converted kinds of resources TLSRoutes, TCPRoutes, ReferenceGrants * init func brought further upwards * code format * Provider-specific options --openapi3-backend and --openapi3-gateway-class-name Defined using a newly introduced system of dynamically registered provider-specific configuration flags. * provider-specific flag: --openapi3-gateway-tls-secret * ReferenceGrants for HTTPRoute to Backends and Gateway to TLS Secrets * fix: provider-specific configs for providers with dashes in the name * name Gateway and HTTPRoutes after the OAS title * fix: missing backend ref argument * update README * Support for backend port numbers * refactor: addressed comments from the pr * provider-specific conf renamed as provided-specific flags * mutex to read/write provider-specific flag definitions wrapped within a type along with the definitions themselves * minor string handling enhancements (concatenation, trim prefix) * additional comments explaining logics and reasoning throughout the code (thread-safety, helper funcs and expressions, etc) * log message in case of provider-specific flag supplied without a matching provider * more comments to explain the flow and decision of the converter * lint: typos, gofmt and false positives * return error in case of invalid OpenAPI 3.x spec --------- Signed-off-by: Guilherme Cassolato <guicassolato@gmail.com>
What type of PR is this?
/kind feature
What this PR does / why we need it:
Adds new
openapiprovider.Which issue(s) this PR fixes:
Closes #147
Does this PR introduce a user-facing change?:
Try this PR out: