mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat(plugins): progress on dashboard installs , #4298
This commit is contained in:
parent
60adcedebe
commit
2de439bd1e
@ -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)
|
||||
|
@ -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"`
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
56
pkg/plugins/dashboard_installer.go
Normal file
56
pkg/plugins/dashboard_installer.go
Normal file
@ -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
|
||||
}
|
@ -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")
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
import(dash) {
|
||||
}
|
||||
}
|
||||
|
||||
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>
|
||||
|
@ -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'});
|
||||
});
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user