mirror of
https://github.com/rancher/steve.git
synced 2025-04-27 19:05:09 +00:00
This uses SQLite-backed informers provided by Lasso with https://github.com/rancher/lasso/pull/65 to implement Steve API (/v1/) functionality. This new functionality is available behind a feature flag to be specified at Steve startup See https://confluence.suse.com/pages/viewpage.action?pageId=1359086083 Co-authored-by: Ricardo Weir <ricardo.weir@suse.com> Co-authored-by: Michael Bolot <michael.bolot@suse.com> Co-authored-by: Silvio Moioli <silvio@moioli.net> Signed-off-by: Silvio Moioli <silvio@moioli.net>
134 lines
3.1 KiB
Go
134 lines
3.1 KiB
Go
/*
|
|
Package tablelistconvert provides a client that will use a table client but convert *UnstructuredList and *Unstructured objects
|
|
returned by ByID and List to resemble those returned by non-table clients while preserving some table-related data.
|
|
*/
|
|
package tablelistconvert
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/rancher/wrangler/v2/pkg/data"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
k8sWatch "k8s.io/apimachinery/pkg/watch"
|
|
"k8s.io/client-go/dynamic"
|
|
)
|
|
|
|
type Client struct {
|
|
dynamic.ResourceInterface
|
|
}
|
|
|
|
var _ dynamic.ResourceInterface = (*Client)(nil)
|
|
|
|
type tableConvertWatch struct {
|
|
done chan struct{}
|
|
events chan k8sWatch.Event
|
|
k8sWatch.Interface
|
|
}
|
|
|
|
// List will return an *UnstructuredList that contains Items instead of just using the Object field to store a table as
|
|
// Table Clients do. The items will preserve values for columns in the form of metadata.fields.
|
|
func (c *Client) List(ctx context.Context, opts metav1.ListOptions) (*unstructured.UnstructuredList, error) {
|
|
list, err := c.ResourceInterface.List(ctx, opts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
tableToList(list)
|
|
return list, nil
|
|
}
|
|
|
|
func (c *Client) Watch(ctx context.Context, opts metav1.ListOptions) (k8sWatch.Interface, error) {
|
|
w, err := c.ResourceInterface.Watch(ctx, opts)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
events := make(chan k8sWatch.Event)
|
|
done := make(chan struct{})
|
|
eventWatch := &tableConvertWatch{done: done, events: events, Interface: w}
|
|
eventWatch.feed()
|
|
return eventWatch, nil
|
|
}
|
|
|
|
func (w *tableConvertWatch) feed() {
|
|
tableEvents := w.Interface.ResultChan()
|
|
go func() {
|
|
for {
|
|
select {
|
|
case e, ok := <-tableEvents:
|
|
if !ok {
|
|
close(w.events)
|
|
return
|
|
}
|
|
if unstr, ok := e.Object.(*unstructured.Unstructured); ok {
|
|
rowToObject(unstr)
|
|
w.events <- e
|
|
}
|
|
case <-w.done:
|
|
close(w.events)
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
func (w *tableConvertWatch) ResultChan() <-chan k8sWatch.Event {
|
|
return w.events
|
|
}
|
|
|
|
func (w *tableConvertWatch) Stop() {
|
|
fmt.Println("stop")
|
|
close(w.done)
|
|
w.Interface.Stop()
|
|
}
|
|
|
|
func rowToObject(obj *unstructured.Unstructured) {
|
|
if obj == nil {
|
|
return
|
|
}
|
|
if obj.Object["kind"] != "Table" ||
|
|
(obj.Object["apiVersion"] != "meta.k8s.io/v1" &&
|
|
obj.Object["apiVersion"] != "meta.k8s.io/v1beta1") {
|
|
return
|
|
}
|
|
|
|
items := tableToObjects(obj.Object)
|
|
if len(items) == 1 {
|
|
obj.Object = items[0].Object
|
|
}
|
|
}
|
|
|
|
func tableToList(obj *unstructured.UnstructuredList) {
|
|
if obj.Object["kind"] != "Table" ||
|
|
(obj.Object["apiVersion"] != "meta.k8s.io/v1" &&
|
|
obj.Object["apiVersion"] != "meta.k8s.io/v1beta1") {
|
|
return
|
|
}
|
|
|
|
obj.Items = tableToObjects(obj.Object)
|
|
}
|
|
|
|
func tableToObjects(obj map[string]interface{}) []unstructured.Unstructured {
|
|
var result []unstructured.Unstructured
|
|
|
|
rows, _ := obj["rows"].([]interface{})
|
|
for _, row := range rows {
|
|
m, ok := row.(map[string]interface{})
|
|
if !ok {
|
|
continue
|
|
}
|
|
cells := m["cells"]
|
|
object, ok := m["object"].(map[string]interface{})
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
data.PutValue(object, cells, "metadata", "fields")
|
|
result = append(result, unstructured.Unstructured{
|
|
Object: object,
|
|
})
|
|
}
|
|
|
|
return result
|
|
}
|