Skip to content

Commit a4b1398

Browse files
stttsbertinatto
authored andcommitted
UPSTREAM: <carry>: crd: add ClusterOperator condition message table column
The logic is not exressible via JSONPath. Hence, if we want this, we have to help a little with this custom column writer. OpenShift-Rebase-Source: 633a422
1 parent c56304a commit a4b1398

File tree

4 files changed

+106
-6
lines changed

4 files changed

+106
-6
lines changed

staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
807807
utilruntime.HandleError(err)
808808
return nil, fmt.Errorf("the server could not properly serve the CR columns")
809809
}
810-
table, err := tableconvertor.New(columns)
810+
table, err := tableconvertor.New(columns, schema.GroupVersionKind{crd.Spec.Group, v.Name, crd.Spec.Names.Kind})
811811
if err != nil {
812812
klog.V(2).Infof("The CRD for %v has an invalid printer specification, falling back to default printing: %v", kind, err)
813813
}
@@ -966,7 +966,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
966966
if err != nil {
967967
return nil, fmt.Errorf("the server could not properly serve the CR scale subresource columns %w", err)
968968
}
969-
scaleTable, _ := tableconvertor.New(scaleColumns)
969+
scaleTable, _ := tableconvertor.New(scaleColumns, schema.GroupVersionKind{crd.Spec.Group, v.Name, crd.Spec.Names.Kind})
970970

971971
// override scale subresource values
972972
// shallow copy

staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/etcd_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ func newStorage(t *testing.T) (customresource.CustomResourceStorage, *etcd3testi
9090
{Name: "Float64", Type: "number", JSONPath: ".spec.float64"},
9191
{Name: "Bool", Type: "boolean", JSONPath: ".spec.bool"},
9292
}
93-
table, _ := tableconvertor.New(headers)
93+
table, _ := tableconvertor.New(headers, schema.GroupVersionKind{Group: "mygroup.example.com", Version: "v1beta1", Kind: "NoxuItemList"})
9494

9595
storage, err := customresource.NewStorage(
9696
groupResource,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package tableconvertor
2+
3+
import (
4+
"encoding/json"
5+
"io"
6+
"reflect"
7+
8+
configv1 "github.com/openshift/api/config/v1"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
11+
"k8s.io/apimachinery/pkg/runtime/schema"
12+
"k8s.io/apiserver/pkg/registry/rest"
13+
)
14+
15+
var clusterOperatorGVK = schema.GroupVersionKind{configv1.GroupName, "v1", "ClusterOperator"}
16+
17+
func withClusterOperatorColumns(c *convertor, gvk schema.GroupVersionKind) rest.TableConvertor {
18+
if gvk != clusterOperatorGVK {
19+
return c
20+
}
21+
22+
c.headers = append(c.headers, metav1.TableColumnDefinition{
23+
Name: "Message",
24+
Type: "string",
25+
Description: "A message describing the status of the operator",
26+
Priority: 0,
27+
})
28+
c.additionalColumns = append(c.additionalColumns, clusterOperatorConditionMessage{})
29+
30+
return c
31+
}
32+
33+
type clusterOperatorConditionMessage struct {
34+
}
35+
36+
func (c clusterOperatorConditionMessage) FindResults(data interface{}) ([][]reflect.Value, error) {
37+
obj := data.(map[string]interface{})
38+
unstructuredConds, _, _ := unstructured.NestedFieldNoCopy(obj, "status", "conditions")
39+
var conds []configv1.ClusterOperatorStatusCondition
40+
bs, err := json.Marshal(unstructuredConds)
41+
if err != nil {
42+
return nil, err
43+
}
44+
if err := json.Unmarshal(bs, &conds); err != nil {
45+
return nil, err
46+
}
47+
48+
var available, degraded, progressing *configv1.ClusterOperatorStatusCondition
49+
for i := range conds {
50+
cond := &conds[i]
51+
switch {
52+
case cond.Type == configv1.OperatorAvailable && cond.Status == configv1.ConditionFalse:
53+
available = cond
54+
case cond.Type == configv1.OperatorDegraded && cond.Status == configv1.ConditionTrue:
55+
degraded = cond
56+
case cond.Type == configv1.OperatorProgressing && cond.Status == configv1.ConditionTrue:
57+
progressing = cond
58+
}
59+
}
60+
61+
mostCritical := progressing
62+
if degraded != nil {
63+
mostCritical = degraded
64+
}
65+
if available != nil {
66+
mostCritical = available
67+
}
68+
69+
if mostCritical != nil {
70+
if len(mostCritical.Message) > 0 {
71+
return [][]reflect.Value{{reflect.ValueOf(mostCritical.Message)}}, nil
72+
}
73+
if len(mostCritical.Reason) > 0 {
74+
return [][]reflect.Value{{reflect.ValueOf(mostCritical.Reason)}}, nil
75+
}
76+
}
77+
78+
return nil, nil
79+
}
80+
81+
func (c clusterOperatorConditionMessage) PrintResults(wr io.Writer, results []reflect.Value) error {
82+
first := true
83+
for _, r := range results {
84+
if !first {
85+
wr.Write([]byte("; ")) // should never happen as we only return one result
86+
}
87+
if _, err := wr.Write([]byte(r.String())); err != nil {
88+
return err
89+
}
90+
first = false
91+
}
92+
93+
return nil
94+
}

staging/src/k8s.io/apiextensions-apiserver/pkg/registry/customresource/tableconvertor/tableconvertor.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ import (
2929
metatable "k8s.io/apimachinery/pkg/api/meta/table"
3030
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3131
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
32-
"k8s.io/apimachinery/pkg/runtime"
32+
runtime "k8s.io/apimachinery/pkg/runtime"
33+
"k8s.io/apimachinery/pkg/runtime/schema"
3334
"k8s.io/apiserver/pkg/registry/rest"
3435
"k8s.io/client-go/util/jsonpath"
3536
)
@@ -38,7 +39,7 @@ var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc()
3839

3940
// New creates a new table convertor for the provided CRD column definition. If the printer definition cannot be parsed,
4041
// error will be returned along with a default table convertor.
41-
func New(crdColumns []apiextensionsv1.CustomResourceColumnDefinition) (rest.TableConvertor, error) {
42+
func New(crdColumns []apiextensionsv1.CustomResourceColumnDefinition, gvk schema.GroupVersionKind) (rest.TableConvertor, error) {
4243
headers := []metav1.TableColumnDefinition{
4344
{Name: "Name", Type: "string", Format: "name", Description: swaggerMetadataDescriptions["name"]},
4445
}
@@ -68,7 +69,12 @@ func New(crdColumns []apiextensionsv1.CustomResourceColumnDefinition) (rest.Tabl
6869
})
6970
}
7071

71-
return c, nil
72+
return withClusterOperatorColumns(c, gvk), nil
73+
}
74+
75+
type column interface {
76+
FindResults(data interface{}) ([][]reflect.Value, error)
77+
PrintResults(wr io.Writer, results []reflect.Value) error
7278
}
7379

7480
type columnPrinter interface {

0 commit comments

Comments
 (0)