mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-17 15:13:08 +00:00
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:
@@ -81,7 +81,7 @@ func ObjectReaction(o ObjectRetriever, mapper meta.RESTMapper) ReactionFunc {
|
||||
|
||||
// AddObjectsFromPath loads the JSON or YAML file containing Kubernetes API resources
|
||||
// and adds them to the provided ObjectRetriever.
|
||||
func AddObjectsFromPath(path string, o ObjectRetriever) error {
|
||||
func AddObjectsFromPath(path string, o ObjectRetriever, decoder runtime.Decoder) error {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -90,7 +90,7 @@ func AddObjectsFromPath(path string, o ObjectRetriever) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
obj, err := api.Codec.Decode(data)
|
||||
obj, err := decoder.Decode(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -103,17 +103,12 @@ func AddObjectsFromPath(path string, o ObjectRetriever) error {
|
||||
type objects struct {
|
||||
types map[string][]runtime.Object
|
||||
last map[string]int
|
||||
typer runtime.ObjectTyper
|
||||
creater runtime.ObjectCreater
|
||||
copier copier
|
||||
scheme runtime.ObjectScheme
|
||||
decoder runtime.ObjectDecoder
|
||||
}
|
||||
|
||||
var _ ObjectRetriever = &objects{}
|
||||
|
||||
type copier interface {
|
||||
Copy(obj runtime.Object) (runtime.Object, error)
|
||||
}
|
||||
|
||||
// NewObjects implements the ObjectRetriever interface by introspecting the
|
||||
// objects provided to Add() and returning them when the Kind method is invoked.
|
||||
// If an api.List object is provided to Add(), each child item is added. If an
|
||||
@@ -124,18 +119,17 @@ type copier interface {
|
||||
// as a runtime.Object if Status == Success). If multiple PodLists are provided, they
|
||||
// will be returned in order by the Kind call, and the last PodList will be reused for
|
||||
// subsequent calls.
|
||||
func NewObjects(scheme *runtime.Scheme) ObjectRetriever {
|
||||
func NewObjects(scheme runtime.ObjectScheme, decoder runtime.ObjectDecoder) ObjectRetriever {
|
||||
return objects{
|
||||
types: make(map[string][]runtime.Object),
|
||||
last: make(map[string]int),
|
||||
typer: scheme,
|
||||
creater: scheme,
|
||||
copier: scheme,
|
||||
scheme: scheme,
|
||||
decoder: decoder,
|
||||
}
|
||||
}
|
||||
|
||||
func (o objects) Kind(kind, name string) (runtime.Object, error) {
|
||||
empty, _ := o.creater.New("", kind)
|
||||
empty, _ := o.scheme.New("", kind)
|
||||
nilValue := reflect.Zero(reflect.TypeOf(empty)).Interface().(runtime.Object)
|
||||
|
||||
arr, ok := o.types[kind]
|
||||
@@ -146,14 +140,14 @@ func (o objects) Kind(kind, name string) (runtime.Object, error) {
|
||||
if !ok {
|
||||
return empty, nil
|
||||
}
|
||||
out, err := o.creater.New("", kind)
|
||||
out, err := o.scheme.New("", kind)
|
||||
if err != nil {
|
||||
return nilValue, err
|
||||
}
|
||||
if err := runtime.SetList(out, arr); err != nil {
|
||||
return nilValue, err
|
||||
}
|
||||
if out, err = o.copier.Copy(out); err != nil {
|
||||
if out, err = o.scheme.Copy(out); err != nil {
|
||||
return nilValue, err
|
||||
}
|
||||
return out, nil
|
||||
@@ -168,7 +162,7 @@ func (o objects) Kind(kind, name string) (runtime.Object, error) {
|
||||
if index < 0 {
|
||||
return nilValue, errors.NewNotFound(kind, name)
|
||||
}
|
||||
out, err := o.copier.Copy(arr[index])
|
||||
out, err := o.scheme.Copy(arr[index])
|
||||
if err != nil {
|
||||
return nilValue, err
|
||||
}
|
||||
@@ -187,7 +181,7 @@ func (o objects) Kind(kind, name string) (runtime.Object, error) {
|
||||
}
|
||||
|
||||
func (o objects) Add(obj runtime.Object) error {
|
||||
_, kind, err := o.typer.ObjectVersionAndKind(obj)
|
||||
_, kind, err := o.scheme.ObjectVersionAndKind(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -202,6 +196,9 @@ func (o objects) Add(obj runtime.Object) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if errs := runtime.DecodeList(list, o.decoder); len(errs) > 0 {
|
||||
return errs[0]
|
||||
}
|
||||
for _, obj := range list {
|
||||
if err := o.Add(obj); err != nil {
|
||||
return err
|
||||
|
@@ -27,7 +27,7 @@ import (
|
||||
|
||||
// NewSimpleFake returns a client that will respond with the provided objects
|
||||
func NewSimpleFake(objects ...runtime.Object) *Fake {
|
||||
o := NewObjects(api.Scheme)
|
||||
o := NewObjects(api.Scheme, api.Scheme)
|
||||
for _, obj := range objects {
|
||||
if err := o.Add(obj); err != nil {
|
||||
panic(err)
|
||||
|
@@ -27,8 +27,8 @@ import (
|
||||
)
|
||||
|
||||
func TestNewClient(t *testing.T) {
|
||||
o := NewObjects(api.Scheme)
|
||||
if err := AddObjectsFromPath("../../../examples/guestbook/frontend-service.json", o); err != nil {
|
||||
o := NewObjects(api.Scheme, api.Scheme)
|
||||
if err := AddObjectsFromPath("../../../examples/guestbook/frontend-service.json", o, api.Scheme); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
client := &Fake{ReactFn: ObjectReaction(o, latest.RESTMapper)}
|
||||
@@ -52,7 +52,7 @@ func TestNewClient(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestErrors(t *testing.T) {
|
||||
o := NewObjects(api.Scheme)
|
||||
o := NewObjects(api.Scheme, api.Scheme)
|
||||
o.Add(&api.List{
|
||||
Items: []runtime.Object{
|
||||
// This first call to List will return this error
|
||||
|
Reference in New Issue
Block a user