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:
Clayton Coleman
2015-04-28 23:15:16 -04:00
parent a4316aa638
commit 12ba4e2452
20 changed files with 391 additions and 61 deletions

View File

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