Merge pull request #63010 from deads2k/api-04-metadataaccessor

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 confusing flexibility for metadata interpretation

Metadata accessors are coded in.  This means that we don't need to inject flexibility, the flexibility is already present based on what your code relies up.  This removes the per-individual resource injection which simplifies all calling code.

intersection of @kubernetes/sig-api-machinery-pr-reviews @kubernetes/sig-cli-maintainers 

```release-note
NONE
```
This commit is contained in:
Kubernetes Submit Queue 2018-04-24 17:59:12 -07:00 committed by GitHub
commit 6fbca94fae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 113 additions and 165 deletions

View File

@ -417,16 +417,6 @@ func (g TestGroup) Converter() runtime.ObjectConvertor {
return interfaces.ObjectConvertor return interfaces.ObjectConvertor
} }
// MetadataAccessor returns the MetadataAccessor for the API version to test against,
// as set by the KUBE_TEST_API env var.
func (g TestGroup) MetadataAccessor() meta.MetadataAccessor {
interfaces, err := legacyscheme.Registry.GroupOrDie(g.externalGroupVersion.Group).InterfacesFor(g.externalGroupVersion)
if err != nil {
panic(err)
}
return interfaces.MetadataAccessor
}
// SelfLink returns a self link that will appear to be for the version Version(). // SelfLink returns a self link that will appear to be for the version Version().
// 'resource' should be the resource path, e.g. "pods" for the Pod type. 'name' should be // 'resource' should be the resource path, e.g. "pods" for the Pod type. 'name' should be
// empty for lists. // empty for lists.

View File

@ -28,7 +28,7 @@ go_test(
deps = [ deps = [
"//pkg/api/legacyscheme:go_default_library", "//pkg/api/legacyscheme:go_default_library",
"//pkg/apis/core:go_default_library", "//pkg/apis/core: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/apis/meta/v1: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:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",

View File

@ -21,7 +21,7 @@ import (
"reflect" "reflect"
"testing" "testing"
"k8s.io/api/core/v1" "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"
@ -30,18 +30,8 @@ import (
) )
func TestResourceVersioner(t *testing.T) { func TestResourceVersioner(t *testing.T) {
g, err := legacyscheme.Registry.Group(v1.GroupName)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
intf, err := g.DefaultInterfacesFor(v1.SchemeGroupVersion)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
accessor := intf.MetadataAccessor
pod := internal.Pod{ObjectMeta: metav1.ObjectMeta{ResourceVersion: "10"}} pod := internal.Pod{ObjectMeta: metav1.ObjectMeta{ResourceVersion: "10"}}
version, err := accessor.ResourceVersion(&pod) version, err := meta.NewAccessor().ResourceVersion(&pod)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -50,7 +40,7 @@ func TestResourceVersioner(t *testing.T) {
} }
podList := internal.PodList{ListMeta: metav1.ListMeta{ResourceVersion: "10"}} podList := internal.PodList{ListMeta: metav1.ListMeta{ResourceVersion: "10"}}
version, err = accessor.ResourceVersion(&podList) version, err = meta.NewAccessor().ResourceVersion(&podList)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@ -119,12 +109,12 @@ func TestRESTMapper(t *testing.T) {
} }
rc := &internal.ReplicationController{ObjectMeta: metav1.ObjectMeta{Name: "foo"}} rc := &internal.ReplicationController{ObjectMeta: metav1.ObjectMeta{Name: "foo"}}
name, err := mapping.MetadataAccessor.Name(rc) name, err := meta.NewAccessor().Name(rc)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
if name != "foo" { if name != "foo" {
t.Errorf("unable to retrieve object meta with: %v", mapping.MetadataAccessor) t.Errorf("bad name: %q", name)
} }
} }
} }

View File

