plugins.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package plugins
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "os"
  6. "path"
  7. "path/filepath"
  8. "github.com/grafana/grafana/pkg/log"
  9. "github.com/grafana/grafana/pkg/setting"
  10. )
  11. type PluginMeta struct {
  12. Type string `json:"type"`
  13. Name string `json:"name"`
  14. }
  15. type ExternalPluginRoute struct {
  16. Path string `json:"path"`
  17. Method string `json:"method"`
  18. ReqSignedIn bool `json:"req_signed_in"`
  19. ReqGrafanaAdmin bool `json:"req_grafana_admin"`
  20. ReqRole string `json:"req_role"`
  21. Url string `json:"url"`
  22. }
  23. type ExternalPluginJs struct {
  24. Src string `json:"src"`
  25. }
  26. type ExternalPluginMenuItem struct {
  27. Text string `json:"text"`
  28. Icon string `json:"icon"`
  29. Href string `json:"href"`
  30. }
  31. type ExternalPluginCss struct {
  32. Href string `json:"href"`
  33. }
  34. type ExternalPluginSettings struct {
  35. Routes []*ExternalPluginRoute `json:"routes"`
  36. Js []*ExternalPluginJs `json:"js"`
  37. Css []*ExternalPluginCss `json:"css"`
  38. MenuItems []*ExternalPluginMenuItem `json:"menu_items"`
  39. }
  40. type ExternalPlugin struct {
  41. PluginType string `json:"pluginType"`
  42. Settings ExternalPluginSettings `json:"settings"`
  43. }
  44. var (
  45. DataSources map[string]interface{}
  46. ExternalPlugins []ExternalPlugin
  47. )
  48. type PluginScanner struct {
  49. pluginPath string
  50. errors []error
  51. }
  52. func Init() {
  53. scan(path.Join(setting.StaticRootPath, "app/plugins"))
  54. }
  55. func scan(pluginDir string) error {
  56. DataSources = make(map[string]interface{})
  57. ExternalPlugins = make([]ExternalPlugin, 0)
  58. scanner := &PluginScanner{
  59. pluginPath: pluginDir,
  60. }
  61. if err := filepath.Walk(pluginDir, scanner.walker); err != nil {
  62. return err
  63. }
  64. if len(scanner.errors) > 0 {
  65. return errors.New("Some plugins failed to load")
  66. }
  67. return nil
  68. }
  69. func (scanner *PluginScanner) walker(path string, f os.FileInfo, err error) error {
  70. if err != nil {
  71. return err
  72. }
  73. if f.IsDir() {
  74. return nil
  75. }
  76. if f.Name() == "plugin.json" {
  77. err := scanner.loadPluginJson(path)
  78. if err != nil {
  79. log.Error(3, "Failed to load plugin json file: %v, err: %v", path, err)
  80. scanner.errors = append(scanner.errors, err)
  81. }
  82. }
  83. return nil
  84. }
  85. func (scanner *PluginScanner) loadPluginJson(path string) error {
  86. reader, err := os.Open(path)
  87. if err != nil {
  88. return err
  89. }
  90. defer reader.Close()
  91. jsonParser := json.NewDecoder(reader)
  92. pluginJson := make(map[string]interface{})
  93. if err := jsonParser.Decode(&pluginJson); err != nil {
  94. return err
  95. }
  96. pluginType, exists := pluginJson["pluginType"]
  97. if !exists {
  98. return errors.New("Did not find pluginType property in plugin.json")
  99. }
  100. if pluginType == "datasource" {
  101. datasourceType, exists := pluginJson["type"]
  102. if !exists {
  103. return errors.New("Did not find type property in plugin.json")
  104. }
  105. DataSources[datasourceType.(string)] = pluginJson
  106. }
  107. if pluginType == "externalPlugin" {
  108. p := ExternalPlugin{}
  109. reader.Seek(0, 0)
  110. if err := jsonParser.Decode(&p); err != nil {
  111. return err
  112. }
  113. ExternalPlugins = append(ExternalPlugins, p)
  114. }
  115. return nil
  116. }