mirror of
https://github.com/rancher/norman.git
synced 2025-09-17 15:49:53 +00:00
Random fixes
This commit is contained in:
@@ -55,6 +55,10 @@ func getTypeString(nullable bool, typeName string, schema *types.Schema, schemas
|
||||
name = "float64"
|
||||
case "int":
|
||||
name = "int64"
|
||||
case "multiline":
|
||||
return "string"
|
||||
case "masked":
|
||||
return "string"
|
||||
case "password":
|
||||
return "string"
|
||||
case "date":
|
||||
|
@@ -221,8 +221,6 @@ func (c *Store) Create(apiContext *types.APIContext, schema *types.Schema, data
|
||||
|
||||
namespace, _ := data["namespace"].(string)
|
||||
|
||||
//mapping.Metadata.Forward(data)
|
||||
|
||||
data["apiVersion"] = crd.Spec.Group + "/" + crd.Spec.Version
|
||||
data["kind"] = crd.Status.AcceptedNames.Kind
|
||||
|
||||
@@ -230,10 +228,10 @@ func (c *Store) Create(apiContext *types.APIContext, schema *types.Schema, data
|
||||
|
||||
req := c.k8sClient.Post().
|
||||
Prefix("apis", crd.Spec.Group, crd.Spec.Version).
|
||||
Resource(crd.Status.AcceptedNames.Plural).
|
||||
Body(&unstructured.Unstructured{
|
||||
Object: data,
|
||||
}).
|
||||
Resource(crd.Status.AcceptedNames.Plural)
|
||||
})
|
||||
|
||||
if crd.Spec.Scope == apiext.NamespaceScoped {
|
||||
req.Namespace(namespace)
|
||||
@@ -352,7 +350,8 @@ func (c *Store) createCRD(schema *types.Schema, ready map[string]apiext.CustomRe
|
||||
Spec: apiext.CustomResourceDefinitionSpec{
|
||||
Group: schema.Version.Group,
|
||||
Version: schema.Version.Version,
|
||||
Scope: getScope(schema),
|
||||
//Scope: getScope(schema),
|
||||
Scope: apiext.ClusterScoped,
|
||||
Names: apiext.CustomResourceDefinitionNames{
|
||||
Plural: plural,
|
||||
Kind: capitalize(schema.ID),
|
||||
|
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
type Embed struct {
|
||||
Field string
|
||||
ReadOnly bool
|
||||
ignoreOverride bool
|
||||
embeddedFields []string
|
||||
}
|
||||
@@ -56,6 +57,10 @@ func (e *Embed) ModifySchema(schema *types.Schema, schemas *types.Schemas) error
|
||||
e.Field, schema.ID, name)
|
||||
}
|
||||
}
|
||||
if e.ReadOnly {
|
||||
field.Create = false
|
||||
field.Update = false
|
||||
}
|
||||
schema.ResourceFields[name] = field
|
||||
e.embeddedFields = append(e.embeddedFields, name)
|
||||
}
|
||||
|
@@ -3,6 +3,8 @@ package mapper
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/norman/types"
|
||||
"github.com/rancher/norman/types/convert"
|
||||
)
|
||||
@@ -12,39 +14,69 @@ type Move struct {
|
||||
}
|
||||
|
||||
func (m Move) FromInternal(data map[string]interface{}) {
|
||||
if v, ok := data[m.From]; ok {
|
||||
delete(data, m.From)
|
||||
data[m.To] = v
|
||||
if v, ok := RemoveValue(data, strings.Split(m.From, "/")...); ok {
|
||||
PutValue(data, v, strings.Split(m.To, "/")...)
|
||||
}
|
||||
}
|
||||
|
||||
func (m Move) ToInternal(data map[string]interface{}) {
|
||||
if v, ok := data[m.To]; ok {
|
||||
delete(data, m.To)
|
||||
data[m.From] = v
|
||||
if v, ok := RemoveValue(data, strings.Split(m.To, "/")...); ok {
|
||||
PutValue(data, v, strings.Split(m.From, "/")...)
|
||||
}
|
||||
}
|
||||
|
||||
func (m Move) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
|
||||
internalSchema, err := getInternal(schema)
|
||||
func (m Move) ModifySchema(s *types.Schema, schemas *types.Schemas) error {
|
||||
internalSchema, err := getInternal(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
field, ok := internalSchema.ResourceFields[m.From]
|
||||
_, _, fromInternalField, ok, err := getField(internalSchema, schemas, m.From)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
return fmt.Errorf("missing field %s on internal schema %s", m.From, internalSchema.ID)
|
||||
}
|
||||
|
||||
_, ok = schema.ResourceFields[m.To]
|
||||
if ok {
|
||||
return fmt.Errorf("field %s already exists on schema %s", m.From, internalSchema.ID)
|
||||
fromSchema, _, _, _, err := getField(s, schemas, m.From)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
delete(schema.ResourceFields, m.From)
|
||||
toSchema, toFieldName, toField, ok, err := getField(s, schemas, m.To)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, ok = toSchema.ResourceFields[toFieldName]
|
||||
if ok && !strings.Contains(m.To, "/") {
|
||||
return fmt.Errorf("field %s already exists on schema %s", m.To, s.ID)
|
||||
}
|
||||
|
||||
field.CodeName = convert.Capitalize(m.To)
|
||||
schema.ResourceFields[m.To] = field
|
||||
delete(fromSchema.ResourceFields, m.From)
|
||||
|
||||
toField.CodeName = convert.Capitalize(toFieldName)
|
||||
toSchema.ResourceFields[toFieldName] = fromInternalField
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getField(schema *types.Schema, schemas *types.Schemas, target string) (*types.Schema, string, types.Field, bool, error) {
|
||||
parts := strings.Split(target, "/")
|
||||
for i, part := range parts {
|
||||
if i == len(parts)-1 {
|
||||
continue
|
||||
}
|
||||
|
||||
subSchema := schemas.Schema(&schema.Version, schema.ResourceFields[part].Type)
|
||||
if subSchema == nil {
|
||||
return nil, "", types.Field{}, false, fmt.Errorf("failed to find field or schema for %s on %s", part, schema.ID)
|
||||
}
|
||||
|
||||
schema = subSchema
|
||||
}
|
||||
|
||||
name := parts[len(parts)-1]
|
||||
f, ok := schema.ResourceFields[name]
|
||||
return schema, name, f, ok, nil
|
||||
}
|
||||
|
@@ -6,14 +6,14 @@ type Object struct {
|
||||
types.TypeMapper
|
||||
}
|
||||
|
||||
func NewObject(mappers []types.Mapper) *Object {
|
||||
func NewObject(mappers ...types.Mapper) *Object {
|
||||
return &Object{
|
||||
TypeMapper: types.TypeMapper{
|
||||
Mappers: append(mappers,
|
||||
&Drop{"status"},
|
||||
Mappers: append([]types.Mapper{
|
||||
&Embed{Field: "metadata"},
|
||||
&Embed{Field: "spec"},
|
||||
),
|
||||
&ReadOnly{"status"},
|
||||
}, mappers...),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
30
types/mapping/mapper/read_only.go
Normal file
30
types/mapping/mapper/read_only.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package mapper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/rancher/norman/types"
|
||||
)
|
||||
|
||||
type ReadOnly struct {
|
||||
Field string
|
||||
}
|
||||
|
||||
func (r *ReadOnly) FromInternal(data map[string]interface{}) {
|
||||
}
|
||||
|
||||
func (r *ReadOnly) ToInternal(data map[string]interface{}) {
|
||||
}
|
||||
|
||||
func (r *ReadOnly) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
|
||||
field, ok := schema.ResourceFields[r.Field]
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to find field %s on schema %s", r.Field, schema.ID)
|
||||
}
|
||||
|
||||
field.Create = false
|
||||
field.Update = false
|
||||
schema.ResourceFields[r.Field] = field
|
||||
|
||||
return nil
|
||||
}
|
@@ -24,7 +24,9 @@ func (s SliceToMap) FromInternal(data map[string]interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
data[s.Field] = result
|
||||
if len(result) > 0 {
|
||||
data[s.Field] = result
|
||||
}
|
||||
}
|
||||
|
||||
func (s SliceToMap) ToInternal(data map[string]interface{}) {
|
||||
@@ -39,7 +41,9 @@ func (s SliceToMap) ToInternal(data map[string]interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
data[s.Field] = result
|
||||
if len(result) > 0 {
|
||||
data[s.Field] = result
|
||||
}
|
||||
}
|
||||
|
||||
func (s SliceToMap) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
|
||||
|
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
var (
|
||||
resourceType = reflect.TypeOf(Resource{})
|
||||
typeType = reflect.TypeOf(metav1.TypeMeta{})
|
||||
metaType = reflect.TypeOf(metav1.ObjectMeta{})
|
||||
blacklistNames = map[string]bool{
|
||||
"links": true,
|
||||
@@ -114,6 +115,9 @@ func (s *Schemas) readFields(schema *Schema, t reflect.Type) error {
|
||||
schema.ResourceMethods = []string{"GET", "PUT", "DELETE"}
|
||||
}
|
||||
|
||||
hasType := false
|
||||
hasMeta := false
|
||||
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
|
||||
@@ -128,6 +132,14 @@ func (s *Schemas) readFields(schema *Schema, t reflect.Type) error {
|
||||
continue
|
||||
}
|
||||
|
||||
if field.Anonymous && jsonName == "" && field.Type == typeType {
|
||||
hasType = true
|
||||
}
|
||||
|
||||
if field.Anonymous && jsonName == "metadata" && field.Type == metaType {
|
||||
hasMeta = true
|
||||
}
|
||||
|
||||
if field.Anonymous && jsonName == "" {
|
||||
t := field.Type
|
||||
if t.Kind() == reflect.Ptr {
|
||||
@@ -177,15 +189,15 @@ func (s *Schemas) readFields(schema *Schema, t reflect.Type) error {
|
||||
schemaField.Type = inferedType
|
||||
}
|
||||
|
||||
if field.Type == metaType {
|
||||
schema.CollectionMethods = []string{"GET", "POST"}
|
||||
schema.ResourceMethods = []string{"GET", "PUT", "DELETE"}
|
||||
}
|
||||
|
||||
logrus.Debugf("Setting field %s.%s: %#v", schema.ID, fieldName, schemaField)
|
||||
schema.ResourceFields[fieldName] = schemaField
|
||||
}
|
||||
|
||||
if hasType && hasMeta {
|
||||
schema.CollectionMethods = []string{"GET", "POST"}
|
||||
schema.ResourceMethods = []string{"GET", "PUT", "DELETE"}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@@ -13,6 +13,8 @@ type SchemaCollection struct {
|
||||
Data []Schema
|
||||
}
|
||||
|
||||
type SchemaInitFunc func(*Schemas) *Schemas
|
||||
|
||||
type Schemas struct {
|
||||
schemasByPath map[string]map[string]*Schema
|
||||
mappers map[string]map[string]Mapper
|
||||
@@ -28,6 +30,10 @@ func NewSchemas() *Schemas {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Schemas) Init(initFunc SchemaInitFunc) *Schemas {
|
||||
return initFunc(s)
|
||||
}
|
||||
|
||||
func (s *Schemas) Err() error {
|
||||
return NewErrors(s.errors)
|
||||
}
|
||||
|
Reference in New Issue
Block a user