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

Serve OpenAPI spec with single /openapi/v2 endpoint #59293

Merged
merged 3 commits into from
Feb 27, 2018

Conversation

roycaihw
Copy link
Member

@roycaihw roycaihw commented Feb 2, 2018

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_G7TcORIJXGHyq3wpwcH28nU

Requested format is specified by setting HTTP headers

header possible values
Accept application/json, application/com.github.proto-openapi.spec.v2@v1.0+protobuf
Accept-Encoding 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:

previous now
GET /swagger.json GET /openapi/v2 Accept: application/json
GET /swagger-2.0.0.pb-v1 GET /openapi/v2 Accept: application/com.github.proto-openapi.spec.v2@v1.0+protobuf
GET /swagger-2.0.0.pb-v1.gz GET /openapi/v2 Accept: application/com.github.proto-openapi.spec.v2@v1.0+protobuf Accept-Encoding: gzip

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:

action required: Deprecate format-separated endpoints for OpenAPI spec. Please use single `/openapi/v2` endpoint instead.

/sig api-machinery

@k8s-ci-robot k8s-ci-robot added release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. size/M Denotes a PR that changes 30-99 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Feb 2, 2018
@roycaihw roycaihw force-pushed the openapi_endpoint branch 2 times, most recently from 63ee6d3 to bf5dc3a Compare February 5, 2018 18:48
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Feb 5, 2018
@lavalamp
Copy link
Member

lavalamp commented Feb 5, 2018

/assign @yliaog
/assign @mbohlool

@@ -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/*",
Copy link
Member Author

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.

@@ -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,
Copy link
Member

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

Copy link
Member Author

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")

Copy link
Member

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

Copy link
Member

@liggitt liggitt Feb 6, 2018

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

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
}

Copy link
Member Author

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()
Copy link
Member

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

Copy link
Contributor

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.

Copy link
Member Author

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(
Copy link
Member

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?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, according to

if err != nil {
return err
}
return s.openAPIVersionedService.UpdateSpec(specToServe)
Copy link
Contributor

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.

Copy link
Member Author

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)
Copy link
Contributor

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).

Copy link
Member Author

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()
Copy link
Contributor

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.

@roycaihw roycaihw force-pushed the openapi_endpoint branch 2 times, most recently from 4d3ae79 to b07f6d4 Compare February 7, 2018 18:37
@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 20, 2018
@k8s-ci-robot k8s-ci-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 20, 2018
@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

7 similar comments
@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@k8s-github-robot
Copy link

/test all [submit-queue is verifying that this PR is safe to merge]

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@k8s-github-robot
Copy link

/test all [submit-queue is verifying that this PR is safe to merge]

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

6 similar comments
@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@roycaihw
Copy link
Member Author

TestCRDDeletionCascading flake #59426

@roycaihw
Copy link
Member Author

/retest

@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

1 similar comment
@fejta-bot
Copy link

/retest
This bot automatically retries jobs that failed/flaked on approved PRs (send feedback to fejta).

Review the full test history for this PR.

Silence the bot with an /lgtm cancel comment for consistent failures.

@k8s-github-robot
Copy link

/test all

Tests are more than 96 hours old. Re-running tests.

@k8s-github-robot
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. release-note-action-required Denotes a PR that introduces potentially breaking changes that require user action. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants