瀏覽代碼

feat(plugins): progress on dashboard installs , #4298

Torkel Ödegaard 9 年之前
父節點
當前提交
2de439bd1e

+ 10 - 4
pkg/api/api.go

@@ -126,10 +126,6 @@ func Register(r *macaron.Macaron) {
 			r.Post("/invites", quota("user"), bind(dtos.AddInviteForm{}), wrap(AddOrgInvite))
 			r.Patch("/invites/:code/revoke", wrap(RevokeInvite))
 
-			// apps
-			r.Get("/plugins", wrap(GetPluginList))
-			r.Get("/plugins/:pluginId/settings", wrap(GetPluginSettingById))
-			r.Post("/plugins/:pluginId/settings", bind(m.UpdatePluginSettingCmd{}), wrap(UpdatePluginSetting))
 		}, reqOrgAdmin)
 
 		// create new org
@@ -177,6 +173,16 @@ func Register(r *macaron.Macaron) {
 			r.Get("/", wrap(GetDataSourceByName))
 		}, reqOrgAdmin)
 
+		r.Group("/plugins", func() {
+			r.Get("/", wrap(GetPluginList))
+
+			r.Get("/dashboards/:pluginId", wrap(GetPluginDashboards))
+			r.Post("/dashboards/install", bind(dtos.InstallPluginDashboardCmd{}), wrap(InstallPluginDashboard))
+
+			r.Get("/:pluginId/settings", wrap(GetPluginSettingById))
+			r.Post("/:pluginId/settings", bind(m.UpdatePluginSettingCmd{}), wrap(UpdatePluginSetting))
+		}, reqOrgAdmin)
+
 		r.Get("/frontend/settings/", GetFrontendSettings)
 		r.Any("/datasources/proxy/:id/*", reqSignedIn, ProxyDataSourceRequest)
 		r.Any("/datasources/proxy/:id", reqSignedIn, ProxyDataSourceRequest)

+ 6 - 0
pkg/api/dtos/plugins.go

@@ -25,3 +25,9 @@ type PluginListItem struct {
 	Pinned  bool                `json:"pinned"`
 	Info    *plugins.PluginInfo `json:"info"`
 }
+
+type InstallPluginDashboardCmd struct {
+	PluginId string                 `json:"pluginId"`
+	Path     string                 `json:"path"`
+	Inputs   map[string]interface{} `json:"inputs"`
+}

+ 31 - 0
pkg/api/plugin_setting.go → pkg/api/plugins.go

@@ -107,3 +107,34 @@ func UpdatePluginSetting(c *middleware.Context, cmd m.UpdatePluginSettingCmd) Re
 
 	return ApiSuccess("Plugin settings updated")
 }
+
+func GetPluginDashboards(c *middleware.Context) Response {
+	pluginId := c.Params(":pluginId")
+
+	if list, err := plugins.GetPluginDashboards(c.OrgId, pluginId); err != nil {
+		if notfound, ok := err.(plugins.PluginNotFoundError); ok {
+			return ApiError(404, notfound.Error(), nil)
+		}
+
+		return ApiError(500, "Failed to get plugin dashboards", err)
+	} else {
+		return Json(200, list)
+	}
+}
+
+func InstallPluginDashboard(c *middleware.Context, apiCmd dtos.InstallPluginDashboardCmd) Response {
+
+	cmd := plugins.InstallPluginDashboardCommand{
+		OrgId:    c.OrgId,
+		UserId:   c.UserId,
+		PluginId: apiCmd.PluginId,
+		Path:     apiCmd.Path,
+		Inputs:   apiCmd.Inputs,
+	}
+
+	if err := bus.Dispatch(&cmd); err != nil {
+		return ApiError(500, "Failed to install dashboard", err)
+	}
+
+	return Json(200, cmd.Result)
+}

+ 0 - 0
pkg/models/plugin_setting.go → pkg/models/plugin_settings.go


+ 56 - 0
pkg/plugins/dashboard_installer.go

@@ -0,0 +1,56 @@
+package plugins
+
+import (
+	"github.com/grafana/grafana/pkg/bus"
+	m "github.com/grafana/grafana/pkg/models"
+)
+
+type InstallPluginDashboardCommand struct {
+	Path   string                 `json:"string"`
+	Inputs map[string]interface{} `json:"inputs"`
+
+	OrgId    int64  `json:"-"`
+	UserId   int64  `json:"-"`
+	PluginId string `json:"-"`
+	Result   *PluginDashboardInfoDTO
+}
+
+func init() {
+	bus.AddHandler("plugins", InstallPluginDashboard)
+}
+
+func InstallPluginDashboard(cmd *InstallPluginDashboardCommand) error {
+	plugin, exists := Plugins[cmd.PluginId]
+
+	if !exists {
+		return PluginNotFoundError{cmd.PluginId}
+	}
+
+	var dashboard *m.Dashboard
+	var err error
+
+	if dashboard, err = loadPluginDashboard(plugin, cmd.Path); err != nil {
+		return err
+	}
+
+	saveCmd := m.SaveDashboardCommand{
+		Dashboard: dashboard.Data,
+		OrgId:     cmd.OrgId,
+		UserId:    cmd.UserId,
+	}
+
+	if err := bus.Dispatch(&saveCmd); err != nil {
+		return err
+	}
+
+	cmd.Result = &PluginDashboardInfoDTO{
+		PluginId:          cmd.PluginId,
+		Title:             dashboard.Title,
+		Path:              cmd.Path,
+		Revision:          dashboard.GetString("revision", "1.0"),
+		InstalledURI:      "db/" + saveCmd.Result.Slug,
+		InstalledRevision: dashboard.GetString("revision", "1.0"),
+	}
+
+	return nil
+}

+ 25 - 11
pkg/plugins/dashboards.go

