mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Plugins Catalog: hide plugins based on the Grafana config (#41679)
* refactor(pkg/api/frontendsettings): group plugin catalog settings * feat(plugins/admin): add a default config value for `pluginCatalogHiddenPlugins` * chore(grafana/config): add type for `pluginCatalogHiddenPlugins` * feat(plugins/admin): hide plugins from the catalog based on the grafana config * fix(plugins/admin): fix a rebase typo * fix(plugins/admin): remove unnecessary filtering
This commit is contained in:
parent
2c8ac1f58f
commit
4219e4f107
@ -84,6 +84,7 @@ export class GrafanaBootConfig implements GrafanaConfig {
|
|||||||
pluginCatalogURL = 'https://grafana.com/grafana/plugins/';
|
pluginCatalogURL = 'https://grafana.com/grafana/plugins/';
|
||||||
pluginAdminEnabled = true;
|
pluginAdminEnabled = true;
|
||||||
pluginAdminExternalManageEnabled = false;
|
pluginAdminExternalManageEnabled = false;
|
||||||
|
pluginCatalogHiddenPlugins: string[] = [];
|
||||||
expressionsEnabled = false;
|
expressionsEnabled = false;
|
||||||
customTheme?: any;
|
customTheme?: any;
|
||||||
awsAllowedAuthProviders: string[] = [];
|
awsAllowedAuthProviders: string[] = [];
|
||||||
|
@ -288,6 +288,7 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i
|
|||||||
"pluginCatalogURL": hs.Cfg.PluginCatalogURL,
|
"pluginCatalogURL": hs.Cfg.PluginCatalogURL,
|
||||||
"pluginAdminEnabled": hs.Cfg.PluginAdminEnabled,
|
"pluginAdminEnabled": hs.Cfg.PluginAdminEnabled,
|
||||||
"pluginAdminExternalManageEnabled": hs.Cfg.PluginAdminEnabled && hs.Cfg.PluginAdminExternalManageEnabled,
|
"pluginAdminExternalManageEnabled": hs.Cfg.PluginAdminEnabled && hs.Cfg.PluginAdminExternalManageEnabled,
|
||||||
|
"pluginCatalogHiddenPlugins": hs.Cfg.PluginCatalogHiddenPlugins,
|
||||||
"expressionsEnabled": hs.Cfg.ExpressionsEnabled,
|
"expressionsEnabled": hs.Cfg.ExpressionsEnabled,
|
||||||
"awsAllowedAuthProviders": hs.Cfg.AWSAllowedAuthProviders,
|
"awsAllowedAuthProviders": hs.Cfg.AWSAllowedAuthProviders,
|
||||||
"awsAssumeRoleEnabled": hs.Cfg.AWSAssumeRoleEnabled,
|
"awsAssumeRoleEnabled": hs.Cfg.AWSAssumeRoleEnabled,
|
||||||
@ -298,8 +299,7 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i
|
|||||||
"caching": map[string]bool{
|
"caching": map[string]bool{
|
||||||
"enabled": hs.Cfg.SectionWithEnvOverrides("caching").Key("enabled").MustBool(true),
|
"enabled": hs.Cfg.SectionWithEnvOverrides("caching").Key("enabled").MustBool(true),
|
||||||
},
|
},
|
||||||
"unifiedAlertingEnabled": hs.Cfg.UnifiedAlerting.Enabled,
|
"unifiedAlertingEnabled": hs.Cfg.UnifiedAlerting.Enabled,
|
||||||
"pluginCatalogHiddenPlugins": hs.Cfg.PluginCatalogHiddenPlugins,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if hs.Cfg.GeomapDefaultBaseLayerConfig != nil {
|
if hs.Cfg.GeomapDefaultBaseLayerConfig != nil {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { getBackendSrv } from '@grafana/runtime';
|
import { getBackendSrv } from '@grafana/runtime';
|
||||||
import { PluginError, renderMarkdown } from '@grafana/data';
|
import { PluginError, renderMarkdown } from '@grafana/data';
|
||||||
import { API_ROOT, GCOM_API_ROOT } from './constants';
|
import { API_ROOT, GCOM_API_ROOT } from './constants';
|
||||||
import { mergeLocalAndRemote } from './helpers';
|
import { mergeLocalAndRemote, isLocalPluginVisible, isRemotePluginVisible } from './helpers';
|
||||||
import {
|
import {
|
||||||
PluginDetails,
|
PluginDetails,
|
||||||
Org,
|
Org,
|
||||||
@ -40,8 +40,9 @@ export async function getPluginDetails(id: string): Promise<CatalogPluginDetails
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getRemotePlugins(): Promise<RemotePlugin[]> {
|
export async function getRemotePlugins(): Promise<RemotePlugin[]> {
|
||||||
const res = await getBackendSrv().get(`${GCOM_API_ROOT}/plugins`);
|
const { items: remotePlugins }: { items: RemotePlugin[] } = await getBackendSrv().get(`${GCOM_API_ROOT}/plugins`);
|
||||||
return res.items;
|
|
||||||
|
return remotePlugins.filter(isRemotePluginVisible);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getPlugin(slug: string): Promise<PluginDetails> {
|
async function getPlugin(slug: string): Promise<PluginDetails> {
|
||||||
@ -108,8 +109,9 @@ async function getLocalPluginReadme(id: string): Promise<string> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getLocalPlugins(): Promise<LocalPlugin[]> {
|
export async function getLocalPlugins(): Promise<LocalPlugin[]> {
|
||||||
const installed = await getBackendSrv().get(`${API_ROOT}`, { embedded: 0 });
|
const localPlugins: LocalPlugin[] = await getBackendSrv().get(`${API_ROOT}`, { embedded: 0 });
|
||||||
return installed;
|
|
||||||
|
return localPlugins.filter(isLocalPluginVisible);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getOrg(slug: string): Promise<Org> {
|
async function getOrg(slug: string): Promise<Org> {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { RemotePlugin, LocalPlugin } from './types';
|
import { RemotePlugin, LocalPlugin } from './types';
|
||||||
import { getLocalPluginMock, getRemotePluginMock, getCatalogPluginMock } from './__mocks__';
|
import { getLocalPluginMock, getRemotePluginMock, getCatalogPluginMock } from './__mocks__';
|
||||||
import { PluginSignatureStatus, PluginSignatureType, PluginType } from '@grafana/data';
|
import { PluginSignatureStatus, PluginSignatureType, PluginType } from '@grafana/data';
|
||||||
|
import { config } from '@grafana/runtime';
|
||||||
import {
|
import {
|
||||||
mapToCatalogPlugin,
|
mapToCatalogPlugin,
|
||||||
mapRemoteToCatalog,
|
mapRemoteToCatalog,
|
||||||
@ -9,6 +10,8 @@ import {
|
|||||||
mergeLocalsAndRemotes,
|
mergeLocalsAndRemotes,
|
||||||
sortPlugins,
|
sortPlugins,
|
||||||
Sorters,
|
Sorters,
|
||||||
|
isLocalPluginVisible,
|
||||||
|
isRemotePluginVisible,
|
||||||
} from './helpers';
|
} from './helpers';
|
||||||
|
|
||||||
describe('Plugins/Helpers', () => {
|
describe('Plugins/Helpers', () => {
|
||||||
@ -641,4 +644,44 @@ describe('Plugins/Helpers', () => {
|
|||||||
expect(sorted.map(({ id }) => id)).toEqual(['pie-chart', 'cloud-watch', 'jira', 'zabbix', 'snowflake']);
|
expect(sorted.map(({ id }) => id)).toEqual(['pie-chart', 'cloud-watch', 'jira', 'zabbix', 'snowflake']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('isLocalPluginVisible()', () => {
|
||||||
|
test('should return TRUE if the plugin is not listed as hidden in the main Grafana configuration', () => {
|
||||||
|
config.pluginCatalogHiddenPlugins = ['akumuli-datasource'];
|
||||||
|
const plugin = getLocalPluginMock({
|
||||||
|
id: 'barchart',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(isLocalPluginVisible(plugin)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return FALSE if the plugin is listed as hidden in the main Grafana configuration', () => {
|
||||||
|
config.pluginCatalogHiddenPlugins = ['akumuli-datasource'];
|
||||||
|
const plugin = getLocalPluginMock({
|
||||||
|
id: 'akumuli-datasource',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(isLocalPluginVisible(plugin)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isRemotePluginVisible()', () => {
|
||||||
|
test('should return TRUE if the plugin is not listed as hidden in the main Grafana configuration', () => {
|
||||||
|
config.pluginCatalogHiddenPlugins = ['akumuli-datasource'];
|
||||||
|
const plugin = getRemotePluginMock({
|
||||||
|
slug: 'barchart',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(isRemotePluginVisible(plugin)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return FALSE if the plugin is listed as hidden in the main Grafana configuration', () => {
|
||||||
|
config.pluginCatalogHiddenPlugins = ['akumuli-datasource'];
|
||||||
|
const plugin = getRemotePluginMock({
|
||||||
|
slug: 'akumuli-datasource',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(isRemotePluginVisible(plugin)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -257,3 +257,13 @@ export function getLatestCompatibleVersion(versions: Version[] | undefined): Ver
|
|||||||
|
|
||||||
return latest;
|
return latest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const isLocalPluginVisible = (p: LocalPlugin) => isPluginVisible(p.id);
|
||||||
|
|
||||||
|
export const isRemotePluginVisible = (p: RemotePlugin) => isPluginVisible(p.slug);
|
||||||
|
|
||||||
|
function isPluginVisible(id: string) {
|
||||||
|
const { pluginCatalogHiddenPlugins }: { pluginCatalogHiddenPlugins: string[] } = config;
|
||||||
|
|
||||||
|
return !pluginCatalogHiddenPlugins.includes(id);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user