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

PublicDashboards: Add annotations support #56413

Merged
merged 49 commits into from Oct 19, 2022

Conversation

owensmallwood
Copy link
Contributor

@owensmallwood owensmallwood commented Oct 5, 2022

Changes
This adds support for Grafana annotations. Annotations that query an external datasource are not supported yet. Any Grafana annotations that query by dashboard or by tag should work with public dashboards.

Implementation Notes

  • The pubdash service gathers all unique annotation events in a single api call for the dashboard. In the case that an annotation event belongs to a dashboard annotation and a tags annotation, the tags annotation will take priority.
  • Generated types were used for the dashboard annotations.

fixes https://github.com/grafana/grafana-enterprise/issues/4475

@grafanabot
Copy link
Contributor

@grafanabot
Copy link
Contributor

@ryantxu
Copy link
Member

ryantxu commented Oct 6, 2022

It is worth checking if we can do this though the builtin grafana datasource -- that already has annotation support (but may require some munging on the frontend)

@@ -199,7 +199,7 @@ type HTTPServer struct {
orgService org.Service
teamService team.Service
accesscontrolService accesscontrol.Service
annotationsRepo annotations.Repository
AnnotationsRepo annotations.Repository
Copy link
Member

Choose a reason for hiding this comment

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

why does it need to be public? better if we we can avoid that

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I remember needing it public for some reason when I started tinkering around with this card, but looks like I don't need it anymore. Changed it back to private!

@grafanabot
Copy link
Contributor

@owensmallwood
Copy link
Contributor Author

@ryantxu We could use the Grafana datasource for annotations, but I'm hesitant about sprinkling pubdash code around the various datasources we already have. Most have enough complexity as it is, and it's nice to have all the pubdash stuff in one datasource right now. Its been helpful to use the PublicDashboardDatasource for all our pubdash api calls (currently just running queries and getting annotations) since they need to be to our service's unauthed endpoints.

@grafanabot
Copy link
Contributor

Comment on lines 254 to 290
type annotation struct {
Datasource struct {
DType string `json:"type"`
Uid string `json:"uid"`
}
Enable bool `json:"enable"`
Type string `json:"type"`
Target struct {
Limit int64 `json:"limit"`
MatchAny bool `json:"matchAny"`
Tags []string `json:"tags"`
Type string `json:"type"`
}
}

type annotationsDto struct {
Annotations struct {
List []annotation `json:"list"`
}
}

dto := annotationsDto{}
bytes, err := dash.Data.MarshalJSON()
if err != nil {
return nil, err
}
err = json.Unmarshal(bytes, &dto)
if err != nil {
return nil, err
}

anonymousUser, err := pd.BuildAnonymousUser(ctx, dash)
if err != nil {
return nil, err
}

var results []*annotations.ItemDTO
Copy link
Member

Choose a reason for hiding this comment

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

@sdboyer how close are we to use the cue generated go types for dashboard to loop through in this case Annotation queries. We loop and manipulate the dashboard model in many places in the core code would be a good place to start using the generated types.

Copy link
Contributor

Choose a reason for hiding this comment

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

For this purpose, we're close, plausibly close enough that this PR should be refactored to use generated types.

Looks like the main issue is that there's no specification for Target written down yet. But if the fields given here are indeed what's expected to be there (even if it's not ALL of them), then there's no reason this PR couldn't just add them to the schema then re-run make gen-cue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Once this PR is functional, I'll come back and tackle this.

Comment on lines 291 to 292
for _, anno := range dto.Annotations.List {
if anno.Enable {
Copy link
Member

Choose a reason for hiding this comment

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

Because this is only dealing with Grafana's built-in annotation data source here (and many use Prometheus, loki or Elasticsearch instead to query for annotations) you need to check the annotation query datasource prop.

Check if the uid is grafanads.DatasourceUID

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! This is still a work in progress. Just put up the draft PR for visibility

let datasourceObservable;
if (dashboard.meta.publicDashboardAccessToken !== '') {
const pubdashDatasource = new PublicDashboardDataSource(PUBLIC_DATASOURCE);
datasourceObservable = of(pubdashDatasource).pipe(catchError(handleDatasourceSrvError));
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice work with RXJS, would love a rundown of your experience!

Copy link
Contributor

@jalevin jalevin left a comment

Choose a reason for hiding this comment

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

Monster PR Owen! Great work. A few things to tidy up, but LGTM

};
const annotations = await getBackendSrv().get(`/api/public/dashboards/${accessToken}/annotations`, params);

return { data: [toDataFrame(annotations)] };
Copy link
Contributor

Choose a reason for hiding this comment

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

Question: would it be a smart idea to return it as data frames directly from the backend instead of needing to transform the response in the frontend? Or do we have any other consumers of this API a part of this frontend?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is the only consumer of this endpoint right now. Since we can already transform it to dataframes on the frontend, I did it there. I didn't see a benefit to reimplementing it on the backend at this point.

@grafanabot
Copy link
Contributor

@grafanabot
Copy link
Contributor

@grafanabot
Copy link
Contributor

Copy link
Contributor

@jalevin jalevin left a comment

Choose a reason for hiding this comment

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

LGTM!

@owensmallwood owensmallwood merged commit b2408dd into main Oct 19, 2022
@owensmallwood owensmallwood deleted the owensmallwood/pubdash-add-annotations-support branch October 19, 2022 01:48
@daniellee daniellee changed the title Publicdasboards: Add annotations support Publicdashboards: Add annotations support Oct 21, 2022
@daniellee daniellee changed the title Publicdashboards: Add annotations support PublicDashboards: Add annotations support Oct 21, 2022
@leandro-deveikis leandro-deveikis modified the milestones: 9.3.0, 9.3.0-beta1 Nov 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants