mirror of https://github.com/grafana/grafana.git
				
				
				
			Plugins: Show that Secrets Manager Plugin is active in the UI (#50953)
* add special handling on the plugin gathering side to check whether secrets manager plugins are enabled or not * show disabled badge in front end if the plugin is not enabled * Only show error in disabled badge hover if one is present (otherwise it shows "undefined") * refactor to make use of fields already available in the DTO * fix typo * if there is no error returned for the plugin, just show 'disabled' * fix typo * Update public/app/features/plugins/admin/components/Badges/PluginDisabledBadge.tsx Co-authored-by: Levente Balogh <balogh.levente.hu@gmail.com> * Update frontendsettings.go add clarifying comment * fix unit test * rework task to use new frontend property combined with plugin type to determine if the plugin should be disabled * Update helpers.test.ts revert test change * fix unit test * bogus commit to trigger precommit * undo commit * run precommit manually Co-authored-by: Levente Balogh <balogh.levente.hu@gmail.com>
This commit is contained in:
		
							parent
							
								
									b30680d33c
								
							
						
					
					
						commit
						7ef21662f9
					
				|  | @ -684,7 +684,7 @@ exports[`better eslint`] = { | |||
|     "packages/grafana-data/src/types/app.ts:2148970488": [ | ||||
|       [75, 48, 3, "Unexpected any. Specify a different type.", "193409811"] | ||||
|     ], | ||||
|     "packages/grafana-data/src/types/config.ts:2312759525": [ | ||||
|     "packages/grafana-data/src/types/config.ts:21897200": [ | ||||
|       [185, 11, 3, "Unexpected any. Specify a different type.", "193409811"], | ||||
|       [199, 16, 3, "Unexpected any. Specify a different type.", "193409811"] | ||||
|     ], | ||||
|  | @ -819,10 +819,10 @@ exports[`better eslint`] = { | |||
|       [192, 52, 3, "Unexpected any. Specify a different type.", "193409811"], | ||||
|       [192, 72, 3, "Unexpected any. Specify a different type.", "193409811"] | ||||
|     ], | ||||
|     "packages/grafana-data/src/types/plugin.ts:695757440": [ | ||||
|       [173, 22, 3, "Unexpected any. Specify a different type.", "193409811"], | ||||
|       [190, 29, 3, "Unexpected any. Specify a different type.", "193409811"], | ||||
|       [196, 16, 7, "Do not use any type assertions.", "3399135973"] | ||||
|     "packages/grafana-data/src/types/plugin.ts:2556367579": [ | ||||
|       [174, 22, 3, "Unexpected any. Specify a different type.", "193409811"], | ||||
|       [191, 29, 3, "Unexpected any. Specify a different type.", "193409811"], | ||||
|       [197, 16, 7, "Do not use any type assertions.", "3399135973"] | ||||
|     ], | ||||
|     "packages/grafana-data/src/types/query.ts:4277928644": [ | ||||
|       [100, 14, 3, "Unexpected any. Specify a different type.", "193409811"], | ||||
|  | @ -1211,12 +1211,12 @@ exports[`better eslint`] = { | |||
|       [31, 49, 3, "Unexpected any. Specify a different type.", "193409811"], | ||||
|       [31, 73, 3, "Unexpected any. Specify a different type.", "193409811"] | ||||
|     ], | ||||
|     "packages/grafana-runtime/src/config.ts:4181107692": [ | ||||
|     "packages/grafana-runtime/src/config.ts:2639113063": [ | ||||
|       [66, 11, 3, "Unexpected any. Specify a different type.", "193409811"], | ||||
|       [75, 29, 17, "Do not use any type assertions.", "4278379396"], | ||||
|       [106, 16, 3, "Unexpected any. Specify a different type.", "193409811"], | ||||
|       [191, 18, 13, "Do not use any type assertions.", "538937261"], | ||||
|       [191, 28, 3, "Unexpected any. Specify a different type.", "193409811"] | ||||
|       [107, 16, 3, "Unexpected any. Specify a different type.", "193409811"], | ||||
|       [192, 18, 13, "Do not use any type assertions.", "538937261"], | ||||
|       [192, 28, 3, "Unexpected any. Specify a different type.", "193409811"] | ||||
|     ], | ||||
|     "packages/grafana-runtime/src/services/AngularLoader.ts:3455177907": [ | ||||
|       [45, 14, 3, "Unexpected any. Specify a different type.", "193409811"], | ||||
|  | @ -6439,8 +6439,8 @@ exports[`better eslint`] = { | |||
|       [135, 28, 52, "Do not use any type assertions.", "963107955"], | ||||
|       [177, 42, 56, "Do not use any type assertions.", "2128061450"] | ||||
|     ], | ||||
|     "public/app/features/plugins/admin/helpers.ts:2721255382": [ | ||||
|       [215, 5, 45, "Do not use any type assertions.", "2083447632"] | ||||
|     "public/app/features/plugins/admin/helpers.ts:1783021315": [ | ||||
|       [216, 5, 45, "Do not use any type assertions.", "2083447632"] | ||||
|     ], | ||||
|     "public/app/features/plugins/admin/hooks/useHistory.tsx:3882862818": [ | ||||
|       [4, 22, 3, "Unexpected any. Specify a different type.", "193409811"] | ||||
|  | @ -6475,8 +6475,8 @@ exports[`better eslint`] = { | |||
|     "public/app/features/plugins/admin/state/selectors.ts:345773501": [ | ||||
|       [62, 23, 27, "Do not use any type assertions.", "1285719276"] | ||||
|     ], | ||||
|     "public/app/features/plugins/admin/types.ts:1638901340": [ | ||||
|       [238, 10, 3, "Unexpected any. Specify a different type.", "193409811"] | ||||
|     "public/app/features/plugins/admin/types.ts:804526334": [ | ||||
|       [239, 10, 3, "Unexpected any. Specify a different type.", "193409811"] | ||||
|     ], | ||||
|     "public/app/features/plugins/built_in_plugins.ts:2973583336": [ | ||||
|       [93, 22, 3, "Unexpected any. Specify a different type.", "193409811"] | ||||
|  |  | |||
|  | @ -203,6 +203,7 @@ export interface GrafanaConfig { | |||
|   unifiedAlertingEnabled: boolean; | ||||
|   angularSupportEnabled: boolean; | ||||
|   feedbackLinksEnabled: boolean; | ||||
|   secretsManagerPluginEnabled: boolean; | ||||
|   googleAnalyticsId: string | undefined; | ||||
|   rudderstackWriteKey: string | undefined; | ||||
|   rudderstackDataPlaneUrl: string | undefined; | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ export enum PluginType { | |||
|   datasource = 'datasource', | ||||
|   app = 'app', | ||||
|   renderer = 'renderer', | ||||
|   secretsmanager = 'secretsmanager', | ||||
| } | ||||
| 
 | ||||
| /** Describes status of {@link https://grafana.com/docs/grafana/latest/plugins/plugin-signatures/ | plugin signature} */ | ||||
|  |  | |||
|  | @ -83,6 +83,7 @@ export class GrafanaBootConfig implements GrafanaConfig { | |||
|     thumbnailsExist: boolean; | ||||
|   } = { systemRequirements: { met: false, requiredImageRendererPluginVersion: '' }, thumbnailsExist: false }; | ||||
|   rendererVersion = ''; | ||||
|   secretsManagerPluginEnabled = false; | ||||
|   http2Enabled = false; | ||||
|   dateFormats?: SystemDateFormatSettings; | ||||
|   sentry = { | ||||
|  |  | |||
|  | @ -152,6 +152,7 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i | |||
| 		"featureToggles":                   hs.Features.GetEnabled(c.Req.Context()), | ||||
| 		"rendererAvailable":                hs.RenderService.IsAvailable(), | ||||
| 		"rendererVersion":                  hs.RenderService.Version(), | ||||
| 		"secretsManagerPluginEnabled":      hs.remoteSecretsCheck.ShouldUseRemoteSecretsPlugin(), | ||||
| 		"http2Enabled":                     hs.Cfg.Protocol == setting.HTTP2Scheme, | ||||
| 		"sentry":                           hs.Cfg.Sentry, | ||||
| 		"grafanaJavascriptAgent":           hs.Cfg.GrafanaJavascriptAgent, | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ import ( | |||
| 	pluginSettings "github.com/grafana/grafana/pkg/services/pluginsettings/service" | ||||
| 	"github.com/grafana/grafana/pkg/services/rendering" | ||||
| 	"github.com/grafana/grafana/pkg/services/secrets/fakes" | ||||
| 	"github.com/grafana/grafana/pkg/services/secrets/kvstore" | ||||
| 	secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" | ||||
| 	"github.com/grafana/grafana/pkg/services/sqlstore" | ||||
| 	"github.com/grafana/grafana/pkg/services/updatechecker" | ||||
|  | @ -55,6 +56,7 @@ func setupTestEnvironment(t *testing.T, cfg *setting.Cfg, features *featuremgmt. | |||
| 		grafanaUpdateChecker: &updatechecker.GrafanaService{}, | ||||
| 		AccessControl:        accesscontrolmock.New().WithDisabled(), | ||||
| 		PluginSettings:       pluginSettings.ProvideService(sqlStore, secretsService), | ||||
| 		remoteSecretsCheck:   &kvstore.OSSRemoteSecretsPluginCheck{}, | ||||
| 	} | ||||
| 
 | ||||
| 	m := web.New() | ||||
|  |  | |||
|  | @ -69,6 +69,7 @@ import ( | |||
| 	"github.com/grafana/grafana/pkg/services/search" | ||||
| 	"github.com/grafana/grafana/pkg/services/searchusers" | ||||
| 	"github.com/grafana/grafana/pkg/services/secrets" | ||||
| 	secretsKV "github.com/grafana/grafana/pkg/services/secrets/kvstore" | ||||
| 	"github.com/grafana/grafana/pkg/services/serviceaccounts" | ||||
| 	"github.com/grafana/grafana/pkg/services/shorturls" | ||||
| 	"github.com/grafana/grafana/pkg/services/sqlstore" | ||||
|  | @ -132,6 +133,7 @@ type HTTPServer struct { | |||
| 	Listener                     net.Listener | ||||
| 	EncryptionService            encryption.Internal | ||||
| 	SecretsService               secrets.Service | ||||
| 	remoteSecretsCheck           secretsKV.UseRemoteSecretsPluginCheck | ||||
| 	DataSourcesService           datasources.DataSourceService | ||||
| 	cleanUpService               *cleanup.CleanUpService | ||||
| 	tracer                       tracing.Tracer | ||||
|  | @ -199,7 +201,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi | |||
| 	teamsPermissionsService accesscontrol.TeamPermissionsService, folderPermissionsService accesscontrol.FolderPermissionsService, | ||||
| 	dashboardPermissionsService accesscontrol.DashboardPermissionsService, dashboardVersionService dashver.Service, | ||||
| 	starService star.Service, csrfService csrf.Service, coremodelRegistry *registry.Generic, coremodelStaticRegistry *registry.Static, | ||||
| 	kvStore kvstore.KVStore, | ||||
| 	kvStore kvstore.KVStore, remoteSecretsCheck secretsKV.UseRemoteSecretsPluginCheck, | ||||
| ) (*HTTPServer, error) { | ||||
| 	web.Env = cfg.Env | ||||
| 	m := web.New() | ||||
|  | @ -254,6 +256,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi | |||
| 		SocialService:                socialService, | ||||
| 		EncryptionService:            encryptionService, | ||||
| 		SecretsService:               secretsService, | ||||
| 		remoteSecretsCheck:           remoteSecretsCheck, | ||||
| 		DataSourcesService:           dataSourcesService, | ||||
| 		searchUsersService:           searchUsersService, | ||||
| 		ldapGroups:                   ldapGroups, | ||||
|  |  | |||
|  | @ -81,6 +81,10 @@ func (p PluginDTO) IsCorePlugin() bool { | |||
| 	return p.Class == Core | ||||
| } | ||||
| 
 | ||||
| func (p PluginDTO) IsSecretsManager() bool { | ||||
| 	return p.JSONData.Type == SecretsManager | ||||
| } | ||||
| 
 | ||||
| func (p PluginDTO) IncludedInSignature(file string) bool { | ||||
| 	// permit Core plugin files
 | ||||
| 	if p.IsCorePlugin() { | ||||
|  |  | |||
|  | @ -18,7 +18,10 @@ function errorCodeToTooltip(error?: PluginErrorCode): string | undefined { | |||
|       return 'Plugin disabled due to invalid plugin signature'; | ||||
|     case PluginErrorCode.missingSignature: | ||||
|       return 'Plugin disabled due to missing plugin signature'; | ||||
|     case null: | ||||
|     case undefined: | ||||
|       return 'Plugin disabled'; | ||||
|     default: | ||||
|       return `Plugin disabled due to unkown error: ${error}`; | ||||
|       return `Plugin disabled due to unknown error${error ? `: ${error}` : ''}`; | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -69,7 +69,7 @@ function renderDescriptionFromError(error?: PluginErrorCode): ReactElement { | |||
|     default: | ||||
|       return ( | ||||
|         <p> | ||||
|           We failed to run this plugin due to an unkown reason and have therefor disabled it. We recommend you to | ||||
|           We failed to run this plugin due to an unkown reason and have therefore disabled it. We recommend you to | ||||
|           reinstall the plugin to make sure you are running a working version of this plugin. | ||||
|         </p> | ||||
|       ); | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import { PluginSignatureStatus, dateTimeParse, PluginError, PluginErrorCode } from '@grafana/data'; | ||||
| import { PluginSignatureStatus, dateTimeParse, PluginError, PluginType, PluginErrorCode } from '@grafana/data'; | ||||
| import { config } from '@grafana/runtime'; | ||||
| import { Settings } from 'app/core/config'; | ||||
| import { getBackendSrv } from 'app/core/services/backend_srv'; | ||||
|  | @ -61,7 +61,7 @@ export function mapRemoteToCatalog(plugin: RemotePlugin, error?: PluginError): C | |||
|     status, | ||||
|   } = plugin; | ||||
| 
 | ||||
|   const isDisabled = !!error; | ||||
|   const isDisabled = !!error || isDisabledSecretsPlugin(typeCode); | ||||
|   return { | ||||
|     description, | ||||
|     downloads, | ||||
|  | @ -103,6 +103,7 @@ export function mapLocalToCatalog(plugin: LocalPlugin, error?: PluginError): Cat | |||
|     hasUpdate, | ||||
|   } = plugin; | ||||
| 
 | ||||
|   const isDisabled = !!error || isDisabledSecretsPlugin(type); | ||||
|   return { | ||||
|     description, | ||||
|     downloads: 0, | ||||
|  | @ -119,7 +120,7 @@ export function mapLocalToCatalog(plugin: LocalPlugin, error?: PluginError): Cat | |||
|     installedVersion: version, | ||||
|     hasUpdate, | ||||
|     isInstalled: true, | ||||
|     isDisabled: !!error, | ||||
|     isDisabled: isDisabled, | ||||
|     isCore: signature === 'internal', | ||||
|     isPublished: false, | ||||
|     isDev: Boolean(dev), | ||||
|  | @ -134,7 +135,7 @@ export function mapToCatalogPlugin(local?: LocalPlugin, remote?: RemotePlugin, e | |||
|   const installedVersion = local?.info.version; | ||||
|   const id = remote?.slug || local?.id || ''; | ||||
|   const type = local?.type || remote?.typeCode; | ||||
|   const isDisabled = !!error; | ||||
|   const isDisabled = !!error || isDisabledSecretsPlugin(type); | ||||
| 
 | ||||
|   let logos = { | ||||
|     small: `/public/img/icn-${type}.svg`, | ||||
|  | @ -274,6 +275,10 @@ function isPluginVisible(id: string) { | |||
|   return !pluginCatalogHiddenPlugins.includes(id); | ||||
| } | ||||
| 
 | ||||
| function isDisabledSecretsPlugin(type?: PluginType): boolean { | ||||
|   return type === PluginType.secretsmanager && !config.secretsManagerPluginEnabled; | ||||
| } | ||||
| 
 | ||||
| export function isLocalCorePlugin(local?: LocalPlugin): boolean { | ||||
|   return Boolean(local?.signature === 'internal'); | ||||
| } | ||||
|  |  | |||
|  | @ -31,6 +31,7 @@ export enum PluginIconName { | |||
|   datasource = 'database', | ||||
|   panel = 'credit-card', | ||||
|   renderer = 'capture', | ||||
|   secretsmanager = 'key-skeleton-alt', | ||||
| } | ||||
| 
 | ||||
| export interface CatalogPlugin { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue