mirror of
https://github.com/rancher/norman.git
synced 2025-06-29 16:58:05 +00:00
179 lines
4.3 KiB
Go
179 lines
4.3 KiB
Go
package types
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/rancher/norman/types/convert"
|
|
"github.com/rancher/norman/types/definition"
|
|
"github.com/rancher/norman/types/values"
|
|
)
|
|
|
|
type Mapper interface {
|
|
FromInternal(data map[string]interface{})
|
|
ToInternal(data map[string]interface{}) error
|
|
ModifySchema(schema *Schema, schemas *Schemas) error
|
|
}
|
|
|
|
type Mappers []Mapper
|
|
|
|
func (m Mappers) FromInternal(data map[string]interface{}) {
|
|
for _, mapper := range m {
|
|
mapper.FromInternal(data)
|
|
}
|
|
}
|
|
|
|
func (m Mappers) ToInternal(data map[string]interface{}) error {
|
|
var errors []error
|
|
for i := len(m) - 1; i >= 0; i-- {
|
|
errors = append(errors, m[i].ToInternal(data))
|
|
}
|
|
return NewErrors(errors...)
|
|
}
|
|
|
|
func (m Mappers) ModifySchema(schema *Schema, schemas *Schemas) error {
|
|
for _, mapper := range m {
|
|
if err := mapper.ModifySchema(schema, schemas); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
type typeMapper struct {
|
|
Mappers []Mapper
|
|
root bool
|
|
typeName string
|
|
subSchemas map[string]*Schema
|
|
subArraySchemas map[string]*Schema
|
|
subMapSchemas map[string]*Schema
|
|
}
|
|
|
|
func (t *typeMapper) FromInternal(data map[string]interface{}) {
|
|
name, _ := values.GetValueN(data, "metadata", "name").(string)
|
|
namespace, _ := values.GetValueN(data, "metadata", "namespace").(string)
|
|
|
|
for fieldName, schema := range t.subSchemas {
|
|
if schema.Mapper == nil {
|
|
continue
|
|
}
|
|
fieldData, _ := data[fieldName].(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
|
|
}
|
|
datas, _ := data[fieldName].([]interface{})
|
|
for _, fieldData := range datas {
|
|
mapFieldData, _ := fieldData.(map[string]interface{})
|
|
schema.Mapper.FromInternal(mapFieldData)
|
|
}
|
|
}
|
|
|
|
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 != "" {
|
|
id, _ := data["id"].(string)
|
|
data["id"] = namespace + ":" + id
|
|
}
|
|
} else {
|
|
if name != "" {
|
|
if namespace == "" {
|
|
data["id"] = name
|
|
} else {
|
|
data["id"] = namespace + ":" + name
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if _, ok := data["type"]; !ok && data != nil {
|
|
if _, ok := data["id"]; ok {
|
|
data["type"] = t.typeName
|
|
}
|
|
}
|
|
}
|
|
|
|
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 {
|
|
continue
|
|
}
|
|
datas, _ := data[fieldName].([]interface{})
|
|
for _, fieldData := range datas {
|
|
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)))
|
|
}
|
|
}
|
|
|
|
for fieldName, schema := range t.subSchemas {
|
|
if schema.Mapper == nil {
|
|
continue
|
|
}
|
|
fieldData, _ := data[fieldName].(map[string]interface{})
|
|
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
|
|
if schema.InternalSchema != nil {
|
|
mapperSchema = schema.InternalSchema
|
|
}
|
|
for name, field := range mapperSchema.ResourceFields {
|
|
fieldType := field.Type
|
|
targetMap := t.subSchemas
|
|
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)
|
|
if schema != nil {
|
|
targetMap[name] = schema
|
|
}
|
|
}
|
|
|
|
return Mappers(t.Mappers).ModifySchema(schema, schemas)
|
|
}
|