mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-17 20:00:07 +00:00
discovery: Add profile-based content negotiation
Add support for 'profile=nopeer' in Accept headers to allow clients to opt out of peer-aggregated discovery and request local-only results. Updates discovery client to set appropriate Accept headers based on whether peer-aggregated discovery is desired. Part of KEP-4020: Unknown Version Interoperability Proxy
This commit is contained in:
@@ -168,6 +168,9 @@ type MediaTypeOptions struct {
|
||||
// has set
|
||||
Export bool
|
||||
|
||||
// profile controls the discovery profile (e.g., "local" for local (non peer-aggregated) discovery)
|
||||
Profile string
|
||||
|
||||
// unrecognized is a list of all unrecognized keys
|
||||
Unrecognized []string
|
||||
|
||||
@@ -227,6 +230,10 @@ func acceptMediaTypeOptions(params map[string]string, accepts *runtime.Serialize
|
||||
case "pretty":
|
||||
options.Pretty = v == "1"
|
||||
|
||||
// controls the discovery profile (eg local vs peer-aggregated)
|
||||
case "profile":
|
||||
options.Profile = v
|
||||
|
||||
default:
|
||||
options.Unrecognized = append(options.Unrecognized, k)
|
||||
}
|
||||
|
||||
@@ -59,12 +59,14 @@ const (
|
||||
// defaultBurst is the default burst to be used with the discovery client's token bucket rate limiter
|
||||
defaultBurst = 300
|
||||
|
||||
AcceptV1 = runtime.ContentTypeJSON
|
||||
AcceptV1 = runtime.ContentTypeJSON
|
||||
// Aggregated discovery content-type (v2beta1). NOTE: content-type parameters
|
||||
// MUST be ordered (g, v, as) for server in "Accept" header (BUT we are resilient
|
||||
// to ordering when comparing returned values in "Content-Type" header).
|
||||
AcceptV2Beta1 = runtime.ContentTypeJSON + ";" + "g=apidiscovery.k8s.io;v=v2beta1;as=APIGroupDiscoveryList"
|
||||
AcceptV2 = runtime.ContentTypeJSON + ";" + "g=apidiscovery.k8s.io;v=v2;as=APIGroupDiscoveryList"
|
||||
AcceptV2Beta1 = runtime.ContentTypeJSON + ";" + "g=apidiscovery.k8s.io;v=v2beta1;as=APIGroupDiscoveryList"
|
||||
AcceptV2 = runtime.ContentTypeJSON + ";" + "g=apidiscovery.k8s.io;v=v2;as=APIGroupDiscoveryList"
|
||||
AcceptV2NoPeer = runtime.ContentTypeJSON + ";" + "g=apidiscovery.k8s.io;v=v2;as=APIGroupDiscoveryList;profile=nopeer"
|
||||
// Prioritize aggregated discovery by placing first in the order of discovery accept types.
|
||||
acceptDiscoveryFormats = AcceptV2 + "," + AcceptV2Beta1 + "," + AcceptV1
|
||||
)
|
||||
@@ -168,6 +170,11 @@ type DiscoveryClient struct {
|
||||
LegacyPrefix string
|
||||
// Forces the client to request only "unaggregated" (legacy) discovery.
|
||||
UseLegacyDiscovery bool
|
||||
// NoPeerDiscovery will request the "nopeer" profile of aggregated discovery.
|
||||
// This allows a client to get just the discovery documents served by the single apiserver
|
||||
// that it is talking to. This is useful for clients that need to understand the state
|
||||
// of a single apiserver, for example, to validate that the apiserver is ready to serve traffic.
|
||||
NoPeerDiscovery bool
|
||||
}
|
||||
|
||||
var _ AggregatedDiscoveryInterface = &DiscoveryClient{}
|
||||
@@ -241,10 +248,7 @@ func (d *DiscoveryClient) downloadLegacy() (
|
||||
map[schema.GroupVersion]*metav1.APIResourceList,
|
||||
map[schema.GroupVersion]error,
|
||||
error) {
|
||||
accept := acceptDiscoveryFormats
|
||||
if d.UseLegacyDiscovery {
|
||||
accept = AcceptV1
|
||||
}
|
||||
accept := selectDiscoveryAcceptHeader(d.UseLegacyDiscovery, d.NoPeerDiscovery)
|
||||
var responseContentType string
|
||||
body, err := d.restClient.Get().
|
||||
AbsPath("/api").
|
||||
@@ -307,10 +311,7 @@ func (d *DiscoveryClient) downloadAPIs() (
|
||||
map[schema.GroupVersion]*metav1.APIResourceList,
|
||||
map[schema.GroupVersion]error,
|
||||
error) {
|
||||
accept := acceptDiscoveryFormats
|
||||
if d.UseLegacyDiscovery {
|
||||
accept = AcceptV1
|
||||
}
|
||||
accept := selectDiscoveryAcceptHeader(d.UseLegacyDiscovery, d.NoPeerDiscovery)
|
||||
var responseContentType string
|
||||
body, err := d.restClient.Get().
|
||||
AbsPath("/apis").
|
||||
@@ -351,6 +352,16 @@ func (d *DiscoveryClient) downloadAPIs() (
|
||||
return apiGroupList, resourcesByGV, failedGVs, nil
|
||||
}
|
||||
|
||||
func selectDiscoveryAcceptHeader(useLegacy, nopeer bool) string {
|
||||
if useLegacy {
|
||||
return AcceptV1
|
||||
}
|
||||
if nopeer {
|
||||
return AcceptV2NoPeer + "," + acceptDiscoveryFormats
|
||||
}
|
||||
return acceptDiscoveryFormats
|
||||
}
|
||||
|
||||
// ContentTypeIsGVK checks of the content-type string is both
|
||||
// "application/json" and matches the provided GVK. An error
|
||||
// is returned if the content type string is malformed.
|
||||
|
||||
Reference in New Issue
Block a user