github.com/rancher/types@v0.0.0-20220328215343-4370ff10ecd5/mapper/namespace_reference.go (about) 1 package mapper 2 3 import ( 4 "strings" 5 6 "fmt" 7 8 "github.com/rancher/norman/types" 9 "github.com/rancher/norman/types/convert" 10 "github.com/rancher/norman/types/definition" 11 ) 12 13 type NamespaceReference struct { 14 fields [][]string 15 VersionPath string 16 } 17 18 func (n *NamespaceReference) FromInternal(data map[string]interface{}) { 19 namespaceID, ok := data["namespaceId"] 20 if ok { 21 for _, path := range n.fields { 22 convert.Transform(data, path, func(input interface{}) interface{} { 23 parts := strings.SplitN(convert.ToString(input), ":", 2) 24 if len(parts) == 2 { 25 return input 26 } 27 return fmt.Sprintf("%s:%v", namespaceID, input) 28 }) 29 } 30 } 31 } 32 33 func (n *NamespaceReference) ToInternal(data map[string]interface{}) error { 34 namespaceID, ok := data["namespaceId"] 35 for _, path := range n.fields { 36 convert.Transform(data, path, func(input interface{}) interface{} { 37 parts := strings.SplitN(convert.ToString(input), ":", 2) 38 if len(parts) == 2 && (!ok || parts[0] == namespaceID) { 39 return parts[1] 40 } 41 return input 42 }) 43 } 44 45 return nil 46 } 47 48 func (n *NamespaceReference) ModifySchema(schema *types.Schema, schemas *types.Schemas) error { 49 _, hasNamespace := schema.ResourceFields["namespaceId"] 50 if schema.Version.Path != n.VersionPath || !hasNamespace { 51 return nil 52 } 53 n.fields = traverse(nil, schema, schemas) 54 return nil 55 } 56 57 func traverse(prefix []string, schema *types.Schema, schemas *types.Schemas) [][]string { 58 var result [][]string 59 60 for name, field := range schema.ResourceFields { 61 localPrefix := []string{name} 62 subType := field.Type 63 if definition.IsArrayType(field.Type) { 64 localPrefix = append(localPrefix, "{ARRAY}") 65 subType = definition.SubType(field.Type) 66 } else if definition.IsMapType(field.Type) { 67 localPrefix = append(localPrefix, "{MAP}") 68 subType = definition.SubType(field.Type) 69 } 70 if definition.IsReferenceType(subType) { 71 result = appendReference(result, prefix, localPrefix, field, schema, schemas) 72 continue 73 } 74 75 subSchema := schemas.Schema(&schema.Version, subType) 76 if subSchema != nil { 77 result = append(result, traverse(append(prefix, localPrefix...), subSchema, schemas)...) 78 } 79 } 80 81 return result 82 } 83 84 func appendReference(result [][]string, prefix []string, name []string, field types.Field, schema *types.Schema, schemas *types.Schemas) [][]string { 85 targetSchema := schemas.Schema(&schema.Version, definition.SubType(field.Type)) 86 if targetSchema != nil && targetSchema.Scope == types.NamespaceScope { 87 result = append(result, append(prefix, name...)) 88 } 89 return result 90 }