Merge pull request #11 from hunterlong/dev

upgrades n updates
pull/12/merge
Hunter Long 2018-07-04 19:03:17 -07:00 committed by GitHub
commit a845f2531a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 170 additions and 81 deletions

View File

@ -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"

View File

@ -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

View File

@ -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 && \

View File

@ -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
View File

@ -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")
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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,

View File

@ -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,

View File

@ -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 (

View File

@ -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>