-
Notifications
You must be signed in to change notification settings - Fork 40.1k
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
Serve OpenAPI spec with single /openapi/v2 endpoint #59293
Serve OpenAPI spec with single /openapi/v2 endpoint #59293
Conversation
63ee6d3
to
bf5dc3a
Compare
@@ -175,6 +175,7 @@ func ClusterRoles() []rbac.ClusterRole { | |||
// do not expand this pattern for openapi discovery docs | |||
// move to a single openapi endpoint that takes accept/accept-encoding headers | |||
"/swagger.json", "/swagger-2.0.0.pb-v1", | |||
"/openapi", "/openapi/*", |
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.
Saving the place for /openapi/v3
in future. Also, we will add /openapi
(which returns list of supported versions) as a followup.
fb23bf2
to
173b0ec
Compare
@@ -77,6 +78,10 @@ func computeETag(data []byte) string { | |||
return fmt.Sprintf("\"%X\"", sha512.Sum512(data)) | |||
} | |||
|
|||
// NOTE: [DEPRECATION] We will announce deprecation for format-separated endpoints for OpenAPI spec, |
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.
Switch is in 1.10
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.
Sent out PR to correct that in kube-openapi
decipherableFormat = "application/json" | ||
} | ||
w.Header().Add("Vary", "Accept") | ||
|
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 needs to work with actual Accept headers, which are allowed to specify a prioritized list of accepted content types. For example, a request could indicate it accepts some unknown protobuf format, the known protobuf format, yaml, and json, and the server would be expected to return the known protobuf format
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.
For example, see parsing/prioritization/matching in
kubernetes/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/negotiation/negotiate.go
Lines 284 to 312 in 228b7d5
func NegotiateMediaTypeOptions(header string, accepted []AcceptedMediaType, endpoint EndpointRestrictions) (MediaTypeOptions, bool) { | |
if len(header) == 0 && len(accepted) > 0 { | |
return MediaTypeOptions{ | |
Accepted: &accepted[0], | |
}, true | |
} | |
var candidates candidateMediaTypeSlice | |
clauses := goautoneg.ParseAccept(header) | |
for _, clause := range clauses { | |
for i := range accepted { | |
accepts := &accepted[i] | |
switch { | |
case clause.Type == accepts.Type && clause.SubType == accepts.SubType, | |
clause.Type == accepts.Type && clause.SubType == "*", | |
clause.Type == "*" && clause.SubType == "*": | |
candidates = append(candidates, candidateMediaType{accepted: accepts, clauses: clause}) | |
} | |
} | |
} | |
for _, v := range candidates { | |
if retVal, ret := acceptMediaTypeOptions(v.clauses.Params, v.accepted, endpoint); ret { | |
return retVal, true | |
} | |
} | |
return MediaTypeOptions{}, false | |
} |
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! PR sent in kube-openapi repo to use that kubernetes/kube-openapi#36
@@ -329,7 +333,7 @@ func (d *DiscoveryClient) ServerVersion() (*version.Info, error) { | |||
|
|||
// OpenAPISchema fetches the open api schema using a rest client and parses the proto. | |||
func (d *DiscoveryClient) OpenAPISchema() (*openapi_v2.Document, error) { | |||
data, err := d.restClient.Get().AbsPath("/swagger-2.0.0.pb-v1").Do().Raw() | |||
data, err := d.restClient.Get().AbsPath("/openapi/v2").SetHeader("Accept", mimePb).Do().Raw() |
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.
Cannot change this until 1.11 to maintain one version skew compatibility in kubectl
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 can do that or we can try new endpoint first and then fallback on the old one. Pro: we have new endpoints in one version and if there is any problem, we would figure it out before completely remove the old endpoint. Con: new clients will have a little more latency to talk to old clusters.
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 was working on the fallback logic after I sent out the PR. Thanks for pointing that out :) Updated.
"application/com.github.proto-openapi.spec.v2@v1.0+protobuf": o.getSwaggerPbBytes, | ||
} | ||
|
||
handler.Handle(servePath, gziphandler.GzipHandler(http.HandlerFunc( |
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.
Does this handle varying on Accept-Encoding as well?
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.
Yes, according to
if acceptsGzip(r) { |
if err != nil { | ||
return err | ||
} | ||
return s.openAPIVersionedService.UpdateSpec(specToServe) |
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 know that versionedService's updateSpec will also update the spec fo the old endpoint? We should verify that and add a comment here to document we confirmed that.
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.
Comment added
return nil | ||
} | ||
specToServe, err := s.buildOpenAPISpec() | ||
if err != nil { | ||
return err | ||
} | ||
return s.openAPIService.UpdateSpec(specToServe) | ||
err = s.openAPIService.UpdateSpec(specToServe) |
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 am pretty sure somewhere in aggregation, we access /swagger.json file. It should be somewhere in kube-openapi repo. Can you please verify that we updated that code to try version'ed endpoint first (with fallback to /swagger.json endpoint).
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 didn't find /swagger.json
being accessed in kube-openapi repo. Do you mean staging/src/k8s.io/kube-aggregator/pkg/controllers/openapi/downloader.go
? Change added
@@ -329,7 +333,7 @@ func (d *DiscoveryClient) ServerVersion() (*version.Info, error) { | |||
|
|||
// OpenAPISchema fetches the open api schema using a rest client and parses the proto. | |||
func (d *DiscoveryClient) OpenAPISchema() (*openapi_v2.Document, error) { | |||
data, err := d.restClient.Get().AbsPath("/swagger-2.0.0.pb-v1").Do().Raw() | |||
data, err := d.restClient.Get().AbsPath("/openapi/v2").SetHeader("Accept", mimePb).Do().Raw() |
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 can do that or we can try new endpoint first and then fallback on the old one. Pro: we have new endpoints in one version and if there is any problem, we would figure it out before completely remove the old endpoint. Con: new clients will have a little more latency to talk to old clusters.
4d3ae79
to
b07f6d4
Compare
b07f6d4
to
119da39
Compare
119da39
to
f422dec
Compare
/retest Review the full test history for this PR. Silence the bot with an |
7 similar comments
/retest Review the full test history for this PR. Silence the bot with an |
/retest Review the full test history for this PR. Silence the bot with an |
/retest Review the full test history for this PR. Silence the bot with an |
/retest Review the full test history for this PR. Silence the bot with an |
/retest Review the full test history for this PR. Silence the bot with an |
/retest Review the full test history for this PR. Silence the bot with an |
/retest Review the full test history for this PR. Silence the bot with an |
/test all [submit-queue is verifying that this PR is safe to merge] |
/retest Review the full test history for this PR. Silence the bot with an |
/test all [submit-queue is verifying that this PR is safe to merge] |
/retest Review the full test history for this PR. Silence the bot with an |
6 similar comments
/retest Review the full test history for this PR. Silence the bot with an |
/retest Review the full test history for this PR. Silence the bot with an |
/retest Review the full test history for this PR. Silence the bot with an |
/retest Review the full test history for this PR. Silence the bot with an |
/retest Review the full test history for this PR. Silence the bot with an |
/retest Review the full test history for this PR. Silence the bot with an |
TestCRDDeletionCascading flake #59426 |
/retest |
/retest Review the full test history for this PR. Silence the bot with an |
1 similar comment
/retest Review the full test history for this PR. Silence the bot with an |
/test all Tests are more than 96 hours old. Re-running tests. |
Automatic merge from submit-queue (batch tested with PRs 60011, 59256, 59293, 60328, 60367). If you want to cherry-pick this change to another branch, please follow the instructions here. |
What this PR does / why we need it:
We are deprecating format-separated endpoints (
/swagger.json
,/swagger-2.0.0.json
,/swagger-2.0.0.pb-v1
,/swagger-2.0.0.pb-v1.gz
) for OpenAPI spec, and switching to a single/openapi/v2
endpoint in Kubernetes 1.10. The design doc and deprecation process are tracked at: https://docs.google.com/document/d/19lEqE9lc4yHJ3WJAJxS_G7TcORIJXGHyq3wpwcH28nURequested format is specified by setting HTTP headers
application/json
,application/com.github.proto-openapi.spec.v2@v1.0+protobuf
gzip
This PR changes dynamic_client (and kubectl as a result) to use the new endpoint. The old endpoints will remain in 1.10, 1.11, 1.12 and 1.13, and get removed in 1.14.
Examples:
Which issue(s) this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close the issue(s) when PR gets merged):Fixes #
Special notes for your reviewer:
Release note:
/sig api-machinery