K8s/Annotations: Use manager/source annotations rather than repo (#101313)

Co-authored-by: Stephanie Hingtgen <stephanie.hingtgen@grafana.com>
This commit is contained in:
Ryan McKinley
2025-03-05 08:54:20 +02:00
committed by GitHub
co-authored by Stephanie Hingtgen
parent e7baf9804e
commit dc2defd84f
37 changed files with 589 additions and 573 deletions
@@ -317,13 +317,6 @@ func (a *dashboardSqlAccess) scanRow(rows *sql.Rows, history bool) (*dashboardRo
}
if origin_name.String != "" {
ts := time.Unix(origin_ts.Int64, 0)
repo := &utils.ResourceRepositoryInfo{
Name: dashboardOG.ProvisionedFileNameWithPrefix(origin_name.String),
Hash: origin_hash.String,
Timestamp: &ts,
}
// if the reader cannot be found, it may be an orphaned provisioned dashboard
resolvedPath := a.provisioning.GetDashboardProvisionerResolvedPath(origin_name.String)
if resolvedPath != "" {
@@ -334,13 +327,20 @@ func (a *dashboardSqlAccess) scanRow(rows *sql.Rows, history bool) (*dashboardRo
if err != nil {
return nil, err
}
repo.Path = originPath
meta.SetSourceProperties(utils.SourceProperties{
Path: originPath, // relative path within source
Checksum: origin_hash.String,
TimestampMillis: origin_ts.Int64,
})
meta.SetManagerProperties(utils.ManagerProperties{
Kind: utils.ManagerKindClassicFP, // nolint:staticcheck
Identity: origin_name.String,
})
}
meta.SetRepositoryInfo(repo)
} else if plugin_id.String != "" {
meta.SetRepositoryInfo(&utils.ResourceRepositoryInfo{
Name: dashboardOG.PluginIDRepoName,
Path: plugin_id.String,
meta.SetManagerProperties(utils.ManagerProperties{
Kind: utils.ManagerKindPlugin,
Identity: plugin_id.String,
})
}
@@ -83,12 +83,18 @@ func TestScanRow(t *testing.T) {
meta, err := utils.MetaAccessor(row.Dash)
require.NoError(t, err)
require.Equal(t, "file:provisioner", meta.GetRepositoryName()) // should be prefixed by file:
require.Equal(t, "../"+pathToFile, meta.GetRepositoryPath()) // relative to provisioner
require.Equal(t, "hashing", meta.GetRepositoryHash())
ts, err := meta.GetRepositoryTimestamp()
m, ok := meta.GetManagerProperties()
require.True(t, ok)
s, ok := meta.GetSourceProperties()
require.True(t, ok)
require.Equal(t, utils.ManagerKindClassicFP, m.Kind) // nolint:staticcheck
require.Equal(t, "provisioner", m.Identity)
require.Equal(t, "../"+pathToFile, s.Path) // relative to provisioner
require.Equal(t, "hashing", s.Checksum)
require.NoError(t, err)
require.Equal(t, int64(100000), ts.Unix())
require.Equal(t, int64(100000), s.TimestampMillis)
})
t.Run("Plugin provisioned dashboard should have annotations", func(t *testing.T) {
@@ -105,8 +111,11 @@ func TestScanRow(t *testing.T) {
meta, err := utils.MetaAccessor(row.Dash)
require.NoError(t, err)
require.Equal(t, "plugin", meta.GetRepositoryName())
require.Equal(t, "slo", meta.GetRepositoryPath()) // the ID of the plugin
require.Equal(t, "", meta.GetRepositoryHash()) // hash is not used on plugins
manager, ok := meta.GetManagerProperties()
require.True(t, ok)
require.Equal(t, utils.ManagerKindPlugin, manager.Kind)
require.Equal(t, "slo", manager.Identity) // the ID of the plugin
require.Equal(t, "", meta.GetAnnotations()[utils.AnnoKeySourceChecksum]) // hash is not used on plugins
})
}
@@ -13,7 +13,6 @@ import (
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/apimachinery/utils"
dashboardOG "github.com/grafana/grafana/pkg/apis/dashboard"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
folderv0alpha1 "github.com/grafana/grafana/pkg/apis/folder/v0alpha1"
"github.com/grafana/grafana/pkg/services/dashboards"
@@ -181,18 +180,22 @@ func (c *DashboardSearchClient) Search(ctx context.Context, req *resource.Resour
}
query.FolderUIDs = folders
case resource.SEARCH_FIELD_REPOSITORY_PATH:
case resource.SEARCH_FIELD_SOURCE_PATH:
// only one value is supported in legacy search
if len(vals) != 1 {
return nil, fmt.Errorf("only one repo path query is supported")
}
query.ProvisionedPath = vals[0]
case resource.SEARCH_FIELD_REPOSITORY_NAME:
query.SourcePath = vals[0]
case resource.SEARCH_FIELD_MANAGER_KIND:
if len(vals) != 1 {
return nil, fmt.Errorf("only one manager kind supported")
}
query.ManagedBy = utils.ManagerKind(vals[0])
case resource.SEARCH_FIELD_MANAGER_ID:
if field.Operator == string(selection.NotIn) {
for _, val := range vals {
name, _ := dashboardOG.GetProvisionedFileNameFromMeta(val)
query.ProvisionedReposNotIn = append(query.ProvisionedReposNotIn, name)
}
query.ManagerIdentityNotIn = vals
continue
}
@@ -200,8 +203,7 @@ func (c *DashboardSearchClient) Search(ctx context.Context, req *resource.Resour
if len(vals) != 1 {
return nil, fmt.Errorf("only one repo name is supported")
}
query.ProvisionedRepo, _ = dashboardOG.GetProvisionedFileNameFromMeta(vals[0])
query.ManagerIdentity = vals[0]
}
}
searchFields := resource.StandardSearchFields()
@@ -221,17 +223,21 @@ func (c *DashboardSearchClient) Search(ctx context.Context, req *resource.Resour
// if we are querying for provisioning information, we need to use a different
// legacy sql query, since legacy search does not support this
if query.ProvisionedRepo != "" || len(query.ProvisionedReposNotIn) > 0 {
if query.ManagerIdentity != "" || len(query.ManagerIdentityNotIn) > 0 {
if query.ManagedBy == utils.ManagerKindUnknown {
return nil, fmt.Errorf("query by manager identity also requires manager.kind parameter")
}
var dashes []*dashboards.Dashboard
if query.ProvisionedRepo == dashboardOG.PluginIDRepoName {
if query.ManagedBy == utils.ManagerKindPlugin {
dashes, err = c.dashboardStore.GetDashboardsByPluginID(ctx, &dashboards.GetDashboardsByPluginIDQuery{
PluginID: query.ProvisionedPath,
PluginID: query.ManagerIdentity,
OrgID: user.GetOrgID(),
})
} else if query.ProvisionedRepo != "" {
dashes, err = c.dashboardStore.GetProvisionedDashboardsByName(ctx, query.ProvisionedRepo)
} else if len(query.ProvisionedReposNotIn) > 0 {
dashes, err = c.dashboardStore.GetOrphanedProvisionedDashboards(ctx, query.ProvisionedReposNotIn)
} else if query.ManagerIdentity != "" {
dashes, err = c.dashboardStore.GetProvisionedDashboardsByName(ctx, query.ManagerIdentity)
} else if len(query.ManagerIdentityNotIn) > 0 {
dashes, err = c.dashboardStore.GetOrphanedProvisionedDashboards(ctx, query.ManagerIdentityNotIn)
}
if err != nil {
return nil, err
@@ -373,12 +373,12 @@ func TestDashboardSearchClient_Search(t *testing.T) {
Key: dashboardKey,
Fields: []*resource.Requirement{
{
Key: resource.SEARCH_FIELD_REPOSITORY_PATH,
Key: resource.SEARCH_FIELD_MANAGER_ID,
Operator: "in",
Values: []string{"slo"},
},
{
Key: resource.SEARCH_FIELD_REPOSITORY_NAME,
Key: resource.SEARCH_FIELD_MANAGER_KIND,
Operator: "in",
Values: []string{"plugin"},
},
@@ -402,9 +402,14 @@ func TestDashboardSearchClient_Search(t *testing.T) {
Key: dashboardKey,
Fields: []*resource.Requirement{
{
Key: resource.SEARCH_FIELD_REPOSITORY_NAME,
Key: resource.SEARCH_FIELD_MANAGER_KIND,
Operator: "=",
Values: []string{string(utils.ManagerKindClassicFP)}, // nolint:staticcheck
},
{
Key: resource.SEARCH_FIELD_MANAGER_ID,
Operator: "in",
Values: []string{"file:test"}, // file prefix should be removed before going to legacy
Values: []string{"test"},
},
},
},
@@ -426,9 +431,14 @@ func TestDashboardSearchClient_Search(t *testing.T) {
Key: dashboardKey,
Fields: []*resource.Requirement{
{
Key: resource.SEARCH_FIELD_REPOSITORY_NAME,
Key: resource.SEARCH_FIELD_MANAGER_KIND,
Operator: "=",
Values: []string{string(utils.ManagerKindClassicFP)}, // nolint:staticcheck
},
{
Key: resource.SEARCH_FIELD_MANAGER_ID,
Operator: string(selection.NotIn),
Values: []string{"file:test", "file:test2"}, // file prefix should be removed before going to legacy
Values: []string{"test", "test2"},
},
},
},
+3 -7
View File
@@ -134,13 +134,9 @@ func (r *DTOConnector) Connect(ctx context.Context, name string, opts runtime.Ob
OrgID: info.OrgID,
ID: obj.GetDeprecatedInternalID(), // nolint:staticcheck
}
repo, err := obj.GetRepositoryInfo()
if err != nil {
responder.Error(err)
return
}
if repo != nil && repo.Name == dashboard.PluginIDRepoName {
dto.PluginID = repo.Path
manager, ok := obj.GetManagerProperties()
if ok && manager.Kind == utils.ManagerKindPlugin {
dto.PluginID = manager.Identity
}
guardian, err := guardian.NewByDashboard(ctx, dto, info.OrgID, user)