瀏覽代碼

refactor.

Rename externalPlugin to apiPlugin
Rename bundle to app
Move js, css, menuItem and staticRoot to be properties os App
Add "app" field to panel, datasource and api plugin models. If populated
then the plugin is only enabled if the specific app is enabled for the Org.
If app is "", then the plugin is enabled for all orgs and can't be disabled.
woodsaj 10 年之前
父節點
當前提交
c35b51a268

+ 3 - 3
pkg/api/api.go

@@ -157,8 +157,8 @@ func Register(r *macaron.Macaron) {
 
 		// PluginBundles
 		r.Group("/plugins", func() {
-			r.Get("/", wrap(GetPluginBundles))
-			r.Post("/", bind(m.UpdatePluginBundleCmd{}), wrap(UpdatePluginBundle))
+			r.Get("/", wrap(GetAppPlugins))
+			r.Post("/", bind(m.UpdateAppPluginCmd{}), wrap(UpdateAppPlugin))
 		}, reqOrgAdmin)
 
 		r.Get("/frontend/settings/", GetFrontendSettings)
@@ -196,7 +196,7 @@ func Register(r *macaron.Macaron) {
 	// rendering
 	r.Get("/render/*", reqSignedIn, RenderToPng)
 
-	InitExternalPluginRoutes(r)
+	InitApiPluginRoutes(r)
 
 	r.NotFound(NotFoundHandler)
 }

+ 7 - 7
pkg/api/externalplugin.go → pkg/api/api_plugin.go

@@ -14,9 +14,9 @@ import (
 	"github.com/grafana/grafana/pkg/util"
 )
 
-func InitExternalPluginRoutes(r *macaron.Macaron) {
-	for _, plugin := range plugins.ExternalPlugins {
-		log.Info("Plugin: Adding proxy routes for backend plugin")
+func InitApiPluginRoutes(r *macaron.Macaron) {
+	for _, plugin := range plugins.ApiPlugins {
+		log.Info("Plugin: Adding proxy routes for api plugin")
 		for _, route := range plugin.Routes {
 			url := util.JoinUrlFragments("/api/plugin-proxy/", route.Path)
 			handlers := make([]macaron.Handler, 0)
@@ -33,14 +33,14 @@ func InitExternalPluginRoutes(r *macaron.Macaron) {
 					handlers = append(handlers, middleware.RoleAuth(m.ROLE_EDITOR, m.ROLE_ADMIN))
 				}
 			}
-			handlers = append(handlers, ExternalPlugin(route.Url))
+			handlers = append(handlers, ApiPlugin(route.Url))
 			r.Route(url, route.Method, handlers...)
 			log.Info("Plugin: Adding route %s", url)
 		}
 	}
 }
 
-func ExternalPlugin(routeUrl string) macaron.Handler {
+func ApiPlugin(routeUrl string) macaron.Handler {
 	return func(c *middleware.Context) {
 		path := c.Params("*")
 
@@ -51,13 +51,13 @@ func ExternalPlugin(routeUrl string) macaron.Handler {
 			return
 		}
 		targetUrl, _ := url.Parse(routeUrl)
-		proxy := NewExternalPluginProxy(string(ctx), path, targetUrl)
+		proxy := NewApiPluginProxy(string(ctx), path, targetUrl)
 		proxy.Transport = dataProxyTransport
 		proxy.ServeHTTP(c.RW(), c.Req.Request)
 	}
 }
 
-func NewExternalPluginProxy(ctx string, proxyPath string, targetUrl *url.URL) *httputil.ReverseProxy {
+func NewApiPluginProxy(ctx string, proxyPath string, targetUrl *url.URL) *httputil.ReverseProxy {
 	director := func(req *http.Request) {
 		req.URL.Scheme = targetUrl.Scheme
 		req.URL.Host = targetUrl.Host

+ 65 - 0
pkg/api/app_plugin.go

@@ -0,0 +1,65 @@
+package api
+
+import (
+	"github.com/grafana/grafana/pkg/api/dtos"
+	"github.com/grafana/grafana/pkg/bus"
+	"github.com/grafana/grafana/pkg/middleware"
+	m "github.com/grafana/grafana/pkg/models"
+	"github.com/grafana/grafana/pkg/plugins"
+)
+
+func GetAppPlugins(c *middleware.Context) Response {
+	query := m.GetAppPluginsQuery{OrgId: c.OrgId}
+
+	if err := bus.Dispatch(&query); err != nil {
+		return ApiError(500, "Failed to list Plugin Bundles", err)
+	}
+
+	installedAppsMap := make(map[string]*dtos.AppPlugin)
+	for t, a := range plugins.Apps {
+		installedAppsMap[t] = &dtos.AppPlugin{
+			Type:     a.Type,
+			Enabled:  a.Enabled,
+			Module:   a.Module,
+			JsonData: make(map[string]interface{}),
+		}
+	}
+
+	seenApps := make(map[string]bool)
+
+	result := make([]*dtos.AppPlugin, 0)
+	for _, b := range query.Result {
+		if def, ok := installedAppsMap[b.Type]; ok {
+			result = append(result, &dtos.AppPlugin{
+				Type:     b.Type,
+				Enabled:  b.Enabled,
+				Module:   def.Module,
+				JsonData: b.JsonData,
+			})
+			seenApps[b.Type] = true
+		}
+	}
+
+	for t, a := range installedAppsMap {
+		if _, ok := seenApps[t]; !ok {
+			result = append(result, a)
+		}
+	}
+
+	return Json(200, result)
+}
+
+func UpdateAppPlugin(c *middleware.Context, cmd m.UpdateAppPluginCmd) Response {
+	cmd.OrgId = c.OrgId
+
+	if _, ok := plugins.Apps[cmd.Type]; !ok {
+		return ApiError(404, "App type not installed.", nil)
+	}
+
+	err := bus.Dispatch(&cmd)
+	if err != nil {
+		return ApiError(500, "Failed to update App Plugin", err)
+	}
+
+	return ApiSuccess("App updated")
+}

+ 5 - 4
pkg/api/datasources.go

@@ -3,6 +3,7 @@ package api
 import (
 	"github.com/grafana/grafana/pkg/api/dtos"
 	"github.com/grafana/grafana/pkg/bus"
+	//"github.com/grafana/grafana/pkg/log"
 	"github.com/grafana/grafana/pkg/middleware"
 	m "github.com/grafana/grafana/pkg/models"
 	"github.com/grafana/grafana/pkg/plugins"
@@ -114,14 +115,14 @@ func UpdateDataSource(c *middleware.Context, cmd m.UpdateDataSourceCommand) {
 }
 
 func GetDataSourcePlugins(c *middleware.Context) {
-	dsList := make(map[string]interface{})
+	dsList := make(map[string]*plugins.DataSourcePlugin)
 
-	orgBundles := m.GetPluginBundlesQuery{OrgId: c.OrgId}
-	err := bus.Dispatch(&orgBundles)
+	orgApps := m.GetAppPluginsQuery{OrgId: c.OrgId}
+	err := bus.Dispatch(&orgApps)
 	if err != nil {
 		c.JsonApiErr(500, "Failed to get org plugin Bundles", err)
 	}
-	enabledPlugins := plugins.GetEnabledPlugins(orgBundles.Result)
+	enabledPlugins := plugins.GetEnabledPlugins(orgApps.Result)
 
 	for key, value := range enabledPlugins.DataSourcePlugins {
 		if !value.BuiltIn {

+ 1 - 1
pkg/api/dtos/plugin_bundle.go → pkg/api/dtos/app_plugin.go

@@ -1,6 +1,6 @@
 package dtos
 
-type PluginBundle struct {
+type AppPlugin struct {
 	Type     string                 `json:"type"`
 	Enabled  bool                   `json:"enabled"`
 	Module   string                 `json:"module"`

+ 3 - 3
pkg/api/frontendsettings.go

@@ -29,12 +29,12 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
 	datasources := make(map[string]interface{})
 	var defaultDatasource string
 
-	orgBundles := m.GetPluginBundlesQuery{OrgId: c.OrgId}
-	err := bus.Dispatch(&orgBundles)
+	orgApps := m.GetAppPluginsQuery{OrgId: c.OrgId}
+	err := bus.Dispatch(&orgApps)
 	if err != nil {
 		return nil, err
 	}
-	enabledPlugins := plugins.GetEnabledPlugins(orgBundles.Result)
+	enabledPlugins := plugins.GetEnabledPlugins(orgApps.Result)
 
 	for _, ds := range orgDataSources {
 		url := ds.Url

+ 4 - 4
pkg/api/index.go

@@ -67,14 +67,14 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
 		})
 	}
 
-	orgBundles := m.GetPluginBundlesQuery{OrgId: c.OrgId}
-	err = bus.Dispatch(&orgBundles)
+	orgApps := m.GetAppPluginsQuery{OrgId: c.OrgId}
+	err = bus.Dispatch(&orgApps)
 	if err != nil {
 		return nil, err
 	}
-	enabledPlugins := plugins.GetEnabledPlugins(orgBundles.Result)
+	enabledPlugins := plugins.GetEnabledPlugins(orgApps.Result)
 
-	for _, plugin := range enabledPlugins.ExternalPlugins {
+	for _, plugin := range enabledPlugins.AppPlugins {
 		for _, js := range plugin.Js {
 			data.PluginJs = append(data.PluginJs, js.Module)
 		}

+ 0 - 65
pkg/api/plugin_bundle.go

@@ -1,65 +0,0 @@
-package api
-
-import (
-	"github.com/grafana/grafana/pkg/api/dtos"
-	"github.com/grafana/grafana/pkg/bus"
-	"github.com/grafana/grafana/pkg/middleware"
-	m "github.com/grafana/grafana/pkg/models"
-	"github.com/grafana/grafana/pkg/plugins"
-)
-
-func GetPluginBundles(c *middleware.Context) Response {
-	query := m.GetPluginBundlesQuery{OrgId: c.OrgId}
-
-	if err := bus.Dispatch(&query); err != nil {
-		return ApiError(500, "Failed to list Plugin Bundles", err)
-	}
-
-	installedBundlesMap := make(map[string]*dtos.PluginBundle)
-	for t, b := range plugins.Bundles {
-		installedBundlesMap[t] = &dtos.PluginBundle{
-			Type:     b.Type,
-			Enabled:  b.Enabled,
-			Module:   b.Module,
-			JsonData: make(map[string]interface{}),
-		}
-	}
-
-	seenBundles := make(map[string]bool)
-
-	result := make([]*dtos.PluginBundle, 0)
-	for _, b := range query.Result {
-		if def, ok := installedBundlesMap[b.Type]; ok {
-			result = append(result, &dtos.PluginBundle{
-				Type:     b.Type,
-				Enabled:  b.Enabled,
-				Module:   def.Module,
-				JsonData: b.JsonData,
-			})
-			seenBundles[b.Type] = true
-		}
-	}
-
-	for t, b := range installedBundlesMap {
-		if _, ok := seenBundles[t]; !ok {
-			result = append(result, b)
-		}
-	}
-
-	return Json(200, result)
-}
-
-func UpdatePluginBundle(c *middleware.Context, cmd m.UpdatePluginBundleCmd) Response {
-	cmd.OrgId = c.OrgId
-
-	if _, ok := plugins.Bundles[cmd.Type]; !ok {
-		return ApiError(404, "Bundle type not installed.", nil)
-	}
-
-	err := bus.Dispatch(&cmd)
-	if err != nil {
-		return ApiError(500, "Failed to update plugin bundle", err)
-	}
-
-	return ApiSuccess("Plugin updated")
-}

+ 4 - 4
pkg/models/plugin_bundle.go → pkg/models/app_plugin.go

@@ -2,7 +2,7 @@ package models
 
 import "time"
 
-type PluginBundle struct {
+type AppPlugin struct {
 	Id       int64
 	Type     string
 	OrgId    int64
@@ -17,7 +17,7 @@ type PluginBundle struct {
 // COMMANDS
 
 // Also acts as api DTO
-type UpdatePluginBundleCmd struct {
+type UpdateAppPluginCmd struct {
 	Type     string                 `json:"type" binding:"Required"`
 	Enabled  bool                   `json:"enabled"`
 	JsonData map[string]interface{} `json:"jsonData"`
@@ -28,7 +28,7 @@ type UpdatePluginBundleCmd struct {
 
 // ---------------------
 // QUERIES
-type GetPluginBundlesQuery struct {
+type GetAppPluginsQuery struct {
 	OrgId  int64
-	Result []*PluginBundle
+	Result []*AppPlugin
 }

+ 26 - 20
pkg/plugins/models.go

@@ -12,6 +12,7 @@ type DataSourcePlugin struct {
 	Annotations        bool                   `json:"annotations"`
 	Metrics            bool                   `json:"metrics"`
 	BuiltIn            bool                   `json:"builtIn"`
+	App                string                 `json:"app"`
 	StaticRootConfig   *StaticRootConfig      `json:"staticRoot"`
 }
 
@@ -20,6 +21,7 @@ type PanelPlugin struct {
 	Name             string            `json:"name"`
 	Module           string            `json:"module"`
 	StaticRootConfig *StaticRootConfig `json:"staticRoot"`
+	App              string            `json:"app"`
 }
 
 type StaticRootConfig struct {
@@ -27,59 +29,63 @@ type StaticRootConfig struct {
 	Path string `json:"path"`
 }
 
-type ExternalPluginRoute struct {
+type ApiPluginRoute struct {
 	Path            string          `json:"path"`
 	Method          string          `json:"method"`
 	ReqSignedIn     bool            `json:"reqSignedIn"`
 	ReqGrafanaAdmin bool            `json:"reqGrafanaAdmin"`
 	ReqRole         models.RoleType `json:"reqRole"`
 	Url             string          `json:"url"`
+	App             string          `json:"app"`
 }
 
-type ExternalPluginJs struct {
+type AppPluginJs struct {
 	Module string `json:"module"`
 }
 
-type ExternalPluginNavLink struct {
+type AppPluginNavLink struct {
 	Text    string          `json:"text"`
 	Icon    string          `json:"icon"`
 	Href    string          `json:"href"`
 	ReqRole models.RoleType `json:"reqRole"`
 }
 
-type ExternalPluginCss struct {
+type AppPluginCss struct {
 	Light string `json:"light"`
 	Dark  string `json:"dark"`
 }
 
-type ExternalPlugin struct {
-	Type             string                   `json:"type"`
-	Routes           []*ExternalPluginRoute   `json:"routes"`
-	Js               []*ExternalPluginJs      `json:"js"`
-	Css              []*ExternalPluginCss     `json:"css"`
-	MainNavLinks     []*ExternalPluginNavLink `json:"mainNavLinks"`
-	StaticRootConfig *StaticRootConfig        `json:"staticRoot"`
+type ApiPlugin struct {
+	Type   string            `json:"type"`
+	Routes []*ApiPluginRoute `json:"routes"`
+	App    string            `json:"app"`
 }
 
-type PluginBundle struct {
-	Type              string   `json:"type"`
-	Enabled           bool     `json:"enabled"`
-	PanelPlugins      []string `json:"panelPlugins"`
-	DatasourcePlugins []string `json:"datasourcePlugins"`
-	ExternalPlugins   []string `json:"externalPlugins"`
-	Module            string   `json:"module"`
+type AppPlugin struct {
+	Type              string              `json:"type"`
+	Enabled           bool                `json:"enabled"`
+	PanelPlugins      []string            `json:"panelPlugins"`
+	DatasourcePlugins []string            `json:"datasourcePlugins"`
+	ApiPlugins        []string            `json:"apiPlugins"`
+	Module            string              `json:"module"`
+	Js                []*AppPluginJs      `json:"js"`
+	Css               []*AppPluginCss     `json:"css"`
+	MainNavLinks      []*AppPluginNavLink `json:"mainNavLinks"`
+	StaticRootConfig  *StaticRootConfig   `json:"staticRoot"`
 }
 
 type EnabledPlugins struct {
 	PanelPlugins      []*PanelPlugin
 	DataSourcePlugins map[string]*DataSourcePlugin
-	ExternalPlugins   []*ExternalPlugin
+	ApiPlugins        []*ApiPlugin
+	AppPlugins        []*AppPlugin
 }
 
 func NewEnabledPlugins() EnabledPlugins {
 	return EnabledPlugins{
 		PanelPlugins:      make([]*PanelPlugin, 0),
 		DataSourcePlugins: make(map[string]*DataSourcePlugin),
-		ExternalPlugins:   make([]*ExternalPlugin, 0),
+		ApiPlugins:        make([]*ApiPlugin, 0),
+		AppPlugins:        make([]*AppPlugin, 0),
 	}
 }

+ 79 - 43
pkg/plugins/plugins.go

@@ -14,11 +14,11 @@ import (
 )
 
 var (
-	DataSources     map[string]DataSourcePlugin
-	Panels          map[string]PanelPlugin
-	ExternalPlugins map[string]ExternalPlugin
-	StaticRoutes    []*StaticRootConfig
-	Bundles         map[string]PluginBundle
+	DataSources  map[string]*DataSourcePlugin
+	Panels       map[string]*PanelPlugin
+	ApiPlugins   map[string]*ApiPlugin
+	StaticRoutes []*StaticRootConfig
+	Apps         map[string]*AppPlugin
 )
 
 type PluginScanner struct {
@@ -27,39 +27,39 @@ type PluginScanner struct {
 }
 
 func Init() error {
-	DataSources = make(map[string]DataSourcePlugin)
-	ExternalPlugins = make(map[string]ExternalPlugin)
+	DataSources = make(map[string]*DataSourcePlugin)
+	ApiPlugins = make(map[string]*ApiPlugin)
 	StaticRoutes = make([]*StaticRootConfig, 0)
-	Panels = make(map[string]PanelPlugin)
-	Bundles = make(map[string]PluginBundle)
+	Panels = make(map[string]*PanelPlugin)
+	Apps = make(map[string]*AppPlugin)
 
 	scan(path.Join(setting.StaticRootPath, "app/plugins"))
-	checkExternalPluginPaths()
+	checkPluginPaths()
 	checkDependencies()
 	return nil
 }
 
 func checkDependencies() {
-	for bundleType, bundle := range Bundles {
-		for _, reqPanel := range bundle.PanelPlugins {
+	for appType, app := range Apps {
+		for _, reqPanel := range app.PanelPlugins {
 			if _, ok := Panels[reqPanel]; !ok {
-				log.Fatal(4, "Bundle %s requires Panel type %s, but it is not present.", bundleType, reqPanel)
+				log.Fatal(4, "App %s requires Panel type %s, but it is not present.", appType, reqPanel)
 			}
 		}
-		for _, reqDataSource := range bundle.DatasourcePlugins {
+		for _, reqDataSource := range app.DatasourcePlugins {
 			if _, ok := DataSources[reqDataSource]; !ok {
-				log.Fatal(4, "Bundle %s requires DataSource type %s, but it is not present.", bundleType, reqDataSource)
+				log.Fatal(4, "App %s requires DataSource type %s, but it is not present.", appType, reqDataSource)
 			}
 		}
-		for _, reqExtPlugin := range bundle.ExternalPlugins {
-			if _, ok := ExternalPlugins[reqExtPlugin]; !ok {
-				log.Fatal(4, "Bundle %s requires DataSource type %s, but it is not present.", bundleType, reqExtPlugin)
+		for _, reqApiPlugin := range app.ApiPlugins {
+			if _, ok := ApiPlugins[reqApiPlugin]; !ok {
+				log.Fatal(4, "App %s requires ApiPlugin type %s, but it is not present.", appType, reqApiPlugin)
 			}
 		}
 	}
 }
 
-func checkExternalPluginPaths() error {
+func checkPluginPaths() error {
 	for _, section := range setting.Cfg.Sections() {
 		if strings.HasPrefix(section.Name(), "plugin.") {
 			path := section.Key("path").String()
@@ -146,7 +146,7 @@ func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error {
 			return errors.New("Did not find type property in plugin.json")
 		}
 
-		DataSources[p.Type] = p
+		DataSources[p.Type] = &p
 		addStaticRoot(p.StaticRootConfig, currentDir)
 	}
 
@@ -161,12 +161,12 @@ func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error {
 			return errors.New("Did not find type property in plugin.json")
 		}
 
-		Panels[p.Type] = p
+		Panels[p.Type] = &p
 		addStaticRoot(p.StaticRootConfig, currentDir)
 	}
 
-	if pluginType == "external" {
-		p := ExternalPlugin{}
+	if pluginType == "api" {
+		p := ApiPlugin{}
 		reader.Seek(0, 0)
 		if err := jsonParser.Decode(&p); err != nil {
 			return err
@@ -174,12 +174,11 @@ func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error {
 		if p.Type == "" {
 			return errors.New("Did not find type property in plugin.json")
 		}
-		ExternalPlugins[p.Type] = p
-		addStaticRoot(p.StaticRootConfig, currentDir)
+		ApiPlugins[p.Type] = &p
 	}
 
-	if pluginType == "bundle" {
-		p := PluginBundle{}
+	if pluginType == "app" {
+		p := AppPlugin{}
 		reader.Seek(0, 0)
 		if err := jsonParser.Decode(&p); err != nil {
 			return err
@@ -187,44 +186,81 @@ func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error {
 		if p.Type == "" {
 			return errors.New("Did not find type property in plugin.json")
 		}
-		Bundles[p.Type] = p
+		Apps[p.Type] = &p
+		addStaticRoot(p.StaticRootConfig, currentDir)
 	}
 
 	return nil
 }
 
-func GetEnabledPlugins(orgBundles []*models.PluginBundle) EnabledPlugins {
+func GetEnabledPlugins(orgApps []*models.AppPlugin) EnabledPlugins {
 	enabledPlugins := NewEnabledPlugins()
 
-	orgBundlesMap := make(map[string]*models.PluginBundle)
-	for _, orgBundle := range orgBundles {
-		orgBundlesMap[orgBundle.Type] = orgBundle
+	orgAppsMap := make(map[string]*models.AppPlugin)
+	for _, orgApp := range orgApps {
+		orgAppsMap[orgApp.Type] = orgApp
 	}
+	seenPanels := make(map[string]bool)
+	seenApi := make(map[string]bool)
 
-	for bundleType, bundle := range Bundles {
-		enabled := bundle.Enabled
-		// check if the bundle is stored in the DB.
-		if b, ok := orgBundlesMap[bundleType]; ok {
+	for appType, app := range Apps {
+		// start with enabled set to the default state listed in the json config.
+		enabled := app.Enabled
+
+		// check if the app is stored in the DB for this org and if so, use the
+		// enabled state stored there.
+		if b, ok := orgAppsMap[appType]; ok {
 			enabled = b.Enabled
 		}
 
 		if enabled {
-			for _, d := range bundle.DatasourcePlugins {
+			for _, d := range app.DatasourcePlugins {
 				if ds, ok := DataSources[d]; ok {
-					enabledPlugins.DataSourcePlugins[d] = &ds
+					enabledPlugins.DataSourcePlugins[d] = ds
 				}
 			}
-			for _, p := range bundle.PanelPlugins {
+			for _, p := range app.PanelPlugins {
 				if panel, ok := Panels[p]; ok {
-					enabledPlugins.PanelPlugins = append(enabledPlugins.PanelPlugins, &panel)
+					if _, ok := seenPanels[p]; !ok {
+						seenPanels[p] = true
+						enabledPlugins.PanelPlugins = append(enabledPlugins.PanelPlugins, panel)
+					}
 				}
 			}
-			for _, e := range bundle.ExternalPlugins {
-				if external, ok := ExternalPlugins[e]; ok {
-					enabledPlugins.ExternalPlugins = append(enabledPlugins.ExternalPlugins, &external)
+			for _, a := range app.ApiPlugins {
+				if api, ok := ApiPlugins[a]; ok {
+					if _, ok := seenApi[a]; !ok {
+						seenApi[a] = true
+						enabledPlugins.ApiPlugins = append(enabledPlugins.ApiPlugins, api)
+					}
 				}
 			}
+			enabledPlugins.AppPlugins = append(enabledPlugins.AppPlugins, app)
 		}
 	}
+
+	// add all plugins that are not part of an App.
+	for d, installedDs := range DataSources {
+		if installedDs.App == "" {
+			enabledPlugins.DataSourcePlugins[d] = installedDs
+		}
+	}
+	for p, panel := range Panels {
+		if panel.App == "" {
+			if _, ok := seenPanels[p]; !ok {
+				seenPanels[p] = true
+				enabledPlugins.PanelPlugins = append(enabledPlugins.PanelPlugins, panel)
+			}
+		}
+	}
+	for a, api := range ApiPlugins {
+		if api.App == "" {
+			if _, ok := seenApi[a]; !ok {
+				seenApi[a] = true
+				enabledPlugins.ApiPlugins = append(enabledPlugins.ApiPlugins, api)
+			}
+		}
+	}
+
 	return enabledPlugins
 }

+ 12 - 12
pkg/services/sqlstore/plugin_bundle.go → pkg/services/sqlstore/app_plugin.go

@@ -8,25 +8,25 @@ import (
 )
 
 func init() {
-	bus.AddHandler("sql", GetPluginBundles)
-	bus.AddHandler("sql", UpdatePluginBundle)
+	bus.AddHandler("sql", GetAppPlugins)
+	bus.AddHandler("sql", UpdateAppPlugin)
 }
 
-func GetPluginBundles(query *m.GetPluginBundlesQuery) error {
+func GetAppPlugins(query *m.GetAppPluginsQuery) error {
 	sess := x.Where("org_id=?", query.OrgId)
 
-	query.Result = make([]*m.PluginBundle, 0)
+	query.Result = make([]*m.AppPlugin, 0)
 	return sess.Find(&query.Result)
 }
 
-func UpdatePluginBundle(cmd *m.UpdatePluginBundleCmd) error {
+func UpdateAppPlugin(cmd *m.UpdateAppPluginCmd) error {
 	return inTransaction2(func(sess *session) error {
-		var bundle m.PluginBundle
+		var app m.AppPlugin
 
-		exists, err := sess.Where("org_id=? and type=?", cmd.OrgId, cmd.Type).Get(&bundle)
+		exists, err := sess.Where("org_id=? and type=?", cmd.OrgId, cmd.Type).Get(&app)
 		sess.UseBool("enabled")
 		if !exists {
-			bundle = m.PluginBundle{
+			app = m.AppPlugin{
 				Type:     cmd.Type,
 				OrgId:    cmd.OrgId,
 				Enabled:  cmd.Enabled,
@@ -34,12 +34,12 @@ func UpdatePluginBundle(cmd *m.UpdatePluginBundleCmd) error {
 				Created:  time.Now(),
 				Updated:  time.Now(),
 			}
-			_, err = sess.Insert(&bundle)
+			_, err = sess.Insert(&app)
 			return err
 		} else {
-			bundle.Enabled = cmd.Enabled
-			bundle.JsonData = cmd.JsonData
-			_, err = sess.Id(bundle.Id).Update(&bundle)
+			app.Enabled = cmd.Enabled
+			app.JsonData = cmd.JsonData
+			_, err = sess.Id(app.Id).Update(&app)
 			return err
 		}
 	})

+ 5 - 5
pkg/services/sqlstore/migrations/plugin_bundle.go → pkg/services/sqlstore/migrations/app_plugin.go

@@ -2,10 +2,10 @@ package migrations
 
 import . "github.com/grafana/grafana/pkg/services/sqlstore/migrator"
 
-func addPluginBundleMigration(mg *Migrator) {
+func addAppPluginMigration(mg *Migrator) {
 
-	var pluginBundleV1 = Table{
-		Name: "plugin_bundle",
+	var appPluginV1 = Table{
+		Name: "app_plugin",
 		Columns: []*Column{
 			{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
 			{Name: "org_id", Type: DB_BigInt, Nullable: true},
@@ -19,8 +19,8 @@ func addPluginBundleMigration(mg *Migrator) {
 			{Cols: []string{"org_id", "type"}, Type: UniqueIndex},
 		},
 	}
-	mg.AddMigration("create plugin_bundle table v1", NewAddTableMigration(pluginBundleV1))
+	mg.AddMigration("create app_plugin table v1", NewAddTableMigration(appPluginV1))
 
 	//-------  indexes ------------------
-	addTableIndicesMigrations(mg, "v1", pluginBundleV1)
+	addTableIndicesMigrations(mg, "v1", appPluginV1)
 }

+ 1 - 1
pkg/services/sqlstore/migrations/migrations.go

@@ -18,7 +18,7 @@ func AddMigrations(mg *Migrator) {
 	addApiKeyMigrations(mg)
 	addDashboardSnapshotMigrations(mg)
 	addQuotaMigration(mg)
-	addPluginBundleMigration(mg)
+	addAppPluginMigration(mg)
 }
 
 func addMigrationLogMigrations(mg *Migrator) {

+ 0 - 9
public/app/plugins/plugin.json

@@ -1,9 +0,0 @@
-{
-  "pluginType": "bundle",
-  "type": "core",
-  "module": "",
-  "enabled": true,
-  "panelPlugins": ["graph", "singlestat", "text", "dashlist", "table"],
-  "datasourcePlugins": ["mixed", "grafana", "graphite", "cloudwatch", "elasticsearch", "influxdb", "influxdb_08", "kairosdb", "opentsdb", "prometheus"],
-  "externalPlugins": []
-}