Commit 3bb20dbf by Torkel Ödegaard

feat(plugins): changed plugin schema, pluginType -> type, type -> id

parent 7a8b3c41
......@@ -22,7 +22,7 @@ func GetAppPlugins(c *middleware.Context) Response {
Enabled: app.Enabled,
Pinned: app.Pinned,
Module: app.Module,
Info: app.Info,
Info: &app.Info,
}
}
......
......@@ -119,7 +119,7 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
panels := map[string]interface{}{}
for _, panel := range enabledPlugins.Panels {
panels[panel.Type] = map[string]interface{}{
panels[panel.Id] = map[string]interface{}{
"module": panel.Module,
"name": panel.Name,
}
......
......@@ -4,6 +4,13 @@ import (
"github.com/grafana/grafana/pkg/models"
)
type PluginCommon struct {
Type string `json:"type"`
Name string `json:"name"`
Id string `json:"id"`
Info PluginInfo `json:"info"`
}
type PluginInfo struct {
Author PluginInfoLink `json:"author"`
Description string `json:"description"`
......@@ -22,10 +29,9 @@ type PluginLogos struct {
}
type DataSourcePlugin struct {
Type string `json:"type"`
Name string `json:"name"`
ServiceName string `json:"serviceName"`
PluginCommon
Module string `json:"module"`
ServiceName string `json:"serviceName"`
Partials map[string]interface{} `json:"partials"`
DefaultMatchFormat string `json:"defaultMatchFormat"`
Annotations bool `json:"annotations"`
......@@ -36,8 +42,7 @@ type DataSourcePlugin struct {
}
type PanelPlugin struct {
Type string `json:"type"`
Name string `json:"name"`
PluginCommon
Module string `json:"module"`
PublicContent *PublicContent `json:"public"`
App string `json:"app"`
......@@ -71,21 +76,19 @@ type AppPluginCss struct {
}
type ApiPlugin struct {
Type string `json:"type"`
PluginCommon
Routes []*ApiPluginRoute `json:"routes"`
App string `json:"app"`
}
type AppPlugin struct {
Type string `json:"type"`
Name string `json:"name"`
PluginCommon
Enabled bool `json:"enabled"`
Pinned bool `json:"pinned"`
Module string `json:"module"`
Css *AppPluginCss `json:"css"`
Page *AppPluginPage `json:"page"`
PublicContent *PublicContent `json:"public"`
Info *PluginInfo `json:"info"`
}
type EnabledPlugins struct {
......
......@@ -121,7 +121,7 @@ func addPublicContent(public *PublicContent, currentDir string) {
}
}
func interpolatePluginJson(reader io.Reader) (io.Reader, error) {
func interpolatePluginJson(reader io.Reader, pluginCommon *PluginCommon) (io.Reader, error) {
buf := new(bytes.Buffer)
buf.ReadFrom(reader)
jsonStr := buf.String() //
......@@ -132,7 +132,7 @@ func interpolatePluginJson(reader io.Reader) (io.Reader, error) {
}
data := map[string]interface{}{
"PluginPublicRoot": "HAHAHA",
"PluginPublicRoot": "public/plugins/" + pluginCommon.Id,
}
var resultBuffer bytes.Buffer
......@@ -153,76 +153,59 @@ func (scanner *PluginScanner) loadPluginJson(pluginJsonFilePath string) error {
defer reader.Close()
jsonParser := json.NewDecoder(reader)
pluginJson := make(map[string]interface{})
if err := jsonParser.Decode(&pluginJson); err != nil {
pluginCommon := PluginCommon{}
if err := jsonParser.Decode(&pluginCommon); err != nil {
return err
}
pluginType, exists := pluginJson["pluginType"]
if !exists {
return errors.New("Did not find pluginType property in plugin.json")
if pluginCommon.Id == "" || pluginCommon.Type == "" {
return errors.New("Did not find type and id property in plugin.json")
}
reader.Seek(0, 0)
if newReader, err := interpolatePluginJson(reader); err != nil {
if newReader, err := interpolatePluginJson(reader, &pluginCommon); err != nil {
return err
} else {
jsonParser = json.NewDecoder(newReader)
}
if pluginType == "datasource" {
switch pluginCommon.Type {
case "datasource":
p := DataSourcePlugin{}
if err := jsonParser.Decode(&p); err != nil {
return err
}
if p.Type == "" {
return errors.New("Did not find type property in plugin.json")
}
DataSources[p.Type] = &p
DataSources[p.Id] = &p
addPublicContent(p.PublicContent, currentDir)
}
if pluginType == "panel" {
case "panel":
p := PanelPlugin{}
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")
}
Panels[p.Type] = &p
Panels[p.Id] = &p
addPublicContent(p.PublicContent, currentDir)
}
if pluginType == "api" {
case "api":
p := ApiPlugin{}
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")
}
ApiPlugins[p.Type] = &p
}
if pluginType == "app" {
ApiPlugins[p.Id] = &p
case "app":
p := AppPlugin{}
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")
}
Apps[p.Type] = &p
Apps[p.Id] = &p
addPublicContent(p.PublicContent, currentDir)
default:
return errors.New("Unkown plugin type " + pluginCommon.Type)
}
return nil
......
......@@ -29,7 +29,7 @@ func TestPluginScans(t *testing.T) {
So(err, ShouldBeNil)
So(len(Apps), ShouldBeGreaterThan, 0)
So(Apps["app-test"].Info.Logos.Large, ShouldEqual, "plugins/app-exampl/img/logo_large.png")
So(Apps["app-test"].Info.Logos.Large, ShouldEqual, "public/plugins/app-test/logo_large.png")
})
}
{
"pluginType": "datasource",
"type": "datasource",
"name": "CloudWatch",
"id": "cloudwatch",
"type": "cloudwatch",
"serviceName": "CloudWatchDatasource",
"module": "app/plugins/datasource/cloudwatch/datasource",
......
{
"pluginType": "datasource",
"type": "datasource",
"name": "Elasticsearch",
"id": "elasticsearch",
"type": "elasticsearch",
"serviceName": "ElasticDatasource",
"module": "app/plugins/datasource/elasticsearch/datasource",
......
{
"pluginType": "datasource",
"type": "datasource",
"name": "Grafana",
"id": "grafana",
"builtIn": true,
"type": "grafana",
"serviceName": "GrafanaDatasource",
"module": "app/plugins/datasource/grafana/datasource",
......
{
"pluginType": "datasource",
"name": "Graphite",
"type": "graphite",
"type": "datasource",
"id": "graphite",
"serviceName": "GraphiteDatasource",
"module": "app/plugins/datasource/graphite/datasource",
......
{
"pluginType": "datasource",
"type": "datasource",
"name": "InfluxDB 0.9.x",
"id": "influxdb",
"type": "influxdb",
"serviceName": "InfluxDatasource",
"module": "app/plugins/datasource/influxdb/datasource",
......
{
"pluginType": "datasource",
"type": "datasource",
"name": "Mixed datasource",
"id": "mixed",
"builtIn": true,
"mixed": true,
"type": "mixed",
"serviceName": "MixedDatasource",
"module": "app/plugins/datasource/mixed/datasource",
......
{
"pluginType": "datasource",
"type": "datasource",
"name": "OpenTSDB",
"id": "opentsdb",
"type": "opentsdb",
"serviceName": "OpenTSDBDatasource",
"module": "app/plugins/datasource/opentsdb/datasource",
"partials": {
......
{
"pluginType": "datasource",
"type": "datasource",
"name": "Prometheus",
"id": "prometheus",
"type": "prometheus",
"serviceName": "PrometheusDatasource",
"module": "app/plugins/datasource/prometheus/datasource",
......
define([
'angular',
],
function (angular) {
'use strict';
var module = angular.module('grafana.services');
module.factory('SqlDatasource', function() {
function SqlDatasource() {
}
return SqlDatasource;
});
});
<h2>SQL Options</h2>
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 80px">
DB Type
</li>
<li>
<select class="input-medium tight-form-input" ng-model="current.jsonData.dbType" ng-options="f for f in ['sqlite3','mysql','postgres']"></select>
</li>
<li class="tight-form-item" style="width: 80px">
Host
</li>
<li>
<input type="text" class="tight-form-input input-medium" ng-model='current.jsonData.host' placeholder="localhost:3306">
</li>
<li class="tight-form-item" ng-if="current.jsonData.dbType === 'postgres'">
SSL&nbsp;
<input class="cr1" id="jsonData.ssl" type="checkbox" ng-model="current.jsonData.ssl" ng-checked="current.jsonData.ssl">
<label for="jsonData.ssl" class="cr1"></label>
</li>
</ul>
<div class="clearfix"></div>
</div>
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 80px">
Database
</li>
<li>
<input type="text" class="tight-form-input input-medium" ng-model='current.database' placeholder="">
</li>
</ul>
<div class="clearfix"></div>
</div>
<div class="tight-form">
<ul class="tight-form-list">
<li class="tight-form-item" style="width: 80px">
User
</li>
<li>
<input type="text" class="tight-form-input input-medium" ng-model='current.user' placeholder="">
</li>
<li class="tight-form-item" style="width: 80px">
Password
</li>
<li>
<input type="password" class="tight-form-input input-medium" ng-model='current.password' placeholder="">
</li>
</ul>
<div class="clearfix"></div>
</div>
<div class="fluid-row" style="margin-top: 20px">
<div class="span2"></div>
<div class="grafana-info-box span8">
<h5>Test graph</h5>
<p>
This is just a test data source that generates random walk series. If this is your only data source
open the left side menu and navigate to the data sources admin screen and add your data sources. You can change
data source using the button to the left of the <strong>Add query</strong> button.
</p>
</div>
<div class="span2"></div>
<div class="clearfix"></div>
</div>
{
"pluginType": "datasource",
"name": "Generic SQL (prototype)",
"type": "generic_sql",
"serviceName": "SqlDatasource",
"module": "app/plugins/datasource/sql/datasource",
"partials": {
"config": "app/plugins/datasource/sql/partials/config.html",
"query": "app/plugins/datasource/sql/partials/query.editor.html"
},
"metrics": true
}
{
"pluginType": "panel",
"type": "panel",
"name": "Dashboard list",
"type": "dashlist",
"id": "dashlist",
"module": "app/plugins/panels/dashlist/module"
}
{
"pluginType": "panel",
"type": "panel",
"name": "Graph",
"type": "graph",
"id": "graph",
"module": "app/plugins/panels/graph/module"
}
{
"pluginType": "panel",
"type": "panel",
"name": "Singlestat",
"type": "singlestat",
"id": "singlestat",
"module": "app/plugins/panels/singlestat/module"
}
{
"pluginType": "panel",
"type": "panel",
"name": "Table",
"type": "table",
"id": "table",
"module": "app/plugins/panels/table/module"
}
{
"pluginType": "panel",
"type": "panel",
"name": "Text",
"type": "text",
"id": "text",
"module": "app/plugins/panels/text/module"
}
{
"pluginType": "app",
"name": "App Example",
"type": "app-test",
"plugins": [],
"css": {
"light": "plugin.dark.css",
"dark": "plugin.light.css"
},
"module": "app",
"pages": [
{"name": "Example1", "url": "/app-example", "reqRole": "Editor"}
],
"public": {
"urlFragment": "app-example",
"path": "./public"
},
"id": "app-test",
"type": "app",
"info": {
"description": "Example Grafana App",
......@@ -40,6 +22,22 @@
"updated": "2015-02-10"
},
"css": {
"light": "plugin.dark.css",
"dark": "plugin.light.css"
},
"module": "app",
"pages": [
{"name": "Example1", "url": "/app-example", "reqRole": "Editor"}
],
"public": {
"urlFragment": "app-example",
"path": "./public"
},
"dependencies": {
"grafanaVersion": "2.6.x",
"plugins": [
......
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