command Factory should provide Printers

The factory knows all possible types, and should abstract the process of
creating all printers. A future refactor can further reduce the
dependencies between printer code and internal types.
This commit is contained in:
Clayton Coleman
2017-02-19 17:39:43 -05:00
parent 90fdd067e9
commit 19ae89dcd8
7 changed files with 114 additions and 75 deletions

View File

@@ -27,7 +27,6 @@ import (
"time"
"github.com/emicklei/go-restful/swagger"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -48,6 +47,8 @@ import (
"k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/printers"
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
)
type ring1Factory struct {
@@ -58,10 +59,12 @@ func NewObjectMappingFactory(clientAccessFactory ClientAccessFactory) ObjectMapp
f := &ring1Factory{
clientAccessFactory: clientAccessFactory,
}
return f
}
// TODO: This method should return an error now that it can fail. Alternatively, it needs to
// return lazy implementations of mapper and typer that don't hit the wire until they are
// invoked.
func (f *ring1Factory) Object() (meta.RESTMapper, runtime.ObjectTyper) {
mapper := api.Registry.RESTMapper()
discoveryClient, err := f.clientAccessFactory.DiscoveryClient()
@@ -143,7 +146,7 @@ func (f *ring1Factory) UnstructuredClientForMapping(mapping *meta.RESTMapping) (
return restclient.RESTClientFor(cfg)
}
func (f *ring1Factory) Describer(mapping *meta.RESTMapping) (kubectl.Describer, error) {
func (f *ring1Factory) Describer(mapping *meta.RESTMapping) (printers.Describer, error) {
mappingVersion := mapping.GroupVersionKind.GroupVersion()
if mapping.GroupVersionKind.Group == federation.GroupName {
fedClientSet, err := f.clientAccessFactory.FederationClientSetForVersion(&mappingVersion)
@@ -151,7 +154,7 @@ func (f *ring1Factory) Describer(mapping *meta.RESTMapping) (kubectl.Describer,
return nil, err
}
if mapping.GroupVersionKind.Kind == "Cluster" {
return &kubectl.ClusterDescriber{Interface: fedClientSet}, nil
return &printersinternal.ClusterDescriber{Interface: fedClientSet}, nil
}
}
@@ -166,7 +169,7 @@ func (f *ring1Factory) Describer(mapping *meta.RESTMapping) (kubectl.Describer,
}
// try to get a describer
if describer, ok := kubectl.DescriberFor(mapping.GroupVersionKind.GroupKind(), clientset); ok {
if describer, ok := printersinternal.DescriberFor(mapping.GroupVersionKind.GroupKind(), clientset); ok {
return describer, nil
}
// if this is a kind we don't have a describer for yet, go generic if possible
@@ -178,7 +181,7 @@ func (f *ring1Factory) Describer(mapping *meta.RESTMapping) (kubectl.Describer,
}
// helper function to make a generic describer, or return an error
func genericDescriber(clientAccessFactory ClientAccessFactory, mapping *meta.RESTMapping) (kubectl.Describer, error) {
func genericDescriber(clientAccessFactory ClientAccessFactory, mapping *meta.RESTMapping) (printers.Describer, error) {
clientConfig, err := clientAccessFactory.ClientConfig()
if err != nil {
return nil, err
@@ -202,7 +205,7 @@ func genericDescriber(clientAccessFactory ClientAccessFactory, mapping *meta.RES
}
eventsClient := clientSet.Core()
return kubectl.GenericDescriberFor(mapping, dynamicClient, eventsClient), nil
return printersinternal.GenericDescriberFor(mapping, dynamicClient, eventsClient), nil
}
func (f *ring1Factory) LogsForObject(object, options runtime.Object) (*restclient.Request, error) {
@@ -361,48 +364,6 @@ func (f *ring1Factory) AttachablePodForObject(object runtime.Object) (*api.Pod,
return pod, err
}
func (f *ring1Factory) PrinterForMapping(cmd *cobra.Command, mapping *meta.RESTMapping, withNamespace bool) (kubectl.ResourcePrinter, error) {
printer, generic, err := PrinterForCommand(cmd)
if err != nil {
return nil, err
}
// Make sure we output versioned data for generic printers
if generic {
if mapping == nil {
return nil, fmt.Errorf("no serialization format found")
}
version := mapping.GroupVersionKind.GroupVersion()
if version.Empty() {
return nil, fmt.Errorf("no serialization format found")
}
printer = kubectl.NewVersionedPrinter(printer, mapping.ObjectConvertor, version, mapping.GroupVersionKind.GroupVersion())
} else {
// Some callers do not have "label-columns" so we can't use the GetFlagStringSlice() helper
columnLabel, err := cmd.Flags().GetStringSlice("label-columns")
if err != nil {
columnLabel = []string{}
}
printer, err = f.clientAccessFactory.Printer(mapping, kubectl.PrintOptions{
NoHeaders: GetFlagBool(cmd, "no-headers"),
WithNamespace: withNamespace,
Wide: GetWideFlag(cmd),
ShowAll: GetFlagBool(cmd, "show-all"),
ShowLabels: GetFlagBool(cmd, "show-labels"),
AbsoluteTimestamps: isWatch(cmd),
ColumnLabels: columnLabel,
})
if err != nil {
return nil, err
}
printer = maybeWrapSortingPrinter(cmd, printer)
}
return printer, nil
}
func (f *ring1Factory) Validator(validate bool, cacheDir string) (validation.Schema, error) {
if validate {
discovery, err := f.clientAccessFactory.DiscoveryClient()