mirror of https://github.com/statping/statping
parent
b81b76881f
commit
afd6ec52f1
|
@ -14,7 +14,7 @@ services:
|
||||||
- docker
|
- docker
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- VERSION=0.1
|
- VERSION=0.12
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
allow_failures:
|
allow_failures:
|
||||||
|
|
1
core.go
1
core.go
|
@ -12,6 +12,7 @@ type Core struct {
|
||||||
Secret string
|
Secret string
|
||||||
Version string
|
Version string
|
||||||
Plugins []plugin.Info
|
Plugins []plugin.Info
|
||||||
|
Repos []PluginJSON
|
||||||
}
|
}
|
||||||
|
|
||||||
func SelectCore() (*Core, error) {
|
func SelectCore() (*Core, error) {
|
||||||
|
|
|
@ -6,16 +6,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (f *Failure) ParseError() string {
|
func (f *Failure) ParseError() string {
|
||||||
|
|
||||||
err := strings.Contains(f.Issue, "operation timed out")
|
err := strings.Contains(f.Issue, "operation timed out")
|
||||||
if err {
|
if err {
|
||||||
return fmt.Sprintf("HTTP Request timed out after x seconds")
|
return fmt.Sprintf("HTTP Request timed out after x seconds")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = strings.Contains(f.Issue, "x509: certificate is valid")
|
err = strings.Contains(f.Issue, "x509: certificate is valid")
|
||||||
if err {
|
if err {
|
||||||
return fmt.Sprintf("SSL Certificate invalid")
|
return fmt.Sprintf("SSL Certificate invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
return f.Issue
|
return f.Issue
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
||||||
|
|
||||||
{{template "nav"}}
|
{{template "nav"}}
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
|
|
||||||
<div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
|
<div class="nav flex-column nav-pills" id="v-pills-tab" role="tablist" aria-orientation="vertical">
|
||||||
<a class="nav-link active" id="v-pills-home-tab" data-toggle="pill" href="#v-pills-home" role="tab" aria-controls="v-pills-home" aria-selected="true">Settings</a>
|
<a class="nav-link active" id="v-pills-home-tab" data-toggle="pill" href="#v-pills-home" role="tab" aria-controls="v-pills-home" aria-selected="true">Settings</a>
|
||||||
|
<a class="nav-link" id="v-pills-browse-tab" data-toggle="pill" href="#v-pills-browse" role="tab" aria-controls="v-pills-home" aria-selected="true">Browse Plugins</a>
|
||||||
{{ range .Plugins }}
|
{{ range .Plugins }}
|
||||||
<a class="nav-link text-capitalize" id="v-pills-{{.Name}}-tab" data-toggle="pill" href="#v-pills-{{.Name}}" role="tab" aria-controls="v-pills-profile" aria-selected="false">{{.Name}}</a>
|
<a class="nav-link text-capitalize" id="v-pills-{{.Name}}-tab" data-toggle="pill" href="#v-pills-{{.Name}}" role="tab" aria-controls="v-pills-profile" aria-selected="false">{{.Name}}</a>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
@ -29,15 +31,27 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="col-8">
|
<div class="col-8">
|
||||||
<div class="tab-content" id="v-pills-tabContent">
|
<div class="tab-content" id="v-pills-tabContent">
|
||||||
<div class="tab-pane fade show active" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab">...</div>
|
<div class="tab-pane fade show active" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab">
|
||||||
|
<h3>Settings</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab-pane fade" id="v-pills-browse" role="tabpanel" aria-labelledby="v-pills-browse-tab">
|
||||||
|
{{ range .Repos }}
|
||||||
|
<div class="card col-6" style="width: 18rem;">
|
||||||
|
<div class="card-body">
|
||||||
|
<h5 class="card-title">{{ .Name }}</h5>
|
||||||
|
<p class="card-text">{{ .Description }}</p>
|
||||||
|
<a href="/plugins/download/{{ .Name }}" class="card-link">Add</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
{{ range .Plugins }}
|
{{ range .Plugins }}
|
||||||
<div class="tab-pane fade" id="v-pills-{{.Name}}" role="tabpanel" aria-labelledby="v-pills-{{.Name}}-tab">
|
<div class="tab-pane fade" id="v-pills-{{.Name}}" role="tabpanel" aria-labelledby="v-pills-{{.Name}}-tab">
|
||||||
|
|
||||||
<form action="/plugins/{{.Name}}/save" method="POST">
|
<form action="/plugins/{{.Name}}/save" method="POST">
|
||||||
{{safe .Form }}
|
{{safe .Form }}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
|
76
main.go
76
main.go
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/GeertJohan/go.rice"
|
"github.com/GeertJohan/go.rice"
|
||||||
"github.com/go-yaml/yaml"
|
"github.com/go-yaml/yaml"
|
||||||
|
@ -10,6 +11,8 @@ import (
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
plg "plugin"
|
plg "plugin"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
@ -28,6 +31,10 @@ var (
|
||||||
allPlugins []plg.Plugin
|
allPlugins []plg.Plugin
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
pluginsRepo = "https://raw.githubusercontent.com/hunterlong/statup/master/plugins.json"
|
||||||
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Connection string `yaml:"connection"`
|
Connection string `yaml:"connection"`
|
||||||
Host string `yaml:"host"`
|
Host string `yaml:"host"`
|
||||||
|
@ -38,6 +45,71 @@ type Config struct {
|
||||||
Secret string `yaml:"secret"`
|
Secret string `yaml:"secret"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
func SelectPlugin(name string) *PluginJSON {
|
||||||
|
for _, v := range core.FetchPluginRepo() {
|
||||||
|
if v.Namespace == name {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
VERSION = "1.1.1"
|
VERSION = "1.1.1"
|
||||||
fmt.Printf("Starting Statup v%v\n", VERSION)
|
fmt.Printf("Starting Statup v%v\n", VERSION)
|
||||||
|
@ -74,6 +146,10 @@ func ForEachPlugin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadPlugins() {
|
func LoadPlugins() {
|
||||||
|
if _, err := os.Stat("./plugins"); os.IsNotExist(err) {
|
||||||
|
os.Mkdir("./plugins", os.ModePerm)
|
||||||
|
}
|
||||||
|
|
||||||
ForEachPlugin()
|
ForEachPlugin()
|
||||||
|
|
||||||
files, err := ioutil.ReadDir("./plugins")
|
files, err := ioutil.ReadDir("./plugins")
|
||||||
|
|
|
@ -3,7 +3,9 @@ package plugin
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -34,6 +36,27 @@ func (i Info) Template() *template.Template {
|
||||||
return temp
|
return temp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
type Add func(p PluginInfo)
|
type Add func(p PluginInfo)
|
||||||
|
|
||||||
type PluginActions interface {
|
type PluginActions interface {
|
||||||
|
|
19
web.go
19
web.go
|
@ -42,6 +42,7 @@ func RunHTTPServer() {
|
||||||
|
|
||||||
r.Handle("/settings", http.HandlerFunc(SettingsHandler))
|
r.Handle("/settings", http.HandlerFunc(SettingsHandler))
|
||||||
r.Handle("/plugins", http.HandlerFunc(PluginsHandler))
|
r.Handle("/plugins", http.HandlerFunc(PluginsHandler))
|
||||||
|
r.Handle("/plugins/download/{name}", http.HandlerFunc(PluginsDownloadHandler))
|
||||||
r.Handle("/help", http.HandlerFunc(HelpHandler))
|
r.Handle("/help", http.HandlerFunc(HelpHandler))
|
||||||
|
|
||||||
for _, p := range allPlugins {
|
for _, p := range allPlugins {
|
||||||
|
@ -251,7 +252,23 @@ func PluginsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tmpl := ParsePlugins("plugins.html")
|
tmpl := ParsePlugins("plugins.html")
|
||||||
tmpl.Execute(w, core)
|
core.FetchPluginRepo()
|
||||||
|
|
||||||
|
fmt.Println(core.FetchPluginRepo())
|
||||||
|
tmpl.Execute(w, &core)
|
||||||
|
}
|
||||||
|
|
||||||
|
func PluginsDownloadHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
auth := IsAuthenticated(r)
|
||||||
|
if !auth {
|
||||||
|
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
name := vars["name"]
|
||||||
|
DownloadPlugin(name)
|
||||||
|
LoadConfig()
|
||||||
|
http.Redirect(w, r, "/plugins", http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
|
||||||
func HelpHandler(w http.ResponseWriter, r *http.Request) {
|
func HelpHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
Loading…
Reference in New Issue