Skip to content
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

Alerting: Update API to use folders' full paths #81214

Merged
merged 14 commits into from
Feb 6, 2024

Conversation

yuri-tceretian
Copy link
Contributor

@yuri-tceretian yuri-tceretian commented Jan 24, 2024

What is this feature?
This PR changes Alerting API and Scheduler to refer to a folder using its full path.
This will have the following effect:

  1. Alert list UI will display full paths of folders that contain alert rules. This corresponds with how it displays data source managed rules.
  2. Scheduler will include the full path to label grafana_folder.

Why do we need this feature?
This is needed to properly support nested folders and relaxed constraints that allow folder title to be unique only among folders that share the same parent.

Who is this feature for?
Users of nested folders

Which issue(s) does this PR fix?:

Fixes #80324

Special notes for your reviewer:

Please check that:

  • It works as expected from a user's perspective.
  • If this is a pre-GA feature, it is behind a feature toggle.
  • The docs are updated, and if this is a notable improvement, it's added to our What's New doc.

Release notice breaking change

The following breaking change occurs only when feature flag nestedFolders is enabled.
If the folder title contains the symbol / (forward-slash) the notifications created from the rules that are placed in that folder will contain an escape sequence for that symbol in the label grafana_folder.
For example, the folder title is Grafana / Folder. Currently the label grafana_folder will contain the title as it is. If PR is merged - the label value will be Grafana \/ Folder.
This can break notifications if notification policies have matches that match that label and folder.

@grafana-delivery-bot grafana-delivery-bot bot added this to the 10.4.x milestone Jan 24, 2024
@yuri-tceretian yuri-tceretian changed the title Alerting: Update how API fetches rules available to user Alerting: Update API to use folders' full paths Jan 25, 2024
@yuri-tceretian yuri-tceretian force-pushed the yuri-tceretian/fullpaths-folder branch 2 times, most recently from 6d9b358 to c222d70 Compare January 31, 2024 14:30
@yuri-tceretian yuri-tceretian marked this pull request as ready for review January 31, 2024 15:19
@yuri-tceretian yuri-tceretian requested review from a team, rwwiv, JacobsonMT and grobinson-grafana and removed request for a team January 31, 2024 15:19
@yuri-tceretian yuri-tceretian self-assigned this Jan 31, 2024
@yuri-tceretian yuri-tceretian added the area/alerting Grafana Alerting label Jan 31, 2024
@yuri-tceretian yuri-tceretian requested a review from a team as a code owner January 31, 2024 18:10
@yuri-tceretian yuri-tceretian requested review from mildwonkey and undef1nd and removed request for a team January 31, 2024 18:10
@ephemeral-instances-bot
Copy link

Error: Contact #proj-ephemeral-hg-instances if it is not a compile error

handling pull request comment event: calling gcom to upsert instance: creating instance: unexpected response status: status=409 responseBody={
"code": "Conflict",
"message": "Region is missing required fields: llm_gateway_url",
"requestId": "43c13578-df95-4531-b5f2-e9b4984a7139"
}

@yuri-tceretian yuri-tceretian added the breaking change Relevant for changelog generation label Jan 31, 2024
@yuri-tceretian
Copy link
Contributor Author

/deploy-to-hg --enterprise-ref yuri-tceretian/fullpaths-folder

@ephemeral-instances-bot
Copy link

  • Preparing your instance. A comment containing your instance's url will be added to this PR when the instance is ready.
  • Your instance will be ready in ~10 minutes.
  • Check the GitHub actions tab to follow the workflow progress
  • Slack channel: #proj-ephemeral-hg-instances
  • Building instance with yuri-tceretian/fullpaths-folder oss branch and yuri-tceretian/fullpaths-folder enterprise branch. How to choose a branch

@ephemeral-instances-bot
Copy link

return folder, nil
if len(f) == 0 {
return nil, dashboards.ErrFolderAccessDenied
}
Copy link
Contributor Author

@yuri-tceretian yuri-tceretian Feb 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to replicate FolderService.Get behavior. @papagian, I wonder if you can fix Get to provide full path too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, I'll do but I would suggest not to block the current work (merge this one and address it in a follow up)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yuri-tceretian the FolderService.Get() change: #81972

Copy link
Contributor

@alexweav alexweav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking very good, a couple question comments that are quite minor. I will defer the folderimpl changes to @papagian

@@ -705,29 +704,3 @@ func GroupByAlertRuleGroupKey(rules []*AlertRule) map[AlertRuleGroupKey]RulesGro
}
return result
}

// GetNamespaceKey concatenates two strings with / as separator. If the latter string contains '/' it gets escaped with \/
func GetNamespaceKey(parentUID, title string) string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small reminder to merge the Enterprise change (consuming this function) before or at the same time as this PR 😄

@@ -128,6 +128,7 @@ func (api *API) RegisterAPIEndpoints(m *metrics.API) {
featureManager: api.FeatureManager,
appUrl: api.AppUrl,
tracer: api.Tracer,
rulesStore: api.RuleStore,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: RuleStore is a pretty large interface, and we seem to only use it to actually query for folders, not even rules directly. Rather than adding fairly big dependency here, would it be worth declaring a minimal interface containing just GetNamespaceByUID and whatever else is needed?

}

