mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
rest mappings cannot logically be object converters
This commit is contained in:
parent
d4b678036f
commit
6900f8856f
@ -103,11 +103,6 @@ func TestRESTMapper(t *testing.T) {
|
|||||||
t.Errorf("incorrect version: %v", mapping)
|
t.Errorf("incorrect version: %v", mapping)
|
||||||
}
|
}
|
||||||
|
|
||||||
interfaces, _ := legacyscheme.Registry.GroupOrDie(internal.GroupName).InterfacesFor(version)
|
|
||||||
if mapping.ObjectConvertor != interfaces.ObjectConvertor {
|
|
||||||
t.Errorf("unexpected: %#v, expected: %#v", mapping, interfaces)
|
|
||||||
}
|
|
||||||
|
|
||||||
rc := &internal.ReplicationController{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
|
rc := &internal.ReplicationController{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
|
||||||
name, err := meta.NewAccessor().Name(rc)
|
name, err := meta.NewAccessor().Name(rc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -248,7 +248,7 @@ func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) erro
|
|||||||
var outputObj runtime.Object
|
var outputObj runtime.Object
|
||||||
var obj runtime.Object
|
var obj runtime.Object
|
||||||
|
|
||||||
obj, err = info.Mapping.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupVersion())
|
obj, err = info.ObjectConverter.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupVersion())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
@ -230,10 +231,11 @@ func (o *AutoscaleOptions) Run() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resourceMapper := &resource.Mapper{
|
resourceMapper := &resource.Mapper{
|
||||||
ObjectTyper: o.Typer,
|
ObjectTyper: o.Typer,
|
||||||
RESTMapper: o.Mapper,
|
ObjectConverter: legacyscheme.Scheme,
|
||||||
ClientMapper: resource.ClientMapperFunc(o.ClientForMapping),
|
RESTMapper: o.Mapper,
|
||||||
Decoder: cmdutil.InternalVersionDecoder(),
|
ClientMapper: resource.ClientMapperFunc(o.ClientForMapping),
|
||||||
|
Decoder: cmdutil.InternalVersionDecoder(),
|
||||||
}
|
}
|
||||||
hpa, err := resourceMapper.InfoForObject(object, nil)
|
hpa, err := resourceMapper.InfoForObject(object, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -282,7 +282,7 @@ func asVersionedObjects(infos []*resource.Info, specifiedOutputVersion schema.Gr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
converted, err := tryConvert(info.Mapping.ObjectConvertor, info.Object, targetVersions...)
|
converted, err := tryConvert(scheme.Scheme, info.Object, targetVersions...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ go_library(
|
|||||||
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/create",
|
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/create",
|
||||||
visibility = ["//build/visible_to:pkg_kubectl_cmd_create_CONSUMERS"],
|
visibility = ["//build/visible_to:pkg_kubectl_cmd_create_CONSUMERS"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//pkg/api/legacyscheme:go_default_library",
|
||||||
"//pkg/kubectl:go_default_library",
|
"//pkg/kubectl:go_default_library",
|
||||||
"//pkg/kubectl/cmd/templates:go_default_library",
|
"//pkg/kubectl/cmd/templates:go_default_library",
|
||||||
"//pkg/kubectl/cmd/util:go_default_library",
|
"//pkg/kubectl/cmd/util:go_default_library",
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
kruntime "k8s.io/apimachinery/pkg/runtime"
|
kruntime "k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
@ -404,9 +405,10 @@ func RunCreateSubcommand(f cmdutil.Factory, options *CreateSubcommandOptions) er
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
resourceMapper := &resource.Mapper{
|
resourceMapper := &resource.Mapper{
|
||||||
ObjectTyper: typer,
|
ObjectTyper: typer,
|
||||||
RESTMapper: mapper,
|
ObjectConverter: legacyscheme.Scheme,
|
||||||
ClientMapper: resource.ClientMapperFunc(f.ClientForMapping),
|
RESTMapper: mapper,
|
||||||
|
ClientMapper: resource.ClientMapperFunc(f.ClientForMapping),
|
||||||
}
|
}
|
||||||
info, err := resourceMapper.InfoForObject(obj, nil)
|
info, err := resourceMapper.InfoForObject(obj, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -718,7 +718,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error {
|
|||||||
|
|
||||||
for _, nodeInfo := range o.nodeInfos {
|
for _, nodeInfo := range o.nodeInfos {
|
||||||
if nodeInfo.Mapping.GroupVersionKind.Kind == "Node" {
|
if nodeInfo.Mapping.GroupVersionKind.Kind == "Node" {
|
||||||
obj, err := nodeInfo.Mapping.ConvertToVersion(nodeInfo.Object, nodeInfo.Mapping.GroupVersionKind.GroupVersion())
|
obj, err := nodeInfo.ObjectConverter.ConvertToVersion(nodeInfo.Object, nodeInfo.Mapping.GroupVersionKind.GroupVersion())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("error: unable to %s node %q: %v", cordonOrUncordon, nodeInfo.Name, err)
|
fmt.Printf("error: unable to %s node %q: %v", cordonOrUncordon, nodeInfo.Name, err)
|
||||||
continue
|
continue
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/util/validation"
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
@ -311,10 +312,11 @@ func (o *ExposeServiceOptions) RunExpose(cmd *cobra.Command, args []string) erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
resourceMapper := &resource.Mapper{
|
resourceMapper := &resource.Mapper{
|
||||||
ObjectTyper: o.Typer,
|
ObjectTyper: o.Typer,
|
||||||
RESTMapper: o.Mapper,
|
ObjectConverter: legacyscheme.Scheme,
|
||||||
ClientMapper: resource.ClientMapperFunc(o.ClientForMapping),
|
RESTMapper: o.Mapper,
|
||||||
Decoder: cmdutil.InternalVersionDecoder(),
|
ClientMapper: resource.ClientMapperFunc(o.ClientForMapping),
|
||||||
|
Decoder: cmdutil.InternalVersionDecoder(),
|
||||||
}
|
}
|
||||||
info, err = resourceMapper.InfoForObject(object, nil)
|
info, err = resourceMapper.InfoForObject(object, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -24,6 +24,7 @@ go_library(
|
|||||||
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/get",
|
importpath = "k8s.io/kubernetes/pkg/kubectl/cmd/get",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//pkg/api/legacyscheme:go_default_library",
|
||||||
"//pkg/apis/core:go_default_library",
|
"//pkg/apis/core:go_default_library",
|
||||||
"//pkg/kubectl:go_default_library",
|
"//pkg/kubectl:go_default_library",
|
||||||
"//pkg/kubectl/cmd/templates:go_default_library",
|
"//pkg/kubectl/cmd/templates:go_default_library",
|
||||||
@ -66,7 +67,6 @@ go_test(
|
|||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/api/legacyscheme:go_default_library",
|
"//pkg/api/legacyscheme:go_default_library",
|
||||||
"//pkg/api/testapi:go_default_library",
|
|
||||||
"//pkg/api/testing:go_default_library",
|
"//pkg/api/testing:go_default_library",
|
||||||
"//pkg/apis/core:go_default_library",
|
"//pkg/apis/core:go_default_library",
|
||||||
"//pkg/apis/core/v1:go_default_library",
|
"//pkg/apis/core/v1:go_default_library",
|
||||||
@ -77,8 +77,8 @@ go_test(
|
|||||||
"//pkg/kubectl/genericclioptions:go_default_library",
|
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||||
"//pkg/kubectl/scheme:go_default_library",
|
"//pkg/kubectl/scheme:go_default_library",
|
||||||
"//pkg/printers:go_default_library",
|
"//pkg/printers:go_default_library",
|
||||||
|
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/json:go_default_library",
|
||||||
|
@ -38,6 +38,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
@ -428,7 +429,14 @@ func (o *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
|
|||||||
lastMapping = mapping
|
lastMapping = mapping
|
||||||
}
|
}
|
||||||
|
|
||||||
printer.PrintObj(info.AsInternal(), w)
|
internalObj, err := legacyscheme.Scheme.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion())
|
||||||
|
if err != nil {
|
||||||
|
// if there's an error, try to print what you have (mirrors old behavior).
|
||||||
|
glog.V(1).Info(err)
|
||||||
|
printer.PrintObj(info.Object, w)
|
||||||
|
} else {
|
||||||
|
printer.PrintObj(internalObj, w)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
w.Flush()
|
w.Flush()
|
||||||
if nonEmptyObjCount == 0 && !o.IgnoreNotFound {
|
if nonEmptyObjCount == 0 && !o.IgnoreNotFound {
|
||||||
@ -542,7 +550,7 @@ func (o *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []string)
|
|||||||
if !o.IsGeneric {
|
if !o.IsGeneric {
|
||||||
// printing always takes the internal version, but the watch event uses externals
|
// printing always takes the internal version, but the watch event uses externals
|
||||||
internalGV := mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()
|
internalGV := mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()
|
||||||
objToPrint = attemptToConvertToInternal(objToPrint, mapping, internalGV)
|
objToPrint = attemptToConvertToInternal(objToPrint, legacyscheme.Scheme, internalGV)
|
||||||
}
|
}
|
||||||
if err := printer.PrintObj(objToPrint, writer); err != nil {
|
if err := printer.PrintObj(objToPrint, writer); err != nil {
|
||||||
return fmt.Errorf("unable to output the provided object: %v", err)
|
return fmt.Errorf("unable to output the provided object: %v", err)
|
||||||
@ -570,7 +578,7 @@ func (o *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []string)
|
|||||||
// printing always takes the internal version, but the watch event uses externals
|
// printing always takes the internal version, but the watch event uses externals
|
||||||
// TODO fix printing to use server-side or be version agnostic
|
// TODO fix printing to use server-side or be version agnostic
|
||||||
internalGV := mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()
|
internalGV := mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()
|
||||||
if err := printer.PrintObj(attemptToConvertToInternal(e.Object, mapping, internalGV), o.Out); err != nil {
|
if err := printer.PrintObj(attemptToConvertToInternal(e.Object, legacyscheme.Scheme, internalGV), o.Out); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
|
@ -27,24 +27,22 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
api "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||||
"k8s.io/apimachinery/pkg/runtime/serializer/streaming"
|
"k8s.io/apimachinery/pkg/runtime/serializer/streaming"
|
||||||
"k8s.io/apimachinery/pkg/util/diff"
|
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
"k8s.io/client-go/dynamic"
|
"k8s.io/client-go/dynamic"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/rest/fake"
|
"k8s.io/client-go/rest/fake"
|
||||||
restclientwatch "k8s.io/client-go/rest/watch"
|
restclientwatch "k8s.io/client-go/rest/watch"
|
||||||
"k8s.io/kube-openapi/pkg/util/proto"
|
"k8s.io/kube-openapi/pkg/util/proto"
|
||||||
"k8s.io/kubernetes/pkg/api/testapi"
|
|
||||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
|
||||||
"k8s.io/kubernetes/pkg/apis/core/v1"
|
"k8s.io/kubernetes/pkg/apis/core/v1"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/diff"
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
@ -104,11 +102,11 @@ func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList)
|
|||||||
Items: []api.Pod{
|
Items: []api.Pod{
|
||||||
{
|
{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"},
|
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"},
|
||||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
Spec: apitesting.V1DeepEqualSafePodSpec(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "11"},
|
ObjectMeta: metav1.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "11"},
|
||||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
Spec: apitesting.V1DeepEqualSafePodSpec(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -126,6 +124,8 @@ func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList)
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
one := int32(1)
|
||||||
rc := &api.ReplicationControllerList{
|
rc := &api.ReplicationControllerList{
|
||||||
ListMeta: metav1.ListMeta{
|
ListMeta: metav1.ListMeta{
|
||||||
ResourceVersion: "17",
|
ResourceVersion: "17",
|
||||||
@ -134,7 +134,7 @@ func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList)
|
|||||||
{
|
{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "rc1", Namespace: "test", ResourceVersion: "18"},
|
ObjectMeta: metav1.ObjectMeta{Name: "rc1", Namespace: "test", ResourceVersion: "18"},
|
||||||
Spec: api.ReplicationControllerSpec{
|
Spec: api.ReplicationControllerSpec{
|
||||||
Replicas: 1,
|
Replicas: &one,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -193,25 +193,6 @@ func TestGetUnknownSchemaObject(t *testing.T) {
|
|||||||
tf.Namespace = "test"
|
tf.Namespace = "test"
|
||||||
tf.ClientConfigVal = defaultClientConfig()
|
tf.ClientConfigVal = defaultClientConfig()
|
||||||
|
|
||||||
mapper, _ := tf.Object()
|
|
||||||
m, err := mapper.RESTMapping(schema.GroupKind{Group: "apitest", Kind: "Type"})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
convertedObj, err := m.ConvertToVersion(&unstructured.Unstructured{
|
|
||||||
Object: map[string]interface{}{
|
|
||||||
"kind": "Type",
|
|
||||||
"apiVersion": "apitest/unlikelyversion",
|
|
||||||
"name": "foo",
|
|
||||||
},
|
|
||||||
}, schema.GroupVersion{Group: "apitest", Version: "unlikelyversion"})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(convertedObj, obj) {
|
|
||||||
t.Fatalf("unexpected conversion of unstructured object to structured: %s", diff.ObjectReflectDiff(convertedObj, obj))
|
|
||||||
}
|
|
||||||
|
|
||||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||||
cmd := NewCmdGet("kubectl", tf, streams)
|
cmd := NewCmdGet("kubectl", tf, streams)
|
||||||
cmd.SetOutput(buf)
|
cmd.SetOutput(buf)
|
||||||
@ -246,7 +227,9 @@ func TestGetUnknownSchemaObject(t *testing.T) {
|
|||||||
func TestGetSchemaObject(t *testing.T) {
|
func TestGetSchemaObject(t *testing.T) {
|
||||||
tf := cmdtesting.NewTestFactory()
|
tf := cmdtesting.NewTestFactory()
|
||||||
defer tf.Cleanup()
|
defer tf.Cleanup()
|
||||||
codec := testapi.Default.Codec()
|
codec := legacyscheme.Codecs.LegacyCodec(schema.GroupVersion{Version: "v1"})
|
||||||
|
t.Logf("%v", string(runtime.EncodeOrDie(codec, &api.ReplicationController{ObjectMeta: metav1.ObjectMeta{Name: "foo"}})))
|
||||||
|
|
||||||
tf.UnstructuredClient = &fake.RESTClient{
|
tf.UnstructuredClient = &fake.RESTClient{
|
||||||
NegotiatedSerializer: unstructuredSerializer,
|
NegotiatedSerializer: unstructuredSerializer,
|
||||||
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &api.ReplicationController{ObjectMeta: metav1.ObjectMeta{Name: "foo"}})},
|
Resp: &http.Response{StatusCode: 200, Header: defaultHeader(), Body: objBody(codec, &api.ReplicationController{ObjectMeta: metav1.ObjectMeta{Name: "foo"}})},
|
||||||
@ -401,15 +384,15 @@ func TestGetSortedObjects(t *testing.T) {
|
|||||||
Items: []api.Pod{
|
Items: []api.Pod{
|
||||||
{
|
{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: "test", ResourceVersion: "10"},
|
ObjectMeta: metav1.ObjectMeta{Name: "c", Namespace: "test", ResourceVersion: "10"},
|
||||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
Spec: apitesting.V1DeepEqualSafePodSpec(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "b", Namespace: "test", ResourceVersion: "11"},
|
ObjectMeta: metav1.ObjectMeta{Name: "b", Namespace: "test", ResourceVersion: "11"},
|
||||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
Spec: apitesting.V1DeepEqualSafePodSpec(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ObjectMeta: metav1.ObjectMeta{Name: "a", Namespace: "test", ResourceVersion: "9"},
|
ObjectMeta: metav1.ObjectMeta{Name: "a", Namespace: "test", ResourceVersion: "9"},
|
||||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
Spec: apitesting.V1DeepEqualSafePodSpec(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -701,7 +684,6 @@ func TestGetMultipleTypeObjectsAsList(t *testing.T) {
|
|||||||
"containers": null,
|
"containers": null,
|
||||||
"dnsPolicy": "ClusterFirst",
|
"dnsPolicy": "ClusterFirst",
|
||||||
"restartPolicy": "Always",
|
"restartPolicy": "Always",
|
||||||
"schedulerName": "default-scheduler",
|
|
||||||
"securityContext": {},
|
"securityContext": {},
|
||||||
"terminationGracePeriodSeconds": 30
|
"terminationGracePeriodSeconds": 30
|
||||||
},
|
},
|
||||||
@ -720,7 +702,6 @@ func TestGetMultipleTypeObjectsAsList(t *testing.T) {
|
|||||||
"containers": null,
|
"containers": null,
|
||||||
"dnsPolicy": "ClusterFirst",
|
"dnsPolicy": "ClusterFirst",
|
||||||
"restartPolicy": "Always",
|
"restartPolicy": "Always",
|
||||||
"schedulerName": "default-scheduler",
|
|
||||||
"securityContext": {},
|
"securityContext": {},
|
||||||
"terminationGracePeriodSeconds": 30
|
"terminationGracePeriodSeconds": 30
|
||||||
},
|
},
|
||||||
@ -752,7 +733,7 @@ func TestGetMultipleTypeObjectsAsList(t *testing.T) {
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
if e, a := expected, buf.String(); e != a {
|
if e, a := expected, buf.String(); e != a {
|
||||||
t.Errorf("expected %v, got %v", e, a)
|
t.Errorf("did not match: %v", diff.StringDiff(e, a))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -896,7 +877,7 @@ func watchTestData() ([]api.Pod, []watch.Event) {
|
|||||||
Namespace: "test",
|
Namespace: "test",
|
||||||
ResourceVersion: "9",
|
ResourceVersion: "9",
|
||||||
},
|
},
|
||||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
Spec: apitesting.V1DeepEqualSafePodSpec(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@ -904,7 +885,7 @@ func watchTestData() ([]api.Pod, []watch.Event) {
|
|||||||
Namespace: "test",
|
Namespace: "test",
|
||||||
ResourceVersion: "10",
|
ResourceVersion: "10",
|
||||||
},
|
},
|
||||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
Spec: apitesting.V1DeepEqualSafePodSpec(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
events := []watch.Event{
|
events := []watch.Event{
|
||||||
@ -917,7 +898,7 @@ func watchTestData() ([]api.Pod, []watch.Event) {
|
|||||||
Namespace: "test",
|
Namespace: "test",
|
||||||
ResourceVersion: "9",
|
ResourceVersion: "9",
|
||||||
},
|
},
|
||||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
Spec: apitesting.V1DeepEqualSafePodSpec(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -928,7 +909,7 @@ func watchTestData() ([]api.Pod, []watch.Event) {
|
|||||||
Namespace: "test",
|
Namespace: "test",
|
||||||
ResourceVersion: "10",
|
ResourceVersion: "10",
|
||||||
},
|
},
|
||||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
Spec: apitesting.V1DeepEqualSafePodSpec(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// resource events
|
// resource events
|
||||||
@ -940,7 +921,7 @@ func watchTestData() ([]api.Pod, []watch.Event) {
|
|||||||
Namespace: "test",
|
Namespace: "test",
|
||||||
ResourceVersion: "11",
|
ResourceVersion: "11",
|
||||||
},
|
},
|
||||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
Spec: apitesting.V1DeepEqualSafePodSpec(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -951,7 +932,7 @@ func watchTestData() ([]api.Pod, []watch.Event) {
|
|||||||
Namespace: "test",
|
Namespace: "test",
|
||||||
ResourceVersion: "12",
|
ResourceVersion: "12",
|
||||||
},
|
},
|
||||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
Spec: apitesting.V1DeepEqualSafePodSpec(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,12 @@ func RunRollingUpdate(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args
|
|||||||
switch t := infos[0].AsVersioned().(type) {
|
switch t := infos[0].AsVersioned().(type) {
|
||||||
case *v1.ReplicationController:
|
case *v1.ReplicationController:
|
||||||
replicasDefaulted = t.Spec.Replicas == nil
|
replicasDefaulted = t.Spec.Replicas == nil
|
||||||
newRc, _ = infos[0].AsInternal().(*api.ReplicationController)
|
|
||||||
|
// previous code ignored the error. Seem like it's very unlikely to fail, so ok for now.
|
||||||
|
uncastObj, err := legacyscheme.Scheme.ConvertToVersion(t, api.SchemeGroupVersion)
|
||||||
|
if err == nil {
|
||||||
|
newRc, _ = uncastObj.(*api.ReplicationController)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if newRc == nil {
|
if newRc == nil {
|
||||||
glog.V(4).Infof("Object %T is not a ReplicationController", infos[0].Object)
|
glog.V(4).Infof("Object %T is not a ReplicationController", infos[0].Object)
|
||||||
|
@ -32,6 +32,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
@ -673,10 +674,11 @@ func (o *RunOptions) createGeneratedObject(f cmdutil.Factory, cmd *cobra.Command
|
|||||||
versioned := obj
|
versioned := obj
|
||||||
if !o.DryRun {
|
if !o.DryRun {
|
||||||
resourceMapper := &resource.Mapper{
|
resourceMapper := &resource.Mapper{
|
||||||
ObjectTyper: typer,
|
ObjectTyper: typer,
|
||||||
RESTMapper: mapper,
|
ObjectConverter: legacyscheme.Scheme,
|
||||||
ClientMapper: resource.ClientMapperFunc(f.ClientForMapping),
|
RESTMapper: mapper,
|
||||||
Decoder: cmdutil.InternalVersionDecoder(),
|
ClientMapper: resource.ClientMapperFunc(f.ClientForMapping),
|
||||||
|
Decoder: cmdutil.InternalVersionDecoder(),
|
||||||
}
|
}
|
||||||
info, err := resourceMapper.InfoForObject(obj, nil)
|
info, err := resourceMapper.InfoForObject(obj, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -272,7 +272,7 @@ func (o *EnvOptions) RunEnv(f cmdutil.Factory) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, info := range infos {
|
for _, info := range infos {
|
||||||
versionedObject, err := info.Mapping.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupVersion())
|
versionedObject, err := info.ObjectConverter.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupVersion())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ func (o TaintOptions) RunTaint() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
obj, err := info.Mapping.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupVersion())
|
obj, err := info.ObjectConverter.ConvertToVersion(info.Object, info.Mapping.GroupVersionKind.GroupVersion())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -346,16 +346,18 @@ func (f *TestFactory) NewBuilder() *resource.Builder {
|
|||||||
|
|
||||||
return resource.NewBuilder(
|
return resource.NewBuilder(
|
||||||
&resource.Mapper{
|
&resource.Mapper{
|
||||||
RESTMapper: mapper,
|
RESTMapper: mapper,
|
||||||
ObjectTyper: typer,
|
ObjectTyper: typer,
|
||||||
ClientMapper: resource.ClientMapperFunc(f.ClientForMapping),
|
ClientMapper: resource.ClientMapperFunc(f.ClientForMapping),
|
||||||
Decoder: cmdutil.InternalVersionDecoder(),
|
ObjectConverter: legacyscheme.Scheme,
|
||||||
|
Decoder: cmdutil.InternalVersionDecoder(),
|
||||||
},
|
},
|
||||||
&resource.Mapper{
|
&resource.Mapper{
|
||||||
RESTMapper: mapper,
|
RESTMapper: mapper,
|
||||||
ObjectTyper: typer,
|
ObjectTyper: typer,
|
||||||
ClientMapper: resource.ClientMapperFunc(f.UnstructuredClientForMapping),
|
ClientMapper: resource.ClientMapperFunc(f.UnstructuredClientForMapping),
|
||||||
Decoder: unstructured.UnstructuredJSONScheme,
|
ObjectConverter: unstructured.UnstructuredObjectConverter{},
|
||||||
|
Decoder: unstructured.UnstructuredJSONScheme,
|
||||||
},
|
},
|
||||||
f.CategoryExpander(),
|
f.CategoryExpander(),
|
||||||
)
|
)
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/client-go/dynamic"
|
"k8s.io/client-go/dynamic"
|
||||||
scaleclient "k8s.io/client-go/scale"
|
scaleclient "k8s.io/client-go/scale"
|
||||||
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
"k8s.io/kubernetes/pkg/kubectl"
|
"k8s.io/kubernetes/pkg/kubectl"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/plugins"
|
"k8s.io/kubernetes/pkg/kubectl/plugins"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||||
@ -55,16 +56,18 @@ func (f *ring2Factory) NewBuilder() *resource.Builder {
|
|||||||
|
|
||||||
return resource.NewBuilder(
|
return resource.NewBuilder(
|
||||||
&resource.Mapper{
|
&resource.Mapper{
|
||||||
RESTMapper: mapper,
|
RESTMapper: mapper,
|
||||||
ObjectTyper: typer,
|
ObjectTyper: typer,
|
||||||
ClientMapper: clientMapperFunc,
|
ObjectConverter: legacyscheme.Scheme,
|
||||||
Decoder: InternalVersionDecoder(),
|
ClientMapper: clientMapperFunc,
|
||||||
|
Decoder: InternalVersionDecoder(),
|
||||||
},
|
},
|
||||||
&resource.Mapper{
|
&resource.Mapper{
|
||||||
RESTMapper: mapper,
|
RESTMapper: mapper,
|
||||||
ObjectTyper: typer,
|
ObjectTyper: typer,
|
||||||
ClientMapper: unstructuredClientMapperFunc,
|
ObjectConverter: unstructured.UnstructuredObjectConverter{},
|
||||||
Decoder: unstructured.UnstructuredJSONScheme,
|
ClientMapper: unstructuredClientMapperFunc,
|
||||||
|
Decoder: unstructured.UnstructuredJSONScheme,
|
||||||
},
|
},
|
||||||
categoryExpander,
|
categoryExpander,
|
||||||
)
|
)
|
||||||
|
@ -474,10 +474,11 @@ func TestDiscoveryReplaceAliases(t *testing.T) {
|
|||||||
mapper := NewShortcutExpander(testapi.Default.RESTMapper(), ds)
|
mapper := NewShortcutExpander(testapi.Default.RESTMapper(), ds)
|
||||||
b := resource.NewBuilder(
|
b := resource.NewBuilder(
|
||||||
&resource.Mapper{
|
&resource.Mapper{
|
||||||
RESTMapper: mapper,
|
RESTMapper: mapper,
|
||||||
ObjectTyper: legacyscheme.Scheme,
|
ObjectTyper: legacyscheme.Scheme,
|
||||||
ClientMapper: fakeClient(),
|
ObjectConverter: legacyscheme.Scheme,
|
||||||
Decoder: testapi.Default.Codec(),
|
ClientMapper: fakeClient(),
|
||||||
|
Decoder: testapi.Default.Codec(),
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
categories.LegacyCategoryExpander,
|
categories.LegacyCategoryExpander,
|
||||||
|
@ -760,7 +760,7 @@ func (b *Builder) visitBySelector() *Result {
|
|||||||
if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
|
if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
|
||||||
selectorNamespace = ""
|
selectorNamespace = ""
|
||||||
}
|
}
|
||||||
visitors = append(visitors, NewSelector(client, mapping, selectorNamespace, labelSelector, fieldSelector, b.export, b.includeUninitialized, b.limitChunks))
|
visitors = append(visitors, NewSelector(client, mapping, b.mapper.ObjectConverter, selectorNamespace, labelSelector, fieldSelector, b.export, b.includeUninitialized, b.limitChunks))
|
||||||
}
|
}
|
||||||
if b.continueOnError {
|
if b.continueOnError {
|
||||||
result.visitor = EagerVisitorList(visitors)
|
result.visitor = EagerVisitorList(visitors)
|
||||||
@ -835,11 +835,12 @@ func (b *Builder) visitByResource() *Result {
|
|||||||
}
|
}
|
||||||
|
|
||||||
info := &Info{
|
info := &Info{
|
||||||
Client: client,
|
Client: client,
|
||||||
Mapping: mapping,
|
Mapping: mapping,
|
||||||
Namespace: selectorNamespace,
|
ObjectConverter: b.mapper.ObjectConverter,
|
||||||
Name: tuple.Name,
|
Namespace: selectorNamespace,
|
||||||
Export: b.export,
|
Name: tuple.Name,
|
||||||
|
Export: b.export,
|
||||||
}
|
}
|
||||||
items = append(items, info)
|
items = append(items, info)
|
||||||
}
|
}
|
||||||
@ -900,11 +901,12 @@ func (b *Builder) visitByName() *Result {
|
|||||||
visitors := []Visitor{}
|
visitors := []Visitor{}
|
||||||
for _, name := range b.names {
|
for _, name := range b.names {
|
||||||
info := &Info{
|
info := &Info{
|
||||||
Client: client,
|
Client: client,
|
||||||
Mapping: mapping,
|
Mapping: mapping,
|
||||||
Namespace: selectorNamespace,
|
ObjectConverter: b.mapper.ObjectConverter,
|
||||||
Name: name,
|
Namespace: selectorNamespace,
|
||||||
Export: b.export,
|
Name: name,
|
||||||
|
Export: b.export,
|
||||||
}
|
}
|
||||||
visitors = append(visitors, info)
|
visitors = append(visitors, info)
|
||||||
}
|
}
|
||||||
|
@ -270,10 +270,11 @@ func newDefaultBuilder() *Builder {
|
|||||||
func newDefaultBuilderWith(client ClientMapper) *Builder {
|
func newDefaultBuilderWith(client ClientMapper) *Builder {
|
||||||
return NewBuilder(
|
return NewBuilder(
|
||||||
&Mapper{
|
&Mapper{
|
||||||
RESTMapper: restmapper,
|
RESTMapper: restmapper,
|
||||||
ObjectTyper: scheme.Scheme,
|
ObjectTyper: scheme.Scheme,
|
||||||
ClientMapper: client,
|
ObjectConverter: scheme.Scheme,
|
||||||
Decoder: corev1Codec,
|
ClientMapper: client,
|
||||||
|
Decoder: corev1Codec,
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
categories.LegacyCategoryExpander,
|
categories.LegacyCategoryExpander,
|
||||||
|
@ -29,6 +29,8 @@ import (
|
|||||||
// needed to create Info for arbitrary objects.
|
// needed to create Info for arbitrary objects.
|
||||||
type Mapper struct {
|
type Mapper struct {
|
||||||
runtime.ObjectTyper
|
runtime.ObjectTyper
|
||||||
|
ObjectConverter runtime.ObjectConvertor
|
||||||
|
|
||||||
meta.RESTMapper
|
meta.RESTMapper
|
||||||
ClientMapper
|
ClientMapper
|
||||||
runtime.Decoder
|
runtime.Decoder
|
||||||
@ -70,8 +72,9 @@ func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) {
|
|||||||
resourceVersion, _ := metadataAccessor.ResourceVersion(obj)
|
resourceVersion, _ := metadataAccessor.ResourceVersion(obj)
|
||||||
|
|
||||||
return &Info{
|
return &Info{
|
||||||
Client: client,
|
Client: client,
|
||||||
Mapping: mapping,
|
Mapping: mapping,
|
||||||
|
ObjectConverter: m.ObjectConverter,
|
||||||
|
|
||||||
Source: source,
|
Source: source,
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
@ -109,8 +112,9 @@ func (m *Mapper) InfoForObject(obj runtime.Object, preferredGVKs []schema.GroupV
|
|||||||
namespace, _ := metadataAccessor.Namespace(obj)
|
namespace, _ := metadataAccessor.Namespace(obj)
|
||||||
resourceVersion, _ := metadataAccessor.ResourceVersion(obj)
|
resourceVersion, _ := metadataAccessor.ResourceVersion(obj)
|
||||||
return &Info{
|
return &Info{
|
||||||
Client: client,
|
Client: client,
|
||||||
Mapping: mapping,
|
Mapping: mapping,
|
||||||
|
ObjectConverter: m.ObjectConverter,
|
||||||
|
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
Name: name,
|
Name: name,
|
||||||
@ -199,7 +203,6 @@ func (m relaxedMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*me
|
|||||||
return &meta.RESTMapping{
|
return &meta.RESTMapping{
|
||||||
GroupVersionKind: gk.WithVersion(versions[0]),
|
GroupVersionKind: gk.WithVersion(versions[0]),
|
||||||
Scope: meta.RESTScopeRoot,
|
Scope: meta.RESTScopeRoot,
|
||||||
ObjectConvertor: identityConvertor{},
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
return mapping, err
|
return mapping, err
|
||||||
@ -211,7 +214,6 @@ func (m relaxedMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]
|
|||||||
{
|
{
|
||||||
GroupVersionKind: gk.WithVersion(versions[0]),
|
GroupVersionKind: gk.WithVersion(versions[0]),
|
||||||
Scope: meta.RESTScopeRoot,
|
Scope: meta.RESTScopeRoot,
|
||||||
ObjectConvertor: identityConvertor{},
|
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ import (
|
|||||||
type Selector struct {
|
type Selector struct {
|
||||||
Client RESTClient
|
Client RESTClient
|
||||||
Mapping *meta.RESTMapping
|
Mapping *meta.RESTMapping
|
||||||
|
ObjectConverter runtime.ObjectConvertor
|
||||||
Namespace string
|
Namespace string
|
||||||
LabelSelector string
|
LabelSelector string
|
||||||
FieldSelector string
|
FieldSelector string
|
||||||
@ -38,10 +40,11 @@ type Selector struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewSelector creates a resource selector which hides details of getting items by their label selector.
|
// NewSelector creates a resource selector which hides details of getting items by their label selector.
|
||||||
func NewSelector(client RESTClient, mapping *meta.RESTMapping, namespace, labelSelector, fieldSelector string, export, includeUninitialized bool, limitChunks int64) *Selector {
|
func NewSelector(client RESTClient, mapping *meta.RESTMapping, objectConverter runtime.ObjectConvertor, namespace, labelSelector, fieldSelector string, export, includeUninitialized bool, limitChunks int64) *Selector {
|
||||||
return &Selector{
|
return &Selector{
|
||||||
Client: client,
|
Client: client,
|
||||||
Mapping: mapping,
|
Mapping: mapping,
|
||||||
|
ObjectConverter: objectConverter,
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
LabelSelector: labelSelector,
|
LabelSelector: labelSelector,
|
||||||
FieldSelector: fieldSelector,
|
FieldSelector: fieldSelector,
|
||||||
@ -91,8 +94,9 @@ func (r *Selector) Visit(fn VisitorFunc) error {
|
|||||||
resourceVersion, _ := metadataAccessor.ResourceVersion(list)
|
resourceVersion, _ := metadataAccessor.ResourceVersion(list)
|
||||||
nextContinueToken, _ := metadataAccessor.Continue(list)
|
nextContinueToken, _ := metadataAccessor.Continue(list)
|
||||||
info := &Info{
|
info := &Info{
|
||||||
Client: r.Client,
|
Client: r.Client,
|
||||||
Mapping: r.Mapping,
|
Mapping: r.Mapping,
|
||||||
|
ObjectConverter: r.ObjectConverter,
|
||||||
|
|
||||||
Namespace: r.Namespace,
|
Namespace: r.Namespace,
|
||||||
ResourceVersion: resourceVersion,
|
ResourceVersion: resourceVersion,
|
||||||
|
@ -78,6 +78,9 @@ type Info struct {
|
|||||||
// Mapping may be nil if the object has no available metadata, but is still parseable
|
// Mapping may be nil if the object has no available metadata, but is still parseable
|
||||||
// from disk.
|
// from disk.
|
||||||
Mapping *meta.RESTMapping
|
Mapping *meta.RESTMapping
|
||||||
|
// ObjectConverter allows conversion
|
||||||
|
ObjectConverter runtime.ObjectConvertor
|
||||||
|
|
||||||
// Namespace will be set if the object is namespaced and has a specified value.
|
// Namespace will be set if the object is namespaced and has a specified value.
|
||||||
Namespace string
|
Namespace string
|
||||||
Name string
|
Name string
|
||||||
@ -180,23 +183,9 @@ func (i *Info) ResourceMapping() *meta.RESTMapping {
|
|||||||
return i.Mapping
|
return i.Mapping
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal attempts to convert the provided object to an internal type or returns an error.
|
|
||||||
func (i *Info) Internal() (runtime.Object, error) {
|
|
||||||
return i.Mapping.ConvertToVersion(i.Object, i.Mapping.GroupVersionKind.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion())
|
|
||||||
}
|
|
||||||
|
|
||||||
// AsInternal returns the object in internal form if possible, or i.Object if it cannot be
|
|
||||||
// converted.
|
|
||||||
func (i *Info) AsInternal() runtime.Object {
|
|
||||||
if obj, err := i.Internal(); err == nil {
|
|
||||||
return obj
|
|
||||||
}
|
|
||||||
return i.Object
|
|
||||||
}
|
|
||||||
|
|
||||||
// Versioned returns the object as a Go type in the mapping's version or returns an error.
|
// Versioned returns the object as a Go type in the mapping's version or returns an error.
|
||||||
func (i *Info) Versioned() (runtime.Object, error) {
|
func (i *Info) Versioned() (runtime.Object, error) {
|
||||||
return i.Mapping.ConvertToVersion(i.Object, i.Mapping.GroupVersionKind.GroupVersion())
|
return i.ObjectConverter.ConvertToVersion(i.Object, i.Mapping.GroupVersionKind.GroupVersion())
|
||||||
}
|
}
|
||||||
|
|
||||||
// AsVersioned returns the object as a Go object in the external form if possible (matching the
|
// AsVersioned returns the object as a Go object in the external form if possible (matching the
|
||||||
@ -219,7 +208,7 @@ func (i *Info) Unstructured() (runtime.Unstructured, error) {
|
|||||||
return out.(runtime.Unstructured), err
|
return out.(runtime.Unstructured), err
|
||||||
default:
|
default:
|
||||||
out := &unstructured.Unstructured{}
|
out := &unstructured.Unstructured{}
|
||||||
if err := i.Mapping.Convert(i.Object, out, nil); err != nil {
|
if err := i.ObjectConverter.Convert(i.Object, out, nil); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return out, nil
|
return out, nil
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
||||||
"k8s.io/apimachinery/pkg/labels"
|
"k8s.io/apimachinery/pkg/labels"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
@ -297,7 +298,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
|
// 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.
|
// trying to print, since the printers are keyed by type. This is extremely expensive.
|
||||||
if h.encoder != nil && h.decoder != nil {
|
if h.encoder != nil && h.decoder != nil {
|
||||||
obj, _ = decodeUnknownObject(obj, h.encoder, h.decoder)
|
obj, _ = decodeUnknownObject(obj, h.decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
// print with a registered handler
|
// print with a registered handler
|
||||||
@ -817,15 +818,19 @@ func AppendAllLabels(showLabels bool, itemLabels map[string]string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if the object is unstructured. If so, attempt to convert it to a type we can understand.
|
// check if the object is unstructured. If so, attempt to convert it to a type we can understand.
|
||||||
func decodeUnknownObject(obj runtime.Object, encoder runtime.Encoder, decoder runtime.Decoder) (runtime.Object, error) {
|
func decodeUnknownObject(obj runtime.Object, decoder runtime.Decoder) (runtime.Object, error) {
|
||||||
var err error
|
var err error
|
||||||
switch obj.(type) {
|
switch t := obj.(type) {
|
||||||
case runtime.Unstructured, *runtime.Unknown:
|
case runtime.Unstructured:
|
||||||
if objBytes, err := runtime.Encode(encoder, obj); err == nil {
|
if objBytes, err := runtime.Encode(unstructured.UnstructuredJSONScheme, obj); err == nil {
|
||||||
if decodedObj, err := runtime.Decode(decoder, objBytes); err == nil {
|
if decodedObj, err := runtime.Decode(decoder, objBytes); err == nil {
|
||||||
obj = decodedObj
|
obj = decodedObj
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
case *runtime.Unknown:
|
||||||
|
if decodedObj, err := runtime.Decode(decoder, t.Raw); err == nil {
|
||||||
|
obj = decodedObj
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj, err
|
return obj, err
|
||||||
|
@ -223,6 +223,10 @@ func (r *ScaleREST) GroupVersionKind(containingGV schema.GroupVersion) schema.Gr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ScaleREST) ClusterScoped() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// New creates a new Scale object
|
// New creates a new Scale object
|
||||||
func (r *ScaleREST) New() runtime.Object {
|
func (r *ScaleREST) New() runtime.Object {
|
||||||
return &autoscaling.Scale{}
|
return &autoscaling.Scale{}
|
||||||
|
@ -151,6 +151,10 @@ func (r *ScaleREST) GroupVersionKind(containingGV schema.GroupVersion) schema.Gr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ScaleREST) ClusterScoped() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// New creates a new Scale object
|
// New creates a new Scale object
|
||||||
func (r *ScaleREST) New() runtime.Object {
|
func (r *ScaleREST) New() runtime.Object {
|
||||||
return &autoscaling.Scale{}
|
return &autoscaling.Scale{}
|
||||||
|
@ -140,6 +140,10 @@ func (r *ScaleREST) GroupVersionKind(containingGV schema.GroupVersion) schema.Gr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ScaleREST) ClusterScoped() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// New creates a new Scale object
|
// New creates a new Scale object
|
||||||
func (r *ScaleREST) New() runtime.Object {
|
func (r *ScaleREST) New() runtime.Object {
|
||||||
return &autoscaling.Scale{}
|
return &autoscaling.Scale{}
|
||||||
|
@ -72,6 +72,11 @@ func (r *EvictionREST) GroupVersionKind(containingGV schema.GroupVersion) schema
|
|||||||
return schema.GroupVersionKind{Group: "policy", Version: "v1beta1", Kind: "Eviction"}
|
return schema.GroupVersionKind{Group: "policy", Version: "v1beta1", Kind: "Eviction"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClusterScoped fulfills GroupVersionKindProvider
|
||||||
|
func (*EvictionREST) ClusterScoped() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// New creates a new eviction resource
|
// New creates a new eviction resource
|
||||||
func (r *EvictionREST) New() runtime.Object {
|
func (r *EvictionREST) New() runtime.Object {
|
||||||
return &policy.Eviction{}
|
return &policy.Eviction{}
|
||||||
|
@ -140,6 +140,10 @@ func (r *ScaleREST) GroupVersionKind(containingGV schema.GroupVersion) schema.Gr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ScaleREST) ClusterScoped() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// New creates a new Scale object
|
// New creates a new Scale object
|
||||||
func (r *ScaleREST) New() runtime.Object {
|
func (r *ScaleREST) New() runtime.Object {
|
||||||
return &autoscaling.Scale{}
|
return &autoscaling.Scale{}
|
||||||
|
@ -46,6 +46,7 @@ type TokenREST struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var _ = rest.NamedCreater(&TokenREST{})
|
var _ = rest.NamedCreater(&TokenREST{})
|
||||||
|
var _ = rest.GroupVersionKindProvider(&TokenREST{})
|
||||||
|
|
||||||
func (r *TokenREST) Create(ctx context.Context, name string, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) {
|
func (r *TokenREST) Create(ctx context.Context, name string, obj runtime.Object, createValidation rest.ValidateObjectFunc, includeUninitialized bool) (runtime.Object, error) {
|
||||||
if err := createValidation(obj); err != nil {
|
if err := createValidation(obj); err != nil {
|
||||||
@ -120,6 +121,10 @@ func (r *TokenREST) GroupVersionKind(containingGV schema.GroupVersion) schema.Gr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*TokenREST) ClusterScoped() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
type getter interface {
|
type getter interface {
|
||||||
Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error)
|
Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error)
|
||||||
}
|
}
|
||||||
|
@ -145,6 +145,10 @@ func (r *ScaleREST) GroupVersionKind(containingGV schema.GroupVersion) schema.Gr
|
|||||||
return autoscalingv1.SchemeGroupVersion.WithKind("Scale")
|
return autoscalingv1.SchemeGroupVersion.WithKind("Scale")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*ScaleREST) ClusterScoped() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// New creates a new Scale object
|
// New creates a new Scale object
|
||||||
func (r *ScaleREST) New() runtime.Object {
|
func (r *ScaleREST) New() runtime.Object {
|
||||||
return &autoscalingv1.Scale{}
|
return &autoscalingv1.Scale{}
|
||||||
|
@ -25,7 +25,7 @@ import (
|
|||||||
|
|
||||||
// VersionInterfaces contains the interfaces one should use for dealing with types of a particular version.
|
// VersionInterfaces contains the interfaces one should use for dealing with types of a particular version.
|
||||||
type VersionInterfaces struct {
|
type VersionInterfaces struct {
|
||||||
runtime.ObjectConvertor
|
ObjectConvertor runtime.ObjectConvertor
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListMetaAccessor interface {
|
type ListMetaAccessor interface {
|
||||||
@ -91,13 +91,6 @@ const (
|
|||||||
type RESTScope interface {
|
type RESTScope interface {
|
||||||
// Name of the scope
|
// Name of the scope
|
||||||
Name() RESTScopeName
|
Name() RESTScopeName
|
||||||
// ParamName is the optional name of the parameter that should be inserted in the resource url
|
|
||||||
// If empty, no param will be inserted
|
|
||||||
ParamName() string
|
|
||||||
// ArgumentName is the optional name that should be used for the variable holding the value.
|
|
||||||
ArgumentName() string
|
|
||||||
// ParamDescription is the optional description to use to document the parameter in api documentation
|
|
||||||
ParamDescription() string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RESTMapping contains the information needed to deal with objects of a specific
|
// RESTMapping contains the information needed to deal with objects of a specific
|
||||||
@ -110,8 +103,6 @@ type RESTMapping struct {
|
|||||||
|
|
||||||
// Scope contains the information needed to deal with REST Resources that are in a resource hierarchy
|
// Scope contains the information needed to deal with REST Resources that are in a resource hierarchy
|
||||||
Scope RESTScope
|
Scope RESTScope
|
||||||
|
|
||||||
runtime.ObjectConvertor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RESTMapper allows clients to map resources to kind, and map kind and version
|
// RESTMapper allows clients to map resources to kind, and map kind and version
|
||||||
|
@ -28,30 +28,15 @@ import (
|
|||||||
|
|
||||||
// Implements RESTScope interface
|
// Implements RESTScope interface
|
||||||
type restScope struct {
|
type restScope struct {
|
||||||
name RESTScopeName
|
name RESTScopeName
|
||||||
paramName string
|
|
||||||
argumentName string
|
|
||||||
paramDescription string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *restScope) Name() RESTScopeName {
|
func (r *restScope) Name() RESTScopeName {
|
||||||
return r.name
|
return r.name
|
||||||
}
|
}
|
||||||
func (r *restScope) ParamName() string {
|
|
||||||
return r.paramName
|
|
||||||
}
|
|
||||||
func (r *restScope) ArgumentName() string {
|
|
||||||
return r.argumentName
|
|
||||||
}
|
|
||||||
func (r *restScope) ParamDescription() string {
|
|
||||||
return r.paramDescription
|
|
||||||
}
|
|
||||||
|
|
||||||
var RESTScopeNamespace = &restScope{
|
var RESTScopeNamespace = &restScope{
|
||||||
name: RESTScopeNameNamespace,
|
name: RESTScopeNameNamespace,
|
||||||
paramName: "namespaces",
|
|
||||||
argumentName: "namespace",
|
|
||||||
paramDescription: "object name and auth scope, such as for teams and projects",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var RESTScopeRoot = &restScope{
|
var RESTScopeRoot = &restScope{
|
||||||
@ -526,17 +511,10 @@ func (m *DefaultRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string
|
|||||||
return nil, fmt.Errorf("the provided version %q and kind %q cannot be mapped to a supported scope", gvk.GroupVersion(), gvk.Kind)
|
return nil, fmt.Errorf("the provided version %q and kind %q cannot be mapped to a supported scope", gvk.GroupVersion(), gvk.Kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
interfaces, err := m.interfacesFunc(gvk.GroupVersion())
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("the provided version %q has no relevant versions: %v", gvk.GroupVersion().String(), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
mappings = append(mappings, &RESTMapping{
|
mappings = append(mappings, &RESTMapping{
|
||||||
Resource: res.Resource,
|
Resource: res.Resource,
|
||||||
GroupVersionKind: gvk,
|
GroupVersionKind: gvk,
|
||||||
Scope: scope,
|
Scope: scope,
|
||||||
|
|
||||||
ObjectConvertor: interfaces.ObjectConvertor,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,10 +577,6 @@ func TestRESTMapperRESTMapping(t *testing.T) {
|
|||||||
t.Errorf("%d: unexpected resource: %#v", i, mapping)
|
t.Errorf("%d: unexpected resource: %#v", i, mapping)
|
||||||
}
|
}
|
||||||
|
|
||||||
if mapping.ObjectConvertor == nil {
|
|
||||||
t.Errorf("%d: missing codec: %#v", i, mapping)
|
|
||||||
}
|
|
||||||
|
|
||||||
groupVersion := testCase.ExpectedGroupVersion
|
groupVersion := testCase.ExpectedGroupVersion
|
||||||
if groupVersion == nil {
|
if groupVersion == nil {
|
||||||
groupVersion = &testCase.APIGroupVersions[0]
|
groupVersion = &testCase.APIGroupVersions[0]
|
||||||
@ -727,9 +723,6 @@ func TestRESTMapperRESTMappings(t *testing.T) {
|
|||||||
if mapping.Resource != exp.Resource {
|
if mapping.Resource != exp.Resource {
|
||||||
t.Errorf("%d - %d: unexpected resource: %#v", i, j, mapping)
|
t.Errorf("%d - %d: unexpected resource: %#v", i, j, mapping)
|
||||||
}
|
}
|
||||||
if mapping.ObjectConvertor == nil {
|
|
||||||
t.Errorf("%d - %d: missing codec: %#v", i, j, mapping)
|
|
||||||
}
|
|
||||||
if mapping.GroupVersionKind != exp.GroupVersionKind {
|
if mapping.GroupVersionKind != exp.GroupVersionKind {
|
||||||
t.Errorf("%d - %d: unexpected GroupVersionKind: %#v", i, j, mapping)
|
t.Errorf("%d - %d: unexpected GroupVersionKind: %#v", i, j, mapping)
|
||||||
}
|
}
|
||||||
@ -744,7 +737,7 @@ func TestRESTMapperReportsErrorOnBadVersion(t *testing.T) {
|
|||||||
|
|
||||||
mapper := NewDefaultRESTMapper([]schema.GroupVersion{expectedGroupVersion1, expectedGroupVersion2}, unmatchedVersionInterfaces)
|
mapper := NewDefaultRESTMapper([]schema.GroupVersion{expectedGroupVersion1, expectedGroupVersion2}, unmatchedVersionInterfaces)
|
||||||
mapper.Add(expectedGroupVersion1.WithKind("InternalObject"), RESTScopeNamespace)
|
mapper.Add(expectedGroupVersion1.WithKind("InternalObject"), RESTScopeNamespace)
|
||||||
_, err := mapper.RESTMapping(internalObjectGK, expectedGroupVersion1.Version)
|
_, err := mapper.RESTMapping(internalObjectGK, "test3")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("unexpected non-error")
|
t.Errorf("unexpected non-error")
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ go_library(
|
|||||||
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -153,8 +153,9 @@ func (gmf *GroupMetaFactory) Register(m *registered.APIRegistrationManager, sche
|
|||||||
accessor := meta.NewAccessor()
|
accessor := meta.NewAccessor()
|
||||||
|
|
||||||
groupMeta := &apimachinery.GroupMeta{
|
groupMeta := &apimachinery.GroupMeta{
|
||||||
GroupVersions: externalVersions,
|
GroupVersions: externalVersions,
|
||||||
SelfLinker: runtime.SelfLinker(accessor),
|
SelfLinker: runtime.SelfLinker(accessor),
|
||||||
|
RootScopedKinds: gmf.GroupArgs.RootScopedKinds,
|
||||||
}
|
}
|
||||||
for _, v := range externalVersions {
|
for _, v := range externalVersions {
|
||||||
gvf := gmf.VersionArgs[v.Version]
|
gvf := gmf.VersionArgs[v.Version]
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GroupMeta stores the metadata of a group.
|
// GroupMeta stores the metadata of a group.
|
||||||
@ -29,6 +30,8 @@ type GroupMeta struct {
|
|||||||
// GroupVersions is Group + all versions in that group.
|
// GroupVersions is Group + all versions in that group.
|
||||||
GroupVersions []schema.GroupVersion
|
GroupVersions []schema.GroupVersion
|
||||||
|
|
||||||
|
RootScopedKinds sets.String
|
||||||
|
|
||||||
// SelfLinker can set or get the SelfLink field of all API types.
|
// SelfLinker can set or get the SelfLink field of all API types.
|
||||||
// TODO: when versioning changes, make this part of each API definition.
|
// TODO: when versioning changes, make this part of each API definition.
|
||||||
// TODO(lavalamp): Combine SelfLinker & ResourceVersioner interfaces, force all uses
|
// TODO(lavalamp): Combine SelfLinker & ResourceVersioner interfaces, force all uses
|
||||||
|
@ -65,13 +65,13 @@ go_library(
|
|||||||
importpath = "k8s.io/apiserver/pkg/endpoints",
|
importpath = "k8s.io/apiserver/pkg/endpoints",
|
||||||
deps = [
|
deps = [
|
||||||
"//vendor/github.com/emicklei/go-restful:go_default_library",
|
"//vendor/github.com/emicklei/go-restful: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/apis/meta/v1:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||||
|
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/endpoints/discovery:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/endpoints/discovery:go_default_library",
|
||||||
"//vendor/k8s.io/apiserver/pkg/endpoints/handlers:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/endpoints/handlers:go_default_library",
|
||||||
|
@ -117,7 +117,6 @@ var parameterCodec = runtime.NewParameterCodec(scheme)
|
|||||||
|
|
||||||
var accessor = meta.NewAccessor()
|
var accessor = meta.NewAccessor()
|
||||||
var selfLinker runtime.SelfLinker = accessor
|
var selfLinker runtime.SelfLinker = accessor
|
||||||
var mapper, namespaceMapper meta.RESTMapper // The mappers with namespace and with legacy namespace scopes.
|
|
||||||
var admissionControl admission.Interface
|
var admissionControl admission.Interface
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -203,25 +202,6 @@ func init() {
|
|||||||
addTestTypes()
|
addTestTypes()
|
||||||
addNewTestTypes()
|
addNewTestTypes()
|
||||||
|
|
||||||
nsMapper := newMapper()
|
|
||||||
|
|
||||||
// enumerate all supported versions, get the kinds, and register with
|
|
||||||
// the mapper how to address our resources
|
|
||||||
for _, gv := range groupVersions {
|
|
||||||
for kind := range scheme.KnownTypes(gv) {
|
|
||||||
gvk := gv.WithKind(kind)
|
|
||||||
root := bool(kind == "SimpleRoot")
|
|
||||||
if root {
|
|
||||||
nsMapper.Add(gvk, meta.RESTScopeRoot)
|
|
||||||
} else {
|
|
||||||
nsMapper.Add(gvk, meta.RESTScopeNamespace)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mapper = nsMapper
|
|
||||||
namespaceMapper = nsMapper
|
|
||||||
|
|
||||||
scheme.AddFieldLabelConversionFunc(grouplessGroupVersion.String(), "Simple",
|
scheme.AddFieldLabelConversionFunc(grouplessGroupVersion.String(), "Simple",
|
||||||
func(label, value string) (string, string, error) {
|
func(label, value string) (string, string, error) {
|
||||||
return label, value, nil
|
return label, value, nil
|
||||||
@ -263,12 +243,12 @@ func handleInternal(storage map[string]rest.Storage, admissionControl admission.
|
|||||||
template := APIGroupVersion{
|
template := APIGroupVersion{
|
||||||
Storage: storage,
|
Storage: storage,
|
||||||
|
|
||||||
Creater: scheme,
|
Creater: scheme,
|
||||||
Convertor: scheme,
|
Convertor: scheme,
|
||||||
Defaulter: scheme,
|
Defaulter: scheme,
|
||||||
Typer: scheme,
|
Typer: scheme,
|
||||||
Linker: selfLinker,
|
Linker: selfLinker,
|
||||||
Mapper: namespaceMapper,
|
RootScopedKinds: sets.NewString("SimpleRoot"),
|
||||||
|
|
||||||
ParameterCodec: parameterCodec,
|
ParameterCodec: parameterCodec,
|
||||||
|
|
||||||
@ -841,7 +821,6 @@ func TestNotFound(t *testing.T) {
|
|||||||
|
|
||||||
if response.StatusCode != v.Status {
|
if response.StatusCode != v.Status {
|
||||||
t.Errorf("Expected %d for %s (%s), Got %#v", v.Status, v.Method, k, response)
|
t.Errorf("Expected %d for %s (%s), Got %#v", v.Status, v.Method, k, response)
|
||||||
t.Errorf("MAPPER: %v", mapper)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3188,15 +3167,15 @@ func TestParentResourceIsRequired(t *testing.T) {
|
|||||||
Storage: map[string]rest.Storage{
|
Storage: map[string]rest.Storage{
|
||||||
"simple/sub": storage,
|
"simple/sub": storage,
|
||||||
},
|
},
|
||||||
Root: "/" + prefix,
|
Root: "/" + prefix,
|
||||||
Creater: scheme,
|
Creater: scheme,
|
||||||
Convertor: scheme,
|
Convertor: scheme,
|
||||||
Defaulter: scheme,
|
Defaulter: scheme,
|
||||||
Typer: scheme,
|
Typer: scheme,
|
||||||
Linker: selfLinker,
|
Linker: selfLinker,
|
||||||
|
RootScopedKinds: sets.NewString("SimpleRoot"),
|
||||||
|
|
||||||
Admit: admissionControl,
|
Admit: admissionControl,
|
||||||
Mapper: namespaceMapper,
|
|
||||||
|
|
||||||
GroupVersion: newGroupVersion,
|
GroupVersion: newGroupVersion,
|
||||||
OptionsExternalVersion: &newGroupVersion,
|
OptionsExternalVersion: &newGroupVersion,
|
||||||
@ -3225,8 +3204,7 @@ func TestParentResourceIsRequired(t *testing.T) {
|
|||||||
Typer: scheme,
|
Typer: scheme,
|
||||||
Linker: selfLinker,
|
Linker: selfLinker,
|
||||||
|
|
||||||
Admit: admissionControl,
|
Admit: admissionControl,
|
||||||
Mapper: namespaceMapper,
|
|
||||||
|
|
||||||
GroupVersion: newGroupVersion,
|
GroupVersion: newGroupVersion,
|
||||||
OptionsExternalVersion: &newGroupVersion,
|
OptionsExternalVersion: &newGroupVersion,
|
||||||
@ -3806,6 +3784,8 @@ type SimpleXGSubresourceRESTStorage struct {
|
|||||||
itemGVK schema.GroupVersionKind
|
itemGVK schema.GroupVersionKind
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ = rest.GroupVersionKindProvider(&SimpleXGSubresourceRESTStorage{})
|
||||||
|
|
||||||
func (storage *SimpleXGSubresourceRESTStorage) New() runtime.Object {
|
func (storage *SimpleXGSubresourceRESTStorage) New() runtime.Object {
|
||||||
return &genericapitesting.SimpleXGSubresource{}
|
return &genericapitesting.SimpleXGSubresource{}
|
||||||
}
|
}
|
||||||
@ -3814,12 +3794,14 @@ func (storage *SimpleXGSubresourceRESTStorage) Get(ctx context.Context, id strin
|
|||||||
return storage.item.DeepCopyObject(), nil
|
return storage.item.DeepCopyObject(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ = rest.GroupVersionKindProvider(&SimpleXGSubresourceRESTStorage{})
|
|
||||||
|
|
||||||
func (storage *SimpleXGSubresourceRESTStorage) GroupVersionKind(containingGV schema.GroupVersion) schema.GroupVersionKind {
|
func (storage *SimpleXGSubresourceRESTStorage) GroupVersionKind(containingGV schema.GroupVersion) schema.GroupVersionKind {
|
||||||
return storage.itemGVK
|
return storage.itemGVK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*SimpleXGSubresourceRESTStorage) ClusterScoped() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func TestXGSubresource(t *testing.T) {
|
func TestXGSubresource(t *testing.T) {
|
||||||
container := restful.NewContainer()
|
container := restful.NewContainer()
|
||||||
container.Router(restful.CurlyRouter{})
|
container.Router(restful.CurlyRouter{})
|
||||||
@ -3845,7 +3827,6 @@ func TestXGSubresource(t *testing.T) {
|
|||||||
Defaulter: scheme,
|
Defaulter: scheme,
|
||||||
Typer: scheme,
|
Typer: scheme,
|
||||||
Linker: selfLinker,
|
Linker: selfLinker,
|
||||||
Mapper: namespaceMapper,
|
|
||||||
|
|
||||||
ParameterCodec: parameterCodec,
|
ParameterCodec: parameterCodec,
|
||||||
|
|
||||||
|
@ -22,11 +22,11 @@ import (
|
|||||||
|
|
||||||
"github.com/emicklei/go-restful"
|
"github.com/emicklei/go-restful"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
"k8s.io/apiserver/pkg/endpoints/discovery"
|
"k8s.io/apiserver/pkg/endpoints/discovery"
|
||||||
"k8s.io/apiserver/pkg/registry/rest"
|
"k8s.io/apiserver/pkg/registry/rest"
|
||||||
@ -55,7 +55,8 @@ type APIGroupVersion struct {
|
|||||||
// version (for when the inevitable meta/v2 group emerges).
|
// version (for when the inevitable meta/v2 group emerges).
|
||||||
MetaGroupVersion *schema.GroupVersion
|
MetaGroupVersion *schema.GroupVersion
|
||||||
|
|
||||||
Mapper meta.RESTMapper
|
// RootScopedKinds are the root scoped kinds for the primary GroupVersion
|
||||||
|
RootScopedKinds sets.String
|
||||||
|
|
||||||
// Serializer is used to determine how to convert responses from API methods into bytes to send over
|
// Serializer is used to determine how to convert responses from API methods into bytes to send over
|
||||||
// the wire.
|
// the wire.
|
||||||
|
@ -28,7 +28,6 @@ import (
|
|||||||
|
|
||||||
restful "github.com/emicklei/go-restful"
|
restful "github.com/emicklei/go-restful"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/conversion"
|
"k8s.io/apimachinery/pkg/conversion"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
@ -133,18 +132,18 @@ func (a *APIInstaller) newWebService() *restful.WebService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getResourceKind returns the external group version kind registered for the given storage
|
// getResourceKind returns the external group version kind registered for the given storage
|
||||||
// object. If the storage object is a subresource and has an override supplied for it, it returns
|
// object and whether or not the kind is cluster scoped. If the storage object is a subresource and has an override supplied for it, it returns
|
||||||
// the group version kind supplied in the override.
|
// the group version kind supplied in the override.
|
||||||
func (a *APIInstaller) getResourceKind(path string, storage rest.Storage) (schema.GroupVersionKind, error) {
|
func (a *APIInstaller) getResourceKind(path string, storage rest.Storage) (schema.GroupVersionKind, bool, error) {
|
||||||
// Let the storage tell us exactly what GVK it has
|
// Let the storage tell us exactly what GVK it has
|
||||||
if gvkProvider, ok := storage.(rest.GroupVersionKindProvider); ok {
|
if gvkProvider, ok := storage.(rest.GroupVersionKindProvider); ok {
|
||||||
return gvkProvider.GroupVersionKind(a.group.GroupVersion), nil
|
return gvkProvider.GroupVersionKind(a.group.GroupVersion), gvkProvider.ClusterScoped(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
object := storage.New()
|
object := storage.New()
|
||||||
fqKinds, _, err := a.group.Typer.ObjectKinds(object)
|
fqKinds, _, err := a.group.Typer.ObjectKinds(object)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return schema.GroupVersionKind{}, err
|
return schema.GroupVersionKind{}, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// a given go type can have multiple potential fully qualified kinds. Find the one that corresponds with the group
|
// a given go type can have multiple potential fully qualified kinds. Find the one that corresponds with the group
|
||||||
@ -157,32 +156,11 @@ func (a *APIInstaller) getResourceKind(path string, storage rest.Storage) (schem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if fqKindToRegister.Empty() {
|
if fqKindToRegister.Empty() {
|
||||||
return schema.GroupVersionKind{}, fmt.Errorf("unable to locate fully qualified kind for %v: found %v when registering for %v", reflect.TypeOf(object), fqKinds, a.group.GroupVersion)
|
return schema.GroupVersionKind{}, false, fmt.Errorf("unable to locate fully qualified kind for %v: found %v when registering for %v", reflect.TypeOf(object), fqKinds, a.group.GroupVersion)
|
||||||
}
|
}
|
||||||
return fqKindToRegister, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// restMapping returns rest mapper for the resource.
|
// group is guaranteed to match based on the check above
|
||||||
// Example REST paths that this mapper maps.
|
return fqKindToRegister, a.group.RootScopedKinds.Has(fqKindToRegister.Kind), nil
|
||||||
// 1. Resource only, no subresource:
|
|
||||||
// Resource Type: batch/v1.Job (input args: resource = "jobs")
|
|
||||||
// REST path: /apis/batch/v1/namespaces/{namespace}/job/{name}
|
|
||||||
// 2. Subresource and its parent belong to different API groups and/or versions:
|
|
||||||
// Resource Type: extensions/v1beta1.ReplicaSet (input args: resource = "replicasets")
|
|
||||||
// Subresource Type: autoscaling/v1.Scale
|
|
||||||
// REST path: /apis/extensions/v1beta1/namespaces/{namespace}/replicaset/{name}/scale
|
|
||||||
func (a *APIInstaller) restMapping(resource string) (*meta.RESTMapping, error) {
|
|
||||||
// subresources must have parent resources, and follow the namespacing rules of their parent.
|
|
||||||
// So get the storage of the resource (which is the parent resource in case of subresources)
|
|
||||||
storage, ok := a.group.Storage[resource]
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("unable to locate the storage object for resource: %s", resource)
|
|
||||||
}
|
|
||||||
fqKindToRegister, err := a.getResourceKind(resource, storage)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to locate fully qualified kind for mapper resource %s: %v", resource, err)
|
|
||||||
}
|
|
||||||
return a.group.Mapper.RESTMapping(fqKindToRegister.GroupKind(), fqKindToRegister.Version)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storage, ws *restful.WebService) (*metav1.APIResource, error) {
|
func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storage, ws *restful.WebService) (*metav1.APIResource, error) {
|
||||||
@ -198,12 +176,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
mapping, err := a.restMapping(resource)
|
fqKindToRegister, clusterScoped, err := a.getResourceKind(path, storage)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
fqKindToRegister, err := a.getResourceKind(path, storage)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -338,7 +311,6 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||||||
}
|
}
|
||||||
|
|
||||||
allowWatchList := isWatcher && isLister // watching on lists is allowed only for kinds that support both watch and list.
|
allowWatchList := isWatcher && isLister // watching on lists is allowed only for kinds that support both watch and list.
|
||||||
scope := mapping.Scope
|
|
||||||
nameParam := ws.PathParameter("name", "name of the "+kind).DataType("string")
|
nameParam := ws.PathParameter("name", "name of the "+kind).DataType("string")
|
||||||
pathParam := ws.PathParameter("path", "path to the resource").DataType("string")
|
pathParam := ws.PathParameter("path", "path to the resource").DataType("string")
|
||||||
|
|
||||||
@ -357,8 +329,8 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||||||
|
|
||||||
var apiResource metav1.APIResource
|
var apiResource metav1.APIResource
|
||||||
// Get the list of actions for the given scope.
|
// Get the list of actions for the given scope.
|
||||||
switch scope.Name() {
|
switch {
|
||||||
case meta.RESTScopeNameRoot:
|
case clusterScoped:
|
||||||
// Handle non-namespace scoped resources like nodes.
|
// Handle non-namespace scoped resources like nodes.
|
||||||
resourcePath := resource
|
resourcePath := resource
|
||||||
resourceParams := params
|
resourceParams := params
|
||||||
@ -402,10 +374,11 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||||||
actions = appendIf(actions, action{"CONNECT", itemPath, nameParams, namer, false}, isConnecter)
|
actions = appendIf(actions, action{"CONNECT", itemPath, nameParams, namer, false}, isConnecter)
|
||||||
actions = appendIf(actions, action{"CONNECT", itemPath + "/{path:*}", proxyParams, namer, false}, isConnecter && connectSubpath)
|
actions = appendIf(actions, action{"CONNECT", itemPath + "/{path:*}", proxyParams, namer, false}, isConnecter && connectSubpath)
|
||||||
break
|
break
|
||||||
case meta.RESTScopeNameNamespace:
|
default:
|
||||||
|
namespaceParamName := "namespaces"
|
||||||
// Handler for standard REST verbs (GET, PUT, POST and DELETE).
|
// Handler for standard REST verbs (GET, PUT, POST and DELETE).
|
||||||
namespaceParam := ws.PathParameter(scope.ArgumentName(), scope.ParamDescription()).DataType("string")
|
namespaceParam := ws.PathParameter("namespace", "object name and auth scope, such as for teams and projects").DataType("string")
|
||||||
namespacedPath := scope.ParamName() + "/{" + scope.ArgumentName() + "}/" + resource
|
namespacedPath := namespaceParamName + "/{" + "namespace" + "}/" + resource
|
||||||
namespaceParams := []*restful.Parameter{namespaceParam}
|
namespaceParams := []*restful.Parameter{namespaceParam}
|
||||||
|
|
||||||
resourcePath := namespacedPath
|
resourcePath := namespacedPath
|
||||||
@ -426,7 +399,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||||||
namer := handlers.ContextBasedNaming{
|
namer := handlers.ContextBasedNaming{
|
||||||
SelfLinker: a.group.Linker,
|
SelfLinker: a.group.Linker,
|
||||||
ClusterScoped: false,
|
ClusterScoped: false,
|
||||||
SelfLinkPathPrefix: gpath.Join(a.prefix, scope.ParamName()) + "/",
|
SelfLinkPathPrefix: gpath.Join(a.prefix, namespaceParamName) + "/",
|
||||||
SelfLinkPathSuffix: itemPathSuffix,
|
SelfLinkPathSuffix: itemPathSuffix,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,8 +428,6 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||||||
actions = appendIf(actions, action{"WATCHLIST", "watch/" + resource, params, namer, true}, allowWatchList)
|
actions = appendIf(actions, action{"WATCHLIST", "watch/" + resource, params, namer, true}, allowWatchList)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unsupported restscope: %s", scope.Name())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create Routes for the actions.
|
// Create Routes for the actions.
|
||||||
@ -539,7 +510,11 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||||||
|
|
||||||
// If there is a subresource, kind should be the parent's kind.
|
// If there is a subresource, kind should be the parent's kind.
|
||||||
if hasSubresource {
|
if hasSubresource {
|
||||||
fqParentKind, err := a.getResourceKind(resource, a.group.Storage[resource])
|
parentStorage, ok := a.group.Storage[resource]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("missing parent storage: %q", resource)
|
||||||
|
}
|
||||||
|
fqParentKind, _, err := a.getResourceKind(resource, parentStorage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -654,7 +629,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
|
|||||||
string(types.MergePatchType),
|
string(types.MergePatchType),
|
||||||
string(types.StrategicMergePatchType),
|
string(types.StrategicMergePatchType),
|
||||||
}
|
}
|
||||||
handler := metrics.InstrumentRouteFunc(action.Verb, resource, subresource, requestScope, restfulPatchResource(patcher, reqScope, admit, mapping.ObjectConvertor, supportedTypes))
|
handler := metrics.InstrumentRouteFunc(action.Verb, resource, subresource, requestScope, restfulPatchResource(patcher, reqScope, admit, a.group.Convertor, supportedTypes))
|
||||||
route := ws.PATCH(action.Path).To(handler).
|
route := ws.PATCH(action.Path).To(handler).
|
||||||
Doc(doc).
|
Doc(doc).
|
||||||
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
|
Param(ws.QueryParameter("pretty", "If 'true', then the output is pretty printed.")).
|
||||||
|
@ -83,6 +83,7 @@ type CategoriesProvider interface {
|
|||||||
// TODO KindProvider (only used by federation) should be removed and replaced with this, but that presents greater risk late in 1.8.
|
// TODO KindProvider (only used by federation) should be removed and replaced with this, but that presents greater risk late in 1.8.
|
||||||
type GroupVersionKindProvider interface {
|
type GroupVersionKindProvider interface {
|
||||||
GroupVersionKind(containingGV schema.GroupVersion) schema.GroupVersionKind
|
GroupVersionKind(containingGV schema.GroupVersion) schema.GroupVersionKind
|
||||||
|
ClusterScoped() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lister is an object that can retrieve resources that match the provided field and label criteria.
|
// Lister is an object that can retrieve resources that match the provided field and label criteria.
|
||||||
|
@ -423,7 +423,7 @@ func (s *GenericAPIServer) newAPIGroupVersion(apiGroupInfo *APIGroupInfo, groupV
|
|||||||
Defaulter: apiGroupInfo.Scheme,
|
Defaulter: apiGroupInfo.Scheme,
|
||||||
Typer: apiGroupInfo.Scheme,
|
Typer: apiGroupInfo.Scheme,
|
||||||
Linker: apiGroupInfo.GroupMeta.SelfLinker,
|
Linker: apiGroupInfo.GroupMeta.SelfLinker,
|
||||||
Mapper: apiGroupInfo.GroupMeta.RESTMapper,
|
RootScopedKinds: apiGroupInfo.GroupMeta.RootScopedKinds,
|
||||||
|
|
||||||
Admit: s.admissionControl,
|
Admit: s.admissionControl,
|
||||||
MinRequestTimeout: s.minRequestTimeout,
|
MinRequestTimeout: s.minRequestTimeout,
|
||||||
|
@ -192,7 +192,7 @@ func TestServerSidePrint(t *testing.T) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
intGV := gvk.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()
|
intGV := gvk.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()
|
||||||
intObj, err := mapping.ConvertToVersion(obj, intGV)
|
intObj, err := legacyscheme.Scheme.ConvertToVersion(obj, intGV)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error converting %s to internal: %v", gvk, err)
|
t.Errorf("unexpected error converting %s to internal: %v", gvk, err)
|
||||||
continue
|
continue
|
||||||
|
Loading…
Reference in New Issue
Block a user