Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
9bc3ead5
Unverified
Commit
9bc3ead5
authored
May 03, 2019
by
Kubernetes Prow Robot
Committed by
GitHub
May 03, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #77148 from seans3/default-printing-cleanup
tableprinter: simplifies default printer handler
parents
7287ae6b
13f3f11f
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
108 additions
and
107 deletions
+108
-107
BUILD
pkg/printers/BUILD
+1
-0
BUILD
pkg/printers/internalversion/BUILD
+0
-1
printers.go
pkg/printers/internalversion/printers.go
+0
-43
printers_test.go
pkg/printers/internalversion/printers_test.go
+38
-24
tablegenerator.go
pkg/printers/tablegenerator.go
+4
-24
tableprinter.go
pkg/printers/tableprinter.go
+65
-15
No files found.
pkg/printers/BUILD
View file @
9bc3ead5
...
@@ -22,6 +22,7 @@ go_library(
...
@@ -22,6 +22,7 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/duration:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//vendor/github.com/liggitt/tabwriter:go_default_library",
"//vendor/github.com/liggitt/tabwriter:go_default_library",
],
],
...
...
pkg/printers/internalversion/BUILD
View file @
9bc3ead5
...
@@ -95,7 +95,6 @@ go_library(
...
@@ -95,7 +95,6 @@ go_library(
"//staging/src/k8s.io/api/rbac/v1beta1:go_default_library",
"//staging/src/k8s.io/api/rbac/v1beta1:go_default_library",
"//staging/src/k8s.io/api/scheduling/v1:go_default_library",
"//staging/src/k8s.io/api/scheduling/v1:go_default_library",
"//staging/src/k8s.io/api/storage/v1:go_default_library",
"//staging/src/k8s.io/api/storage/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library",
...
...
pkg/printers/internalversion/printers.go
View file @
9bc3ead5
...
@@ -37,7 +37,6 @@ import (
...
@@ -37,7 +37,6 @@ import (
rbacv1beta1
"k8s.io/api/rbac/v1beta1"
rbacv1beta1
"k8s.io/api/rbac/v1beta1"
schedulingv1
"k8s.io/api/scheduling/v1"
schedulingv1
"k8s.io/api/scheduling/v1"
storagev1
"k8s.io/api/storage/v1"
storagev1
"k8s.io/api/storage/v1"
"k8s.io/apimachinery/pkg/api/meta"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1
"k8s.io/apimachinery/pkg/apis/meta/v1beta1"
metav1beta1
"k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/labels"
...
@@ -468,48 +467,6 @@ func AddHandlers(h printers.PrintHandler) {
...
@@ -468,48 +467,6 @@ func AddHandlers(h printers.PrintHandler) {
}
}
h
.
TableHandler
(
volumeAttachmentColumnDefinitions
,
printVolumeAttachment
)
h
.
TableHandler
(
volumeAttachmentColumnDefinitions
,
printVolumeAttachment
)
h
.
TableHandler
(
volumeAttachmentColumnDefinitions
,
printVolumeAttachmentList
)
h
.
TableHandler
(
volumeAttachmentColumnDefinitions
,
printVolumeAttachmentList
)
AddDefaultHandlers
(
h
)
}
// AddDefaultHandlers adds handlers that can work with most Kubernetes objects.
func
AddDefaultHandlers
(
h
printers
.
PrintHandler
)
{
// types without defined columns
objectMetaColumnDefinitions
:=
[]
metav1beta1
.
TableColumnDefinition
{
{
Name
:
"Name"
,
Type
:
"string"
,
Format
:
"name"
,
Description
:
metav1
.
ObjectMeta
{}
.
SwaggerDoc
()[
"name"
]},
{
Name
:
"Age"
,
Type
:
"string"
,
Description
:
metav1
.
ObjectMeta
{}
.
SwaggerDoc
()[
"creationTimestamp"
]},
}
h
.
DefaultTableHandler
(
objectMetaColumnDefinitions
,
printObjectMeta
)
}
func
printObjectMeta
(
obj
runtime
.
Object
,
options
printers
.
PrintOptions
)
([]
metav1beta1
.
TableRow
,
error
)
{
if
meta
.
IsListType
(
obj
)
{
rows
:=
make
([]
metav1beta1
.
TableRow
,
0
,
16
)
err
:=
meta
.
EachListItem
(
obj
,
func
(
obj
runtime
.
Object
)
error
{
nestedRows
,
err
:=
printObjectMeta
(
obj
,
options
)
if
err
!=
nil
{
return
err
}
rows
=
append
(
rows
,
nestedRows
...
)
return
nil
})
if
err
!=
nil
{
return
nil
,
err
}
return
rows
,
nil
}
rows
:=
make
([]
metav1beta1
.
TableRow
,
0
,
1
)
m
,
err
:=
meta
.
Accessor
(
obj
)
if
err
!=
nil
{
return
nil
,
err
}
row
:=
metav1beta1
.
TableRow
{
Object
:
runtime
.
RawExtension
{
Object
:
obj
},
}
row
.
Cells
=
append
(
row
.
Cells
,
m
.
GetName
(),
translateTimestampSince
(
m
.
GetCreationTimestamp
()))
rows
=
append
(
rows
,
row
)
return
rows
,
nil
}
}
// Pass ports=nil for all ports.
// Pass ports=nil for all ports.
...
...
pkg/printers/internalversion/printers_test.go
View file @
9bc3ead5
...
@@ -171,7 +171,7 @@ func TestPrintUnstructuredObject(t *testing.T) {
...
@@ -171,7 +171,7 @@ func TestPrintUnstructuredObject(t *testing.T) {
for
_
,
test
:=
range
tests
{
for
_
,
test
:=
range
tests
{
out
.
Reset
()
out
.
Reset
()
printer
:=
printers
.
NewTablePrinter
(
test
.
options
)
.
With
(
AddDefaultHandlers
)
printer
:=
printers
.
NewTablePrinter
(
test
.
options
)
printer
.
PrintObj
(
test
.
object
,
out
)
printer
.
PrintObj
(
test
.
object
,
out
)
matches
,
err
:=
regexp
.
MatchString
(
test
.
expected
,
out
.
String
())
matches
,
err
:=
regexp
.
MatchString
(
test
.
expected
,
out
.
String
())
...
@@ -1339,7 +1339,8 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) {
...
@@ -1339,7 +1339,8 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) {
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"127.0.0.1"
},
{
IP
:
"localhost"
}},
Addresses
:
[]
api
.
EndpointAddress
{{
IP
:
"127.0.0.1"
},
{
IP
:
"localhost"
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
8080
}},
Ports
:
[]
api
.
EndpointPort
{{
Port
:
8080
}},
},
},
}},
},
},
isNamespaced
:
true
,
isNamespaced
:
true
,
},
},
{
{
...
@@ -1370,7 +1371,7 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) {
...
@@ -1370,7 +1371,7 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) {
},
},
{
{
obj
:
&
api
.
PersistentVolume
{
obj
:
&
api
.
PersistentVolume
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
name
,
Namespace
:
namespaceName
},
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
name
},
Spec
:
api
.
PersistentVolumeSpec
{},
Spec
:
api
.
PersistentVolumeSpec
{},
},
},
isNamespaced
:
false
,
isNamespaced
:
false
,
...
@@ -1414,33 +1415,46 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) {
...
@@ -1414,33 +1415,46 @@ func TestPrintHumanReadableWithNamespace(t *testing.T) {
},
},
isNamespaced
:
false
,
isNamespaced
:
false
,
},
},
{
obj
:
&
unstructured
.
Unstructured
{
Object
:
map
[
string
]
interface
{}{
"kind"
:
"Foo"
,
"apiVersion"
:
"example.com/v1"
,
"metadata"
:
map
[
string
]
interface
{}{
"name"
:
"test"
,
"namespace"
:
namespaceName
},
},
},
isNamespaced
:
true
,
},
{
obj
:
&
unstructured
.
Unstructured
{
Object
:
map
[
string
]
interface
{}{
"kind"
:
"Foo"
,
"apiVersion"
:
"example.com/v1"
,
"metadata"
:
map
[
string
]
interface
{}{
"name"
:
"test"
},
},
},
isNamespaced
:
false
,
},
}
}
for
i
,
test
:=
range
table
{
for
i
,
test
:=
range
table
{
printer
:=
printers
.
NewTablePrinter
(
printers
.
PrintOptions
{
WithNamespace
:
true
,
NoHeaders
:
true
,
})
AddHandlers
(
printer
)
buffer
:=
&
bytes
.
Buffer
{}
err
:=
printer
.
PrintObj
(
test
.
obj
,
buffer
)
if
err
!=
nil
{
t
.
Fatalf
(
"An error occurred printing object: %#v"
,
err
)
}
if
test
.
isNamespaced
{
if
test
.
isNamespaced
{
// Expect output to include namespace when requested.
if
!
strings
.
HasPrefix
(
buffer
.
String
(),
namespaceName
+
" "
)
{
printer
:=
printers
.
NewTablePrinter
(
printers
.
PrintOptions
{
t
.
Errorf
(
"%d: Expect printing object %T to contain namespace %q, got %s"
,
i
,
test
.
obj
,
namespaceName
,
buffer
.
String
())
WithNamespace
:
true
,
})
AddHandlers
(
printer
)
buffer
:=
&
bytes
.
Buffer
{}
err
:=
printer
.
PrintObj
(
test
.
obj
,
buffer
)
if
err
!=
nil
{
t
.
Fatalf
(
"An error occurred printing object: %#v"
,
err
)
}
matched
:=
contains
(
strings
.
Fields
(
buffer
.
String
()),
fmt
.
Sprintf
(
"%s"
,
namespaceName
))
if
!
matched
{
t
.
Errorf
(
"%d: Expect printing object to contain namespace: %#v"
,
i
,
test
.
obj
)
}
}
}
else
{
}
else
{
// Expect error when trying to get all namespaces for un-namespaced object.
if
!
strings
.
HasPrefix
(
buffer
.
String
(),
" "
)
{
printer
:=
printers
.
NewTablePrinter
(
printers
.
PrintOptions
{
t
.
Errorf
(
"%d: Expect printing object %T to not contain namespace got %s"
,
i
,
test
.
obj
,
buffer
.
String
())
WithNamespace
:
true
,
})
buffer
:=
&
bytes
.
Buffer
{}
err
:=
printer
.
PrintObj
(
test
.
obj
,
buffer
)
if
err
==
nil
{
t
.
Errorf
(
"Expected error when printing un-namespaced type"
)
}
}
}
}
}
}
...
...
pkg/printers/tablegenerator.go
View file @
9bc3ead5
...
@@ -35,7 +35,6 @@ type TableGenerator interface {
...
@@ -35,7 +35,6 @@ type TableGenerator interface {
// PrintHandler - interface to handle printing provided an array of metav1beta1.TableColumnDefinition
// PrintHandler - interface to handle printing provided an array of metav1beta1.TableColumnDefinition
type
PrintHandler
interface
{
type
PrintHandler
interface
{
TableHandler
(
columns
[]
metav1beta1
.
TableColumnDefinition
,
printFunc
interface
{})
error
TableHandler
(
columns
[]
metav1beta1
.
TableColumnDefinition
,
printFunc
interface
{})
error
DefaultTableHandler
(
columns
[]
metav1beta1
.
TableColumnDefinition
,
printFunc
interface
{})
error
}
}
type
handlerEntry
struct
{
type
handlerEntry
struct
{
...
@@ -49,11 +48,10 @@ type handlerEntry struct {
...
@@ -49,11 +48,10 @@ type handlerEntry struct {
// will only be printed if the object type changes. This makes it useful for printing items
// will only be printed if the object type changes. This makes it useful for printing items
// received from watches.
// received from watches.
type
HumanReadablePrinter
struct
{
type
HumanReadablePrinter
struct
{
handlerMap
map
[
reflect
.
Type
]
*
handlerEntry
handlerMap
map
[
reflect
.
Type
]
*
handlerEntry
defaultHandler
*
handlerEntry
options
PrintOptions
options
PrintOptions
lastType
interface
{}
lastType
interface
{}
lastColumns
[]
metav1beta1
.
TableColumnDefinition
lastColumns
[]
metav1beta1
.
TableColumnDefinition
}
}
var
_
TableGenerator
=
&
HumanReadablePrinter
{}
var
_
TableGenerator
=
&
HumanReadablePrinter
{}
...
@@ -149,24 +147,6 @@ func (h *HumanReadablePrinter) TableHandler(columnDefinitions []metav1beta1.Tabl
...
@@ -149,24 +147,6 @@ func (h *HumanReadablePrinter) TableHandler(columnDefinitions []metav1beta1.Tabl
return
nil
return
nil
}
}
// DefaultTableHandler registers a set of columns and a print func that is given a chance to process
// any object without an explicit handler. Only the most recently set print handler is used.
// See ValidateRowPrintHandlerFunc for required method signature.
func
(
h
*
HumanReadablePrinter
)
DefaultTableHandler
(
columnDefinitions
[]
metav1beta1
.
TableColumnDefinition
,
printFunc
interface
{})
error
{
printFuncValue
:=
reflect
.
ValueOf
(
printFunc
)
if
err
:=
ValidateRowPrintHandlerFunc
(
printFuncValue
);
err
!=
nil
{
utilruntime
.
HandleError
(
fmt
.
Errorf
(
"unable to register print function: %v"
,
err
))
return
err
}
entry
:=
&
handlerEntry
{
columnDefinitions
:
columnDefinitions
,
printFunc
:
printFuncValue
,
}
h
.
defaultHandler
=
entry
return
nil
}
// ValidateRowPrintHandlerFunc validates print handler signature.
// ValidateRowPrintHandlerFunc validates print handler signature.
// printFunc is the function that will be called to print an object.
// printFunc is the function that will be called to print an object.
// It must be of the following type:
// It must be of the following type:
...
...
pkg/printers/tableprinter.go
View file @
9bc3ead5
...
@@ -21,6 +21,7 @@ import (
...
@@ -21,6 +21,7 @@ import (
"io"
"io"
"reflect"
"reflect"
"strings"
"strings"
"time"
"github.com/liggitt/tabwriter"
"github.com/liggitt/tabwriter"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/api/meta"
...
@@ -28,10 +29,24 @@ import (
...
@@ -28,10 +29,24 @@ import (
metav1beta1
"k8s.io/apimachinery/pkg/apis/meta/v1beta1"
metav1beta1
"k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/duration"
)
)
var
_
ResourcePrinter
=
&
HumanReadablePrinter
{}
var
_
ResourcePrinter
=
&
HumanReadablePrinter
{}
var
withNamespacePrefixColumns
=
[]
string
{
"NAMESPACE"
}
// TODO(erictune): print cluster name too.
var
(
defaultHandlerEntry
=
&
handlerEntry
{
columnDefinitions
:
objectMetaColumnDefinitions
,
printFunc
:
reflect
.
ValueOf
(
printObjectMeta
),
}
objectMetaColumnDefinitions
=
[]
metav1beta1
.
TableColumnDefinition
{
{
Name
:
"Name"
,
Type
:
"string"
,
Format
:
"name"
,
Description
:
metav1
.
ObjectMeta
{}
.
SwaggerDoc
()[
"name"
]},
{
Name
:
"Age"
,
Type
:
"string"
,
Description
:
metav1
.
ObjectMeta
{}
.
SwaggerDoc
()[
"creationTimestamp"
]},
}
withNamespacePrefixColumns
=
[]
string
{
"NAMESPACE"
}
// TODO(erictune): print cluster name too.
)
// NewTablePrinter creates a printer suitable for calling PrintObj().
// NewTablePrinter creates a printer suitable for calling PrintObj().
// TODO(seans3): Change return type to ResourcePrinter interface once we no longer need
// TODO(seans3): Change return type to ResourcePrinter interface once we no longer need
...
@@ -104,23 +119,18 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
...
@@ -104,23 +119,18 @@ func (h *HumanReadablePrinter) PrintObj(obj runtime.Object, output io.Writer) er
}
}
// Case 3: Could not find print handler for "obj"; use the default print handler.
// Case 3: Could not find print handler for "obj"; use the default print handler.
// print with the default handler if set, and use the columns from the last time
// Print with the default handler, and use the columns from the last time
if
h
.
defaultHandler
!=
nil
{
includeHeaders
:=
h
.
lastType
!=
defaultHandlerEntry
&&
!
h
.
options
.
NoHeaders
includeHeaders
:=
h
.
lastType
!=
h
.
defaultHandler
&&
!
h
.
options
.
NoHeaders
if
h
.
lastType
!=
nil
&&
h
.
lastType
!=
h
.
defaultHandler
&&
!
h
.
options
.
NoHeaders
{
if
h
.
lastType
!=
nil
&&
h
.
lastType
!=
defaultHandlerEntry
&&
!
h
.
options
.
NoHeaders
{
fmt
.
Fprintln
(
output
)
fmt
.
Fprintln
(
output
)
}
if
err
:=
printRowsForHandlerEntry
(
output
,
h
.
defaultHandler
,
obj
,
h
.
options
,
includeHeaders
);
err
!=
nil
{
return
err
}
h
.
lastType
=
h
.
defaultHandler
return
nil
}
}
// we failed all reasonable printing efforts, report failure
if
err
:=
printRowsForHandlerEntry
(
output
,
defaultHandlerEntry
,
obj
,
h
.
options
,
includeHeaders
);
err
!=
nil
{
return
fmt
.
Errorf
(
"error: unknown type %#v"
,
obj
)
return
err
}
h
.
lastType
=
defaultHandlerEntry
return
nil
}
}
// PrintTable prints a table to the provided output respecting the filtering rules for options
// PrintTable prints a table to the provided output respecting the filtering rules for options
...
@@ -384,3 +394,43 @@ func appendLabelCells(values []interface{}, itemLabels map[string]string, opts P
...
@@ -384,3 +394,43 @@ func appendLabelCells(values []interface{}, itemLabels map[string]string, opts P
}
}
return
values
return
values
}
}
func
printObjectMeta
(
obj
runtime
.
Object
,
options
PrintOptions
)
([]
metav1beta1
.
TableRow
,
error
)
{
if
meta
.
IsListType
(
obj
)
{
rows
:=
make
([]
metav1beta1
.
TableRow
,
0
,
16
)
err
:=
meta
.
EachListItem
(
obj
,
func
(
obj
runtime
.
Object
)
error
{
nestedRows
,
err
:=
printObjectMeta
(
obj
,
options
)
if
err
!=
nil
{
return
err
}
rows
=
append
(
rows
,
nestedRows
...
)
return
nil
})
if
err
!=
nil
{
return
nil
,
err
}
return
rows
,
nil
}
rows
:=
make
([]
metav1beta1
.
TableRow
,
0
,
1
)
m
,
err
:=
meta
.
Accessor
(
obj
)
if
err
!=
nil
{
return
nil
,
err
}
row
:=
metav1beta1
.
TableRow
{
Object
:
runtime
.
RawExtension
{
Object
:
obj
},
}
row
.
Cells
=
append
(
row
.
Cells
,
m
.
GetName
(),
translateTimestampSince
(
m
.
GetCreationTimestamp
()))
rows
=
append
(
rows
,
row
)
return
rows
,
nil
}
// translateTimestampSince returns the elapsed time since timestamp in
// human-readable approximation.
func
translateTimestampSince
(
timestamp
metav1
.
Time
)
string
{
if
timestamp
.
IsZero
()
{
return
"<unknown>"
}
return
duration
.
HumanDuration
(
time
.
Since
(
timestamp
.
Time
))
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment