feat(unified-storage): return guid, group and resource on read/list (#104121)

This commit is contained in:
Jean-Philippe Quéméner 2025-04-17 12:58:58 +02:00 committed by GitHub
parent a02ff218df
commit 3380ea441a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
34 changed files with 106 additions and 21 deletions

View File

@ -1,7 +1,7 @@
package resource package resource
import ( import (
context "context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"log/slog" "log/slog"
@ -71,6 +71,8 @@ type BackendReadResponse struct {
Key *ResourceKey Key *ResourceKey
Folder string Folder string
// GUID that is used internally
GUID string
// The new resource version // The new resource version
ResourceVersion int64 ResourceVersion int64
// The properties // The properties

View File

@ -21,6 +21,7 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
"github.com/grafana/grafana-app-sdk/logging" "github.com/grafana/grafana-app-sdk/logging"
"github.com/grafana/grafana/pkg/storage/unified/resource" "github.com/grafana/grafana/pkg/storage/unified/resource"
"github.com/grafana/grafana/pkg/storage/unified/sql/db" "github.com/grafana/grafana/pkg/storage/unified/sql/db"
"github.com/grafana/grafana/pkg/storage/unified/sql/dbutil" "github.com/grafana/grafana/pkg/storage/unified/sql/dbutil"
@ -593,9 +594,12 @@ type listIter struct {
err error err error
// The row // The row
guid string
rv int64 rv int64
value []byte value []byte
namespace string namespace string
resource string
group string
name string name string
folder string folder string
} }
@ -639,7 +643,7 @@ func (l *listIter) Value() []byte {
func (l *listIter) Next() bool { func (l *listIter) Next() bool {
if l.rows.Next() { if l.rows.Next() {
l.offset++ l.offset++
l.err = l.rows.Scan(&l.rv, &l.namespace, &l.name, &l.folder, &l.value) l.err = l.rows.Scan(&l.guid, &l.rv, &l.namespace, &l.resource, &l.group, &l.name, &l.folder, &l.value)
return true return true
} }
return false return false

View File

@ -7,16 +7,17 @@ import (
"fmt" "fmt"
"testing" "testing"
sqlmock "github.com/DATA-DOG/go-sqlmock" "github.com/DATA-DOG/go-sqlmock"
"github.com/mattn/go-sqlite3" "github.com/mattn/go-sqlite3"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"github.com/grafana/grafana/pkg/apimachinery/utils" "github.com/grafana/grafana/pkg/apimachinery/utils"
"github.com/grafana/grafana/pkg/storage/unified/resource" "github.com/grafana/grafana/pkg/storage/unified/resource"
"github.com/grafana/grafana/pkg/storage/unified/sql/db/dbimpl" "github.com/grafana/grafana/pkg/storage/unified/sql/db/dbimpl"
"github.com/grafana/grafana/pkg/storage/unified/sql/test" "github.com/grafana/grafana/pkg/storage/unified/sql/test"
"github.com/grafana/grafana/pkg/util/testutil" "github.com/grafana/grafana/pkg/util/testutil"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
) )
var ( var (
@ -401,6 +402,7 @@ func TestBackend_delete(t *testing.T) {
} }
type readHistoryRow struct { type readHistoryRow struct {
guid string
namespace string namespace string
group string group string
resource string resource string
@ -418,6 +420,7 @@ func TestBackend_ReadResource(t *testing.T) {
b, ctx := setupBackendTest(t) b, ctx := setupBackendTest(t)
expectedReadRow := readHistoryRow{ expectedReadRow := readHistoryRow{
guid: "guid",
namespace: "ns", namespace: "ns",
group: "gr", group: "gr",
resource: "rs", resource: "rs",
@ -426,11 +429,12 @@ func TestBackend_ReadResource(t *testing.T) {
resource_version: "300", resource_version: "300",
value: "rv-300", value: "rv-300",
} }
readResource := []string{"namespace", "group", "resource", "name", "folder", "resource_version", "value"} readResource := []string{"guid", "namespace", "group", "resource", "name", "folder", "resource_version", "value"}
b.SQLMock.ExpectBegin() b.SQLMock.ExpectBegin()
b.SQLMock.ExpectQuery("SELECT .* FROM resource"). b.SQLMock.ExpectQuery("SELECT .* FROM resource").
WillReturnRows(sqlmock.NewRows(readResource). WillReturnRows(sqlmock.NewRows(readResource).
AddRow( AddRow(
expectedReadRow.guid,
expectedReadRow.namespace, expectedReadRow.namespace,
expectedReadRow.group, expectedReadRow.group,
expectedReadRow.resource, expectedReadRow.resource,
@ -473,6 +477,7 @@ func TestBackend_ReadResource(t *testing.T) {
b, ctx := setupBackendTest(t) b, ctx := setupBackendTest(t)
expectedReadRow := readHistoryRow{ expectedReadRow := readHistoryRow{
guid: "guid",
namespace: "ns", namespace: "ns",
group: "gr", group: "gr",
resource: "rs", resource: "rs",
@ -482,11 +487,12 @@ func TestBackend_ReadResource(t *testing.T) {
value: "rv-300", value: "rv-300",
} }
readHistoryColumns := []string{"namespace", "group", "resource", "name", "folder", "resource_version", "value"} readHistoryColumns := []string{"guid", "namespace", "group", "resource", "name", "folder", "resource_version", "value"}
b.SQLMock.ExpectBegin() b.SQLMock.ExpectBegin()
b.SQLMock.ExpectQuery("SELECT .* FROM resource_history"). b.SQLMock.ExpectQuery("SELECT .* FROM resource_history").
WillReturnRows(sqlmock.NewRows(readHistoryColumns). WillReturnRows(sqlmock.NewRows(readHistoryColumns).
AddRow( AddRow(
expectedReadRow.guid,
expectedReadRow.namespace, expectedReadRow.namespace,
expectedReadRow.group, expectedReadRow.group,
expectedReadRow.resource, expectedReadRow.resource,
@ -534,7 +540,7 @@ func TestBackend_getHistory(t *testing.T) {
Name: "nm", Name: "nm",
} }
rv1, rv2, rv3 := int64(100), int64(200), int64(300) rv1, rv2, rv3 := int64(100), int64(200), int64(300)
cols := []string{"resource_version", "namespace", "name", "folder", "value"} cols := []string{"guid", "resource_version", "namespace", "group", "resource", "name", "folder", "value"}
tests := []struct { tests := []struct {
name string name string
@ -657,8 +663,11 @@ func TestBackend_getHistory(t *testing.T) {
historyRows := sqlmock.NewRows(cols) historyRows := sqlmock.NewRows(cols)
for _, rv := range tc.expectedVersions { for _, rv := range tc.expectedVersions {
historyRows.AddRow( historyRows.AddRow(
"guid", // guid
rv, // resource_version rv, // resource_version
"ns", // namespace "ns", // namespace
"gr", // group
"rs", // resource
"nm", // name "nm", // name
"folder", // folder "folder", // folder
[]byte(fmt.Sprintf("rv-%d", rv)), // value []byte(fmt.Sprintf("rv-%d", rv)), // value
@ -829,12 +838,15 @@ func setupHistoryTest(b testBackend, resourceVersions []int64, latestRV int64, e
} }
// Create the mock rows for the history items // Create the mock rows for the history items
cols := []string{"resource_version", "namespace", "name", "folder", "value"} cols := []string{"guid", "resource_version", "namespace", "group", "resource", "name", "folder", "value"}
historyRows := sqlmock.NewRows(cols) historyRows := sqlmock.NewRows(cols)
for _, rv := range resourceVersions { for _, rv := range resourceVersions {
historyRows.AddRow( historyRows.AddRow(
"guid", // guid
rv, // resource_version rv, // resource_version
"ns", // namespace "ns", // namespace
"gr", // group
"rs", // resource
"nm", // name "nm", // name
"folder", // folder "folder", // folder
[]byte(fmt.Sprintf("rv-%d", rv)), // value []byte(fmt.Sprintf("rv-%d", rv)), // value

View File

@ -1,6 +1,9 @@
SELECT SELECT
{{ .Ident "guid" }},
{{ .Ident "resource_version" }}, {{ .Ident "resource_version" }},
{{ .Ident "namespace" }}, {{ .Ident "namespace" }},
{{ .Ident "group" }},
{{ .Ident "resource" }},
{{ .Ident "name" }}, {{ .Ident "name" }},
{{ .Ident "folder" }}, {{ .Ident "folder" }},
{{ .Ident "value" }} {{ .Ident "value" }}

View File

@ -1,6 +1,9 @@
SELECT SELECT
kv.{{ .Ident "guid" }},
kv.{{ .Ident "resource_version" }}, kv.{{ .Ident "resource_version" }},
kv.{{ .Ident "namespace" }}, kv.{{ .Ident "namespace" }},
kv.{{ .Ident "group" }},
kv.{{ .Ident "resource" }},
kv.{{ .Ident "name" }}, kv.{{ .Ident "name" }},
kv.{{ .Ident "folder" }}, kv.{{ .Ident "folder" }},
kv.{{ .Ident "value" }} kv.{{ .Ident "value" }}

View File

@ -1,4 +1,5 @@
SELECT SELECT
{{ .Ident "guid" | .Into .Response.GUID }},
{{ .Ident "resource_version" | .Into .Response.ResourceVersion }}, {{ .Ident "resource_version" | .Into .Response.ResourceVersion }},
{{ .Ident "namespace" | .Into .Response.Key.Namespace }}, {{ .Ident "namespace" | .Into .Response.Key.Namespace }},
{{ .Ident "group" | .Into .Response.Key.Group }}, {{ .Ident "group" | .Into .Response.Key.Group }},

View File

@ -1,4 +1,5 @@
SELECT SELECT
{{ .Ident "guid" | .Into .Response.GUID }},
{{ .Ident "namespace" | .Into .Response.Key.Namespace }}, {{ .Ident "namespace" | .Into .Response.Key.Namespace }},
{{ .Ident "group" | .Into .Response.Key.Group }}, {{ .Ident "group" | .Into .Response.Key.Group }},
{{ .Ident "resource" | .Into .Response.Key.Resource }}, {{ .Ident "resource" | .Into .Response.Key.Resource }},

View File

@ -1,6 +1,9 @@
SELECT SELECT
{{ .Ident "guid" }},
{{ .Ident "resource_version" }}, {{ .Ident "resource_version" }},
{{ .Ident "namespace" }}, {{ .Ident "namespace" }},
{{ .Ident "group" }},
{{ .Ident "resource" }},
{{ .Ident "name" }}, {{ .Ident "name" }},
{{ .Ident "folder" }}, {{ .Ident "folder" }},
{{ .Ident "value" }} {{ .Ident "value" }}

View File

@ -1,4 +1,5 @@
SELECT SELECT
{{ .Ident "guid" | .Into .Response.GUID }},
{{ .Ident "namespace" | .Into .Response.Key.Namespace }}, {{ .Ident "namespace" | .Into .Response.Key.Namespace }},
{{ .Ident "group" | .Into .Response.Key.Group }}, {{ .Ident "group" | .Into .Response.Key.Group }},
{{ .Ident "resource" | .Into .Response.Key.Resource }}, {{ .Ident "resource" | .Into .Response.Key.Resource }},

View File

@ -116,6 +116,7 @@ func (r sqlStatsRequest) Validate() error {
type historyPollResponse struct { type historyPollResponse struct {
Key resource.ResourceKey Key resource.ResourceKey
GUID string
ResourceVersion int64 ResourceVersion int64
PreviousRV *int64 PreviousRV *int64
Value []byte Value []byte

View File

@ -1,6 +1,9 @@
SELECT SELECT
`guid`,
`resource_version`, `resource_version`,
`namespace`, `namespace`,
`group`,
`resource`,
`name`, `name`,
`folder`, `folder`,
`value` `value`

View File

@ -1,6 +1,9 @@
SELECT SELECT
`guid`,
`resource_version`, `resource_version`,
`namespace`, `namespace`,
`group`,
`resource`,
`name`, `name`,
`folder`, `folder`,
`value` `value`

View File

@ -1,6 +1,9 @@
SELECT SELECT
`guid`,
`resource_version`, `resource_version`,
`namespace`, `namespace`,
`group`,
`resource`,
`name`, `name`,
`folder`, `folder`,
`value` `value`

View File

@ -1,6 +1,9 @@
SELECT SELECT
kv.`guid`,
kv.`resource_version`, kv.`resource_version`,
kv.`namespace`, kv.`namespace`,
kv.`group`,
kv.`resource`,
kv.`name`, kv.`name`,
kv.`folder`, kv.`folder`,
kv.`value` kv.`value`

View File

@ -1,4 +1,5 @@
SELECT SELECT
`guid`,
`resource_version`, `resource_version`,
`namespace`, `namespace`,
`group`, `group`,

View File

@ -1,4 +1,5 @@
SELECT SELECT
`guid`,
`namespace`, `namespace`,
`group`, `group`,
`resource`, `resource`,

View File

@ -1,6 +1,9 @@
SELECT SELECT
`guid`,
`resource_version`, `resource_version`,
`namespace`, `namespace`,
`group`,
`resource`,
`name`, `name`,
`folder`, `folder`,
`value` `value`

View File

@ -1,4 +1,5 @@
SELECT SELECT
`guid`,
`namespace`, `namespace`,
`group`, `group`,
`resource`, `resource`,

View File

@ -1,6 +1,9 @@
SELECT SELECT
"guid",
"resource_version", "resource_version",
"namespace", "namespace",
"group",
"resource",
"name", "name",
"folder", "folder",
"value" "value"

View File

@ -1,6 +1,9 @@
SELECT SELECT
"guid",
"resource_version", "resource_version",
"namespace", "namespace",
"group",
"resource",
"name", "name",
"folder", "folder",
"value" "value"

View File

@ -1,6 +1,9 @@
SELECT SELECT
"guid",
"resource_version", "resource_version",
"namespace", "namespace",
"group",
"resource",
"name", "name",
"folder", "folder",
"value" "value"

View File

@ -1,6 +1,9 @@
SELECT SELECT
kv."guid",
kv."resource_version", kv."resource_version",
kv."namespace", kv."namespace",
kv."group",
kv."resource",
kv."name", kv."name",
kv."folder", kv."folder",
kv."value" kv."value"

View File

@ -1,4 +1,5 @@
SELECT SELECT
"guid",
"resource_version", "resource_version",
"namespace", "namespace",
"group", "group",

View File

@ -1,4 +1,5 @@
SELECT SELECT
"guid",
"namespace", "namespace",
"group", "group",
"resource", "resource",

View File

@ -1,6 +1,9 @@
SELECT SELECT
"guid",
"resource_version", "resource_version",
"namespace", "namespace",
"group",
"resource",
"name", "name",
"folder", "folder",
"value" "value"

View File

@ -1,4 +1,5 @@
SELECT SELECT
"guid",
"namespace", "namespace",
"group", "group",
"resource", "resource",

View File

@ -1,6 +1,9 @@
SELECT SELECT
"guid",
"resource_version", "resource_version",
"namespace", "namespace",
"group",
"resource",
"name", "name",
"folder", "folder",
"value" "value"

View File

@ -1,6 +1,9 @@
SELECT SELECT
"guid",
"resource_version", "resource_version",
"namespace", "namespace",
"group",
"resource",
"name", "name",
"folder", "folder",
"value" "value"

View File

@ -1,6 +1,9 @@
SELECT SELECT
"guid",
"resource_version", "resource_version",
"namespace", "namespace",
"group",
"resource",
"name", "name",
"folder", "folder",
"value" "value"

View File

@ -1,6 +1,9 @@
SELECT SELECT
kv."guid",
kv."resource_version", kv."resource_version",
kv."namespace", kv."namespace",
kv."group",
kv."resource",
kv."name", kv."name",
kv."folder", kv."folder",
kv."value" kv."value"

View File

@ -1,4 +1,5 @@
SELECT SELECT
"guid",
"resource_version", "resource_version",
"namespace", "namespace",
"group", "group",

View File

@ -1,4 +1,5 @@
SELECT SELECT
"guid",
"namespace", "namespace",
"group", "group",
"resource", "resource",

View File

@ -1,6 +1,9 @@
SELECT SELECT
"guid",
"resource_version", "resource_version",
"namespace", "namespace",
"group",
"resource",
"name", "name",
"folder", "folder",
"value" "value"

View File

@ -1,4 +1,5 @@
SELECT SELECT
"guid",
"namespace", "namespace",
"group", "group",
"resource", "resource",