1
0
mirror of https://github.com/rancher/norman.git synced 2025-08-30 13:28:48 +00:00

Change ToInternal to return error

This commit is contained in:
Darren Shepherd 2018-06-04 16:48:22 -07:00
parent 6db31068a0
commit 875bcf4b2d
28 changed files with 185 additions and 66 deletions

View File

@ -17,6 +17,7 @@ import (
"github.com/rancher/norman/types/values"
"github.com/sirupsen/logrus"
"k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
@ -294,7 +295,9 @@ func getNamespace(apiContext *types.APIContext, opt *types.QueryOptions) string
}
func (s *Store) Create(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}) (map[string]interface{}, error) {
s.toInternal(schema.Mapper, data)
if err := s.toInternal(schema.Mapper, data); err != nil {
return nil, err
}
namespace, _ := values.GetValueN(data, "metadata", "namespace").(string)
@ -322,9 +325,11 @@ func (s *Store) Create(apiContext *types.APIContext, schema *types.Schema, data
return result, err
}
func (s *Store) toInternal(mapper types.Mapper, data map[string]interface{}) {
func (s *Store) toInternal(mapper types.Mapper, data map[string]interface{}) error {
if mapper != nil {
mapper.ToInternal(data)
if err := mapper.ToInternal(data); err != nil {
return err
}
}
if s.group == "" {
@ -333,37 +338,52 @@ func (s *Store) toInternal(mapper types.Mapper, data map[string]interface{}) {
data["apiVersion"] = s.group + "/" + s.version
}
data["kind"] = s.kind
return nil
}
func (s *Store) Update(apiContext *types.APIContext, schema *types.Schema, data map[string]interface{}, id string) (map[string]interface{}, error) {
var (
result map[string]interface{}
err error
)
k8sClient, err := s.k8sClient(apiContext)
if err != nil {
return nil, err
}
namespace, id := splitID(id)
req := s.common(namespace, k8sClient.Get()).
Name(id)
resourceVersion, existing, err := s.singleResultRaw(apiContext, schema, req)
if err != nil {
return data, nil
if err := s.toInternal(schema.Mapper, data); err != nil {
return nil, err
}
s.toInternal(schema.Mapper, data)
existing = merge.APIUpdateMerge(schema.InternalSchema, apiContext.Schemas, existing, data, apiContext.Query.Get("_replace") == "true")
for i := 0; i < 5; i++ {
req := s.common(namespace, k8sClient.Get()).
Name(id)
values.PutValue(existing, resourceVersion, "metadata", "resourceVersion")
values.PutValue(existing, namespace, "metadata", "namespace")
values.PutValue(existing, id, "metadata", "name")
resourceVersion, existing, rawErr := s.singleResultRaw(apiContext, schema, req)
if rawErr != nil {
return nil, rawErr
}
req = s.common(namespace, k8sClient.Put()).
Body(&unstructured.Unstructured{
Object: existing,
}).
Name(id)
existing = merge.APIUpdateMerge(schema.InternalSchema, apiContext.Schemas, existing, data, apiContext.Option("replace") == "true")
values.PutValue(existing, resourceVersion, "metadata", "resourceVersion")
values.PutValue(existing, namespace, "metadata", "namespace")
values.PutValue(existing, id, "metadata", "name")
req = s.common(namespace, k8sClient.Put()).
Body(&unstructured.Unstructured{
Object: existing,
}).
Name(id)
_, result, err = s.singleResult(apiContext, schema, req)
if errors.IsConflict(err) {
continue
}
}
_, result, err := s.singleResult(apiContext, schema, req)
return result, err
}

View File

@ -11,7 +11,9 @@ func InternalToInternal(from interface{}, fromSchema *types.Schema, toSchema *ty
return err
}
fromSchema.Mapper.FromInternal(data)
toSchema.Mapper.ToInternal(data)
if err := toSchema.Mapper.ToInternal(data); err != nil {
return err
}
return convert.ToObj(data, target)
}
@ -20,6 +22,8 @@ func ToInternal(from interface{}, schema *types.Schema, target interface{}) erro
if err != nil {
return err
}
schema.Mapper.ToInternal(data)
if err := schema.Mapper.ToInternal(data); err != nil {
return err
}
return convert.ToObj(data, target)
}

View File

@ -10,7 +10,7 @@ import (
type Mapper interface {
FromInternal(data map[string]interface{})
ToInternal(data map[string]interface{})
ToInternal(data map[string]interface{}) error
ModifySchema(schema *Schema, schemas *Schemas) error
}
@ -22,10 +22,12 @@ func (m Mappers) FromInternal(data map[string]interface{}) {
}
}
func (m Mappers) ToInternal(data map[string]interface{}) {
func (m Mappers) ToInternal(data map[string]interface{}) error {
var errors []error
for i := len(m) - 1; i >= 0; i-- {
m[i].ToInternal(data)
errors = append(errors, m[i].ToInternal(data))
}
return NewErrors(errors...)
}
func (m Mappers) ModifySchema(schema *Schema, schemas *Schemas) error {
@ -43,6 +45,7 @@ type typeMapper struct {
typeName string
subSchemas map[string]*Schema
subArraySchemas map[string]*Schema
subMapSchemas map[string]*Schema
}
func (t *typeMapper) FromInternal(data map[string]interface{}) {
@ -57,6 +60,17 @@ func (t *typeMapper) FromInternal(data map[string]interface{}) {
schema.Mapper.FromInternal(fieldData)
}
for fieldName, schema := range t.subMapSchemas {
if schema.Mapper == nil {
continue
}
datas, _ := data[fieldName].(map[string]interface{})
for _, fieldData := range datas {
mapFieldData, _ := fieldData.(map[string]interface{})
schema.Mapper.FromInternal(mapFieldData)
}
}
for fieldName, schema := range t.subArraySchemas {
if schema.Mapper == nil {
continue
@ -68,12 +82,12 @@ func (t *typeMapper) FromInternal(data map[string]interface{}) {
}
}
Mappers(t.Mappers).FromInternal(data)
if _, ok := data["type"]; !ok && data != nil {
data["type"] = t.typeName
}
Mappers(t.Mappers).FromInternal(data)
if data != nil && t.root {
if _, ok := data["id"]; ok {
if namespace != "" {
@ -92,8 +106,9 @@ func (t *typeMapper) FromInternal(data map[string]interface{}) {
}
}
func (t *typeMapper) ToInternal(data map[string]interface{}) {
Mappers(t.Mappers).ToInternal(data)
func (t *typeMapper) ToInternal(data map[string]interface{}) error {
errors := Errors{}
errors.Add(Mappers(t.Mappers).ToInternal(data))
for fieldName, schema := range t.subArraySchemas {
if schema.Mapper == nil {
@ -101,7 +116,17 @@ func (t *typeMapper) ToInternal(data map[string]interface{}) {
}
datas, _ := data[fieldName].([]interface{})
for _, fieldData := range datas {
schema.Mapper.ToInternal(convert.ToMapInterface(fieldData))
errors.Add(schema.Mapper.ToInternal(convert.ToMapInterface(fieldData)))
}
}
for fieldName, schema := range t.subMapSchemas {
if schema.Mapper == nil {
continue
}
datas, _ := data[fieldName].(map[string]interface{})
for _, fieldData := range datas {
errors.Add(schema.Mapper.ToInternal(convert.ToMapInterface(fieldData)))
}
}
@ -110,13 +135,16 @@ func (t *typeMapper) ToInternal(data map[string]interface{}) {
continue
}
fieldData, _ := data[fieldName].(map[string]interface{})
schema.Mapper.ToInternal(fieldData)
errors.Add(schema.Mapper.ToInternal(fieldData))
}
return errors.Err()
}
func (t *typeMapper) ModifySchema(schema *Schema, schemas *Schemas) error {
t.subSchemas = map[string]*Schema{}
t.subArraySchemas = map[string]*Schema{}
t.subMapSchemas = map[string]*Schema{}
t.typeName = fmt.Sprintf("%s/schemas/%s", schema.Version.Path, schema.ID)
mapperSchema := schema
@ -129,6 +157,9 @@ func (t *typeMapper) ModifySchema(schema *Schema, schemas *Schemas) error {
if definition.IsArrayType(fieldType) {
fieldType = definition.SubType(fieldType)
targetMap = t.subArraySchemas
} else if definition.IsMapType(fieldType) {
fieldType = definition.SubType(fieldType)
targetMap = t.subMapSchemas
}
schema := schemas.Schema(&schema.Version, fieldType)

View File

@ -13,7 +13,8 @@ type Access struct {
func (e Access) FromInternal(data map[string]interface{}) {
}
func (e Access) ToInternal(data map[string]interface{}) {
func (e Access) ToInternal(data map[string]interface{}) error {
return nil
}
func (e Access) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {

View File

@ -36,7 +36,7 @@ func (e AnnotationField) FromInternal(data map[string]interface{}) {
}
}
func (e AnnotationField) ToInternal(data map[string]interface{}) {
func (e AnnotationField) ToInternal(data map[string]interface{}) error {
v, ok := data[e.Field]
if ok {
if e.Object || e.List {
@ -47,6 +47,7 @@ func (e AnnotationField) ToInternal(data map[string]interface{}) {
values.PutValue(data, convert.ToString(v), "annotations", "field.cattle.io/"+e.Field)
}
values.RemoveValue(data, e.Field)
return nil
}
func (e AnnotationField) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {

35
types/mapper/apigroup.go Normal file
View File

@ -0,0 +1,35 @@
package mapper
import (
"github.com/rancher/norman/types"
"github.com/rancher/norman/types/convert"
)
type APIGroup struct {
apiVersion string
kind string
}
func (a *APIGroup) FromInternal(data map[string]interface{}) {
}
func (a *APIGroup) ToInternal(data map[string]interface{}) error {
_, ok := data["apiVersion"]
if !ok && data != nil {
data["apiVersion"] = a.apiVersion
}
_, ok = data["kind"]
if !ok && data != nil {
data["kind"] = a.kind
}
return nil
}
func (a *APIGroup) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {
a.apiVersion = schema.Version.Group + "/" + schema.Version.Version
a.kind = convert.Capitalize(schema.ID)
return nil
}

View File

@ -31,16 +31,18 @@ func (m Base64) FromInternal(data map[string]interface{}) {
}
}
func (m Base64) ToInternal(data map[string]interface{}) {
func (m Base64) ToInternal(data map[string]interface{}) error {
if v, ok := values.RemoveValue(data, strings.Split(m.Field, m.getSep())...); ok {
str := convert.ToString(v)
if str == "" {
return
return nil
}
newData := base64.StdEncoding.EncodeToString([]byte(str))
values.PutValue(data, newData, strings.Split(m.Field, m.getSep())...)
}
return nil
}
func (m Base64) ModifySchema(s *types.Schema, schemas *types.Schemas) error {

View File

@ -20,10 +20,12 @@ func (b *BatchMove) FromInternal(data map[string]interface{}) {
}
}
func (b *BatchMove) ToInternal(data map[string]interface{}) {
func (b *BatchMove) ToInternal(data map[string]interface{}) error {
errors := types.Errors{}
for i := len(b.moves) - 1; i >= 0; i-- {
b.moves[i].ToInternal(data)
errors.Add(b.moves[i].ToInternal(data))
}
return errors.Err()
}
func (b *BatchMove) ModifySchema(s *types.Schema, schemas *types.Schemas) error {

View File

@ -12,7 +12,8 @@ type ChangeType struct {
func (c ChangeType) FromInternal(data map[string]interface{}) {
}
func (c ChangeType) ToInternal(data map[string]interface{}) {
func (c ChangeType) ToInternal(data map[string]interface{}) error {
return nil
}
func (c ChangeType) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {

View File

@ -16,10 +16,11 @@ func (m Condition) FromInternal(data map[string]interface{}) {
}
}
func (m Condition) ToInternal(data map[string]interface{}) {
func (m Condition) ToInternal(data map[string]interface{}) error {
if data[m.Field] == m.Value {
m.Mapper.ToInternal(data)
return m.Mapper.ToInternal(data)
}
return nil
}
func (m Condition) ModifySchema(s *types.Schema, schemas *types.Schemas) error {

View File

@ -20,15 +20,17 @@ func (c Copy) FromInternal(data map[string]interface{}) {
}
}
func (c Copy) ToInternal(data map[string]interface{}) {
func (c Copy) ToInternal(data map[string]interface{}) error {
if data == nil {
return
return nil
}
t, tok := data[c.To]
_, fok := data[c.From]
if tok && !fok {
data[c.From] = t
}
return nil
}
func (c Copy) ModifySchema(s *types.Schema, schemas *types.Schemas) error {

View File

@ -20,8 +20,8 @@ func (d DisplayName) FromInternal(data map[string]interface{}) {
displayNameMappers.FromInternal(data)
}
func (d DisplayName) ToInternal(data map[string]interface{}) {
displayNameMappers.ToInternal(data)
func (d DisplayName) ToInternal(data map[string]interface{}) error {
return displayNameMappers.ToInternal(data)
}
func (d DisplayName) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {

View File

@ -15,7 +15,8 @@ func (d Drop) FromInternal(data map[string]interface{}) {
delete(data, d.Field)
}
func (d Drop) ToInternal(data map[string]interface{}) {
func (d Drop) ToInternal(data map[string]interface{}) error {
return nil
}
func (d Drop) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {

View File

@ -26,9 +26,9 @@ func (e *Embed) FromInternal(data map[string]interface{}) {
delete(data, e.Field)
}
func (e *Embed) ToInternal(data map[string]interface{}) {
func (e *Embed) ToInternal(data map[string]interface{}) error {
if data == nil {
return
return nil
}
sub := map[string]interface{}{}
@ -43,9 +43,10 @@ func (e *Embed) ToInternal(data map[string]interface{}) {
if e.EmptyValueOk {
data[e.Field] = nil
}
return
return nil
}
data[e.Field] = sub
return nil
}
func (e *Embed) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {

View File

@ -12,7 +12,8 @@ type Enum struct {
func (e Enum) FromInternal(data map[string]interface{}) {
}
func (e Enum) ToInternal(data map[string]interface{}) {
func (e Enum) ToInternal(data map[string]interface{}) error {
return nil
}
func (e Enum) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {

View File

@ -27,12 +27,13 @@ func (m JSONEncode) FromInternal(data map[string]interface{}) {
}
}
func (m JSONEncode) ToInternal(data map[string]interface{}) {
func (m JSONEncode) ToInternal(data map[string]interface{}) error {
if v, ok := values.RemoveValue(data, strings.Split(m.Field, m.getSep())...); ok && v != nil {
if bytes, err := json.Marshal(v); err == nil {
values.PutValue(data, string(bytes), strings.Split(m.Field, m.getSep())...)
}
}
return nil
}
func (m JSONEncode) getSep() string {

View File

@ -16,11 +16,12 @@ func (e LabelField) FromInternal(data map[string]interface{}) {
}
}
func (e LabelField) ToInternal(data map[string]interface{}) {
func (e LabelField) ToInternal(data map[string]interface{}) error {
v, ok := data[e.Field]
if ok {
values.PutValue(data, v, "labels", "field.cattle.io/"+e.Field)
}
return nil
}
func (e LabelField) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {

View File

@ -23,10 +23,11 @@ func (m Move) FromInternal(data map[string]interface{}) {
}
}
func (m Move) ToInternal(data map[string]interface{}) {
func (m Move) ToInternal(data map[string]interface{}) error {
if v, ok := values.RemoveValue(data, strings.Split(m.To, "/")...); ok {
values.PutValue(data, v, strings.Split(m.From, "/")...)
}
return nil
}
func (m Move) ModifySchema(s *types.Schema, schemas *types.Schemas) error {

View File

@ -11,6 +11,7 @@ type Object struct {
func NewObject(mappers ...types.Mapper) Object {
return Object{
Mappers: append([]types.Mapper{
&APIGroup{},
&Embed{Field: "metadata"},
&Embed{Field: "spec", Optional: true},
&ReadOnly{Field: "status", Optional: true, SubFields: true},

View File

@ -13,7 +13,8 @@ type ReadOnly struct {
func (r ReadOnly) FromInternal(data map[string]interface{}) {
}
func (r ReadOnly) ToInternal(data map[string]interface{}) {
func (r ReadOnly) ToInternal(data map[string]interface{}) error {
return nil
}
func (r ReadOnly) readOnly(field types.Field, schema *types.Schema, schemas *types.Schemas) types.Field {

View File

@ -17,10 +17,11 @@ func (r *RenameReference) FromInternal(data map[string]interface{}) {
}
}
func (r *RenameReference) ToInternal(data map[string]interface{}) {
func (r *RenameReference) ToInternal(data map[string]interface{}) error {
if r.mapper != nil {
r.mapper.ToInternal(data)
return r.mapper.ToInternal(data)
}
return nil
}
func (r *RenameReference) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {

View File

@ -11,7 +11,8 @@ type Required struct {
func (e Required) FromInternal(data map[string]interface{}) {
}
func (e Required) ToInternal(data map[string]interface{}) {
func (e Required) ToInternal(data map[string]interface{}) error {
return nil
}
func (e Required) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {

View File

@ -17,10 +17,11 @@ func (s *Scope) FromInternal(data map[string]interface{}) {
}
}
func (s *Scope) ToInternal(data map[string]interface{}) {
func (s *Scope) ToInternal(data map[string]interface{}) error {
if s.run {
types.Mappers(s.Mappers).ToInternal(data)
return types.Mappers(s.Mappers).ToInternal(data)
}
return nil
}
func (s *Scope) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {

View File

@ -39,10 +39,10 @@ func (s SetValue) getTo() string {
return s.To
}
func (s SetValue) ToInternal(data map[string]interface{}) {
func (s SetValue) ToInternal(data map[string]interface{}) error {
v, ok := values.GetValue(data, strings.Split(s.getTo(), "/")...)
if !ok {
return
return nil
}
if s.IfEq == nil {
@ -50,6 +50,8 @@ func (s SetValue) ToInternal(data map[string]interface{}) {
} else if v == s.Value {
values.PutValue(data, s.IfEq, strings.Split(s.Field, "/")...)
}
return nil
}
func (s SetValue) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {

View File

@ -26,7 +26,8 @@ func (s SliceMerge) FromInternal(data map[string]interface{}) {
}
}
func (s SliceMerge) ToInternal(data map[string]interface{}) {
func (s SliceMerge) ToInternal(data map[string]interface{}) error {
return nil
}
func (s SliceMerge) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {

View File

@ -29,7 +29,7 @@ func (s SliceToMap) FromInternal(data map[string]interface{}) {
}
}
func (s SliceToMap) ToInternal(data map[string]interface{}) {
func (s SliceToMap) ToInternal(data map[string]interface{}) error {
datas, _ := data[s.Field].(map[string]interface{})
var result []interface{}
@ -46,6 +46,8 @@ func (s SliceToMap) ToInternal(data map[string]interface{}) {
} else if datas != nil {
data[s.Field] = result
}
return nil
}
func (s SliceToMap) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {

View File

@ -23,7 +23,7 @@ func (u *UnionEmbed) FromInternal(data map[string]interface{}) {
}
}
func (u *UnionEmbed) ToInternal(data map[string]interface{}) {
func (u *UnionEmbed) ToInternal(data map[string]interface{}) error {
outer:
for _, mapper := range u.Fields {
if len(mapper.CheckFields) == 0 {
@ -38,9 +38,10 @@ outer:
}
embed := u.embeds[mapper.FieldName]
embed.ToInternal(data)
return
return embed.ToInternal(data)
}
return nil
}
func (u *UnionEmbed) ModifySchema(schema *types.Schema, schemas *types.Schemas) error {

View File

@ -18,10 +18,12 @@ func (m UntypedMove) FromInternal(data map[string]interface{}) {
}
}
func (m UntypedMove) ToInternal(data map[string]interface{}) {
func (m UntypedMove) ToInternal(data map[string]interface{}) error {
if v, ok := values.RemoveValue(data, strings.Split(m.To, m.getSep())...); ok {
values.PutValue(data, v, strings.Split(m.From, m.getSep())...)
}
return nil
}
func (m UntypedMove) getSep() string {