// RouteTestGrafanaRuleConfig returns a list of potential alerts for a given rule configuration. This is intended to be
// as true as possible to what would be generated by the ruler except that the resulting alerts are not filtered to
// only Resolved / Firing and ready to send.
func (srv TestingApiSrv) RouteTestGrafanaRuleConfig(c *contextmodel.ReqContext, body apimodels.PostableExtendedRuleNodeExtended) response.Response {
folder, err := srv.rulesStore.GetNamespaceByUID(c.Req.Context(), body.NamespaceUID, c.OrgID, c.SignedInUser)
if err != nil {
return toNamespaceErrorResponse(dashboards.ErrFolderAccessDenied)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the previous version, we purely passed along the UID without validating it.

I think there are contexts where this endpoint may be hit without a valid folder supplied (i.e. you try to test your query and have not yet selected a folder in the UI, the folder selector being below the query).

Does this break such cases, by attempting to look up the folder and failing the test if it's not yet selected? Or, is there a spot later in the flow that does this lookup anyway? We could consider filling the folder with something arbitrary and allowing the test to proceed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, this becomes mandatory in this API. Otherwise, we risk providing incorrect routing information. Previously we took the folder title from the request and it was enough but UI cannot provide full path in the folder title anymore. So, I had to update it. Anyway, as long as user has access to the rule it has access to the folder it contains.

OrgID: f.OrgId,
UID: f.Uid,
for orgID, uids := range uids {
schedulerUser := accesscontrol.BackgroundUser("grafana_scheduler", orgID, org.RoleAdmin,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we extract schedulerUserFor in schedule.go to some shared location and call it from here? And add the folder permissions to it?

That way we don't have an inconsistency if the fake user ever changes, and we have a list of all combined permissions for the rule evaluation in one place.

Copy link
Contributor Author

@yuri-tceretian yuri-tceretian Feb 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem here is that this is supposed to be a multi-org user (it requires per -org permissions) we can extract it to a function but it won't make any difference because we won't be able to pass it around in scheduler. Another problem is where to put it... perhaps in store or in models package but neither of them seem to be good.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I wonder if we could change UX so user is not guided into the path? Put folder selector next to name selector, above the query or something? @gillesdemey

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clicked the wrong comment box...that was meant for the one about testing API
#81214 (comment)

Copy link
Contributor

@papagian papagian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

however I observe some no rule groups found errors but I assume that these are attempts to fetch rule from the different data sources

return folder, nil
if len(f) == 0 {
return nil, dashboards.ErrFolderAccessDenied
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, I'll do but I would suggest not to block the current work (merge this one and address it in a follow up)

@yuri-tceretian
Copy link
Contributor Author

yuri-tceretian commented Feb 2, 2024

however I observe some no rule groups found errors but I assume that these are attempts to fetch rule from the different data sources

those are for Lotex APIs. I did not touch them in this PR

@yuri-tceretian
Copy link
Contributor Author

/deploy-to-hg --enterprise-ref yuri-tceretian/fullpaths-folder

@grafana grafana deleted a comment from ephemeral-instances-bot bot Feb 6, 2024
@grafana grafana deleted a comment from ephemeral-instances-bot bot Feb 6, 2024
@yuri-tceretian
Copy link
Contributor Author

/deploy-to-hg --enterprise-ref yuri-tceretian/fullpaths-folder

@ephemeral-instances-bot
Copy link

  • Preparing your instance. A comment containing your instance's url will be added to this PR when the instance is ready.
  • Your instance will be ready in ~10 minutes.
  • Check the GitHub actions tab to follow the workflow progress
  • Slack channel: #proj-ephemeral-hg-instances
  • Building instance with yuri-tceretian/fullpaths-folder oss branch and yuri-tceretian/fullpaths-folder enterprise branch. How to choose a branch

@ephemeral-instances-bot
Copy link

@yuri-tceretian yuri-tceretian merged commit 47546a4 into main Feb 6, 2024
12 checks passed
@yuri-tceretian yuri-tceretian deleted the yuri-tceretian/fullpaths-folder branch February 6, 2024 22:12
Ukochka pushed a commit that referenced this pull request Feb 14, 2024
* update GetUserVisibleNamespaces to use FolderSeriver
* update GetNamespaceByUID to use FolderService.GetFolders
* update GetAlertRulesForScheduling to use FolderService.GetFolders 

* Update API and GetAlertRulesForScheduling to use the folder's full path
* get full path of folder in RouteTestGrafanaRuleConfig

* fix escaping of titles for MySQL
@aangelisc aangelisc modified the milestones: 10.4.x, 10.4.0 Mar 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
add to changelog area/alerting Grafana Alerting area/backend breaking change Relevant for changelog generation no-backport Skip backport of PR
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Alerting: Update scheduler to include the full path to the folder to label grafana_folder
4 participants