func()

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())
	}
}