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
This commit is contained in:
Will Browne
2021-05-27 12:45:06 +02:00
committed by GitHub
parent f76f426da3
commit c7b58fe186
7 changed files with 67 additions and 29 deletions
+1
View File
@@ -885,6 +885,7 @@ app_tls_skip_verify_insecure = false
allow_loading_unsigned_plugins = allow_loading_unsigned_plugins =
# Enable or disable installing plugins directly from within Grafana. # Enable or disable installing plugins directly from within Grafana.
plugin_admin_enabled = false plugin_admin_enabled = false
plugin_admin_external_manage_enabled = false
plugin_catalog_url = https://grafana.com/grafana/plugins/ plugin_catalog_url = https://grafana.com/grafana/plugins/
#################################### Grafana Image Renderer Plugin ########################## #################################### Grafana Image Renderer Plugin ##########################
+1
View File
@@ -871,6 +871,7 @@
;allow_loading_unsigned_plugins = ;allow_loading_unsigned_plugins =
# Enable or disable installing plugins directly from within Grafana. # Enable or disable installing plugins directly from within Grafana.
;plugin_admin_enabled = false ;plugin_admin_enabled = false
;plugin_admin_external_manage_enabled = false
;plugin_catalog_url = https://grafana.com/grafana/plugins/ ;plugin_catalog_url = https://grafana.com/grafana/plugins/
#################################### Grafana Image Renderer Plugin ########################## #################################### Grafana Image Renderer Plugin ##########################
+3 -1
View File
@@ -1473,11 +1473,13 @@ Enter a comma-separated list of plugin identifiers to identify plugins that are
### plugin_admin_enabled ### 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. 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" >}}). 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 ### plugin_catalog_url
+1
View File
@@ -76,6 +76,7 @@ export class GrafanaBootConfig implements GrafanaConfig {
}; };
pluginCatalogURL = 'https://grafana.com/grafana/plugins/'; pluginCatalogURL = 'https://grafana.com/grafana/plugins/';
pluginAdminEnabled = false; pluginAdminEnabled = false;
pluginAdminExternalManageEnabled = false;
expressionsEnabled = false; expressionsEnabled = false;
customTheme?: any; customTheme?: any;
awsAllowedAuthProviders: string[] = []; awsAllowedAuthProviders: string[] = [];
+10 -9
View File
@@ -242,15 +242,16 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i
"licenseUrl": hs.License.LicenseURL(c.SignedInUser), "licenseUrl": hs.License.LicenseURL(c.SignedInUser),
"edition": hs.License.Edition(), "edition": hs.License.Edition(),
}, },
"featureToggles": hs.Cfg.FeatureToggles, "featureToggles": hs.Cfg.FeatureToggles,
"rendererAvailable": hs.RenderService.IsAvailable(), "rendererAvailable": hs.RenderService.IsAvailable(),
"http2Enabled": hs.Cfg.Protocol == setting.HTTP2Scheme, "http2Enabled": hs.Cfg.Protocol == setting.HTTP2Scheme,
"sentry": hs.Cfg.Sentry, "sentry": hs.Cfg.Sentry,
"pluginCatalogURL": hs.Cfg.PluginCatalogURL, "pluginCatalogURL": hs.Cfg.PluginCatalogURL,
"pluginAdminEnabled": c.IsGrafanaAdmin && hs.Cfg.PluginAdminEnabled && hasPluginManagerApp, "pluginAdminEnabled": c.IsGrafanaAdmin && hs.Cfg.PluginAdminEnabled && hasPluginManagerApp,
"expressionsEnabled": hs.Cfg.ExpressionsEnabled, "pluginAdminExternalManageEnabled": hs.Cfg.PluginAdminExternalManageEnabled,
"awsAllowedAuthProviders": hs.Cfg.AWSAllowedAuthProviders, "expressionsEnabled": hs.Cfg.ExpressionsEnabled,
"awsAssumeRoleEnabled": hs.Cfg.AWSAssumeRoleEnabled, "awsAllowedAuthProviders": hs.Cfg.AWSAllowedAuthProviders,
"awsAssumeRoleEnabled": hs.Cfg.AWSAssumeRoleEnabled,
"azure": map[string]interface{}{ "azure": map[string]interface{}{
"cloud": hs.Cfg.Azure.Cloud, "cloud": hs.Cfg.Azure.Cloud,
"managedIdentityEnabled": hs.Cfg.Azure.ManagedIdentityEnabled, "managedIdentityEnabled": hs.Cfg.Azure.ManagedIdentityEnabled,
+11 -9
View File
@@ -253,15 +253,16 @@ type Cfg struct {
// CSPTemplate contains the Content Security Policy template. // CSPTemplate contains the Content Security Policy template.
CSPTemplate string CSPTemplate string
TempDataLifetime time.Duration TempDataLifetime time.Duration
PluginsEnableAlpha bool PluginsEnableAlpha bool
PluginsAppsSkipVerifyTLS bool PluginsAppsSkipVerifyTLS bool
PluginSettings PluginSettings PluginSettings PluginSettings
PluginsAllowUnsigned []string PluginsAllowUnsigned []string
PluginCatalogURL string PluginCatalogURL string
PluginAdminEnabled bool PluginAdminEnabled bool
DisableSanitizeHtml bool PluginAdminExternalManageEnabled bool
EnterpriseLicensePath string DisableSanitizeHtml bool
EnterpriseLicensePath string
// Metrics // Metrics
MetricsEndpointEnabled bool 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.PluginCatalogURL = pluginsSection.Key("plugin_catalog_url").MustString("https://grafana.com/grafana/plugins/")
cfg.PluginAdminEnabled = pluginsSection.Key("plugin_admin_enabled").MustBool(false) 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 // Read and populate feature toggles list
featureTogglesSection := iniFile.Section("feature_toggles") featureTogglesSection := iniFile.Section("feature_toggles")
@@ -3,7 +3,7 @@ import { css } from '@emotion/css';
import { gt, satisfies } from 'semver'; import { gt, satisfies } from 'semver';
import { config } from '@grafana/runtime'; 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 { AppEvents, GrafanaTheme2, OrgRole } from '@grafana/data';
import { Metadata, Plugin } from '../types'; import { Metadata, Plugin } from '../types';
@@ -25,6 +25,8 @@ export const InstallControls = ({ localPlugin, remotePlugin }: Props) => {
const [shouldUpdate, setShouldUpdate] = useState( const [shouldUpdate, setShouldUpdate] = useState(
remotePlugin?.version && localPlugin?.info.version && gt(remotePlugin?.version!, localPlugin?.info.version!) remotePlugin?.version && localPlugin?.info.version && gt(remotePlugin?.version!, localPlugin?.info.version!)
); );
const isExternallyManaged = config.pluginAdminExternalManageEnabled;
const externalManageLink = getExternalManageLink(remotePlugin);
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
@@ -93,14 +95,32 @@ export const InstallControls = ({ localPlugin, remotePlugin }: Props) => {
if (isInstalled) { if (isInstalled) {
return ( return (
<HorizontalGroup height="auto"> <HorizontalGroup height="auto">
{shouldUpdate && ( {shouldUpdate &&
<Button disabled={loading || !hasPermission} onClick={onUpdate}> (isExternallyManaged ? (
{loading ? 'Updating' : 'Update'} <LinkButton disabled={!hasPermission} href={externalManageLink} target="_blank" rel="noopener noreferrer">
{'Update via grafana.com'}
</LinkButton>
) : (
<Button disabled={loading || !hasPermission} onClick={onUpdate}>
{loading ? 'Updating' : 'Update'}
</Button>
))}
{isExternallyManaged ? (
<LinkButton
variant="destructive"
disabled={!hasPermission}
href={externalManageLink}
target="_blank"
rel="noopener noreferrer"
>
{'Uninstall via grafana.com'}
</LinkButton>
) : (
<Button variant="destructive" disabled={loading || !hasPermission} onClick={onUninstall}>
{loading && !shouldUpdate ? 'Uninstalling' : 'Uninstall'}
</Button> </Button>
)} )}
<Button variant="destructive" disabled={loading || !hasPermission} onClick={onUninstall}>
{loading && !shouldUpdate ? 'Uninstalling' : 'Uninstall'}
</Button>
{!hasPermission && <div className={styles.message}>You need admin privileges to manage this plugin.</div>} {!hasPermission && <div className={styles.message}>You need admin privileges to manage this plugin.</div>}
</HorizontalGroup> </HorizontalGroup>
); );
@@ -117,14 +137,24 @@ export const InstallControls = ({ localPlugin, remotePlugin }: Props) => {
return ( return (
<HorizontalGroup height="auto"> <HorizontalGroup height="auto">
<Button disabled={loading || !hasPermission} onClick={onInstall}> {isExternallyManaged ? (
{loading ? 'Installing' : 'Install'} <LinkButton disabled={!hasPermission} href={externalManageLink} target="_blank" rel="noopener noreferrer">
</Button> {'Install via grafana.com'}
</LinkButton>
) : (
<Button disabled={loading || !hasPermission} onClick={onInstall}>
{loading ? 'Installing' : 'Install'}
</Button>
)}
{!hasPermission && <div className={styles.message}>You need admin privileges to install this plugin.</div>} {!hasPermission && <div className={styles.message}>You need admin privileges to install this plugin.</div>}
</HorizontalGroup> </HorizontalGroup>
); );
}; };
function getExternalManageLink(plugin: Plugin): string {
return `https://grafana.com/grafana/plugins/${plugin.slug}`;
}
export const getStyles = (theme: GrafanaTheme2) => { export const getStyles = (theme: GrafanaTheme2) => {
return { return {
message: css` message: css`