2017-11-10 21:44:02 -07:00
|
|
|
package schema
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2018-01-16 18:03:35 -07:00
|
|
|
"net/http"
|
2017-11-10 21:44:02 -07:00
|
|
|
"strings"
|
|
|
|
|
2018-02-14 15:48:47 -07:00
|
|
|
"github.com/rancher/norman/httperror"
|
2017-11-10 21:44:02 -07:00
|
|
|
"github.com/rancher/norman/store/empty"
|
|
|
|
"github.com/rancher/norman/types"
|
2017-11-28 14:28:25 -07:00
|
|
|
"github.com/rancher/norman/types/definition"
|
2018-01-16 18:03:35 -07:00
|
|
|
"github.com/rancher/norman/types/slice"
|
2017-11-10 21:44:02 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
type Store struct {
|
|
|
|
empty.Store
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewSchemaStore() types.Store {
|
|
|
|
return &Store{}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Store) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) {
|
2017-11-21 13:46:30 -07:00
|
|
|
for _, schema := range apiContext.Schemas.SchemasForVersion(*apiContext.Version) {
|
2017-11-10 21:44:02 -07:00
|
|
|
if strings.EqualFold(schema.ID, id) {
|
2019-05-29 10:49:34 -07:00
|
|
|
if schema.Enabled != nil {
|
|
|
|
if !schema.Enabled() {
|
|
|
|
return nil, httperror.NewAPIError(httperror.NotFound, "schema disabled")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-10 21:44:02 -07:00
|
|
|
schemaData := map[string]interface{}{}
|
|
|
|
|
2018-01-16 18:03:35 -07:00
|
|
|
data, err := json.Marshal(s.modifyForAccessControl(apiContext, *schema))
|
2017-11-10 21:44:02 -07:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return schemaData, json.Unmarshal(data, &schemaData)
|
|
|
|
}
|
|
|
|
}
|
2018-02-14 15:48:47 -07:00
|
|
|
return nil, httperror.NewAPIError(httperror.NotFound, "no such schema")
|
2017-11-10 21:44:02 -07:00
|
|
|
}
|
|
|
|
|
2018-01-16 18:03:35 -07:00
|
|
|
func (s *Store) modifyForAccessControl(context *types.APIContext, schema types.Schema) *types.Schema {
|
|
|
|
var resourceMethods []string
|
2018-03-31 00:13:30 -07:00
|
|
|
if slice.ContainsString(schema.ResourceMethods, http.MethodPut) && schema.CanUpdate(context) == nil {
|
2018-01-16 18:03:35 -07:00
|
|
|
resourceMethods = append(resourceMethods, http.MethodPut)
|
|
|
|
}
|
2018-03-31 00:13:30 -07:00
|
|
|
if slice.ContainsString(schema.ResourceMethods, http.MethodDelete) && schema.CanDelete(context) == nil {
|
2018-01-16 18:03:35 -07:00
|
|
|
resourceMethods = append(resourceMethods, http.MethodDelete)
|
|
|
|
}
|
2018-03-31 00:13:30 -07:00
|
|
|
if slice.ContainsString(schema.ResourceMethods, http.MethodGet) && schema.CanGet(context) == nil {
|
2018-02-14 15:49:24 -07:00
|
|
|
resourceMethods = append(resourceMethods, http.MethodGet)
|
|
|
|
}
|
2018-01-16 18:03:35 -07:00
|
|
|
|
|
|
|
var collectionMethods []string
|
2018-03-31 00:13:30 -07:00
|
|
|
if slice.ContainsString(schema.CollectionMethods, http.MethodPost) && schema.CanCreate(context) == nil {
|
2018-01-16 18:03:35 -07:00
|
|
|
collectionMethods = append(collectionMethods, http.MethodPost)
|
|
|
|
}
|
2018-03-31 00:13:30 -07:00
|
|
|
if slice.ContainsString(schema.CollectionMethods, http.MethodGet) && schema.CanList(context) == nil {
|
2018-01-16 18:03:35 -07:00
|
|
|
collectionMethods = append(collectionMethods, http.MethodGet)
|
|
|
|
}
|
|
|
|
|
|
|
|
schema.ResourceMethods = resourceMethods
|
|
|
|
schema.CollectionMethods = collectionMethods
|
|
|
|
|
|
|
|
return &schema
|
|
|
|
}
|
|
|
|
|
2017-12-28 08:47:10 -07:00
|
|
|
func (s *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) (chan map[string]interface{}, error) {
|
2017-11-28 14:28:25 -07:00
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
2017-12-28 08:47:10 -07:00
|
|
|
func (s *Store) List(apiContext *types.APIContext, schema *types.Schema, opt *types.QueryOptions) ([]map[string]interface{}, error) {
|
2017-11-21 13:46:30 -07:00
|
|
|
schemaMap := apiContext.Schemas.SchemasForVersion(*apiContext.Version)
|
|
|
|
schemas := make([]*types.Schema, 0, len(schemaMap))
|
|
|
|
schemaData := make([]map[string]interface{}, 0, len(schemaMap))
|
2017-11-10 21:44:02 -07:00
|
|
|
|
2017-11-28 14:28:25 -07:00
|
|
|
included := map[string]bool{}
|
|
|
|
|
2017-11-21 13:46:30 -07:00
|
|
|
for _, schema := range schemaMap {
|
2017-11-28 14:28:25 -07:00
|
|
|
if included[schema.ID] {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2019-05-29 10:49:34 -07:00
|
|
|
if schema.Enabled != nil {
|
|
|
|
if !schema.Enabled() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-31 00:13:30 -07:00
|
|
|
if schema.CanList(apiContext) == nil || schema.CanGet(apiContext) == nil {
|
2018-01-16 18:03:35 -07:00
|
|
|
schemas = s.addSchema(apiContext, schema, schemaMap, schemas, included)
|
2017-11-28 14:28:25 -07:00
|
|
|
}
|
2017-11-10 21:44:02 -07:00
|
|
|
}
|
|
|
|
|
2017-11-21 13:46:30 -07:00
|
|
|
data, err := json.Marshal(schemas)
|
|
|
|
if err != nil {
|
2017-11-10 21:44:02 -07:00
|
|
|
return nil, err
|
|
|
|
}
|
2017-11-21 13:46:30 -07:00
|
|
|
|
|
|
|
return schemaData, json.Unmarshal(data, &schemaData)
|
2017-11-10 21:44:02 -07:00
|
|
|
}
|
2017-11-28 14:28:25 -07:00
|
|
|
|
2018-01-16 18:03:35 -07:00
|
|
|
func (s *Store) addSchema(apiContext *types.APIContext, schema *types.Schema, schemaMap map[string]*types.Schema, schemas []*types.Schema, included map[string]bool) []*types.Schema {
|
2017-11-28 14:28:25 -07:00
|
|
|
included[schema.ID] = true
|
2018-01-16 18:03:35 -07:00
|
|
|
schemas = s.traverseAndAdd(apiContext, schema, schemaMap, schemas, included)
|
|
|
|
schemas = append(schemas, s.modifyForAccessControl(apiContext, *schema))
|
2017-11-28 14:28:25 -07:00
|
|
|
return schemas
|
|
|
|
}
|
|
|
|
|
2018-01-16 18:03:35 -07:00
|
|
|
func (s *Store) traverseAndAdd(apiContext *types.APIContext, schema *types.Schema, schemaMap map[string]*types.Schema, schemas []*types.Schema, included map[string]bool) []*types.Schema {
|
2017-11-28 14:28:25 -07:00
|
|
|
for _, field := range schema.ResourceFields {
|
2017-12-16 01:25:37 -07:00
|
|
|
t := ""
|
|
|
|
subType := field.Type
|
|
|
|
for subType != t {
|
|
|
|
t = subType
|
|
|
|
subType = definition.SubType(t)
|
2017-11-28 14:28:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
if refSchema, ok := schemaMap[t]; ok && !included[t] {
|
2018-01-16 18:03:35 -07:00
|
|
|
schemas = s.addSchema(apiContext, refSchema, schemaMap, schemas, included)
|
2017-11-28 14:28:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, action := range schema.ResourceActions {
|
|
|
|
for _, t := range []string{action.Output, action.Input} {
|
|
|
|
if t == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if refSchema, ok := schemaMap[t]; ok && !included[t] {
|
2018-01-16 18:03:35 -07:00
|
|
|
schemas = s.addSchema(apiContext, refSchema, schemaMap, schemas, included)
|
2017-11-28 14:28:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-20 01:08:31 -07:00
|
|
|
for _, action := range schema.CollectionActions {
|
|
|
|
for _, t := range []string{action.Output, action.Input} {
|
|
|
|
if t == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if refSchema, ok := schemaMap[t]; ok && !included[t] {
|
|
|
|
schemas = s.addSchema(apiContext, refSchema, schemaMap, schemas, included)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-28 14:28:25 -07:00
|
|
|
return schemas
|
|
|
|
}
|