Skip to content

Commit

Permalink
Plugins: Enable catalog management link to gcom (grafana#34673)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
wbrowne authored May 27, 2021
1 parent f76f426 commit c7b58fe
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 29 deletions.
1 change: 1 addition & 0 deletions conf/defaults.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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 ##########################
Expand Down
1 change: 1 addition & 0 deletions conf/sample.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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 ##########################
Expand Down
4 changes: 3 additions & 1 deletion docs/sources/administration/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions packages/grafana-runtime/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = [];
Expand Down
19 changes: 10 additions & 9 deletions pkg/api/frontendsettings.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
20 changes: 11 additions & 9 deletions pkg/setting/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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);

Expand Down Expand Up @@ -93,14 +95,32 @@ export const InstallControls = ({ localPlugin, remotePlugin }: Props) => {
if (isInstalled) {
return (
<HorizontalGroup height="auto">
{shouldUpdate && (
<Button disabled={loading || !hasPermission} onClick={onUpdate}>
{loading ? 'Updating' : 'Update'}
{shouldUpdate &&
(isExternallyManaged ? (
<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 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>}
</HorizontalGroup>
);
Expand All @@ -117,14 +137,24 @@ export const InstallControls = ({ localPlugin, remotePlugin }: Props) => {

return (
<HorizontalGroup height="auto">
<Button disabled={loading || !hasPermission} onClick={onInstall}>
{loading ? 'Installing' : 'Install'}
</Button>
{isExternallyManaged ? (
<LinkButton disabled={!hasPermission} href={externalManageLink} target="_blank" rel="noopener noreferrer">
{'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>}
</HorizontalGroup>
);
};

function getExternalManageLink(plugin: Plugin): string {
return `https://grafana.com/grafana/plugins/${plugin.slug}`;
}

export const getStyles = (theme: GrafanaTheme2) => {
return {
message: css`
Expand Down

0 comments on commit c7b58fe

Please sign in to comment.