Commit 69daede5 by Torkel Ödegaard

feat(external plugins): worked on supporting external plugins better

parent 65a7fa32
...@@ -2,14 +2,15 @@ package api ...@@ -2,14 +2,15 @@ package api
import ( import (
"encoding/json" "encoding/json"
"net/http"
"net/http/httputil"
"net/url"
"github.com/Unknwon/macaron" "github.com/Unknwon/macaron"
"github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/middleware" "github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/util" "github.com/grafana/grafana/pkg/util"
"net/http"
"net/http/httputil"
"net/url"
) )
func InitExternalPluginRoutes(r *macaron.Macaron) { func InitExternalPluginRoutes(r *macaron.Macaron) {
...@@ -31,10 +32,10 @@ func InitExternalPluginRoutes(r *macaron.Macaron) { ...@@ -31,10 +32,10 @@ func InitExternalPluginRoutes(r *macaron.Macaron) {
} }
*/ */
for _, plugin := range plugins.ExternalPlugins { for _, plugin := range plugins.ExternalPlugins {
log.Info("adding routes for external plugin") log.Info("Plugin: Adding proxy routes for backend plugin")
for _, route := range plugin.Settings.Routes { for _, route := range plugin.Routes {
log.Info("adding route %s /plugins%s", route.Method, route.Path) log.Info("Plugin: Adding route %s /api/plugin-proxy/%s", route.Method, route.Path)
r.Route(util.JoinUrlFragments("/plugins/", route.Path), route.Method, ExternalPlugin(route.Url)) r.Route(util.JoinUrlFragments("/api/plugin-proxy/", route.Path), route.Method, ExternalPlugin(route.Url))
} }
} }
} }
......
...@@ -57,16 +57,15 @@ func setIndexViewData(c *middleware.Context) error { ...@@ -57,16 +57,15 @@ func setIndexViewData(c *middleware.Context) error {
externalPluginCss := make([]string, 0) externalPluginCss := make([]string, 0)
externalPluginMenu := make([]*plugins.ExternalPluginMenuItem, 0) externalPluginMenu := make([]*plugins.ExternalPluginMenuItem, 0)
for _, plugin := range plugins.ExternalPlugins { for _, plugin := range plugins.ExternalPlugins {
for _, js := range plugin.Settings.Js { for _, js := range plugin.Js {
externalPluginJs = append(externalPluginJs, js.Src) externalPluginJs = append(externalPluginJs, js.Module)
} }
for _, css := range plugin.Settings.Css { for _, css := range plugin.Css {
externalPluginCss = append(externalPluginCss, css.Href) externalPluginCss = append(externalPluginCss, css.Href)
} }
for _, item := range plugin.Settings.MenuItems { for _, item := range plugin.MenuItems {
externalPluginMenu = append(externalPluginMenu, item) externalPluginMenu = append(externalPluginMenu, item)
} }
} }
c.Data["ExternalPluginJs"] = externalPluginJs c.Data["ExternalPluginJs"] = externalPluginJs
c.Data["ExternalPluginCss"] = externalPluginCss c.Data["ExternalPluginCss"] = externalPluginCss
......
...@@ -29,6 +29,12 @@ func newMacaron() *macaron.Macaron { ...@@ -29,6 +29,12 @@ func newMacaron() *macaron.Macaron {
m.Use(middleware.Gziper()) m.Use(middleware.Gziper())
} }
for _, route := range plugins.StaticRoutes {
pluginRoute := path.Join("/public/plugins/", route.Url)
log.Info("Plugin: Adding static route %s -> %s", pluginRoute, route.Path)
mapStatic(m, route.Path, "", pluginRoute)
}
mapStatic(m, setting.StaticRootPath, "", "public") mapStatic(m, setting.StaticRootPath, "", "public")
mapStatic(m, setting.StaticRootPath, "app", "app") mapStatic(m, setting.StaticRootPath, "app", "app")
mapStatic(m, setting.StaticRootPath, "css", "css") mapStatic(m, setting.StaticRootPath, "css", "css")
...@@ -36,11 +42,6 @@ func newMacaron() *macaron.Macaron { ...@@ -36,11 +42,6 @@ func newMacaron() *macaron.Macaron {
mapStatic(m, setting.StaticRootPath, "fonts", "fonts") mapStatic(m, setting.StaticRootPath, "fonts", "fonts")
mapStatic(m, setting.StaticRootPath, "robots.txt", "robots.txt") mapStatic(m, setting.StaticRootPath, "robots.txt", "robots.txt")
for _, route := range plugins.StaticRoutes {
log.Info("Adding plugin static route %s -> %s", route.Url, route.Path)
mapStatic(m, route.Path, "", route.Url)
}
m.Use(macaron.Renderer(macaron.RenderOptions{ m.Use(macaron.Renderer(macaron.RenderOptions{
Directory: path.Join(setting.StaticRootPath, "views"), Directory: path.Join(setting.StaticRootPath, "views"),
IndentJSON: macaron.Env != macaron.PROD, IndentJSON: macaron.Env != macaron.PROD,
......
...@@ -16,22 +16,21 @@ type DataSourcePlugin struct { ...@@ -16,22 +16,21 @@ type DataSourcePlugin struct {
} }
type StaticRootConfig struct { type StaticRootConfig struct {
Url string `json:"url"` Url string `json:"url"`
Path string `json:"path"` Path string `json:"path"`
PluginRoot string `json:"-"`
} }
type ExternalPluginRoute struct { type ExternalPluginRoute struct {
Path string `json:"path"` Path string `json:"path"`
Method string `json:"method"` Method string `json:"method"`
ReqSignedIn bool `json:"req_signed_in"` ReqSignedIn bool `json:"reqSignedIn"`
ReqGrafanaAdmin bool `json:"req_grafana_admin"` ReqGrafanaAdmin bool `json:"reqGrafanaAdmin"`
ReqRole models.RoleType `json:"req_role"` ReqRole models.RoleType `json:"reqRole"`
Url string `json:"url"` Url string `json:"url"`
} }
type ExternalPluginJs struct { type ExternalPluginJs struct {
Src string `json:"src"` Module string `json:"module"`
} }
type ExternalPluginMenuItem struct { type ExternalPluginMenuItem struct {
...@@ -44,14 +43,10 @@ type ExternalPluginCss struct { ...@@ -44,14 +43,10 @@ type ExternalPluginCss struct {
Href string `json:"href"` 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 { type ExternalPlugin struct {
PluginType string `json:"pluginType"` Routes []*ExternalPluginRoute `json:"routes"`
Settings ExternalPluginSettings `json:"settings"` Js []*ExternalPluginJs `json:"js"`
Css []*ExternalPluginCss `json:"css"`
MenuItems []*ExternalPluginMenuItem `json:"menuItems"`
StaticRootConfig *StaticRootConfig `json:"staticRoot"`
} }
...@@ -38,7 +38,7 @@ func checkExternalPluginPaths() error { ...@@ -38,7 +38,7 @@ func checkExternalPluginPaths() error {
if strings.HasPrefix(section.Name(), "plugin.") { if strings.HasPrefix(section.Name(), "plugin.") {
path := section.Key("path").String() path := section.Key("path").String()
if path != "" { if path != "" {
log.Info("Plugin: scaning specific dir %s", path) log.Info("Plugin: Scaning dir %s", path)
scan(path) scan(path)
} }
} }
...@@ -81,6 +81,13 @@ func (scanner *PluginScanner) walker(currentPath string, f os.FileInfo, err erro ...@@ -81,6 +81,13 @@ func (scanner *PluginScanner) walker(currentPath string, f os.FileInfo, err erro
return nil return nil
} }
func addStaticRoot(staticRootConfig *StaticRootConfig, currentDir string) {
if staticRootConfig != nil {
staticRootConfig.Path = path.Join(currentDir, staticRootConfig.Path)
StaticRoutes = append(StaticRoutes, staticRootConfig)
}
}
func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error { func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error {
currentDir := filepath.Dir(pluginJsonFilePath) currentDir := filepath.Dir(pluginJsonFilePath)
reader, err := os.Open(pluginJsonFilePath) reader, err := os.Open(pluginJsonFilePath)
...@@ -114,20 +121,17 @@ func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error { ...@@ -114,20 +121,17 @@ func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error {
} }
DataSources[p.Type] = p DataSources[p.Type] = p
addStaticRoot(p.StaticRootConfig, currentDir)
if p.StaticRootConfig != nil {
p.StaticRootConfig.Path = path.Join(currentDir, p.StaticRootConfig.Path)
StaticRoutes = append(StaticRoutes, p.StaticRootConfig)
}
} }
if pluginType == "externalPlugin" { if pluginType == "external" {
p := ExternalPlugin{} p := ExternalPlugin{}
reader.Seek(0, 0) reader.Seek(0, 0)
if err := jsonParser.Decode(&p); err != nil { if err := jsonParser.Decode(&p); err != nil {
return err return err
} }
ExternalPlugins = append(ExternalPlugins, p) ExternalPlugins = append(ExternalPlugins, p)
addStaticRoot(p.StaticRootConfig, currentDir)
} }
return nil return nil
......
...@@ -68,9 +68,13 @@ function (angular, $, _, appLevelRequire) { ...@@ -68,9 +68,13 @@ function (angular, $, _, appLevelRequire) {
app.useModule(angular.module(module_name, [])); app.useModule(angular.module(module_name, []));
}); });
var preBootRequires = [ var preBootRequires = ['app/features/all'];
'app/features/all', var pluginModules = window.grafanaBootData.pluginModules || [];
];
// add plugin modules
for (var i = 0; i < pluginModules.length; i++) {
preBootRequires.push(pluginModules[i]);
}
app.boot = function() { app.boot = function() {
require(preBootRequires, function () { require(preBootRequires, function () {
......
...@@ -29,8 +29,8 @@ function (angular, _, $, coreModule, config) { ...@@ -29,8 +29,8 @@ function (angular, _, $, coreModule, config) {
}); });
} }
if (_.isArray(window.externalPlugins.MainLinks)) { if (_.isArray(window.externalPlugins.mainLinks)) {
_.forEach(window.externalPlugins.MainLinks, function(item) { _.forEach(window.externalPlugins.mainLinks, function(item) {
if (!item.adminOnly || contextSrv.hasRole('Admin')) { if (!item.adminOnly || contextSrv.hasRole('Admin')) {
$scope.mainLinks.push({ $scope.mainLinks.push({
text: item.text, text: item.text,
......
...@@ -10,7 +10,7 @@ define([ ...@@ -10,7 +10,7 @@ define([
$locationProvider.html5Mode(true); $locationProvider.html5Mode(true);
var loadOrgBundle = new BundleLoader.BundleLoader('app/features/org/all'); var loadOrgBundle = new BundleLoader.BundleLoader('app/features/org/all');
console.log("adding grafana routes");
$routeProvider $routeProvider
.when('/', { .when('/', {
templateUrl: 'app/partials/dashboard.html', templateUrl: 'app/partials/dashboard.html',
......
...@@ -16,7 +16,6 @@ function (_) { ...@@ -16,7 +16,6 @@ function (_) {
'dashlist': { path: 'app/panels/dashlist', name: 'Dashboard list' }, 'dashlist': { path: 'app/panels/dashlist', name: 'Dashboard list' },
}, },
new_panel_title: 'Panel Title', new_panel_title: 'Panel Title',
plugins: {},
playlist_timespan: "1m", playlist_timespan: "1m",
unsaved_changes_warning: true, unsaved_changes_warning: true,
appSubUrl: "" appSubUrl: ""
......
...@@ -37,11 +37,6 @@ ...@@ -37,11 +37,6 @@
"adminOnly": false, "adminOnly": false,
} }
] ]
}, }
"staticRoot": {
"url": "_plugins/test_ds",
"path": "public"
},
} }
...@@ -3,8 +3,6 @@ require.config({ ...@@ -3,8 +3,6 @@ require.config({
baseUrl: 'public', baseUrl: 'public',
paths: { paths: {
'_plugins': '../_plugins',
'lodash-src': 'vendor/lodash', 'lodash-src': 'vendor/lodash',
lodash: 'app/core/lodash_extended', lodash: 'app/core/lodash_extended',
......
...@@ -95,6 +95,8 @@ function file2moduleName(filePath) { ...@@ -95,6 +95,8 @@ function file2moduleName(filePath) {
.replace(/\.\w*$/, ''); .replace(/\.\w*$/, '');
} }
window.grafanaBootData = {};
require([ require([
'lodash', 'lodash',
'angular', 'angular',
......
...@@ -13,8 +13,9 @@ ...@@ -13,8 +13,9 @@
[[else]] [[else]]
<link rel="stylesheet" href="[[.AppSubUrl]]/css/grafana.dark.min.css"> <link rel="stylesheet" href="[[.AppSubUrl]]/css/grafana.dark.min.css">
[[end]] [[end]]
[[ range $css := .ExternalPluginCss ]] [[ range $css := .ExternalPluginCss ]]
<link rel="stylesheet" href="[[$.AppSubUrl]]/plugins[[ $css ]]"> <link rel="stylesheet" href="[[$.AppSubUrl]]/[[ $css ]]">
[[ end ]] [[ end ]]
<link rel="icon" type="image/png" href="[[.AppSubUrl]]/img/fav32.png"> <link rel="icon" type="image/png" href="[[.AppSubUrl]]/img/fav32.png">
...@@ -53,19 +54,18 @@ ...@@ -53,19 +54,18 @@
window.grafanaBootData = { window.grafanaBootData = {
user:[[.User]], user:[[.User]],
settings: [[.Settings]], settings: [[.Settings]],
pluginModules: [[.ExternalPluginJs]],
}; };
window.externalPlugins = { window.externalPlugins = {
MainLinks: [[.ExternalPluginMenu]] mainLinks: [[.ExternalPluginMenu]]
}; };
require(['app/app'], function (app) { require(['app/app'], function (app) {
app.boot(); app.boot();
}) })
</script> </script>
[[ range $js := .ExternalPluginJs]]
<script src="[[$.AppSubUrl]]/plugins[[ $js ]]"></script>
[[ end ]]
[[if .GoogleAnalyticsId]] [[if .GoogleAnalyticsId]]
<script> <script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment