in pkg/controllers/openapiv3/aggregator/downloader.go [58:129]
func (s *Downloader) Download(handler http.Handler, etagList map[string]string) (returnSpec map[string]*SpecETag, err error) {
// TODO(jefftree): https://github.com/kubernetes/kubernetes/pull/105945#issuecomment-966455034
// Move to proxy request in the aggregator and let the APIServices serve the OpenAPI directly
handler = s.handlerWithUser(handler, &user.DefaultInfo{Name: aggregatorUser})
handler = http.TimeoutHandler(handler, specDownloadTimeout, "request timed out")
req, err := http.NewRequest("GET", "/openapi/v3", nil)
if err != nil {
return nil, err
}
req.Header.Add("Accept", "application/json")
writer := newInMemoryResponseWriter()
handler.ServeHTTP(writer, req)
switch writer.respCode {
case http.StatusNotFound:
// Gracefully skip 404, assuming the server won't provide any spec
return nil, nil
case http.StatusOK:
groups := gvList{}
aggregated := make(map[string]*SpecETag)
if err := json.Unmarshal(writer.data, &groups); err != nil {
return nil, err
}
for _, path := range groups.Paths {
reqPath := fmt.Sprintf("/openapi/v3/%s", path)
req, err := http.NewRequest("GET", reqPath, nil)
if err != nil {
return nil, err
}
req.Header.Add("Accept", "application/json")
oldEtag, ok := etagList[path]
if ok {
req.Header.Add("If-None-Match", oldEtag)
}
openAPIWriter := newInMemoryResponseWriter()
handler.ServeHTTP(openAPIWriter, req)
switch openAPIWriter.respCode {
case http.StatusNotFound:
continue
case http.StatusNotModified:
aggregated[path] = &SpecETag{
etag: oldEtag,
}
case http.StatusOK:
var spec spec3.OpenAPI
// TODO|jefftree: For OpenAPI v3 Beta, if the v3 spec is empty then
// we should request the v2 endpoint and convert it to v3
if len(openAPIWriter.data) > 0 {
err = json.Unmarshal(openAPIWriter.data, &spec)
if err != nil {
return nil, err
}
etag := openAPIWriter.Header().Get("Etag")
aggregated[path] = &SpecETag{
spec: &spec,
etag: etag,
}
}
default:
klog.Errorf("Error: unknown status %v", openAPIWriter.respCode)
}
}
return aggregated, nil
default:
return nil, fmt.Errorf("failed to retrieve openAPI spec, http error: %s", writer.String())
}
}