Skip to content

Commit

Permalink
update bulk to have a serialization priority
Browse files Browse the repository at this point in the history
  • Loading branch information
deads2k committed Jun 28, 2017
1 parent 3b22095 commit 563719a
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 3 deletions.
16 changes: 14 additions & 2 deletions pkg/cmd/cli/cmd/newapp.go
Expand Up @@ -153,8 +153,21 @@ func (o *ObjectGeneratorOptions) Complete(baseName, commandName string, f *clien
}
o.Config.ErrOut = o.ErrOut

clientConfig, err := f.ClientConfig()
if err != nil {
return err
}
mapper, typer := f.Object()
// ignore errors. We use this to make a best guess at preferred seralizations, but the command might run without a server
discoveryClient, _ := f.DiscoveryClient()

o.Action.Out, o.Action.ErrOut = out, o.ErrOut
o.Action.Bulk.Mapper = clientcmd.ResourceMapper(f)
o.Action.Bulk.Mapper = &resource.Mapper{
RESTMapper: mapper,
ObjectTyper: typer,
ClientMapper: configcmd.ClientMapperFromConfig(clientConfig),
}
o.Action.Bulk.PreferredSerializationOrder = configcmd.PreferredSerializationOrder(discoveryClient)
o.Action.Bulk.Op = configcmd.Create
// Retry is used to support previous versions of the API server that will
// consider the presence of an unknown trigger type to be an error.
Expand All @@ -168,7 +181,6 @@ func (o *ObjectGeneratorOptions) Complete(baseName, commandName string, f *clien
o.BaseName = baseName
o.CommandName = commandName

mapper, _ := f.Object()
o.PrintObject = cmdutil.VersionedPrintObject(f.PrintObject, c, mapper, out)
o.LogsForObject = f.LogsForObject
if err := CompleteAppConfig(o.Config, f, c, args); err != nil {
Expand Down
65 changes: 64 additions & 1 deletion pkg/config/cmd/cmd.go
Expand Up @@ -3,13 +3,15 @@ package cmd
import (
"fmt"
"io"
"strings"

"github.com/spf13/pflag"

"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/discovery"
"k8s.io/client-go/rest"
kapi "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/client/unversioned"
Expand Down Expand Up @@ -51,6 +53,10 @@ type IgnoreErrorFunc func(e error) bool
type Bulk struct {
Mapper Mapper

// PreferredSerializationOrder take a list of GVKs to decide how to serialize out the individual list items
// It allows partial values, so you specify just groups or versions as a for instance
PreferredSerializationOrder []schema.GroupVersionKind

Op OpFunc
After AfterFunc
Retry RetryFunc
Expand All @@ -72,7 +78,7 @@ func (b *Bulk) Run(list *kapi.List, namespace string) []error {

errs := []error{}
for i, item := range list.Items {
info, err := b.Mapper.InfoForObject(item, []schema.GroupVersionKind{{Group: ""}})
info, err := b.Mapper.InfoForObject(item, b.getPreferredSerializationOrder())
if err != nil {
errs = append(errs, err)
if after(info, err) {
Expand Down Expand Up @@ -104,6 +110,15 @@ func (b *Bulk) Run(list *kapi.List, namespace string) []error {
return errs
}

func (b *Bulk) getPreferredSerializationOrder() []schema.GroupVersionKind {
if len(b.PreferredSerializationOrder) > 0 {
return b.PreferredSerializationOrder
}
// it seems that the underlying impl expects to have at least one, even though this
// logically means something different.
return []schema.GroupVersionKind{{Group: ""}}
}

// ClientMapperFromConfig returns a ClientMapper suitable for Bulk operations.
// TODO: copied from
// pkg/cmd/util/clientcmd/factory_object_mapping.go#ClientForMapping and
Expand Down Expand Up @@ -141,6 +156,54 @@ func ClientMapperFromConfig(config *rest.Config) resource.ClientMapperFunc {
})
}

// PreferredSerializationOrder returns the preferred ordering via discovery. If anything fails, it just
// returns a list of with the empty (legacy) group
func PreferredSerializationOrder(client discovery.DiscoveryInterface) []schema.GroupVersionKind {
ret := []schema.GroupVersionKind{{Group: ""}}
if client == nil {
return ret
}

groups, err := client.ServerGroups()
if err != nil {
return ret
}

resources, err := client.ServerResources()
if err != nil {
return ret
}

// add resources with kinds first, then groupversions second as a fallback. Not all server versions provide kinds
// we have to specify individual kinds since our local scheme may have kinds not present on the server
for _, resourceList := range resources {
for _, resource := range resourceList.APIResources {
// if this is a sub resource, skip it
if strings.Contains(resource.Name, "/") {
continue
}
// if there is no kind, skip it
if len(resource.Kind) == 0 {
continue
}
gv, err := schema.ParseGroupVersion(resourceList.GroupVersion)
if err != nil {
continue
}
ret = append(ret, gv.WithKind(resource.Kind))
}
}

// we actually have to get to the granularity of versions because the server may not support the same versions
// in a group that we have locally.
for _, group := range groups.Groups {
for _, version := range group.Versions {
ret = append(ret, schema.GroupVersionKind{Group: group.Name, Version: version.Version})
}
}
return ret
}

func NewPrintNameOrErrorAfterIndent(mapper meta.RESTMapper, short bool, operation string, out, errs io.Writer, dryRun bool, indent string, prefixForError PrefixForError) AfterFunc {
return func(info *resource.Info, err error) bool {
if err == nil {
Expand Down

0 comments on commit 563719a

Please sign in to comment.