Unverified Commit f03f83a2 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #63206 from deads2k/api-11-restmapper

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. remove incorrect static restmapper from type registry A RESTMapping can only be determined by inspecting a server since discovery is the authoritative source of mapping decisions. This removes a deceptive method from the type registry and makes the old logic available for existing tests in a separate, clearly labeled package. @kubernetes/sig-api-machinery-pr-reviews @kubernetes/sig-cli-maintainers ```release-note NONE ```
parents 8e99d621 1e5372b6
......@@ -48,7 +48,6 @@ go_library(
"//pkg/apis/settings/install:go_default_library",
"//pkg/apis/storage:go_default_library",
"//pkg/apis/storage/install: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/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer/recognizer:go_default_library",
......
......@@ -30,7 +30,6 @@ import (
"reflect"
"strings"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/recognizer"
......@@ -473,51 +472,3 @@ func (g TestGroup) SubResourcePath(resource, namespace, name, sub string) string
return path
}
// RESTMapper returns RESTMapper in legacyscheme.Registry.
func (g TestGroup) RESTMapper() meta.RESTMapper {
return legacyscheme.Registry.RESTMapper()
}
// ExternalGroupVersions returns all external group versions allowed for the server.
func ExternalGroupVersions() schema.GroupVersions {
versions := []schema.GroupVersion{}
for _, g := range Groups {
gv := g.GroupVersion()
versions = append(versions, *gv)
}
return versions
}
// GetCodecForObject gets codec based on runtime.Object
func GetCodecForObject(obj runtime.Object) (runtime.Codec, error) {
kinds, _, err := legacyscheme.Scheme.ObjectKinds(obj)
if err != nil {
return nil, fmt.Errorf("unexpected encoding error: %v", err)
}
kind := kinds[0]
for _, group := range Groups {
if group.GroupVersion().Group != kind.Group {
continue
}
if legacyscheme.Scheme.Recognizes(kind) {
return group.Codec(), nil
}
}
// Codec used for unversioned types
if legacyscheme.Scheme.Recognizes(kind) {
serializer, ok := runtime.SerializerInfoForMediaType(legacyscheme.Codecs.SupportedMediaTypes(), runtime.ContentTypeJSON)
if !ok {
return nil, fmt.Errorf("no serializer registered for json")
}
return serializer.Serializer, nil
}
return nil, fmt.Errorf("unexpected kind: %v", kind)
}
// NewTestGroup creates a new TestGroup.
func NewTestGroup(external, internal schema.GroupVersion, internalTypes map[string]reflect.Type, externalTypes map[string]reflect.Type) TestGroup {
return TestGroup{external, internal, internalTypes, externalTypes}
}
......@@ -31,7 +31,6 @@ go_test(
"//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",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
],
)
......
......@@ -45,18 +45,6 @@ func Install(registry *registered.APIRegistrationManager, scheme *runtime.Scheme
"PersistentVolume",
"ComponentStatus",
),
IgnoredKinds: sets.NewString(
"ListOptions",
"DeleteOptions",
"Status",
"PodLogOptions",
"PodExecOptions",
"PodAttachOptions",
"PodPortForwardOptions",
"PodProxyOptions",
"NodeProxyOptions",
"ServiceProxyOptions",
),
},
announced.VersionToSchemeFunc{
v1.SchemeGroupVersion.Version: v1.AddToScheme,
......
......@@ -24,7 +24,6 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/api/legacyscheme"
internal "k8s.io/kubernetes/pkg/apis/core"
)
......@@ -66,43 +65,6 @@ func TestCodec(t *testing.T) {
}
}
func TestRESTMapper(t *testing.T) {
gv := schema.GroupVersion{Group: "", Version: "v1"}
rcGVK := gv.WithKind("ReplicationController")
podTemplateGVK := gv.WithKind("PodTemplate")
if gvk, err := legacyscheme.Registry.RESTMapper().KindFor(internal.SchemeGroupVersion.WithResource("replicationcontrollers")); err != nil || gvk != rcGVK {
t.Errorf("unexpected version mapping: %v %v", gvk, err)
}
if m, err := legacyscheme.Registry.GroupOrDie(internal.GroupName).RESTMapper.RESTMapping(podTemplateGVK.GroupKind(), ""); err != nil || m.GroupVersionKind != podTemplateGVK || m.Resource != "podtemplates" {
t.Errorf("unexpected version mapping: %#v %v", m, err)
}
for _, version := range legacyscheme.Registry.GroupOrDie(internal.GroupName).GroupVersions {
mapping, err := legacyscheme.Registry.GroupOrDie(internal.GroupName).RESTMapper.RESTMapping(rcGVK.GroupKind(), version.Version)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if mapping.Resource != "replicationControllers" && mapping.Resource != "replicationcontrollers" {
t.Errorf("incorrect resource name: %#v", mapping)
}
if mapping.GroupVersionKind.GroupVersion() != version {
t.Errorf("incorrect version: %v", mapping)
}
rc := &internal.ReplicationController{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
name, err := meta.NewAccessor().Name(rc)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if name != "foo" {
t.Errorf("bad name: %q", name)
}
}
}
func TestUnversioned(t *testing.T) {
for _, obj := range []runtime.Object{
&metav1.Status{},
......
......@@ -14,7 +14,6 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/apis/core/validation",
visibility = ["//visibility:public"],
deps = [
"//pkg/api/legacyscheme:go_default_library",
"//pkg/api/service:go_default_library",
"//pkg/apis/core:go_default_library",
"//pkg/apis/core/helper:go_default_library",
......@@ -29,13 +28,11 @@ go_library(
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/validation:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/validation:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
......
......@@ -20,12 +20,9 @@ import (
"fmt"
"time"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/apis/core"
)
......@@ -90,40 +87,8 @@ func ValidateEvent(event *core.Event) field.ErrorList {
}
}
// For kinds we recognize, make sure InvolvedObject.Namespace is set for namespaced kinds
if namespaced, err := isNamespacedKind(event.InvolvedObject.Kind, event.InvolvedObject.APIVersion); err == nil {
if namespaced && len(event.InvolvedObject.Namespace) == 0 {
allErrs = append(allErrs, field.Required(field.NewPath("involvedObject", "namespace"), fmt.Sprintf("required for kind %s", event.InvolvedObject.Kind)))
}
if !namespaced && len(event.InvolvedObject.Namespace) > 0 {
allErrs = append(allErrs, field.Invalid(field.NewPath("involvedObject", "namespace"), event.InvolvedObject.Namespace, fmt.Sprintf("not allowed for kind %s", event.InvolvedObject.Kind)))
}
}
for _, msg := range validation.IsDNS1123Subdomain(event.Namespace) {
allErrs = append(allErrs, field.Invalid(field.NewPath("namespace"), event.Namespace, msg))
}
return allErrs
}
// Check whether the kind in groupVersion is scoped at the root of the api hierarchy
func isNamespacedKind(kind, groupVersion string) (bool, error) {
gv, err := schema.ParseGroupVersion(groupVersion)
if err != nil {
return false, err
}
g, err := legacyscheme.Registry.Group(gv.Group)
if err != nil {
return false, err
}
restMapping, err := g.RESTMapper.RESTMapping(schema.GroupKind{Group: gv.Group, Kind: kind}, gv.Version)
if err != nil {
return false, err
}
scopeName := restMapping.Scope.Name()
if scopeName == meta.RESTScopeNameNamespace {
return true, nil
}
return false, nil
}
......@@ -58,6 +58,7 @@ go_test(
"//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
......
......@@ -32,6 +32,7 @@ import (
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
......@@ -60,7 +61,7 @@ func TestGarbageCollectorConstruction(t *testing.T) {
config := &restclient.Config{}
config.ContentConfig.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: metaonly.NewMetadataCodecFactory()}
tweakableRM := meta.NewDefaultRESTMapper(nil)
rm := &testRESTMapper{meta.MultiRESTMapper{tweakableRM, legacyscheme.Registry.RESTMapper()}}
rm := &testRESTMapper{meta.MultiRESTMapper{tweakableRM, testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme)}}
metaOnlyClientPool := dynamic.NewClientPool(config, rm, dynamic.LegacyAPIPathResolverFunc)
config.ContentConfig.NegotiatedSerializer = nil
clientPool := dynamic.NewClientPool(config, rm, dynamic.LegacyAPIPathResolverFunc)
......@@ -190,15 +191,15 @@ type garbageCollector struct {
func setupGC(t *testing.T, config *restclient.Config) garbageCollector {
config.ContentConfig.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: metaonly.NewMetadataCodecFactory()}
metaOnlyClientPool := dynamic.NewClientPool(config, legacyscheme.Registry.RESTMapper(), dynamic.LegacyAPIPathResolverFunc)
metaOnlyClientPool := dynamic.NewClientPool(config, testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme), dynamic.LegacyAPIPathResolverFunc)
config.ContentConfig.NegotiatedSerializer = nil
clientPool := dynamic.NewClientPool(config, legacyscheme.Registry.RESTMapper(), dynamic.LegacyAPIPathResolverFunc)
clientPool := dynamic.NewClientPool(config, testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme), dynamic.LegacyAPIPathResolverFunc)
podResource := map[schema.GroupVersionResource]struct{}{{Version: "v1", Resource: "pods"}: {}}
client := fake.NewSimpleClientset()
sharedInformers := informers.NewSharedInformerFactory(client, 0)
alwaysStarted := make(chan struct{})
close(alwaysStarted)
gc, err := NewGarbageCollector(metaOnlyClientPool, clientPool, &testRESTMapper{legacyscheme.Registry.RESTMapper()}, podResource, ignoredResources, sharedInformers, alwaysStarted)
gc, err := NewGarbageCollector(metaOnlyClientPool, clientPool, &testRESTMapper{testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme)}, podResource, ignoredResources, sharedInformers, alwaysStarted)
if err != nil {
t.Fatal(err)
}
......@@ -433,7 +434,7 @@ func TestGCListWatcher(t *testing.T) {
testHandler := &fakeActionHandler{}
srv, clientConfig := testServerAndClientConfig(testHandler.ServeHTTP)
defer srv.Close()
clientPool := dynamic.NewClientPool(clientConfig, legacyscheme.Registry.RESTMapper(), dynamic.LegacyAPIPathResolverFunc)
clientPool := dynamic.NewClientPool(clientConfig, testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme), dynamic.LegacyAPIPathResolverFunc)
podResource := schema.GroupVersionResource{Version: "v1", Resource: "pods"}
client, err := clientPool.ClientForGroupVersionResource(podResource)
if err != nil {
......@@ -822,7 +823,7 @@ func TestGarbageCollectorSync(t *testing.T) {
t.Fatal(err)
}
rm := &testRESTMapper{legacyscheme.Registry.RESTMapper()}
rm := &testRESTMapper{testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme)}
metaOnlyClientPool := dynamic.NewClientPool(clientConfig, rm, dynamic.LegacyAPIPathResolverFunc)
clientPool := dynamic.NewClientPool(clientConfig, rm, dynamic.LegacyAPIPathResolverFunc)
podResource := map[schema.GroupVersionResource]struct{}{
......
......@@ -69,6 +69,7 @@ go_test(
"//vendor/k8s.io/api/autoscaling/v1:go_default_library",
"//vendor/k8s.io/api/autoscaling/v2beta1:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
......
......@@ -27,6 +27,7 @@ import (
autoscalingv1 "k8s.io/api/autoscaling/v1"
autoscalingv2 "k8s.io/api/autoscaling/v2beta1"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
......@@ -511,7 +512,7 @@ func (tc *testCase) prepareTestClient(t *testing.T) (*fake.Clientset, *metricsfa
}
name := getForAction.GetName()
mapper := legacyscheme.Registry.RESTMapper()
mapper := testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme)
metrics := &cmapi.MetricValueList{}
var matchedTarget *autoscalingv2.MetricSpec
for i, target := range tc.metricsTarget {
......@@ -649,7 +650,7 @@ func (tc *testCase) setupController(t *testing.T) (*HorizontalController, inform
eventClient.Core(),
testScaleClient,
testClient.Autoscaling(),
legacyscheme.Registry.RESTMapper(),
testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme),
replicaCalc,
informerFactory.Autoscaling().V1().HorizontalPodAutoscalers(),
controller.NoResyncPeriodFunc(),
......
......@@ -30,6 +30,7 @@ import (
autoscalingv1 "k8s.io/api/autoscaling/v1"
autoscalingv2 "k8s.io/api/autoscaling/v2beta1"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
......@@ -497,7 +498,7 @@ func (tc *legacyTestCase) runTest(t *testing.T) {
eventClient.Core(),
testScaleClient,
testClient.Autoscaling(),
legacyscheme.Registry.RESTMapper(),
testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme),
replicaCalc,
informerFactory.Autoscaling().V1().HorizontalPodAutoscalers(),
controller.NoResyncPeriodFunc(),
......
......@@ -47,6 +47,7 @@ go_test(
"//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/k8s.io/api/autoscaling/v2beta1:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
......
......@@ -23,6 +23,7 @@ import (
autoscalingapi "k8s.io/api/autoscaling/v2beta1"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
......@@ -153,7 +154,7 @@ func (tc *restClientTestCase) prepareTestClient(t *testing.T) (*metricsfake.Clie
return true, &metrics, nil
} else {
name := getForAction.GetName()
mapper := legacyscheme.Registry.RESTMapper()
mapper := testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme)
assert.NotNil(t, tc.singleObject, "should have only requested a single-object metric when we asked for metrics for a single object")
gk := schema.FromAPIVersionAndKind(tc.singleObject.APIVersion, tc.singleObject.Kind).GroupKind()
mapping, err := mapper.RESTMapping(gk)
......
......@@ -24,6 +24,7 @@ import (
autoscalingv2 "k8s.io/api/autoscaling/v2beta1"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
......@@ -221,7 +222,7 @@ func (tc *replicaCalcTestCase) prepareTestClient(t *testing.T) (*fake.Clientset,
return true, &metrics, nil
}
name := getForAction.GetName()
mapper := legacyscheme.Registry.RESTMapper()
mapper := testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme)
metrics := &cmapi.MetricValueList{}
assert.NotNil(t, tc.metric.singleObject, "should have only requested a single-object metric when calling GetObjectMetricReplicas")
gk := schema.FromAPIVersionAndKind(tc.metric.singleObject.APIVersion, tc.metric.singleObject.Kind).GroupKind()
......
......@@ -25,7 +25,6 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
......@@ -46,7 +45,6 @@ type SetLastAppliedOptions struct {
FilenameOptions resource.FilenameOptions
infoList []*resource.Info
mapper meta.RESTMapper
namespace string
enforceNamespace bool
dryRun bool
......@@ -117,7 +115,6 @@ func (o *SetLastAppliedOptions) Complete(f cmdutil.Factory, cmd *cobra.Command)
o.output = cmdutil.GetFlagString(cmd, "output")
o.shortOutput = o.output == "name"
o.mapper = f.RESTMapper()
var err error
o.namespace, o.enforceNamespace, err = f.DefaultNamespace()
if err != nil {
......@@ -205,7 +202,7 @@ func (o *SetLastAppliedOptions) RunSetLastApplied() error {
}
info.Refresh(patchedObj, false)
}
if err := o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil {
if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil {
return err
}
}
......
......@@ -127,7 +127,10 @@ func (o *CanIOptions) Complete(f cmdutil.Factory, args []string) error {
break
}
resourceTokens := strings.SplitN(args[1], "/", 2)
restMapper := f.RESTMapper()
restMapper, err := f.RESTMapper()
if err != nil {
return err
}
o.Resource = o.resourceFor(restMapper, resourceTokens[0])
if len(resourceTokens) > 1 {
o.ResourceName = resourceTokens[1]
......
......@@ -127,16 +127,20 @@ func NewCmdAutoscale(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *
}
func (o *AutoscaleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
var err error
o.dryRun = cmdutil.GetFlagBool(cmd, "dry-run")
o.createAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag)
o.builder = f.NewBuilder()
o.canBeAutoscaled = f.CanBeAutoscaled
o.mapper = f.RESTMapper()
o.mapper, err = f.RESTMapper()
if err != nil {
return err
}
o.clientForMapping = f.ClientForMapping
o.args = args
o.RecordFlags.Complete(f.Command(cmd, false))
var err error
o.Recorder, err = o.RecordFlags.ToRecorder()
if err != nil {
return err
......@@ -249,7 +253,7 @@ func (o *AutoscaleOptions) Run() error {
if err != nil {
return err
}
return printer.PrintObj(hpa.AsVersioned(legacyscheme.Scheme), o.Out)
return printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(hpa.Object, hpa.Mapping), o.Out)
}
if err := kubectl.CreateOrUpdateAnnotation(o.createAnnotation, hpa.Object, cmdutil.InternalVersionJSONEncoder()); err != nil {
......@@ -266,7 +270,7 @@ func (o *AutoscaleOptions) Run() error {
if err != nil {
return err
}
return printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
return printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, hpa.Mapping), o.Out)
})
if err != nil {
return err
......
......@@ -228,7 +228,7 @@ func (options *CertificateOptions) modifyCertificateCondition(builder *resource.
}
found++
return options.PrintObj(info.AsVersioned(legacyscheme.Scheme), options.Out)
return options.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), options.Out)
})
if found == 0 {
fmt.Fprintf(options.Out, "No resources found\n")
......
......@@ -389,7 +389,10 @@ func RunCreateSubcommand(f cmdutil.Factory, options *CreateSubcommandOptions) er
if err != nil {
return err
}
mapper := f.RESTMapper()
mapper, err := f.RESTMapper()
if err != nil {
return err
}
if !options.DryRun {
// create subcommands have compiled knowledge of things they create, so type them directly
gvks, _, err := legacyscheme.Scheme.ObjectKinds(obj)
......@@ -423,7 +426,7 @@ func RunCreateSubcommand(f cmdutil.Factory, options *CreateSubcommandOptions) er
}
// ensure we pass a versioned object to the printer
obj = info.AsVersioned(legacyscheme.Scheme)
obj = cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping)
} else {
if meta, err := meta.Accessor(obj); err == nil && nsOverriden {
meta.SetNamespace(namespace)
......
......@@ -437,8 +437,12 @@ func TestClusterRoleValidate(t *testing.T) {
for name, test := range tests {
t.Run(name, func(t *testing.T) {
test.clusterRoleOptions.Mapper = tf.RESTMapper()
err := test.clusterRoleOptions.Validate()
var err error
test.clusterRoleOptions.Mapper, err = tf.RESTMapper()
if err != nil {
t.Fatal(err)
}
err = test.clusterRoleOptions.Validate()
if test.expectErr && err == nil {
t.Errorf("%s: expect error happens, but validate passes.", name)
}
......
......@@ -205,7 +205,10 @@ func (o *CreateRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
o.ResourceNames = resourceNames
// Complete other options for Run.
o.Mapper = f.RESTMapper()
o.Mapper, err = f.RESTMapper()
if err != nil {
return err
}
o.DryRun = cmdutil.GetDryRunFlag(cmd)
o.OutputFormat = cmdutil.GetFlagString(cmd, "output")
......
......@@ -339,8 +339,12 @@ func TestValidate(t *testing.T) {
}
for name, test := range tests {
test.roleOptions.Mapper = tf.RESTMapper()
err := test.roleOptions.Validate()
var err error
test.roleOptions.Mapper, err = tf.RESTMapper()
if err != nil {
t.Fatal(err)
}
err = test.roleOptions.Validate()
if test.expectErr && err == nil {
t.Errorf("%s: expect error happens but validate passes.", name)
}
......
......@@ -29,7 +29,6 @@ import (
corev1 "k8s.io/api/core/v1"
policyv1beta1 "k8s.io/api/policy/v1beta1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/labels"
......@@ -68,7 +67,6 @@ type DrainOptions struct {
DeleteLocalData bool
Selector string
PodSelector string
mapper meta.RESTMapper
nodeInfos []*resource.Info
typer runtime.ObjectTyper
......@@ -741,7 +739,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error {
fmt.Printf("error: %v", err)
continue
}
printer.PrintObj(nodeInfo.AsVersioned(legacyscheme.Scheme), o.Out)
printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(nodeInfo.Object, nodeInfo.Mapping), o.Out)
} else {
if !o.DryRun {
helper := resource.NewHelper(o.restClient, nodeInfo.Mapping)
......@@ -767,7 +765,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error {
fmt.Fprintf(o.ErrOut, "%v", err)
continue
}
printer.PrintObj(nodeInfo.AsVersioned(legacyscheme.Scheme), o.Out)
printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(nodeInfo.Object, nodeInfo.Mapping), o.Out)
}
} else {
printer, err := o.ToPrinter("skipped")
......@@ -775,7 +773,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error {
fmt.Fprintf(o.ErrOut, "%v", err)
continue
}
printer.PrintObj(nodeInfo.AsVersioned(legacyscheme.Scheme), o.Out)
printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(nodeInfo.Object, nodeInfo.Mapping), o.Out)
}
}
......
......@@ -836,7 +836,6 @@ func TestDeletePods(t *testing.T) {
o := DrainOptions{
PrintFlags: printers.NewPrintFlags("drained"),
}
o.mapper = tf.RESTMapper()
o.Out = os.Stdout
o.ToPrinter = func(operation string) (printers.ResourcePrinterFunc, error) {
......
......@@ -91,12 +91,16 @@ func NewCmdExplain(parent string, f cmdutil.Factory, streams genericclioptions.I
}
func (o *ExplainOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
var err error
o.Recursive = cmdutil.GetFlagBool(cmd, "recursive")
o.ApiVersion = cmdutil.GetFlagString(cmd, "api-version")
o.Mapper = f.RESTMapper()
o.Mapper, err = f.RESTMapper()
if err != nil {
return err
}
var err error
o.Schema, err = f.OpenAPISchema()
if err != nil {
return err
......
......@@ -187,7 +187,10 @@ func (o *ExposeServiceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) e
o.MapBasedSelectorForObject = f.MapBasedSelectorForObject
o.PortsForObject = f.PortsForObject
o.ProtocolsForObject = f.ProtocolsForObject
o.Mapper = f.RESTMapper()
o.Mapper, err = f.RESTMapper()
if err != nil {
return err
}
o.LabelsForObject = f.LabelsForObject
o.Namespace, o.EnforceNamespace, err = f.DefaultNamespace()
......@@ -336,7 +339,7 @@ func (o *ExposeServiceOptions) RunExpose(cmd *cobra.Command, args []string) erro
return err
}
return o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
return o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out)
})
if err != nil {
return err
......
......@@ -21,7 +21,6 @@ import (
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/kubernetes/pkg/api/legacyscheme"
......@@ -43,7 +42,6 @@ type PauseConfig struct {
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
Pauser func(info *resource.Info) ([]byte, error)
Mapper meta.RESTMapper
Infos []*resource.Info
genericclioptions.IOStreams
......@@ -105,8 +103,6 @@ func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, args
return cmdutil.UsageErrorf(cmd, "%s", cmd.Use)
}
o.Mapper = f.RESTMapper()
o.Pauser = f.Pauser
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
......@@ -160,7 +156,7 @@ func (o PauseConfig) RunPause() error {
allErrs = append(allErrs, err)
continue
}
printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out)
continue
}
......@@ -176,7 +172,7 @@ func (o PauseConfig) RunPause() error {
allErrs = append(allErrs, err)
continue
}
printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out)
}
return utilerrors.NewAggregate(allErrs)
......
......@@ -21,7 +21,6 @@ import (
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/kubernetes/pkg/api/legacyscheme"
......@@ -43,7 +42,6 @@ type ResumeConfig struct {
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
Resumer func(object *resource.Info) ([]byte, error)
Mapper meta.RESTMapper
Infos []*resource.Info
genericclioptions.IOStreams
......@@ -103,8 +101,6 @@ func (o *ResumeConfig) CompleteResume(f cmdutil.Factory, cmd *cobra.Command, arg
return cmdutil.UsageErrorf(cmd, "%s", cmd.Use)
}
o.Mapper = f.RESTMapper()
o.Resumer = f.Resumer
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
......@@ -165,7 +161,7 @@ func (o ResumeConfig) RunResume() error {
allErrs = append(allErrs, err)
continue
}
printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out)
}
obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
......@@ -180,7 +176,7 @@ func (o ResumeConfig) RunResume() error {
allErrs = append(allErrs, err)
continue
}
printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out)
}
return utilerrors.NewAggregate(allErrs)
......
......@@ -19,7 +19,6 @@ package rollout
import (
"io"
"k8s.io/apimachinery/pkg/api/meta"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/kubectl"
......@@ -41,7 +40,6 @@ type UndoOptions struct {
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
Rollbackers []kubectl.Rollbacker
Mapper meta.RESTMapper
Infos []*resource.Info
ToRevision int64
DryRun bool
......@@ -107,7 +105,6 @@ func (o *UndoOptions) CompleteUndo(f cmdutil.Factory, cmd *cobra.Command, out io
}
o.ToRevision = cmdutil.GetFlagInt64(cmd, "to-revision")
o.Mapper = f.RESTMapper()
o.Out = out
o.DryRun = cmdutil.GetDryRunFlag(cmd)
......@@ -171,7 +168,7 @@ func (o *UndoOptions) RunUndo() error {
allErrs = append(allErrs, err)
continue
}
printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
printer.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out)
}
return utilerrors.NewAggregate(allErrs)
}
......@@ -643,7 +643,10 @@ func (o *RunOptions) createGeneratedObject(f cmdutil.Factory, cmd *cobra.Command
return nil, err
}
mapper := f.RESTMapper()
mapper, err := f.RESTMapper()
if err != nil {
return nil, err
}
// run has compiled knowledge of the thing is is creating
groupVersionKinds, _, err := legacyscheme.Scheme.ObjectKinds(obj)
if err != nil {
......@@ -693,7 +696,7 @@ func (o *RunOptions) createGeneratedObject(f cmdutil.Factory, cmd *cobra.Command
return nil, err
}
versioned = info.AsVersioned(legacyscheme.Scheme)
versioned = cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping)
}
return &RunObject{
Versioned: versioned,
......
......@@ -327,7 +327,7 @@ func (o *EnvOptions) RunEnv() error {
return err
}
patches := CalculatePatches(infos, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) {
info.Object = info.AsVersioned(legacyscheme.Scheme)
info.Object = cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping)
_, err := o.updatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error {
resolutionErrorsEncountered := false
containers, _ := selectContainers(spec.Containers, o.ContainerSelector)
......@@ -418,7 +418,7 @@ func (o *EnvOptions) RunEnv() error {
}
if o.Local || o.dryRun {
if err := o.PrintObj(patch.Info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil {
if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(patch.Info.Object, patch.Info.Mapping), o.Out); err != nil {
return err
}
continue
......@@ -437,7 +437,7 @@ func (o *EnvOptions) RunEnv() error {
return fmt.Errorf("at least one environment variable must be provided")
}
if err := o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil {
if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil {
return err
}
}
......
......@@ -211,7 +211,7 @@ func (o *SetImageOptions) Run() error {
patches := CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) {
transformed := false
info.Object = info.AsVersioned(legacyscheme.Scheme)
info.Object = cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping)
_, err := o.UpdatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error {
for name, image := range o.ContainerImages {
var (
......@@ -275,7 +275,7 @@ func (o *SetImageOptions) Run() error {
}
if o.Local || o.DryRun {
if err := o.PrintObj(patch.Info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil {
if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(patch.Info.Object, patch.Info.Mapping), o.Out); err != nil {
return err
}
continue
......@@ -289,7 +289,7 @@ func (o *SetImageOptions) Run() error {
}
info.Refresh(obj, true)
if err := o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil {
if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil {
return err
}
}
......
......@@ -224,7 +224,7 @@ func (o *SetResourcesOptions) Run() error {
allErrs := []error{}
patches := CalculatePatches(o.Infos, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) {
transformed := false
info.Object = info.AsVersioned(legacyscheme.Scheme)
info.Object = cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping)
_, err := o.UpdatePodSpecForObject(info.Object, func(spec *v1.PodSpec) error {
containers, _ := selectContainers(spec.Containers, o.ContainerSelector)
if len(containers) != 0 {
......@@ -277,7 +277,7 @@ func (o *SetResourcesOptions) Run() error {
}
if o.Local || o.DryRun {
if err := o.PrintObj(patch.Info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil {
if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(patch.Info.Object, patch.Info.Mapping), o.Out); err != nil {
return err
}
continue
......@@ -290,7 +290,7 @@ func (o *SetResourcesOptions) Run() error {
}
info.Refresh(obj, true)
if err := o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil {
if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil {
return err
}
}
......
......@@ -59,7 +59,6 @@ type SetSelectorOptions struct {
Recorder genericclioptions.Recorder
builder *resource.Builder
mapper meta.RESTMapper
genericclioptions.IOStreams
}
......@@ -140,9 +139,6 @@ func (o *SetSelectorOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, arg
return err
}
mapper := f.RESTMapper()
o.mapper = mapper
o.resources, o.selector, err = getResourcesAndSelector(args)
if err != nil {
return err
......@@ -208,7 +204,7 @@ func (o *SetSelectorOptions) RunSelector() error {
return r.Visit(func(info *resource.Info, err error) error {
patch := &Patch{Info: info}
CalculatePatch(patch, cmdutil.InternalVersionJSONEncoder(), func(info *resource.Info) ([]byte, error) {
versioned := info.AsVersioned(legacyscheme.Scheme)
versioned := cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping)
patch.Info.Object = versioned
selectErr := updateSelectorForObject(info.Object, *o.selector)
if selectErr != nil {
......@@ -236,7 +232,7 @@ func (o *SetSelectorOptions) RunSelector() error {
}
info.Refresh(patched, true)
return o.PrintObj(patch.Info.AsVersioned(legacyscheme.Scheme), o.Out)
return o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(patch.Info.Object, info.Mapping), o.Out)
})
}
......
......@@ -174,7 +174,7 @@ func (o *SetServiceAccountOptions) Complete(f cmdutil.Factory, cmd *cobra.Comman
func (o *SetServiceAccountOptions) Run() error {
patchErrs := []error{}
patchFn := func(info *resource.Info) ([]byte, error) {
info.Object = info.AsVersioned(legacyscheme.Scheme)
info.Object = cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping)
_, err := o.updatePodSpecForObject(info.Object, func(podSpec *v1.PodSpec) error {
podSpec.ServiceAccountName = o.serviceAccountName
return nil
......@@ -198,7 +198,7 @@ func (o *SetServiceAccountOptions) Run() error {
continue
}
if o.local || o.dryRun {
if err := o.PrintObj(patch.Info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil {
if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(patch.Info.Object, patch.Info.Mapping), o.Out); err != nil {
return err
}
continue
......@@ -210,7 +210,7 @@ func (o *SetServiceAccountOptions) Run() error {
}
info.Refresh(patched, true)
if err := o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out); err != nil {
if err := o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out); err != nil {
return err
}
}
......
......@@ -230,7 +230,7 @@ func (o *SubjectOptions) Run(fn updateSubjects) error {
transformed, err := updateSubjectForObject(info.Object, subjects, fn)
if transformed && err == nil {
// TODO: switch UpdatePodSpecForObject to work on v1.PodSpec
return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), info.AsVersioned(legacyscheme.Scheme))
return runtime.Encode(cmdutil.InternalVersionJSONEncoder(), cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping))
}
return nil, err
})
......@@ -263,7 +263,7 @@ func (o *SubjectOptions) Run(fn updateSubjects) error {
}
info.Refresh(obj, true)
return o.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
return o.PrintObj(cmdutil.AsDefaultVersionedOrOriginal(info.Object, info.Mapping), o.Out)
}
return utilerrors.NewAggregate(allErrs)
}
......
......@@ -22,6 +22,7 @@ go_library(
"//pkg/printers:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta/testrestmapper: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",
......
......@@ -28,6 +28,7 @@ import (
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
......@@ -337,7 +338,7 @@ func (f *TestFactory) Command(*cobra.Command, bool) string {
}
func (f *TestFactory) NewBuilder() *resource.Builder {
mapper := f.RESTMapper()
mapper, err := f.RESTMapper()
return resource.NewBuilder(
&resource.Mapper{
......@@ -351,7 +352,7 @@ func (f *TestFactory) NewBuilder() *resource.Builder {
Decoder: unstructured.UnstructuredJSONScheme,
},
f.CategoryExpander(),
)
).AddError(err)
}
func (f *TestFactory) KubernetesClientSet() (*kubernetes.Clientset, error) {
......@@ -425,7 +426,7 @@ func (f *TestFactory) ClientSetForVersion(requiredVersion *schema.GroupVersion)
return f.ClientSet()
}
func (f *TestFactory) RESTMapper() meta.RESTMapper {
func (f *TestFactory) RESTMapper() (meta.RESTMapper, error) {
groupResources := testDynamicResources()
mapper := discovery.NewRESTMapper(groupResources)
// for backwards compatibility with existing tests, allow rest mappings from the scheme to show up
......@@ -433,14 +434,14 @@ func (f *TestFactory) RESTMapper() meta.RESTMapper {
mapper = meta.FirstHitRESTMapper{
MultiRESTMapper: meta.MultiRESTMapper{
mapper,
legacyscheme.Registry.RESTMapper(),
testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme),
},
}
// TODO: should probably be the external scheme
fakeDs := &fakeCachedDiscoveryClient{}
expander := cmdutil.NewShortcutExpander(mapper, fakeDs)
return expander
return expander, nil
}
func (f *TestFactory) LogsForObject(object, options runtime.Object, timeout time.Duration) (*restclient.Request, error) {
......
......@@ -4,6 +4,7 @@ go_library(
name = "go_default_library",
srcs = [
"cached_discovery.go",
"conversion.go",
"factory.go",
"factory_builder.go",
"factory_client_access.go",
......@@ -104,6 +105,7 @@ go_test(
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
......
/*
Copyright 2018 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.
*/
package util
import (
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/api/legacyscheme"
)
// AsDefaultVersionedOrOriginal returns the object as a Go object in the external form if possible (matching the
// group version kind of the mapping if provided, a best guess based on serialization if not provided, or obj if it cannot be converted.
// TODO update call sites to specify the scheme they want on their builder.
func AsDefaultVersionedOrOriginal(obj runtime.Object, mapping *meta.RESTMapping) runtime.Object {
converter := runtime.ObjectConvertor(legacyscheme.Scheme)
groupVersioner := runtime.GroupVersioner(schema.GroupVersions(legacyscheme.Registry.RegisteredGroupVersions()))
if mapping != nil {
groupVersioner = mapping.GroupVersionKind.GroupVersion()
}
if obj, err := converter.ConvertToVersion(obj, groupVersioner); err == nil {
return obj
}
return obj
}
......@@ -164,7 +164,7 @@ type ClientAccessFactory interface {
// Generally they provide object typing and functions that build requests based on the negotiated clients.
type ObjectMappingFactory interface {
// Returns interfaces for dealing with arbitrary runtime.Objects.
RESTMapper() meta.RESTMapper
RESTMapper() (meta.RESTMapper, error)
// Returns interface for expanding categories like `all`.
CategoryExpander() categories.CategoryExpander
// Returns a RESTClient for working with the specified RESTMapping or an error. This is intended
......
......@@ -47,7 +47,7 @@ func NewBuilderFactory(clientAccessFactory ClientAccessFactory, objectMappingFac
// NewBuilder returns a new resource builder for structured api objects.
func (f *ring2Factory) NewBuilder() *resource.Builder {
clientMapperFunc := resource.ClientMapperFunc(f.objectMappingFactory.ClientForMapping)
mapper := f.objectMappingFactory.RESTMapper()
mapper, mapperErr := f.objectMappingFactory.RESTMapper()
unstructuredClientMapperFunc := resource.ClientMapperFunc(f.objectMappingFactory.UnstructuredClientForMapping)
......@@ -65,7 +65,7 @@ func (f *ring2Factory) NewBuilder() *resource.Builder {
Decoder: unstructured.UnstructuredJSONScheme,
},
categoryExpander,
)
).AddError(mapperErr)
}
// PluginLoader loads plugins from a path set by the KUBECTL_PLUGINS_PATH env var.
......@@ -97,7 +97,11 @@ func (f *ring2Factory) ScaleClient() (scaleclient.ScalesGetter, error) {
return nil, err
}
resolver := scaleclient.NewDiscoveryScaleKindResolver(discoClient)
mapper := f.objectMappingFactory.RESTMapper()
mapper, err := f.objectMappingFactory.RESTMapper()
if err != nil {
return nil, err
}
return scaleclient.New(restClient, mapper, dynamic.LegacyAPIPathResolverFunc, resolver), nil
}
......
......@@ -27,8 +27,6 @@ import (
"sync"
"time"
"github.com/golang/glog"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
......@@ -37,7 +35,6 @@ import (
"k8s.io/client-go/discovery"
"k8s.io/client-go/dynamic"
restclient "k8s.io/client-go/rest"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/batch"
api "k8s.io/kubernetes/pkg/apis/core"
......@@ -72,26 +69,18 @@ func NewObjectMappingFactory(clientAccessFactory ClientAccessFactory) ObjectMapp
return f
}
// objectLoader attempts to perform discovery against the server, and will fall back to
// the built in mapper if necessary. It supports unstructured objects either way, since
// the underlying Scheme supports Unstructured. The mapper will return converters that can
// convert versioned types to unstructured and back.
func (f *ring1Factory) restMapper() (meta.RESTMapper, error) {
// RESTMapper returns a mapper.
func (f *ring1Factory) RESTMapper() (meta.RESTMapper, error) {
discoveryClient, err := f.clientAccessFactory.DiscoveryClient()
if err != nil {
glog.V(3).Infof("Unable to get a discovery client to find server resources, falling back to hardcoded types: %v", err)
return legacyscheme.Registry.RESTMapper(), nil
return nil, err
}
// allow conversion between typed and unstructured objects
mapper := discovery.NewDeferredDiscoveryRESTMapper(discoveryClient)
// TODO: should this also indicate it recognizes typed objects?
expander := NewShortcutExpander(mapper, discoveryClient)
return expander, err
}
func (f *ring1Factory) RESTMapper() meta.RESTMapper {
return meta.NewLazyRESTMapperLoader(f.restMapper)
return expander, nil
}
func (f *ring1Factory) CategoryExpander() categories.CategoryExpander {
......
......@@ -26,6 +26,7 @@ import (
"k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
......@@ -34,6 +35,7 @@ import (
"k8s.io/apimachinery/pkg/watch"
manualfake "k8s.io/client-go/rest/fake"
testcore "k8s.io/client-go/testing"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/api/testapi"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
......@@ -470,7 +472,7 @@ func TestDiscoveryReplaceAliases(t *testing.T) {
}
ds := &fakeDiscoveryClient{}
mapper := NewShortcutExpander(testapi.Default.RESTMapper(), ds)
mapper := NewShortcutExpander(testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme), ds)
b := resource.NewBuilder(
&resource.Mapper{
RESTMapper: mapper,
......
......@@ -19,9 +19,10 @@ package util
import (
"testing"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/api/legacyscheme"
)
func TestReplaceAliases(t *testing.T) {
......@@ -126,7 +127,7 @@ func TestReplaceAliases(t *testing.T) {
}
ds := &fakeDiscoveryClient{}
mapper := NewShortcutExpander(testapi.Default.RESTMapper(), ds)
mapper := NewShortcutExpander(testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme), ds)
for _, test := range tests {
ds.serverResourcesHandler = func() ([]*metav1.APIResourceList, error) {
......@@ -178,7 +179,7 @@ func TestKindFor(t *testing.T) {
}
ds := &fakeDiscoveryClient{}
mapper := NewShortcutExpander(testapi.Default.RESTMapper(), ds)
mapper := NewShortcutExpander(testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme), ds)
for i, test := range tests {
ds.serverResourcesHandler = func() ([]*metav1.APIResourceList, error) {
......
......@@ -51,6 +51,7 @@ go_test(
deps = [
"//pkg/kubectl/cmd/util/openapi/testing:go_default_library",
"//pkg/kubectl/scheme:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
],
)
......@@ -20,6 +20,7 @@ import (
"reflect"
"testing"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
"k8s.io/kubernetes/pkg/kubectl/scheme"
)
......@@ -56,7 +57,7 @@ func TestSplitAndParseResourceRequest(t *testing.T) {
},
}
mapper := scheme.Registry.RESTMapper(scheme.Versions...)
mapper := testrestmapper.TestOnlyStaticRESTMapper(scheme.Registry, scheme.Scheme, scheme.Versions...)
for _, test := range tests {
gotInResource, gotFieldsPath, err := SplitAndParseResourceRequest(test.inresource, mapper)
if err != nil {
......
......@@ -65,6 +65,7 @@ go_test(
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
......
......@@ -56,6 +56,9 @@ type Builder struct {
// it does not ever need to rely upon discovery.
objectTyper runtime.ObjectTyper
// local indicates that we cannot make server calls
local bool
errs []error
paths []Visitor
......@@ -142,6 +145,14 @@ func (b *Builder) Schema(schema validation.Schema) *Builder {
return b
}
func (b *Builder) AddError(err error) *Builder {
if err == nil {
return b
}
b.errs = append(b.errs, err)
return b
}
// FilenameParam groups input in two categories: URLs and files (files, directories, STDIN)
// If enforceNamespace is false, namespaces in the specs will be allowed to
// override the default namespace. If it is true, namespaces that don't match
......@@ -192,6 +203,7 @@ func (b *Builder) Unstructured() *Builder {
return b
}
b.mapper = b.unstructured
b.mapper.localFn = b.isLocal
b.objectTyper = unstructuredscheme.NewUnstructuredObjectTyper()
return b
......@@ -212,6 +224,7 @@ func (b *Builder) Internal(typer runtime.ObjectTyper) *Builder {
return b
}
b.mapper = b.internal
b.mapper.localFn = b.isLocal
b.objectTyper = typer
return b
......@@ -227,12 +240,17 @@ func (b *Builder) LocalParam(local bool) *Builder {
// Local will avoid asking the server for results.
func (b *Builder) Local() *Builder {
b.local = true
mapper := *b.mapper
mapper.ClientMapper = DisabledClientForMapping{ClientMapper: mapper.ClientMapper}
b.mapper = &mapper
return b
}
func (b *Builder) isLocal() bool {
return b.local
}
// Mapper returns a copy of the current mapper.
func (b *Builder) Mapper() *Mapper {
mapper := *b.mapper
......
......@@ -34,6 +34,7 @@ import (
"k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
......@@ -58,7 +59,7 @@ var (
corev1GV = schema.GroupVersion{Version: "v1"}
corev1Codec = scheme.Codecs.CodecForVersions(scheme.Codecs.LegacyCodec(corev1GV), scheme.Codecs.UniversalDecoder(corev1GV), corev1GV, corev1GV)
metaAccessor = meta.NewAccessor()
restmapper = scheme.Registry.RESTMapper()
restmapper = testrestmapper.TestOnlyStaticRESTMapper(scheme.Registry, scheme.Scheme)
)
func stringBody(body string) io.ReadCloser {
......@@ -299,7 +300,8 @@ func TestPathBuilderAndVersionedObjectNotDefaulted(t *testing.T) {
if info.Name != "update-demo-kitten" || info.Namespace != "" || info.Object == nil {
t.Errorf("unexpected info: %#v", info)
}
obj := info.AsVersioned(legacyscheme.Scheme)
obj := info.Object
version, ok := obj.(*v1.ReplicationController)
// versioned object does not have defaulting applied
if obj == nil || !ok || version.Spec.Replicas != nil {
......
......@@ -22,6 +22,8 @@ import (
client "k8s.io/client-go/rest"
)
type RESTMapperFunc func() (meta.RESTMapper, error)
// RESTClient is a client helper for dealing with RESTful resources
// in a generic way.
type RESTClient interface {
......
......@@ -28,6 +28,9 @@ import (
// Mapper is a convenience struct for holding references to the interfaces
// needed to create Info for arbitrary objects.
type Mapper struct {
// localFn indicates the call can't make server requests
localFn func() bool
RESTMapper meta.RESTMapper
ClientMapper ClientMapper
Decoder runtime.Decoder
......@@ -42,31 +45,34 @@ func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) {
return nil, fmt.Errorf("unable to decode %q: %v", source, err)
}
mapping, err := m.RESTMapper.RESTMapping(gvk.GroupKind(), gvk.Version)
if err != nil {
return nil, fmt.Errorf("unable to recognize %q: %v", source, err)
}
client, err := m.ClientMapper.ClientForMapping(mapping)
if err != nil {
return nil, fmt.Errorf("unable to connect to a server to handle %q: %v", mapping.Resource, err)
}
name, _ := metadataAccessor.Name(obj)
namespace, _ := metadataAccessor.Namespace(obj)
resourceVersion, _ := metadataAccessor.ResourceVersion(obj)
return &Info{
Client: client,
Mapping: mapping,
ret := &Info{
Source: source,
Namespace: namespace,
Name: name,
ResourceVersion: resourceVersion,
Object: obj,
}, nil
}
if m.localFn == nil || !m.localFn() {
mapping, err := m.RESTMapper.RESTMapping(gvk.GroupKind(), gvk.Version)
if err != nil {
return nil, fmt.Errorf("unable to recognize %q: %v", source, err)
}
ret.Mapping = mapping
client, err := m.ClientMapper.ClientForMapping(mapping)
if err != nil {
return nil, fmt.Errorf("unable to connect to a server to handle %q: %v", mapping.Resource, err)
}
ret.Client = client
}
return ret, nil
}
// InfoForObject creates an Info object for the given Object. An error is returned
......@@ -78,33 +84,37 @@ func (m *Mapper) InfoForObject(obj runtime.Object, typer runtime.ObjectTyper, pr
return nil, fmt.Errorf("unable to get type info from the object %q: %v", reflect.TypeOf(obj), err)
}
groupVersionKind := groupVersionKinds[0]
gvk := groupVersionKinds[0]
if len(groupVersionKinds) > 1 && len(preferredGVKs) > 0 {
groupVersionKind = preferredObjectKind(groupVersionKinds, preferredGVKs)
}
mapping, err := m.RESTMapper.RESTMapping(groupVersionKind.GroupKind(), groupVersionKind.Version)
if err != nil {
return nil, fmt.Errorf("unable to recognize %v: %v", groupVersionKind, err)
gvk = preferredObjectKind(groupVersionKinds, preferredGVKs)
}
client, err := m.ClientMapper.ClientForMapping(mapping)
if err != nil {
return nil, fmt.Errorf("unable to connect to a server to handle %q: %v", mapping.Resource, err)
}
name, _ := metadataAccessor.Name(obj)
namespace, _ := metadataAccessor.Namespace(obj)
resourceVersion, _ := metadataAccessor.ResourceVersion(obj)
return &Info{
Client: client,
Mapping: mapping,
ret := &Info{
Namespace: namespace,
Name: name,
ResourceVersion: resourceVersion,
Object: obj,
}, nil
}
if m.localFn == nil || !m.localFn() {
mapping, err := m.RESTMapper.RESTMapping(gvk.GroupKind(), gvk.Version)
if err != nil {
return nil, fmt.Errorf("unable to recognize %v", err)
}
ret.Mapping = mapping
client, err := m.ClientMapper.ClientForMapping(mapping)
if err != nil {
return nil, fmt.Errorf("unable to connect to a server to handle %q: %v", mapping.Resource, err)
}
ret.Client = client
}
return ret, nil
}
// preferredObjectKind picks the possibility that most closely matches the priority list in this order:
......
......@@ -180,22 +180,6 @@ func (i *Info) ResourceMapping() *meta.RESTMapping {
return i.Mapping
}
// Versioned returns the object as a Go type in the mapping's version or returns an error.
func (i *Info) versioned(convertor runtime.ObjectConvertor) (runtime.Object, error) {
return convertor.ConvertToVersion(i.Object, i.Mapping.GroupVersionKind.GroupVersion())
}
// AsVersioned returns the object as a Go object in the external form if possible (matching the
// group version kind of the mapping, or i.Object if it cannot be converted.
// Deprecated this function will be removed once calling code is updated to indicate the correct
// negoticatedserializers during construction of the builder
func (i *Info) AsVersioned(convertor runtime.ObjectConvertor) runtime.Object {
if obj, err := i.versioned(convertor); err == nil {
return obj
}
return i.Object
}
// VisitorList implements Visit for the sub visitors it contains. The first error
// returned from a child Visitor will terminate iteration.
type VisitorList []Visitor
......
......@@ -71,18 +71,6 @@ func init() {
"PersistentVolume",
"ComponentStatus",
),
IgnoredKinds: sets.NewString(
"ListOptions",
"DeleteOptions",
"Status",
"PodLogOptions",
"PodExecOptions",
"PodAttachOptions",
"PodPortForwardOptions",
"PodProxyOptions",
"NodeProxyOptions",
"ServiceProxyOptions",
),
},
announced.VersionToSchemeFunc{
corev1.SchemeGroupVersion.Version: corev1.AddToScheme,
......
......@@ -30,6 +30,7 @@ go_test(
"//pkg/api/legacyscheme:go_default_library",
"//pkg/apis/core:go_default_library",
"//pkg/kubeapiserver/admission:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
......
......@@ -20,6 +20,7 @@ import (
"strings"
"testing"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
......@@ -87,7 +88,7 @@ func newGCPermissionsEnforcement() (*gcPermissionsEnforcement, error) {
}
genericPluginInitializer := initializer.New(nil, nil, fakeAuthorizer{}, nil)
pluginInitializer := kubeadmission.NewPluginInitializer(nil, nil, nil, legacyscheme.Registry.RESTMapper(), nil)
pluginInitializer := kubeadmission.NewPluginInitializer(nil, nil, nil, testrestmapper.TestOnlyStaticRESTMapper(legacyscheme.Registry, legacyscheme.Scheme), nil)
initializersChain := admission.PluginInitializers{}
initializersChain = append(initializersChain, genericPluginInitializer)
initializersChain = append(initializersChain, pluginInitializer)
......
......@@ -65,6 +65,7 @@ filegroup(
srcs = [
":package-srcs",
"//staging/src/k8s.io/apimachinery/pkg/api/meta/table:all-srcs",
"//staging/src/k8s.io/apimachinery/pkg/api/meta/testrestmapper:all-srcs",
],
tags = ["automanaged"],
)
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["test_restmapper.go"],
importpath = "k8s.io/apimachinery/pkg/api/meta/testrestmapper",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apimachinery:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apimachinery/registered: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/util/sets:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
/*
Copyright 2018 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.
*/
package testrestmapper
import (
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apimachinery"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
)
// TestOnlyStaticRESTMapper returns a union RESTMapper of all known types with priorities chosen in the following order:
// 1. legacy kube group preferred version, extensions preferred version, metrics perferred version, legacy
// kube any version, extensions any version, metrics any version, all other groups alphabetical preferred version,
// all other groups alphabetical.
func TestOnlyStaticRESTMapper(m *registered.APIRegistrationManager, scheme *runtime.Scheme, versionPatterns ...schema.GroupVersion) meta.RESTMapper {
unionMapper := meta.MultiRESTMapper{}
unionedGroups := sets.NewString()
for _, enabledVersion := range m.RegisteredGroupVersions() {
if !unionedGroups.Has(enabledVersion.Group) {
unionedGroups.Insert(enabledVersion.Group)
groupMeta := m.GroupOrDie(enabledVersion.Group)
if groupMeta != nil {
unionMapper = append(unionMapper, newRESTMapper(scheme, groupMeta))
}
}
}
if len(versionPatterns) != 0 {
resourcePriority := []schema.GroupVersionResource{}
kindPriority := []schema.GroupVersionKind{}
for _, versionPriority := range versionPatterns {
resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource))
kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind))
}
return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
}
prioritizedGroups := []string{"", "extensions", "metrics"}
resourcePriority, kindPriority := prioritiesForGroups(m, prioritizedGroups...)
prioritizedGroupsSet := sets.NewString(prioritizedGroups...)
remainingGroups := sets.String{}
for _, enabledVersion := range m.RegisteredGroupVersions() {
if !prioritizedGroupsSet.Has(enabledVersion.Group) {
remainingGroups.Insert(enabledVersion.Group)
}
}
remainingResourcePriority, remainingKindPriority := prioritiesForGroups(m, remainingGroups.List()...)
resourcePriority = append(resourcePriority, remainingResourcePriority...)
kindPriority = append(kindPriority, remainingKindPriority...)
return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
}
// prioritiesForGroups returns the resource and kind priorities for a PriorityRESTMapper, preferring the preferred version of each group first,
// then any non-preferred version of the group second.
func prioritiesForGroups(m *registered.APIRegistrationManager, groups ...string) ([]schema.GroupVersionResource, []schema.GroupVersionKind) {
resourcePriority := []schema.GroupVersionResource{}
kindPriority := []schema.GroupVersionKind{}
for _, group := range groups {
availableVersions := m.RegisteredVersionsForGroup(group)
if len(availableVersions) > 0 {
resourcePriority = append(resourcePriority, availableVersions[0].WithResource(meta.AnyResource))
kindPriority = append(kindPriority, availableVersions[0].WithKind(meta.AnyKind))
}
}
for _, group := range groups {
resourcePriority = append(resourcePriority, schema.GroupVersionResource{Group: group, Version: meta.AnyVersion, Resource: meta.AnyResource})
kindPriority = append(kindPriority, schema.GroupVersionKind{Group: group, Version: meta.AnyVersion, Kind: meta.AnyKind})
}
return resourcePriority, kindPriority
}
func newRESTMapper(scheme *runtime.Scheme, groupMeta *apimachinery.GroupMeta) meta.RESTMapper {
// the list of kinds that are scoped at the root of the api hierarchy
// if a kind is not enumerated here, it is assumed to have a namespace scope
rootScoped := sets.NewString()
if groupMeta.RootScopedKinds != nil {
rootScoped = groupMeta.RootScopedKinds
}
mapper := meta.NewDefaultRESTMapper(groupMeta.GroupVersions)
for _, gv := range groupMeta.GroupVersions {
for kind := range scheme.KnownTypes(gv) {
if ignoredKinds.Has(kind) {
continue
}
scope := meta.RESTScopeNamespace
if rootScoped.Has(kind) {
scope = meta.RESTScopeRoot
}
mapper.Add(gv.WithKind(kind), scope)
}
}
return mapper
}
// hardcoded is good enough for the test we're running
var ignoredKinds = sets.NewString(
"ListOptions",
"DeleteOptions",
"Status",
"PodLogOptions",
"PodExecOptions",
"PodAttachOptions",
"PodPortForwardOptions",
"PodProxyOptions",
"NodeProxyOptions",
"ServiceProxyOptions",
)
......@@ -13,7 +13,6 @@ go_library(
],
importpath = "k8s.io/apimachinery/pkg/apimachinery",
deps = [
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
],
......
......@@ -11,7 +11,6 @@ go_library(
importpath = "k8s.io/apimachinery/pkg/apimachinery/announced",
deps = [
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apimachinery:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apimachinery/registered:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
......
......@@ -21,7 +21,6 @@ import (
"github.com/golang/glog"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apimachinery"
"k8s.io/apimachinery/pkg/apimachinery/registered"
"k8s.io/apimachinery/pkg/runtime"
......@@ -49,7 +48,6 @@ type GroupMetaFactoryArgs struct {
VersionPreferenceOrder []string
// RootScopedKinds are resources that are not namespaced.
RootScopedKinds sets.String // nil is allowed
IgnoredKinds sets.String // nil is allowed
// May be nil if there are no internal objects.
AddInternalObjectsToScheme SchemeFunc
......@@ -154,40 +152,9 @@ func (gmf *GroupMetaFactory) Register(m *registered.APIRegistrationManager, sche
GroupVersions: externalVersions,
RootScopedKinds: gmf.GroupArgs.RootScopedKinds,
}
groupMeta.RESTMapper = gmf.newRESTMapper(scheme, externalVersions, groupMeta)
if err := m.RegisterGroup(*groupMeta); err != nil {
return err
}
return nil
}
func (gmf *GroupMetaFactory) newRESTMapper(scheme *runtime.Scheme, externalVersions []schema.GroupVersion, groupMeta *apimachinery.GroupMeta) meta.RESTMapper {
// the list of kinds that are scoped at the root of the api hierarchy
// if a kind is not enumerated here, it is assumed to have a namespace scope
rootScoped := sets.NewString()
if gmf.GroupArgs.RootScopedKinds != nil {
rootScoped = gmf.GroupArgs.RootScopedKinds
}
ignoredKinds := sets.NewString()
if gmf.GroupArgs.IgnoredKinds != nil {
ignoredKinds = gmf.GroupArgs.IgnoredKinds
}
mapper := meta.NewDefaultRESTMapper(externalVersions)
for _, gv := range externalVersions {
for kind := range scheme.KnownTypes(gv) {
if ignoredKinds.Has(kind) {
continue
}
scope := meta.RESTScopeNamespace
if rootScoped.Has(kind) {
scope = meta.RESTScopeRoot
}
mapper.Add(gv.WithKind(kind), scope)
}
}
return mapper
}
......@@ -21,10 +21,8 @@ go_library(
srcs = ["registered.go"],
importpath = "k8s.io/apimachinery/pkg/apimachinery/registered",
deps = [
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apimachinery:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
],
)
......
......@@ -22,10 +22,8 @@ import (
"sort"
"strings"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apimachinery"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
)
// APIRegistrationManager provides the concept of what API groups are enabled.
......@@ -140,73 +138,6 @@ func (m *APIRegistrationManager) GroupOrDie(group string) *apimachinery.GroupMet
return &groupMetaCopy
}
// RESTMapper returns a union RESTMapper of all known types with priorities chosen in the following order:
// 1. legacy kube group preferred version, extensions preferred version, metrics perferred version, legacy
// kube any version, extensions any version, metrics any version, all other groups alphabetical preferred version,
// all other groups alphabetical.
func (m *APIRegistrationManager) RESTMapper(versionPatterns ...schema.GroupVersion) meta.RESTMapper {
unionMapper := meta.MultiRESTMapper{}
unionedGroups := sets.NewString()
for enabledVersion := range m.registeredVersions {
if !unionedGroups.Has(enabledVersion.Group) {
unionedGroups.Insert(enabledVersion.Group)
groupMeta := m.groupMetaMap[enabledVersion.Group]
if groupMeta != nil {
unionMapper = append(unionMapper, groupMeta.RESTMapper)
}
}
}
if len(versionPatterns) != 0 {
resourcePriority := []schema.GroupVersionResource{}
kindPriority := []schema.GroupVersionKind{}
for _, versionPriority := range versionPatterns {
resourcePriority = append(resourcePriority, versionPriority.WithResource(meta.AnyResource))
kindPriority = append(kindPriority, versionPriority.WithKind(meta.AnyKind))
}
return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
}
prioritizedGroups := []string{"", "extensions", "metrics"}
resourcePriority, kindPriority := m.prioritiesForGroups(prioritizedGroups...)
prioritizedGroupsSet := sets.NewString(prioritizedGroups...)
remainingGroups := sets.String{}
for enabledVersion := range m.registeredVersions {
if !prioritizedGroupsSet.Has(enabledVersion.Group) {
remainingGroups.Insert(enabledVersion.Group)
}
}
remainingResourcePriority, remainingKindPriority := m.prioritiesForGroups(remainingGroups.List()...)
resourcePriority = append(resourcePriority, remainingResourcePriority...)
kindPriority = append(kindPriority, remainingKindPriority...)
return meta.PriorityRESTMapper{Delegate: unionMapper, ResourcePriority: resourcePriority, KindPriority: kindPriority}
}
// prioritiesForGroups returns the resource and kind priorities for a PriorityRESTMapper, preferring the preferred version of each group first,
// then any non-preferred version of the group second.
func (m *APIRegistrationManager) prioritiesForGroups(groups ...string) ([]schema.GroupVersionResource, []schema.GroupVersionKind) {
resourcePriority := []schema.GroupVersionResource{}
kindPriority := []schema.GroupVersionKind{}
for _, group := range groups {
availableVersions := m.RegisteredVersionsForGroup(group)
if len(availableVersions) > 0 {
resourcePriority = append(resourcePriority, availableVersions[0].WithResource(meta.AnyResource))
kindPriority = append(kindPriority, availableVersions[0].WithKind(meta.AnyKind))
}
}
for _, group := range groups {
resourcePriority = append(resourcePriority, schema.GroupVersionResource{Group: group, Version: meta.AnyVersion, Resource: meta.AnyResource})
kindPriority = append(kindPriority, schema.GroupVersionKind{Group: group, Version: meta.AnyVersion, Kind: meta.AnyKind})
}
return resourcePriority, kindPriority
}
// AllPreferredGroupVersions returns the preferred versions of all registered
// groups in the form of "group1/version1,group2/version2,..."
func (m *APIRegistrationManager) AllPreferredGroupVersions() string {
......
......@@ -17,7 +17,6 @@ limitations under the License.
package apimachinery
import (
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets"
)
......@@ -28,8 +27,4 @@ type GroupMeta struct {
GroupVersions []schema.GroupVersion
RootScopedKinds sets.String
// RESTMapper provides the default mapping between REST paths and the objects declared in a Scheme and all known
// versions.
RESTMapper meta.RESTMapper
}
......@@ -16,7 +16,6 @@ go_test(
embed = [":go_default_library"],
deps = [
"//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apimachinery:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
......
......@@ -34,7 +34,6 @@ import (
// "github.com/go-openapi/spec"
"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apimachinery"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
......@@ -153,13 +152,8 @@ func TestInstallAPIGroups(t *testing.T) {
scheme.AddKnownTypes(v1GroupVersion, &metav1.Status{})
metav1.AddToGroupVersion(scheme, v1GroupVersion)
mapper := meta.NewDefaultRESTMapper([]schema.GroupVersion{gv})
for kind := range scheme.KnownTypes(gv) {
mapper.Add(gv.WithKind(kind), meta.RESTScopeNamespace)
}
groupMeta := apimachinery.GroupMeta{
GroupVersions: []schema.GroupVersion{gv},
RESTMapper: mapper,
}
return APIGroupInfo{
......
......@@ -147,8 +147,11 @@ func TestServerSidePrint(t *testing.T) {
printer := newFakePrinter(printersinternal.AddHandlers)
factory := util.NewFactory(clientcmd.NewDefaultClientConfig(*createKubeConfig(s.URL), &clientcmd.ConfigOverrides{}))
mapper := factory.RESTMapper()
mapper, err := factory.RESTMapper()
if err != nil {
t.Errorf("unexpected error getting mapper: %v", err)
return
}
for gvk, apiType := range legacyscheme.Scheme.AllKnownTypes() {
// we do not care about internal objects or lists // TODO make sure this is always true
if gvk.Version == runtime.APIVersionInternal || strings.HasSuffix(apiType.Name(), "List") {
......
......@@ -21,7 +21,6 @@ go_test(
"//cmd/kube-apiserver/app/options:go_default_library",
"//pkg/api/legacyscheme:go_default_library",
"//pkg/apis/core:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/master:go_default_library",
"//test/integration:go_default_library",
"//test/integration/framework:go_default_library",
......@@ -38,10 +37,10 @@ go_test(
"//vendor/k8s.io/apiserver/pkg/server:go_default_library",
"//vendor/k8s.io/apiserver/pkg/server/options:go_default_library",
"//vendor/k8s.io/apiserver/pkg/storage/storagebackend:go_default_library",
"//vendor/k8s.io/client-go/discovery:go_default_library",
"//vendor/k8s.io/client-go/discovery/cached:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
"//vendor/k8s.io/client-go/util/flowcontrol:go_default_library",
],
)
......
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