HAOJX

聚合api编程之自定义kubectl输出字段的方法:metav1.Table

字数统计: 920阅读时长: 4 min
2022/05/22 Share

kubectl输出的格式一般是设置好的 写死的 也就是各个资源的列表头的定义都是写死的 具体代码在

github.com/kubernetes/kubernetes/-/blob/pkg/printers/internalversion/printers.go

验证: 当我们输入

1
kubectl describe pod xxx -v=10

可以看到kubectl的输出是转换成了table这种type形式输出的

如果kubectl无法解析成table的话, 他会自己解析成一个 no-Table Object 也就是说只显示NAME和AGE

下面是个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
....
import (
"github.com/haojianxun/k8s-aa/pkg/apis/myingress/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
var (
Table_ListColumns=[]string{"name","namespace","path","host"}
)
// 把列表 或单资源 变成表格化
func ConvertToTable(obj interface{}) *metav1.Table{

t:= &metav1.Table{}
t.Kind="Table"
t.APIVersion="meta.k8s.io/v1"
if v,ok:=obj.(*v1beta1.MyIngressList);ok{ //代表取列表
//设置表头
th:=make([]metav1.TableColumnDefinition,len(Table_ListColumns))
for i,h:=range Table_ListColumns{
format:="name"

th[i]=metav1.TableColumnDefinition{Name: h,Type: "string",Format:format}
}
t.ColumnDefinitions=th //设置表头
//设置 行 数据
rows:=make([]metav1.TableRow,len(v.Items))
for i,item:=range v.Items{
rows[i]=metav1.TableRow{
Cells: []interface{}{item.Name,item.Namespace,
item.Spec.Path,item.Spec.Host},
}
}
t.Rows=rows
}
return t

}

....

总之 想显示自定义的列的话 先构造一个metav1.Table

那Table的type长什么样子呢

1
2
3
4
5
6
7
8
9
10
11
12
13
type Table struct {
TypeMeta `json:",inline"`
// Standard list metadata.
// More info: <https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds>
// +optional
ListMeta `json:"metadata,omitempty"`

// columnDefinitions describes each column in the returned items array. The number of cells per row
// will always match the number of column definitions.
ColumnDefinitions []TableColumnDefinition `json:"columnDefinitions"`
// rows is the list of items in the table.
Rows []TableRow `json:"rows"`
}

可以看到 我们要做的就是把 ColumnDefinitions 去填充自己定义的想打印的列

ColumnDefinitions的定义如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
type TableColumnDefinition struct {
// name is a human readable name for the column.
Name string `json:"name"`
// type is an OpenAPI type definition for this column, such as number, integer, string, or
// array.
// See <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types> for more.
Type string `json:"type"`
// format is an optional OpenAPI type modifier for this column. A format modifies the type and
// imposes additional rules, like date or time formatting for a string. The 'name' format is applied
// to the primary identifier column which has type 'string' to assist in clients identifying column
// is the resource name.
// See <https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types> for more.
Format string `json:"format"`
// description is a human readable description of this column.
Description string `json:"description"`
// priority is an integer defining the relative importance of this column compared to others. Lower
// numbers are considered higher priority. Columns that may be omitted in limited space scenarios
// should be given a higher priority.
Priority int32 `json:"priority"`
}

至于想定义那些列 你可以自己去定义 , 下面给个源码中kubectl输出deployment资源的列的定义

可以参考下deployment是怎么定义的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....

deploymentColumnDefinitions := []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name", Description: metav1.ObjectMeta{}.SwaggerDoc()["name"]},
{Name: "Ready", Type: "string", Description: "Number of the pod with ready state"},
{Name: "Up-to-date", Type: "string", Description: extensionsv1beta1.DeploymentStatus{}.SwaggerDoc()["updatedReplicas"]},
{Name: "Available", Type: "string", Description: extensionsv1beta1.DeploymentStatus{}.SwaggerDoc()["availableReplicas"]},
{Name: "Age", Type: "string", Description: metav1.ObjectMeta{}.SwaggerDoc()["creationTimestamp"]},
{Name: "Containers", Type: "string", Priority: 1, Description: "Names of each container in the template."},
{Name: "Images", Type: "string", Priority: 1, Description: "Images referenced by each container in the template."},
{Name: "Selector", Type: "string", Priority: 1, Description: extensionsv1beta1.DeploymentSpec{}.SwaggerDoc()["selector"]},
}
t := &metav1.Table{
ColumnDefinitions: deploymentColumnDefinitions,
}
t.Kind = "Table"
t.APIVersion = "meta.k8s.io/v1"

.....

table的Kind固定为”Table” 里面的metav1.TableColumnDefinition 里面的东西自己去自定义格式

之后定义完了格式之后 就可以填充数据了 填充数据的话 用的就是Table中的Rows

上面的例子的填充的地方在

1
2
3
4
5
6
for i,item:=range v.Items{
rows[i]=metav1.TableRow{
Cells: []interface{}{item.Name,item.Namespace,
item.Spec.Path,item.Spec.Host},
}
}

就是构造出一个

1
2
3
metav1.TableRow{
Cells: []interface{}{这里按照列的顺序依次填入想填的数据即可}
}
CATALOG