mirror of https://github.com/statping/statping
commit
a845f2531a
|
@ -18,7 +18,7 @@ services:
|
|||
|
||||
env:
|
||||
global:
|
||||
- VERSION=0.29.4
|
||||
- VERSION=0.29.5
|
||||
- DB_HOST=localhost
|
||||
- DB_USER=travis
|
||||
- DB_PASS=
|
||||
|
@ -37,6 +37,7 @@ before_deploy:
|
|||
deploy:
|
||||
- provider: releases
|
||||
api_key: $GH_TOKEN
|
||||
if: branch = master
|
||||
file:
|
||||
- "build/statup-osx-x64.tar.gz"
|
||||
- "build/statup-osx-x32.tar.gz"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# update homebrew to newest version by building on travis
|
||||
# update homebrew and cypress testing to newest version by building on travis
|
||||
body='{ "request": { "branch": "master", "config": { "env": { "VERSION": "'$VERSION'" } } } }'
|
||||
|
||||
curl -s -X POST \
|
||||
|
@ -11,10 +11,18 @@ curl -s -X POST \
|
|||
-d "$body" \
|
||||
https://api.travis-ci.com/repo/hunterlong%2Fstatup-testing/requests
|
||||
|
||||
#git clone https://$GH_USER:$GH_TOKEN@github.com/hunterlong/homebrew-statup.git
|
||||
#cd homebrew-statup
|
||||
#
|
||||
#./build.sh
|
||||
#cd ../
|
||||
# notify Docker hub to built this branch
|
||||
if [ "$TRAVIS_BRANCH" == "master" ]
|
||||
then
|
||||
curl -s -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Travis-API-Version: 3" \
|
||||
-H "Authorization: token $TRAVIS_API" \
|
||||
-d "$body" \
|
||||
https://api.travis-ci.com/repo/hunterlong%2Fhomebrew-statup/requests
|
||||
|
||||
curl -H "Content-Type: application/json" --data '{"source_type": "Branch", "source_name": "'"$TRAVIS_BRANCH"'"}' -X POST $DOCKER > /dev/null
|
||||
curl -H "Content-Type: application/json" --data '{"docker_tag": "latest"}' -X POST $DOCKER
|
||||
else
|
||||
curl -H "Content-Type: application/json" --data '{"source_type": "Branch", "source_name": "'"$TRAVIS_BRANCH"'"}' -X POST $DOCKER > /dev/null
|
||||
fi
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
FROM alpine:latest
|
||||
|
||||
ENV VERSION=v0.29.4
|
||||
ENV VERSION=v0.29.5
|
||||
|
||||
RUN apk --no-cache add libstdc++ ca-certificates
|
||||
RUN wget -q https://github.com/hunterlong/statup/releases/download/$VERSION/statup-linux-alpine.tar.gz && \
|
||||
|
|
|
@ -13,7 +13,7 @@ An easy to use Status Page for your websites and applications. Statup will autom
|
|||
Statup strives to remain future-proof and remain intact if a failure is created. Your Statup service should not be running on the same instance you're trying to monitor. If your server crashes your Status Page should still remaining online to notify your users of downtime.
|
||||
|
||||
<p align="center">
|
||||
<img width="80%" src="https://s3-us-west-2.amazonaws.com/gitimgs/statuphead1.png">
|
||||
<img width="80%" src="https://s3-us-west-2.amazonaws.com/gitimgs/statupsiterun.gif">
|
||||
</p>
|
||||
|
||||
## Lightweight and Fast
|
||||
|
@ -27,14 +27,15 @@ Statup is built in Go Language so all you need is the precompile binary based on
|
|||
Statup will allow you to completely customize your Status Page using SASS styling with easy to use variables. The Docker image actually contains a prebuilt SASS binary so you won't even need to setup anything!
|
||||
|
||||
<p align="center">
|
||||
<img width="100%" src="https://s3-us-west-2.amazonaws.com/gitimgs/statupstyler.png">
|
||||
<img width="100%" src="https://s3-us-west-2.amazonaws.com/gitimgs/statupthempicker.gif">
|
||||
</p>
|
||||
|
||||
## Mobile View is Gorgeous
|
||||
Your status page will be optimized for mobile and desktop viewers. Statup has a full width edge to edge view, which you can also edit to meet your requirements.
|
||||
|
||||
<p align="center">
|
||||
<img width="40%" src="https://s3-us-west-2.amazonaws.com/gitimgs/statupmob1.jpg">
|
||||
<img width="30%" src="https://s3-us-west-2.amazonaws.com/gitimgs/mobileview.gif">
|
||||
<img width="30%" src="https://s3-us-west-2.amazonaws.com/gitimgs/statupmobile2.gif">
|
||||
</p>
|
||||
|
||||
## Run on Any Server
|
||||
|
@ -57,7 +58,7 @@ Plugin are created in Golang using the [statup/plugin](https://github.com/hunter
|
|||
## Easy to use Dashboard
|
||||
Having a straight forward dashboard makes Statup that much better. Monitor your websites and applications with a basic HTTP GET request, or add a POST request with your own JSON to post to the endpoint.
|
||||
<p align="center">
|
||||
<img width="80%" src="https://s3-us-west-2.amazonaws.com/gitimgs/statupcreat.png">
|
||||
<img width="80%" src="https://s3-us-west-2.amazonaws.com/gitimgs/statupsettingsview.gif">
|
||||
</p>
|
||||
|
||||
## Exporting Static HTML
|
||||
|
|
175
cli.go
175
cli.go
|
@ -4,8 +4,10 @@ import (
|
|||
"fmt"
|
||||
"github.com/hunterlong/statup/core"
|
||||
"github.com/hunterlong/statup/plugin"
|
||||
"github.com/hunterlong/statup/types"
|
||||
"github.com/hunterlong/statup/utils"
|
||||
"github.com/joho/godotenv"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
"upper.io/db.v3/sqlite"
|
||||
|
@ -111,9 +113,9 @@ func HelpEcho() {
|
|||
}
|
||||
|
||||
func TestPlugin(plug plugin.PluginActions) {
|
||||
RenderBoxes()
|
||||
defer utils.DeleteFile("./.plugin_test.db")
|
||||
core.CoreApp.AllPlugins = []plugin.PluginActions{plug}
|
||||
RenderBoxes()
|
||||
|
||||
info := plug.GetInfo()
|
||||
fmt.Printf("\n" + BRAKER + "\n")
|
||||
fmt.Printf(" Plugin Name: %v\n", info.Name)
|
||||
|
@ -123,25 +125,91 @@ func TestPlugin(plug plugin.PluginActions) {
|
|||
fmt.Printf(" - Route %v - (%v) /%v \n", k+1, r.Method, r.URL)
|
||||
}
|
||||
|
||||
// Function to create a new Core with example services, hits, failures, users, and default communications
|
||||
FakeSeed(plug)
|
||||
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnLoad(sqlbuilder.Database)'")
|
||||
core.OnLoad(core.DbSession)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnSuccess(Service)'")
|
||||
core.OnSuccess(core.SelectService(1))
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnFailure(Service, FailureData)'")
|
||||
fakeFailD := core.FailureData{
|
||||
Issue: "No issue, just testing this plugin. This would include HTTP failure information though",
|
||||
}
|
||||
core.OnFailure(core.SelectService(1), fakeFailD)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnSettingsSaved(Core)'")
|
||||
fmt.Println(BRAKER)
|
||||
core.OnSettingsSaved(core.CoreApp)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnNewService(Service)'")
|
||||
core.OnNewService(core.SelectService(2))
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnNewUser(User)'")
|
||||
user, _ := core.SelectUser(1)
|
||||
core.OnNewUser(user)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnUpdateService(Service)'")
|
||||
srv := core.SelectService(2)
|
||||
srv.Type = "http"
|
||||
srv.Domain = "https://yahoo.com"
|
||||
core.OnUpdateService(srv)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnDeletedService(Service)'")
|
||||
core.OnDeletedService(core.SelectService(1))
|
||||
fmt.Println("\n" + BRAKER)
|
||||
}
|
||||
|
||||
func FakeSeed(plug plugin.PluginActions) {
|
||||
var err error
|
||||
core.CoreApp = core.NewCore()
|
||||
|
||||
core.CoreApp.AllPlugins = []plugin.PluginActions{plug}
|
||||
|
||||
fmt.Printf("\n" + BRAKER)
|
||||
|
||||
fmt.Println("\nCreating a SQLite database for testing, will be deleted automatically...")
|
||||
sqlFake := sqlite.ConnectionURL{
|
||||
Database: "./.plugin_test.db",
|
||||
}
|
||||
core.DbSession, err = sqlite.Open(sqlFake)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
}
|
||||
up, _ := core.SqlBox.String("sqlite_up.sql")
|
||||
requests := strings.Split(up, ";")
|
||||
for _, request := range requests {
|
||||
_, err := core.DbSession.Exec(request)
|
||||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("Finished creating Test SQLite database")
|
||||
fmt.Println("Inserting example services into test database...")
|
||||
|
||||
core.CoreApp.Name = "Plugin Test"
|
||||
core.CoreApp.Description = "This is a fake Core for testing your plugin"
|
||||
core.CoreApp.Domain = "http://localhost:8080"
|
||||
core.CoreApp.ApiSecret = "0x0x0x0x0"
|
||||
core.CoreApp.ApiKey = "abcdefg12345"
|
||||
|
||||
fakeSrv := &core.Service{
|
||||
Id: 56,
|
||||
Name: "Test Plugin Service",
|
||||
Domain: "https://google.com",
|
||||
Method: "GET",
|
||||
}
|
||||
fakeSrv.Create()
|
||||
|
||||
fakeFailD := core.FailureData{
|
||||
Issue: "No issue, just testing this plugin.",
|
||||
}
|
||||
|
||||
fakeCore := &core.Core{
|
||||
Name: "Plugin Test",
|
||||
Description: "This is a fake Core for testing your plugin",
|
||||
ApiSecret: "0x0x0x0x0",
|
||||
ApiKey: "abcdefg12345",
|
||||
Services: []*core.Service{fakeSrv},
|
||||
fakeSrv2 := &core.Service{
|
||||
Name: "Awesome Plugin Service",
|
||||
Domain: "https://netflix.com",
|
||||
Method: "GET",
|
||||
}
|
||||
fakeSrv2.Create()
|
||||
|
||||
fakeUser := &core.User{
|
||||
Id: 6334,
|
||||
|
@ -151,54 +219,49 @@ func TestPlugin(plug plugin.PluginActions) {
|
|||
Admin: true,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
fakeUser.Create()
|
||||
|
||||
fmt.Println("\nCreating a SQLite database for testing, will be deleted automatically...")
|
||||
sqlFake := sqlite.ConnectionURL{
|
||||
Database: "./.plugin_test.db",
|
||||
fakeUser = &core.User{
|
||||
Id: 6335,
|
||||
Username: "Billy",
|
||||
Password: "$2a$14$NzT/fLdE3f9iB1Eux2C84O6ZoPhI4NfY0Ke32qllCFo8pMTkUPZzy",
|
||||
Email: "info@awesome.com",
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
fakeDb, err := sqlite.Open(sqlFake)
|
||||
if err != nil {
|
||||
utils.Log(3, err)
|
||||
fakeUser.Create()
|
||||
|
||||
comm := &types.Communication{
|
||||
Id: 1,
|
||||
Method: "email",
|
||||
}
|
||||
up, _ := core.SqlBox.String("sqlite_up.sql")
|
||||
requests := strings.Split(up, ";")
|
||||
for _, request := range requests {
|
||||
_, err := fakeDb.Exec(request)
|
||||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
core.Create(comm)
|
||||
|
||||
comm2 := &types.Communication{
|
||||
Id: 2,
|
||||
Method: "slack",
|
||||
}
|
||||
core.Create(comm2)
|
||||
|
||||
for i := 0; i <= 50; i++ {
|
||||
dd := core.HitData{
|
||||
Latency: rand.Float64(),
|
||||
}
|
||||
fakeSrv.CreateHit(dd)
|
||||
dd = core.HitData{
|
||||
Latency: rand.Float64(),
|
||||
}
|
||||
fakeSrv2.CreateHit(dd)
|
||||
fail := core.FailureData{
|
||||
Issue: "This is not an issue, but it would container HTTP response errors.",
|
||||
}
|
||||
fakeSrv.CreateFailure(fail)
|
||||
|
||||
fail = core.FailureData{
|
||||
Issue: "HTTP Status Code 521 did not match 200",
|
||||
}
|
||||
fakeSrv2.CreateFailure(fail)
|
||||
}
|
||||
fmt.Println("Finished creating Test SQLite database, sending events.")
|
||||
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnLoad(sqlbuilder.Database)'")
|
||||
core.OnLoad(fakeDb)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnSuccess(Service)'")
|
||||
core.OnSuccess(fakeSrv)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnFailure(Service, FailureData)'")
|
||||
core.OnFailure(fakeSrv, fakeFailD)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnSettingsSaved(Core)'")
|
||||
fmt.Println(BRAKER)
|
||||
core.OnSettingsSaved(fakeCore)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnNewService(Service)'")
|
||||
core.OnNewService(fakeSrv)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnNewUser(User)'")
|
||||
core.OnNewUser(fakeUser)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnUpdateService(Service)'")
|
||||
core.OnUpdateService(fakeSrv)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
fmt.Println(POINT + "Sending 'OnDeletedService(Service)'")
|
||||
core.OnDeletedService(fakeSrv)
|
||||
fmt.Println("\n" + BRAKER)
|
||||
|
||||
}
|
||||
|
||||
func FakeSeed() {
|
||||
fmt.Println("Seeding example data is complete, running Plugin Tests")
|
||||
|
||||
}
|
||||
|
|
|
@ -244,8 +244,6 @@ func (u *Service) Create() (int64, error) {
|
|||
u.Id = uuid.(int64)
|
||||
u.stopRoutine = make(chan struct{})
|
||||
CoreApp.Services = append(CoreApp.Services, u)
|
||||
go u.CheckQueue()
|
||||
OnNewService(u)
|
||||
return uuid.(int64), err
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@ func (u *User) Create() (int64, error) {
|
|||
utils.Log(3, fmt.Sprintf("Failed to create user %v. %v", u.Username, err))
|
||||
return 0, err
|
||||
}
|
||||
OnNewUser(u)
|
||||
return uuid.(int64), err
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,10 @@ func CreateServiceHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if err != nil {
|
||||
utils.Log(3, fmt.Sprintf("Error starting %v check routine. %v", service.Name, err))
|
||||
}
|
||||
|
||||
go service.CheckQueue()
|
||||
core.OnNewService(service)
|
||||
|
||||
http.Redirect(w, r, "/services", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
|
|||
if err != nil {
|
||||
utils.Log(2, err)
|
||||
}
|
||||
core.OnNewUser(user)
|
||||
http.Redirect(w, r, "/users", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
|
14
main_test.go
14
main_test.go
|
@ -64,6 +64,10 @@ func TestRunAll(t *testing.T) {
|
|||
t.Run(dbt+" Create Users", func(t *testing.T) {
|
||||
RunUser_Create(t)
|
||||
})
|
||||
t.Run(dbt+" Create Non Unique Users", func(t *testing.T) {
|
||||
t.SkipNow()
|
||||
RunUser_NonUniqueCreate(t)
|
||||
})
|
||||
t.Run(dbt+" Select Users", func(t *testing.T) {
|
||||
RunUser_SelectAll(t)
|
||||
})
|
||||
|
@ -275,6 +279,16 @@ func RunUser_Create(t *testing.T) {
|
|||
assert.Equal(t, int64(2), id)
|
||||
}
|
||||
|
||||
func RunUser_NonUniqueCreate(t *testing.T) {
|
||||
user := &core.User{
|
||||
Username: "admin",
|
||||
Password: "admin",
|
||||
Email: "info@testuser.com",
|
||||
}
|
||||
_, err := user.Create()
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func RunUser_Delete(t *testing.T) {
|
||||
user, err := core.SelectUser(2)
|
||||
assert.Nil(t, err)
|
||||
|
|
|
@ -13,12 +13,13 @@ CREATE TABLE users (
|
|||
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
username VARCHAR(50),
|
||||
password text,
|
||||
email text,
|
||||
email VARCHAR (50),
|
||||
api_key VARCHAR(50),
|
||||
api_secret VARCHAR(50),
|
||||
administrator BOOL NOT NULL DEFAULT '0',
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX (id)
|
||||
INDEX (id),
|
||||
UNIQUE (username, email)
|
||||
);
|
||||
CREATE TABLE services (
|
||||
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
|
|
|
@ -12,9 +12,9 @@ CREATE TABLE core (
|
|||
|
||||
CREATE TABLE users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
username text,
|
||||
username VARCHAR (50) UNIQUE,
|
||||
password text,
|
||||
email text,
|
||||
email VARCHAR (50) UNIQUE,
|
||||
api_key text,
|
||||
api_secret text,
|
||||
administrator bool,
|
||||
|
|
|
@ -18,7 +18,8 @@ CREATE TABLE users (
|
|||
api_key text,
|
||||
api_secret text,
|
||||
administrator bool,
|
||||
created_at DATETIME
|
||||
created_at DATETIME,
|
||||
UNIQUE (username, email)
|
||||
);
|
||||
|
||||
CREATE TABLE services (
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
<div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
|
||||
|
||||
<div class="col-12 mt-3">
|
||||
<div class="col-8 offset-2 mt-3">
|
||||
|
||||
{{ if .Error }}
|
||||
<div class="alert alert-danger" role="alert">
|
||||
|
@ -35,9 +35,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-10">
|
||||
<button type="submit" class="btn btn-primary btn-block d-block d-md-none">Sign in</button>
|
||||
<button type="submit" class="btn btn-primary d-none d-md-block">Sign in</button>
|
||||
<div class="col-sm-12">
|
||||
<button type="submit" class="btn btn-primary btn-block">Sign in</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
Loading…
Reference in New Issue