diff --git a/pkg/api/datasources.go b/pkg/api/datasources.go index 38a4004c241..15a13ee60c7 100644 --- a/pkg/api/datasources.go +++ b/pkg/api/datasources.go @@ -117,7 +117,7 @@ func GetDataSourcePlugins(c *middleware.Context) { dsList := make(map[string]interface{}) for key, value := range plugins.DataSources { - if value.(map[string]interface{})["builtIn"] == nil { + if !value.BuiltIn { dsList[key] = value } } diff --git a/pkg/cmd/web.go b/pkg/cmd/web.go index 69843b6b095..9ab2df82921 100644 --- a/pkg/cmd/web.go +++ b/pkg/cmd/web.go @@ -28,12 +28,13 @@ func newMacaron() *macaron.Macaron { m.Use(middleware.Gziper()) } - mapStatic(m, "", "public") - mapStatic(m, "app", "app") - mapStatic(m, "css", "css") - mapStatic(m, "img", "img") - mapStatic(m, "fonts", "fonts") - mapStatic(m, "robots.txt", "robots.txt") + mapStatic(m, setting.StaticRootPath, "", "public") + mapStatic(m, setting.StaticRootPath, "app", "app") + mapStatic(m, setting.StaticRootPath, "css", "css") + mapStatic(m, setting.StaticRootPath, "img", "img") + mapStatic(m, setting.StaticRootPath, "fonts", "fonts") + mapStatic(m, setting.StaticRootPath, "robots.txt", "robots.txt") + mapStatic(m, setting.DataPath, "plugins", "_plugins") m.Use(macaron.Renderer(macaron.RenderOptions{ Directory: path.Join(setting.StaticRootPath, "views"), @@ -51,7 +52,7 @@ func newMacaron() *macaron.Macaron { return m } -func mapStatic(m *macaron.Macaron, dir string, prefix string) { +func mapStatic(m *macaron.Macaron, rootDir string, dir string, prefix string) { headers := func(c *macaron.Context) { c.Resp.Header().Set("Cache-Control", "public, max-age=3600") } @@ -63,7 +64,7 @@ func mapStatic(m *macaron.Macaron, dir string, prefix string) { } m.Use(httpstatic.Static( - path.Join(setting.StaticRootPath, dir), + path.Join(rootDir, dir), httpstatic.StaticOptions{ SkipLogging: true, Prefix: prefix, diff --git a/pkg/plugins/models.go b/pkg/plugins/models.go new file mode 100644 index 00000000000..fe294d9b576 --- /dev/null +++ b/pkg/plugins/models.go @@ -0,0 +1,50 @@ +package plugins + +import "github.com/grafana/grafana/pkg/models" + +type DataSourcePlugin struct { + Type string `json:"type"` + Name string `json:"name"` + ServiceName string `json:"serviceName"` + Module string `json:"module"` + Partials map[string]interface{} `json:"partials"` + DefaultMatchFormat string `json:"defaultMatchFormat"` + Annotations bool `json:"annotations"` + Metrics bool `json:"metrics"` + BuiltIn bool `json:"builtIn"` +} + +type ExternalPluginRoute struct { + Path string `json:"path"` + Method string `json:"method"` + ReqSignedIn bool `json:"req_signed_in"` + ReqGrafanaAdmin bool `json:"req_grafana_admin"` + ReqRole models.RoleType `json:"req_role"` + Url string `json:"url"` +} + +type ExternalPluginJs struct { + Src string `json:"src"` +} + +type ExternalPluginMenuItem struct { + Text string `json:"text"` + Icon string `json:"icon"` + Href string `json:"href"` +} + +type ExternalPluginCss struct { + Href string `json:"href"` +} + +type ExternalPluginSettings struct { + Routes []*ExternalPluginRoute `json:"routes"` + Js []*ExternalPluginJs `json:"js"` + Css []*ExternalPluginCss `json:"css"` + MenuItems []*ExternalPluginMenuItem `json:"menu_items"` +} + +type ExternalPlugin struct { + PluginType string `json:"pluginType"` + Settings ExternalPluginSettings `json:"settings"` +} diff --git a/pkg/plugins/plugins.go b/pkg/plugins/plugins.go index 323c5e87aaa..e823964e485 100644 --- a/pkg/plugins/plugins.go +++ b/pkg/plugins/plugins.go @@ -8,52 +8,11 @@ import ( "path/filepath" "github.com/grafana/grafana/pkg/log" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/setting" ) -type PluginMeta struct { - Type string `json:"type"` - Name string `json:"name"` -} - -type ExternalPluginRoute struct { - Path string `json:"path"` - Method string `json:"method"` - ReqSignedIn bool `json:"req_signed_in"` - ReqGrafanaAdmin bool `json:"req_grafana_admin"` - ReqRole models.RoleType `json:"req_role"` - Url string `json:"url"` -} - -type ExternalPluginJs struct { - Src string `json:"src"` -} - -type ExternalPluginMenuItem struct { - Text string `json:"text"` - Icon string `json:"icon"` - Href string `json:"href"` -} - -type ExternalPluginCss struct { - Href string `json:"href"` -} - -type ExternalPluginSettings struct { - Routes []*ExternalPluginRoute `json:"routes"` - Js []*ExternalPluginJs `json:"js"` - Css []*ExternalPluginCss `json:"css"` - MenuItems []*ExternalPluginMenuItem `json:"menu_items"` -} - -type ExternalPlugin struct { - PluginType string `json:"pluginType"` - Settings ExternalPluginSettings `json:"settings"` -} - var ( - DataSources map[string]interface{} + DataSources map[string]DataSourcePlugin ExternalPlugins []ExternalPlugin ) @@ -63,13 +22,14 @@ type PluginScanner struct { } func Init() { + DataSources = make(map[string]DataSourcePlugin) + ExternalPlugins = make([]ExternalPlugin, 0) + scan(path.Join(setting.StaticRootPath, "app/plugins")) + scan(path.Join(setting.DataPath, "plugins")) } func scan(pluginDir string) error { - DataSources = make(map[string]interface{}) - ExternalPlugins = make([]ExternalPlugin, 0) - scanner := &PluginScanner{ pluginPath: pluginDir, } @@ -125,12 +85,19 @@ func (scanner *PluginScanner) loadPluginJson(path string) error { } if pluginType == "datasource" { - datasourceType, exists := pluginJson["type"] - if !exists { + p := DataSourcePlugin{} + reader.Seek(0, 0) + if err := jsonParser.Decode(&p); err != nil { + return err + } + + if p.Type == "" { return errors.New("Did not find type property in plugin.json") } - DataSources[datasourceType.(string)] = pluginJson + + DataSources[p.Type] = p } + if pluginType == "externalPlugin" { p := ExternalPlugin{} reader.Seek(0, 0)