wip
This commit is contained in:
@@ -65,6 +65,11 @@ func (s *StandardDocumentBuilders) GetDocumentBuilders() ([]resource.DocumentBui
|
||||
}, nil
|
||||
})
|
||||
|
||||
users, err := GetUserBuilder()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return []resource.DocumentBuilderInfo{
|
||||
// The default builder
|
||||
{
|
||||
@@ -72,5 +77,7 @@ func (s *StandardDocumentBuilders) GetDocumentBuilders() ([]resource.DocumentBui
|
||||
},
|
||||
// Dashboard builder
|
||||
dashboards,
|
||||
// User builder
|
||||
users,
|
||||
}, err
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"key": {
|
||||
"namespace": "default",
|
||||
"group": "iam.grafana.app",
|
||||
"resource": "users",
|
||||
"name": "example"
|
||||
},
|
||||
"name": "example",
|
||||
"rv": 1234,
|
||||
"title": "example",
|
||||
"title_ngram": "example",
|
||||
"title_phrase": "example",
|
||||
"fields": {
|
||||
"email": "example@example.com",
|
||||
"login": "example"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"apiVersion": "iam.grafana.app/v0alpha1",
|
||||
"kind": "User",
|
||||
"metadata": {
|
||||
"name": "example",
|
||||
"namespace": "default"
|
||||
},
|
||||
"spec": {
|
||||
"login": "example",
|
||||
"email": "example@example.com",
|
||||
"role": "Viewer"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package search
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
iamv0 "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resource"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
)
|
||||
|
||||
const (
|
||||
USER_EMAIL = "email"
|
||||
USER_LOGIN = "login"
|
||||
)
|
||||
|
||||
func GetUserBuilder() (resource.DocumentBuilderInfo, error) {
|
||||
fields, err := resource.NewSearchableDocumentFields([]*resourcepb.ResourceTableColumnDefinition{
|
||||
{
|
||||
Name: USER_EMAIL,
|
||||
Type: resourcepb.ResourceTableColumnDefinition_STRING,
|
||||
Description: "The email address of the user",
|
||||
Properties: &resourcepb.ResourceTableColumnDefinition_Properties{
|
||||
Filterable: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: USER_LOGIN,
|
||||
Type: resourcepb.ResourceTableColumnDefinition_STRING,
|
||||
Description: "The login of the user",
|
||||
Properties: &resourcepb.ResourceTableColumnDefinition_Properties{
|
||||
UniqueValues: true,
|
||||
Filterable: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
return resource.DocumentBuilderInfo{
|
||||
GroupResource: iamv0.UserResourceInfo.GroupResource(),
|
||||
Fields: fields,
|
||||
Builder: new(userDocumentBuilder),
|
||||
}, err
|
||||
}
|
||||
|
||||
var _ resource.DocumentBuilder = new(userDocumentBuilder)
|
||||
|
||||
type userDocumentBuilder struct{}
|
||||
|
||||
// BuildDocument implements resource.DocumentBuilder.
|
||||
func (u *userDocumentBuilder) BuildDocument(ctx context.Context, key *resourcepb.ResourceKey, rv int64, value []byte) (*resource.IndexableDocument, error) {
|
||||
tmp := &unstructured.Unstructured{}
|
||||
err := tmp.UnmarshalJSON(value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
obj, err := utils.MetaAccessor(tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
doc := resource.NewIndexableDocument(key, rv, obj)
|
||||
|
||||
if spec, err := obj.GetSpec(); err == nil {
|
||||
if m, ok := spec.(map[string]any); ok {
|
||||
email, _ := m[USER_EMAIL].(string)
|
||||
login, _ := m[USER_LOGIN].(string)
|
||||
if email != "" || login != "" {
|
||||
doc.Fields = make(map[string]any)
|
||||
if email != "" {
|
||||
doc.Fields[USER_EMAIL] = email
|
||||
}
|
||||
if login != "" {
|
||||
doc.Fields[USER_LOGIN] = login
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return doc, nil
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package search_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
iamv0 "github.com/grafana/grafana/apps/iam/pkg/apis/iam/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/resourcepb"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/search"
|
||||
)
|
||||
|
||||
func TestUserDocumentBuilder(t *testing.T) {
|
||||
info, err := search.GetUserBuilder()
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, info.Builder)
|
||||
|
||||
builder := info.Builder
|
||||
|
||||
base := filepath.Join("testdata", "doc")
|
||||
inPath := filepath.Join(base, "user-example.json")
|
||||
outPath := filepath.Join(base, "user-example-out.json")
|
||||
|
||||
// nolint:gosec
|
||||
raw, err := os.ReadFile(inPath)
|
||||
if err != nil {
|
||||
t.Fatalf("missing input fixture %s: %v", inPath, err)
|
||||
}
|
||||
|
||||
gr := iamv0.UserResourceInfo.GroupResource()
|
||||
key := &resourcepb.ResourceKey{
|
||||
Namespace: "default",
|
||||
Group: gr.Group,
|
||||
Resource: gr.Resource,
|
||||
Name: "example", // set by input file metadata.name
|
||||
}
|
||||
|
||||
doc, err := builder.BuildDocument(context.Background(), key, 1234, raw)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, doc)
|
||||
|
||||
// Core
|
||||
require.Equal(t, key.Name, doc.Name)
|
||||
require.Equal(t, int64(1234), doc.RV)
|
||||
require.Equal(t, key, doc.Key)
|
||||
require.Equal(t, key.Name, doc.Title)
|
||||
|
||||
// Custom field assertions (email/login added to Fields)
|
||||
if assert.NotNil(t, doc.Fields) {
|
||||
assert.Equal(t, "example@example.com", doc.Fields[search.USER_EMAIL])
|
||||
assert.Equal(t, "example", doc.Fields[search.USER_LOGIN])
|
||||
}
|
||||
|
||||
// Snapshot compare
|
||||
out, err := json.MarshalIndent(doc, "", " ")
|
||||
require.NoError(t, err)
|
||||
|
||||
// nolint:gosec
|
||||
expected, readErr := os.ReadFile(outPath)
|
||||
if readErr != nil {
|
||||
err2 := os.MkdirAll(filepath.Dir(outPath), 0o755)
|
||||
require.NoError(t, err2)
|
||||
err2 = os.WriteFile(outPath, out, 0o600)
|
||||
require.NoError(t, err2)
|
||||
t.Fatalf("snapshot created at %s; re-run tests", outPath)
|
||||
}
|
||||
assert.JSONEq(t, string(expected), string(out))
|
||||
}
|
||||
Reference in New Issue
Block a user