mirror of
https://github.com/niusmallnan/steve.git
synced 2025-09-02 05:34:25 +00:00
testing
This commit is contained in:
@@ -15,7 +15,6 @@ type Config struct {
|
||||
KubeConfig string
|
||||
HTTPSListenPort int
|
||||
HTTPListenPort int
|
||||
DashboardURL string
|
||||
Authentication bool
|
||||
|
||||
WebhookConfig authcli.WebhookConfig
|
||||
@@ -31,8 +30,7 @@ func (c *Config) MustServer(ctx context.Context) *server.Server {
|
||||
|
||||
func (c *Config) ToServer(ctx context.Context) (*server.Server, error) {
|
||||
var (
|
||||
auth steveauth.Middleware
|
||||
startHooks []server.StartHook
|
||||
auth steveauth.Middleware
|
||||
)
|
||||
|
||||
restConfig, err := kubeconfig.GetNonInteractiveClientConfig(c.KubeConfig).ClientConfig()
|
||||
@@ -48,14 +46,9 @@ func (c *Config) ToServer(ctx context.Context) (*server.Server, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return &server.Server{
|
||||
RESTConfig: restConfig,
|
||||
return server.New(ctx, restConfig, &server.Options{
|
||||
AuthMiddleware: auth,
|
||||
DashboardURL: func() string {
|
||||
return c.DashboardURL
|
||||
},
|
||||
StartHooks: startHooks,
|
||||
}, nil
|
||||
})
|
||||
}
|
||||
|
||||
func Flags(config *Config) []cli.Flag {
|
||||
@@ -75,11 +68,6 @@ func Flags(config *Config) []cli.Flag {
|
||||
Value: 9080,
|
||||
Destination: &config.HTTPListenPort,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "dashboard-url",
|
||||
Value: "https://releases.rancher.com/dashboard/latest/index.html",
|
||||
Destination: &config.DashboardURL,
|
||||
},
|
||||
cli.BoolTFlag{
|
||||
Name: "authentication",
|
||||
Destination: &config.Authentication,
|
||||
|
@@ -2,16 +2,8 @@ package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/rancher/apiserver/pkg/types"
|
||||
"github.com/rancher/steve/pkg/accesscontrol"
|
||||
"github.com/rancher/steve/pkg/auth"
|
||||
"github.com/rancher/steve/pkg/client"
|
||||
"github.com/rancher/steve/pkg/clustercache"
|
||||
"github.com/rancher/steve/pkg/schema"
|
||||
"github.com/rancher/steve/pkg/server/router"
|
||||
"github.com/rancher/wrangler/pkg/generated/controllers/apiextensions.k8s.io"
|
||||
apiextensionsv1beta1 "github.com/rancher/wrangler/pkg/generated/controllers/apiextensions.k8s.io/v1beta1"
|
||||
"github.com/rancher/wrangler/pkg/generated/controllers/apiregistration.k8s.io"
|
||||
@@ -27,24 +19,6 @@ import (
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
*Controllers
|
||||
|
||||
RESTConfig *rest.Config
|
||||
|
||||
ClientFactory *client.Factory
|
||||
BaseSchemas *types.APISchemas
|
||||
AccessSetLookup accesscontrol.AccessSetLookup
|
||||
SchemaTemplates []schema.Template
|
||||
AuthMiddleware auth.Middleware
|
||||
Next http.Handler
|
||||
Router router.RouterFunc
|
||||
ClusterCache clustercache.ClusterCache
|
||||
PostStartHooks []func() error
|
||||
StartHooks []StartHook
|
||||
DashboardURL func() string
|
||||
}
|
||||
|
||||
type Controllers struct {
|
||||
RESTConfig *rest.Config
|
||||
K8s kubernetes.Interface
|
||||
|
@@ -38,13 +38,12 @@ func New(cfg *rest.Config, sf schema.Factory, authMiddleware auth.Middleware, ne
|
||||
proxy = k8sproxy.ImpersonatingHandler("/", cfg)
|
||||
}
|
||||
|
||||
w := authMiddleware.Wrap
|
||||
w := authMiddleware
|
||||
handlers := router.Handlers{
|
||||
Next: next,
|
||||
K8sResource: w(a.apiHandler(k8sAPI)),
|
||||
GenericResource: w(a.apiHandler(nil)),
|
||||
K8sProxy: w(proxy),
|
||||
APIRoot: w(a.apiHandler(apiRoot)),
|
||||
Next: next,
|
||||
K8sResource: w(a.apiHandler(k8sAPI)),
|
||||
K8sProxy: w(proxy),
|
||||
APIRoot: w(a.apiHandler(apiRoot)),
|
||||
}
|
||||
if routerFunc == nil {
|
||||
return router.Routes(handlers), nil
|
||||
@@ -89,16 +88,12 @@ type APIFunc func(schema.Factory, *types.APIRequest)
|
||||
|
||||
func (a *apiServer) apiHandler(apiFunc APIFunc) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
a.api(rw, req, apiFunc)
|
||||
apiOp, ok := a.common(rw, req)
|
||||
if ok {
|
||||
if apiFunc != nil {
|
||||
apiFunc(a.sf, apiOp)
|
||||
}
|
||||
a.server.Handle(apiOp)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (a *apiServer) api(rw http.ResponseWriter, req *http.Request, apiFunc APIFunc) {
|
||||
apiOp, ok := a.common(rw, req)
|
||||
if ok {
|
||||
if apiFunc != nil {
|
||||
apiFunc(a.sf, apiOp)
|
||||
}
|
||||
a.server.Handle(apiOp)
|
||||
}
|
||||
}
|
||||
|
@@ -10,11 +10,10 @@ import (
|
||||
type RouterFunc func(h Handlers) http.Handler
|
||||
|
||||
type Handlers struct {
|
||||
K8sResource http.Handler
|
||||
GenericResource http.Handler
|
||||
APIRoot http.Handler
|
||||
K8sProxy http.Handler
|
||||
Next http.Handler
|
||||
K8sResource http.Handler
|
||||
APIRoot http.Handler
|
||||
K8sProxy http.Handler
|
||||
Next http.Handler
|
||||
}
|
||||
|
||||
func Routes(h Handlers) http.Handler {
|
||||
|
@@ -8,35 +8,87 @@ import (
|
||||
"github.com/rancher/apiserver/pkg/types"
|
||||
"github.com/rancher/dynamiclistener/server"
|
||||
"github.com/rancher/steve/pkg/accesscontrol"
|
||||
"github.com/rancher/steve/pkg/auth"
|
||||
"github.com/rancher/steve/pkg/client"
|
||||
"github.com/rancher/steve/pkg/clustercache"
|
||||
schemacontroller "github.com/rancher/steve/pkg/controllers/schema"
|
||||
"github.com/rancher/steve/pkg/dashboard"
|
||||
"github.com/rancher/steve/pkg/resources"
|
||||
"github.com/rancher/steve/pkg/resources/common"
|
||||
"github.com/rancher/steve/pkg/resources/schemas"
|
||||
"github.com/rancher/steve/pkg/schema"
|
||||
"github.com/rancher/steve/pkg/server/handler"
|
||||
"github.com/rancher/steve/pkg/server/router"
|
||||
"github.com/rancher/steve/pkg/summarycache"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
var ErrConfigRequired = errors.New("rest config is required")
|
||||
|
||||
type Server struct {
|
||||
http.Handler
|
||||
|
||||
ClientFactory *client.Factory
|
||||
ClusterCache clustercache.ClusterCache
|
||||
SchemaFactory schema.Factory
|
||||
RESTConfig *rest.Config
|
||||
BaseSchemas *types.APISchemas
|
||||
AccessSetLookup accesscontrol.AccessSetLookup
|
||||
|
||||
authMiddleware auth.Middleware
|
||||
controllers *Controllers
|
||||
needControllerStart bool
|
||||
next http.Handler
|
||||
router router.RouterFunc
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
// Controllers If the controllers are passed in the caller must also start the controllers
|
||||
Controllers *Controllers
|
||||
ClientFactory *client.Factory
|
||||
AccessSetLookup accesscontrol.AccessSetLookup
|
||||
AuthMiddleware auth.Middleware
|
||||
Next http.Handler
|
||||
Router router.RouterFunc
|
||||
}
|
||||
|
||||
func New(ctx context.Context, restConfig *rest.Config, opts *Options) (*Server, error) {
|
||||
if opts == nil {
|
||||
opts = &Options{}
|
||||
}
|
||||
|
||||
server := &Server{
|
||||
RESTConfig: restConfig,
|
||||
ClientFactory: opts.ClientFactory,
|
||||
AccessSetLookup: opts.AccessSetLookup,
|
||||
authMiddleware: opts.AuthMiddleware,
|
||||
controllers: opts.Controllers,
|
||||
next: opts.Next,
|
||||
router: opts.Router,
|
||||
}
|
||||
|
||||
if err := setup(ctx, server); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return server, server.start(ctx)
|
||||
}
|
||||
|
||||
func setDefaults(server *Server) error {
|
||||
if server.RESTConfig == nil {
|
||||
return ErrConfigRequired
|
||||
}
|
||||
|
||||
if server.Controllers == nil {
|
||||
if server.controllers == nil {
|
||||
var err error
|
||||
server.Controllers, err = NewController(server.RESTConfig, nil)
|
||||
server.controllers, err = NewController(server.RESTConfig, nil)
|
||||
server.needControllerStart = true
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if server.Next == nil {
|
||||
server.Next = http.NotFoundHandler()
|
||||
if server.next == nil {
|
||||
server.next = http.NotFoundHandler()
|
||||
}
|
||||
|
||||
if server.BaseSchemas == nil {
|
||||
@@ -46,24 +98,24 @@ func setDefaults(server *Server) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func setup(ctx context.Context, server *Server) (http.Handler, *schema.Collection, error) {
|
||||
func setup(ctx context.Context, server *Server) error {
|
||||
err := setDefaults(server)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
cf := server.ClientFactory
|
||||
if cf == nil {
|
||||
cf, err = client.NewFactory(server.RESTConfig, server.AuthMiddleware != nil)
|
||||
cf, err = client.NewFactory(server.RESTConfig, server.authMiddleware != nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return err
|
||||
}
|
||||
server.ClientFactory = cf
|
||||
}
|
||||
|
||||
asl := server.AccessSetLookup
|
||||
if asl == nil {
|
||||
asl = accesscontrol.NewAccessStore(ctx, true, server.RBAC)
|
||||
asl = accesscontrol.NewAccessStore(ctx, true, server.controllers.RBAC)
|
||||
}
|
||||
|
||||
ccache := clustercache.NewClusterCache(ctx, cf.DynamicClient())
|
||||
@@ -71,7 +123,7 @@ func setup(ctx context.Context, server *Server) (http.Handler, *schema.Collectio
|
||||
|
||||
server.BaseSchemas, err = resources.DefaultSchemas(ctx, server.BaseSchemas, ccache, cf)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
sf := schema.NewCollection(ctx, server.BaseSchemas, asl)
|
||||
@@ -80,88 +132,53 @@ func setup(ctx context.Context, server *Server) (http.Handler, *schema.Collectio
|
||||
ccache.OnRemove(ctx, summaryCache.OnRemove)
|
||||
ccache.OnChange(ctx, summaryCache.OnChange)
|
||||
|
||||
server.SchemaTemplates = append(server.SchemaTemplates, resources.DefaultSchemaTemplates(cf, summaryCache, asl, server.K8s.Discovery())...)
|
||||
for _, template := range resources.DefaultSchemaTemplates(cf, summaryCache, asl, server.controllers.K8s.Discovery()) {
|
||||
sf.AddTemplate(template)
|
||||
}
|
||||
|
||||
cols, err := common.NewDynamicColumns(server.RESTConfig)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
schemas.SetupWatcher(ctx, server.BaseSchemas, asl, sf)
|
||||
|
||||
sync := schemacontroller.Register(ctx,
|
||||
schemacontroller.Register(ctx,
|
||||
cols,
|
||||
server.K8s.Discovery(),
|
||||
server.CRD.CustomResourceDefinition(),
|
||||
server.API.APIService(),
|
||||
server.K8s.AuthorizationV1().SelfSubjectAccessReviews(),
|
||||
server.controllers.K8s.Discovery(),
|
||||
server.controllers.CRD.CustomResourceDefinition(),
|
||||
server.controllers.API.APIService(),
|
||||
server.controllers.K8s.AuthorizationV1().SelfSubjectAccessReviews(),
|
||||
ccache,
|
||||
sf)
|
||||
|
||||
handler, err := handler.New(server.RESTConfig, sf, server.AuthMiddleware, server.Next, server.Router)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
server.PostStartHooks = append(server.PostStartHooks, func() error {
|
||||
return sync()
|
||||
})
|
||||
|
||||
if server.DashboardURL != nil && server.DashboardURL() != "" {
|
||||
handler = dashboard.Route(handler, server.DashboardURL)
|
||||
}
|
||||
|
||||
return handler, sf, nil
|
||||
}
|
||||
|
||||
func (c *Server) Handler(ctx context.Context) (http.Handler, error) {
|
||||
handler, sf, err := setup(ctx, c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.Next = handler
|
||||
|
||||
for _, hook := range c.StartHooks {
|
||||
if err := hook(ctx, c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for i := range c.SchemaTemplates {
|
||||
sf.AddTemplate(&c.SchemaTemplates[i])
|
||||
}
|
||||
|
||||
if err := c.Controllers.Start(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, hook := range c.PostStartHooks {
|
||||
if err := hook(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return c.Next, nil
|
||||
}
|
||||
|
||||
func (c *Server) ListenAndServe(ctx context.Context, httpsPort, httpPort int, opts *server.ListenOpts) error {
|
||||
handler, err := c.Handler(ctx)
|
||||
handler, err := handler.New(server.RESTConfig, sf, server.authMiddleware, server.next, server.router)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
server.Handler = handler
|
||||
server.SchemaFactory = sf
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Server) start(ctx context.Context) error {
|
||||
if c.needControllerStart {
|
||||
if err := c.controllers.Start(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Server) ListenAndServe(ctx context.Context, httpsPort, httpPort int, opts *server.ListenOpts) error {
|
||||
if opts == nil {
|
||||
opts = &server.ListenOpts{}
|
||||
}
|
||||
if opts.Storage == nil && opts.Secrets == nil {
|
||||
opts.Secrets = c.Core.Secret()
|
||||
opts.Secrets = c.controllers.Core.Secret()
|
||||
}
|
||||
if err := server.ListenAndServe(ctx, httpsPort, httpPort, handler, opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.Controllers.Start(ctx); err != nil {
|
||||
if err := server.ListenAndServe(ctx, httpsPort, httpPort, c, opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user