statping/main.go

340 lines
7.0 KiB
Go
Raw Normal View History

2018-06-10 01:31:13 +00:00
package main
import (
"database/sql"
2018-06-12 07:21:16 +00:00
"encoding/json"
2018-06-10 01:47:57 +00:00
"fmt"
2018-06-10 01:31:13 +00:00
"github.com/GeertJohan/go.rice"
"github.com/go-yaml/yaml"
"github.com/gorilla/sessions"
2018-06-12 05:23:30 +00:00
"github.com/hunterlong/statup/plugin"
2018-06-10 01:31:13 +00:00
_ "github.com/lib/pq"
"golang.org/x/crypto/bcrypt"
2018-06-14 06:38:15 +00:00
"io"
2018-06-10 01:31:13 +00:00
"io/ioutil"
2018-06-12 07:21:16 +00:00
"net/http"
"os"
2018-06-11 07:49:41 +00:00
plg "plugin"
"strings"
2018-06-10 01:31:13 +00:00
)
var (
2018-06-12 05:23:30 +00:00
db *sql.DB
configs *Config
core *Core
store *sessions.CookieStore
VERSION string
sqlBox *rice.Box
cssBox *rice.Box
jsBox *rice.Box
tmplBox *rice.Box
setupMode bool
2018-06-14 01:19:00 +00:00
allPlugins []plugin.PluginActions
2018-06-10 01:31:13 +00:00
)
2018-06-12 07:21:16 +00:00
const (
pluginsRepo = "https://raw.githubusercontent.com/hunterlong/statup/master/plugins.json"
)
2018-06-10 01:31:13 +00:00
type Config struct {
Connection string `yaml:"connection"`
Host string `yaml:"host"`
Database string `yaml:"database"`
User string `yaml:"user"`
Password string `yaml:"password"`
Port string `yaml:"port"`
Secret string `yaml:"secret"`
}
2018-06-12 07:21:16 +00:00
type PluginRepos struct {
Plugins []PluginJSON
}
type PluginJSON struct {
Name string `json:"name"`
Description string `json:"description"`
Repo string `json:"repo"`
Author string `json:"author"`
Namespace string `json:"namespace"`
}
func (c *Core) FetchPluginRepo() []PluginJSON {
resp, err := http.Get(pluginsRepo)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var pk []PluginJSON
json.Unmarshal(body, &pk)
c.Repos = pk
return pk
}
2018-06-14 06:38:15 +00:00
func DownloadFile(filepath string, url string) error {
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
}
func SelectSettings(p plugin.Info) map[string]string {
data := make(map[string]string)
var tableInput []string
for _, v := range p.Form {
val := fmt.Sprintf("%v", v.InputName)
tableInput = append(tableInput, val)
}
ins := strings.Join(tableInput, ", ")
sql := fmt.Sprintf("SELECT %v FROM settings_%v LIMIT 1", ins, p.Name)
rows, err := db.Query(sql)
if err != nil {
fmt.Println("SQL ERROR: ", err)
return map[string]string{}
}
count := len(p.Form)
valuePtrs := make([]interface{}, count)
values := make([]interface{}, count)
for rows.Next() {
for i, _ := range p.Form {
valuePtrs[i] = &values[i]
}
err = rows.Scan(valuePtrs...)
if err != nil {
panic(err)
}
for i, col := range p.Form {
val := values[i]
b, _ := val.([]byte)
realVal := string(b)
//col.ChangeVal(realVal)
fmt.Println(col.Value, realVal)
data[col.InputName] = realVal
}
}
return data
}
func CreateSettingsTable(p plugin.Info) string {
var tableValues []string
tableValues = append(tableValues, "plugin text")
tableValues = append(tableValues, "enabled bool")
for _, v := range p.Form {
tb := fmt.Sprintf("%v %v", v.InputName, v.InputType)
tableValues = append(tableValues, tb)
}
vals := strings.Join(tableValues, ", ")
out := fmt.Sprintf("CREATE TABLE settings_%v (%v);", p.Name, vals)
smtp, _ := db.Prepare(out)
_, _ = smtp.Exec()
InitalSettings(p)
return out
}
func InitalSettings(p plugin.Info) {
var tableValues []string
var tableInput []string
tableValues = append(tableValues, "plugin")
tableInput = append(tableInput, fmt.Sprintf("'%v'", p.Name))
tableValues = append(tableValues, "enabled")
tableInput = append(tableInput, "false")
for _, v := range p.Form {
val := fmt.Sprintf("'%v'", v.Value)
tableValues = append(tableValues, v.InputName)
tableInput = append(tableInput, val)
}
vals := strings.Join(tableValues, ",")
ins := strings.Join(tableInput, ",")
sql := fmt.Sprintf("INSERT INTO settings_%v(%v) VALUES(%v);", p.Name, vals, ins)
smtp, _ := db.Prepare(sql)
_, _ = smtp.Exec()
}
func UpdateSettings(p plugin.Info, data map[string]string) {
var tableInput []string
for _, v := range p.Form {
newValue := data[v.InputName]
val := fmt.Sprintf("%v='%v'", v.InputName, newValue)
tableInput = append(tableInput, val)
}
ins := strings.Join(tableInput, ", ")
sql := fmt.Sprintf("UPDATE settings_%v SET %v WHERE plugin='%v';", p.Name, ins, p.Name)
smtp, _ := db.Prepare(sql)
_, _ = smtp.Exec()
}
2018-06-14 01:19:00 +00:00
//func DownloadPlugin(name string) {
// plugin := SelectPlugin(name)
// var _, err = os.Stat("plugins/" + plugin.Namespace)
// if err != nil {
// }
// if os.IsNotExist(err) {
// var file, _ = os.Create("plugins/" + plugin.Namespace)
// defer file.Close()
// }
// resp, err := http.Get("https://raw.githubusercontent.com/hunterlong/statup/master/plugins.json")
// if err != nil {
// panic(err)
// }
// defer resp.Body.Close()
// body, err := ioutil.ReadAll(resp.Body)
// if err != nil {
// panic(err)
// }
// file, err := os.OpenFile("plugins/"+plugin.Namespace, os.O_RDWR, 0644)
// if err != nil {
// panic(err)
// }
// defer file.Close()
//
// _, err = file.Write(body)
// if err != nil {
// panic(err)
// }
// err = file.Sync()
//}
2018-06-12 07:21:16 +00:00
2018-06-10 01:31:13 +00:00
func main() {
VERSION = "1.1.1"
2018-06-11 09:58:41 +00:00
fmt.Printf("Starting Statup v%v\n", VERSION)
2018-06-10 01:31:13 +00:00
RenderBoxes()
configs = LoadConfig()
if configs == nil {
fmt.Println("config.yml file not found - starting in setup mode")
setupMode = true
RunHTTPServer()
}
mainProcess()
}
func mainProcess() {
var err error
DbConnection()
core, err = SelectCore()
if err != nil {
2018-06-14 06:38:15 +00:00
throw(err)
2018-06-10 01:31:13 +00:00
}
go CheckServices()
if !setupMode {
2018-06-11 07:49:41 +00:00
LoadPlugins()
2018-06-10 01:31:13 +00:00
RunHTTPServer()
}
}
2018-06-14 06:38:15 +00:00
func throw(err error) {
fmt.Println(err)
os.Exit(1)
}
2018-06-11 09:58:41 +00:00
func ForEachPlugin() {
if len(core.Plugins) > 0 {
//for _, p := range core.Plugins {
// p.OnShutdown()
//}
}
}
2018-06-11 07:49:41 +00:00
func LoadPlugins() {
2018-06-12 07:21:16 +00:00
if _, err := os.Stat("./plugins"); os.IsNotExist(err) {
os.Mkdir("./plugins", os.ModePerm)
}
2018-06-11 09:58:41 +00:00
ForEachPlugin()
2018-06-11 07:49:41 +00:00
files, err := ioutil.ReadDir("./plugins")
if err != nil {
fmt.Printf("Plugins directory was not found. Error: %v\n", err)
return
}
for _, f := range files {
ext := strings.Split(f.Name(), ".")
if len(ext) != 2 {
continue
}
2018-06-11 10:19:08 +00:00
if ext[1] != "so" {
continue
}
plug, err := plg.Open("plugins/" + f.Name())
if err != nil {
fmt.Printf("Plugin '%v' could not load correctly.\n", f.Name())
continue
2018-06-11 07:49:41 +00:00
}
2018-06-11 10:19:08 +00:00
symPlugin, err := plug.Lookup("Plugin")
2018-06-14 06:38:15 +00:00
2018-06-11 10:19:08 +00:00
var plugActions plugin.PluginActions
plugActions, ok := symPlugin.(plugin.PluginActions)
if !ok {
fmt.Printf("Plugin '%v' could not load correctly, error: %v\n", f.Name(), "unexpected type from module symbol")
continue
}
plugActions.OnLoad()
2018-06-14 01:19:00 +00:00
allPlugins = append(allPlugins, plugActions)
core.Plugins = append(core.Plugins, plugActions.GetInfo())
2018-06-11 07:49:41 +00:00
}
2018-06-14 01:19:00 +00:00
2018-06-11 07:49:41 +00:00
fmt.Printf("Loaded %v Plugins\n", len(allPlugins))
2018-06-11 09:58:41 +00:00
ForEachPlugin()
2018-06-11 07:49:41 +00:00
}
2018-06-10 01:31:13 +00:00
func RenderBoxes() {
sqlBox = rice.MustFindBox("sql")
cssBox = rice.MustFindBox("html/css")
jsBox = rice.MustFindBox("html/js")
tmplBox = rice.MustFindBox("html/tmpl")
}
func LoadConfig() *Config {
var config Config
file, err := ioutil.ReadFile("config.yml")
if err != nil {
return nil
}
yaml.Unmarshal(file, &config)
return &config
}
func HashPassword(password string) string {
bytes, _ := bcrypt.GenerateFromPassword([]byte(password), 14)
return string(bytes)
}