From b61ac7d555220073dcf622585a26327222b6f573 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Fri, 31 Jan 2020 21:29:43 -0700 Subject: [PATCH] Add ability to start on controllers when type is seen --- pkg/controllers/schema/schemas.go | 32 ++++++++++++++++++++++++++ pkg/schema/collection.go | 6 +++++ pkg/schemaserver/types/server_types.go | 4 ++++ 3 files changed, 42 insertions(+) diff --git a/pkg/controllers/schema/schemas.go b/pkg/controllers/schema/schemas.go index a69e0a3..7c138f6 100644 --- a/pkg/controllers/schema/schemas.go +++ b/pkg/controllers/schema/schemas.go @@ -27,12 +27,15 @@ type SchemasHandler interface { type handler struct { sync.Mutex + ctx context.Context toSync int32 schemas *schema2.Collection client discovery.DiscoveryInterface crd apiextcontrollerv1beta1.CustomResourceDefinitionClient ssar authorizationv1client.SelfSubjectAccessReviewInterface handler SchemasHandler + + running map[string]func() } func Register(ctx context.Context, @@ -44,11 +47,13 @@ func Register(ctx context.Context, schemas *schema2.Collection) (init func() error) { h := &handler{ + ctx: ctx, client: discovery, schemas: schemas, handler: schemasHandler, crd: crd, ssar: ssar, + running: map[string]func(){}, } apiService.OnChange(ctx, "schema", h.OnChangeAPIService) @@ -126,6 +131,7 @@ func (h *handler) refreshAll() error { filteredSchemas[id] = schema } + h.startStopTemplate(filteredSchemas) h.schemas.Reset(filteredSchemas) if h.handler != nil { return h.handler.OnSchemas(h.schemas) @@ -134,6 +140,32 @@ func (h *handler) refreshAll() error { return nil } +func (h *handler) startStopTemplate(schemas map[string]*types.APISchema) { + for id := range schemas { + if _, ok := h.running[id]; ok { + continue + } + template := h.schemas.TemplateForSchemaID(id) + if template == nil || template.Start == nil { + continue + } + + subCtx, cancel := context.WithCancel(h.ctx) + if err := template.Start(subCtx); err != nil { + logrus.Errorf("failed to start schema template: %s", id) + continue + } + h.running[id] = cancel + } + + for id, cancel := range h.running { + if _, ok := schemas[id]; !ok { + cancel() + delete(h.running, id) + } + } +} + func (h *handler) allowed(schema *types.APISchema) (bool, error) { gvr := attributes.GVR(schema) ssar, err := h.ssar.Create(&authorizationv1.SelfSubjectAccessReview{ diff --git a/pkg/schema/collection.go b/pkg/schema/collection.go index ec3e9ef..57a5350 100644 --- a/pkg/schema/collection.go +++ b/pkg/schema/collection.go @@ -1,6 +1,7 @@ package schema import ( + "context" "strings" "github.com/rancher/steve/pkg/accesscontrol" @@ -38,6 +39,7 @@ type Template struct { Customize func(*types.APISchema) Formatter types.Formatter Store types.Store + Start func(ctx context.Context) error StoreFactory func(types.Store) types.Store Mapper schemas.Mapper Columns []table.Column @@ -108,6 +110,10 @@ func (c *Collection) ByGVK(gvk schema.GroupVersionKind) string { return c.byGVK[gvk] } +func (c *Collection) TemplateForSchemaID(id string) *Template { + return c.templates[id] +} + func (c *Collection) AddTemplate(template *Template) { if template.Kind != "" { c.templates[template.Group+"/"+template.Kind] = template diff --git a/pkg/schemaserver/types/server_types.go b/pkg/schemaserver/types/server_types.go index a57154d..fe489a6 100644 --- a/pkg/schemaserver/types/server_types.go +++ b/pkg/schemaserver/types/server_types.go @@ -10,6 +10,7 @@ import ( "github.com/rancher/wrangler/pkg/data/convert" "github.com/rancher/wrangler/pkg/schemas/validation" meta2 "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/endpoints/request" @@ -220,6 +221,9 @@ type APIObjectList struct { } func (a *APIObject) Data() data.Object { + if unstr, ok := a.Object.(*unstructured.Unstructured); ok { + return unstr.Object + } data, err := convert.EncodeToMap(a.Object) if err != nil { return convert.ToMapInterface(a.Object)