-
Notifications
You must be signed in to change notification settings - Fork 11.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dashboards: Evaluate provisioned dashboard titles in a backwards compatible way #65184
Conversation
Slug: slugify.Slugify(folderName), | ||
OrgID: orgID, | ||
Title: &folderName, | ||
FolderID: util.Pointer(int64(0)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's can be fine for now but if nested folders are enabled then we need also the parent folder information
fae2d39
to
df30d5d
Compare
if query.Title != nil { | ||
dashboard.Title = *query.Title | ||
mustCols = append(mustCols, "title") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not completely familiar with MustCols yet but seems to me it would make sense to require that both title
and folder_id
be included if query.Title != nil
. Same comment for if query.FolderID != nil
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I suppose we can rely on the check on line 850 if query.ID == 0 && len(query.UID) == 0 && (query.Title == nil || query.FolderID == nil)
to ensure that we do include both "title" and "folder_id" in case either of them is non-nil so please disregard the earlier comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would love to have this query re-written without the xorm
magic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rn, you can say “give me a dashboard with this ID and this title”, which has the same uniqueness as title + folder. We don’t need to do it like that, but that’s why those are separated. Note that as long as orgID is properly set (…out of scope for this fix) at least one unique index will be hit, but there’s nothing preventing you from adding further constraints (give me dashboard 5 but only if it’s in folder 10)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
One question, does the API documentation for this need to get updated separately or is the doc comment you added going to be included somehow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have tested and it solves the problem (thank you for the database and the provisioning file to reproduce it)
maybe we could improve the query performance by always using the UQE_dashboard_org_id_folder_id_title
index
if query.FolderID != nil { | ||
dashboard.FolderID = *query.FolderID | ||
mustCols = append(mustCols, "folder_id") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if it's nil, I think that the UQE_dashboard_org_id_folder_id_title
index won't be used
maybe it's not a big problem given that another index (IDX_dashboard_title
) is used, but still has to filter out rows using where (for the org_id
)
mysql> EXPLAIN SELECT * FROM dashboard WHERE org_id = 1 AND title = 'gdev dashboards';
+----+-------------+-----------+------------+------+---------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+------+---------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | dashboard | NULL | ref | UQE_dashboard_org_id_folder_id_title,UQE_dashboard_org_id_uid,IDX_dashboard_org_id,IDX_dashboard_org_id_plugin_id,IDX_dashboard_title | IDX_dashboard_title | 758 | const | 1 | 100.00 | Using where |
+----+-------------+-----------+------------+------+---------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)
mysql> EXPLAIN SELECT * FROM dashboard WHERE org_id = 1 AND title = 'gdev dashboards' AND folder_id = 0;
+----+-------------+-----------+------------+-------+---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+---------+-------------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+-------+---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+---------+-------------------+------+----------+-------+
| 1 | SIMPLE | dashboard | NULL | const | UQE_dashboard_org_id_folder_id_title,UQE_dashboard_org_id_uid,IDX_dashboard_org_id,IDX_dashboard_org_id_plugin_id,IDX_dashboard_title | UQE_dashboard_org_id_folder_id_title | 774 | const,const,const | 1 | 100.00 | NULL |
+----+-------------+-----------+------------+-------+---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------+---------+-------------------+------+----------+-------+
1 row in set, 1 warning (0.01 sec)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it’s nil, then either UID or ID is set and those have indices?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my mistake, I think that you are right
@suntala That API documentation is just internal in the codebase, so it won’t show up anywhere. If Grafana had been compatible with pkg.go.dev you might’ve been able to see it there, but we wouldn’t have to do anything for that. |
What is this feature?
UQE_org_id_folder_id_title
index).Why do we need this feature?
#59517 changed some corner cases for slug generation and previously alerting and dashboards were using slugs to determine whether a folder already existed or not.
grafana/pkg/services/provisioning/dashboards/file_reader.go
Line 302 in b54b80f
grafana/pkg/services/provisioning/alerting/rules_provisioner.go
Lines 99 to 102 in c006df3
Who is this feature for?
Bug fix for provisioning for users upgrading to Grafana 9.4 from an earlier version.
Which issue(s) does this PR fix?:
Fixes #64525
Fixes #64595
Special notes for your reviewer:
The steps to reproduce that I was successful in following were provided in #64525 by @ThomasFOC (🙏 thank you for the very good step-by-step instructions for reproduction), here's a tarball containing a docker-compose environment that should show the issue. Use the commented out line to alternate between the earlier version of Grafana and a later version of Grafana should trigger the issue:
For manually testing the patch, I'd recommend copying over the 1.yml provisioning file to the provisioning directory in your development environment and checking out the
v9.3.8
and then a later version (I started out by testing it against 6a1d736 which was the current head of the v9.4.x branch). Validate that this is broken, and then check out this branch to validate its function.Please check that: