From fd534cf332c488f229b77657cc99424e0e428b69 Mon Sep 17 00:00:00 2001 From: "Dr. Stefan Schimanski" Date: Tue, 16 Jul 2024 14:34:00 +0200 Subject: [PATCH 1/2] apis/query: add table row responses Signed-off-by: Dr. Stefan Schimanski --- apis/query/v1alpha1/query_types.go | 26 ++++++++++++++++++++++ apis/query/v1alpha1/queryresponse_types.go | 18 +++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/apis/query/v1alpha1/query_types.go b/apis/query/v1alpha1/query_types.go index c7b46ab..36f62da 100644 --- a/apis/query/v1alpha1/query_types.go +++ b/apis/query/v1alpha1/query_types.go @@ -238,6 +238,9 @@ type QueryObjects struct { // +kubebuilder:pruning:PreserveUnknownFields Object *common.JSON `json:"object,omitempty"` + // table specifies whether to return the object in a table format. + Table *QueryTable `json:"table,omitempty"` + // relations specifies which relations to query and what to return. // Relation names are predefined strings relative to the release of // Spaces. @@ -247,6 +250,29 @@ type QueryObjects struct { Relations map[string]QueryRelation `json:"relations,omitempty"` } +// QueryGrouping specifies how to group the returned objects into multiple +// tables. +type QueryGrouping string + +const ( + // ByGVKsAndColumns specifies to group by GVKs and column definitions. I.e. + // rows of different GVKs or with different column definitions are grouped + // into different tables. + ByGVKsAndColumns QueryGrouping = "ByGVKsAndColumn" +) + +// QueryTable specifies how to return objects in a table or multiple tables +// (in case of grouping). +type QueryTable struct { + // grouping specifies how to group the returned objects into multiple + // tables where every table can have different sets of columns. + Grouping QueryGrouping `json:"grouping,omitempty"` + + // noHeaders specifies whether to return the headers of the table in the + // first row. + NoHeaders bool `json:"noHeaders,omitempty"` +} + // A QueryRelation specifies how to return objects in a relation. type QueryRelation struct { QueryNestedResources `json:",inline"` diff --git a/apis/query/v1alpha1/queryresponse_types.go b/apis/query/v1alpha1/queryresponse_types.go index ccb183b..3aad9e7 100644 --- a/apis/query/v1alpha1/queryresponse_types.go +++ b/apis/query/v1alpha1/queryresponse_types.go @@ -36,8 +36,16 @@ type QueryResponseObjects struct { Cursor *QueryResponseCursor `json:"cursor,omitempty"` // objects is the list of objects returned by the query. + // + // Objects is mutual exclusive with Tables. Objects []QueryResponseObject `json:"objects,omitempty"` + // tables is the list of tables returned by the query. Objects are grouped + // as specified in the query. Hence, potentially multiple tables are returned. + // + // Objects is mutual exclusive with Tables. + Tables []QueryResponseTable `json:"tables,omitempty"` + // count is the total number of objects that match the query. Count *int `json:"count,omitempty"` @@ -48,6 +56,16 @@ type QueryResponseObjects struct { Incomplete bool `json:"incomplete,omitempty"` } +// QueryResponseTable is a table representation of a set of API resources. +type QueryResponseTable struct { + // groupVersionKind is the group, version, and kind of the objects in the table. + GroupVersionKind metav1.GroupVersionKind `json:"groupVersionKind"` + // columns is the list of columns in the table. + Columns []metav1.TableColumnDefinition `json:"columns"` + // rows is the list of rows in the table. + Rows []metav1.TableRow `json:"rows"` +} + // QueryResponseCursor is the cursor to the next page of results. type QueryResponseCursor struct { // cursor is the cursor to the next page of results. If empty, there are no more, From fdefa8dd244b7f73feb6c7addfb4c7f1a01f6733 Mon Sep 17 00:00:00 2001 From: "Dr. Stefan Schimanski" Date: Wed, 17 Jul 2024 15:50:20 +0200 Subject: [PATCH 2/2] make generate Signed-off-by: Dr. Stefan Schimanski --- apis/query/v1alpha1/zz_generated.deepcopy.go | 56 ++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/apis/query/v1alpha1/zz_generated.deepcopy.go b/apis/query/v1alpha1/zz_generated.deepcopy.go index 8edde10..2fdebdc 100644 --- a/apis/query/v1alpha1/zz_generated.deepcopy.go +++ b/apis/query/v1alpha1/zz_generated.deepcopy.go @@ -21,6 +21,7 @@ limitations under the License. package v1alpha1 import ( + "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -178,6 +179,11 @@ func (in *QueryObjects) DeepCopyInto(out *QueryObjects) { in, out := &in.Object, &out.Object *out = (*in).DeepCopy() } + if in.Table != nil { + in, out := &in.Table, &out.Table + *out = new(QueryTable) + **out = **in + } if in.Relations != nil { in, out := &in.Relations, &out.Relations *out = make(map[string]QueryRelation, len(*in)) @@ -407,6 +413,13 @@ func (in *QueryResponseObjects) DeepCopyInto(out *QueryResponseObjects) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Tables != nil { + in, out := &in.Tables, &out.Tables + *out = make([]QueryResponseTable, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } if in.Count != nil { in, out := &in.Count, &out.Count *out = new(int) @@ -440,6 +453,34 @@ func (in *QueryResponseRelation) DeepCopy() *QueryResponseRelation { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *QueryResponseTable) DeepCopyInto(out *QueryResponseTable) { + *out = *in + out.GroupVersionKind = in.GroupVersionKind + if in.Columns != nil { + in, out := &in.Columns, &out.Columns + *out = make([]v1.TableColumnDefinition, len(*in)) + copy(*out, *in) + } + if in.Rows != nil { + in, out := &in.Rows, &out.Rows + *out = make([]v1.TableRow, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new QueryResponseTable. +func (in *QueryResponseTable) DeepCopy() *QueryResponseTable { + if in == nil { + return nil + } + out := new(QueryResponseTable) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *QuerySpec) DeepCopyInto(out *QuerySpec) { *out = *in @@ -456,6 +497,21 @@ func (in *QuerySpec) DeepCopy() *QuerySpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *QueryTable) DeepCopyInto(out *QueryTable) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new QueryTable. +func (in *QueryTable) DeepCopy() *QueryTable { + if in == nil { + return nil + } + out := new(QueryTable) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *QueryTopLevelFilter) DeepCopyInto(out *QueryTopLevelFilter) { *out = *in