Dashboards: Add dashboard embed route (#69596)

* Dashboard embed: Set up route

* Dashboard embed: Cleanup

* Dashboard embed: Separate routes

* Dashboard embed: Render dashboard page

* Dashboard embed: Add toolbar

* Dashboard embed: Send JSON on save

* Dashboard embed: Add JSON param

* Dashboard embed: Make the dashboard editable

* Fix sending dashboard to remote server

* Add notifications

* Add "dashboardEmbed" feature toggle

* Use the toggle

* Update toggles

* Add toggle on backend

* Add get JSON endpoint

* Add drawer

* Close drawer on success

* Update toggles

* Cleanup

* Update toggle

* Allow embedding for the d-embed url

* Allow embedding via custom X-Allow-Embedding header

* Use callbackUrl

* Cleanup

* Update public/app/features/dashboard/containers/EmbeddedDashboardPage.tsx

Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com>

* Use theme for spacing

* Update toggles

* Update public/app/features/dashboard/components/EmbeddedDashboard/SaveDashboardForm.tsx

Co-authored-by: Polina Boneva <13227501+polibb@users.noreply.github.com>

* Add select data source modal

---------

Co-authored-by: kay delaney <45561153+kaydelaney@users.noreply.github.com>
Co-authored-by: Polina Boneva <13227501+polibb@users.noreply.github.com>
This commit is contained in:
Alex Khomenko
2023-07-06 17:43:20 +03:00
committed by GitHub
co-authored by kay delaney Polina Boneva
parent a8d2a9ae2b
commit 420b19e0e4
14 changed files with 336 additions and 2 deletions
+4
View File
@@ -148,6 +148,10 @@ func (hs *HTTPServer) registerRoutes() {
r.Get("/dashboards/*", reqSignedIn, hs.Index)
r.Get("/goto/:uid", reqSignedIn, hs.redirectFromShortURL, hs.Index)
if hs.Features.IsEnabled(featuremgmt.FlagDashboardEmbed) {
r.Get("/d-embed", reqSignedIn, middleware.AddAllowEmbeddingHeader(), hs.Index)
}
if hs.Features.IsEnabled(featuremgmt.FlagPublicDashboards) {
// list public dashboards
r.Get("/public-dashboards/list", reqSignedIn, hs.Index)
+12 -1
View File
@@ -52,7 +52,10 @@ func AddDefaultResponseHeaders(cfg *setting.Cfg) web.Handler {
addNoCacheHeaders(c.Resp)
}
if !cfg.AllowEmbedding {
// X-Allow-Embedding header is set for specific URLs that need to be embedded in an iframe regardless
// of the configured allow_embedding setting.
embeddingHeader := w.Header().Get("X-Allow-Embedding")
if !cfg.AllowEmbedding && embeddingHeader != "allow" {
addXFrameOptionsDenyHeader(w)
}
addSecurityHeaders(w, cfg)
@@ -60,6 +63,14 @@ func AddDefaultResponseHeaders(cfg *setting.Cfg) web.Handler {
}
}
func AddAllowEmbeddingHeader() web.Handler {
return func(c *web.Context) {
c.Resp.Before(func(w web.ResponseWriter) {
w.Header().Set("X-Allow-Embedding", "allow")
})
}
}
// addSecurityHeaders adds HTTP(S) response headers that enable various security protections in the client's browser.
func addSecurityHeaders(w web.ResponseWriter, cfg *setting.Cfg) {
if cfg.StrictTransportSecurity {
+7
View File
@@ -545,6 +545,13 @@ var (
FrontendOnly: true,
Owner: grafanaPluginsPlatformSquad,
},
{
Name: "dashboardEmbed",
Description: "Allow embedding dashboard for external use in Code editors",
FrontendOnly: true,
Stage: FeatureStageExperimental,
Owner: grafanaAsCodeSquad,
},
{
Name: "frontendSandboxMonitorOnly",
Description: "Enables monitor only in the plugin frontend sandbox (if enabled)",
+1
View File
@@ -79,6 +79,7 @@ dataSourcePageHeader,preview,@grafana/enterprise-datasources,false,false,false,t
extraThemes,experimental,@grafana/grafana-frontend-platform,false,false,false,true
lokiPredefinedOperations,experimental,@grafana/observability-logs,false,false,false,true
pluginsFrontendSandbox,experimental,@grafana/plugins-platform-backend,false,false,false,true
dashboardEmbed,experimental,@grafana/grafana-as-code,false,false,false,true
frontendSandboxMonitorOnly,experimental,@grafana/plugins-platform-backend,false,false,false,true
sqlDatasourceDatabaseSelection,preview,@grafana/grafana-bi-squad,false,false,false,true
cloudWatchLogsMonacoEditor,experimental,@grafana/aws-plugins,false,false,false,true
1 Name Stage Owner requiresDevMode RequiresLicense RequiresRestart FrontendOnly
79 extraThemes experimental @grafana/grafana-frontend-platform false false false true
80 lokiPredefinedOperations experimental @grafana/observability-logs false false false true
81 pluginsFrontendSandbox experimental @grafana/plugins-platform-backend false false false true
82 dashboardEmbed experimental @grafana/grafana-as-code false false false true
83 frontendSandboxMonitorOnly experimental @grafana/plugins-platform-backend false false false true
84 sqlDatasourceDatabaseSelection preview @grafana/grafana-bi-squad false false false true
85 cloudWatchLogsMonacoEditor experimental @grafana/aws-plugins false false false true
+4
View File
@@ -327,6 +327,10 @@ const (
// Enables the plugins frontend sandbox
FlagPluginsFrontendSandbox = "pluginsFrontendSandbox"
// FlagDashboardEmbed
// Allow embedding dashboard for external use in Code editors
FlagDashboardEmbed = "dashboardEmbed"
// FlagFrontendSandboxMonitorOnly
// Enables monitor only in the plugin frontend sandbox (if enabled)
FlagFrontendSandboxMonitorOnly = "frontendSandboxMonitorOnly"