fix: update search request for existing provisioned dashboards in modes 3+ (#114412)

Fix search for existing provisioned dashboards in modes 3+

The search query was not requesting the dashboard's "legacy ID". As a result,
the provisioning process would not find existing provisioned dashboards, making
copies of these dashboards every time there was a change in the provisioned
dashboard's definition.

Signed-off-by: Maicon Costa <maiconscosta@gmail.com>
This commit is contained in:
Renato Costa
2025-12-05 12:32:30 -03:00
committed by Maicon Costa
parent 6b854bc57d
commit 076d378adc
3 changed files with 31 additions and 4 deletions
+3 -3
View File
@@ -15,7 +15,6 @@ import (
_ "github.com/blugelabs/bluge"
_ "github.com/blugelabs/bluge_segment_api"
_ "github.com/crewjam/saml"
_ "github.com/docker/go-connections/nat"
_ "github.com/go-jose/go-jose/v4"
_ "github.com/gobwas/glob"
_ "github.com/googleapis/gax-go/v2"
@@ -31,7 +30,6 @@ import (
_ "github.com/spf13/cobra" // used by the standalone apiserver cli
_ "github.com/spyzhov/ajson"
_ "github.com/stretchr/testify/require"
_ "github.com/testcontainers/testcontainers-go"
_ "gocloud.dev/secrets/awskms"
_ "gocloud.dev/secrets/azurekeyvault"
_ "gocloud.dev/secrets/gcpkms"
@@ -56,7 +54,9 @@ import (
_ "github.com/grafana/e2e"
_ "github.com/grafana/gofpdf"
_ "github.com/grafana/gomemcache/memcache"
_ "github.com/grafana/tempo/pkg/traceql"
_ "github.com/grafana/grafana/apps/alerting/alertenrichment/pkg/apis/alertenrichment/v1beta1"
_ "github.com/grafana/grafana/apps/scope/pkg/apis/scope/v0alpha1"
_ "github.com/grafana/tempo/pkg/traceql"
_ "github.com/testcontainers/testcontainers-go"
)
@@ -2009,7 +2009,14 @@ func (dr *DashboardServiceImpl) searchDashboardsThroughK8sRaw(ctx context.Contex
request.Limit = query.Limit
request.Page = query.Page
request.Offset = (query.Page - 1) * query.Limit // only relevant when running in modes 3+
request.Fields = dashboardsearch.IncludeFields
request.Fields = append(
dashboardsearch.IncludeFields,
// Include the dashboard legacy ID in the results, as it is needed when
// determining whether a provisioned dashboard exists or not, see
// `(*DashboardServiceImpl).searchProvisionedDashboardsThroughK8s`.
resource.SEARCH_FIELD_LEGACY_ID,
resource.SEARCH_FIELD_LABELS+"."+resource.SEARCH_FIELD_LEGACY_ID,
)
namespace := dr.k8sclient.GetNamespace(query.OrgId)
var err error
@@ -2016,6 +2016,26 @@ func TestSearchDashboardsThroughK8sRaw(t *testing.T) {
_, err := service.searchDashboardsThroughK8s(ctx, query)
require.NoError(t, err)
})
t.Run("search will request legacy dashboard ID", func(t *testing.T) {
ctx := context.Background()
k8sCliMock := new(client.MockK8sHandler)
service := &DashboardServiceImpl{k8sclient: k8sCliMock}
query := &dashboards.FindPersistedDashboardsQuery{
ManagedBy: utils.ManagerKindClassicFP, //nolint:staticcheck
OrgId: 1,
}
k8sCliMock.On("GetNamespace", mock.Anything, mock.Anything).Return("default")
k8sCliMock.On("Search", mock.Anything, mock.Anything, mock.MatchedBy(func(req *resourcepb.ResourceSearchRequest) bool {
return slices.Contains(req.Fields, "grafana.app/deprecatedInternalID") &&
slices.Contains(req.Fields, "labels.grafana.app/deprecatedInternalID")
})).Return(&resourcepb.ResourceSearchResponse{
Results: &resourcepb.ResourceTable{},
TotalHits: 0,
}, nil)
_, err := service.searchDashboardsThroughK8s(ctx, query)
require.NoError(t, err)
})
}
func TestSearchProvisionedDashboardsThroughK8sRaw(t *testing.T) {