diff --git a/pkg/api/meta/help.go b/pkg/api/meta/help.go index 97b6c2ce6c3..a1255a0942b 100644 --- a/pkg/api/meta/help.go +++ b/pkg/api/meta/help.go @@ -20,19 +20,16 @@ import ( "fmt" "reflect" - "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" "k8s.io/kubernetes/pkg/conversion" "k8s.io/kubernetes/pkg/runtime" ) // IsListType returns true if the provided Object has a slice called Items func IsListType(obj runtime.Object) bool { - // if we're a runtime.Unstructured, check to see if we have an `items` key - // This is a list type for recognition, but other Items type methods will fail on it - // and give you errors. - if unstructured, ok := obj.(*unstructured.Unstructured); ok { - _, ok := unstructured.Object["items"] - return ok + // if we're a runtime.Unstructured, check whether this is a list. + // TODO: refactor GetItemsPtr to use an interface that returns []runtime.Object + if unstructured, ok := obj.(runtime.Unstructured); ok { + return unstructured.IsList() } _, err := GetItemsPtr(obj) diff --git a/pkg/api/meta/help_test.go b/pkg/api/meta/help_test.go index 4bc42aafde4..0a8b107cca1 100644 --- a/pkg/api/meta/help_test.go +++ b/pkg/api/meta/help_test.go @@ -23,6 +23,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/v1" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime/schema" "k8s.io/kubernetes/pkg/util/diff" @@ -300,11 +301,11 @@ func TestSetListToRuntimeObjectArray(t *testing.T) { } func TestSetListToMatchingType(t *testing.T) { - pl := &runtime.UnstructuredList{} + pl := &unstructured.UnstructuredList{} list := []runtime.Object{ - &runtime.Unstructured{Object: map[string]interface{}{"foo": 1}}, - &runtime.Unstructured{Object: map[string]interface{}{"foo": 2}}, - &runtime.Unstructured{Object: map[string]interface{}{"foo": 3}}, + &unstructured.Unstructured{Object: map[string]interface{}{"foo": 1}}, + &unstructured.Unstructured{Object: map[string]interface{}{"foo": 2}}, + &unstructured.Unstructured{Object: map[string]interface{}{"foo": 3}}, } err := meta.SetList(pl, list) if err != nil { diff --git a/pkg/api/meta/unstructured.go b/pkg/api/meta/unstructured.go index 02cafdedd48..30b6dc881d4 100644 --- a/pkg/api/meta/unstructured.go +++ b/pkg/api/meta/unstructured.go @@ -22,7 +22,7 @@ import ( ) // InterfacesForUnstructured returns VersionInterfaces suitable for -// dealing with runtime.Unstructured objects. +// dealing with unstructured.Unstructured objects. func InterfacesForUnstructured(schema.GroupVersion) (*VersionInterfaces, error) { return &VersionInterfaces{ ObjectConvertor: &unstructured.UnstructuredObjectConverter{}, diff --git a/pkg/api/validation/schema.go b/pkg/api/validation/schema.go index f694baeaeb2..a33904759db 100644 --- a/pkg/api/validation/schema.go +++ b/pkg/api/validation/schema.go @@ -28,7 +28,7 @@ import ( ejson "github.com/exponent-io/jsonpath" "github.com/golang/glog" apiutil "k8s.io/kubernetes/pkg/api/util" - "k8s.io/kubernetes/pkg/runtime" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" utilerrors "k8s.io/kubernetes/pkg/util/errors" "k8s.io/kubernetes/pkg/util/yaml" ) @@ -255,7 +255,7 @@ func (s *SwaggerSchema) ValidateObject(obj interface{}, fieldName, typeName stri if !mapOk { return append(allErrs, fmt.Errorf("field %s: expected object of type map[string]interface{}, but the actual type is %T", fieldName, obj)) } - if delegated, err := s.delegateIfDifferentApiVersion(runtime.Unstructured{Object: fields}); delegated { + if delegated, err := s.delegateIfDifferentApiVersion(&unstructured.Unstructured{Object: fields}); delegated { if err != nil { allErrs = append(allErrs, err) } @@ -326,7 +326,7 @@ func (s *SwaggerSchema) ValidateObject(obj interface{}, fieldName, typeName stri // current SwaggerSchema. // First return value is true if the validation was delegated (by a different ApiGroup SwaggerSchema) // Second return value is the result of the delegated validation if performed. -func (s *SwaggerSchema) delegateIfDifferentApiVersion(obj runtime.Unstructured) (bool, error) { +func (s *SwaggerSchema) delegateIfDifferentApiVersion(obj *unstructured.Unstructured) (bool, error) { // Never delegate objects in the same ApiVersion or we will get infinite recursion if !s.isDifferentApiVersion(obj) { return false, nil @@ -344,7 +344,7 @@ func (s *SwaggerSchema) delegateIfDifferentApiVersion(obj runtime.Unstructured) // isDifferentApiVersion Returns true if obj lives in a different ApiVersion than the SwaggerSchema does. // The SwaggerSchema will not be able to process objects in different ApiVersions unless they are vendored. -func (s *SwaggerSchema) isDifferentApiVersion(obj runtime.Unstructured) bool { +func (s *SwaggerSchema) isDifferentApiVersion(obj *unstructured.Unstructured) bool { groupVersion := obj.GetAPIVersion() return len(groupVersion) > 0 && s.api.ApiVersion != groupVersion } diff --git a/pkg/client/typed/discovery/unstructured.go b/pkg/client/typed/discovery/unstructured.go index bd886e5ef1b..5d791047a22 100644 --- a/pkg/client/typed/discovery/unstructured.go +++ b/pkg/client/typed/discovery/unstructured.go @@ -50,10 +50,10 @@ func NewUnstructuredObjectTyper(groupResources []*APIGroupResources) *Unstructur } // ObjectKind returns the group,version,kind of the provided object, or an error -// if the object in not *runtime.Unstructured or has no group,version,kind +// if the object in not runtime.Unstructured or has no group,version,kind // information. func (d *UnstructuredObjectTyper) ObjectKind(obj runtime.Object) (schema.GroupVersionKind, error) { - if _, ok := obj.(*runtime.Unstructured); !ok { + if _, ok := obj.(runtime.Unstructured); !ok { return schema.GroupVersionKind{}, fmt.Errorf("type %T is invalid for dynamic object typer", obj) } @@ -61,7 +61,7 @@ func (d *UnstructuredObjectTyper) ObjectKind(obj runtime.Object) (schema.GroupVe } // ObjectKinds returns a slice of one element with the group,version,kind of the -// provided object, or an error if the object is not *runtime.Unstructured or +// provided object, or an error if the object is not runtime.Unstructured or // has no group,version,kind information. unversionedType will always be false // because runtime.Unstructured object should always have group,version,kind // information set. @@ -80,7 +80,7 @@ func (d *UnstructuredObjectTyper) Recognizes(gvk schema.GroupVersionKind) bool { return d.registered[gvk] } -// IsUnversioned returns false always because *runtime.Unstructured objects +// IsUnversioned returns false always because runtime.Unstructured objects // should always have group,version,kind information set. ok will be true if the // object's group,version,kind is registered. func (d *UnstructuredObjectTyper) IsUnversioned(obj runtime.Object) (unversioned bool, ok bool) { diff --git a/pkg/client/typed/dynamic/client.go b/pkg/client/typed/dynamic/client.go index d965bcbb36f..5039a988982 100644 --- a/pkg/client/typed/dynamic/client.go +++ b/pkg/client/typed/dynamic/client.go @@ -29,6 +29,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" "k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/conversion/queryparams" "k8s.io/kubernetes/pkg/runtime" @@ -124,8 +125,8 @@ func (rc *ResourceClient) List(opts runtime.Object) (runtime.Object, error) { } // Get gets the resource with the specified name. -func (rc *ResourceClient) Get(name string) (*runtime.Unstructured, error) { - result := new(runtime.Unstructured) +func (rc *ResourceClient) Get(name string) (*unstructured.Unstructured, error) { + result := new(unstructured.Unstructured) err := rc.cl.Get(). NamespaceIfScoped(rc.ns, rc.resource.Namespaced). Resource(rc.resource.Name). @@ -162,8 +163,8 @@ func (rc *ResourceClient) DeleteCollection(deleteOptions *v1.DeleteOptions, list } // Create creates the provided resource. -func (rc *ResourceClient) Create(obj *runtime.Unstructured) (*runtime.Unstructured, error) { - result := new(runtime.Unstructured) +func (rc *ResourceClient) Create(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) { + result := new(unstructured.Unstructured) err := rc.cl.Post(). NamespaceIfScoped(rc.ns, rc.resource.Namespaced). Resource(rc.resource.Name). @@ -174,8 +175,8 @@ func (rc *ResourceClient) Create(obj *runtime.Unstructured) (*runtime.Unstructur } // Update updates the provided resource. -func (rc *ResourceClient) Update(obj *runtime.Unstructured) (*runtime.Unstructured, error) { - result := new(runtime.Unstructured) +func (rc *ResourceClient) Update(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) { + result := new(unstructured.Unstructured) if len(obj.GetName()) == 0 { return result, errors.New("object missing name") } @@ -203,8 +204,8 @@ func (rc *ResourceClient) Watch(opts runtime.Object) (watch.Interface, error) { Watch() } -func (rc *ResourceClient) Patch(name string, pt api.PatchType, data []byte) (*runtime.Unstructured, error) { - result := new(runtime.Unstructured) +func (rc *ResourceClient) Patch(name string, pt api.PatchType, data []byte) (*unstructured.Unstructured, error) { + result := new(unstructured.Unstructured) err := rc.cl.Patch(pt). NamespaceIfScoped(rc.ns, rc.resource.Namespaced). Resource(rc.resource.Name). @@ -220,7 +221,7 @@ func (rc *ResourceClient) Patch(name string, pt api.PatchType, data []byte) (*ru type dynamicCodec struct{} func (dynamicCodec) Decode(data []byte, gvk *schema.GroupVersionKind, obj runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) { - obj, gvk, err := runtime.UnstructuredJSONScheme.Decode(data, gvk, obj) + obj, gvk, err := unstructured.UnstructuredJSONScheme.Decode(data, gvk, obj) if err != nil { return nil, nil, err } @@ -237,7 +238,7 @@ func (dynamicCodec) Decode(data []byte, gvk *schema.GroupVersionKind, obj runtim } func (dynamicCodec) Encode(obj runtime.Object, w io.Writer) error { - return runtime.UnstructuredJSONScheme.Encode(obj, w) + return unstructured.UnstructuredJSONScheme.Encode(obj, w) } // ContentConfig returns a restclient.ContentConfig for dynamic types. diff --git a/pkg/client/typed/dynamic/client_test.go b/pkg/client/typed/dynamic/client_test.go index 09902b92626..8b1e385251f 100644 --- a/pkg/client/typed/dynamic/client_test.go +++ b/pkg/client/typed/dynamic/client_test.go @@ -28,6 +28,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" "k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime/schema" @@ -46,8 +47,8 @@ func getListJSON(version, kind string, items ...[]byte) []byte { return []byte(json) } -func getObject(version, kind, name string) *runtime.Unstructured { - return &runtime.Unstructured{ +func getObject(version, kind, name string) *unstructured.Unstructured { + return &unstructured.Unstructured{ Object: map[string]interface{}{ "apiVersion": version, "kind": kind, @@ -77,7 +78,7 @@ func TestList(t *testing.T) { namespace string path string resp []byte - want *runtime.UnstructuredList + want *unstructured.UnstructuredList }{ { name: "normal_list", @@ -85,12 +86,12 @@ func TestList(t *testing.T) { resp: getListJSON("vTest", "rTestList", getJSON("vTest", "rTest", "item1"), getJSON("vTest", "rTest", "item2")), - want: &runtime.UnstructuredList{ + want: &unstructured.UnstructuredList{ Object: map[string]interface{}{ "apiVersion": "vTest", "kind": "rTestList", }, - Items: []*runtime.Unstructured{ + Items: []*unstructured.Unstructured{ getObject("vTest", "rTest", "item1"), getObject("vTest", "rTest", "item2"), }, @@ -103,12 +104,12 @@ func TestList(t *testing.T) { resp: getListJSON("vTest", "rTestList", getJSON("vTest", "rTest", "item1"), getJSON("vTest", "rTest", "item2")), - want: &runtime.UnstructuredList{ + want: &unstructured.UnstructuredList{ Object: map[string]interface{}{ "apiVersion": "vTest", "kind": "rTestList", }, - Items: []*runtime.Unstructured{ + Items: []*unstructured.Unstructured{ getObject("vTest", "rTest", "item1"), getObject("vTest", "rTest", "item2"), }, @@ -154,7 +155,7 @@ func TestGet(t *testing.T) { name string path string resp []byte - want *runtime.Unstructured + want *unstructured.Unstructured }{ { name: "normal_get", @@ -236,7 +237,7 @@ func TestDelete(t *testing.T) { } w.Header().Set("Content-Type", runtime.ContentTypeJSON) - runtime.UnstructuredJSONScheme.Encode(statusOK, w) + unstructured.UnstructuredJSONScheme.Encode(statusOK, w) }) if err != nil { t.Errorf("unexpected error when creating client: %v", err) @@ -285,7 +286,7 @@ func TestDeleteCollection(t *testing.T) { } w.Header().Set("Content-Type", runtime.ContentTypeJSON) - runtime.UnstructuredJSONScheme.Encode(statusOK, w) + unstructured.UnstructuredJSONScheme.Encode(statusOK, w) }) if err != nil { t.Errorf("unexpected error when creating client: %v", err) @@ -305,7 +306,7 @@ func TestCreate(t *testing.T) { tcs := []struct { name string namespace string - obj *runtime.Unstructured + obj *unstructured.Unstructured path string }{ { @@ -364,7 +365,7 @@ func TestUpdate(t *testing.T) { tcs := []struct { name string namespace string - obj *runtime.Unstructured + obj *unstructured.Unstructured path string }{ { @@ -489,7 +490,7 @@ func TestPatch(t *testing.T) { name string namespace string patch []byte - want *runtime.Unstructured + want *unstructured.Unstructured path string }{ { diff --git a/pkg/client/typed/dynamic/dynamic_util.go b/pkg/client/typed/dynamic/dynamic_util.go index b251d4b6b5a..802f98329bd 100644 --- a/pkg/client/typed/dynamic/dynamic_util.go +++ b/pkg/client/typed/dynamic/dynamic_util.go @@ -21,6 +21,7 @@ import ( "k8s.io/kubernetes/pkg/api/meta" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime/schema" ) @@ -29,7 +30,7 @@ import ( // accessor appropriate for use with unstructured objects. func VersionInterfaces(schema.GroupVersion) (*meta.VersionInterfaces, error) { return &meta.VersionInterfaces{ - ObjectConvertor: &runtime.UnstructuredObjectConverter{}, + ObjectConvertor: &unstructured.UnstructuredObjectConverter{}, MetadataAccessor: meta.NewAccessor(), }, nil } @@ -56,7 +57,7 @@ func NewDiscoveryRESTMapper(resources []*metav1.APIResourceList, versionFunc met } // ObjectTyper provides an ObjectTyper implementation for -// runtime.Unstructured object based on discovery information. +// unstructured.Unstructured object based on discovery information. type ObjectTyper struct { registered map[schema.GroupVersionKind]bool } @@ -79,10 +80,10 @@ func NewObjectTyper(resources []*metav1.APIResourceList) (runtime.ObjectTyper, e // ObjectKinds returns a slice of one element with the // group,version,kind of the provided object, or an error if the -// object is not *runtime.Unstructured or has no group,version,kind +// object is not *unstructured.Unstructured or has no group,version,kind // information. func (ot *ObjectTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) { - if _, ok := obj.(*runtime.Unstructured); !ok { + if _, ok := obj.(*unstructured.Unstructured); !ok { return nil, false, fmt.Errorf("type %T is invalid for dynamic object typer", obj) } return []schema.GroupVersionKind{obj.GetObjectKind().GroupVersionKind()}, false, nil diff --git a/pkg/controller/garbagecollector/garbagecollector.go b/pkg/controller/garbagecollector/garbagecollector.go index 95e025bd42b..93b4aeb7d58 100644 --- a/pkg/controller/garbagecollector/garbagecollector.go +++ b/pkg/controller/garbagecollector/garbagecollector.go @@ -28,6 +28,7 @@ import ( "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" "k8s.io/kubernetes/pkg/client/cache" "k8s.io/kubernetes/pkg/client/typed/dynamic" "k8s.io/kubernetes/pkg/controller/garbagecollector/metaonly" @@ -621,7 +622,7 @@ func (gc *GarbageCollector) deleteObject(item objectReference) error { return client.Resource(resource, item.Namespace).Delete(item.Name, &deleteOptions) } -func (gc *GarbageCollector) getObject(item objectReference) (*runtime.Unstructured, error) { +func (gc *GarbageCollector) getObject(item objectReference) (*unstructured.Unstructured, error) { fqKind := schema.FromAPIVersionAndKind(item.APIVersion, item.Kind) client, err := gc.clientPool.ClientForGroupVersionKind(fqKind) gc.registeredRateLimiter.registerIfNotPresent(fqKind.GroupVersion(), client, "garbage_collector_operation") @@ -632,7 +633,7 @@ func (gc *GarbageCollector) getObject(item objectReference) (*runtime.Unstructur return client.Resource(resource, item.Namespace).Get(item.Name) } -func (gc *GarbageCollector) updateObject(item objectReference, obj *runtime.Unstructured) (*runtime.Unstructured, error) { +func (gc *GarbageCollector) updateObject(item objectReference, obj *unstructured.Unstructured) (*unstructured.Unstructured, error) { fqKind := schema.FromAPIVersionAndKind(item.APIVersion, item.Kind) client, err := gc.clientPool.ClientForGroupVersionKind(fqKind) gc.registeredRateLimiter.registerIfNotPresent(fqKind.GroupVersion(), client, "garbage_collector_operation") @@ -643,7 +644,7 @@ func (gc *GarbageCollector) updateObject(item objectReference, obj *runtime.Unst return client.Resource(resource, item.Namespace).Update(obj) } -func (gc *GarbageCollector) patchObject(item objectReference, patch []byte) (*runtime.Unstructured, error) { +func (gc *GarbageCollector) patchObject(item objectReference, patch []byte) (*unstructured.Unstructured, error) { fqKind := schema.FromAPIVersionAndKind(item.APIVersion, item.Kind) client, err := gc.clientPool.ClientForGroupVersionKind(fqKind) gc.registeredRateLimiter.registerIfNotPresent(fqKind.GroupVersion(), client, "garbage_collector_operation") @@ -654,8 +655,8 @@ func (gc *GarbageCollector) patchObject(item objectReference, patch []byte) (*ru return client.Resource(resource, item.Namespace).Patch(item.Name, api.StrategicMergePatchType, patch) } -func objectReferenceToUnstructured(ref objectReference) *runtime.Unstructured { - ret := &runtime.Unstructured{} +func objectReferenceToUnstructured(ref objectReference) *unstructured.Unstructured { + ret := &unstructured.Unstructured{} ret.SetKind(ref.Kind) ret.SetAPIVersion(ref.APIVersion) ret.SetUID(ref.UID) diff --git a/pkg/controller/namespace/namespace_controller_utils.go b/pkg/controller/namespace/namespace_controller_utils.go index f484fbe6dca..0b87103a063 100644 --- a/pkg/controller/namespace/namespace_controller_utils.go +++ b/pkg/controller/namespace/namespace_controller_utils.go @@ -21,17 +21,17 @@ import ( "sync" "time" + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5" "k8s.io/kubernetes/pkg/client/typed/discovery" "k8s.io/kubernetes/pkg/client/typed/dynamic" - "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime/schema" "k8s.io/kubernetes/pkg/util/sets" - - "github.com/golang/glog" ) // contentRemainingError is used to inform the caller that content is not fully removed from the namespace @@ -210,7 +210,7 @@ func listCollection( opCache *operationNotSupportedCache, gvr schema.GroupVersionResource, namespace string, -) (*runtime.UnstructuredList, bool, error) { +) (*unstructured.UnstructuredList, bool, error) { glog.V(5).Infof("namespace controller - listCollection - namespace: %s, gvr: %v", namespace, gvr) key := operationKey{op: operationList, gvr: gvr} @@ -222,9 +222,9 @@ func listCollection( apiResource := metav1.APIResource{Name: gvr.Resource, Namespaced: true} obj, err := dynamicClient.Resource(&apiResource, namespace).List(&v1.ListOptions{}) if err == nil { - unstructuredList, ok := obj.(*runtime.UnstructuredList) + unstructuredList, ok := obj.(*unstructured.UnstructuredList) if !ok { - return nil, false, fmt.Errorf("resource: %s, expected *runtime.UnstructuredList, got %#v", apiResource.Name, obj) + return nil, false, fmt.Errorf("resource: %s, expected *unstructured.UnstructuredList, got %#v", apiResource.Name, obj) } return unstructuredList, true, nil } diff --git a/pkg/kubectl/cmd/create.go b/pkg/kubectl/cmd/create.go index 1ae04d7feb2..e4d6272f520 100644 --- a/pkg/kubectl/cmd/create.go +++ b/pkg/kubectl/cmd/create.go @@ -23,11 +23,11 @@ import ( "github.com/spf13/cobra" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" - "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime/schema" ) @@ -117,7 +117,7 @@ func RunCreate(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, opt if err != nil { return err } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). diff --git a/pkg/kubectl/cmd/delete.go b/pkg/kubectl/cmd/delete.go index bd65d50e034..3d284b1d080 100644 --- a/pkg/kubectl/cmd/delete.go +++ b/pkg/kubectl/cmd/delete.go @@ -26,11 +26,11 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" - "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/wait" ) @@ -142,7 +142,7 @@ func RunDelete(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, arg if err != nil { return err } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). diff --git a/pkg/kubectl/cmd/edit.go b/pkg/kubectl/cmd/edit.go index 346627b4ac2..30f7d4d5ed2 100644 --- a/pkg/kubectl/cmd/edit.go +++ b/pkg/kubectl/cmd/edit.go @@ -30,6 +30,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -399,7 +400,7 @@ func getMapperAndResult(f cmdutil.Factory, args []string, options *resource.File ResourceTypeOrNameArgs(true, args...). Latest() case EditBeforeCreateMode: - b = resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme) + b = resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme) default: return nil, nil, nil, "", fmt.Errorf("Not supported edit mode %q", editMode) } diff --git a/pkg/kubectl/cmd/get.go b/pkg/kubectl/cmd/get.go index b34d0b02362..9b0672594e0 100644 --- a/pkg/kubectl/cmd/get.go +++ b/pkg/kubectl/cmd/get.go @@ -24,6 +24,7 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api/meta" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" @@ -194,7 +195,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ // handle watch separately since we cannot watch multiple resource types isWatch, isWatchOnly := cmdutil.GetFlagBool(cmd, "watch"), cmdutil.GetFlagBool(cmd, "watch-only") if isWatch || isWatchOnly { - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces). FilenameParam(enforceNamespace, &options.FilenameOptions). SelectorParam(selector). @@ -279,7 +280,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ return nil } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces). FilenameParam(enforceNamespace, &options.FilenameOptions). SelectorParam(selector). @@ -327,7 +328,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ obj = infos[0].Object } else { // we have more than one item, so coerce all items into a list - list := &runtime.UnstructuredList{ + list := &unstructured.UnstructuredList{ Object: map[string]interface{}{ "kind": "List", "apiVersion": "v1", @@ -335,7 +336,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ }, } for _, info := range infos { - list.Items = append(list.Items, info.Object.(*runtime.Unstructured)) + list.Items = append(list.Items, info.Object.(*unstructured.Unstructured)) } obj = list } @@ -348,7 +349,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ } // take the filtered items and create a new list for display - list := &runtime.UnstructuredList{ + list := &unstructured.UnstructuredList{ Object: map[string]interface{}{ "kind": "List", "apiVersion": "v1", @@ -361,7 +362,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ } for _, item := range items { - list.Items = append(list.Items, item.(*runtime.Unstructured)) + list.Items = append(list.Items, item.(*unstructured.Unstructured)) } if err := printer.PrintObj(list, out); err != nil { errs = append(errs, err) diff --git a/pkg/kubectl/cmd/replace.go b/pkg/kubectl/cmd/replace.go index 30ffbc1889c..36b336ec10f 100644 --- a/pkg/kubectl/cmd/replace.go +++ b/pkg/kubectl/cmd/replace.go @@ -27,11 +27,11 @@ import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api/errors" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/cmd/templates" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" "k8s.io/kubernetes/pkg/kubectl/resource" - "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/wait" ) @@ -128,7 +128,7 @@ func RunReplace(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str if err != nil { return err } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). @@ -199,7 +199,7 @@ func forceReplace(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s if err != nil { return err } - r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme). + r := resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). FilenameParam(enforceNamespace, options). @@ -248,7 +248,7 @@ func forceReplace(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s }) }) - r = resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), runtime.UnstructuredJSONScheme). + r = resource.NewBuilder(mapper, typer, resource.ClientMapperFunc(f.UnstructuredClientForMapping), unstructured.UnstructuredJSONScheme). Schema(schema). ContinueOnError(). NamespaceParam(cmdNamespace).DefaultNamespace(). diff --git a/pkg/kubectl/cmd/util/helpers.go b/pkg/kubectl/cmd/util/helpers.go index 3423ac6d1b1..ab4bb4699ad 100644 --- a/pkg/kubectl/cmd/util/helpers.go +++ b/pkg/kubectl/cmd/util/helpers.go @@ -28,12 +28,17 @@ import ( "strings" "time" + jsonpatch "github.com/evanphx/json-patch" + "github.com/golang/glog" + "github.com/spf13/cobra" + "k8s.io/kubernetes/pkg/api" kerrors "k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/apimachinery/registered" "k8s.io/kubernetes/pkg/apis/extensions" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" "k8s.io/kubernetes/pkg/client/unversioned/clientcmd" "k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl/resource" @@ -43,10 +48,6 @@ import ( utilexec "k8s.io/kubernetes/pkg/util/exec" "k8s.io/kubernetes/pkg/util/sets" "k8s.io/kubernetes/pkg/util/strategicpatch" - - jsonpatch "github.com/evanphx/json-patch" - "github.com/golang/glog" - "github.com/spf13/cobra" ) const ( @@ -663,7 +664,7 @@ func FilterResourceList(obj runtime.Object, filterFuncs kubectl.Filters, filterO if err != nil { return 0, []runtime.Object{obj}, utilerrors.NewAggregate([]error{err}) } - if errs := runtime.DecodeList(items, api.Codecs.UniversalDecoder(), runtime.UnstructuredJSONScheme); len(errs) > 0 { + if errs := runtime.DecodeList(items, api.Codecs.UniversalDecoder(), unstructured.UnstructuredJSONScheme); len(errs) > 0 { return 0, []runtime.Object{obj}, utilerrors.NewAggregate(errs) } diff --git a/pkg/kubectl/custom_column_printer.go b/pkg/kubectl/custom_column_printer.go index a73c99d9fd2..cb964ecb2a1 100644 --- a/pkg/kubectl/custom_column_printer.go +++ b/pkg/kubectl/custom_column_printer.go @@ -212,8 +212,8 @@ func (s *CustomColumnsPrinter) printOneObject(obj runtime.Object, parsers []*jso var values [][]reflect.Value var err error - if unstructured, ok := obj.(*runtime.Unstructured); ok { - values, err = parser.FindResults(unstructured.Object) + if unstructured, ok := obj.(runtime.Unstructured); ok { + values, err = parser.FindResults(unstructured.UnstructuredContent()) } else { values, err = parser.FindResults(reflect.ValueOf(obj).Elem().Interface()) } diff --git a/pkg/kubectl/resource_filter.go b/pkg/kubectl/resource_filter.go index cd6470ba23e..fc7434225d1 100644 --- a/pkg/kubectl/resource_filter.go +++ b/pkg/kubectl/resource_filter.go @@ -61,7 +61,7 @@ func (f Filters) Filter(obj runtime.Object, opts *PrintOptions) (bool, error) { // check if the object is unstructured. If so, let's attempt to convert it to a type we can understand // before apply filter func. switch obj.(type) { - case *runtime.UnstructuredList, *runtime.Unstructured, *runtime.Unknown: + case runtime.Unstructured, *runtime.Unknown: if objBytes, err := runtime.Encode(api.Codecs.LegacyCodec(), obj); err == nil { if decodedObj, err := runtime.Decode(api.Codecs.UniversalDecoder(), objBytes); err == nil { obj = decodedObj diff --git a/pkg/kubectl/resource_printer.go b/pkg/kubectl/resource_printer.go index def1e847f7e..2a3621f3717 100644 --- a/pkg/kubectl/resource_printer.go +++ b/pkg/kubectl/resource_printer.go @@ -40,6 +40,7 @@ import ( "k8s.io/kubernetes/pkg/apis/certificates" "k8s.io/kubernetes/pkg/apis/extensions" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" "k8s.io/kubernetes/pkg/apis/policy" "k8s.io/kubernetes/pkg/apis/rbac" "k8s.io/kubernetes/pkg/apis/storage" @@ -232,7 +233,7 @@ func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error { if err != nil { return err } - if errs := runtime.DecodeList(items, p.Decoder, runtime.UnstructuredJSONScheme); len(errs) > 0 { + if errs := runtime.DecodeList(items, p.Decoder, unstructured.UnstructuredJSONScheme); len(errs) > 0 { return utilerrors.NewAggregate(errs) } for _, obj := range items { @@ -2394,7 +2395,7 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er // check if the object is unstructured. If so, let's attempt to convert it to a type we can understand before // trying to print, since the printers are keyed by type. This is extremely expensive. switch obj.(type) { - case *runtime.UnstructuredList, *runtime.Unstructured, *runtime.Unknown: + case runtime.Unstructured, *runtime.Unknown: if objBytes, err := runtime.Encode(api.Codecs.LegacyCodec(), obj); err == nil { if decodedObj, err := runtime.Decode(api.Codecs.UniversalDecoder(), objBytes); err == nil { obj = decodedObj @@ -2423,12 +2424,6 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er return resultValue.Interface().(error) } - // we don't recognize this type, but we can still attempt to print some reasonable information about. - unstructured, ok := obj.(*runtime.Unstructured) - if !ok { - return fmt.Errorf("error: unknown type %#v", obj) - } - if _, err := meta.Accessor(obj); err == nil { if !h.options.NoHeaders && t != h.lastType { headers := []string{"NAME", "KIND"} @@ -2441,6 +2436,12 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er h.printHeader(headers, w) h.lastType = t } + + // we don't recognize this type, but we can still attempt to print some reasonable information about. + unstructured, ok := obj.(runtime.Unstructured) + if !ok { + return fmt.Errorf("error: unknown type %#v", obj) + } // if the error isn't nil, report the "I don't recognize this" error if err := printUnstructured(unstructured, w, h.options); err != nil { return err @@ -2452,7 +2453,7 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er return fmt.Errorf("error: unknown type %#v", obj) } -func printUnstructured(unstructured *runtime.Unstructured, w io.Writer, options PrintOptions) error { +func printUnstructured(unstructured runtime.Unstructured, w io.Writer, options PrintOptions) error { metadata, err := meta.Accessor(unstructured) if err != nil { return err @@ -2464,13 +2465,14 @@ func printUnstructured(unstructured *runtime.Unstructured, w io.Writer, options } } + content := unstructured.UnstructuredContent() kind := "" - if objKind, ok := unstructured.Object["kind"]; ok { + if objKind, ok := content["kind"]; ok { if str, ok := objKind.(string); ok { kind = str } } - if objAPIVersion, ok := unstructured.Object["apiVersion"]; ok { + if objAPIVersion, ok := content["apiVersion"]; ok { if str, ok := objAPIVersion.(string); ok { version, err := schema.ParseGroupVersion(str) if err != nil { @@ -2521,12 +2523,7 @@ func (p *TemplatePrinter) AfterPrint(w io.Writer, res string) error { func (p *TemplatePrinter) PrintObj(obj runtime.Object, w io.Writer) error { var data []byte var err error - if unstructured, ok := obj.(*runtime.Unstructured); ok { - data, err = json.Marshal(unstructured.Object) - } else { - data, err = json.Marshal(obj) - - } + data, err = json.Marshal(obj) if err != nil { return err } @@ -2700,7 +2697,7 @@ func (j *JSONPathPrinter) PrintObj(obj runtime.Object, w io.Writer) error { return err } } - if unstructured, ok := obj.(*runtime.Unstructured); ok { + if unstructured, ok := obj.(*unstructured.Unstructured); ok { queryObj = unstructured.Object } diff --git a/pkg/kubectl/sorting_printer.go b/pkg/kubectl/sorting_printer.go index 00ddef76272..da5bc502743 100644 --- a/pkg/kubectl/sorting_printer.go +++ b/pkg/kubectl/sorting_printer.go @@ -22,14 +22,15 @@ import ( "reflect" "sort" + "github.com/golang/glog" + "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/v1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/integer" "k8s.io/kubernetes/pkg/util/jsonpath" - - "github.com/golang/glog" ) // Sorting printer sorts list types before delegating to another printer. @@ -112,7 +113,7 @@ func SortObjects(decoder runtime.Decoder, objs []runtime.Object, fieldInput stri } var values [][]reflect.Value - if unstructured, ok := objs[0].(*runtime.Unstructured); ok { + if unstructured, ok := objs[0].(*unstructured.Unstructured); ok { values, err = parser.FindResults(unstructured.Object) } else { values, err = parser.FindResults(reflect.ValueOf(objs[0]).Elem().Interface()) @@ -266,7 +267,7 @@ func (r *RuntimeSort) Less(i, j int) bool { var jValues [][]reflect.Value var err error - if unstructured, ok := iObj.(*runtime.Unstructured); ok { + if unstructured, ok := iObj.(*unstructured.Unstructured); ok { iValues, err = parser.FindResults(unstructured.Object) } else { iValues, err = parser.FindResults(reflect.ValueOf(iObj).Elem().Interface()) @@ -275,7 +276,7 @@ func (r *RuntimeSort) Less(i, j int) bool { glog.Fatalf("Failed to get i values for %#v using %s (%#v)", iObj, r.field, err) } - if unstructured, ok := jObj.(*runtime.Unstructured); ok { + if unstructured, ok := jObj.(*unstructured.Unstructured); ok { jValues, err = parser.FindResults(unstructured.Object) } else { jValues, err = parser.FindResults(reflect.ValueOf(jObj).Elem().Interface()) diff --git a/pkg/runtime/helper_test.go b/pkg/runtime/helper_test.go index 48e1dd48707..8c6dc8da861 100644 --- a/pkg/runtime/helper_test.go +++ b/pkg/runtime/helper_test.go @@ -34,13 +34,6 @@ func TestDecodeList(t *testing.T) { Raw: []byte(`{"kind":"Pod","apiVersion":"` + registered.GroupOrDie(api.GroupName).GroupVersion.String() + `","metadata":{"name":"test"}}`), ContentType: runtime.ContentTypeJSON, }, - &runtime.Unstructured{ - Object: map[string]interface{}{ - "kind": "Foo", - "apiVersion": "Bar", - "test": "value", - }, - }, }, } if errs := runtime.DecodeList(pl.Items, testapi.Default.Codec()); len(errs) != 0 { diff --git a/test/e2e/framework/util.go b/test/e2e/framework/util.go index 528dde36f2e..e905e695e1e 100644 --- a/test/e2e/framework/util.go +++ b/test/e2e/framework/util.go @@ -40,8 +40,16 @@ import ( "text/tabwriter" "time" + "github.com/blang/semver" "github.com/golang/glog" + "golang.org/x/crypto/ssh" + "golang.org/x/net/websocket" "google.golang.org/api/googleapi" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + gomegatypes "github.com/onsi/gomega/types" + "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5" "k8s.io/kubernetes/pkg/api" apierrs "k8s.io/kubernetes/pkg/api/errors" @@ -52,6 +60,7 @@ import ( extensionsinternal "k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5" "k8s.io/kubernetes/pkg/client/conditions" @@ -83,15 +92,6 @@ import ( "k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/predicates" "k8s.io/kubernetes/plugin/pkg/scheduler/schedulercache" testutils "k8s.io/kubernetes/test/utils" - - "github.com/blang/semver" - "golang.org/x/crypto/ssh" - "golang.org/x/net/websocket" - - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - gomegatypes "github.com/onsi/gomega/types" ) const ( @@ -1132,9 +1132,9 @@ func hasRemainingContent(c clientset.Interface, clientPool dynamic.ClientPool, n } return false, err } - unstructuredList, ok := obj.(*runtime.UnstructuredList) + unstructuredList, ok := obj.(*unstructured.UnstructuredList) if !ok { - return false, fmt.Errorf("namespace: %s, resource: %s, expected *runtime.UnstructuredList, got %#v", namespace, apiResource.Name, obj) + return false, fmt.Errorf("namespace: %s, resource: %s, expected *unstructured.UnstructuredList, got %#v", namespace, apiResource.Name, obj) } if len(unstructuredList.Items) > 0 { Logf("namespace: %s, resource: %s, items remaining: %v", namespace, apiResource.Name, len(unstructuredList.Items)) diff --git a/test/integration/client/dynamic_client_test.go b/test/integration/client/dynamic_client_test.go index 12708769661..b608ed0d803 100644 --- a/test/integration/client/dynamic_client_test.go +++ b/test/integration/client/dynamic_client_test.go @@ -26,6 +26,7 @@ import ( "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/apimachinery/registered" metav1 "k8s.io/kubernetes/pkg/apis/meta/v1" + "k8s.io/kubernetes/pkg/apis/meta/v1/unstructured" clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5" "k8s.io/kubernetes/pkg/client/restclient" "k8s.io/kubernetes/pkg/client/typed/dynamic" @@ -93,9 +94,9 @@ func TestDynamicClient(t *testing.T) { // check dynamic list obj, err := dynamicClient.Resource(&resource, ns.Name).List(&v1.ListOptions{}) - unstructuredList, ok := obj.(*runtime.UnstructuredList) + unstructuredList, ok := obj.(*unstructured.UnstructuredList) if !ok { - t.Fatalf("expected *runtime.UnstructuredList, got %#v", obj) + t.Fatalf("expected *unstructured.UnstructuredList, got %#v", obj) } if err != nil { t.Fatalf("unexpected error when listing pods: %v", err) @@ -145,8 +146,8 @@ func TestDynamicClient(t *testing.T) { } } -func unstructuredToPod(obj *runtime.Unstructured) (*v1.Pod, error) { - json, err := runtime.Encode(runtime.UnstructuredJSONScheme, obj) +func unstructuredToPod(obj *unstructured.Unstructured) (*v1.Pod, error) { + json, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj) if err != nil { return nil, err }