Commit 49ed2a31 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #50204 from smarterclayton/move_list_to_metav1

Automatic merge from submit-queue (batch tested with PRs 50711, 50742, 50204) Move List (the type) into metav1 but preserve the exposed type Make a list something that other components can use without depending on the core API. This does not change the public API exposure of `List` (it is still in `v1`) but makes the interface common across both.
parents bc2bb37f 1b3836d5
......@@ -25,6 +25,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apimachinery/announced:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/internalversion:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/fields:go_default_library",
......
......@@ -24,6 +24,7 @@ go_library(
deps = [
"//pkg/api:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
],
)
......
......@@ -23,6 +23,7 @@ import (
"strings"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/api"
)
......@@ -61,10 +62,10 @@ func GetReference(scheme *runtime.Scheme, obj runtime.Object) (*api.ObjectRefere
}
// An object that implements only List has enough metadata to build a reference
var listMeta meta.List
var listMeta metav1.Common
objectMeta, err := meta.Accessor(obj)
if err != nil {
listMeta, err = meta.ListAccessor(obj)
listMeta, err = meta.CommonAccessor(obj)
if err != nil {
return nil, err
}
......
......@@ -18,10 +18,10 @@ package api
import (
"k8s.io/apimachinery/pkg/api/resource"
metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
)
......@@ -3626,13 +3626,7 @@ type EventList struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// List holds a list of objects, which may not be known by the server.
type List struct {
metav1.TypeMeta
// +optional
metav1.ListMeta
Items []runtime.Object
}
type List metainternalversion.List
// A type of object that is limited
type LimitType string
......
......@@ -19,7 +19,6 @@ package v1
import (
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
)
......@@ -4150,16 +4149,7 @@ type EventList struct {
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// List holds a list of objects, which may not be known by the server.
type List struct {
metav1.TypeMeta `json:",inline"`
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
// +optional
metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// List of objects
Items []runtime.RawExtension `json:"items" protobuf:"bytes,2,rep,name=items"`
}
type List metav1.List
// LimitType is a type of object that is limited
type LimitType string
......
......@@ -744,16 +744,6 @@ func (LimitRangeSpec) SwaggerDoc() map[string]string {
return map_LimitRangeSpec
}
var map_List = map[string]string{
"": "List holds a list of objects, which may not be known by the server.",
"metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
"items": "List of objects",
}
func (List) SwaggerDoc() map[string]string {
return map_List
}
var map_ListOptions = map[string]string{
"": "ListOptions is the query options to a standard REST list call. DEPRECATED: This type has been moved to meta/v1 and will be removed soon.",
"labelSelector": "A selector to restrict the list of returned objects by their labels. Defaults to everything.",
......
......@@ -36,7 +36,7 @@ type ListMetaAccessor interface {
// List lets you work with list metadata from any of the versioned or
// internal API objects. Attempting to set or retrieve a field on an object that does
// not support that field will be a no-op and return a default value.
type List metav1.List
type List metav1.ListInterface
// Type exposes the type and APIVersion of versioned or internal API objects.
type Type metav1.Type
......
......@@ -34,36 +34,62 @@ import (
// interfaces.
var errNotList = fmt.Errorf("object does not implement the List interfaces")
// ListAccessor returns a List interface for the provided object or an error if the object does
var errNotCommon = fmt.Errorf("object does not implement the common interface for accessing the SelfLink")
// CommonAccessor returns a Common interface for the provided object or an error if the object does
// not provide List.
// IMPORTANT: Objects are a superset of lists, so all Objects return List metadata. Do not use this
// check to determine whether an object *is* a List.
// TODO: return bool instead of error
func ListAccessor(obj interface{}) (List, error) {
func CommonAccessor(obj interface{}) (metav1.Common, error) {
switch t := obj.(type) {
case List:
return t, nil
case metav1.List:
case metav1.ListInterface:
return t, nil
case ListMetaAccessor:
if m := t.GetListMeta(); m != nil {
return m, nil
}
return nil, errNotList
return nil, errNotCommon
case metav1.ListMetaAccessor:
if m := t.GetListMeta(); m != nil {
return m, nil
}
return nil, errNotList
return nil, errNotCommon
case metav1.Object:
return t, nil
case metav1.ObjectMetaAccessor:
if m := t.GetObjectMeta(); m != nil {
return m, nil
}
return nil, errNotList
return nil, errNotCommon
default:
return nil, errNotCommon
}
}
// ListAccessor returns a List interface for the provided object or an error if the object does
// not provide List.
// IMPORTANT: Objects are NOT a superset of lists. Do not use this check to determine whether an
// object *is* a List.
// TODO: return bool instead of error
func ListAccessor(obj interface{}) (List, error) {
switch t := obj.(type) {
case List:
return t, nil
case metav1.ListInterface:
return t, nil
case ListMetaAccessor:
if m := t.GetListMeta(); m != nil {
return m, nil
}
return nil, errNotList
case metav1.ListMetaAccessor:
if m := t.GetListMeta(); m != nil {
return m, nil
}
return nil, errNotList
default:
panic(fmt.Errorf("%T does not implement the List interface", obj))
}
}
......@@ -274,7 +300,7 @@ func (resourceAccessor) SetUID(obj runtime.Object, uid types.UID) error {
}
func (resourceAccessor) SelfLink(obj runtime.Object) (string, error) {
accessor, err := ListAccessor(obj)
accessor, err := CommonAccessor(obj)
if err != nil {
return "", err
}
......@@ -282,7 +308,7 @@ func (resourceAccessor) SelfLink(obj runtime.Object) (string, error) {
}
func (resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error {
accessor, err := ListAccessor(obj)
accessor, err := CommonAccessor(obj)
if err != nil {
return err
}
......@@ -325,7 +351,7 @@ func (resourceAccessor) SetAnnotations(obj runtime.Object, annotations map[strin
}
func (resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) {
accessor, err := ListAccessor(obj)
accessor, err := CommonAccessor(obj)
if err != nil {
return "", err
}
......@@ -333,7 +359,7 @@ func (resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) {
}
func (resourceAccessor) SetResourceVersion(obj runtime.Object, version string) error {
accessor, err := ListAccessor(obj)
accessor, err := CommonAccessor(obj)
if err != nil {
return err
}
......
......@@ -28,6 +28,7 @@ go_library(
"doc.go",
"register.go",
"types.go",
"zz_generated.conversion.go",
"zz_generated.deepcopy.go",
],
deps = [
......
......@@ -30,6 +30,14 @@ const GroupName = "meta.k8s.io"
// Scheme is the registry for any type that adheres to the meta API spec.
var scheme = runtime.NewScheme()
var (
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder
AddToScheme = localSchemeBuilder.AddToScheme
)
// Copier exposes copying on this scheme.
var Copier runtime.ObjectCopier = scheme
......
......@@ -20,6 +20,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
......@@ -48,3 +49,14 @@ type ListOptions struct {
// Timeout for the list/watch call.
TimeoutSeconds *int64
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// List holds a list of objects, which may not be known by the server.
type List struct {
metav1.TypeMeta
// +optional
metav1.ListMeta
Items []runtime.Object
}
// +build !ignore_autogenerated
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
// This file was autogenerated by conversion-gen. Do not edit it manually!
package internalversion
import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
conversion "k8s.io/apimachinery/pkg/conversion"
runtime "k8s.io/apimachinery/pkg/runtime"
unsafe "unsafe"
)
func init() {
localSchemeBuilder.Register(RegisterConversions)
}
// RegisterConversions adds conversion functions to the given scheme.
// Public to allow building arbitrary schemes.
func RegisterConversions(scheme *runtime.Scheme) error {
return scheme.AddGeneratedConversionFuncs(
Convert_internalversion_List_To_v1_List,
Convert_v1_List_To_internalversion_List,
Convert_internalversion_ListOptions_To_v1_ListOptions,
Convert_v1_ListOptions_To_internalversion_ListOptions,
)
}
func autoConvert_internalversion_List_To_v1_List(in *List, out *v1.List, s conversion.Scope) error {
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]runtime.RawExtension, len(*in))
for i := range *in {
if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Items = make([]runtime.RawExtension, 0)
}
return nil
}
// Convert_internalversion_List_To_v1_List is an autogenerated conversion function.
func Convert_internalversion_List_To_v1_List(in *List, out *v1.List, s conversion.Scope) error {
return autoConvert_internalversion_List_To_v1_List(in, out, s)
}
func autoConvert_v1_List_To_internalversion_List(in *v1.List, out *List, s conversion.Scope) error {
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]runtime.Object, len(*in))
for i := range *in {
if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&(*in)[i], &(*out)[i], s); err != nil {
return err
}
}
} else {
out.Items = nil
}
return nil
}
// Convert_v1_List_To_internalversion_List is an autogenerated conversion function.
func Convert_v1_List_To_internalversion_List(in *v1.List, out *List, s conversion.Scope) error {
return autoConvert_v1_List_To_internalversion_List(in, out, s)
}
func autoConvert_internalversion_ListOptions_To_v1_ListOptions(in *ListOptions, out *v1.ListOptions, s conversion.Scope) error {
if err := v1.Convert_labels_Selector_To_string(&in.LabelSelector, &out.LabelSelector, s); err != nil {
return err
}
if err := v1.Convert_fields_Selector_To_string(&in.FieldSelector, &out.FieldSelector, s); err != nil {
return err
}
out.IncludeUninitialized = in.IncludeUninitialized
out.Watch = in.Watch
out.ResourceVersion = in.ResourceVersion
out.TimeoutSeconds = (*int64)(unsafe.Pointer(in.TimeoutSeconds))
return nil
}
func autoConvert_v1_ListOptions_To_internalversion_ListOptions(in *v1.ListOptions, out *ListOptions, s conversion.Scope) error {
if err := v1.Convert_string_To_labels_Selector(&in.LabelSelector, &out.LabelSelector, s); err != nil {
return err
}
if err := v1.Convert_string_To_fields_Selector(&in.FieldSelector, &out.FieldSelector, s); err != nil {
return err
}
out.IncludeUninitialized = in.IncludeUninitialized
out.Watch = in.Watch
out.ResourceVersion = in.ResourceVersion
out.TimeoutSeconds = (*int64)(unsafe.Pointer(in.TimeoutSeconds))
return nil
}
......@@ -32,6 +32,10 @@ import (
func GetGeneratedDeepCopyFuncs() []conversion.GeneratedDeepCopyFunc {
return []conversion.GeneratedDeepCopyFunc{
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*List).DeepCopyInto(out.(*List))
return nil
}, InType: reflect.TypeOf(&List{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*ListOptions).DeepCopyInto(out.(*ListOptions))
return nil
}, InType: reflect.TypeOf(&ListOptions{})},
......@@ -39,6 +43,44 @@ func GetGeneratedDeepCopyFuncs() []conversion.GeneratedDeepCopyFunc {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *List) DeepCopyInto(out *List) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]runtime.Object, len(*in))
for i := range *in {
if (*in)[i] == nil {
(*out)[i] = nil
} else {
(*out)[i] = (*in)[i].DeepCopyObject()
}
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new List.
func (in *List) DeepCopy() *List {
if in == nil {
return nil
}
out := new(List)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *List) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
} else {
return nil
}
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ListOptions) DeepCopyInto(out *ListOptions) {
*out = *in
out.TypeMeta = in.TypeMeta
......
......@@ -19,4 +19,4 @@ limitations under the License.
// +k8s:defaulter-gen=TypeMeta
// +groupName=meta.k8s.io
package v1
package v1 // import "k8s.io/apimachinery/pkg/apis/meta/v1"
......@@ -292,6 +292,17 @@ message LabelSelectorRequirement {
repeated string values = 3;
}
// List holds a list of objects, which may not be known by the server.
message List {
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
// +optional
optional ListMeta metadata = 1;
// List of objects
repeated k8s.io.apimachinery.pkg.runtime.RawExtension items = 2;
}
// ListMeta describes metadata that synthetic resources must have, including lists and
// various status objects. A resource may have only one of {ObjectMeta, ListMeta}.
message ListMeta {
......
......@@ -67,14 +67,25 @@ type Object interface {
// ListMetaAccessor retrieves the list interface from an object
type ListMetaAccessor interface {
GetListMeta() List
GetListMeta() ListInterface
}
// List lets you work with list metadata from any of the versioned or
// Common lets you work with core metadata from any of the versioned or
// internal API objects. Attempting to set or retrieve a field on an object that does
// not support that field will be a no-op and return a default value.
// TODO: move this, and TypeMeta and ListMeta, to a different package
type List interface {
type Common interface {
GetResourceVersion() string
SetResourceVersion(version string)
GetSelfLink() string
SetSelfLink(selfLink string)
}
// ListInterface lets you work with list metadata from any of the versioned or
// internal API objects. Attempting to set or retrieve a field on an object that does
// not support that field will be a no-op and return a default value.
// TODO: move this, and TypeMeta and ListMeta, to a different package
type ListInterface interface {
GetResourceVersion() string
SetResourceVersion(version string)
GetSelfLink() string
......@@ -107,7 +118,7 @@ func (obj *TypeMeta) GroupVersionKind() schema.GroupVersionKind {
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
}
func (obj *ListMeta) GetListMeta() List { return obj }
func (obj *ListMeta) GetListMeta() ListInterface { return obj }
func (obj *ObjectMeta) GetObjectMeta() Object { return obj }
......
......@@ -29,6 +29,7 @@ import (
"fmt"
"strings"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
)
......@@ -679,6 +680,20 @@ const (
CauseTypeUnexpectedServerResponse CauseType = "UnexpectedServerResponse"
)
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// List holds a list of objects, which may not be known by the server.
type List struct {
TypeMeta `json:",inline"`
// Standard list metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
// +optional
ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// List of objects
Items []runtime.RawExtension `json:"items" protobuf:"bytes,2,rep,name=items"`
}
// APIVersions lists the versions that are available, to allow clients to
// discover the API at /api, which is the root path of the legacy v1 API.
//
......
......@@ -165,6 +165,16 @@ func (LabelSelectorRequirement) SwaggerDoc() map[string]string {
return map_LabelSelectorRequirement
}
var map_List = map[string]string{
"": "List holds a list of objects, which may not be known by the server.",
"metadata": "Standard list metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds",
"items": "List of objects",
}
func (List) SwaggerDoc() map[string]string {
return map_List
}
var map_ListMeta = map[string]string{
"": "ListMeta describes metadata that synthetic resources must have, including lists and various status objects. A resource may have only one of {ObjectMeta, ListMeta}.",
"selfLink": "SelfLink is a URL representing this object. Populated by the system. Read-only.",
......
......@@ -596,6 +596,8 @@ type UnstructuredList struct {
Items []Unstructured `json:"items"`
}
var _ metav1.ListInterface = &UnstructuredList{}
// MarshalJSON ensures that the unstructured list object produces proper
// JSON when passed to Go's standard JSON library.
func (u *UnstructuredList) MarshalJSON() ([]byte, error) {
......
......@@ -113,6 +113,10 @@ func GetGeneratedDeepCopyFuncs() []conversion.GeneratedDeepCopyFunc {
return nil
}, InType: reflect.TypeOf(&LabelSelectorRequirement{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*List).DeepCopyInto(out.(*List))
return nil
}, InType: reflect.TypeOf(&List{})},
{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {
in.(*ListMeta).DeepCopyInto(out.(*ListMeta))
return nil
}, InType: reflect.TypeOf(&ListMeta{})},
......@@ -690,6 +694,40 @@ func (in *LabelSelectorRequirement) DeepCopy() *LabelSelectorRequirement {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *List) DeepCopyInto(out *List) {
*out = *in
out.TypeMeta = in.TypeMeta
out.ListMeta = in.ListMeta
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]runtime.RawExtension, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
return
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new List.
func (in *List) DeepCopy() *List {
if in == nil {
return nil
}
out := new(List)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *List) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
} else {
return nil
}
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ListMeta) DeepCopyInto(out *ListMeta) {
*out = *in
return
......
......@@ -215,7 +215,7 @@ type MyAPIObject struct {
TypeMeta InternalTypeMeta `json:",inline"`
}
func (obj *MyAPIObject) GetListMeta() metav1.List { return &obj.TypeMeta }
func (obj *MyAPIObject) GetListMeta() metav1.ListInterface { return &obj.TypeMeta }
func (obj *MyAPIObject) GetObjectKind() schema.ObjectKind { return obj }
func (obj *MyAPIObject) SetGroupVersionKind(gvk schema.GroupVersionKind) {
......
......@@ -11,6 +11,7 @@ go_library(
deps = [
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
],
)
......
......@@ -24,6 +24,7 @@ import (
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)
......@@ -61,10 +62,10 @@ func GetReference(scheme *runtime.Scheme, obj runtime.Object) (*v1.ObjectReferen
}
// An object that implements only List has enough metadata to build a reference
var listMeta meta.List
var listMeta metav1.Common
objectMeta, err := meta.Accessor(obj)
if err != nil {
listMeta, err = meta.ListAccessor(obj)
listMeta, err = meta.CommonAccessor(obj)
if err != nil {
return nil, err
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment