diff --git a/client/context.go b/client/context.go index 5f7971e9..653037e9 100644 --- a/client/context.go +++ b/client/context.go @@ -25,6 +25,7 @@ import ( "k8s.io/apiserver/pkg/authentication/user" "k8s.io/client-go/dynamic" + "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/cluster" @@ -116,3 +117,20 @@ func User(ctx context.Context) user.Info { u, _ := request.UserFrom(ctx) return u } + +// cfgKeyOfApp is the key that the config make is associated with. +type cfgKeyOfApp struct{} + +// WithAppConfig associates a given config with the app context. +func WithAppConfig(ctx context.Context, cfg *rest.Config) context.Context { + return context.WithValue(ctx, cfgKeyOfApp{}, cfg) +} + +// GetAppConfig gets the current config of app (pod) from the context. +func GetAppConfig(ctx context.Context) *rest.Config { + value := ctx.Value(cfgKeyOfApp{}) + if value == nil { + return nil + } + return value.(*rest.Config) +} diff --git a/client/context_test.go b/client/context_test.go index 92d9a9c0..241f1f4c 100644 --- a/client/context_test.go +++ b/client/context_test.go @@ -20,6 +20,8 @@ import ( "context" "testing" + "k8s.io/client-go/rest" + dynamicFake "k8s.io/client-go/dynamic/fake" . "github.com/onsi/gomega" @@ -79,3 +81,16 @@ func TestDynamicContext(t *testing.T) { ctx = WithDynamicClient(ctx, client) g.Expect(DynamicClient(ctx)).To(Equal(client)) } + +func TestAppConfigContext(t *testing.T) { + g := NewGomegaWithT(t) + + ctx := context.TODO() + + cfg := GetAppConfig(ctx) + g.Expect(cfg).To(BeNil()) + + cfg = &rest.Config{} + ctx = WithAppConfig(ctx, cfg) + g.Expect(GetAppConfig(ctx)).To(Equal(cfg)) +} diff --git a/client/manager.go b/client/manager.go index 7fc113ce..85852b20 100644 --- a/client/manager.go +++ b/client/manager.go @@ -95,6 +95,7 @@ func ManagerFilter(ctx context.Context, mgr *Manager) restful.FilterFunction { log := logging.FromContext(ctx).Named("manager-filter") scheme := kscheme.Scheme(ctx) serviceAccountClient := Client(ctx) + configInApp := GetAppConfig(ctx) return func(req *restful.Request, resp *restful.Response, chain *restful.FilterChain) { start := time.Now() @@ -115,6 +116,7 @@ func ManagerFilter(ctx context.Context, mgr *Manager) restful.FilterFunction { config.Timeout = DefaultTimeout reqCtx = injection.WithConfig(reqCtx, config) + reqCtx = WithAppConfig(reqCtx, configInApp) user, err := userFromBearerToken(strings.TrimPrefix(req.Request.Header.Get("Authorization"), "Bearer ")) if err != nil { diff --git a/client/rbac_filter.go b/client/rbac_filter.go index c89bb973..7abd29ec 100644 --- a/client/rbac_filter.go +++ b/client/rbac_filter.go @@ -108,6 +108,9 @@ func SubjectReviewFilterForResource(ctx context.Context, resourceAtt authv1.Reso func isImpersonateRequest(reqCtx context.Context) bool { var config = injection.GetConfig(reqCtx) + if config == nil { + return false + } return config.Impersonate.UserName != "" || len(config.Impersonate.Groups) != 0 || len(config.Impersonate.Extra) != 0 } diff --git a/plugin/storage/route/archive/v1alpha1/archive.go b/plugin/storage/route/archive/v1alpha1/archive.go index 1c3805d1..e02474a5 100644 --- a/plugin/storage/route/archive/v1alpha1/archive.go +++ b/plugin/storage/route/archive/v1alpha1/archive.go @@ -53,6 +53,7 @@ func NewArchive(impl archivev1alpha1.ArchiveCapable) storage.VersionedRouter { } func (a *archive) Register(ctx context.Context, ws *restful.WebService) error { + storagePluginParam := ws.PathParameter("storageplugin", "storage plugin to be used") ws.Route( ws.POST("storageplugin/{storageplugin}/records").To(a.ListRecords). diff --git a/plugin/storage/route/core/v1alpha1/auth.go b/plugin/storage/route/core/v1alpha1/auth.go index 1a4ac6f6..5c7c49d9 100644 --- a/plugin/storage/route/core/v1alpha1/auth.go +++ b/plugin/storage/route/core/v1alpha1/auth.go @@ -47,6 +47,7 @@ func NewAuthCheck(impl corev1alpha1.AuthChecker) storage.VersionedRouter { } func (a *authCheck) Register(ctx context.Context, ws *restful.WebService) error { + ws.Route( ws.POST("/auth/check").To(a.AuthCheck). Doc("Storage plugin auth check"). diff --git a/plugin/storage/route/filestore/v1alpha1/filemeta.go b/plugin/storage/route/filestore/v1alpha1/filemeta.go index 1ae1e3d7..23d03ade 100644 --- a/plugin/storage/route/filestore/v1alpha1/filemeta.go +++ b/plugin/storage/route/filestore/v1alpha1/filemeta.go @@ -53,16 +53,6 @@ func (a *fileMeta) Register(ctx context.Context, ws *restful.WebService) error { storagePluginParam := ws.PathParameter("storagePlugin", "storage plugin to be used") objectNameParam := ws.PathParameter("objectName", "file object name in storage plugin") - if manager := kclient.ManagerCtx(ctx); manager != nil { - filters, err := manager.Filters(ctx) - if err != nil { - return err - } - for _, filter := range filters { - ws = ws.Filter(filter) - } - } - ws.Route( ws.GET("/storageplugins/{storagePlugin}/filemetas/{objectName:*}").To(a.GetFileMeta). Filter(kclient.SubjectReviewFilterForResource(ctx, v1alpha1.FileMetaResourceAttributes("get"), "", "")). diff --git a/plugin/storage/route/filestore/v1alpha1/fileobject.go b/plugin/storage/route/filestore/v1alpha1/fileobject.go index 7c0c78d7..9008ac5e 100644 --- a/plugin/storage/route/filestore/v1alpha1/fileobject.go +++ b/plugin/storage/route/filestore/v1alpha1/fileobject.go @@ -56,16 +56,6 @@ func (a *fileObject) Register(ctx context.Context, ws *restful.WebService) error storagePluginParam := ws.PathParameter("storagePlugin", "storage plugin toe used") objectNameParam := ws.PathParameter("objectName", "file object name in storage tools") - if manager := kclient.ManagerCtx(ctx); manager != nil { - filters, err := manager.Filters(ctx) - if err != nil { - return err - } - for _, filter := range filters { - ws = ws.Filter(filter) - } - } - ws.Route( ws.PUT("storageplugins/{storagePlugin}/fileobjects/{objectName:*}").To(a.PutFileObject). Filter(kclient.SubjectReviewFilterForResource(ctx, v1alpha1.FileObjectResourceAttributes("update"), "", "")). diff --git a/plugin/storage/route/route.go b/plugin/storage/route/route.go index ea12e051..c84184a8 100644 --- a/plugin/storage/route/route.go +++ b/plugin/storage/route/route.go @@ -67,6 +67,7 @@ func NewServicesWithContext(ctx context.Context, c client.Interface, filters ... groups = append(groups, group) servicesMap[groupVersionedPath] = group } + r.Register(ctx, group) } diff --git a/sharedmain/app.go b/sharedmain/app.go index 931dddb8..394d66bd 100644 --- a/sharedmain/app.go +++ b/sharedmain/app.go @@ -173,6 +173,7 @@ func (a *AppBuilder) init() { a.Config.Burst = Burst } a.Context, a.startInformers = injection.EnableInjectionOrDie(a.Context, a.Config) + a.Context = kclient.WithAppConfig(a.Context, a.Config) restyClient := resty.NewWithClient(kclient.NewHTTPClient()) restyClient.SetDisableWarn(true) @@ -343,6 +344,10 @@ func (a *AppBuilder) Controllers(ctors ...controllers.SetupChecker) *AppBuilder a.Logger.Infow("inject resource lock") } + // BaseContext provides Context values to Runnables + options.BaseContext = func() context.Context { + return a.Context + } a.Manager, err = ctrl.NewManager(a.Config, options) if err != nil { a.Logger.Fatalw("unable to start manager", "err", err) @@ -483,7 +488,8 @@ func (a *AppBuilder) StoragePlugins(plugins ...client.Interface) *AppBuilder { if err := plugin.Setup(a.Context, a.Logger); err != nil { a.Logger.Fatalw("plugin could not be setup correctly", "err", err, "plugin", plugin.Path()) } - wss, err := storageroute.NewServicesWithContext(a.Context, plugin) + filters, _ := a.ClientManager.Filters(a.Context) + wss, err := storageroute.NewServicesWithContext(a.Context, plugin, filters...) if err != nil { a.Logger.Fatalw("plugin could not start correctly", "err", err, "plugin", plugin.Path()) }