|
|
|
@ -16,7 +16,7 @@ import ( |
|
|
|
|
"k8s.io/apiserver/pkg/storage" |
|
|
|
|
|
|
|
|
|
authtypes "github.com/grafana/authlib/types" |
|
|
|
|
"github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1alpha1" |
|
|
|
|
dashv1 "github.com/grafana/grafana/apps/dashboard/pkg/apis/dashboard/v1alpha1" |
|
|
|
|
"github.com/grafana/grafana/pkg/apimachinery/identity" |
|
|
|
|
"github.com/grafana/grafana/pkg/apimachinery/utils" |
|
|
|
|
) |
|
|
|
@ -25,11 +25,11 @@ var scheme = runtime.NewScheme() |
|
|
|
|
var codecs = serializer.NewCodecFactory(scheme) |
|
|
|
|
|
|
|
|
|
func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
_ = v1alpha1.AddToScheme(scheme) |
|
|
|
|
_ = dashv1.AddToScheme(scheme) |
|
|
|
|
node, err := snowflake.NewNode(rand.Int63n(1024)) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
s := &Storage{ |
|
|
|
|
codec: apitesting.TestCodec(codecs, v1alpha1.DashboardResourceInfo.GroupVersion()), |
|
|
|
|
codec: apitesting.TestCodec(codecs, dashv1.DashboardResourceInfo.GroupVersion()), |
|
|
|
|
snowflake: node, |
|
|
|
|
opts: StorageOptions{ |
|
|
|
|
EnableFolderSupport: true, |
|
|
|
@ -48,14 +48,14 @@ func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
t.Run("Error on missing name", func(t *testing.T) { |
|
|
|
|
dashboard := v1alpha1.Dashboard{} |
|
|
|
|
dashboard := dashv1.Dashboard{} |
|
|
|
|
_, _, err := s.prepareObjectForStorage(ctx, dashboard.DeepCopyObject()) |
|
|
|
|
require.Error(t, err) |
|
|
|
|
require.Contains(t, err.Error(), "missing name") |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
t.Run("Error on non-empty resource version", func(t *testing.T) { |
|
|
|
|
dashboard := v1alpha1.Dashboard{} |
|
|
|
|
dashboard := dashv1.Dashboard{} |
|
|
|
|
dashboard.Name = "test-name" |
|
|
|
|
dashboard.ResourceVersion = "123" |
|
|
|
|
_, _, err := s.prepareObjectForStorage(ctx, dashboard.DeepCopyObject()) |
|
|
|
@ -64,13 +64,13 @@ func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
t.Run("Generate UID and leave deprecated ID empty, if not required", func(t *testing.T) { |
|
|
|
|
dashboard := v1alpha1.Dashboard{} |
|
|
|
|
dashboard := dashv1.Dashboard{} |
|
|
|
|
dashboard.Name = "test-name" |
|
|
|
|
|
|
|
|
|
encodedData, _, err := s.prepareObjectForStorage(ctx, dashboard.DeepCopyObject()) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
newObject, _, err := s.codec.Decode(encodedData, nil, &v1alpha1.Dashboard{}) |
|
|
|
|
newObject, _, err := s.codec.Decode(encodedData, nil, &dashv1.Dashboard{}) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
obj, err := utils.MetaAccessor(newObject) |
|
|
|
|
require.NoError(t, err) |
|
|
|
@ -90,7 +90,7 @@ func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
ctx, _, err := identity.WithProvisioningIdentity(ctx, "default") |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
dashboard := v1alpha1.Dashboard{} |
|
|
|
|
dashboard := dashv1.Dashboard{} |
|
|
|
|
dashboard.Name = "test-name" |
|
|
|
|
obj := dashboard.DeepCopyObject() |
|
|
|
|
meta, err := utils.MetaAccessor(obj) |
|
|
|
@ -109,7 +109,7 @@ func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
encodedData, _, err := s.prepareObjectForStorage(ctx, obj) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
newObject, _, err := s.codec.Decode(encodedData, nil, &v1alpha1.Dashboard{}) |
|
|
|
|
newObject, _, err := s.codec.Decode(encodedData, nil, &dashv1.Dashboard{}) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
meta, err = utils.MetaAccessor(newObject) |
|
|
|
|
require.NoError(t, err) |
|
|
|
@ -126,7 +126,7 @@ func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
t.Run("Update should manage incrementing generation and metadata", func(t *testing.T) { |
|
|
|
|
dashboard := v1alpha1.Dashboard{} |
|
|
|
|
dashboard := dashv1.Dashboard{} |
|
|
|
|
dashboard.Name = "test-name" |
|
|
|
|
obj := dashboard.DeepCopyObject() |
|
|
|
|
meta, err := utils.MetaAccessor(obj) |
|
|
|
@ -136,7 +136,7 @@ func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
encodedData, _, err := s.prepareObjectForStorage(ctx, obj) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
insertedObject, _, err := s.codec.Decode(encodedData, nil, &v1alpha1.Dashboard{}) |
|
|
|
|
insertedObject, _, err := s.codec.Decode(encodedData, nil, &dashv1.Dashboard{}) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
meta, err = utils.MetaAccessor(insertedObject) |
|
|
|
|
require.NoError(t, err) |
|
|
|
@ -156,8 +156,8 @@ func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
updatedObject := insertedObject.DeepCopyObject() |
|
|
|
|
meta, err = utils.MetaAccessor(updatedObject) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
err = meta.SetStatus(v1alpha1.DashboardStatus{ |
|
|
|
|
Conversion: &v1alpha1.DashboardConversionStatus{ |
|
|
|
|
err = meta.SetStatus(dashv1.DashboardStatus{ |
|
|
|
|
Conversion: &dashv1.DashboardConversionStatus{ |
|
|
|
|
Failed: true, |
|
|
|
|
Error: "test", |
|
|
|
|
}, |
|
|
|
@ -172,7 +172,7 @@ func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
require.Equal(t, int64(1), meta.GetGeneration()) |
|
|
|
|
|
|
|
|
|
// Change the folder -- the generation should increase and the updatedBy metadata
|
|
|
|
|
dashboard2 := &v1alpha1.Dashboard{ObjectMeta: v1.ObjectMeta{ |
|
|
|
|
dashboard2 := &dashv1.Dashboard{ObjectMeta: v1.ObjectMeta{ |
|
|
|
|
Name: dashboard.Name, |
|
|
|
|
}} // TODO... deep copy, See: https://github.com/grafana/grafana/pull/102258
|
|
|
|
|
meta2, err := utils.MetaAccessor(dashboard2) |
|
|
|
@ -186,12 +186,12 @@ func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
|
|
|
|
|
s.opts.RequireDeprecatedInternalID = true |
|
|
|
|
t.Run("Should generate internal id", func(t *testing.T) { |
|
|
|
|
dashboard := v1alpha1.Dashboard{} |
|
|
|
|
dashboard := dashv1.Dashboard{} |
|
|
|
|
dashboard.Name = "test-name" |
|
|
|
|
|
|
|
|
|
encodedData, _, err := s.prepareObjectForStorage(ctx, dashboard.DeepCopyObject()) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
newObject, _, err := s.codec.Decode(encodedData, nil, &v1alpha1.Dashboard{}) |
|
|
|
|
newObject, _, err := s.codec.Decode(encodedData, nil, &dashv1.Dashboard{}) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
obj, err := utils.MetaAccessor(newObject) |
|
|
|
|
require.NoError(t, err) |
|
|
|
@ -201,7 +201,7 @@ func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
t.Run("Should use deprecated ID if given it", func(t *testing.T) { |
|
|
|
|
dashboard := v1alpha1.Dashboard{} |
|
|
|
|
dashboard := dashv1.Dashboard{} |
|
|
|
|
dashboard.Name = "test-name" |
|
|
|
|
obj := dashboard.DeepCopyObject() |
|
|
|
|
meta, err := utils.MetaAccessor(obj) |
|
|
|
@ -210,7 +210,7 @@ func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
|
|
|
|
|
encodedData, _, err := s.prepareObjectForStorage(ctx, obj) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
newObject, _, err := s.codec.Decode(encodedData, nil, &v1alpha1.Dashboard{}) |
|
|
|
|
newObject, _, err := s.codec.Decode(encodedData, nil, &dashv1.Dashboard{}) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
meta, err = utils.MetaAccessor(newObject) |
|
|
|
|
require.NoError(t, err) |
|
|
|
@ -218,7 +218,7 @@ func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
t.Run("Should remove grant permissions annotation", func(t *testing.T) { |
|
|
|
|
dashboard := v1alpha1.Dashboard{} |
|
|
|
|
dashboard := dashv1.Dashboard{} |
|
|
|
|
dashboard.Name = "test-name" |
|
|
|
|
obj := dashboard.DeepCopyObject() |
|
|
|
|
meta, err := utils.MetaAccessor(obj) |
|
|
|
@ -227,7 +227,7 @@ func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
|
|
|
|
|
encodedData, p, err := s.prepareObjectForStorage(ctx, obj) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
newObject, _, err := s.codec.Decode(encodedData, nil, &v1alpha1.Dashboard{}) |
|
|
|
|
newObject, _, err := s.codec.Decode(encodedData, nil, &dashv1.Dashboard{}) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
meta, err = utils.MetaAccessor(newObject) |
|
|
|
|
require.NoError(t, err) |
|
|
|
@ -236,11 +236,11 @@ func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
t.Run("calculate generation", func(t *testing.T) { |
|
|
|
|
dash := &v1alpha1.Dashboard{ |
|
|
|
|
dash := &dashv1.Dashboard{ |
|
|
|
|
ObjectMeta: v1.ObjectMeta{ |
|
|
|
|
Name: "test", |
|
|
|
|
}, |
|
|
|
|
Spec: v1alpha1.DashboardSpec{ |
|
|
|
|
Spec: dashv1.DashboardSpec{ |
|
|
|
|
Object: map[string]interface{}{ |
|
|
|
|
"hello": "world", |
|
|
|
|
}, |
|
|
|
@ -286,8 +286,8 @@ func TestPrepareObjectForStorage(t *testing.T) { |
|
|
|
|
b.Labels = map[string]string{ |
|
|
|
|
"a": "b", |
|
|
|
|
} |
|
|
|
|
b.Status = v1alpha1.DashboardStatus{ |
|
|
|
|
Conversion: &v1alpha1.DashboardConversionStatus{ |
|
|
|
|
b.Status = dashv1.DashboardStatus{ |
|
|
|
|
Conversion: &dashv1.DashboardConversionStatus{ |
|
|
|
|
Failed: true, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
@ -320,13 +320,13 @@ func getPreparedObject(t *testing.T, ctx context.Context, s *Storage, obj runtim |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func TestPrepareLargeObjectForStorage(t *testing.T) { |
|
|
|
|
_ = v1alpha1.AddToScheme(scheme) |
|
|
|
|
_ = dashv1.AddToScheme(scheme) |
|
|
|
|
node, err := snowflake.NewNode(rand.Int63n(1024)) |
|
|
|
|
require.NoError(t, err) |
|
|
|
|
|
|
|
|
|
ctx := authtypes.WithAuthInfo(context.Background(), &identity.StaticRequester{UserID: 1, UserUID: "user-uid", Type: authtypes.TypeUser}) |
|
|
|
|
|
|
|
|
|
dashboard := v1alpha1.Dashboard{} |
|
|
|
|
dashboard := dashv1.Dashboard{} |
|
|
|
|
dashboard.Name = "test-name" |
|
|
|
|
t.Run("Should deconstruct object if size is over threshold", func(t *testing.T) { |
|
|
|
|
los := LargeObjectSupportFake{ |
|
|
|
@ -334,7 +334,7 @@ func TestPrepareLargeObjectForStorage(t *testing.T) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
f := &Storage{ |
|
|
|
|
codec: apitesting.TestCodec(codecs, v1alpha1.DashboardResourceInfo.GroupVersion()), |
|
|
|
|
codec: apitesting.TestCodec(codecs, dashv1.DashboardResourceInfo.GroupVersion()), |
|
|
|
|
snowflake: node, |
|
|
|
|
opts: StorageOptions{ |
|
|
|
|
LargeObjectSupport: &los, |
|
|
|
@ -352,7 +352,7 @@ func TestPrepareLargeObjectForStorage(t *testing.T) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
f := &Storage{ |
|
|
|
|
codec: apitesting.TestCodec(codecs, v1alpha1.DashboardResourceInfo.GroupVersion()), |
|
|
|
|
codec: apitesting.TestCodec(codecs, dashv1.DashboardResourceInfo.GroupVersion()), |
|
|
|
|
snowflake: node, |
|
|
|
|
opts: StorageOptions{ |
|
|
|
|
LargeObjectSupport: &los, |
|
|
|
|