Enhance content negotiation for zpages#135309
Enhance content negotiation for zpages#135309k8s-ci-robot merged 2 commits intokubernetes:masterfrom
Conversation
|
I think this needs a changelog entry. If not, what's the thinking behind not including one? |
| { | ||
| name: "valid request for v1alpha1", | ||
| name: "valid request for application/json", | ||
| acceptHeader: "application/json;v=v1alpha1;g=config.k8s.io;as=Flagz", |
There was a problem hiding this comment.
nit: we could request application/json (just that, no parameters) and / or application/yaml, application/cbor and see what happens.
There was a problem hiding this comment.
I have that below in the "unsupported application/json without params" testcase
|
If CBOR is enabled, can you fetch z pages as CBOR? |
|
/triage accepted |
| } | ||
| // Protobuf is not supported for zpages endpoints | ||
| if mimeType == "application" && mimeSubType == "vnd.kubernetes.protobuf" { | ||
| return false |
There was a problem hiding this comment.
wouldn't only allowing application/json when the gvk is set be better?
if mimeType == "application" && mimeSubType == "json" {
return isStructured(gvk)
}
return falseThere was a problem hiding this comment.
If someone requests a zpage and their Accept: header indicates a preference for CBOR, and CBOR support is enabled, what should we serve?
There was a problem hiding this comment.
@dgrisonnet yeah thats more readable, except that I added checks for both json and yaml to the conditional.
@lmktfy I am not entirely sure that we want to support CBOR for statusz/flagz. Both the endpoints serve as debugging endpoints and have relatively small payloads. I also dont foresee users polling these endpoints every few seconds (which if it was the case, would be a good reason to support CBOR for faster parsing of the response). Since statusz and flagz responses are small diagnostic payloads that never make it to storage, I'm not sure there's significant benefit to adding CBOR support beyond consistency with other Kubernetes APIs. But I cant also think of any obvious downsides to it, so I am open to changing my mind :)
There was a problem hiding this comment.
Also cc @liggitt for this opinion on CBOR support for statusz/flagz
There was a problem hiding this comment.
My (personal) opinion here, not representing any SIG.
Overall I would have it as either an exclusion list ("no Protobuf") or by calling a method to check "is this a text-like format".
So I don't especially support hard coding JSON and YAML as the formats. If we did add, let's say, XML or TOML or something, then the people doing that shouldn't need to look into the z-pages code specifically to find where to change the negotiation rules.
There was a problem hiding this comment.
@benluddy is cbor negotiation wired in for things like serialization of discovery formats today?
There was a problem hiding this comment.
I agree with supporting json / yaml / cbor consistently. I'm actually fine with specifically allowing those three so we can also pair that with tests of the behavior of those three. Making an exclusion list makes it hard to be confident we have exhaustively tested the outputs we allow.
There was a problem hiding this comment.
is cbor negotiation wired in for things like discovery today?
Not today. I don't know why it should not be. Opened a PR to add it to the KEP (kubernetes/enhancements#5740).
There was a problem hiding this comment.
So I added CBOR handling (I check for the CBORServingAndStorage feature gate, and if enabled, include the CBOR serializer when creating the codecFactory. Also added a TODO to remove this explicit check from statusz/flagz once we implement this in the codec_factory.go
Please lmk if this is ok or if I should just remove the explicit feature-gate check and enablement of CBOR support for statusz/flag, and instead wait for CBOR serializer to be included in code_factory in future to use it for zpages.
46985fb to
4ccd2a7
Compare
unsupported requested type should return a 406 error, not a 5xx, by fixing the default case of our switch statement: I'm open to accepting application/json, application/yaml, and application/cbor if it's as simple as expanding our switch statement here (I think all three serializers should be able to serialize resulting object): |
| } | ||
| // Protobuf is not supported for zpages endpoints | ||
| if mimeType == "application" && mimeSubType == "vnd.kubernetes.protobuf" { | ||
| return false |
There was a problem hiding this comment.
I agree with supporting json / yaml / cbor consistently. I'm actually fine with specifically allowing those three so we can also pair that with tests of the behavior of those three. Making an exclusion list makes it hard to be confident we have exhaustively tested the outputs we allow.
|
Also, I noticed another thing, the error message returned for an unsupported media was the following: The error included Happy to also revise this if this is not the preferred approach to fix the wrong list of supported types in the error. |
liggitt
left a comment
There was a problem hiding this comment.
a couple comments, looks reasonable otherwise (also apply to the statusz file)
| m.Handle(DefaultFlagzPath, handleFlagz(componentName, reg, filteredCodecFactory, negotiate.FlagzEndpointRestrictions{})) | ||
| } | ||
|
|
||
| func (f *flagzCodecFactory) SupportedMediaTypes() []runtime.SerializerInfo { |
There was a problem hiding this comment.
is this called on every request to /flagz during negotiation? if so, let's calculate this once and cache/return to avoid reallocating on every request
There was a problem hiding this comment.
yeah it was. Now caching it in flagzCodecFactory once and resuing that, thanks for the tip!
| allTypes := f.CodecFactory.SupportedMediaTypes() | ||
| filtered := make([]runtime.SerializerInfo, 0, len(allTypes)) | ||
| for _, info := range allTypes { | ||
| if info.MediaType == runtime.ContentTypeProtobuf { |
There was a problem hiding this comment.
prefer both positive and negative matching so any future additions get detected / handled
- include text, json, yaml, cbor
- exclude proto
- consider panicing on another unknown type when running tests so we catch this and make a decision about whether to support a new format for this
There was a problem hiding this comment.
Makes sense. Done and added a unit test to check for no errors when creating the flagzCodecFactory and statuszCodecFactory
|
/lgtm |
|
LGTM label has been added. DetailsGit tree hash: 859e15a9b6eef56b933d811f9723789475f9687c |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: liggitt, richabanker 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 |
|
@richabanker: The following tests failed, say
Full PR test history. Your PR dashboard. Please help us cut down on flakes by linking to an open issue when you hit one in your PR. 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. I understand the commands that are listed here. |
|
Retesting failed PR that otherwise appears ready for merge. Please help us fix flaky tests by following our Flaky Tests Guide. Prevent this bot from retesting with /retest-required |
What type of PR is this?
/kind cleanup
What this PR does / why we need it:
This PR:
Which issue(s) this PR is related to:
kubernetes/enhancements#4827
kubernetes/enhancements#4828
Special notes for your reviewer:
Does this PR introduce a user-facing change?
Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.: