1
0
mirror of https://github.com/rancher/steve.git synced 2025-04-27 11:00:48 +00:00
steve/pkg/schema/factory.go

126 lines
3.0 KiB
Go
Raw Normal View History

2019-08-13 23:36:03 +00:00
package schema
import (
"fmt"
"net/http"
2019-09-11 21:05:00 +00:00
"github.com/rancher/steve/pkg/accesscontrol"
"github.com/rancher/steve/pkg/attributes"
2020-01-31 05:37:59 +00:00
"github.com/rancher/steve/pkg/schema/table"
"github.com/rancher/steve/pkg/schemaserver/builtin"
"github.com/rancher/steve/pkg/schemaserver/types"
"github.com/rancher/wrangler/pkg/schemas"
2019-08-13 23:36:03 +00:00
"k8s.io/apiserver/pkg/authentication/user"
)
2020-01-31 05:37:59 +00:00
func newSchemas() (*types.APISchemas, error) {
apiSchemas := types.EmptyAPISchemas()
if err := apiSchemas.AddSchemas(builtin.Schemas); err != nil {
2019-08-13 23:36:03 +00:00
return nil, err
}
2020-01-31 05:37:59 +00:00
apiSchemas.InternalSchemas.DefaultMapper = func() schemas.Mapper {
2019-08-13 23:36:03 +00:00
return newDefaultMapper()
}
2020-01-31 05:37:59 +00:00
return apiSchemas, nil
2019-08-13 23:36:03 +00:00
}
2020-01-31 05:37:59 +00:00
func (c *Collection) Schemas(user user.Info) (*types.APISchemas, error) {
2019-08-13 23:36:03 +00:00
access := c.as.AccessFor(user)
2020-01-31 05:01:21 +00:00
return c.schemasForSubject(access)
2019-08-13 23:36:03 +00:00
}
2020-01-31 05:37:59 +00:00
func (c *Collection) schemasForSubject(access *accesscontrol.AccessSet) (*types.APISchemas, error) {
2019-08-13 23:36:03 +00:00
result, err := newSchemas()
if err != nil {
return nil, err
}
2020-01-31 05:37:59 +00:00
if err := result.AddSchemas(c.baseSchema); err != nil {
2019-08-13 23:36:03 +00:00
return nil, err
}
for _, s := range c.schemas {
gr := attributes.GR(s)
if gr.Resource == "" {
if err := result.AddSchema(*s); err != nil {
return nil, err
}
continue
}
verbs := attributes.Verbs(s)
2020-01-31 05:37:59 +00:00
verbAccess := accesscontrol.AccessListByVerb{}
2019-08-13 23:36:03 +00:00
for _, verb := range verbs {
a := access.AccessListFor(verb, gr)
if len(a) > 0 {
verbAccess[verb] = a
}
}
if len(verbAccess) == 0 {
continue
}
s = s.DeepCopy()
attributes.SetAccess(s, verbAccess)
if verbAccess.AnyVerb("list", "get") {
s.ResourceMethods = append(s.ResourceMethods, http.MethodGet)
s.CollectionMethods = append(s.CollectionMethods, http.MethodGet)
}
if verbAccess.AnyVerb("delete") {
s.ResourceMethods = append(s.ResourceMethods, http.MethodDelete)
}
if verbAccess.AnyVerb("update") {
s.ResourceMethods = append(s.ResourceMethods, http.MethodPut)
2020-01-31 05:01:21 +00:00
s.ResourceMethods = append(s.ResourceMethods, http.MethodPatch)
2019-08-13 23:36:03 +00:00
}
if verbAccess.AnyVerb("create") {
s.CollectionMethods = append(s.CollectionMethods, http.MethodPost)
}
2019-08-14 18:08:34 +00:00
c.applyTemplates(result, s)
2019-08-13 23:36:03 +00:00
if err := result.AddSchema(*s); err != nil {
return nil, err
}
}
return result, nil
}
2020-01-31 05:37:59 +00:00
func (c *Collection) applyTemplates(schemas *types.APISchemas, schema *types.APISchema) {
2019-08-13 23:36:03 +00:00
templates := []*Template{
c.templates[schema.ID],
c.templates[fmt.Sprintf("%s/%s", attributes.Group(schema), attributes.Kind(schema))],
c.templates[""],
}
for _, t := range templates {
if t == nil {
continue
}
2019-08-14 18:08:34 +00:00
if t.Mapper != nil {
2020-01-31 05:37:59 +00:00
schemas.InternalSchemas.AddMapper(schema.ID, t.Mapper)
2019-08-13 23:36:03 +00:00
}
if schema.Formatter == nil {
schema.Formatter = t.Formatter
}
if schema.Store == nil {
2020-01-31 05:01:21 +00:00
if t.StoreFactory == nil {
schema.Store = t.Store
} else {
schema.Store = t.StoreFactory(templates[2].Store)
}
2019-08-13 23:36:03 +00:00
}
2019-08-14 18:08:34 +00:00
if t.Customize != nil {
t.Customize(schema)
}
2019-09-09 21:28:55 +00:00
if len(t.Columns) > 0 {
2020-01-31 05:37:59 +00:00
schemas.InternalSchemas.AddMapper(schema.ID, table.NewColumns(t.ComputedColumns, t.Columns...))
2019-09-09 21:28:55 +00:00
}
2019-08-13 23:36:03 +00:00
}
}