From 85925d076577fe5cf34c20b3cac2fb165f48d9af Mon Sep 17 00:00:00 2001 From: Dafydd Date: Fri, 5 Dec 2025 11:24:59 +0000 Subject: [PATCH] simplify the new datasource client interface to not require group --- .../apis/collections/datasources_validator.go | 6 +-- .../collections/datasources_validator_test.go | 2 +- pkg/registry/apis/datasource/register.go | 2 +- pkg/registry/apis/query/connections.go | 4 +- .../datasources/service/client/client.go | 49 ++++++++++++++++++- .../datasources/service/client/client_mock.go | 42 ++++++++-------- 6 files changed, 75 insertions(+), 30 deletions(-) diff --git a/pkg/registry/apis/collections/datasources_validator.go b/pkg/registry/apis/collections/datasources_validator.go index 79226656caf..2962c278e6b 100644 --- a/pkg/registry/apis/collections/datasources_validator.go +++ b/pkg/registry/apis/collections/datasources_validator.go @@ -63,7 +63,7 @@ func (v *DatasourceStacksValidator) Validate(ctx context.Context, a admission.At return fmt.Errorf("key '%s' is not in the DataSourceStack template (%s %s)", key, a.GetName(), a.GetKind().GroupVersion().String()) } - exists, err := v.checkDatasourceExists(ctx, template[key].Group, item.DataSourceRef) + exists, err := v.checkDatasourceExists(ctx, item.DataSourceRef) if err != nil || !exists { return fmt.Errorf("datasource '%s' in group '%s' does not exist (%s %s): %w", item.DataSourceRef, template[key].Group, a.GetName(), a.GetKind().GroupVersion().String(), err) } @@ -73,8 +73,8 @@ func (v *DatasourceStacksValidator) Validate(ctx context.Context, a admission.At return nil } -func (v *DatasourceStacksValidator) checkDatasourceExists(ctx context.Context, group, name string) (bool, error) { - dsConn, err := v.dsClient.Get(ctx, group, "", name) +func (v *DatasourceStacksValidator) checkDatasourceExists(ctx context.Context, name string) (bool, error) { + dsConn, err := v.dsClient.GetByUID(ctx, name) if err != nil { return false, err } diff --git a/pkg/registry/apis/collections/datasources_validator_test.go b/pkg/registry/apis/collections/datasources_validator_test.go index 2f154e9a330..502539a67dc 100644 --- a/pkg/registry/apis/collections/datasources_validator_test.go +++ b/pkg/registry/apis/collections/datasources_validator_test.go @@ -169,7 +169,7 @@ func TestDataSourceValidator_Validate(t *testing.T) { var client *datasourcesclient.MockDataSourceConnectionClient if tt.needMockDSClient { client = datasourcesclient.NewMockDataSourceConnectionClient(t) - client.On("Get", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tt.dsClientReturnValue, tt.dsClientReturnError) + client.On("GetByUID", mock.Anything, mock.Anything).Return(tt.dsClientReturnValue, tt.dsClientReturnError) } validator := collections.GetDatasourceStacksValidator(client) diff --git a/pkg/registry/apis/datasource/register.go b/pkg/registry/apis/datasource/register.go index bec8fdaec5b..9846283e437 100644 --- a/pkg/registry/apis/datasource/register.go +++ b/pkg/registry/apis/datasource/register.go @@ -85,7 +85,7 @@ func RegisterAPIService( accessControl, //nolint:staticcheck // not yet migrated to OpenFeature features.IsEnabledGlobally(featuremgmt.FlagDatasourceQueryTypes), - false, + true, ) if err != nil { return nil, err diff --git a/pkg/registry/apis/query/connections.go b/pkg/registry/apis/query/connections.go index a4a7e385dfc..279f55b7240 100644 --- a/pkg/registry/apis/query/connections.go +++ b/pkg/registry/apis/query/connections.go @@ -28,7 +28,7 @@ var ( // Get all datasource connections -- this will be backed by search or duplicated resource in unified storage type DataSourceConnectionProvider interface { // Get gets a specific datasource (that the user in context can see) - // The name is {group}:{name}, see /pkg/apis/query/v0alpha1/connection.go#L34 + // The name is the legacy datasource UID. GetConnection(ctx context.Context, namespace string, name string) (*queryV0.DataSourceConnection, error) // List lists all data sources the user in context can see @@ -137,7 +137,7 @@ func (q *connectionsProvider) asConnection(ds *datasources.DataSource, ns string v = &queryV0.DataSourceConnection{ ObjectMeta: metav1.ObjectMeta{ - Name: queryV0.DataSourceConnectionName(gv.Group, ds.UID), + Name: ds.UID, Namespace: ns, CreationTimestamp: metav1.NewTime(ds.Created), ResourceVersion: fmt.Sprintf("%d", ds.Updated.UnixMilli()), diff --git a/pkg/services/datasources/service/client/client.go b/pkg/services/datasources/service/client/client.go index 5a8a80374cb..d6059367666 100644 --- a/pkg/services/datasources/service/client/client.go +++ b/pkg/services/datasources/service/client/client.go @@ -15,7 +15,7 @@ import ( // //go:generate mockery --name DataSourceConnectionClient --structname MockDataSourceConnectionClient --inpackage --filename=client_mock.go --with-expecter type DataSourceConnectionClient interface { - Get(ctx context.Context, group, version, name string) (*queryv0alpha1.DataSourceConnection, error) + GetByUID(ctx context.Context, uid string) (*queryv0alpha1.DataSourceConnection, error) } func ProvideDataSourceConnectionClientFactory( @@ -84,3 +84,50 @@ func (dc *dataSourceConnectionClient) Get(ctx context.Context, group, version, n return dsConnection, nil } + +func (dc *dataSourceConnectionClient) GetByUID(ctx context.Context, uid string) (*queryv0alpha1.DataSourceConnection, error) { + cfg, err := dc.configProvider.GetRestConfig(ctx) + if err != nil { + return nil, err + } + + client, err := kubernetes.NewForConfig(cfg) + if err != nil { + return nil, err + } + + result := client.RESTClient().Get(). + Prefix("apis", "query.grafana.app", "v0alpha1"). + Namespace("default"). // TODO do something about namespace + Resource("connections"). + Name(uid). + Do(ctx) + + if err = result.Error(); err != nil { + return nil, err + } + + var statusCode int + + result = result.StatusCode(&statusCode) + if statusCode == http.StatusNotFound { + return nil, errors.New("not found") + } + + fullDS := datasourcev0alpha1.DataSource{} + err = result.Into(&fullDS) + if err != nil { + return nil, err + } + + dsConnection := &queryv0alpha1.DataSourceConnection{ + Title: fullDS.Spec.Title(), + Datasource: queryv0alpha1.DataSourceConnectionRef{ + Group: fullDS.GroupVersionKind().Group, + Name: fullDS.ObjectMeta.Name, + Version: fullDS.GroupVersionKind().Version, + }, + } + + return dsConnection, nil +} diff --git a/pkg/services/datasources/service/client/client_mock.go b/pkg/services/datasources/service/client/client_mock.go index 03728d36e15..406ef603e32 100644 --- a/pkg/services/datasources/service/client/client_mock.go +++ b/pkg/services/datasources/service/client/client_mock.go @@ -22,29 +22,29 @@ func (_m *MockDataSourceConnectionClient) EXPECT() *MockDataSourceConnectionClie return &MockDataSourceConnectionClient_Expecter{mock: &_m.Mock} } -// Get provides a mock function with given fields: ctx, group, version, name -func (_m *MockDataSourceConnectionClient) Get(ctx context.Context, group string, version string, name string) (*v0alpha1.DataSourceConnection, error) { - ret := _m.Called(ctx, group, version, name) +// GetByUID provides a mock function with given fields: ctx, uid +func (_m *MockDataSourceConnectionClient) GetByUID(ctx context.Context, uid string) (*v0alpha1.DataSourceConnection, error) { + ret := _m.Called(ctx, uid) if len(ret) == 0 { - panic("no return value specified for Get") + panic("no return value specified for GetByUID") } var r0 *v0alpha1.DataSourceConnection var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, string, string) (*v0alpha1.DataSourceConnection, error)); ok { - return rf(ctx, group, version, name) + if rf, ok := ret.Get(0).(func(context.Context, string) (*v0alpha1.DataSourceConnection, error)); ok { + return rf(ctx, uid) } - if rf, ok := ret.Get(0).(func(context.Context, string, string, string) *v0alpha1.DataSourceConnection); ok { - r0 = rf(ctx, group, version, name) + if rf, ok := ret.Get(0).(func(context.Context, string) *v0alpha1.DataSourceConnection); ok { + r0 = rf(ctx, uid) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*v0alpha1.DataSourceConnection) } } - if rf, ok := ret.Get(1).(func(context.Context, string, string, string) error); ok { - r1 = rf(ctx, group, version, name) + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, uid) } else { r1 = ret.Error(1) } @@ -52,33 +52,31 @@ func (_m *MockDataSourceConnectionClient) Get(ctx context.Context, group string, return r0, r1 } -// MockDataSourceConnectionClient_Get_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Get' -type MockDataSourceConnectionClient_Get_Call struct { +// MockDataSourceConnectionClient_GetByUID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetByUID' +type MockDataSourceConnectionClient_GetByUID_Call struct { *mock.Call } -// Get is a helper method to define mock.On call +// GetByUID is a helper method to define mock.On call // - ctx context.Context -// - group string -// - version string -// - name string -func (_e *MockDataSourceConnectionClient_Expecter) Get(ctx interface{}, group interface{}, version interface{}, name interface{}) *MockDataSourceConnectionClient_Get_Call { - return &MockDataSourceConnectionClient_Get_Call{Call: _e.mock.On("Get", ctx, group, version, name)} +// - uid string +func (_e *MockDataSourceConnectionClient_Expecter) GetByUID(ctx interface{}, uid interface{}) *MockDataSourceConnectionClient_GetByUID_Call { + return &MockDataSourceConnectionClient_GetByUID_Call{Call: _e.mock.On("GetByUID", ctx, uid)} } -func (_c *MockDataSourceConnectionClient_Get_Call) Run(run func(ctx context.Context, group string, version string, name string)) *MockDataSourceConnectionClient_Get_Call { +func (_c *MockDataSourceConnectionClient_GetByUID_Call) Run(run func(ctx context.Context, uid string)) *MockDataSourceConnectionClient_GetByUID_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(string), args[2].(string), args[3].(string)) + run(args[0].(context.Context), args[1].(string)) }) return _c } -func (_c *MockDataSourceConnectionClient_Get_Call) Return(_a0 *v0alpha1.DataSourceConnection, _a1 error) *MockDataSourceConnectionClient_Get_Call { +func (_c *MockDataSourceConnectionClient_GetByUID_Call) Return(_a0 *v0alpha1.DataSourceConnection, _a1 error) *MockDataSourceConnectionClient_GetByUID_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *MockDataSourceConnectionClient_Get_Call) RunAndReturn(run func(context.Context, string, string, string) (*v0alpha1.DataSourceConnection, error)) *MockDataSourceConnectionClient_Get_Call { +func (_c *MockDataSourceConnectionClient_GetByUID_Call) RunAndReturn(run func(context.Context, string) (*v0alpha1.DataSourceConnection, error)) *MockDataSourceConnectionClient_GetByUID_Call { _c.Call.Return(run) return _c }