From eec4103473a4bf6f872aae02337e021b13f18245 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Thu, 28 Dec 2017 08:47:10 -0700 Subject: [PATCH] Make queryopts be a pointer --- api/access/list.go | 2 +- api/builtin/api_root.go | 2 +- api/handler/list.go | 2 +- api/handler/query.go | 4 ++-- pkg/subscribe/handler.go | 2 +- store/crd/crd_store.go | 4 ++-- store/empty/empty_store.go | 2 +- store/proxy/proxy_store.go | 9 ++++++--- store/schema/schema_store.go | 4 ++-- store/subtype/subtype_store.go | 11 +++++++++-- store/transform/transform.go | 4 ++-- store/wrapper/wrapper.go | 12 ++++++------ types/server_types.go | 12 ++++++------ 13 files changed, 40 insertions(+), 30 deletions(-) diff --git a/api/access/list.go b/api/access/list.go index 2c3a3d88..0730ea56 100644 --- a/api/access/list.go +++ b/api/access/list.go @@ -30,7 +30,7 @@ func ByID(context *types.APIContext, version *types.APIVersion, typeName string, return convert.ToObj(item, into) } -func List(context *types.APIContext, version *types.APIVersion, typeName string, opts types.QueryOptions, into interface{}) error { +func List(context *types.APIContext, version *types.APIVersion, typeName string, opts *types.QueryOptions, into interface{}) error { schema := context.Schemas.Schema(version, typeName) if schema == nil { return fmt.Errorf("failed to find schema " + typeName) diff --git a/api/builtin/api_root.go b/api/builtin/api_root.go index 5317a548..c51b81a0 100644 --- a/api/builtin/api_root.go +++ b/api/builtin/api_root.go @@ -52,7 +52,7 @@ func (a *APIRootStore) ByID(apiContext *types.APIContext, schema *types.Schema, return nil, nil } -func (a *APIRootStore) List(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) ([]map[string]interface{}, error) { +func (a *APIRootStore) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { var roots []map[string]interface{} for _, version := range apiContext.Schemas.Versions() { diff --git a/api/handler/list.go b/api/handler/list.go index 3f664eef..2f25d64b 100644 --- a/api/handler/list.go +++ b/api/handler/list.go @@ -20,7 +20,7 @@ func ListHandler(request *types.APIContext) error { if request.ID == "" { opts := parse.QueryOptions(request, request.Schema) - data, err = store.List(request, request.Schema, opts) + data, err = store.List(request, request.Schema, &opts) } else if request.Link == "" { data, err = store.ByID(request, request.Schema, request.ID) } else { diff --git a/api/handler/query.go b/api/handler/query.go index e199a883..f3e8ebf6 100644 --- a/api/handler/query.go +++ b/api/handler/query.go @@ -7,11 +7,11 @@ import ( "github.com/rancher/norman/types/convert" ) -func QueryFilter(opts types.QueryOptions, data []map[string]interface{}) []map[string]interface{} { +func QueryFilter(opts *types.QueryOptions, data []map[string]interface{}) []map[string]interface{} { return ApplyQueryOptions(opts, data) } -func ApplyQueryOptions(options types.QueryOptions, data []map[string]interface{}) []map[string]interface{} { +func ApplyQueryOptions(options *types.QueryOptions, data []map[string]interface{}) []map[string]interface{} { data = ApplyQueryConditions(options.Conditions, data) data = ApplySort(options.Sort, data) return ApplyPagination(options.Pagination, data) diff --git a/pkg/subscribe/handler.go b/pkg/subscribe/handler.go index fcdeeaab..7c933db7 100644 --- a/pkg/subscribe/handler.go +++ b/pkg/subscribe/handler.go @@ -115,7 +115,7 @@ func handler(apiContext *types.APIContext) error { func streamStore(ctx context.Context, eg *errgroup.Group, apiContext *types.APIContext, schema *types.Schema, result chan map[string]interface{}) { eg.Go(func() error { opts := parse.QueryOptions(apiContext, schema) - events, err := schema.Store.Watch(apiContext, schema, opts) + events, err := schema.Store.Watch(apiContext, schema, &opts) if err != nil { return err } diff --git a/store/crd/crd_store.go b/store/crd/crd_store.go index 1dbb3303..6521c9ab 100644 --- a/store/crd/crd_store.go +++ b/store/crd/crd_store.go @@ -68,7 +68,7 @@ func (c *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id st return store.Delete(apiContext, schema, id) } -func (c *Store) List(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) ([]map[string]interface{}, error) { +func (c *Store) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { store, ok := c.schemaStores[key(schema)] if !ok { return nil, nil @@ -76,7 +76,7 @@ func (c *Store) List(apiContext *types.APIContext, schema *types.Schema, opt typ return store.List(apiContext, schema, opt) } -func (c *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) (chan map[string]interface{}, error) { +func (c *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { store, ok := c.schemaStores[key(schema)] if !ok { return nil, nil diff --git a/store/empty/empty_store.go b/store/empty/empty_store.go index 3aaa8cc4..24f94e2d 100644 --- a/store/empty/empty_store.go +++ b/store/empty/empty_store.go @@ -27,6 +27,6 @@ func (e *Store) Update(apiContext *types.APIContext, schema *types.Schema, data return nil, nil } -func (e *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) (chan map[string]interface{}, error) { +func (e *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { return nil, nil } diff --git a/store/proxy/proxy_store.go b/store/proxy/proxy_store.go index 48de31bc..b4165ac2 100644 --- a/store/proxy/proxy_store.go +++ b/store/proxy/proxy_store.go @@ -79,7 +79,7 @@ func (p *Store) byID(apiContext *types.APIContext, schema *types.Schema, id stri return p.singleResult(apiContext, schema, req) } -func (p *Store) List(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) ([]map[string]interface{}, error) { +func (p *Store) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { namespace := getNamespace(apiContext, opt) req := p.common(namespace, p.k8sClient.Get()) @@ -99,7 +99,7 @@ func (p *Store) List(apiContext *types.APIContext, schema *types.Schema, opt typ return apiContext.AccessControl.FilterList(apiContext, result, p.authContext), nil } -func (p *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) (chan map[string]interface{}, error) { +func (p *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { namespace := getNamespace(apiContext, opt) req := p.common(namespace, p.k8sClient.Get()) @@ -126,6 +126,9 @@ func (p *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt ty for event := range watcher.ResultChan() { data := event.Object.(*unstructured.Unstructured) p.fromInternal(schema, data.Object) + if event.Type == watch.Deleted && data.Object != nil { + data.Object[".removed"] = true + } result <- apiContext.AccessControl.Filter(apiContext, data.Object, p.authContext) } close(result) @@ -144,7 +147,7 @@ func (d *unstructuredDecoder) Decode(data []byte, defaults *schema.GroupVersionK return into, defaults, ejson.Unmarshal(data, &into) } -func getNamespace(apiContext *types.APIContext, opt types.QueryOptions) string { +func getNamespace(apiContext *types.APIContext, opt *types.QueryOptions) string { if val, ok := apiContext.SubContext["namespaces"]; ok { return convert.ToString(val) } diff --git a/store/schema/schema_store.go b/store/schema/schema_store.go index 58cbc99c..6b27616c 100644 --- a/store/schema/schema_store.go +++ b/store/schema/schema_store.go @@ -34,11 +34,11 @@ func (s *Store) ByID(apiContext *types.APIContext, schema *types.Schema, id stri return nil, nil } -func (s *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) (chan map[string]interface{}, error) { +func (s *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { return nil, nil } -func (s *Store) List(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) ([]map[string]interface{}, error) { +func (s *Store) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { schemaMap := apiContext.Schemas.SchemasForVersion(*apiContext.Version) schemas := make([]*types.Schema, 0, len(schemaMap)) schemaData := make([]map[string]interface{}, 0, len(schemaMap)) diff --git a/store/subtype/subtype_store.go b/store/subtype/subtype_store.go index e2d331d9..367694b3 100644 --- a/store/subtype/subtype_store.go +++ b/store/subtype/subtype_store.go @@ -16,12 +16,19 @@ func NewSubTypeStore(subType string, store types.Store) *Store { } } -func (p *Store) List(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) ([]map[string]interface{}, error) { +func (p *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) { + if data != nil { + data["kind"] = p.subType + } + return p.Store.Create(apiContext, schema, data) +} + +func (p *Store) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { opt.Conditions = append(opt.Conditions, types.NewConditionFromString("type", types.ModifierEQ, p.subType)) return p.Store.List(apiContext, schema, opt) } -func (p *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) (chan map[string]interface{}, error) { +func (p *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { opt.Conditions = append(opt.Conditions, types.NewConditionFromString("type", types.ModifierEQ, p.subType)) return p.Store.Watch(apiContext, schema, opt) } diff --git a/store/transform/transform.go b/store/transform/transform.go index 743ca4b7..48982d8e 100644 --- a/store/transform/transform.go +++ b/store/transform/transform.go @@ -26,7 +26,7 @@ func (t *Store) ByID(apiContext *types.APIContext, schema *types.Schema, id stri return t.Transformer(apiContext, data) } -func (t *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) (chan map[string]interface{}, error) { +func (t *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { c, err := t.Store.Watch(apiContext, schema, opt) if err != nil { return nil, err @@ -50,7 +50,7 @@ func (t *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt ty return result, nil } -func (t *Store) List(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) ([]map[string]interface{}, error) { +func (t *Store) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) { data, err := t.Store.List(apiContext, schema, opt) if err != nil { return nil, err diff --git a/store/wrapper/wrapper.go b/store/wrapper/wrapper.go index 879278da..e345cffc 100644 --- a/store/wrapper/wrapper.go +++ b/store/wrapper/wrapper.go @@ -21,12 +21,12 @@ func (s *StoreWrapper) ByID(apiContext *types.APIContext, schema *types.Schema, return nil, err } - return apiContext.FilterObject(types.QueryOptions{ + return apiContext.FilterObject(&types.QueryOptions{ Conditions: apiContext.SubContextAttributeProvider.Query(apiContext, schema), }, data), nil } -func (s *StoreWrapper) List(apiContext *types.APIContext, schema *types.Schema, opts types.QueryOptions) ([]map[string]interface{}, error) { +func (s *StoreWrapper) List(apiContext *types.APIContext, schema *types.Schema, opts *types.QueryOptions) ([]map[string]interface{}, error) { opts.Conditions = append(opts.Conditions, apiContext.SubContextAttributeProvider.Query(apiContext, schema)...) data, err := s.store.List(apiContext, schema, opts) if err != nil { @@ -36,7 +36,7 @@ func (s *StoreWrapper) List(apiContext *types.APIContext, schema *types.Schema, return apiContext.FilterList(opts, data), nil } -func (s *StoreWrapper) Watch(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) (chan map[string]interface{}, error) { +func (s *StoreWrapper) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) { c, err := s.store.Watch(apiContext, schema, opt) if err != nil || c == nil { return nil, err @@ -45,7 +45,7 @@ func (s *StoreWrapper) Watch(apiContext *types.APIContext, schema *types.Schema, result := make(chan map[string]interface{}) go func() { for item := range c { - item = apiContext.FilterObject(types.QueryOptions{ + item = apiContext.FilterObject(&types.QueryOptions{ Conditions: apiContext.SubContextAttributeProvider.Query(apiContext, schema), }, item) if item != nil { @@ -85,7 +85,7 @@ func (s *StoreWrapper) Update(apiContext *types.APIContext, schema *types.Schema return nil, err } - return apiContext.FilterObject(types.QueryOptions{ + return apiContext.FilterObject(&types.QueryOptions{ Conditions: apiContext.SubContextAttributeProvider.Query(apiContext, schema), }, data), nil } @@ -109,7 +109,7 @@ func validateGet(apiContext *types.APIContext, schema *types.Schema, id string) return err } - if apiContext.Filter(types.QueryOptions{ + if apiContext.Filter(&types.QueryOptions{ Conditions: apiContext.SubContextAttributeProvider.Query(apiContext, schema), }, existing) == nil { return httperror.NewAPIError(httperror.NotFound, "failed to find "+id) diff --git a/types/server_types.go b/types/server_types.go index a5071749..663a702a 100644 --- a/types/server_types.go +++ b/types/server_types.go @@ -44,7 +44,7 @@ type ActionHandler func(actionName string, action *Action, request *APIContext) type RequestHandler func(request *APIContext) error -type QueryFilter func(opts QueryOptions, data []map[string]interface{}) []map[string]interface{} +type QueryFilter func(opts *QueryOptions, data []map[string]interface{}) []map[string]interface{} type Validator func(request *APIContext, data map[string]interface{}) error @@ -100,11 +100,11 @@ func (r *APIContext) WriteResponse(code int, obj interface{}) { r.ResponseWriter.Write(r, code, obj) } -func (r *APIContext) FilterList(opts QueryOptions, obj []map[string]interface{}) []map[string]interface{} { +func (r *APIContext) FilterList(opts *QueryOptions, obj []map[string]interface{}) []map[string]interface{} { return r.QueryFilter(opts, obj) } -func (r *APIContext) FilterObject(opts QueryOptions, obj map[string]interface{}) map[string]interface{} { +func (r *APIContext) FilterObject(opts *QueryOptions, obj map[string]interface{}) map[string]interface{} { opts.Pagination = nil result := r.QueryFilter(opts, []map[string]interface{}{obj}) if len(result) == 0 { @@ -113,7 +113,7 @@ func (r *APIContext) FilterObject(opts QueryOptions, obj map[string]interface{}) return result[0] } -func (r *APIContext) Filter(opts QueryOptions, obj interface{}) interface{} { +func (r *APIContext) Filter(opts *QueryOptions, obj interface{}) interface{} { switch v := obj.(type) { case []map[string]interface{}: return r.FilterList(opts, v) @@ -161,9 +161,9 @@ type URLBuilder interface { type Store interface { ByID(apiContext *APIContext, schema *Schema, id string) (map[string]interface{}, error) - List(apiContext *APIContext, schema *Schema, opt QueryOptions) ([]map[string]interface{}, error) + List(apiContext *APIContext, schema *Schema, opt *QueryOptions) ([]map[string]interface{}, error) Create(apiContext *APIContext, schema *Schema, data map[string]interface{}) (map[string]interface{}, error) Update(apiContext *APIContext, schema *Schema, data map[string]interface{}, id string) (map[string]interface{}, error) Delete(apiContext *APIContext, schema *Schema, id string) (map[string]interface{}, error) - Watch(apiContext *APIContext, schema *Schema, opt QueryOptions) (chan map[string]interface{}, error) + Watch(apiContext *APIContext, schema *Schema, opt *QueryOptions) (chan map[string]interface{}, error) }