From c7b58fe1865bceaecad7f5fb6ecacff625506b4e Mon Sep 17 00:00:00 2001 From: Will Browne Date: Thu, 27 May 2021 12:45:06 +0200 Subject: [PATCH] Plugins: Enable catalog management link to gcom (#34673) * click out to gcom when config enabled * set to false * fix styling for uninstall * remove advertising config + simplify callout URL * add entry to configuration.md * update config name * update lingo --- conf/defaults.ini | 1 + conf/sample.ini | 1 + docs/sources/administration/configuration.md | 4 +- packages/grafana-runtime/src/config.ts | 1 + pkg/api/frontendsettings.go | 19 +++---- pkg/setting/setting.go | 20 ++++---- .../src/components/InstallControls.tsx | 50 +++++++++++++++---- 7 files changed, 67 insertions(+), 29 deletions(-) diff --git a/conf/defaults.ini b/conf/defaults.ini index b3afe596fea..559b1066f89 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -885,6 +885,7 @@ app_tls_skip_verify_insecure = false allow_loading_unsigned_plugins = # Enable or disable installing plugins directly from within Grafana. plugin_admin_enabled = false +plugin_admin_external_manage_enabled = false plugin_catalog_url = https://grafana.com/grafana/plugins/ #################################### Grafana Image Renderer Plugin ########################## diff --git a/conf/sample.ini b/conf/sample.ini index f86c70b5348..50d47258814 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -871,6 +871,7 @@ ;allow_loading_unsigned_plugins = # Enable or disable installing plugins directly from within Grafana. ;plugin_admin_enabled = false +;plugin_admin_external_manage_enabled = false ;plugin_catalog_url = https://grafana.com/grafana/plugins/ #################################### Grafana Image Renderer Plugin ########################## diff --git a/docs/sources/administration/configuration.md b/docs/sources/administration/configuration.md index ce38c87aaba..74376108dde 100644 --- a/docs/sources/administration/configuration.md +++ b/docs/sources/administration/configuration.md @@ -1473,11 +1473,13 @@ Enter a comma-separated list of plugin identifiers to identify plugins that are ### plugin_admin_enabled - Available to Grafana administrators only, the plugin admin app is set to `false` by default. Set it to `true` to enable the app. For more information, refer to [Plugin catalog]({{< relref "../plugins/catalog.md" >}}). +### plugin_admin_external_manage_enabled + +Set to `true` if you want to enable external management of plugins. Default is `false`. This is only applicable to Grafana Cloud users. ### plugin_catalog_url diff --git a/packages/grafana-runtime/src/config.ts b/packages/grafana-runtime/src/config.ts index 032df34f46c..18e2e7a7be1 100644 --- a/packages/grafana-runtime/src/config.ts +++ b/packages/grafana-runtime/src/config.ts @@ -76,6 +76,7 @@ export class GrafanaBootConfig implements GrafanaConfig { }; pluginCatalogURL = 'https://grafana.com/grafana/plugins/'; pluginAdminEnabled = false; + pluginAdminExternalManageEnabled = false; expressionsEnabled = false; customTheme?: any; awsAllowedAuthProviders: string[] = []; diff --git a/pkg/api/frontendsettings.go b/pkg/api/frontendsettings.go index 64998e517d5..5acbf05eb6a 100644 --- a/pkg/api/frontendsettings.go +++ b/pkg/api/frontendsettings.go @@ -242,15 +242,16 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i "licenseUrl": hs.License.LicenseURL(c.SignedInUser), "edition": hs.License.Edition(), }, - "featureToggles": hs.Cfg.FeatureToggles, - "rendererAvailable": hs.RenderService.IsAvailable(), - "http2Enabled": hs.Cfg.Protocol == setting.HTTP2Scheme, - "sentry": hs.Cfg.Sentry, - "pluginCatalogURL": hs.Cfg.PluginCatalogURL, - "pluginAdminEnabled": c.IsGrafanaAdmin && hs.Cfg.PluginAdminEnabled && hasPluginManagerApp, - "expressionsEnabled": hs.Cfg.ExpressionsEnabled, - "awsAllowedAuthProviders": hs.Cfg.AWSAllowedAuthProviders, - "awsAssumeRoleEnabled": hs.Cfg.AWSAssumeRoleEnabled, + "featureToggles": hs.Cfg.FeatureToggles, + "rendererAvailable": hs.RenderService.IsAvailable(), + "http2Enabled": hs.Cfg.Protocol == setting.HTTP2Scheme, + "sentry": hs.Cfg.Sentry, + "pluginCatalogURL": hs.Cfg.PluginCatalogURL, + "pluginAdminEnabled": c.IsGrafanaAdmin && hs.Cfg.PluginAdminEnabled && hasPluginManagerApp, + "pluginAdminExternalManageEnabled": hs.Cfg.PluginAdminExternalManageEnabled, + "expressionsEnabled": hs.Cfg.ExpressionsEnabled, + "awsAllowedAuthProviders": hs.Cfg.AWSAllowedAuthProviders, + "awsAssumeRoleEnabled": hs.Cfg.AWSAssumeRoleEnabled, "azure": map[string]interface{}{ "cloud": hs.Cfg.Azure.Cloud, "managedIdentityEnabled": hs.Cfg.Azure.ManagedIdentityEnabled, diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index dfd554c8c6b..e7d83477323 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -253,15 +253,16 @@ type Cfg struct { // CSPTemplate contains the Content Security Policy template. CSPTemplate string - TempDataLifetime time.Duration - PluginsEnableAlpha bool - PluginsAppsSkipVerifyTLS bool - PluginSettings PluginSettings - PluginsAllowUnsigned []string - PluginCatalogURL string - PluginAdminEnabled bool - DisableSanitizeHtml bool - EnterpriseLicensePath string + TempDataLifetime time.Duration + PluginsEnableAlpha bool + PluginsAppsSkipVerifyTLS bool + PluginSettings PluginSettings + PluginsAllowUnsigned []string + PluginCatalogURL string + PluginAdminEnabled bool + PluginAdminExternalManageEnabled bool + DisableSanitizeHtml bool + EnterpriseLicensePath string // Metrics MetricsEndpointEnabled bool @@ -891,6 +892,7 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error { } cfg.PluginCatalogURL = pluginsSection.Key("plugin_catalog_url").MustString("https://grafana.com/grafana/plugins/") cfg.PluginAdminEnabled = pluginsSection.Key("plugin_admin_enabled").MustBool(false) + cfg.PluginAdminExternalManageEnabled = pluginsSection.Key("plugin_admin_external_manage_enabled").MustBool(false) // Read and populate feature toggles list featureTogglesSection := iniFile.Section("feature_toggles") diff --git a/plugins-bundled/internal/plugin-admin-app/src/components/InstallControls.tsx b/plugins-bundled/internal/plugin-admin-app/src/components/InstallControls.tsx index 4a31ab4fa83..54676297dc8 100644 --- a/plugins-bundled/internal/plugin-admin-app/src/components/InstallControls.tsx +++ b/plugins-bundled/internal/plugin-admin-app/src/components/InstallControls.tsx @@ -3,7 +3,7 @@ import { css } from '@emotion/css'; import { gt, satisfies } from 'semver'; import { config } from '@grafana/runtime'; -import { Button, HorizontalGroup, Icon, useStyles2 } from '@grafana/ui'; +import { Button, HorizontalGroup, Icon, LinkButton, useStyles2 } from '@grafana/ui'; import { AppEvents, GrafanaTheme2, OrgRole } from '@grafana/data'; import { Metadata, Plugin } from '../types'; @@ -25,6 +25,8 @@ export const InstallControls = ({ localPlugin, remotePlugin }: Props) => { const [shouldUpdate, setShouldUpdate] = useState( remotePlugin?.version && localPlugin?.info.version && gt(remotePlugin?.version!, localPlugin?.info.version!) ); + const isExternallyManaged = config.pluginAdminExternalManageEnabled; + const externalManageLink = getExternalManageLink(remotePlugin); const styles = useStyles2(getStyles); @@ -93,14 +95,32 @@ export const InstallControls = ({ localPlugin, remotePlugin }: Props) => { if (isInstalled) { return ( - {shouldUpdate && ( - + ))} + + {isExternallyManaged ? ( + + {'Uninstall via grafana.com'} + + ) : ( + )} - {!hasPermission &&
You need admin privileges to manage this plugin.
}
); @@ -117,14 +137,24 @@ export const InstallControls = ({ localPlugin, remotePlugin }: Props) => { return ( - + {isExternallyManaged ? ( + + {'Install via grafana.com'} + + ) : ( + + )} {!hasPermission &&
You need admin privileges to install this plugin.
}
); }; +function getExternalManageLink(plugin: Plugin): string { + return `https://grafana.com/grafana/plugins/${plugin.slug}`; +} + export const getStyles = (theme: GrafanaTheme2) => { return { message: css`