mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Revert "Separate Build and Serving parts of OpenAPI spec handler"
This reverts commit 0a886ffaf8.
			
			
This commit is contained in:
		@@ -17,17 +17,26 @@ limitations under the License.
 | 
				
			|||||||
package openapi
 | 
					package openapi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"compress/gzip"
 | 
				
			||||||
	"crypto/sha512"
 | 
						"crypto/sha512"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"gopkg.in/yaml.v2"
 | 
				
			||||||
 | 
						"mime"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	restful "github.com/emicklei/go-restful"
 | 
						restful "github.com/emicklei/go-restful"
 | 
				
			||||||
	"github.com/go-openapi/spec"
 | 
						"github.com/go-openapi/spec"
 | 
				
			||||||
 | 
						"github.com/golang/protobuf/proto"
 | 
				
			||||||
 | 
						"github.com/googleapis/gnostic/OpenAPIv2"
 | 
				
			||||||
 | 
						"github.com/googleapis/gnostic/compiler"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/openapi"
 | 
						"k8s.io/apimachinery/pkg/openapi"
 | 
				
			||||||
 | 
						genericmux "k8s.io/apiserver/pkg/server/mux"
 | 
				
			||||||
	"k8s.io/apiserver/pkg/util/trie"
 | 
						"k8s.io/apiserver/pkg/util/trie"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -46,6 +55,10 @@ const (
 | 
				
			|||||||
type openAPI struct {
 | 
					type openAPI struct {
 | 
				
			||||||
	config       *openapi.Config
 | 
						config       *openapi.Config
 | 
				
			||||||
	swagger      *spec.Swagger
 | 
						swagger      *spec.Swagger
 | 
				
			||||||
 | 
						swaggerBytes []byte
 | 
				
			||||||
 | 
						swaggerPb    []byte
 | 
				
			||||||
 | 
						swaggerPbGz  []byte
 | 
				
			||||||
 | 
						lastModified time.Time
 | 
				
			||||||
	protocolList []string
 | 
						protocolList []string
 | 
				
			||||||
	definitions  map[string]openapi.OpenAPIDefinition
 | 
						definitions  map[string]openapi.OpenAPIDefinition
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -54,7 +67,15 @@ func computeEtag(data []byte) string {
 | 
				
			|||||||
	return fmt.Sprintf("\"%X\"", sha512.Sum512(data))
 | 
						return fmt.Sprintf("\"%X\"", sha512.Sum512(data))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func BuildSwaggerSpec(webServices []*restful.WebService, config *openapi.Config) (*spec.Swagger, error) {
 | 
					// RegisterOpenAPIService registers a handler to provides standard OpenAPI specification.
 | 
				
			||||||
 | 
					func RegisterOpenAPIService(servePath string, webServices []*restful.WebService, config *openapi.Config, mux *genericmux.PathRecorderMux) (err error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !strings.HasSuffix(servePath, JSON_EXT) {
 | 
				
			||||||
 | 
							return fmt.Errorf("Serving path must ends with \"%s\".", JSON_EXT)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						servePathBase := servePath[:len(servePath)-len(JSON_EXT)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	o := openAPI{
 | 
						o := openAPI{
 | 
				
			||||||
		config:    config,
 | 
							config:    config,
 | 
				
			||||||
		swagger: &spec.Swagger{
 | 
							swagger: &spec.Swagger{
 | 
				
			||||||
@@ -67,12 +88,44 @@ func BuildSwaggerSpec(webServices []*restful.WebService, config *openapi.Config)
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err := o.init(webServices)
 | 
						err = o.init(webServices)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return o.swagger, nil
 | 
						mime.AddExtensionType(".json", MIME_JSON)
 | 
				
			||||||
 | 
						mime.AddExtensionType(".pb-v1", MIME_PB)
 | 
				
			||||||
 | 
						mime.AddExtensionType(".gz", MIME_PB_GZ)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						type fileInfo struct {
 | 
				
			||||||
 | 
							ext  string
 | 
				
			||||||
 | 
							data []byte
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						files := []fileInfo{
 | 
				
			||||||
 | 
							{".json", o.swaggerBytes},
 | 
				
			||||||
 | 
							{"-2.0.0.json", o.swaggerBytes},
 | 
				
			||||||
 | 
							{"-2.0.0.pb-v1", o.swaggerPb},
 | 
				
			||||||
 | 
							{"-2.0.0.pb-v1.gz", o.swaggerPbGz},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, file := range files {
 | 
				
			||||||
 | 
							path := servePathBase + file.ext
 | 
				
			||||||
 | 
							data := file.data
 | 
				
			||||||
 | 
							etag := computeEtag(file.data)
 | 
				
			||||||
 | 
							mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
								if r.URL.Path != path {
 | 
				
			||||||
 | 
									w.WriteHeader(http.StatusNotFound)
 | 
				
			||||||
 | 
									w.Write([]byte("Path not found!"))
 | 
				
			||||||
 | 
									return
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								w.Header().Set("Etag", etag)
 | 
				
			||||||
 | 
								// ServeContent will take care of caching using eTag.
 | 
				
			||||||
 | 
								http.ServeContent(w, r, path, o.lastModified, bytes.NewReader(data))
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (o *openAPI) init(webServices []*restful.WebService) error {
 | 
					func (o *openAPI) init(webServices []*restful.WebService) error {
 | 
				
			||||||
@@ -88,7 +141,7 @@ func (o *openAPI) init(webServices []*restful.WebService) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	o.definitions = o.config.GetDefinitions(func(name string) spec.Ref {
 | 
						o.definitions = o.config.GetDefinitions(func(name string) spec.Ref {
 | 
				
			||||||
		defName, _ := o.config.GetDefinitionName(name)
 | 
							defName, _ := o.config.GetDefinitionName(name)
 | 
				
			||||||
		return spec.MustCreateRef(DEFINITION_PREFIX + openapi.EscapeJsonPointer(defName))
 | 
							return spec.MustCreateRef("#/definitions/" + openapi.EscapeJsonPointer(defName))
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	if o.config.CommonResponses == nil {
 | 
						if o.config.CommonResponses == nil {
 | 
				
			||||||
		o.config.CommonResponses = map[int]spec.Response{}
 | 
							o.config.CommonResponses = map[int]spec.Response{}
 | 
				
			||||||
@@ -108,9 +161,41 @@ func (o *openAPI) init(webServices []*restful.WebService) error {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						o.swaggerBytes, err = json.MarshalIndent(o.swagger, " ", " ")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						o.swaggerPb, err = toProtoBinary(o.swaggerBytes)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						o.swaggerPbGz = toGzip(o.swaggerPb)
 | 
				
			||||||
 | 
						o.lastModified = time.Now()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func toProtoBinary(spec []byte) ([]byte, error) {
 | 
				
			||||||
 | 
						var info yaml.MapSlice
 | 
				
			||||||
 | 
						err := yaml.Unmarshal(spec, &info)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						document, err := openapi_v2.NewDocument(info, compiler.NewContext("$root", nil))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return proto.Marshal(document)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func toGzip(data []byte) []byte {
 | 
				
			||||||
 | 
						var buf bytes.Buffer
 | 
				
			||||||
 | 
						zw := gzip.NewWriter(&buf)
 | 
				
			||||||
 | 
						zw.Write(data)
 | 
				
			||||||
 | 
						zw.Close()
 | 
				
			||||||
 | 
						return buf.Bytes()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func getCanonicalizeTypeName(t reflect.Type) string {
 | 
					func getCanonicalizeTypeName(t reflect.Type) string {
 | 
				
			||||||
	if t.PkgPath() == "" {
 | 
						if t.PkgPath() == "" {
 | 
				
			||||||
		return t.Name()
 | 
							return t.Name()
 | 
				
			||||||
@@ -166,7 +251,7 @@ func (o *openAPI) buildDefinitionForType(sample interface{}) (string, error) {
 | 
				
			|||||||
		return "", err
 | 
							return "", err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defName, _ := o.config.GetDefinitionName(name)
 | 
						defName, _ := o.config.GetDefinitionName(name)
 | 
				
			||||||
	return DEFINITION_PREFIX + openapi.EscapeJsonPointer(defName), nil
 | 
						return "#/definitions/" + openapi.EscapeJsonPointer(defName), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// buildPaths builds OpenAPI paths using go-restful's web services.
 | 
					// buildPaths builds OpenAPI paths using go-restful's web services.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,163 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
Copyright 2017 The Kubernetes Authors.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
limitations under the License.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package openapi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"compress/gzip"
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"mime"
 | 
					 | 
				
			||||||
	"net/http"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/NYTimes/gziphandler"
 | 
					 | 
				
			||||||
	"github.com/go-openapi/spec"
 | 
					 | 
				
			||||||
	"github.com/golang/protobuf/proto"
 | 
					 | 
				
			||||||
	"github.com/googleapis/gnostic/OpenAPIv2"
 | 
					 | 
				
			||||||
	"github.com/googleapis/gnostic/compiler"
 | 
					 | 
				
			||||||
	"gopkg.in/yaml.v2"
 | 
					 | 
				
			||||||
	genericmux "k8s.io/apiserver/pkg/server/mux"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
type OpenAPIService struct {
 | 
					 | 
				
			||||||
	orgSpec      *spec.Swagger
 | 
					 | 
				
			||||||
	specBytes    []byte
 | 
					 | 
				
			||||||
	specPb       []byte
 | 
					 | 
				
			||||||
	specPbGz     []byte
 | 
					 | 
				
			||||||
	lastModified time.Time
 | 
					 | 
				
			||||||
	updateHooks  []func(*http.Request)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// RegisterOpenAPIService registers a handler to provides standard OpenAPI specification.
 | 
					 | 
				
			||||||
func RegisterOpenAPIService(openapiSpec *spec.Swagger, servePath string, mux *genericmux.PathRecorderMux) (*OpenAPIService, error) {
 | 
					 | 
				
			||||||
	if !strings.HasSuffix(servePath, JSON_EXT) {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("Serving path must ends with \"%s\".", JSON_EXT)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	servePathBase := servePath[:len(servePath)-len(JSON_EXT)]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	o := OpenAPIService{}
 | 
					 | 
				
			||||||
	if err := o.UpdateSpec(openapiSpec); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	mime.AddExtensionType(".json", MIME_JSON)
 | 
					 | 
				
			||||||
	mime.AddExtensionType(".pb-v1", MIME_PB)
 | 
					 | 
				
			||||||
	mime.AddExtensionType(".gz", MIME_PB_GZ)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	type fileInfo struct {
 | 
					 | 
				
			||||||
		ext     string
 | 
					 | 
				
			||||||
		getData func() []byte
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	files := []fileInfo{
 | 
					 | 
				
			||||||
		{".json", o.getSwaggerBytes},
 | 
					 | 
				
			||||||
		{"-2.0.0.json", o.getSwaggerBytes},
 | 
					 | 
				
			||||||
		{"-2.0.0.pb-v1", o.getSwaggerPbBytes},
 | 
					 | 
				
			||||||
		{"-2.0.0.pb-v1.gz", o.getSwaggerPbGzBytes},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for _, file := range files {
 | 
					 | 
				
			||||||
		path := servePathBase + file.ext
 | 
					 | 
				
			||||||
		getData := file.getData
 | 
					 | 
				
			||||||
		mux.Handle(path, gziphandler.GzipHandler(http.HandlerFunc(
 | 
					 | 
				
			||||||
			func(w http.ResponseWriter, r *http.Request) {
 | 
					 | 
				
			||||||
				if r.URL.Path != path {
 | 
					 | 
				
			||||||
					w.WriteHeader(http.StatusNotFound)
 | 
					 | 
				
			||||||
					w.Write([]byte("Path not found!"))
 | 
					 | 
				
			||||||
					return
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				o.update(r)
 | 
					 | 
				
			||||||
				data := getData()
 | 
					 | 
				
			||||||
				etag := computeEtag(data)
 | 
					 | 
				
			||||||
				w.Header().Set("Etag", etag)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				// ServeContent will take care of caching using eTag.
 | 
					 | 
				
			||||||
				http.ServeContent(w, r, path, o.lastModified, bytes.NewReader(data))
 | 
					 | 
				
			||||||
			}),
 | 
					 | 
				
			||||||
		))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return &o, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (o *OpenAPIService) getSwaggerBytes() []byte {
 | 
					 | 
				
			||||||
	return o.specBytes
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (o *OpenAPIService) getSwaggerPbBytes() []byte {
 | 
					 | 
				
			||||||
	return o.specPb
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (o *OpenAPIService) getSwaggerPbGzBytes() []byte {
 | 
					 | 
				
			||||||
	return o.specPbGz
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (o *OpenAPIService) GetSpec() *spec.Swagger {
 | 
					 | 
				
			||||||
	return o.orgSpec
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (o *OpenAPIService) UpdateSpec(openapiSpec *spec.Swagger) (err error) {
 | 
					 | 
				
			||||||
	o.orgSpec = openapiSpec
 | 
					 | 
				
			||||||
	o.specBytes, err = json.MarshalIndent(openapiSpec, " ", " ")
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	o.specPb, err = toProtoBinary(o.specBytes)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	o.specPbGz = toGzip(o.specPb)
 | 
					 | 
				
			||||||
	o.lastModified = time.Now()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func toProtoBinary(spec []byte) ([]byte, error) {
 | 
					 | 
				
			||||||
	var info yaml.MapSlice
 | 
					 | 
				
			||||||
	err := yaml.Unmarshal(spec, &info)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	document, err := openapi_v2.NewDocument(info, compiler.NewContext("$root", nil))
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return proto.Marshal(document)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func toGzip(data []byte) []byte {
 | 
					 | 
				
			||||||
	var buf bytes.Buffer
 | 
					 | 
				
			||||||
	zw := gzip.NewWriter(&buf)
 | 
					 | 
				
			||||||
	zw.Write(data)
 | 
					 | 
				
			||||||
	zw.Close()
 | 
					 | 
				
			||||||
	return buf.Bytes()
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Adds an update hook to be called on each spec request. The hook is responsible
 | 
					 | 
				
			||||||
// to call UpdateSpec method.
 | 
					 | 
				
			||||||
func (o *OpenAPIService) AddUpdateHook(hook func(*http.Request)) {
 | 
					 | 
				
			||||||
	o.updateHooks = append(o.updateHooks, hook)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (o *OpenAPIService) update(r *http.Request) {
 | 
					 | 
				
			||||||
	for _, h := range o.updateHooks {
 | 
					 | 
				
			||||||
		h(r)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -32,16 +32,9 @@ type OpenAPI struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Install adds the SwaggerUI webservice to the given mux.
 | 
					// Install adds the SwaggerUI webservice to the given mux.
 | 
				
			||||||
func (oa OpenAPI) Install(c *restful.Container, mux *mux.PathRecorderMux) *apiserveropenapi.OpenAPIService {
 | 
					func (oa OpenAPI) Install(c *restful.Container, mux *mux.PathRecorderMux) {
 | 
				
			||||||
	openapiSpec, err := apiserveropenapi.BuildSwaggerSpec(c.RegisteredWebServices(), oa.Config)
 | 
						err := apiserveropenapi.RegisterOpenAPIService("/swagger.json", c.RegisteredWebServices(), oa.Config, mux)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		glog.Fatalf("Failed to register open api spec for root: %v", err)
 | 
							glog.Fatalf("Failed to register open api spec for root: %v", err)
 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	service, err := apiserveropenapi.RegisterOpenAPIService(openapiSpec, "/swagger.json", mux)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		glog.Fatalf("Failed to register open api spec for root: %v", err)
 | 
					 | 
				
			||||||
		return nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return service
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user