1
0
mirror of https://github.com/rancher/types.git synced 2025-09-03 22:24:38 +00:00

Update norman

This commit is contained in:
Darren Shepherd
2017-11-14 21:48:51 -07:00
parent 9e7d8a838a
commit 85da50f4b0
42 changed files with 13955 additions and 34 deletions

View File

@@ -35,6 +35,13 @@ func NewObjectClient(namespace string, restClient rest.Interface, apiResource *m
}
}
func (p *ObjectClient) getAPIPrefix() string {
if p.gvk.Group == "" {
return "api"
}
return "apis"
}
func (p *ObjectClient) Create(o runtime.Object) (runtime.Object, error) {
ns := p.ns
if obj, ok := o.(metav1.Object); ok && obj.GetNamespace() != "" {
@@ -42,7 +49,7 @@ func (p *ObjectClient) Create(o runtime.Object) (runtime.Object, error) {
}
result := p.Factory.Object()
err := p.restClient.Post().
Prefix("apis", p.gvk.Group, p.gvk.Version).
Prefix(p.getAPIPrefix(), p.gvk.Group, p.gvk.Version).
NamespaceIfScoped(ns, p.resource.Namespaced).
Resource(p.resource.Name).
Body(o).
@@ -54,7 +61,7 @@ func (p *ObjectClient) Create(o runtime.Object) (runtime.Object, error) {
func (p *ObjectClient) Get(name string, opts metav1.GetOptions) (runtime.Object, error) {
result := p.Factory.Object()
err := p.restClient.Get().
Prefix("apis", p.gvk.Group, p.gvk.Version).
Prefix(p.getAPIPrefix(), p.gvk.Group, p.gvk.Version).
NamespaceIfScoped(p.ns, p.resource.Namespaced).
Resource(p.resource.Name).
VersionedParams(&opts, dynamic.VersionedParameterEncoderWithV1Fallback).
@@ -74,7 +81,7 @@ func (p *ObjectClient) Update(name string, o runtime.Object) (runtime.Object, er
return result, errors.New("object missing name")
}
err := p.restClient.Put().
Prefix("apis", p.gvk.Group, p.gvk.Version).
Prefix(p.getAPIPrefix(), p.gvk.Group, p.gvk.Version).
NamespaceIfScoped(ns, p.resource.Namespaced).
Resource(p.resource.Name).
Name(name).
@@ -86,7 +93,7 @@ func (p *ObjectClient) Update(name string, o runtime.Object) (runtime.Object, er
func (p *ObjectClient) Delete(name string, opts *metav1.DeleteOptions) error {
return p.restClient.Delete().
Prefix("apis", p.gvk.Group, p.gvk.Version).
Prefix(p.getAPIPrefix(), p.gvk.Group, p.gvk.Version).
NamespaceIfScoped(p.ns, p.resource.Namespaced).
Resource(p.resource.Name).
Name(name).
@@ -98,7 +105,7 @@ func (p *ObjectClient) Delete(name string, opts *metav1.DeleteOptions) error {
func (p *ObjectClient) List(opts metav1.ListOptions) (runtime.Object, error) {
result := p.Factory.List()
return result, p.restClient.Get().
Prefix("apis", p.gvk.Group, p.gvk.Version).
Prefix(p.getAPIPrefix(), p.gvk.Group, p.gvk.Version).
NamespaceIfScoped(p.ns, p.resource.Namespaced).
Resource(p.resource.Name).
VersionedParams(&opts, dynamic.VersionedParameterEncoderWithV1Fallback).
@@ -108,7 +115,7 @@ func (p *ObjectClient) List(opts metav1.ListOptions) (runtime.Object, error) {
func (p *ObjectClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
r, err := p.restClient.Get().
Prefix("apis", p.gvk.Group, p.gvk.Version).
Prefix(p.getAPIPrefix(), p.gvk.Group, p.gvk.Version).
Prefix("watch").
Namespace(p.ns).
NamespaceIfScoped(p.ns, p.resource.Namespaced).
@@ -127,7 +134,7 @@ func (p *ObjectClient) Watch(opts metav1.ListOptions) (watch.Interface, error) {
func (p *ObjectClient) DeleteCollection(deleteOptions *metav1.DeleteOptions, listOptions metav1.ListOptions) error {
return p.restClient.Delete().
Prefix("apis", p.gvk.Group, p.gvk.Version).
Prefix(p.getAPIPrefix(), p.gvk.Group, p.gvk.Version).
NamespaceIfScoped(p.ns, p.resource.Namespaced).
Resource(p.resource.Name).
VersionedParams(&listOptions, dynamic.VersionedParameterEncoderWithV1Fallback).

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

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