@ -20,13 +20,14 @@ import (
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta" "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/kubectl/resource"
) )
var metadataAccessor = meta.NewAccessor()
// GetOriginalConfiguration retrieves the original configuration of the object // GetOriginalConfiguration retrieves the original configuration of the object
// from the annotation, or nil if no annotation was found. // from the annotation, or nil if no annotation was found.
func GetOriginalConfiguration(mapping *meta.RESTMapping, obj runtime.Object) ([]byte, error) { func GetOriginalConfiguration(obj runtime.Object) ([]byte, error) {
annots, err := mapping.MetadataAccessor.Annotations(obj) annots, err := metadataAccessor.Annotations(obj)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -45,13 +46,12 @@ func GetOriginalConfiguration(mapping *meta.RESTMapping, obj runtime.Object) ([]
// SetOriginalConfiguration sets the original configuration of the object // SetOriginalConfiguration sets the original configuration of the object
// as the annotation on the object for later use in computing a three way patch. // as the annotation on the object for later use in computing a three way patch.
func SetOriginalConfiguration(info *resource.Info, original []byte) error { func setOriginalConfiguration(obj runtime.Object, original []byte) error {
if len(original) < 1 { if len(original) < 1 {
return nil return nil
} }
accessor := info.Mapping.MetadataAccessor annots, err := metadataAccessor.Annotations(obj)
annots, err := accessor.Annotations(info.Object)
if err != nil { if err != nil {
return err return err
} }
@ -61,22 +61,21 @@ func SetOriginalConfiguration(info *resource.Info, original []byte) error {
} }
annots[v1.LastAppliedConfigAnnotation] = string(original) annots[v1.LastAppliedConfigAnnotation] = string(original)
return info.Mapping.MetadataAccessor.SetAnnotations(info.Object, annots) return metadataAccessor.SetAnnotations(obj, annots)
} }
// GetModifiedConfiguration retrieves the modified configuration of the object. // GetModifiedConfiguration retrieves the modified configuration of the object.
// If annotate is true, it embeds the result as an annotation in the modified // If annotate is true, it embeds the result as an annotation in the modified
// configuration. If an object was read from the command input, it will use that // configuration. If an object was read from the command input, it will use that
// version of the object. Otherwise, it will use the version from the server. // version of the object. Otherwise, it will use the version from the server.
func GetModifiedConfiguration(info *resource.Info, annotate bool, codec runtime.Encoder) ([]byte, error) { func GetModifiedConfiguration(obj runtime.Object, annotate bool, codec runtime.Encoder) ([]byte, error) {
// First serialize the object without the annotation to prevent recursion, // First serialize the object without the annotation to prevent recursion,
// then add that serialization to it as the annotation and serialize it again. // then add that serialization to it as the annotation and serialize it again.
var modified []byte var modified []byte
// Otherwise, use the server side version of the object. // Otherwise, use the server side version of the object.
accessor := info.Mapping.MetadataAccessor
// Get the current annotations from the object. // Get the current annotations from the object.
annots, err := accessor.Annotations(info.Object) annots, err := metadataAccessor.Annotations(obj)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -87,22 +86,22 @@ func GetModifiedConfiguration(info *resource.Info, annotate bool, codec runtime.
original := annots[v1.LastAppliedConfigAnnotation] original := annots[v1.LastAppliedConfigAnnotation]
delete(annots, v1.LastAppliedConfigAnnotation) delete(annots, v1.LastAppliedConfigAnnotation)
if err := accessor.SetAnnotations(info.Object, annots); err != nil { if err := metadataAccessor.SetAnnotations(obj, annots); err != nil {
return nil, err return nil, err
} }
modified, err = runtime.Encode(codec, info.Object) modified, err = runtime.Encode(codec, obj)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if annotate { if annotate {
annots[v1.LastAppliedConfigAnnotation] = string(modified) annots[v1.LastAppliedConfigAnnotation] = string(modified)
if err := info.Mapping.MetadataAccessor.SetAnnotations(info.Object, annots); err != nil { if err := metadataAccessor.SetAnnotations(obj, annots); err != nil {
return nil, err return nil, err
} }
modified, err = runtime.Encode(codec, info.Object) modified, err = runtime.Encode(codec, obj)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -110,7 +109,7 @@ func GetModifiedConfiguration(info *resource.Info, annotate bool, codec runtime.
// Restore the object to its original condition. // Restore the object to its original condition.
annots[v1.LastAppliedConfigAnnotation] = original annots[v1.LastAppliedConfigAnnotation] = original
if err := info.Mapping.MetadataAccessor.SetAnnotations(info.Object, annots); err != nil { if err := metadataAccessor.SetAnnotations(obj, annots); err != nil {
return nil, err return nil, err
} }
@ -119,28 +118,28 @@ func GetModifiedConfiguration(info *resource.Info, annotate bool, codec runtime.
// UpdateApplyAnnotation calls CreateApplyAnnotation if the last applied // UpdateApplyAnnotation calls CreateApplyAnnotation if the last applied
// configuration annotation is already present. Otherwise, it does nothing. // configuration annotation is already present. Otherwise, it does nothing.
func UpdateApplyAnnotation(info *resource.Info, codec runtime.Encoder) error { func UpdateApplyAnnotation(obj runtime.Object, codec runtime.Encoder) error {
if original, err := GetOriginalConfiguration(info.Mapping, info.Object); err != nil || len(original) <= 0 { if original, err := GetOriginalConfiguration(obj); err != nil || len(original) <= 0 {
return err return err
} }
return CreateApplyAnnotation(info, codec) return CreateApplyAnnotation(obj, codec)
} }
// CreateApplyAnnotation gets the modified configuration of the object, // CreateApplyAnnotation gets the modified configuration of the object,
// without embedding it again, and then sets it on the object as the annotation. // without embedding it again, and then sets it on the object as the annotation.
func CreateApplyAnnotation(info *resource.Info, codec runtime.Encoder) error { func CreateApplyAnnotation(obj runtime.Object, codec runtime.Encoder) error {
modified, err := GetModifiedConfiguration(info, false, codec) modified, err := GetModifiedConfiguration(obj, false, codec)
if err != nil { if err != nil {
return err return err
} }
return SetOriginalConfiguration(info, modified) return setOriginalConfiguration(obj, modified)
} }
// Create the annotation used by kubectl apply only when createAnnotation is true // Create the annotation used by kubectl apply only when createAnnotation is true
// Otherwise, only update the annotation when it already exists // Otherwise, only update the annotation when it already exists
func CreateOrUpdateAnnotation(createAnnotation bool, info *resource.Info, codec runtime.Encoder) error { func CreateOrUpdateAnnotation(createAnnotation bool, obj runtime.Object, codec runtime.Encoder) error {
if createAnnotation { if createAnnotation {
return CreateApplyAnnotation(info, codec) return CreateApplyAnnotation(obj, codec)
} }
return UpdateApplyAnnotation(info, codec) return UpdateApplyAnnotation(obj, codec)
} }

View File

@ -321,7 +321,7 @@ func (o *ApplyOptions) Run(f cmdutil.Factory, cmd *cobra.Command) error {
// Get the modified configuration of the object. Embed the result // Get the modified configuration of the object. Embed the result
// as an annotation in the modified configuration, so that it will appear // as an annotation in the modified configuration, so that it will appear
// in the patch sent to the server. // in the patch sent to the server.
modified, err := kubectl.GetModifiedConfiguration(info, true, encoder) modified, err := kubectl.GetModifiedConfiguration(info.Object, true, encoder)
if err != nil { if err != nil {
return cmdutil.AddSourceToErr(fmt.Sprintf("retrieving modified configuration from:\n%s\nfor:", info.String()), info.Source, err) return cmdutil.AddSourceToErr(fmt.Sprintf("retrieving modified configuration from:\n%s\nfor:", info.String()), info.Source, err)
} }
@ -335,7 +335,7 @@ func (o *ApplyOptions) Run(f cmdutil.Factory, cmd *cobra.Command) error {
} }
// Create the resource if it doesn't exist // Create the resource if it doesn't exist
// First, update the annotation used by kubectl apply // First, update the annotation used by kubectl apply
if err := kubectl.CreateApplyAnnotation(info, encoder); err != nil { if err := kubectl.CreateApplyAnnotation(info.Object, encoder); err != nil {
return cmdutil.AddSourceToErr("creating", info.Source, err) return cmdutil.AddSourceToErr("creating", info.Source, err)
} }
@ -346,11 +346,11 @@ func (o *ApplyOptions) Run(f cmdutil.Factory, cmd *cobra.Command) error {
return cmdutil.AddSourceToErr("creating", info.Source, err) return cmdutil.AddSourceToErr("creating", info.Source, err)
} }
info.Refresh(obj, true) info.Refresh(obj, true)
if uid, err := info.Mapping.UID(info.Object); err != nil { metadata, err := meta.Accessor(info.Object)
if err != nil {
return err return err
} else {
visitedUids.Insert(string(uid))
} }
visitedUids.Insert(string(metadata.GetUID()))
} }
count++ count++
@ -368,10 +368,12 @@ func (o *ApplyOptions) Run(f cmdutil.Factory, cmd *cobra.Command) error {
} }
if !o.DryRun { if !o.DryRun {
annotationMap, err := info.Mapping.MetadataAccessor.Annotations(info.Object) metadata, err := meta.Accessor(info.Object)
if err != nil { if err != nil {
return err return err
} }
annotationMap := metadata.GetAnnotations()
if _, ok := annotationMap[api.LastAppliedConfigAnnotation]; !ok { if _, ok := annotationMap[api.LastAppliedConfigAnnotation]; !ok {
fmt.Fprintf(o.ErrOut, warningNoLastAppliedConfigAnnotation, o.cmdBaseName) fmt.Fprintf(o.ErrOut, warningNoLastAppliedConfigAnnotation, o.cmdBaseName)
} }
@ -404,11 +406,7 @@ func (o *ApplyOptions) Run(f cmdutil.Factory, cmd *cobra.Command) error {
info.Refresh(patchedObject, true) info.Refresh(patchedObject, true)
if uid, err := info.Mapping.UID(info.Object); err != nil { visitedUids.Insert(string(metadata.GetUID()))
return err
} else {
visitedUids.Insert(string(uid))
}
if string(patchBytes) == "{}" && !printObject { if string(patchBytes) == "{}" && !printObject {
count++ count++
@ -607,26 +605,20 @@ func (p *pruner) prune(f cmdutil.Factory, namespace string, mapping *meta.RESTMa
} }
for _, obj := range objs { for _, obj := range objs {
annots, err := mapping.MetadataAccessor.Annotations(obj) metadata, err := meta.Accessor(obj)
if err != nil { if err != nil {
return err return err
} }
annots := metadata.GetAnnotations()
if _, ok := annots[api.LastAppliedConfigAnnotation]; !ok { if _, ok := annots[api.LastAppliedConfigAnnotation]; !ok {
// don't prune resources not created with apply // don't prune resources not created with apply
continue continue
} }
uid, err := mapping.UID(obj) uid := metadata.GetUID()
if err != nil {
return err
}
if p.visitedUids.Has(string(uid)) { if p.visitedUids.Has(string(uid)) {
continue continue
} }
name := metadata.GetName()
name, err := mapping.Name(obj)
if err != nil {
return err
}
if !p.dryRun { if !p.dryRun {
if err := p.delete(namespace, name, mapping, scaler); err != nil { if err := p.delete(namespace, name, mapping, scaler); err != nil {
return err return err
@ -716,7 +708,7 @@ func (p *patcher) patchSimple(obj runtime.Object, modified []byte, source, names
} }
// Retrieve the original configuration of the object from the annotation. // Retrieve the original configuration of the object from the annotation.
original, err := kubectl.GetOriginalConfiguration(p.mapping, obj) original, err := kubectl.GetOriginalConfiguration(obj)
if err != nil { if err != nil {
return nil, nil, cmdutil.AddSourceToErr(fmt.Sprintf("retrieving original configuration from:\n%v\nfor:", obj), source, err) return nil, nil, cmdutil.AddSourceToErr(fmt.Sprintf("retrieving original configuration from:\n%v\nfor:", obj), source, err)
} }

View File

@ -149,7 +149,7 @@ func (o *SetLastAppliedOptions) Validate(f cmdutil.Factory, cmd *cobra.Command)
return cmdutil.AddSourceToErr(fmt.Sprintf("retrieving current configuration of:\n%s\nfrom server for:", info.String()), info.Source, err) return cmdutil.AddSourceToErr(fmt.Sprintf("retrieving current configuration of:\n%s\nfrom server for:", info.String()), info.Source, err)
} }
} }
originalBuf, err := kubectl.GetOriginalConfiguration(info.Mapping, info.Object) originalBuf, err := kubectl.GetOriginalConfiguration(info.Object)
if err != nil { if err != nil {
return cmdutil.AddSourceToErr(fmt.Sprintf("retrieving current configuration of:\n%s\nfrom server for:", info.String()), info.Source, err) return cmdutil.AddSourceToErr(fmt.Sprintf("retrieving current configuration of:\n%s\nfrom server for:", info.String()), info.Source, err)
} }

View File

@ -119,7 +119,7 @@ func (o *ViewLastAppliedOptions) Complete(cmd *cobra.Command, f cmdutil.Factory,
return err return err
} }
configString, err := kubectl.GetOriginalConfiguration(info.Mapping, info.Object) configString, err := kubectl.GetOriginalConfiguration(info.Object)
if err != nil { if err != nil {
return err return err
} }

View File

@ -187,7 +187,7 @@ func (o *AutoscaleOptions) RunAutoscale(f cmdutil.Factory, out io.Writer, cmd *c
return cmdutil.PrintObject(cmd, object, out) return cmdutil.PrintObject(cmd, object, out)
} }
if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), hpa, cmdutil.InternalVersionJSONEncoder()); err != nil { if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), hpa.Object, cmdutil.InternalVersionJSONEncoder()); err != nil {
return err return err
} }

View File

@ -21,6 +21,7 @@ import (
"io" "io"
"os" "os"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apiserver/pkg/util/flag" "k8s.io/apiserver/pkg/util/flag"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
"k8s.io/kubernetes/pkg/kubectl/cmd/auth" "k8s.io/kubernetes/pkg/kubectl/cmd/auth"
@ -378,3 +379,5 @@ func deprecatedAlias(deprecatedVersion string, cmd *cobra.Command) *cobra.Comman
cmd.Hidden = true cmd.Hidden = true
return cmd return cmd
} }
var metadataAccessor = meta.NewAccessor()

View File

@ -237,7 +237,7 @@ func (o *CreateOptions) RunCreate(f cmdutil.Factory, cmd *cobra.Command) error {
if err != nil { if err != nil {
return err return err
} }
if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info, cmdutil.InternalVersionJSONEncoder()); err != nil { if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info.Object, cmdutil.InternalVersionJSONEncoder()); err != nil {
return cmdutil.AddSourceToErr("creating", info.Source, err) return cmdutil.AddSourceToErr("creating", info.Source, err)
} }
@ -412,7 +412,7 @@ func RunCreateSubcommand(f cmdutil.Factory, options *CreateSubcommandOptions) er
if err != nil { if err != nil {
return err return err
} }
if err := kubectl.CreateOrUpdateAnnotation(options.CreateAnnotation, info, cmdutil.InternalVersionJSONEncoder()); err != nil { if err := kubectl.CreateOrUpdateAnnotation(options.CreateAnnotation, info.Object, cmdutil.InternalVersionJSONEncoder()); err != nil {
return err return err
} }

View File

@ -289,7 +289,7 @@ func (o *ExposeServiceOptions) RunExpose(f cmdutil.Factory, out io.Writer, cmd *
cmdutil.PrintSuccess(false, out, info.Object, true, "exposed") cmdutil.PrintSuccess(false, out, info.Object, true, "exposed")
return nil return nil
} }
if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info, cmdutil.InternalVersionJSONEncoder()); err != nil { if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info.Object, cmdutil.InternalVersionJSONEncoder()); err != nil {
return err return err
} }

