Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Index more sqlite cache fields #271

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func main() {
func run(_ *cli.Context) error {
ctx := signals.SetupSignalContext()
debugconfig.MustSetupDebug()
s, err := config.ToServer(ctx, false)
s, err := config.ToServer(ctx, debugconfig.SQLCache)
if err != nil {
return err
}
Expand Down
9 changes: 9 additions & 0 deletions pkg/debug/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
type Config struct {
Debug bool
DebugLevel int
SQLCache bool
}

func (c *Config) MustSetupDebug() {
Expand Down Expand Up @@ -54,6 +55,10 @@ func Flags(config *Config) []cli.Flag {
Value: 7,
Destination: &config.DebugLevel,
},
cli.BoolFlag{
Name: "sql-cache",
Destination: &config.SQLCache,
},
}
}

Expand All @@ -68,5 +73,9 @@ func FlagsV2(config *Config) []cliv2.Flag {
Value: 7,
Destination: &config.DebugLevel,
},
&cliv2.BoolFlag{
Name: "sql-cache",
Destination: &config.SQLCache,
},
}
}
23 changes: 5 additions & 18 deletions pkg/resources/virtual/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
wranglerSummary "github.com/rancher/wrangler/v3/pkg/summary"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/cache"
)

// SummaryCache provides an interface to get a summary/relationships for an object. Implemented by the summaryCache
Expand All @@ -24,26 +23,14 @@ type DefaultFields struct {
Cache SummaryCache
}

// GetTransform produces the default transformation func
func (d *DefaultFields) GetTransform() cache.TransformFunc {
return d.transform
}

