diff --git a/pkg/attributes/attributes.go b/pkg/attributes/attributes.go index 2c4ae19..428dedc 100644 --- a/pkg/attributes/attributes.go +++ b/pkg/attributes/attributes.go @@ -122,3 +122,14 @@ func SetAPIResource(s *types.Schema, resource v1.APIResource) { SetVerbs(s, resource.Verbs) SetNamespaced(s, resource.Namespaced) } + +func SetColumns(s *types.Schema, columns interface{}) { + if s.Attributes == nil { + s.Attributes = map[string]interface{}{} + } + s.Attributes["columns"] = columns +} + +func Columns(s *types.Schema) interface{} { + return s.Attributes["columns"] +} diff --git a/pkg/controllers/schema/schemas.go b/pkg/controllers/schema/schemas.go index bbfa371..b028b79 100644 --- a/pkg/controllers/schema/schemas.go +++ b/pkg/controllers/schema/schemas.go @@ -22,6 +22,7 @@ type handler struct { toSync int32 schemas *schema2.Collection client discovery.DiscoveryInterface + crd apiextcontrollerv1beta1.CustomResourceDefinitionClient } func Register(ctx context.Context, @@ -33,6 +34,7 @@ func Register(ctx context.Context, h := &handler{ client: discovery, schemas: schemas, + crd: crd, } apiService.OnChange(ctx, "schema", h.OnChangeAPIService) @@ -70,7 +72,7 @@ func (h *handler) refreshAll() error { } logrus.Info("Refreshing all schemas") - schemas, err := converter.ToSchemas(h.client) + schemas, err := converter.ToSchemas(h.crd, h.client) if err != nil { return err } diff --git a/pkg/resources/common/defaultcolumns.go b/pkg/resources/common/defaultcolumns.go new file mode 100644 index 0000000..17fb825 --- /dev/null +++ b/pkg/resources/common/defaultcolumns.go @@ -0,0 +1,30 @@ +package common + +import ( + "github.com/rancher/naok/pkg/attributes" + "github.com/rancher/naok/pkg/table" + "github.com/rancher/norman/pkg/types" +) + +type DefaultColumns struct { + types.EmptyMapper +} + +func (d *DefaultColumns) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + if attributes.Columns(schema) == nil { + attributes.SetColumns(schema, []table.Column{ + { + Name: "Name", + Field: "metadata.name", + Type: "string", + }, + { + Name: "Created", + Field: "metadata.creationTimestamp", + Type: "date", + }, + }) + } + + return nil +} diff --git a/pkg/resources/common/formatter.go b/pkg/resources/common/formatter.go index 97bba1f..680b55e 100644 --- a/pkg/resources/common/formatter.go +++ b/pkg/resources/common/formatter.go @@ -12,6 +12,7 @@ func Register(collection *schema.Collection, clientGetter proxy.ClientGetter) { collection.AddTemplate(&schema.Template{ Store: proxy.NewProxyStore(clientGetter), Formatter: Formatter, + Mapper: &DefaultColumns{}, }) } diff --git a/pkg/counts/types.go b/pkg/resources/counts/types.go similarity index 100% rename from pkg/counts/types.go rename to pkg/resources/counts/types.go diff --git a/pkg/resources/schema.go b/pkg/resources/schema.go index 1c9e66b..3a9adfe 100644 --- a/pkg/resources/schema.go +++ b/pkg/resources/schema.go @@ -2,8 +2,8 @@ package resources import ( "github.com/rancher/naok/pkg/accesscontrol" - "github.com/rancher/naok/pkg/counts" "github.com/rancher/naok/pkg/resources/common" + "github.com/rancher/naok/pkg/resources/counts" "github.com/rancher/naok/pkg/resources/schema" "github.com/rancher/norman/pkg/store/proxy" "github.com/rancher/norman/pkg/subscribe" diff --git a/pkg/resources/schema/collection.go b/pkg/resources/schema/collection.go index 0d23009..91aabd2 100644 --- a/pkg/resources/schema/collection.go +++ b/pkg/resources/schema/collection.go @@ -26,12 +26,14 @@ type Collection struct { } type Template struct { - Group string - Kind string - ID string - Formatter types.Formatter - Store types.Store - Mapper types.Mapper + Group string + Kind string + ID string + RegisterType interface{} + Customize func(*types.Schema) + Formatter types.Formatter + Store types.Store + Mapper types.Mapper } func NewCollection(baseSchema *types.Schemas, access *accesscontrol.AccessStore) *Collection { diff --git a/pkg/resources/schema/converter/crd.go b/pkg/resources/schema/converter/crd.go new file mode 100644 index 0000000..b27a982 --- /dev/null +++ b/pkg/resources/schema/converter/crd.go @@ -0,0 +1,70 @@ +package converter + +import ( + "github.com/rancher/naok/pkg/attributes" + "github.com/rancher/naok/pkg/table" + "github.com/rancher/norman/pkg/types" + "github.com/rancher/wrangler-api/pkg/generated/controllers/apiextensions.k8s.io/v1beta1" + beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func AddCustomResources(crd v1beta1.CustomResourceDefinitionClient, schemas map[string]*types.Schema) error { + crds, err := crd.List(metav1.ListOptions{}) + if err != nil { + return nil + } + + for _, crd := range crds.Items { + if crd.Status.AcceptedNames.Plural == "" { + continue + } + + var columns []table.Column + for _, col := range crd.Spec.AdditionalPrinterColumns { + columns = append(columns, table.Column{ + Name: col.Name, + Field: col.JSONPath, + Type: col.Type, + }) + } + + group, resource := crd.Spec.Group, crd.Status.AcceptedNames.Plural + + if crd.Spec.Version != "" { + forVersion(group, crd.Spec.Version, resource, schemas, crd.Spec.AdditionalPrinterColumns, columns) + } + for _, version := range crd.Spec.Versions { + forVersion(group, version.Name, resource, schemas, crd.Spec.AdditionalPrinterColumns, columns) + } + } + + return nil +} + +func forVersion(group, version, resource string, schemas map[string]*types.Schema, columnDefs []beta1.CustomResourceColumnDefinition, columns []table.Column) { + var versionColumns []table.Column + for _, col := range columnDefs { + versionColumns = append(versionColumns, table.Column{ + Name: col.Name, + Field: col.JSONPath, + Type: col.Type, + }) + } + if len(versionColumns) == 0 { + versionColumns = columns + } + + id := GVRToSchemaID(schema.GroupVersionResource{ + Group: group, + Version: version, + Resource: resource, + }) + + schema := schemas[id] + if schema == nil { + return + } + attributes.SetColumns(schema, columns) +} diff --git a/pkg/resources/schema/converter/k8stonorman.go b/pkg/resources/schema/converter/k8stonorman.go index 98094c6..49489ae 100644 --- a/pkg/resources/schema/converter/k8stonorman.go +++ b/pkg/resources/schema/converter/k8stonorman.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/rancher/norman/pkg/types" + "github.com/rancher/wrangler-api/pkg/generated/controllers/apiextensions.k8s.io/v1beta1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/discovery" ) @@ -15,14 +16,14 @@ func gvkToSchemaID(gvk schema.GroupVersionKind) string { return fmt.Sprintf("%s.%s.%s", gvk.Group, gvk.Version, gvk.Kind) } -func GVRToSchemaID(gvk schema.GroupVersionResource) string { - if gvk.Group == "" { - return fmt.Sprintf("core.%s.%s", gvk.Version, gvk.Resource) +func GVRToSchemaID(gvr schema.GroupVersionResource) string { + if gvr.Group == "" { + return fmt.Sprintf("core.%s.%s", gvr.Version, gvr.Resource) } - return fmt.Sprintf("%s.%s.%s", gvk.Group, gvk.Version, gvk.Resource) + return fmt.Sprintf("%s.%s.%s", gvr.Group, gvr.Version, gvr.Resource) } -func ToSchemas(client discovery.DiscoveryInterface) (map[string]*types.Schema, error) { +func ToSchemas(crd v1beta1.CustomResourceDefinitionClient, client discovery.DiscoveryInterface) (map[string]*types.Schema, error) { result := map[string]*types.Schema{} if err := AddOpenAPI(client, result); err != nil { @@ -33,5 +34,9 @@ func ToSchemas(client discovery.DiscoveryInterface) (map[string]*types.Schema, e return nil, err } + if err := AddCustomResources(crd, result); err != nil { + return nil, err + } + return result, nil } diff --git a/pkg/resources/schema/defaultmapper.go b/pkg/resources/schema/defaultmapper.go index 16b399b..3727269 100644 --- a/pkg/resources/schema/defaultmapper.go +++ b/pkg/resources/schema/defaultmapper.go @@ -3,9 +3,8 @@ package schema import ( "fmt" + "github.com/rancher/norman/pkg/data" "github.com/rancher/norman/pkg/types" - "github.com/rancher/norman/pkg/types/convert" - "github.com/rancher/norman/pkg/types/values" ) func newDefaultMapper() types.Mapper { @@ -16,7 +15,7 @@ type defaultMapper struct { types.EmptyMapper } -func (d *defaultMapper) FromInternal(data map[string]interface{}) { +func (d *defaultMapper) FromInternal(data data.Object) { if data["kind"] != "" && data["apiVersion"] != "" { if t, ok := data["type"]; ok && data != nil { data["_type"] = t @@ -27,8 +26,8 @@ func (d *defaultMapper) FromInternal(data map[string]interface{}) { return } - name := convert.ToString(values.GetValueN(data, "metadata", "name")) - namespace := convert.ToString(values.GetValueN(data, "metadata", "namespace")) + name := types.Name(data) + namespace := types.Namespace(data) if namespace == "" { data["id"] = name diff --git a/pkg/resources/schema/factory.go b/pkg/resources/schema/factory.go index 18f35f2..ad57194 100644 --- a/pkg/resources/schema/factory.go +++ b/pkg/resources/schema/factory.go @@ -38,6 +38,16 @@ func (c *Collection) schemasForSubject(subjectKey string, access *accesscontrol. return nil, err } + for _, template := range c.templates { + if template.RegisterType != nil { + s, err := result.Import(template.RegisterType) + if err != nil { + return nil, err + } + c.applyTemplates(result, s) + } + } + for _, s := range c.schemas { gr := attributes.GR(s) @@ -78,7 +88,7 @@ func (c *Collection) schemasForSubject(subjectKey string, access *accesscontrol. s.CollectionMethods = append(s.CollectionMethods, http.MethodPost) } - c.applyTemplates(s) + c.applyTemplates(result, s) if err := result.AddSchema(*s); err != nil { return nil, err @@ -88,7 +98,7 @@ func (c *Collection) schemasForSubject(subjectKey string, access *accesscontrol. return result, nil } -func (c *Collection) applyTemplates(schema *types.Schema) { +func (c *Collection) applyTemplates(schemas *types.Schemas, schema *types.Schema) { templates := []*Template{ c.templates[schema.ID], c.templates[fmt.Sprintf("%s/%s", attributes.Group(schema), attributes.Kind(schema))], @@ -99,8 +109,8 @@ func (c *Collection) applyTemplates(schema *types.Schema) { if t == nil { continue } - if schema.Mapper == nil { - schema.Mapper = t.Mapper + if t.Mapper != nil { + schemas.AddMapper(schema.ID, t.Mapper) } if schema.Formatter == nil { schema.Formatter = t.Formatter @@ -108,5 +118,8 @@ func (c *Collection) applyTemplates(schema *types.Schema) { if schema.Store == nil { schema.Store = t.Store } + if t.Customize != nil { + t.Customize(schema) + } } } diff --git a/pkg/server/api.go b/pkg/server/publicapi/apiserver.go similarity index 65% rename from pkg/server/api.go rename to pkg/server/publicapi/apiserver.go index a3cfac4..b20e693 100644 --- a/pkg/server/api.go +++ b/pkg/server/publicapi/apiserver.go @@ -1,14 +1,14 @@ -package server +package publicapi import ( "net/http" "strings" - "github.com/gorilla/mux" "github.com/rancher/naok/pkg/accesscontrol" "github.com/rancher/naok/pkg/attributes" k8sproxy "github.com/rancher/naok/pkg/proxy" "github.com/rancher/naok/pkg/resources/schema" + "github.com/rancher/naok/pkg/server/router" "github.com/rancher/norman/pkg/api" "github.com/rancher/norman/pkg/types" "github.com/rancher/norman/pkg/urlbuilder" @@ -16,29 +16,30 @@ import ( "k8s.io/client-go/rest" ) -func newAPIServer(cfg *rest.Config, sf schema.Factory) (http.Handler, error) { +func NewHandler(cfg *rest.Config, sf schema.Factory) (http.Handler, error) { var ( err error ) a := &apiServer{ - Router: mux.NewRouter(), sf: sf, - server: api.NewAPIServer(), + server: api.DefaultAPIServer(), } + a.server.AccessControl = accesscontrol.NewAccessControl() - a.Router.NotFoundHandler, err = k8sproxy.Handler("/", cfg) + proxy, err := k8sproxy.Handler("/", cfg) if err != nil { return nil, err } - a.Router.StrictSlash(true) - a.server.AccessControl = accesscontrol.NewAccessControl() - return a, a.routes() + return router.Routes(router.Handlers{ + K8sResource: a.apiHandler(k8sAPI), + GenericResource: a.apiHandler(nil), + K8sProxy: proxy, + }), nil } type apiServer struct { - *mux.Router sf schema.Factory server *api.Server } @@ -77,3 +78,21 @@ func (a *apiServer) Schema(base string, schema *types.Schema) string { } return urlbuilder.ConstructBasicURL(base, "v1", strings.ToLower(schema.ID)) } + +type APIFunc func(schema.Factory, *types.APIRequest) + +func (a *apiServer) apiHandler(apiFunc APIFunc) http.Handler { + return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { + a.api(rw, req, apiFunc) + }) +} + +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) + } +} diff --git a/pkg/server/publicapi/handlers.go b/pkg/server/publicapi/handlers.go new file mode 100644 index 0000000..510f185 --- /dev/null +++ b/pkg/server/publicapi/handlers.go @@ -0,0 +1,38 @@ +package publicapi + +import ( + "github.com/gorilla/mux" + "github.com/rancher/naok/pkg/attributes" + "github.com/rancher/naok/pkg/resources/schema" + "github.com/rancher/norman/pkg/types" + runtimeschema "k8s.io/apimachinery/pkg/runtime/schema" +) + +func k8sAPI(sf schema.Factory, apiOp *types.APIRequest) { + vars := mux.Vars(apiOp.Request) + group := vars["group"] + if group == "core" { + group = "" + } + + apiOp.Name = vars["name"] + apiOp.Type = sf.ByGVR(runtimeschema.GroupVersionResource{ + Version: vars["version"], + Group: group, + Resource: vars["resource"], + }) + + nOrN := vars["nameorns"] + if nOrN != "" { + schema := apiOp.Schemas.Schema(apiOp.Type) + if attributes.Namespaced(schema) { + vars["namespace"] = nOrN + } else { + vars["name"] = nOrN + } + } + + if namespace := vars["namespace"]; namespace != "" { + apiOp.Namespaces = []string{namespace} + } +} diff --git a/pkg/server/router/router.go b/pkg/server/router/router.go new file mode 100644 index 0000000..32257b6 --- /dev/null +++ b/pkg/server/router/router.go @@ -0,0 +1,29 @@ +package router + +import ( + "net/http" + + "github.com/gorilla/mux" +) + +type Handlers struct { + K8sResource http.Handler + GenericResource http.Handler + K8sProxy http.Handler +} + +func Routes(h Handlers) http.Handler { + m := mux.NewRouter() + m.UseEncodedPath() + m.StrictSlash(true) + m.NotFoundHandler = h.K8sProxy + + m.Path("/v1/{type:schemas}/{name:.*}").Handler(h.GenericResource) + m.Path("/v1/{group}.{version}.{resource}").Handler(h.K8sResource) + m.Path("/v1/{group}.{version}.{resource}/{nameorns}").Handler(h.K8sResource) + m.Path("/v1/{group}.{version}.{resource}/{namespace}/{name}").Handler(h.K8sResource) + m.Path("/v1/{type}").Handler(h.GenericResource) + m.Path("/v1/{type}/{name}").Handler(h.GenericResource) + + return m +} diff --git a/pkg/server/routes.go b/pkg/server/routes.go deleted file mode 100644 index 5f28913..0000000 --- a/pkg/server/routes.go +++ /dev/null @@ -1,68 +0,0 @@ -package server - -import ( - "net/http" - - "github.com/gorilla/mux" - "github.com/rancher/naok/pkg/attributes" - "github.com/rancher/norman/pkg/types" - "k8s.io/apimachinery/pkg/runtime/schema" -) - -type APIFunc func(*types.APIRequest) - -func (a *apiServer) routes() error { - a.Path("/v1/{type:schemas}/{name:.*}").Handler(a.handle(nil)) - a.Path("/v1/{group}.{version}.{resource}").Handler(a.handle(a.k8sAPI)) - a.Path("/v1/{group}.{version}.{resource}/{nameorns}").Handler(a.handle(a.k8sAPI)) - a.Path("/v1/{group}.{version}.{resource}/{namespace}/{name}").Handler(a.handle(a.k8sAPI)) - a.Path("/v1/{type}").Handler(a.handle(nil)) - a.Path("/v1/{type}/{name}").Handler(a.handle(nil)) - - return nil -} - -func (a *apiServer) handle(apiFunc APIFunc) http.Handler { - return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { - a.api(rw, req, apiFunc) - }) -} - -func (a *apiServer) api(rw http.ResponseWriter, req *http.Request, apiFunc APIFunc) { - apiOp, ok := a.common(rw, req) - if ok { - if apiFunc != nil { - apiFunc(apiOp) - } - a.server.Handle(apiOp) - } -} - -func (a *apiServer) k8sAPI(apiOp *types.APIRequest) { - vars := mux.Vars(apiOp.Request) - group := vars["group"] - if group == "core" { - group = "" - } - - apiOp.Name = vars["name"] - apiOp.Type = a.sf.ByGVR(schema.GroupVersionResource{ - Version: vars["version"], - Group: group, - Resource: vars["resource"], - }) - - nOrN := vars["nameorns"] - if nOrN != "" { - schema := apiOp.Schemas.Schema(apiOp.Type) - if attributes.Namespaced(schema) { - vars["namespace"] = nOrN - } else { - vars["name"] = nOrN - } - } - - if namespace := vars["namespace"]; namespace != "" { - apiOp.Namespaces = []string{namespace} - } -} diff --git a/pkg/server/server.go b/pkg/server/server.go index e77d995..ea1f135 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -4,12 +4,11 @@ import ( "context" "net/http" - "github.com/rancher/naok/pkg/resources" - - "github.com/rancher/naok/pkg/controllers/schema" - "github.com/rancher/naok/pkg/accesscontrol" "github.com/rancher/naok/pkg/client" + "github.com/rancher/naok/pkg/controllers/schema" + "github.com/rancher/naok/pkg/resources" + "github.com/rancher/naok/pkg/server/publicapi" "github.com/rancher/wrangler-api/pkg/generated/controllers/apiextensions.k8s.io" "github.com/rancher/wrangler-api/pkg/generated/controllers/apiregistration.k8s.io" rbaccontroller "github.com/rancher/wrangler-api/pkg/generated/controllers/rbac" @@ -17,7 +16,6 @@ import ( "github.com/rancher/wrangler/pkg/start" "github.com/sirupsen/logrus" "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" ) type Config struct { @@ -52,7 +50,21 @@ func Run(ctx context.Context, cfg Config) error { return err } - starter, err := startAPI(ctx, cfg.ListenAddress, restConfig, k8s, crd, api, rbac) + cf, err := client.NewFactory(restConfig) + if err != nil { + return err + } + + sf := resources.SchemaFactory(cf, + accesscontrol.NewAccessStore(rbac.Rbac().V1())) + + schema.Register(ctx, + k8s.Discovery(), + crd.Apiextensions().V1beta1().CustomResourceDefinition(), + api.Apiregistration().V1().APIService(), + sf) + + handler, err := publicapi.NewHandler(restConfig, sf) if err != nil { return err } @@ -61,37 +73,6 @@ func Run(ctx context.Context, cfg Config) error { return err } - if err := starter(); err != nil { - return err - } - - <-ctx.Done() - return nil -} - -func startAPI(ctx context.Context, listenAddress string, restConfig *rest.Config, k8s *kubernetes.Clientset, crd *apiextensions.Factory, - api *apiregistration.Factory, rbac *rbaccontroller.Factory) (func() error, error) { - - cf, err := client.NewFactory(restConfig) - if err != nil { - return nil, err - } - - as := accesscontrol.NewAccessStore(rbac.Rbac().V1()) - sf := resources.SchemaFactory(cf, as) - - schema.Register(ctx, - k8s.Discovery(), - crd.Apiextensions().V1beta1().CustomResourceDefinition(), - api.Apiregistration().V1().APIService(), - sf) - - return func() error { - handler, err := newAPIServer(restConfig, sf) - if err != nil { - return err - } - logrus.Infof("listening on %s", listenAddress) - return http.ListenAndServe(listenAddress, handler) - }, nil + logrus.Infof("listening on %s", cfg.ListenAddress) + return http.ListenAndServe(cfg.ListenAddress, handler) } diff --git a/pkg/table/mapper.go b/pkg/table/mapper.go new file mode 100644 index 0000000..69a3123 --- /dev/null +++ b/pkg/table/mapper.go @@ -0,0 +1,35 @@ +package table + +import ( + "github.com/rancher/naok/pkg/attributes" + "github.com/rancher/norman/pkg/data" + "github.com/rancher/norman/pkg/types" +) + +type Column struct { + Name string `json:"name,omitempty"` + Field string `json:"field,omitempty"` + Type string `json:"type,omitempty"` +} + +type Table struct { + Columns []Column + Computed func(data.Object) +} + +type ColumnMapper struct { + definition Table + types.EmptyMapper +} + +func (t *ColumnMapper) FromInternal(d data.Object) { + d.Map("metadata").Set("columns", t.definition.Columns) + if t.definition.Computed != nil { + t.definition.Computed(d) + } +} + +func (t *ColumnMapper) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { + attributes.SetColumns(schema, t.definition.Columns) + return nil +} diff --git a/vendor/github.com/rancher/norman/pkg/api/server.go b/vendor/github.com/rancher/norman/pkg/api/server.go index 0c814fd..ce553b8 100644 --- a/vendor/github.com/rancher/norman/pkg/api/server.go +++ b/vendor/github.com/rancher/norman/pkg/api/server.go @@ -51,7 +51,7 @@ type Defaults struct { ErrorHandler types.ErrorHandler } -func NewAPIServer() *Server { +func DefaultAPIServer() *Server { s := &Server{ DefaultNamespace: "default", Schemas: types.EmptySchemas(), diff --git a/vendor/github.com/rancher/norman/pkg/data/data.go b/vendor/github.com/rancher/norman/pkg/data/data.go index aeb701e..8a1bcdc 100644 --- a/vendor/github.com/rancher/norman/pkg/data/data.go +++ b/vendor/github.com/rancher/norman/pkg/data/data.go @@ -19,7 +19,29 @@ func (o Object) Map(names ...string) Object { return Object(m) } +func (o Object) Slice(names ...string) (result []Object) { + v := values.GetValueN(o, names...) + for _, item := range convert.ToInterfaceSlice(v) { + result = append(result, Object(convert.ToMapInterface(item))) + } + return +} + +func (o Object) Values() (result []Object) { + for k := range o { + result = append(result, o.Map(k)) + } + return +} + func (o Object) String(names ...string) string { v := values.GetValueN(o, names...) return convert.ToString(v) } + +func (o Object) Set(key string, obj interface{}) { + if o == nil { + return + } + o[key] = obj +} diff --git a/vendor/github.com/rancher/norman/pkg/store/proxy/mapper.go b/vendor/github.com/rancher/norman/pkg/store/proxy/mapper.go index 10aafc0..ad19345 100644 --- a/vendor/github.com/rancher/norman/pkg/store/proxy/mapper.go +++ b/vendor/github.com/rancher/norman/pkg/store/proxy/mapper.go @@ -1,6 +1,9 @@ package proxy -import "github.com/rancher/norman/pkg/types" +import ( + "github.com/rancher/norman/pkg/data" + "github.com/rancher/norman/pkg/types" +) type AddAPIVersionKind struct { APIVersion string @@ -8,24 +11,21 @@ type AddAPIVersionKind struct { Next types.Mapper } -func (d AddAPIVersionKind) FromInternal(data map[string]interface{}) { +func (d AddAPIVersionKind) FromInternal(data data.Object) { if d.Next != nil { d.Next.FromInternal(data) } } -func (d AddAPIVersionKind) ToInternal(data map[string]interface{}) error { +func (d AddAPIVersionKind) ToInternal(data data.Object) error { if d.Next != nil { if err := d.Next.ToInternal(data); err != nil { return err } } - if data == nil { - return nil - } - data["apiVersion"] = d.APIVersion - data["kind"] = d.Kind + data.Set("apiVersion", d.APIVersion) + data.Set("kind", d.Kind) return nil } diff --git a/vendor/github.com/rancher/norman/pkg/types/mapper.go b/vendor/github.com/rancher/norman/pkg/types/mapper.go index cf18af3..eae519d 100644 --- a/vendor/github.com/rancher/norman/pkg/types/mapper.go +++ b/vendor/github.com/rancher/norman/pkg/types/mapper.go @@ -1,23 +1,23 @@ package types import ( - "github.com/rancher/norman/pkg/types/convert" + "github.com/rancher/norman/pkg/data" "github.com/rancher/norman/pkg/types/definition" ) type Mapper interface { - FromInternal(data map[string]interface{}) - ToInternal(data map[string]interface{}) error + FromInternal(data data.Object) + ToInternal(data data.Object) error ModifySchema(schema *Schema, schemas *Schemas) error } type EmptyMapper struct { } -func (e *EmptyMapper) FromInternal(data map[string]interface{}) { +func (e *EmptyMapper) FromInternal(data data.Object) { } -func (e *EmptyMapper) ToInternal(data map[string]interface{}) error { +func (e *EmptyMapper) ToInternal(data data.Object) error { return nil } @@ -27,13 +27,13 @@ func (e *EmptyMapper) ModifySchema(schema *Schema, schemas *Schemas) error { type Mappers []Mapper -func (m Mappers) FromInternal(data map[string]interface{}) { +func (m Mappers) FromInternal(data data.Object) { for _, mapper := range m { mapper.FromInternal(data) } } -func (m Mappers) ToInternal(data map[string]interface{}) error { +func (m Mappers) ToInternal(data data.Object) error { var errors []error for i := len(m) - 1; i >= 0; i-- { errors = append(errors, m[i].ToInternal(data)) @@ -59,23 +59,20 @@ type typeMapper struct { subMapSchemas map[string]*Schema } -func (t *typeMapper) FromInternal(data map[string]interface{}) { +func (t *typeMapper) FromInternal(data data.Object) { for fieldName, schema := range t.subSchemas { if schema.Mapper == nil { continue } - fieldData, _ := data[fieldName].(map[string]interface{}) - schema.Mapper.FromInternal(fieldData) + schema.Mapper.FromInternal(data.Map(fieldName)) } for fieldName, schema := range t.subMapSchemas { if schema.Mapper == nil { continue } - datas, _ := data[fieldName].(map[string]interface{}) - for _, fieldData := range datas { - mapFieldData, _ := fieldData.(map[string]interface{}) - schema.Mapper.FromInternal(mapFieldData) + for _, fieldData := range data.Map(fieldName).Values() { + schema.Mapper.FromInternal(fieldData) } } @@ -83,17 +80,15 @@ func (t *typeMapper) FromInternal(data map[string]interface{}) { if schema.Mapper == nil { continue } - datas, _ := data[fieldName].([]interface{}) - for _, fieldData := range datas { - mapFieldData, _ := fieldData.(map[string]interface{}) - schema.Mapper.FromInternal(mapFieldData) + for _, fieldData := range data.Slice(fieldName) { + schema.Mapper.FromInternal(fieldData) } } Mappers(t.Mappers).FromInternal(data) } -func (t *typeMapper) ToInternal(data map[string]interface{}) error { +func (t *typeMapper) ToInternal(data data.Object) error { errors := Errors{} errors.Add(Mappers(t.Mappers).ToInternal(data)) @@ -101,9 +96,8 @@ func (t *typeMapper) ToInternal(data map[string]interface{}) error { if schema.Mapper == nil { continue } - datas, _ := data[fieldName].([]interface{}) - for _, fieldData := range datas { - errors.Add(schema.Mapper.ToInternal(convert.ToMapInterface(fieldData))) + for _, fieldData := range data.Slice(fieldName) { + errors.Add(schema.Mapper.ToInternal(fieldData)) } } @@ -111,9 +105,8 @@ func (t *typeMapper) ToInternal(data map[string]interface{}) error { if schema.Mapper == nil { continue } - datas, _ := data[fieldName].(map[string]interface{}) - for _, fieldData := range datas { - errors.Add(schema.Mapper.ToInternal(convert.ToMapInterface(fieldData))) + for _, fieldData := range data.Slice(fieldName) { + errors.Add(schema.Mapper.ToInternal(fieldData)) } } @@ -121,8 +114,7 @@ func (t *typeMapper) ToInternal(data map[string]interface{}) error { if schema.Mapper == nil { continue } - fieldData, _ := data[fieldName].(map[string]interface{}) - errors.Add(schema.Mapper.ToInternal(fieldData)) + errors.Add(schema.Mapper.ToInternal(data.Map(fieldName))) } return errors.Err() diff --git a/vendor/github.com/rancher/norman/pkg/types/server_types.go b/vendor/github.com/rancher/norman/pkg/types/server_types.go index ec2b2a7..94ed05e 100644 --- a/vendor/github.com/rancher/norman/pkg/types/server_types.go +++ b/vendor/github.com/rancher/norman/pkg/types/server_types.go @@ -348,3 +348,10 @@ func APIChan(c <-chan APIEvent, f func(APIEvent) APIEvent) chan APIEvent { }() return result } + +func FormatterChain(formatter Formatter, next Formatter) Formatter { + return func(request *APIRequest, resource *RawResource) { + formatter(request, resource) + next(request, resource) + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 5ca85c4..59e1fb1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -42,16 +42,16 @@ github.com/pkg/errors github.com/rancher/norman/pkg/authorization github.com/rancher/norman/pkg/types github.com/rancher/norman/pkg/types/convert -github.com/rancher/norman/pkg/store/empty github.com/rancher/norman/pkg/store/proxy github.com/rancher/norman/pkg/subscribe github.com/rancher/norman/pkg/types/values +github.com/rancher/norman/pkg/store/empty github.com/rancher/norman/pkg/api/builtin +github.com/rancher/norman/pkg/data github.com/rancher/norman/pkg/api github.com/rancher/norman/pkg/urlbuilder github.com/rancher/norman/pkg/httperror github.com/rancher/norman/pkg/types/slice -github.com/rancher/norman/pkg/data github.com/rancher/norman/pkg/types/definition github.com/rancher/norman/pkg/types/convert/merge github.com/rancher/norman/pkg/api/writer