mirror of https://github.com/statping/statping
plugin
parent
3d6daf0b90
commit
2ade95f14a
2
Makefile
2
Makefile
|
@ -45,7 +45,7 @@ build: compile
|
||||||
|
|
||||||
# build Statup plugins
|
# build Statup plugins
|
||||||
build-plugin:
|
build-plugin:
|
||||||
$(GOBUILD) $(BUILDVERSION) -buildmode=plugin -o $(BINARY_NAME) -v ./dev/plugin
|
$(GOBUILD) $(BUILDVERSION) -buildmode=plugin -o ./dev/plugin/example.so -v ./dev/plugin
|
||||||
|
|
||||||
# build Statup debug app
|
# build Statup debug app
|
||||||
build-debug: compile
|
build-debug: compile
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/hunterlong/statup/core"
|
"github.com/hunterlong/statup/core"
|
||||||
"github.com/hunterlong/statup/handlers"
|
"github.com/hunterlong/statup/handlers"
|
||||||
|
"github.com/hunterlong/statup/plugin"
|
||||||
"github.com/hunterlong/statup/source"
|
"github.com/hunterlong/statup/source"
|
||||||
"github.com/hunterlong/statup/utils"
|
"github.com/hunterlong/statup/utils"
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
|
@ -80,7 +81,7 @@ func CatchCLI(args []string) error {
|
||||||
cmd := args[1]
|
cmd := args[1]
|
||||||
switch cmd {
|
switch cmd {
|
||||||
case "plugins":
|
case "plugins":
|
||||||
LoadPlugins(true)
|
plugin.LoadPlugins(true)
|
||||||
}
|
}
|
||||||
return errors.New("end")
|
return errors.New("end")
|
||||||
case "export":
|
case "export":
|
||||||
|
|
65
cmd/main.go
65
cmd/main.go
|
@ -21,6 +21,7 @@ import (
|
||||||
"github.com/hunterlong/statup/core"
|
"github.com/hunterlong/statup/core"
|
||||||
"github.com/hunterlong/statup/handlers"
|
"github.com/hunterlong/statup/handlers"
|
||||||
_ "github.com/hunterlong/statup/notifiers"
|
_ "github.com/hunterlong/statup/notifiers"
|
||||||
|
"github.com/hunterlong/statup/plugin"
|
||||||
"github.com/hunterlong/statup/source"
|
"github.com/hunterlong/statup/source"
|
||||||
"github.com/hunterlong/statup/utils"
|
"github.com/hunterlong/statup/utils"
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
|
@ -108,7 +109,7 @@ func mainProcess() {
|
||||||
core.Configs.MigrateDatabase()
|
core.Configs.MigrateDatabase()
|
||||||
core.InitApp()
|
core.InitApp()
|
||||||
if !core.SetupMode {
|
if !core.SetupMode {
|
||||||
LoadPlugins(false)
|
plugin.LoadPlugins(false)
|
||||||
fmt.Println(handlers.RunHTTPServer(ipAddress, port))
|
fmt.Println(handlers.RunHTTPServer(ipAddress, port))
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
@ -121,65 +122,3 @@ func ForEachPlugin() {
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadPlugins(debug bool) {
|
|
||||||
//utils.Log(1, fmt.Sprintf("Loading any available Plugins from /plugins directory"))
|
|
||||||
//if _, err := os.Stat("./plugins"); os.IsNotExist(err) {
|
|
||||||
// os.Mkdir("./plugins", os.ModePerm)
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
////ForEachPlugin()
|
|
||||||
//files, err := ioutil.ReadDir("./plugins")
|
|
||||||
//if err != nil {
|
|
||||||
// utils.Log(2, fmt.Sprintf("Plugins directory was not found. Error: %v\n", err))
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
//for _, f := range files {
|
|
||||||
// utils.Log(1, fmt.Sprintf("Attempting to load plugin '%v'", f.Name()))
|
|
||||||
// ext := strings.Split(f.Name(), ".")
|
|
||||||
// if len(ext) != 2 {
|
|
||||||
// utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// if ext[1] != "so" {
|
|
||||||
// utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// plug, err := plg.Open("plugins/" + f.Name())
|
|
||||||
// if err != nil {
|
|
||||||
// utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// symPlugin, err := plug.Lookup("Plugin")
|
|
||||||
// if err != nil {
|
|
||||||
// utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if debug {
|
|
||||||
// utils.Log(1, fmt.Sprintf("Plugin '%v' struct:", f.Name()))
|
|
||||||
// utils.Log(1, structs.Map(symPlugin))
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// var plugActions types.PluginActions
|
|
||||||
// plugActions, ok := symPlugin.(types.PluginActions)
|
|
||||||
// if !ok {
|
|
||||||
// utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly, error: %v", f.Name(), err))
|
|
||||||
// if debug {
|
|
||||||
// //fmt.Println(symPlugin.(plugin.PluginActions))
|
|
||||||
// }
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if debug {
|
|
||||||
// TestPlugin(plugActions)
|
|
||||||
// } else {
|
|
||||||
// plugActions.OnLoad(*core.DbSession)
|
|
||||||
// core.CoreApp.Plugins = append(core.CoreApp.Plugins, plugActions.GetInfo())
|
|
||||||
// core.CoreApp.AllPlugins = append(core.CoreApp.AllPlugins, plugActions)
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//if !debug {
|
|
||||||
// utils.Log(1, fmt.Sprintf("Loaded %v Plugins\n", len(core.CoreApp.Plugins)))
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hunterlong/statup/plugin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Example struct {
|
||||||
|
*plugin.Plugin
|
||||||
|
}
|
||||||
|
|
||||||
|
var example = &Example{&plugin.Plugin{
|
||||||
|
Name: "Example",
|
||||||
|
Description: "This is an example plugin",
|
||||||
|
}}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Example) Select() *plugin.Plugin {
|
||||||
|
return e.Plugin
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package plugin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hunterlong/statup/core/notifier"
|
||||||
|
"github.com/jinzhu/gorm"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PluginObject struct {
|
||||||
|
PluginInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
type Pluginer interface {
|
||||||
|
Select() *PluginObject
|
||||||
|
}
|
||||||
|
|
||||||
|
type Databaser interface {
|
||||||
|
StatupDatabase(*gorm.DB)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Router interface {
|
||||||
|
Routes() []interface{}
|
||||||
|
AddRoute(string, string, http.HandlerFunc) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type Asseter interface {
|
||||||
|
Asset(string) ([]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Notifier interface {
|
||||||
|
notifier.Notifier
|
||||||
|
notifier.BasicEvents
|
||||||
|
}
|
||||||
|
|
||||||
|
type AdvancedNotifier interface {
|
||||||
|
notifier.Notifier
|
||||||
|
notifier.BasicEvents
|
||||||
|
notifier.UserEvents
|
||||||
|
notifier.CoreEvents
|
||||||
|
notifier.NotifierEvents
|
||||||
|
}
|
||||||
|
|
||||||
|
type Routing struct {
|
||||||
|
URL string
|
||||||
|
Method string
|
||||||
|
Handler func(http.ResponseWriter, *http.Request)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Info struct {
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
Form string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Database *gorm.DB
|
||||||
|
|
||||||
|
type Plugin struct {
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
type PluginDatabase interface {
|
||||||
|
Database(gorm.DB)
|
||||||
|
Update() error
|
||||||
|
}
|
||||||
|
|
||||||
|
type PluginInfo struct {
|
||||||
|
i *Info
|
||||||
|
}
|
139
plugin/main.go
139
plugin/main.go
|
@ -16,9 +16,16 @@
|
||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hunterlong/statup/core/notifier"
|
"fmt"
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/fatih/structs"
|
||||||
|
"github.com/hunterlong/statup/core"
|
||||||
|
"github.com/hunterlong/statup/types"
|
||||||
|
"github.com/hunterlong/statup/utils"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"plugin"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -33,12 +40,16 @@ import (
|
||||||
// work even if there's an update or addition.
|
// work even if there's an update or addition.
|
||||||
//
|
//
|
||||||
|
|
||||||
type PluginObject struct{}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
AllPlugins []*PluginObject
|
AllPlugins []*PluginObject
|
||||||
|
dir string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
utils.InitLogs()
|
||||||
|
dir = utils.Directory
|
||||||
|
}
|
||||||
|
|
||||||
func Add(p Pluginer) *PluginObject {
|
func Add(p Pluginer) *PluginObject {
|
||||||
return &PluginObject{}
|
return &PluginObject{}
|
||||||
}
|
}
|
||||||
|
@ -47,67 +58,65 @@ func (p *PluginObject) AddRoute(s string, i string, f http.HandlerFunc) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Pluginer interface {
|
|
||||||
Select() *PluginObject
|
|
||||||
}
|
|
||||||
|
|
||||||
type Databaser interface {
|
|
||||||
StatupDatabase(*gorm.DB)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Router interface {
|
|
||||||
AddRoute(string, string, http.HandlerFunc) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type Notifier interface {
|
|
||||||
notifier.Notifier
|
|
||||||
notifier.BasicEvents
|
|
||||||
}
|
|
||||||
|
|
||||||
type AdvancedNotifier interface {
|
|
||||||
notifier.Notifier
|
|
||||||
notifier.BasicEvents
|
|
||||||
notifier.UserEvents
|
|
||||||
notifier.CoreEvents
|
|
||||||
notifier.NotifierEvents
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
DB *gorm.DB
|
|
||||||
)
|
|
||||||
|
|
||||||
type Routing struct {
|
|
||||||
URL string
|
|
||||||
Method string
|
|
||||||
Handler func(http.ResponseWriter, *http.Request)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Info struct {
|
|
||||||
Name string
|
|
||||||
Description string
|
|
||||||
Form string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Database *gorm.DB
|
|
||||||
|
|
||||||
type Plugin struct {
|
|
||||||
Name string
|
|
||||||
Description string
|
|
||||||
}
|
|
||||||
|
|
||||||
type PluginDatabase interface {
|
|
||||||
Database(gorm.DB)
|
|
||||||
Update() error
|
|
||||||
}
|
|
||||||
|
|
||||||
type PluginInfo struct {
|
|
||||||
i *Info
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetDatabase(database *gorm.DB) {
|
|
||||||
DB = database
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *PluginInfo) Form() string {
|
func (p *PluginInfo) Form() string {
|
||||||
return "okkokokkok"
|
return "okkokokkok"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LoadPlugins(debug bool) {
|
||||||
|
pluginDir := dir + "/plugins"
|
||||||
|
utils.Log(1, fmt.Sprintf("Loading any available Plugins from /plugins directory"))
|
||||||
|
if _, err := os.Stat(pluginDir); os.IsNotExist(err) {
|
||||||
|
os.Mkdir(pluginDir, os.ModePerm)
|
||||||
|
}
|
||||||
|
|
||||||
|
//ForEachPlugin()
|
||||||
|
files, err := ioutil.ReadDir(pluginDir)
|
||||||
|
if err != nil {
|
||||||
|
utils.Log(2, fmt.Sprintf("Plugins directory was not found. Error: %v\n", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, f := range files {
|
||||||
|
utils.Log(1, fmt.Sprintf("Attempting to load plugin '%v'", f.Name()))
|
||||||
|
ext := strings.Split(f.Name(), ".")
|
||||||
|
if len(ext) != 2 {
|
||||||
|
utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if ext[1] != "so" {
|
||||||
|
utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
plug, err := plugin.Open("plugins/" + f.Name())
|
||||||
|
if err != nil {
|
||||||
|
utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
symPlugin, err := plug.Lookup("Plugin")
|
||||||
|
if err != nil {
|
||||||
|
utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if debug {
|
||||||
|
utils.Log(1, fmt.Sprintf("Plugin '%v' struct:", f.Name()))
|
||||||
|
utils.Log(1, structs.Map(symPlugin))
|
||||||
|
}
|
||||||
|
|
||||||
|
var plugActions types.PluginActions
|
||||||
|
plugActions, ok := symPlugin.(types.PluginActions)
|
||||||
|
if !ok {
|
||||||
|
utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly, error: %v", f.Name(), err))
|
||||||
|
if debug {
|
||||||
|
//fmt.Println(symPlugin.(plugin.PluginActions))
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
plugActions.OnLoad(*core.DbSession)
|
||||||
|
core.CoreApp.Plugins = append(core.CoreApp.Plugins, plugActions.GetInfo())
|
||||||
|
core.CoreApp.AllPlugins = append(core.CoreApp.AllPlugins, plugActions)
|
||||||
|
}
|
||||||
|
if !debug {
|
||||||
|
utils.Log(1, fmt.Sprintf("Loaded %v Plugins\n", len(core.CoreApp.Plugins)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/hunterlong/statup/source"
|
||||||
|
"github.com/hunterlong/statup/utils"
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -27,6 +29,11 @@ var (
|
||||||
example *PluginObject
|
example *PluginObject
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
utils.InitLogs()
|
||||||
|
source.Assets()
|
||||||
|
}
|
||||||
|
|
||||||
func (p *PluginObject) StatupDatabase(db *gorm.DB) {
|
func (p *PluginObject) StatupDatabase(db *gorm.DB) {
|
||||||
database = db
|
database = db
|
||||||
}
|
}
|
||||||
|
@ -35,10 +42,18 @@ func (p *PluginObject) Select() *PluginObject {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *PluginObject) Info() *PluginObject {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
func setupHandler(w http.ResponseWriter, r *http.Request) {
|
func setupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Write([]byte("ok"))
|
w.Write([]byte("ok"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLoadPlugins(t *testing.T) {
|
||||||
|
LoadPlugins(false)
|
||||||
|
}
|
||||||
|
|
||||||
func TestAdd(t *testing.T) {
|
func TestAdd(t *testing.T) {
|
||||||
err := Add(example)
|
err := Add(example)
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
|
|
Loading…
Reference in New Issue