mirror of
https://github.com/rancher/norman.git
synced 2025-09-02 15:54:32 +00:00
Many enhancements
This commit is contained in:
@@ -16,6 +16,7 @@ var (
|
|||||||
|
|
||||||
Schema = types.Schema{
|
Schema = types.Schema{
|
||||||
ID: "schema",
|
ID: "schema",
|
||||||
|
PluralName: "schemas",
|
||||||
Version: Version,
|
Version: Version,
|
||||||
CollectionMethods: []string{"GET"},
|
CollectionMethods: []string{"GET"},
|
||||||
ResourceMethods: []string{"GET"},
|
ResourceMethods: []string{"GET"},
|
||||||
@@ -75,10 +76,10 @@ var (
|
|||||||
}
|
}
|
||||||
|
|
||||||
Schemas = types.NewSchemas().
|
Schemas = types.NewSchemas().
|
||||||
AddSchema(&Schema).
|
AddSchema(Schema).
|
||||||
AddSchema(&Error).
|
AddSchema(Error).
|
||||||
AddSchema(&Collection).
|
AddSchema(Collection).
|
||||||
AddSchema(&APIRoot)
|
AddSchema(APIRoot)
|
||||||
)
|
)
|
||||||
|
|
||||||
func apiVersionFromMap(schemas *types.Schemas, apiVersion map[string]interface{}) types.APIVersion {
|
func apiVersionFromMap(schemas *types.Schemas, apiVersion map[string]interface{}) types.APIVersion {
|
||||||
|
@@ -9,7 +9,7 @@ import (
|
|||||||
func CreateHandler(apiContext *types.APIContext) error {
|
func CreateHandler(apiContext *types.APIContext) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
data, err := ParseAndValidateBody(apiContext)
|
data, err := ParseAndValidateBody(apiContext, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func UpdateHandler(apiContext *types.APIContext) error {
|
func UpdateHandler(apiContext *types.APIContext) error {
|
||||||
data, err := ParseAndValidateBody(apiContext)
|
data, err := ParseAndValidateBody(apiContext, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,7 @@ import (
|
|||||||
"github.com/rancher/norman/types"
|
"github.com/rancher/norman/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ParseAndValidateBody(apiContext *types.APIContext) (map[string]interface{}, error) {
|
func ParseAndValidateBody(apiContext *types.APIContext, create bool) (map[string]interface{}, error) {
|
||||||
data, err := parse.Body(apiContext.Request)
|
data, err := parse.Body(apiContext.Request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -14,7 +14,11 @@ func ParseAndValidateBody(apiContext *types.APIContext) (map[string]interface{},
|
|||||||
|
|
||||||
b := builder.NewBuilder(apiContext)
|
b := builder.NewBuilder(apiContext)
|
||||||
|
|
||||||
data, err = b.Construct(apiContext.Schema, data, builder.Create)
|
op := builder.Create
|
||||||
|
if !create {
|
||||||
|
op = builder.Update
|
||||||
|
}
|
||||||
|
data, err = b.Construct(apiContext.Schema, data, op)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@@ -102,19 +102,22 @@ func (s *Server) AddSchemas(schemas *types.Schemas) error {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, schema := range builtin.Schemas.Schemas() {
|
for _, schema := range builtin.Schemas.Schemas() {
|
||||||
s.setupDefaults(schema)
|
s.addSchema(*schema)
|
||||||
s.schemas.AddSchema(schema)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, schema := range schemas.Schemas() {
|
for _, schema := range schemas.Schemas() {
|
||||||
s.setupDefaults(schema)
|
s.addSchema(*schema)
|
||||||
s.schemas.AddSchema(schema)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.schemas.Err()
|
return s.schemas.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) addSchema(schema types.Schema) {
|
||||||
|
s.setupDefaults(&schema)
|
||||||
|
s.schemas.AddSchema(schema)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) setupDefaults(schema *types.Schema) {
|
func (s *Server) setupDefaults(schema *types.Schema) {
|
||||||
if schema.ActionHandler == nil {
|
if schema.ActionHandler == nil {
|
||||||
schema.ActionHandler = s.Defaults.ActionHandler
|
schema.ActionHandler = s.Defaults.ActionHandler
|
||||||
@@ -184,19 +187,19 @@ func (s *Server) handle(rw http.ResponseWriter, req *http.Request) (*types.APICo
|
|||||||
|
|
||||||
if action == nil && apiRequest.Type != "" {
|
if action == nil && apiRequest.Type != "" {
|
||||||
var handler types.RequestHandler
|
var handler types.RequestHandler
|
||||||
switch apiRequest.Method {
|
if apiRequest.Link == "" {
|
||||||
case http.MethodGet:
|
switch apiRequest.Method {
|
||||||
|
case http.MethodGet:
|
||||||
|
handler = apiRequest.Schema.ListHandler
|
||||||
|
case http.MethodPost:
|
||||||
|
handler = apiRequest.Schema.CreateHandler
|
||||||
|
case http.MethodPut:
|
||||||
|
handler = apiRequest.Schema.UpdateHandler
|
||||||
|
case http.MethodDelete:
|
||||||
|
handler = apiRequest.Schema.DeleteHandler
|
||||||
|
}
|
||||||
|
} else {
|
||||||
handler = apiRequest.Schema.ListHandler
|
handler = apiRequest.Schema.ListHandler
|
||||||
case http.MethodPost:
|
|
||||||
handler = apiRequest.Schema.CreateHandler
|
|
||||||
case http.MethodPut:
|
|
||||||
handler = apiRequest.Schema.UpdateHandler
|
|
||||||
case http.MethodDelete:
|
|
||||||
handler = apiRequest.Schema.DeleteHandler
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return apiRequest, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if handler == nil {
|
if handler == nil {
|
||||||
|
@@ -105,7 +105,7 @@ func Parse(rw http.ResponseWriter, req *http.Request, schemas *types.Schemas, ur
|
|||||||
result.Method = http.MethodGet
|
result.Method = http.MethodGet
|
||||||
result.URLBuilder, err = urlbuilder.New(req, types.APIVersion{}, result.Schemas)
|
result.URLBuilder, err = urlbuilder.New(req, types.APIVersion{}, result.Schemas)
|
||||||
result.Type = "apiRoot"
|
result.Type = "apiRoot"
|
||||||
result.Schema = &builtin.APIRoot
|
result.Schema = result.Schemas.Schema(&builtin.Version, "apiRoot")
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ func Parse(rw http.ResponseWriter, req *http.Request, schemas *types.Schemas, ur
|
|||||||
if result.Schema == nil {
|
if result.Schema == nil {
|
||||||
result.Method = http.MethodGet
|
result.Method = http.MethodGet
|
||||||
result.Type = "apiRoot"
|
result.Type = "apiRoot"
|
||||||
result.Schema = &builtin.APIRoot
|
result.Schema = result.Schemas.Schema(&builtin.Version, "apiRoot")
|
||||||
result.ID = result.Version.Path
|
result.ID = result.Version.Path
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,7 @@ func ValidateMethod(request *types.APIContext) error {
|
|||||||
return httperror.NewAPIError(httperror.MethodNotAllowed, fmt.Sprintf("Method %s not supported", request.Method))
|
return httperror.NewAPIError(httperror.MethodNotAllowed, fmt.Sprintf("Method %s not supported", request.Method))
|
||||||
}
|
}
|
||||||
|
|
||||||
if request.Type == "" || request.Schema == nil {
|
if request.Type == "" || request.Schema == nil || request.Link != "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -21,10 +21,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Store struct {
|
type Store struct {
|
||||||
schemas []*types.Schema
|
|
||||||
apiExtClientSet apiextclientset.Interface
|
apiExtClientSet apiextclientset.Interface
|
||||||
k8sClient rest.Interface
|
k8sClient rest.Interface
|
||||||
schemaStores map[*types.Schema]*proxy.Store
|
schemaStores map[string]*proxy.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCRDStoreFromConfig(config rest.Config) (*Store, error) {
|
func NewCRDStoreFromConfig(config rest.Config) (*Store, error) {
|
||||||
@@ -51,12 +50,16 @@ func NewCRDStoreFromClients(apiExtClientSet apiextclientset.Interface, k8sClient
|
|||||||
return &Store{
|
return &Store{
|
||||||
apiExtClientSet: apiExtClientSet,
|
apiExtClientSet: apiExtClientSet,
|
||||||
k8sClient: k8sClient,
|
k8sClient: k8sClient,
|
||||||
schemaStores: map[*types.Schema]*proxy.Store{},
|
schemaStores: map[string]*proxy.Store{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func key(schema *types.Schema) string {
|
||||||
|
return schema.Version.Path + "/" + schema.ID
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Store) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) {
|
func (c *Store) ByID(apiContext *types.APIContext, schema *types.Schema, id string) (map[string]interface{}, error) {
|
||||||
store, ok := c.schemaStores[schema]
|
store, ok := c.schemaStores[key(schema)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -64,7 +67,7 @@ func (c *Store) ByID(apiContext *types.APIContext, schema *types.Schema, id stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id string) error {
|
func (c *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id string) error {
|
||||||
store, ok := c.schemaStores[schema]
|
store, ok := c.schemaStores[key(schema)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -72,7 +75,7 @@ func (c *Store) Delete(apiContext *types.APIContext, schema *types.Schema, id st
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Store) List(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) ([]map[string]interface{}, error) {
|
func (c *Store) List(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) ([]map[string]interface{}, error) {
|
||||||
store, ok := c.schemaStores[schema]
|
store, ok := c.schemaStores[key(schema)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -80,7 +83,7 @@ func (c *Store) List(apiContext *types.APIContext, schema *types.Schema, opt typ
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) (chan map[string]interface{}, error) {
|
func (c *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) (chan map[string]interface{}, error) {
|
||||||
store, ok := c.schemaStores[schema]
|
store, ok := c.schemaStores[key(schema)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -88,7 +91,7 @@ func (c *Store) Watch(apiContext *types.APIContext, schema *types.Schema, opt ty
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) {
|
func (c *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) {
|
||||||
store, ok := c.schemaStores[schema]
|
store, ok := c.schemaStores[key(schema)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -96,7 +99,7 @@ func (c *Store) Update(apiContext *types.APIContext, schema *types.Schema, data
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) {
|
func (c *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) {
|
||||||
store, ok := c.schemaStores[schema]
|
store, ok := c.schemaStores[key(schema)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -105,6 +108,7 @@ func (c *Store) Create(apiContext *types.APIContext, schema *types.Schema, data
|
|||||||
|
|
||||||
func (c *Store) AddSchemas(ctx context.Context, schemas ...*types.Schema) error {
|
func (c *Store) AddSchemas(ctx context.Context, schemas ...*types.Schema) error {
|
||||||
schemaStatus := map[*types.Schema]*apiext.CustomResourceDefinition{}
|
schemaStatus := map[*types.Schema]*apiext.CustomResourceDefinition{}
|
||||||
|
var allSchemas []*types.Schema
|
||||||
|
|
||||||
for _, schema := range schemas {
|
for _, schema := range schemas {
|
||||||
if schema.Store != nil || !contains(schema.CollectionMethods, http.MethodGet) {
|
if schema.Store != nil || !contains(schema.CollectionMethods, http.MethodGet) {
|
||||||
@@ -112,7 +116,7 @@ func (c *Store) AddSchemas(ctx context.Context, schemas ...*types.Schema) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
schema.Store = c
|
schema.Store = c
|
||||||
c.schemas = append(c.schemas, schema)
|
allSchemas = append(allSchemas, schema)
|
||||||
}
|
}
|
||||||
|
|
||||||
ready, err := c.getReadyCRDs()
|
ready, err := c.getReadyCRDs()
|
||||||
@@ -120,7 +124,7 @@ func (c *Store) AddSchemas(ctx context.Context, schemas ...*types.Schema) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, schema := range c.schemas {
|
for _, schema := range allSchemas {
|
||||||
crd, err := c.createCRD(schema, ready)
|
crd, err := c.createCRD(schema, ready)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -144,7 +148,7 @@ func (c *Store) AddSchemas(ctx context.Context, schemas ...*types.Schema) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
for schema, crd := range schemaStatus {
|
for schema, crd := range schemaStatus {
|
||||||
c.schemaStores[schema] = proxy.NewProxyStore(c.k8sClient,
|
c.schemaStores[key(schema)] = proxy.NewProxyStore(c.k8sClient,
|
||||||
[]string{"apis"},
|
[]string{"apis"},
|
||||||
crd.Spec.Group,
|
crd.Spec.Group,
|
||||||
crd.Spec.Version,
|
crd.Spec.Version,
|
||||||
|
@@ -38,7 +38,7 @@ func (s *StoreWrapper) List(apiContext *types.APIContext, schema *types.Schema,
|
|||||||
|
|
||||||
func (s *StoreWrapper) Watch(apiContext *types.APIContext, schema *types.Schema, opt types.QueryOptions) (chan map[string]interface{}, error) {
|
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)
|
c, err := s.store.Watch(apiContext, schema, opt)
|
||||||
if err != nil {
|
if err != nil || c == nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,7 +32,11 @@ func SubType(fieldType string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetType(data map[string]interface{}) string {
|
func GetType(data map[string]interface{}) string {
|
||||||
parts := strings.Split(GetFullType(data), "/")
|
return GetShortTypeFromFull(GetFullType(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetShortTypeFromFull(fullType string) string {
|
||||||
|
parts := strings.Split(fullType, "/")
|
||||||
return parts[len(parts)-1]
|
return parts[len(parts)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -176,7 +176,7 @@ func (s *Schemas) importType(version *APIVersion, t reflect.Type, overrides ...r
|
|||||||
s.setupFilters(schema)
|
s.setupFilters(schema)
|
||||||
|
|
||||||
schema.Mapper = mapper
|
schema.Mapper = mapper
|
||||||
s.AddSchema(schema)
|
s.AddSchema(*schema)
|
||||||
|
|
||||||
return schema, s.Err()
|
return schema, s.Err()
|
||||||
}
|
}
|
||||||
|
@@ -54,12 +54,12 @@ func (s *Schemas) SubContextSchemas() map[string]*Schema {
|
|||||||
|
|
||||||
func (s *Schemas) AddSchemas(schema *Schemas) *Schemas {
|
func (s *Schemas) AddSchemas(schema *Schemas) *Schemas {
|
||||||
for _, schema := range schema.Schemas() {
|
for _, schema := range schema.Schemas() {
|
||||||
s.AddSchema(schema)
|
s.AddSchema(*schema)
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Schemas) AddSchema(schema *Schema) *Schemas {
|
func (s *Schemas) AddSchema(schema Schema) *Schemas {
|
||||||
schema.Type = "/meta/schemas/schema"
|
schema.Type = "/meta/schemas/schema"
|
||||||
if schema.ID == "" {
|
if schema.ID == "" {
|
||||||
s.errors = append(s.errors, fmt.Errorf("ID is not set on schema: %v", schema))
|
s.errors = append(s.errors, fmt.Errorf("ID is not set on schema: %v", schema))
|
||||||
@@ -90,12 +90,12 @@ func (s *Schemas) AddSchema(schema *Schema) *Schemas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := schemas[schema.ID]; !ok {
|
if _, ok := schemas[schema.ID]; !ok {
|
||||||
schemas[schema.ID] = schema
|
schemas[schema.ID] = &schema
|
||||||
s.schemas = append(s.schemas, schema)
|
s.schemas = append(s.schemas, &schema)
|
||||||
}
|
}
|
||||||
|
|
||||||
if schema.SubContext != "" {
|
if schema.SubContext != "" {
|
||||||
s.schemasBySubContext[schema.SubContext] = schema
|
s.schemasBySubContext[schema.SubContext] = &schema
|
||||||
}
|
}
|
||||||
|
|
||||||
return s
|
return s
|
||||||
|
Reference in New Issue
Block a user