Do not automatically decode runtime.RawExtension
Make clients opt in to decoding objects that are stored in the generic api.List object by invoking runtime.DecodeList() with a set of schemes. Makes it easier to handle unknown schema objects because decoding is in the control of the code. Add runtime.Unstructured, which is a simple in memory representation of an external object.
This commit is contained in:
@@ -23,7 +23,7 @@ import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
|
||||
)
|
||||
|
||||
// TODO: move me to pkg/api/meta
|
||||
// IsListType returns true if the provided Object has a slice called Items
|
||||
func IsListType(obj Object) bool {
|
||||
_, err := GetItemsPtr(obj)
|
||||
return err == nil
|
||||
@@ -33,7 +33,6 @@ func IsListType(obj Object) bool {
|
||||
// If 'list' doesn't have an Items member, it's not really a list type
|
||||
// and an error will be returned.
|
||||
// This function will either return a pointer to a slice, or an error, but not both.
|
||||
// TODO: move me to pkg/api/meta
|
||||
func GetItemsPtr(list Object) (interface{}, error) {
|
||||
v, err := conversion.EnforcePtr(list)
|
||||
if err != nil {
|
||||
@@ -150,9 +149,36 @@ func FieldPtr(v reflect.Value, fieldName string, dest interface{}) error {
|
||||
return fmt.Errorf("couldn't assign/convert %v to %v", field.Type(), v.Type())
|
||||
}
|
||||
|
||||
// DecodeList alters the list in place, attempting to decode any objects found in
|
||||
// the list that have the runtime.Unknown type. Any errors that occur are returned
|
||||
// after the entire list is processed. Decoders are tried in order.
|
||||
func DecodeList(objects []Object, decoders ...ObjectDecoder) []error {
|
||||
errs := []error(nil)
|
||||
for i, obj := range objects {
|
||||
switch t := obj.(type) {
|
||||
case *Unknown:
|
||||
for _, decoder := range decoders {
|
||||
if !decoder.Recognizes(t.APIVersion, t.Kind) {
|
||||
continue
|
||||
}
|
||||
obj, err := decoder.Decode(t.RawJSON)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
break
|
||||
}
|
||||
objects[i] = obj
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
// MultiObjectTyper returns the types of objects across multiple schemes in order.
|
||||
type MultiObjectTyper []ObjectTyper
|
||||
|
||||
var _ ObjectTyper = MultiObjectTyper{}
|
||||
|
||||
func (m MultiObjectTyper) DataVersionAndKind(data []byte) (version, kind string, err error) {
|
||||
for _, t := range m {
|
||||
version, kind, err = t.DataVersionAndKind(data)
|
||||
@@ -162,6 +188,7 @@ func (m MultiObjectTyper) DataVersionAndKind(data []byte) (version, kind string,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (m MultiObjectTyper) ObjectVersionAndKind(obj Object) (version, kind string, err error) {
|
||||
for _, t := range m {
|
||||
version, kind, err = t.ObjectVersionAndKind(obj)
|
||||
@@ -171,3 +198,12 @@ func (m MultiObjectTyper) ObjectVersionAndKind(obj Object) (version, kind string
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (m MultiObjectTyper) Recognizes(version, kind string) bool {
|
||||
for _, t := range m {
|
||||
if t.Recognizes(version, kind) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
Reference in New Issue
Block a user