mirror of https://github.com/k3s-io/k3s
Merge pull request #74098 from roycaihw/genericapiserver-openapi-service
genericapiserver: expose openapi service to allow updating the served specpull/564/head
commit
02d1039ec3
|
@ -115,6 +115,7 @@ go_library(
|
|||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/kube-openapi/pkg/builder:go_default_library",
|
||||
"//vendor/k8s.io/kube-openapi/pkg/common:go_default_library",
|
||||
"//vendor/k8s.io/kube-openapi/pkg/handler:go_default_library",
|
||||
"//vendor/k8s.io/kube-openapi/pkg/util:go_default_library",
|
||||
"//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library",
|
||||
],
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"time"
|
||||
|
||||
systemd "github.com/coreos/go-systemd/daemon"
|
||||
"github.com/go-openapi/spec"
|
||||
"k8s.io/klog"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
|
@ -46,6 +47,7 @@ import (
|
|||
restclient "k8s.io/client-go/rest"
|
||||
openapibuilder "k8s.io/kube-openapi/pkg/builder"
|
||||
openapicommon "k8s.io/kube-openapi/pkg/common"
|
||||
"k8s.io/kube-openapi/pkg/handler"
|
||||
openapiutil "k8s.io/kube-openapi/pkg/util"
|
||||
openapiproto "k8s.io/kube-openapi/pkg/util/proto"
|
||||
)
|
||||
|
@ -122,6 +124,14 @@ type GenericAPIServer struct {
|
|||
// Enable swagger and/or OpenAPI if these configs are non-nil.
|
||||
openAPIConfig *openapicommon.Config
|
||||
|
||||
// OpenAPIVersionedService controls the /openapi/v2 endpoint, and can be used to update the served spec.
|
||||
// It is set during PrepareRun.
|
||||
OpenAPIVersionedService *handler.OpenAPIService
|
||||
|
||||
// StaticOpenAPISpec is the spec derived from the restful container endpoints.
|
||||
// It is set during PrepareRun.
|
||||
StaticOpenAPISpec *spec.Swagger
|
||||
|
||||
// PostStartHooks are each called after the server has started listening, in a separate go func for each
|
||||
// with no guarantee of ordering between them. The map key is a name used for error reporting.
|
||||
// It may kill the process with a panic if it wishes to by returning an error.
|
||||
|
@ -239,7 +249,7 @@ type preparedGenericAPIServer struct {
|
|||
// PrepareRun does post API installation setup steps.
|
||||
func (s *GenericAPIServer) PrepareRun() preparedGenericAPIServer {
|
||||
if s.openAPIConfig != nil {
|
||||
routes.OpenAPI{
|
||||
s.OpenAPIVersionedService, s.StaticOpenAPISpec = routes.OpenAPI{
|
||||
Config: s.openAPIConfig,
|
||||
}.Install(s.Handler.GoRestfulContainer, s.Handler.NonGoRestfulMux)
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
openapi "github.com/go-openapi/spec"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
|
@ -338,6 +339,46 @@ func TestPrepareRun(t *testing.T) {
|
|||
assert.Equal(http.StatusOK, resp.StatusCode)
|
||||
}
|
||||
|
||||
func TestUpdateOpenAPISpec(t *testing.T) {
|
||||
s, _, assert := newMaster(t)
|
||||
s.PrepareRun()
|
||||
s.RunPostStartHooks(make(chan struct{}))
|
||||
|
||||
server := httptest.NewServer(s.Handler.Director)
|
||||
defer server.Close()
|
||||
|
||||
// verify the static spec in record is what we currently serve
|
||||
oldSpec, err := json.Marshal(s.StaticOpenAPISpec)
|
||||
assert.NoError(err)
|
||||
|
||||
resp, err := http.Get(server.URL + "/openapi/v2")
|
||||
assert.NoError(err)
|
||||
assert.Equal(http.StatusOK, resp.StatusCode)
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
assert.NoError(err)
|
||||
assert.Equal(oldSpec, body)
|
||||
resp.Body.Close()
|
||||
|
||||
// verify we are able to update the served spec using the exposed service
|
||||
newSpec := []byte(`{"swagger":"2.0","info":{"title":"Test Updated Generic API Server Swagger","version":"v0.1.0"},"paths":null}`)
|
||||
swagger := new(spec.Swagger)
|
||||
err = json.Unmarshal(newSpec, swagger)
|
||||
assert.NoError(err)
|
||||
|
||||
err = s.OpenAPIVersionedService.UpdateSpec(swagger)
|
||||
assert.NoError(err)
|
||||
|
||||
resp, err = http.Get(server.URL + "/openapi/v2")
|
||||
assert.NoError(err)
|
||||
defer resp.Body.Close()
|
||||
assert.Equal(http.StatusOK, resp.StatusCode)
|
||||
|
||||
body, err = ioutil.ReadAll(resp.Body)
|
||||
assert.NoError(err)
|
||||
assert.Equal(newSpec, body)
|
||||
}
|
||||
|
||||
// TestCustomHandlerChain verifies the handler chain with custom handler chain builder functions.
|
||||
func TestCustomHandlerChain(t *testing.T) {
|
||||
config, _ := setUp(t)
|
||||
|
|
|
@ -27,8 +27,10 @@ go_library(
|
|||
"//staging/src/k8s.io/apiserver/pkg/server/mux:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/storage/etcd/metrics:go_default_library",
|
||||
"//vendor/github.com/emicklei/go-restful:go_default_library",
|
||||
"//vendor/github.com/go-openapi/spec:go_default_library",
|
||||
"//vendor/github.com/prometheus/client_golang/prometheus:go_default_library",
|
||||
"//vendor/k8s.io/klog:go_default_library",
|
||||
"//vendor/k8s.io/kube-openapi/pkg/builder:go_default_library",
|
||||
"//vendor/k8s.io/kube-openapi/pkg/common:go_default_library",
|
||||
"//vendor/k8s.io/kube-openapi/pkg/handler:go_default_library",
|
||||
],
|
||||
|
|
|
@ -18,9 +18,11 @@ package routes
|
|||
|
||||
import (
|
||||
restful "github.com/emicklei/go-restful"
|
||||
"github.com/go-openapi/spec"
|
||||
"k8s.io/klog"
|
||||
|
||||
"k8s.io/apiserver/pkg/server/mux"
|
||||
"k8s.io/kube-openapi/pkg/builder"
|
||||
"k8s.io/kube-openapi/pkg/common"
|
||||
"k8s.io/kube-openapi/pkg/handler"
|
||||
)
|
||||
|
@ -31,9 +33,14 @@ type OpenAPI struct {
|
|||
}
|
||||
|
||||
// Install adds the SwaggerUI webservice to the given mux.
|
||||
func (oa OpenAPI) Install(c *restful.Container, mux *mux.PathRecorderMux) {
|
||||
_, err := handler.BuildAndRegisterOpenAPIVersionedService("/openapi/v2", c.RegisteredWebServices(), oa.Config, mux)
|
||||
func (oa OpenAPI) Install(c *restful.Container, mux *mux.PathRecorderMux) (*handler.OpenAPIService, *spec.Swagger) {
|
||||
spec, err := builder.BuildOpenAPISpec(c.RegisteredWebServices(), oa.Config)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to build open api spec for root: %v", err)
|
||||
}
|
||||
openAPIVersionedService, err := handler.RegisterOpenAPIVersionedService(spec, "/openapi/v2", mux)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to register versioned open api spec for root: %v", err)
|
||||
}
|
||||
return openAPIVersionedService, spec
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue