1
0
mirror of https://github.com/rancher/norman.git synced 2025-09-17 15:49:53 +00:00

Random fixes

This commit is contained in:
Darren Shepherd
2017-11-14 21:33:57 -07:00
parent 5189cf8fad
commit 6b05d03f46
9 changed files with 123 additions and 31 deletions

View File

@@ -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":

View File

@@ -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),

View File

@@ -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)
}

View File

@@ -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
}

View File

@@ -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...),
},
}
}

View 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
}

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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)
}