mirror of
https://github.com/niusmallnan/steve.git
synced 2025-06-26 14:41:35 +00:00
testing
This commit is contained in:
parent
f403507ea9
commit
a3fbe499d1
@ -16,6 +16,11 @@ import (
|
|||||||
"k8s.io/client-go/transport"
|
"k8s.io/client-go/transport"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ExistingContext = ToMiddleware(AuthenticatorFunc(func(req *http.Request) (user.Info, bool, error) {
|
||||||
|
user, ok := request.UserFrom(req.Context())
|
||||||
|
return user, ok, nil
|
||||||
|
}))
|
||||||
|
|
||||||
type Authenticator interface {
|
type Authenticator interface {
|
||||||
Authenticate(req *http.Request) (user.Info, bool, error)
|
Authenticate(req *http.Request) (user.Info, bool, error)
|
||||||
}
|
}
|
||||||
@ -26,15 +31,12 @@ func (a AuthenticatorFunc) Authenticate(req *http.Request) (user.Info, bool, err
|
|||||||
return a(req)
|
return a(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Middleware func(http.ResponseWriter, *http.Request, http.Handler)
|
type Middleware func(next http.Handler) http.Handler
|
||||||
|
|
||||||
func (m Middleware) Wrap(handler http.Handler) http.Handler {
|
func (m Middleware) Chain(middleware Middleware) Middleware {
|
||||||
if m == nil {
|
return func(next http.Handler) http.Handler {
|
||||||
return handler
|
return m(middleware(next))
|
||||||
}
|
}
|
||||||
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
|
||||||
m(rw, req, handler)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func WebhookConfigForURL(url string) (string, error) {
|
func WebhookConfigForURL(url string) (string, error) {
|
||||||
@ -127,22 +129,32 @@ func (w *webhookAuth) Authenticate(req *http.Request) (user.Info, bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ToMiddleware(auth Authenticator) Middleware {
|
func ToMiddleware(auth Authenticator) Middleware {
|
||||||
return func(rw http.ResponseWriter, req *http.Request, next http.Handler) {
|
return func(next http.Handler) http.Handler {
|
||||||
info, ok, err := auth.Authenticate(req)
|
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||||
if err != nil {
|
info, ok, err := auth.Authenticate(req)
|
||||||
rw.WriteHeader(http.StatusUnauthorized)
|
if err != nil {
|
||||||
rw.Write([]byte(err.Error()))
|
info = &user.DefaultInfo{
|
||||||
return
|
Name: "system:cattle:error",
|
||||||
}
|
UID: "system:cattle:error",
|
||||||
|
Groups: []string{
|
||||||
|
"system:unauthenticated",
|
||||||
|
"system:cattle:error",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else if !ok {
|
||||||
|
info = &user.DefaultInfo{
|
||||||
|
Name: "system:unauthenticated",
|
||||||
|
UID: "system:unauthenticated",
|
||||||
|
Groups: []string{
|
||||||
|
"system:unauthenticated",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !ok {
|
ctx := request.WithUser(req.Context(), info)
|
||||||
rw.WriteHeader(http.StatusUnauthorized)
|
req = req.WithContext(ctx)
|
||||||
return
|
next.ServeHTTP(rw, req)
|
||||||
}
|
})
|
||||||
|
|
||||||
ctx := request.WithUser(req.Context(), info)
|
|
||||||
req = req.WithContext(ctx)
|
|
||||||
next.ServeHTTP(rw, req)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ func Register(ctx context.Context,
|
|||||||
apiService v1.APIServiceController,
|
apiService v1.APIServiceController,
|
||||||
ssar authorizationv1client.SelfSubjectAccessReviewInterface,
|
ssar authorizationv1client.SelfSubjectAccessReviewInterface,
|
||||||
schemasHandler SchemasHandler,
|
schemasHandler SchemasHandler,
|
||||||
schemas *schema2.Collection) (init func() error) {
|
schemas *schema2.Collection) {
|
||||||
|
|
||||||
h := &handler{
|
h := &handler{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
@ -69,11 +69,6 @@ func Register(ctx context.Context,
|
|||||||
|
|
||||||
apiService.OnChange(ctx, "schema", h.OnChangeAPIService)
|
apiService.OnChange(ctx, "schema", h.OnChangeAPIService)
|
||||||
crd.OnChange(ctx, "schema", h.OnChangeCRD)
|
crd.OnChange(ctx, "schema", h.OnChangeCRD)
|
||||||
|
|
||||||
return func() error {
|
|
||||||
h.queueRefresh()
|
|
||||||
return h.refreshAll(ctx)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *handler) OnChangeCRD(key string, crd *v1beta1.CustomResourceDefinition) (*v1beta1.CustomResourceDefinition, error) {
|
func (h *handler) OnChangeCRD(key string, crd *v1beta1.CustomResourceDefinition) (*v1beta1.CustomResourceDefinition, error) {
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
package dashboard
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/tls"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
|
||||||
"github.com/rancher/apiserver/pkg/middleware"
|
|
||||||
"github.com/rancher/apiserver/pkg/parse"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
insecureClient = &http.Client{
|
|
||||||
Transport: &http.Transport{
|
|
||||||
Proxy: http.ProxyFromEnvironment,
|
|
||||||
TLSClientConfig: &tls.Config{
|
|
||||||
InsecureSkipVerify: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func content(uiSetting func() string) http.Handler {
|
|
||||||
return http.FileServer(http.Dir(uiSetting()))
|
|
||||||
}
|
|
||||||
|
|
||||||
func Route(next http.Handler, uiSetting func() string) http.Handler {
|
|
||||||
uiContent := middleware.NewMiddlewareChain(middleware.Gzip,
|
|
||||||
middleware.DenyFrameOptions,
|
|
||||||
middleware.CacheMiddleware("json", "js", "css")).Handler(content(uiSetting))
|
|
||||||
|
|
||||||
root := mux.NewRouter()
|
|
||||||
root.UseEncodedPath()
|
|
||||||
root.Path("/dashboard").HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
|
||||||
http.Redirect(rw, req, "/dashboard/", http.StatusFound)
|
|
||||||
})
|
|
||||||
root.PathPrefix("/dashboard/assets").Handler(uiContent)
|
|
||||||
root.PathPrefix("/dashboard/translations").Handler(uiContent)
|
|
||||||
root.PathPrefix("/dashboard/engines-dist").Handler(uiContent)
|
|
||||||
root.Handle("/dashboard/asset-manifest.json", uiContent)
|
|
||||||
root.Handle("/dashboard/index.html", uiContent)
|
|
||||||
root.PathPrefix("/dashboard/").Handler(wrapUI(next, uiSetting))
|
|
||||||
root.NotFoundHandler = next
|
|
||||||
|
|
||||||
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
|
||||||
if strings.HasPrefix(req.URL.Path, "/k8s/clusters/local") {
|
|
||||||
req.URL.Path = strings.TrimPrefix(req.URL.Path, "/k8s/clusters/local")
|
|
||||||
if req.URL.Path == "" {
|
|
||||||
req.URL.Path = "/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
root.ServeHTTP(rw, req)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func wrapUI(next http.Handler, uiGetter func() string) http.Handler {
|
|
||||||
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
|
|
||||||
if parse.IsBrowser(req, true) {
|
|
||||||
path := uiGetter()
|
|
||||||
if strings.HasPrefix(path, "http") {
|
|
||||||
ui(resp, req, path)
|
|
||||||
} else {
|
|
||||||
http.ServeFile(resp, req, path)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
next.ServeHTTP(resp, req)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func ui(resp http.ResponseWriter, req *http.Request, url string) {
|
|
||||||
if err := serveIndex(resp, req, url); err != nil {
|
|
||||||
logrus.Errorf("failed to serve UI: %v", err)
|
|
||||||
resp.WriteHeader(500)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func serveIndex(resp http.ResponseWriter, req *http.Request, url string) error {
|
|
||||||
r, err := insecureClient.Get(url)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer r.Body.Close()
|
|
||||||
|
|
||||||
_, err = io.Copy(resp, r.Body)
|
|
||||||
return err
|
|
||||||
}
|
|
@ -23,6 +23,7 @@ type Factory interface {
|
|||||||
ByGVR(gvr schema.GroupVersionResource) string
|
ByGVR(gvr schema.GroupVersionResource) string
|
||||||
ByGVK(gvr schema.GroupVersionKind) string
|
ByGVK(gvr schema.GroupVersionKind) string
|
||||||
OnChange(ctx context.Context, cb func())
|
OnChange(ctx context.Context, cb func())
|
||||||
|
AddTemplate(template ...Template)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Collection struct {
|
type Collection struct {
|
||||||
@ -210,17 +211,19 @@ func (c *Collection) ByGVK(gvk schema.GroupVersionKind) string {
|
|||||||
return c.byGVK[gvk]
|
return c.byGVK[gvk]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Collection) AddTemplate(template *Template) {
|
func (c *Collection) AddTemplate(templates ...Template) {
|
||||||
c.lock.RLock()
|
c.lock.RLock()
|
||||||
defer c.lock.RUnlock()
|
defer c.lock.RUnlock()
|
||||||
|
|
||||||
if template.Kind != "" {
|
for i, template := range templates {
|
||||||
c.templates[template.Group+"/"+template.Kind] = template
|
if template.Kind != "" {
|
||||||
}
|
c.templates[template.Group+"/"+template.Kind] = &templates[i]
|
||||||
if template.ID != "" {
|
}
|
||||||
c.templates[template.ID] = template
|
if template.ID != "" {
|
||||||
}
|
c.templates[template.ID] = &templates[i]
|
||||||
if template.Kind == "" && template.Group == "" && template.ID == "" {
|
}
|
||||||
c.templates[""] = template
|
if template.Kind == "" && template.Group == "" && template.ID == "" {
|
||||||
|
c.templates[""] = &templates[i]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ type Config struct {
|
|||||||
KubeConfig string
|
KubeConfig string
|
||||||
HTTPSListenPort int
|
HTTPSListenPort int
|
||||||
HTTPListenPort int
|
HTTPListenPort int
|
||||||
DashboardURL string
|
|
||||||
Authentication bool
|
Authentication bool
|
||||||
|
|
||||||
WebhookConfig authcli.WebhookConfig
|
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) {
|
func (c *Config) ToServer(ctx context.Context) (*server.Server, error) {
|
||||||
var (
|
var (
|
||||||
auth steveauth.Middleware
|
auth steveauth.Middleware
|
||||||
startHooks []server.StartHook
|
|
||||||
)
|
)
|
||||||
|
|
||||||
restConfig, err := kubeconfig.GetNonInteractiveClientConfig(c.KubeConfig).ClientConfig()
|
restConfig, err := kubeconfig.GetNonInteractiveClientConfig(c.KubeConfig).ClientConfig()
|
||||||
@ -48,14 +46,9 @@ func (c *Config) ToServer(ctx context.Context) (*server.Server, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &server.Server{
|
return server.New(ctx, restConfig, &server.Options{
|
||||||
RESTConfig: restConfig,
|
|
||||||
AuthMiddleware: auth,
|
AuthMiddleware: auth,
|
||||||
DashboardURL: func() string {
|
})
|
||||||
return c.DashboardURL
|
|
||||||
},
|
|
||||||
StartHooks: startHooks,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Flags(config *Config) []cli.Flag {
|
func Flags(config *Config) []cli.Flag {
|
||||||
@ -75,11 +68,6 @@ func Flags(config *Config) []cli.Flag {
|
|||||||
Value: 9080,
|
Value: 9080,
|
||||||
Destination: &config.HTTPListenPort,
|
Destination: &config.HTTPListenPort,
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
|
||||||
Name: "dashboard-url",
|
|
||||||
Value: "https://releases.rancher.com/dashboard/latest/index.html",
|
|
||||||
Destination: &config.DashboardURL,
|
|
||||||
},
|
|
||||||
cli.BoolTFlag{
|
cli.BoolTFlag{
|
||||||
Name: "authentication",
|
Name: "authentication",
|
||||||
Destination: &config.Authentication,
|
Destination: &config.Authentication,
|
||||||
|
@ -2,16 +2,8 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
|
||||||
"time"
|
"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"
|
"github.com/rancher/wrangler/pkg/generated/controllers/apiextensions.k8s.io"
|
||||||
apiextensionsv1beta1 "github.com/rancher/wrangler/pkg/generated/controllers/apiextensions.k8s.io/v1beta1"
|
apiextensionsv1beta1 "github.com/rancher/wrangler/pkg/generated/controllers/apiextensions.k8s.io/v1beta1"
|
||||||
"github.com/rancher/wrangler/pkg/generated/controllers/apiregistration.k8s.io"
|
"github.com/rancher/wrangler/pkg/generated/controllers/apiregistration.k8s.io"
|
||||||
@ -27,24 +19,6 @@ import (
|
|||||||
"k8s.io/client-go/rest"
|
"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 {
|
type Controllers struct {
|
||||||
RESTConfig *rest.Config
|
RESTConfig *rest.Config
|
||||||
K8s kubernetes.Interface
|
K8s kubernetes.Interface
|
||||||
|
@ -38,13 +38,12 @@ func New(cfg *rest.Config, sf schema.Factory, authMiddleware auth.Middleware, ne
|
|||||||
proxy = k8sproxy.ImpersonatingHandler("/", cfg)
|
proxy = k8sproxy.ImpersonatingHandler("/", cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
w := authMiddleware.Wrap
|
w := authMiddleware
|
||||||
handlers := router.Handlers{
|
handlers := router.Handlers{
|
||||||
Next: next,
|
Next: next,
|
||||||
K8sResource: w(a.apiHandler(k8sAPI)),
|
K8sResource: w(a.apiHandler(k8sAPI)),
|
||||||
GenericResource: w(a.apiHandler(nil)),
|
K8sProxy: w(proxy),
|
||||||
K8sProxy: w(proxy),
|
APIRoot: w(a.apiHandler(apiRoot)),
|
||||||
APIRoot: w(a.apiHandler(apiRoot)),
|
|
||||||
}
|
}
|
||||||
if routerFunc == nil {
|
if routerFunc == nil {
|
||||||
return router.Routes(handlers), 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 {
|
func (a *apiServer) apiHandler(apiFunc APIFunc) http.Handler {
|
||||||
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
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 RouterFunc func(h Handlers) http.Handler
|
||||||
|
|
||||||
type Handlers struct {
|
type Handlers struct {
|
||||||
K8sResource http.Handler
|
K8sResource http.Handler
|
||||||
GenericResource http.Handler
|
APIRoot http.Handler
|
||||||
APIRoot http.Handler
|
K8sProxy http.Handler
|
||||||
K8sProxy http.Handler
|
Next http.Handler
|
||||||
Next http.Handler
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Routes(h Handlers) http.Handler {
|
func Routes(h Handlers) http.Handler {
|
||||||
|
@ -8,35 +8,87 @@ import (
|
|||||||
"github.com/rancher/apiserver/pkg/types"
|
"github.com/rancher/apiserver/pkg/types"
|
||||||
"github.com/rancher/dynamiclistener/server"
|
"github.com/rancher/dynamiclistener/server"
|
||||||
"github.com/rancher/steve/pkg/accesscontrol"
|
"github.com/rancher/steve/pkg/accesscontrol"
|
||||||
|
"github.com/rancher/steve/pkg/auth"
|
||||||
"github.com/rancher/steve/pkg/client"
|
"github.com/rancher/steve/pkg/client"
|
||||||
"github.com/rancher/steve/pkg/clustercache"
|
"github.com/rancher/steve/pkg/clustercache"
|
||||||
schemacontroller "github.com/rancher/steve/pkg/controllers/schema"
|
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"
|
||||||
"github.com/rancher/steve/pkg/resources/common"
|
"github.com/rancher/steve/pkg/resources/common"
|
||||||
"github.com/rancher/steve/pkg/resources/schemas"
|
"github.com/rancher/steve/pkg/resources/schemas"
|
||||||
"github.com/rancher/steve/pkg/schema"
|
"github.com/rancher/steve/pkg/schema"
|
||||||
"github.com/rancher/steve/pkg/server/handler"
|
"github.com/rancher/steve/pkg/server/handler"
|
||||||
|
"github.com/rancher/steve/pkg/server/router"
|
||||||
"github.com/rancher/steve/pkg/summarycache"
|
"github.com/rancher/steve/pkg/summarycache"
|
||||||
|
"k8s.io/client-go/rest"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrConfigRequired = errors.New("rest config is required")
|
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 {
|
func setDefaults(server *Server) error {
|
||||||
if server.RESTConfig == nil {
|
if server.RESTConfig == nil {
|
||||||
return ErrConfigRequired
|
return ErrConfigRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
if server.Controllers == nil {
|
if server.controllers == nil {
|
||||||
var err error
|
var err error
|
||||||
server.Controllers, err = NewController(server.RESTConfig, nil)
|
server.controllers, err = NewController(server.RESTConfig, nil)
|
||||||
|
server.needControllerStart = true
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if server.Next == nil {
|
if server.next == nil {
|
||||||
server.Next = http.NotFoundHandler()
|
server.next = http.NotFoundHandler()
|
||||||
}
|
}
|
||||||
|
|
||||||
if server.BaseSchemas == nil {
|
if server.BaseSchemas == nil {
|
||||||
@ -46,24 +98,24 @@ func setDefaults(server *Server) error {
|
|||||||
return nil
|
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)
|
err := setDefaults(server)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cf := server.ClientFactory
|
cf := server.ClientFactory
|
||||||
if cf == nil {
|
if cf == nil {
|
||||||
cf, err = client.NewFactory(server.RESTConfig, server.AuthMiddleware != nil)
|
cf, err = client.NewFactory(server.RESTConfig, server.authMiddleware != nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return err
|
||||||
}
|
}
|
||||||
server.ClientFactory = cf
|
server.ClientFactory = cf
|
||||||
}
|
}
|
||||||
|
|
||||||
asl := server.AccessSetLookup
|
asl := server.AccessSetLookup
|
||||||
if asl == nil {
|
if asl == nil {
|
||||||
asl = accesscontrol.NewAccessStore(ctx, true, server.RBAC)
|
asl = accesscontrol.NewAccessStore(ctx, true, server.controllers.RBAC)
|
||||||
}
|
}
|
||||||
|
|
||||||
ccache := clustercache.NewClusterCache(ctx, cf.DynamicClient())
|
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)
|
server.BaseSchemas, err = resources.DefaultSchemas(ctx, server.BaseSchemas, ccache, cf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
sf := schema.NewCollection(ctx, server.BaseSchemas, asl)
|
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.OnRemove(ctx, summaryCache.OnRemove)
|
||||||
ccache.OnChange(ctx, summaryCache.OnChange)
|
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)
|
cols, err := common.NewDynamicColumns(server.RESTConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
schemas.SetupWatcher(ctx, server.BaseSchemas, asl, sf)
|
schemas.SetupWatcher(ctx, server.BaseSchemas, asl, sf)
|
||||||
|
|
||||||
sync := schemacontroller.Register(ctx,
|
schemacontroller.Register(ctx,
|
||||||
cols,
|
cols,
|
||||||
server.K8s.Discovery(),
|
server.controllers.K8s.Discovery(),
|
||||||
server.CRD.CustomResourceDefinition(),
|
server.controllers.CRD.CustomResourceDefinition(),
|
||||||
server.API.APIService(),
|
server.controllers.API.APIService(),
|
||||||
server.K8s.AuthorizationV1().SelfSubjectAccessReviews(),
|
server.controllers.K8s.AuthorizationV1().SelfSubjectAccessReviews(),
|
||||||
ccache,
|
ccache,
|
||||||
sf)
|
sf)
|
||||||
|
|
||||||
handler, err := handler.New(server.RESTConfig, sf, server.AuthMiddleware, server.Next, server.Router)
|
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)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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 {
|
if opts == nil {
|
||||||
opts = &server.ListenOpts{}
|
opts = &server.ListenOpts{}
|
||||||
}
|
}
|
||||||
if opts.Storage == nil && opts.Secrets == nil {
|
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 {
|
if err := server.ListenAndServe(ctx, httpsPort, httpPort, c, opts); err != nil {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.Controllers.Start(ctx); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,7 +343,7 @@ func (s *Store) WatchNames(apiOp *types.APIRequest, schema *types.APISchema, w t
|
|||||||
go func() {
|
go func() {
|
||||||
defer close(result)
|
defer close(result)
|
||||||
for item := range c {
|
for item := range c {
|
||||||
if item.Error != nil && names.Has(item.Object.Name()) {
|
if item.Error == nil && names.Has(item.Object.Name()) {
|
||||||
result <- item
|
result <- item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
9
test.yaml
Normal file
9
test.yaml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
kind: ConfigMap
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
generateName: test-
|
||||||
|
ownerReferences:
|
||||||
|
- kind: bad
|
||||||
|
apiVersion: bad
|
||||||
|
name: bad
|
||||||
|
uid: bad2
|
9
test2.yaml
Normal file
9
test2.yaml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
kind: ConfigMap
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
generateName: child-
|
||||||
|
ownerReferences:
|
||||||
|
- kind: ConfigMap
|
||||||
|
apiVersion: v1
|
||||||
|
name: bad
|
||||||
|
uid: bad
|
20
user.yaml
Normal file
20
user.yaml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
apiVersion: management.cattle.io/v3
|
||||||
|
displayName: Default Admin
|
||||||
|
kind: User
|
||||||
|
metadata:
|
||||||
|
name: admin
|
||||||
|
password: $2a$10$LWysOkIa80mPXJ9W9dyuteKEP2LIswCURen2fNNuKhnjQ1RLYV00K
|
||||||
|
username: admin
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: imclusteradmin
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: cluster-admin
|
||||||
|
subjects:
|
||||||
|
- kind: User
|
||||||
|
name: admin
|
Loading…
Reference in New Issue
Block a user