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

Pubdash: Email sharing handle dashboard deleted #64247

Conversation

owensmallwood
Copy link
Contributor

@owensmallwood owensmallwood commented Mar 6, 2023

Pubdash services handles when a dashboard is deleted (also handles case when dashboard is folder).

If enterprise, it will also delete all related email shares, magic links, and sessions for each pubdash that gets deleted.

Enterprise PR: https://github.com/grafana/grafana-enterprise/pull/4757
Fixes https://github.com/grafana/grafana-enterprise/issues/4394

pkg/services/publicdashboards/service/service.go Outdated Show resolved Hide resolved
pkg/services/publicdashboards/service/service.go Outdated Show resolved Hide resolved
pkg/services/publicdashboards/service/service.go Outdated Show resolved Hide resolved
@owensmallwood owensmallwood marked this pull request as ready for review March 6, 2023 22:41
@owensmallwood owensmallwood requested review from a team as code owners March 6, 2023 22:41
@owensmallwood owensmallwood requested review from dprokop, polibb, papagian, zserge and yangkb09 and removed request for a team March 6, 2023 22:41
pkg/api/dashboard.go Show resolved Hide resolved
}

// ServiceWrapper these methods have different behavior between OSS and Enterprise. The latter would call the OSS service first
//
//go:generate mockery --name ServiceWrapper --structname FakePublicDashboardServiceWrapper --inpackage --filename public_dashboard_service_wrapper_mock.go
type ServiceWrapper interface {
FindByDashboardUid(ctx context.Context, orgId int64, dashboardUid string) (*PublicDashboard, error)
HandlePublicDashboardDeleted(ctx context.Context, pubdash *PublicDashboard) error
Copy link
Contributor

Choose a reason for hiding this comment

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

remember to change this naming as well

@@ -342,6 +342,32 @@ func (pd *PublicDashboardServiceImpl) Delete(ctx context.Context, orgId int64, u
return nil
}

func (pd *PublicDashboardServiceImpl) DeleteByDashboard(ctx context.Context, dashboard *dashboards.Dashboard) error {
if dashboard.IsFolder {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think all of this should be in the same transaction. Thoughts? @evictorero

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What would the downside be if we only deleted some of the public dashboards and then returned an error?

Copy link
Contributor

Choose a reason for hiding this comment

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

have done an inconsistent deletion. From my point of view, everything should be deleted or if there's an error in any deletion, anything should be deleted and an error should be thrown. Otherwise, we end up in an inconsistent state which we don't know how to manage. It's my thought. We should decide what to do but why not to make it as a transaction if we will throw the error anyways?

Copy link
Contributor

Choose a reason for hiding this comment

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

If we are not blocking the dashboard deletion (which makes sense) I would say it's the same, maybe it is even better to delete a few ones since they will be orphans.
I'm wondering what we should do if the dashboard deletion fails after 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 think we should only use transactions when we want to avoid a weird state. For example, if we start deleting many pubdashes for a dashboard folder then fail halfway through, we'll return an error and there will still be some pubdashes remaining. I don't think this leaves us in a bad state - we just have less pubdashes than when we started, and we're still returning an error letting the caller know something went wrong. Win-win.

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 think this boils down to our definition of what getting left in a weird state is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@evictorero if the dashboard deletion fails, then it might be a confusing state for the user. We'd have to wrap the dashboard deletion itself in a transaction, which I don't think we can do right now. Might need to refactor some stuff in the dashboard api to do that.

Copy link
Contributor

Choose a reason for hiding this comment

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

I was thinking of calling the public dashboard deletion after dashboard deletion success. Since we don't have FKs we can delete the father before the child. If there is no dashboard but we have public dashboard orphans it's ok, the other way we could delete a public dashboard but if the dashboard deletion fails some configuration will disappear (pubdash) and that is not consistent.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

currently we cant delete the pubdash after the dashboard bc we need to query the dashboard table when its a folder that got deleted

var pubdashes []*PublicDashboard

err := d.sqlStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
return sess.SQL("SELECT * from dashboard_public WHERE dashboard_uid IN (SELECT uid FROM dashboard WHERE folder_id = ?)", dashboard.ID).Find(&pubdashes)
Copy link
Contributor

Choose a reason for hiding this comment

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

The dashboard_uid is not enough for dashboard identification, you need to use the org_id as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good call 👍 Will fix

pkg/services/publicdashboards/database/database.go Outdated Show resolved Hide resolved
@@ -43,3 +42,16 @@ func (pd *PublicDashboardServiceWrapperImpl) FindByDashboardUid(ctx context.Cont

return pubdash, nil
}

func (pd *PublicDashboardServiceWrapperImpl) DeleteByPublicDashboard(ctx context.Context, pubdash *PublicDashboard) error {
affectedRows, err := pd.store.Delete(ctx, pubdash.OrgId, pubdash.Uid)
Copy link
Contributor

Choose a reason for hiding this comment

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

The orgId shouldn't be necessary to delete a pubdash, only the uid. This code is old I am making this comment just to be aware of it 😅

pkg/api/dashboard.go Show resolved Hide resolved
pkg/services/publicdashboards/publicdashboard.go Outdated Show resolved Hide resolved
Copy link
Contributor

@evictorero evictorero left a comment

Choose a reason for hiding this comment

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

Great work! Ship it 🚀

@juanicabanas
Copy link
Contributor

LGTM !!! 🤟🏻

@owensmallwood owensmallwood merged commit 1a5a280 into main Mar 8, 2023
@owensmallwood owensmallwood deleted the owensmallwood/pubdash-email-sharing-handle-dashboard-deleted branch March 8, 2023 20:54
eleijonmarck pushed a commit that referenced this pull request Mar 13, 2023
dashboard service calls pubdash service when dashboard deleted
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

4 participants