2019-08-13 23:36:03 +00:00
|
|
|
package schema
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"github.com/rancher/naok/pkg/accesscontrol"
|
|
|
|
"github.com/rancher/naok/pkg/attributes"
|
|
|
|
"github.com/rancher/norman/pkg/api/builtin"
|
|
|
|
"github.com/rancher/norman/pkg/types"
|
|
|
|
"k8s.io/apiserver/pkg/authentication/user"
|
|
|
|
)
|
|
|
|
|
|
|
|
func newSchemas() (*types.Schemas, error) {
|
|
|
|
s, err := types.NewSchemas(builtin.Schemas)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
s.DefaultMapper = func() types.Mapper {
|
|
|
|
return newDefaultMapper()
|
|
|
|
}
|
|
|
|
|
|
|
|
return s, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Collection) Schemas(user user.Info) (*types.Schemas, error) {
|
|
|
|
access := c.as.AccessFor(user)
|
|
|
|
return c.schemasForSubject("", access)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Collection) schemasForSubject(subjectKey string, access *accesscontrol.AccessSet) (*types.Schemas, error) {
|
|
|
|
result, err := newSchemas()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err := result.AddSchemas(c.baseSchema); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2019-08-14 18:08:34 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-13 23:36:03 +00:00
|
|
|
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)
|
|
|
|
verbAccess := accesscontrol.AccessListMap{}
|
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2019-08-14 18:08:34 +00:00
|
|
|
func (c *Collection) applyTemplates(schemas *types.Schemas, schema *types.Schema) {
|
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 {
|
|
|
|
schemas.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 {
|
|
|
|
schema.Store = t.Store
|
|
|
|
}
|
2019-08-14 18:08:34 +00:00
|
|
|
if t.Customize != nil {
|
|
|
|
t.Customize(schema)
|
|
|
|
}
|
2019-08-13 23:36:03 +00:00
|
|
|
}
|
|
|
|
}
|