@@ -10,25 +10,27 @@ import (
 )
 
 type PluginDashboardInfoDTO struct {
-	Title             string
-	InstalledURI      string
-	InstalledRevision string
-	Revision          string
-	Description       string
+	PluginId          string `json:"pluginId"`
+	Title             string `json:"title"`
+	InstalledURI      string `json:"installedURI"`
+	InstalledRevision string `json:"installedRevision"`
+	Revision          string `json:"revision"`
+	Description       string `json:"description"`
+	Path              string `json:"path"`
 }
 
 func GetPluginDashboards(orgId int64, pluginId string) ([]*PluginDashboardInfoDTO, error) {
 	plugin, exists := Plugins[pluginId]
 
 	if !exists {
-		return nil, &PluginNotFoundError{pluginId}
+		return nil, PluginNotFoundError{pluginId}
 	}
 
 	result := make([]*PluginDashboardInfoDTO, 0)
 
 	for _, include := range plugin.Includes {
 		if include.Type == PluginTypeDashboard {
-			if dashInfo, err := getDashboardImportStatus(orgId, plugin, include); err != nil {
+			if dashInfo, err := getDashboardImportStatus(orgId, plugin, include.Path); err != nil {
 				return nil, err
 			} else {
 				result = append(result, dashInfo)
@@ -39,10 +41,9 @@ func GetPluginDashboards(orgId int64, pluginId string) ([]*PluginDashboardInfoDT
 	return result, nil
 }
 
-func getDashboardImportStatus(orgId int64, plugin *PluginBase, dashInclude *PluginInclude) (*PluginDashboardInfoDTO, error) {
-	res := &PluginDashboardInfoDTO{}
+func loadPluginDashboard(plugin *PluginBase, path string) (*m.Dashboard, error) {
 
-	dashboardFilePath := filepath.Join(plugin.PluginDir, dashInclude.Path)
+	dashboardFilePath := filepath.Join(plugin.PluginDir, path)
 	reader, err := os.Open(dashboardFilePath)
 	if err != nil {
 		return nil, err
@@ -57,8 +58,21 @@ func getDashboardImportStatus(orgId int64, plugin *PluginBase, dashInclude *Plug
 		return nil, err
 	}
 
-	dashboard := m.NewDashboardFromJson(data)
+	return m.NewDashboardFromJson(data), nil
+}
+
+func getDashboardImportStatus(orgId int64, plugin *PluginBase, path string) (*PluginDashboardInfoDTO, error) {
+	res := &PluginDashboardInfoDTO{}
+
+	var dashboard *m.Dashboard
+	var err error
+
+	if dashboard, err = loadPluginDashboard(plugin, path); err != nil {
+		return nil, err
+	}
 
+	res.Path = path
+	res.PluginId = plugin.Id
 	res.Title = dashboard.Title
 	res.Revision = dashboard.GetString("revision", "1.0")
 

+ 1 - 1
pkg/plugins/models.go

@@ -21,7 +21,7 @@ type PluginNotFoundError struct {
 	PluginId string
 }
 
-func (e *PluginNotFoundError) Error() string {
+func (e PluginNotFoundError) Error() string {
 	return fmt.Sprintf("Plugin with id %s not found", e.PluginId)
 }
 

+ 21 - 18
public/app/features/dashboard/import_list/import_list.ts

@@ -11,29 +11,26 @@ export class DashImportListCtrl {
   dashboards: any[];
   plugin: any;
 
-  constructor(private $http) {
+  constructor(private $http, private backendSrv, private $rootScope) {
     this.dashboards = [];
 
-    this.plugin.includes
-    .filter(val => val.type === 'dashboard')
-    .forEach(this.getDashbordImportStatus.bind(this));
-  }
-
-  getDashbordImportStatus(dash) {
-    var dashUrl = this.plugin.baseUrl + '/' + dash.path;
-    this.$http.get(dashUrl).then(res => {
-      this.load(res.data);
-
+    backendSrv.get(`/api/plugins/dashboards/${this.plugin.id}`).then(dashboards => {
+      this.dashboards = dashboards;
     });
   }
 
-  load(json) {
-    var model = angular.fromJson(json);
-    console.log(model);
-  }
-
   import(dash) {
+    var installCmd = {
+      pluginId: this.plugin.id,
+      path: dash.path,
+      inputs: {}
+    };
+
+    this.backendSrv.post(`/api/plugins/dashboards/install`, installCmd).then(res => {
+      console.log(res);
+    });
   }
+
 }
 
 var template = `
@@ -45,11 +42,17 @@ var template = `
           <i class="icon-gf icon-gf-dashboard"></i>
         </td>
         <td>
-          {{dash.name}}</span>
+          {{dash.title}}
+        </td>
+        <td>
+          {{dash.revision}}
+        </td>
+        <td>
+          {{dash.installedRevision}}
         </td>
         <td class="width-2">
           <button class="btn btn-secondary" ng-click="ctrl.import(dash)">Install</button>
-        </td
+        </td>
       </tr>
     </tbody>
   </table>

+ 2 - 2
public/app/features/datasources/edit_ctrl.ts

@@ -54,7 +54,7 @@ export class DataSourceEditCtrl {
         return this.$q.when(null);
       }
 
-      return this.backendSrv.get('/api/org/plugins', {enabled: 1, type: 'datasource'}).then(plugins => {
+      return this.backendSrv.get('/api/plugins', {enabled: 1, type: 'datasource'}).then(plugins => {
         datasourceTypes = plugins;
         this.types = plugins;
       });
@@ -70,7 +70,7 @@ export class DataSourceEditCtrl {
 
     typeChanged() {
       this.hasDashboards = false;
-      return this.backendSrv.get('/api/org/plugins/' + this.current.type + '/settings').then(pluginInfo => {
+      return this.backendSrv.get('/api/plugins/' + this.current.type + '/settings').then(pluginInfo => {
         this.datasourceMeta = pluginInfo;
         this.hasDashboards = _.findWhere(pluginInfo.includes, {type: 'dashboard'});
       });

+ 1 - 1
public/app/features/plugins/edit_ctrl.ts

@@ -22,7 +22,7 @@ export class PluginEditCtrl {
    }
 
   init() {
-    return this.backendSrv.get(`/api/org/plugins/${this.pluginId}/settings`).then(result => {
+    return this.backendSrv.get(`/api/plugins/${this.pluginId}/settings`).then(result => {
       this.model = result;
       this.pluginIcon = this.getPluginIcon(this.model.type);
 

+ 1 - 1
public/app/features/plugins/list_ctrl.ts

@@ -8,7 +8,7 @@ export class PluginListCtrl {
   /** @ngInject */
   constructor(private backendSrv: any) {
 
-    this.backendSrv.get('api/org/plugins').then(plugins => {
+    this.backendSrv.get('api/plugins', {embedded: 0}).then(plugins => {
       this.plugins = plugins;
     });
   }