// transform implements virtual.VirtualTransformFunc, and adds reserved fields/summary
func (d *DefaultFields) transform(obj any) (any, error) {
raw, isSignal, err := getUnstructured(obj)
if isSignal {
return obj, nil
}
if err != nil {
return nil, err
}
raw = addIDField(raw)
raw, err = addSummaryFields(raw, d.Cache)
// TransformCommon implements virtual.VirtualTransformFunc, and adds reserved fields/summary
func (d *DefaultFields) TransformCommon(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
obj = addIDField(obj)
obj, err := addSummaryFields(obj, d.Cache)
if err != nil {
return nil, fmt.Errorf("unable to add summary fields: %w", err)
}
return raw, nil
return obj, nil
}

// addSummaryFields adds the virtual fields for object state.
Expand Down
31 changes: 15 additions & 16 deletions pkg/resources/virtual/common/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ import (
"github.com/stretchr/testify/require"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/cache"
)

func TestTransform(t *testing.T) {
func TestTransformCommonObjects(t *testing.T) {
ericpromislow marked this conversation as resolved.
Show resolved Hide resolved
tests := []struct {
name string
input any
Expand Down Expand Up @@ -160,29 +159,29 @@ func TestTransform(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
fakeCache := fakeSummaryCache{
summarizedObject: test.hasSummary,
relationships: test.hasRelationships,
fakeCache := common.FakeSummaryCache{
SummarizedObject: test.hasSummary,
Relationships: test.hasRelationships,
}
df := common.DefaultFields{
Cache: &fakeCache,
}
output, err := df.GetTransform()(test.input)
require.Equal(t, test.wantOutput, output)
raw, isSignal, err := common.GetUnstructured(test.input)
if err != nil {
require.True(t, test.wantError)
return
}
if isSignal {
require.Equal(t, test.input, test.wantOutput)
return
}
output, err := df.TransformCommon(raw)
if test.wantError {
require.Error(t, err)
} else {
require.Equal(t, test.wantOutput, output)
require.NoError(t, err)
}
})
}
}

type fakeSummaryCache struct {
summarizedObject *summary.SummarizedObject
relationships []summarycache.Relationship
}

func (f *fakeSummaryCache) SummaryAndRelationship(runtime.Object) (*summary.SummarizedObject, []summarycache.Relationship) {
return f.summarizedObject, f.relationships
}
16 changes: 16 additions & 0 deletions pkg/resources/virtual/common/testutil.go
ericpromislow marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package common

import (
"github.com/rancher/steve/pkg/summarycache"
"github.com/rancher/wrangler/v3/pkg/summary"
"k8s.io/apimachinery/pkg/runtime"
)

type FakeSummaryCache struct {
SummarizedObject *summary.SummarizedObject
Relationships []summarycache.Relationship
}

func (f *FakeSummaryCache) SummaryAndRelationship(runtime.Object) (*summary.SummarizedObject, []summarycache.Relationship) {
return f.SummarizedObject, f.Relationships
}
2 changes: 1 addition & 1 deletion pkg/resources/virtual/common/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
// GetUnstructured retrieves an unstructured object from the provided input. If this is a signal
// object (like cache.DeletedFinalStateUnknown), returns true, indicating that this wasn't an
// unstructured object, but doesn't need to be processed by our transform function
func getUnstructured(obj any) (*unstructured.Unstructured, bool, error) {
func GetUnstructured(obj any) (*unstructured.Unstructured, bool, error) {
raw, ok := obj.(*unstructured.Unstructured)
if !ok {
_, isFinalUnknown := obj.(cache.DeletedFinalStateUnknown)
Expand Down
16 changes: 16 additions & 0 deletions pkg/resources/virtual/events/events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Package common provides cache.TransformFunc's for /v1 Event objects
package events

import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

// TransformEventObject does special-case handling on event objects
// 1. (only one so far): replaces the _type field with the contents of the field named "type", if it exists
func TransformEventObject(obj *unstructured.Unstructured) (*unstructured.Unstructured, error) {
MbolotSuse marked this conversation as resolved.
Show resolved Hide resolved
currentTypeValue, ok := obj.Object["type"]
if ok {
obj.Object["_type"] = currentTypeValue
}
return obj, nil
}
93 changes: 93 additions & 0 deletions pkg/resources/virtual/events/events_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package events_test

import (
"testing"

"github.com/rancher/steve/pkg/resources/virtual/events"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

func TestTransformEvents(t *testing.T) {
tests := []struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a test case where there's no "type" and so we don't add "_type".

name string
input any
wantOutput any
wantError bool
}{
{
name: "fix event fields",
input: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "/v1",
"kind": "Event",
"metadata": map[string]interface{}{
"name": "gregsFarm",
"namespace": "gregsNamespace",
},
"id": "eventTest1id",
"type": "Gorniplatz",
},
},
wantOutput: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "/v1",
"kind": "Event",
"metadata": map[string]interface{}{
"name": "gregsFarm",
"namespace": "gregsNamespace",
},
"id": "eventTest1id",
"type": "Gorniplatz",
"_type": "Gorniplatz",
},
},
},
{
name: "don't fix non-default-group event fields",
ericpromislow marked this conversation as resolved.
Show resolved Hide resolved
input: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "palau.io/v1",
"kind": "Event",
"metadata": map[string]interface{}{
"name": "gregsFarm",
"namespace": "gregsNamespace",
},
"id": "eventTest1id",
"type": "Gorniplatz",
},
},
wantOutput: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "palau.io/v1",
"kind": "Event",
"metadata": map[string]interface{}{
"name": "gregsFarm",
"namespace": "gregsNamespace",
},
"id": "eventTest1id",
"type": "Gorniplatz",
},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
var output interface{}
var err error
raw, ok := test.input.(*unstructured.Unstructured)
if ok && raw.GetKind() == "Event" && raw.GetAPIVersion() == "/v1" {
output, err = events.TransformEventObject(raw)
} else {
output = raw
err = nil
}
require.Equal(t, test.wantOutput, output)
if test.wantError {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}
35 changes: 31 additions & 4 deletions pkg/resources/virtual/virtual.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
package virtual

import (
"fmt"

"github.com/rancher/steve/pkg/resources/virtual/common"
"github.com/rancher/steve/pkg/resources/virtual/events"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/tools/cache"
)
Expand All @@ -16,13 +20,36 @@ type TransformBuilder struct {
// NewTransformBuilder returns a TransformBuilder using the given summary cache
func NewTransformBuilder(cache common.SummaryCache) *TransformBuilder {
return &TransformBuilder{
&common.DefaultFields{
defaultFields: &common.DefaultFields{
Cache: cache,
},
}
}

// GetTransformFunc retrieves a TransformFunc for a given GVK. Currently only returns a transformFunc for defaultFields
func (t *TransformBuilder) GetTransformFunc(_ schema.GroupVersionKind) cache.TransformFunc {
return t.defaultFields.GetTransform()
// GetTransformFunc returns the func to transform a raw object into a fixed object, if needed
func (t *TransformBuilder) GetTransformFunc(gvk schema.GroupVersionKind) cache.TransformFunc {
converters := make([]func(*unstructured.Unstructured) (*unstructured.Unstructured, error), 0)
if gvk.Kind == "Event" && gvk.Group == "" && gvk.Version == "v1" {
converters = append(converters, events.TransformEventObject)
}
converters = append(converters, t.defaultFields.TransformCommon)
Comment on lines +31 to +35
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: You could initialize this with the common converter:

Suggested change
converters := make([]func(*unstructured.Unstructured) (*unstructured.Unstructured, error), 0)
if gvk.Kind == "Event" && gvk.Group == "" && gvk.Version == "v1" {
converters = append(converters, events.TransformEventObject)
}
converters = append(converters, t.defaultFields.TransformCommon)
converters := []func(*unstructured.Unstructured) (*unstructured.Unstructured, error){t.defaultFields.TransformCommon}
if gvk.Kind == "Event" && gvk.Group == "" && gvk.Version == "v1" {
converters = append(converters, events.TransformEventObject)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather leave the transformers running from specific to general, until we find they can be run in any order.


return func(raw interface{}) (interface{}, error) {
obj, isSignal, err := common.GetUnstructured(raw)
if isSignal {
// isSignal= true overrides any error
return raw, err
}
moio marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return nil, fmt.Errorf("GetUnstructured: failed to get underlying object: %w", err)
}
// Conversions are run in this loop:
for _, f := range converters {
obj, err = f(obj)
if err != nil {
return nil, err
}
}
return obj, nil
}
}
Loading