View File

@ -219,7 +219,7 @@ func (o *ReplaceOptions) Run() error {
return err return err
} }
if err := kubectl.CreateOrUpdateAnnotation(o.createAnnotation, info, cmdutil.InternalVersionJSONEncoder()); err != nil { if err := kubectl.CreateOrUpdateAnnotation(o.createAnnotation, info.Object, cmdutil.InternalVersionJSONEncoder()); err != nil {
return cmdutil.AddSourceToErr("replacing", info.Source, err) return cmdutil.AddSourceToErr("replacing", info.Source, err)
} }
@ -315,7 +315,7 @@ func (o *ReplaceOptions) forceReplace() error {
return err return err
} }
if err := kubectl.CreateOrUpdateAnnotation(o.createAnnotation, info, cmdutil.InternalVersionJSONEncoder()); err != nil { if err := kubectl.CreateOrUpdateAnnotation(o.createAnnotation, info.Object, cmdutil.InternalVersionJSONEncoder()); err != nil {
return err return err
} }

View File

@ -532,7 +532,7 @@ func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []s
if isList { if isList {
// the resourceVersion of list objects is ~now but won't return // the resourceVersion of list objects is ~now but won't return
// an initial watch event // an initial watch event
rv, err = mapping.MetadataAccessor.ResourceVersion(obj) rv, err = meta.NewAccessor().ResourceVersion(obj)
if err != nil { if err != nil {
return err return err
} }

View File

@ -20,6 +20,7 @@ import (
"fmt" "fmt"
"io" "io"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/watch" "k8s.io/apimachinery/pkg/watch"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
@ -110,7 +111,7 @@ func RunStatus(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []stri
if err != nil { if err != nil {
return err return err
} }
rv, err := mapping.MetadataAccessor.ResourceVersion(obj) rv, err := meta.NewAccessor().ResourceVersion(obj)
if err != nil { if err != nil {
return err return err
} }

View File

@ -451,12 +451,12 @@ func (o *RunOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
func (o *RunOptions) removeCreatedObjects(f cmdutil.Factory, createdObjects []*RunObject) error { func (o *RunOptions) removeCreatedObjects(f cmdutil.Factory, createdObjects []*RunObject) error {
for _, obj := range createdObjects { for _, obj := range createdObjects {
namespace, err := obj.Mapping.MetadataAccessor.Namespace(obj.Object) namespace, err := metadataAccessor.Namespace(obj.Object)
if err != nil { if err != nil {
return err return err
} }
var name string var name string
name, err = obj.Mapping.MetadataAccessor.Name(obj.Object) name, err = metadataAccessor.Name(obj.Object)
if err != nil { if err != nil {
return err return err
} }
@ -687,7 +687,7 @@ func (o *RunOptions) createGeneratedObject(f cmdutil.Factory, cmd *cobra.Command
return nil, err return nil, err
} }
if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info, cmdutil.InternalVersionJSONEncoder()); err != nil { if err := kubectl.CreateOrUpdateAnnotation(cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag), info.Object, cmdutil.InternalVersionJSONEncoder()); err != nil {
return nil, err return nil, err
} }

View File

@ -205,8 +205,7 @@ func AddToScheme(scheme *runtime.Scheme) (meta.RESTMapper, runtime.Codec) {
codec := codecs.LegacyCodec(UnlikelyGV) codec := codecs.LegacyCodec(UnlikelyGV)
mapper := meta.NewDefaultRESTMapper([]schema.GroupVersion{UnlikelyGV, ValidVersionGV}, func(version schema.GroupVersion) (*meta.VersionInterfaces, error) { mapper := meta.NewDefaultRESTMapper([]schema.GroupVersion{UnlikelyGV, ValidVersionGV}, func(version schema.GroupVersion) (*meta.VersionInterfaces, error) {
return &meta.VersionInterfaces{ return &meta.VersionInterfaces{
ObjectConvertor: scheme, ObjectConvertor: scheme,
MetadataAccessor: meta.NewAccessor(),
}, versionErrIfFalse(version == ValidVersionGV || version == UnlikelyGV) }, versionErrIfFalse(version == ValidVersionGV || version == UnlikelyGV)
}) })
for _, gv := range []schema.GroupVersion{UnlikelyGV, ValidVersionGV} { for _, gv := range []schema.GroupVersion{UnlikelyGV, ValidVersionGV} {
@ -442,8 +441,7 @@ func (f *TestFactory) Object() (meta.RESTMapper, runtime.ObjectTyper) {
// provide typed objects for these two versions // provide typed objects for these two versions
case ValidVersionGV, UnlikelyGV: case ValidVersionGV, UnlikelyGV:
return &meta.VersionInterfaces{ return &meta.VersionInterfaces{
ObjectConvertor: scheme.Scheme, ObjectConvertor: scheme.Scheme,
MetadataAccessor: meta.NewAccessor(),
}, nil }, nil
// otherwise fall back to the legacy scheme // otherwise fall back to the legacy scheme
default: default:

View File

@ -362,7 +362,7 @@ func (o *EditOptions) Run() error {
} }
var annotationInfos []*resource.Info var annotationInfos []*resource.Info
for i := range infos { for i := range infos {
data, err := kubectl.GetOriginalConfiguration(infos[i].Mapping, infos[i].Object) data, err := kubectl.GetOriginalConfiguration(infos[i].Object)
if err != nil { if err != nil {
return err return err
} }
@ -625,7 +625,7 @@ func (o *EditOptions) visitAnnotation(annotationVisitor resource.Visitor) error
err := annotationVisitor.Visit(func(info *resource.Info, incomingErr error) error { err := annotationVisitor.Visit(func(info *resource.Info, incomingErr error) error {
// put configuration annotation in "updates" // put configuration annotation in "updates"
if o.ApplyAnnotation { if o.ApplyAnnotation {
if err := kubectl.CreateOrUpdateAnnotation(true, info, cmdutil.InternalVersionJSONEncoder()); err != nil { if err := kubectl.CreateOrUpdateAnnotation(true, info.Object, cmdutil.InternalVersionJSONEncoder()); err != nil {
return err return err
} }
} }

View File

@ -502,7 +502,7 @@ func UpdateObject(info *resource.Info, codec runtime.Codec, updateFn func(runtim
} }
// Update the annotation used by kubectl apply // Update the annotation used by kubectl apply
if err := kubectl.UpdateApplyAnnotation(info, codec); err != nil { if err := kubectl.UpdateApplyAnnotation(info.Object, codec); err != nil {
return nil, err return nil, err
} }
@ -517,15 +517,6 @@ func GetDryRunFlag(cmd *cobra.Command) bool {
return GetFlagBool(cmd, "dry-run") return GetFlagBool(cmd, "dry-run")
} }
// ContainsChangeCause checks if input resource info contains change-cause annotation.
func ContainsChangeCause(info *resource.Info) bool {
annotations, err := info.Mapping.MetadataAccessor.Annotations(info.Object)
if err != nil {
return false
}
return len(annotations[kubectl.ChangeCauseAnnotation]) > 0
}
// GetResourcesAndPairs retrieves resources and "KEY=VALUE or KEY-" pair args from given args // GetResourcesAndPairs retrieves resources and "KEY=VALUE or KEY-" pair args from given args
func GetResourcesAndPairs(args []string, pairType string) (resources []string, pairArgs []string, err error) { func GetResourcesAndPairs(args []string, pairType string) (resources []string, pairArgs []string, err error) {
foundPair := false foundPair := false

View File

@ -27,6 +27,8 @@ import (
"k8s.io/apimachinery/pkg/watch" "k8s.io/apimachinery/pkg/watch"
) )
var metadataAccessor = meta.NewAccessor()
// Helper provides methods for retrieving or mutating a RESTful // Helper provides methods for retrieving or mutating a RESTful
// resource. // resource.
type Helper struct { type Helper struct {
@ -34,9 +36,6 @@ type Helper struct {
Resource string Resource string
// A RESTClient capable of mutating this resource. // A RESTClient capable of mutating this resource.
RESTClient RESTClient RESTClient RESTClient
// An interface for reading or writing the resource version of this
// type.
Versioner runtime.ResourceVersioner
// True if the resource type is scoped to namespaces // True if the resource type is scoped to namespaces
NamespaceScoped bool NamespaceScoped bool
} }
@ -46,7 +45,6 @@ func NewHelper(client RESTClient, mapping *meta.RESTMapping) *Helper {
return &Helper{ return &Helper{
Resource: mapping.Resource, Resource: mapping.Resource,
RESTClient: client, RESTClient: client,
Versioner: mapping.MetadataAccessor,
NamespaceScoped: mapping.Scope.Name() == meta.RESTScopeNameNamespace, NamespaceScoped: mapping.Scope.Name() == meta.RESTScopeNameNamespace,
} }
} }
@ -113,13 +111,13 @@ func (m *Helper) DeleteWithOptions(namespace, name string, options *metav1.Delet
func (m *Helper) Create(namespace string, modify bool, obj runtime.Object) (runtime.Object, error) { func (m *Helper) Create(namespace string, modify bool, obj runtime.Object) (runtime.Object, error) {
if modify { if modify {
// Attempt to version the object based on client logic. // Attempt to version the object based on client logic.
version, err := m.Versioner.ResourceVersion(obj) version, err := metadataAccessor.ResourceVersion(obj)
if err != nil { if err != nil {
// We don't know how to clear the version on this object, so send it to the server as is // We don't know how to clear the version on this object, so send it to the server as is
return m.createResource(m.RESTClient, m.Resource, namespace, obj) return m.createResource(m.RESTClient, m.Resource, namespace, obj)
} }
if version != "" { if version != "" {
if err := m.Versioner.SetResourceVersion(obj, ""); err != nil { if err := metadataAccessor.SetResourceVersion(obj, ""); err != nil {
return nil, err return nil, err
} }
} }
@ -145,7 +143,7 @@ func (m *Helper) Replace(namespace, name string, overwrite bool, obj runtime.Obj
c := m.RESTClient c := m.RESTClient
// Attempt to version the object based on client logic. // Attempt to version the object based on client logic.
version, err := m.Versioner.ResourceVersion(obj) version, err := metadataAccessor.ResourceVersion(obj)
if err != nil { if err != nil {
// We don't know how to version this object, so send it to the server as is // We don't know how to version this object, so send it to the server as is
return m.replaceResource(c, m.Resource, namespace, name, obj) return m.replaceResource(c, m.Resource, namespace, name, obj)
@ -157,11 +155,11 @@ func (m *Helper) Replace(namespace, name string, overwrite bool, obj runtime.Obj
// The object does not exist, but we want it to be created // The object does not exist, but we want it to be created
return m.replaceResource(c, m.Resource, namespace, name, obj) return m.replaceResource(c, m.Resource, namespace, name, obj)
} }
serverVersion, err := m.Versioner.ResourceVersion(serverObj) serverVersion, err := metadataAccessor.ResourceVersion(serverObj)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err := m.Versioner.SetResourceVersion(obj, serverVersion); err != nil { if err := metadataAccessor.SetResourceVersion(obj, serverVersion); err != nil {
return nil, err return nil, err
} }
} }

View File

@ -211,7 +211,6 @@ func TestHelperCreate(t *testing.T) {
} }
modifier := &Helper{ modifier := &Helper{
RESTClient: client, RESTClient: client,
Versioner: metaAccessor,
NamespaceScoped: true, NamespaceScoped: true,
} }
_, err := modifier.Create("bar", test.Modify, test.Object) _, err := modifier.Create("bar", test.Modify, test.Object)
@ -568,7 +567,6 @@ func TestHelperReplace(t *testing.T) {
} }
modifier := &Helper{ modifier := &Helper{
RESTClient: client, RESTClient: client,
Versioner: metaAccessor,
NamespaceScoped: test.NamespaceScoped, NamespaceScoped: test.NamespaceScoped,
} }
_, err := modifier.Replace(test.Namespace, "foo", test.Overwrite, test.Object) _, err := modifier.Replace(test.Namespace, "foo", test.Overwrite, test.Object)

View File

@ -65,9 +65,9 @@ func (m *Mapper) InfoForData(data []byte, source string) (*Info, error) {
return nil, fmt.Errorf("unable to connect to a server to handle %q: %v", mapping.Resource, err) return nil, fmt.Errorf("unable to connect to a server to handle %q: %v", mapping.Resource, err)
} }
name, _ := mapping.MetadataAccessor.Name(obj) name, _ := metadataAccessor.Name(obj)
namespace, _ := mapping.MetadataAccessor.Namespace(obj) namespace, _ := metadataAccessor.Namespace(obj)
resourceVersion, _ := mapping.MetadataAccessor.ResourceVersion(obj) resourceVersion, _ := metadataAccessor.ResourceVersion(obj)
return &Info{ return &Info{
Client: client, Client: client,
@ -105,9 +105,9 @@ func (m *Mapper) InfoForObject(obj runtime.Object, preferredGVKs []schema.GroupV
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to connect to a server to handle %q: %v", mapping.Resource, err) return nil, fmt.Errorf("unable to connect to a server to handle %q: %v", mapping.Resource, err)
} }
name, _ := mapping.MetadataAccessor.Name(obj) name, _ := metadataAccessor.Name(obj)
namespace, _ := mapping.MetadataAccessor.Namespace(obj) namespace, _ := metadataAccessor.Namespace(obj)
resourceVersion, _ := mapping.MetadataAccessor.ResourceVersion(obj) resourceVersion, _ := metadataAccessor.ResourceVersion(obj)
return &Info{ return &Info{
Client: client, Client: client,
Mapping: mapping, Mapping: mapping,
@ -198,7 +198,6 @@ func (m relaxedMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*me
if err != nil && meta.IsNoMatchError(err) && len(versions) > 0 { if err != nil && meta.IsNoMatchError(err) && len(versions) > 0 {
return &meta.RESTMapping{ return &meta.RESTMapping{
GroupVersionKind: gk.WithVersion(versions[0]), GroupVersionKind: gk.WithVersion(versions[0]),
MetadataAccessor: meta.NewAccessor(),
Scope: meta.RESTScopeRoot, Scope: meta.RESTScopeRoot,
ObjectConvertor: identityConvertor{}, ObjectConvertor: identityConvertor{},
}, nil }, nil
@ -211,7 +210,6 @@ func (m relaxedMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]
return []*meta.RESTMapping{ return []*meta.RESTMapping{
{ {
GroupVersionKind: gk.WithVersion(versions[0]), GroupVersionKind: gk.WithVersion(versions[0]),
MetadataAccessor: meta.NewAccessor(),
Scope: meta.RESTScopeRoot, Scope: meta.RESTScopeRoot,
ObjectConvertor: identityConvertor{}, ObjectConvertor: identityConvertor{},
}, },

View File

@ -88,9 +88,8 @@ func (r *Selector) Visit(fn VisitorFunc) error {
} }
return err return err
} }
accessor := r.Mapping.MetadataAccessor resourceVersion, _ := metadataAccessor.ResourceVersion(list)
resourceVersion, _ := accessor.ResourceVersion(list) nextContinueToken, _ := metadataAccessor.Continue(list)
nextContinueToken, _ := accessor.Continue(list)
info := &Info{ info := &Info{
Client: r.Client, Client: r.Client,
Mapping: r.Mapping, Mapping: r.Mapping,

View File

@ -118,7 +118,7 @@ func (i *Info) Get() (err error) {
return err return err
} }
i.Object = obj i.Object = obj
i.ResourceVersion, _ = i.Mapping.MetadataAccessor.ResourceVersion(obj) i.ResourceVersion, _ = metadataAccessor.ResourceVersion(obj)
return nil return nil
} }
@ -126,7 +126,7 @@ func (i *Info) Get() (err error) {
// the Object will be updated even if name, namespace, or resourceVersion // the Object will be updated even if name, namespace, or resourceVersion
// attributes cannot be loaded from the object. // attributes cannot be loaded from the object.
func (i *Info) Refresh(obj runtime.Object, ignoreError bool) error { func (i *Info) Refresh(obj runtime.Object, ignoreError bool) error {
name, err := i.Mapping.MetadataAccessor.Name(obj) name, err := metadataAccessor.Name(obj)
if err != nil { if err != nil {
if !ignoreError { if !ignoreError {
return err return err
@ -134,7 +134,7 @@ func (i *Info) Refresh(obj runtime.Object, ignoreError bool) error {
} else { } else {
i.Name = name i.Name = name
} }
namespace, err := i.Mapping.MetadataAccessor.Namespace(obj) namespace, err := metadataAccessor.Namespace(obj)
if err != nil { if err != nil {
if !ignoreError { if !ignoreError {
return err return err
@ -142,7 +142,7 @@ func (i *Info) Refresh(obj runtime.Object, ignoreError bool) error {
} else { } else {
i.Namespace = namespace i.Namespace = namespace
} }
version, err := i.Mapping.MetadataAccessor.ResourceVersion(obj) version, err := metadataAccessor.ResourceVersion(obj)
if err != nil { if err != nil {
if !ignoreError { if !ignoreError {
return err return err
@ -617,7 +617,7 @@ func UpdateObjectNamespace(info *Info, err error) error {
return err return err
} }
if info.Object != nil { if info.Object != nil {
return info.Mapping.MetadataAccessor.SetNamespace(info.Object, info.Namespace) return metadataAccessor.SetNamespace(info.Object, info.Namespace)
} }
return nil return nil
} }

View File

@ -26,7 +26,6 @@ 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 runtime.ObjectConvertor
MetadataAccessor
} }
type ListMetaAccessor interface { type ListMetaAccessor interface {
@ -113,7 +112,6 @@ type RESTMapping struct {
Scope RESTScope Scope RESTScope
runtime.ObjectConvertor runtime.ObjectConvertor
MetadataAccessor
} }
// 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

View File

@ -536,8 +536,7 @@ func (m *DefaultRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string
GroupVersionKind: gvk, GroupVersionKind: gvk,
Scope: scope, Scope: scope,
ObjectConvertor: interfaces.ObjectConvertor, ObjectConvertor: interfaces.ObjectConvertor,
MetadataAccessor: interfaces.MetadataAccessor,
}) })
} }

View File

@ -44,7 +44,7 @@ var validAccessor = resourceAccessor{}
var validConvertor = fakeConvertor{} var validConvertor = fakeConvertor{}
func fakeInterfaces(version schema.GroupVersion) (*VersionInterfaces, error) { func fakeInterfaces(version schema.GroupVersion) (*VersionInterfaces, error) {
return &VersionInterfaces{ObjectConvertor: validConvertor, MetadataAccessor: validAccessor}, nil return &VersionInterfaces{ObjectConvertor: validConvertor}, nil
} }
var unmatchedErr = errors.New("no version") var unmatchedErr = errors.New("no version")
@ -577,8 +577,8 @@ func TestRESTMapperRESTMapping(t *testing.T) {
t.Errorf("%d: unexpected resource: %#v", i, mapping) t.Errorf("%d: unexpected resource: %#v", i, mapping)
} }
if mapping.MetadataAccessor == nil || mapping.ObjectConvertor == nil { if mapping.ObjectConvertor == nil {
t.Errorf("%d: missing codec and accessor: %#v", i, mapping) t.Errorf("%d: missing codec: %#v", i, mapping)
} }
groupVersion := testCase.ExpectedGroupVersion groupVersion := testCase.ExpectedGroupVersion
@ -727,8 +727,8 @@ 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.MetadataAccessor == nil || mapping.ObjectConvertor == nil { if mapping.ObjectConvertor == nil {
t.Errorf("%d - %d: missing codec and accessor: %#v", i, j, mapping) 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)

View File

@ -28,8 +28,7 @@ func InterfacesForUnstructuredConversion(parent VersionInterfacesFunc) VersionIn
return func(version schema.GroupVersion) (*VersionInterfaces, error) { return func(version schema.GroupVersion) (*VersionInterfaces, error) {
if i, err := parent(version); err == nil { if i, err := parent(version); err == nil {
return &VersionInterfaces{ return &VersionInterfaces{
ObjectConvertor: i.ObjectConvertor, ObjectConvertor: i.ObjectConvertor,
MetadataAccessor: NewAccessor(),
}, nil }, nil
} }
return InterfacesForUnstructured(version) return InterfacesForUnstructured(version)
@ -41,7 +40,6 @@ func InterfacesForUnstructuredConversion(parent VersionInterfacesFunc) VersionIn
// other conversions. // other conversions.
func InterfacesForUnstructured(schema.GroupVersion) (*VersionInterfaces, error) { func InterfacesForUnstructured(schema.GroupVersion) (*VersionInterfaces, error) {
return &VersionInterfaces{ return &VersionInterfaces{
ObjectConvertor: &unstructured.UnstructuredObjectConverter{}, ObjectConvertor: &unstructured.UnstructuredObjectConverter{},
MetadataAccessor: NewAccessor(),
}, nil }, nil
} }

View File

@ -224,8 +224,7 @@ func (gmf *GroupMetaFactory) Enable(m *registered.APIRegistrationManager, scheme
if err := groupMeta.AddVersionInterfaces( if err := groupMeta.AddVersionInterfaces(
schema.GroupVersion{Group: gvf.GroupName, Version: gvf.VersionName}, schema.GroupVersion{Group: gvf.GroupName, Version: gvf.VersionName},
&meta.VersionInterfaces{ &meta.VersionInterfaces{
ObjectConvertor: scheme, ObjectConvertor: scheme,
MetadataAccessor: accessor,
}, },
); err != nil { ); err != nil {
return err return err

View File

@ -146,23 +146,19 @@ func interfacesFor(version schema.GroupVersion) (*meta.VersionInterfaces, error)
switch version { switch version {
case testGroupVersion: case testGroupVersion:
return &meta.VersionInterfaces{ return &meta.VersionInterfaces{
ObjectConvertor: scheme, ObjectConvertor: scheme,
MetadataAccessor: accessor,
}, nil }, nil
case newGroupVersion: case newGroupVersion:
return &meta.VersionInterfaces{ return &meta.VersionInterfaces{
ObjectConvertor: scheme, ObjectConvertor: scheme,
MetadataAccessor: accessor,
}, nil }, nil
case grouplessGroupVersion: case grouplessGroupVersion:
return &meta.VersionInterfaces{ return &meta.VersionInterfaces{
ObjectConvertor: scheme, ObjectConvertor: scheme,
MetadataAccessor: accessor,
}, nil }, nil
case testGroup2Version: case testGroup2Version:
return &meta.VersionInterfaces{ return &meta.VersionInterfaces{
ObjectConvertor: scheme, ObjectConvertor: scheme,
MetadataAccessor: accessor,
}, nil }, nil
default: default:
return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, groupVersions) return nil, fmt.Errorf("unsupported storage version: %s (valid: %v)", version, groupVersions)

View File

@ -155,8 +155,7 @@ func TestInstallAPIGroups(t *testing.T) {
interfacesFor := func(version schema.GroupVersion) (*meta.VersionInterfaces, error) { interfacesFor := func(version schema.GroupVersion) (*meta.VersionInterfaces, error) {
return &meta.VersionInterfaces{ return &meta.VersionInterfaces{
ObjectConvertor: scheme, ObjectConvertor: scheme,
MetadataAccessor: meta.NewAccessor(),
}, nil }, nil
} }

View File

@ -14,6 +14,7 @@ go_test(
], ],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//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/apis/meta/v1/unstructured: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",

View File

@ -26,15 +26,6 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
) )
// VersionInterfaces provides an object converter and metadata
// accessor appropriate for use with unstructured objects.
func VersionInterfaces(schema.GroupVersion) (*meta.VersionInterfaces, error) {
return &meta.VersionInterfaces{
ObjectConvertor: &unstructured.UnstructuredObjectConverter{},
MetadataAccessor: meta.NewAccessor(),
}, nil
}
// NewDiscoveryRESTMapper returns a RESTMapper based on discovery information. // NewDiscoveryRESTMapper returns a RESTMapper based on discovery information.
func NewDiscoveryRESTMapper(resources []*metav1.APIResourceList, versionFunc meta.VersionInterfacesFunc) (*meta.DefaultRESTMapper, error) { func NewDiscoveryRESTMapper(resources []*metav1.APIResourceList, versionFunc meta.VersionInterfacesFunc) (*meta.DefaultRESTMapper, error) {
rm := meta.NewDefaultRESTMapper(nil, versionFunc) rm := meta.NewDefaultRESTMapper(nil, versionFunc)

View File

@ -19,7 +19,9 @@ package dynamic
import ( import (
"testing" "testing"
"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"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
) )
@ -43,7 +45,7 @@ func TestDiscoveryRESTMapper(t *testing.T) {
Kind: "test_kind", Kind: "test_kind",
} }
mapper, err := NewDiscoveryRESTMapper(resources, VersionInterfaces) mapper, err := NewDiscoveryRESTMapper(resources, versionInterfaces)
if err != nil { if err != nil {
t.Fatalf("unexpected error creating mapper: %s", err) t.Fatalf("unexpected error creating mapper: %s", err)
} }
@ -77,3 +79,11 @@ func TestDiscoveryRESTMapper(t *testing.T) {
} }
} }
} }
// VersionInterfaces provides an object converter and metadata
// accessor appropriate for use with unstructured objects.
func versionInterfaces(schema.GroupVersion) (*meta.VersionInterfaces, error) {
return &meta.VersionInterfaces{
ObjectConvertor: &unstructured.UnstructuredObjectConverter{},
}, nil
}

View File

@ -970,11 +970,11 @@ func (c *allClient) destroy(obj runtime.Object, mapping *meta.RESTMapping) error
return err return err
} }
namespaced := mapping.Scope.Name() == meta.RESTScopeNameNamespace namespaced := mapping.Scope.Name() == meta.RESTScopeNameNamespace
name, err := mapping.MetadataAccessor.Name(obj) name, err := meta.NewAccessor().Name(obj)
if err != nil { if err != nil {
return err return err
} }
ns, err := mapping.MetadataAccessor.Namespace(obj) ns, err := meta.NewAccessor().Namespace(obj)
if err != nil { if err != nil {
return err return err
} }