1
0
mirror of https://github.com/rancher/norman.git synced 2025-09-25 06:26:50 +00:00
Files
norman/store/wrapper/wrapper.go
Nathan Jenan 7fed8b17a8 Filter resources on default fields
This change gives norman the ability to filter api requests based on the
default value of fields.  Before, it would filter on the actual data in
the resource, and then apply default values to the resource before
returning.

Issue:
https://github.com/rancher/rancher/issues/13418
2018-05-16 10:15:34 -07:00

116 lines
3.2 KiB
Go

package wrapper
import (
"github.com/rancher/norman/httperror"
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/convert"
)
func Wrap(store types.Store) types.Store {
return &StoreWrapper{
store: store,
}
}
type StoreWrapper struct {
store types.Store
}
func (s *StoreWrapper) Context() types.StorageContext {
return s.store.Context()
}
func (s *StoreWrapper) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) {
data, err := s.store.ByID(apiContext, schema, id)
if err != nil {
return nil, err
}
return apiContext.FilterObject(&types.QueryOptions{
Conditions: apiContext.SubContextAttributeProvider.Query(apiContext, schema),
}, schema, data), nil
}
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 {
return nil, err
}
return apiContext.FilterList(opts, schema, data), nil
}
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
}
return convert.Chan(c, func(data map[string]interface{}) map[string]interface{} {
return apiContext.FilterObject(&types.QueryOptions{
Conditions: apiContext.SubContextAttributeProvider.Query(apiContext, schema),
}, schema, data)
}), nil
}
func (s *StoreWrapper) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) {
for key, value := range apiContext.SubContextAttributeProvider.Create(apiContext, schema) {
if data == nil {
data = map[string]interface{}{}
}
data[key] = value
}
data, err := s.store.Create(apiContext, schema, data)
if err != nil {
return nil, err
}
return data, nil
}
func (s *StoreWrapper) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) {
err := validateGet(apiContext, schema, id)
if err != nil {
return nil, err
}
data, err = s.store.Update(apiContext, schema, data, id)
if err != nil {
return nil, err
}
return apiContext.FilterObject(&types.QueryOptions{
Conditions: apiContext.SubContextAttributeProvider.Query(apiContext, schema),
}, schema, data), nil
}
func (s *StoreWrapper) Delete(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) {
if err := validateGet(apiContext, schema, id); err != nil {
return nil, err
}
return s.store.Delete(apiContext, schema, id)
}
func validateGet(apiContext *types.APIContext, schema *types.Schema, id string) error {
store := schema.Store
if store == nil {
return nil
}
existing, err := store.ByID(apiContext, schema, id)
if err != nil {
return err
}
if apiContext.Filter(&types.QueryOptions{
Conditions: apiContext.SubContextAttributeProvider.Query(apiContext, schema),
}, schema, existing) == nil {
return httperror.NewAPIError(httperror.NotFound, "failed to find "+id)
}
return nil
}