pull/78/head
Hunter Long 2018-09-12 14:29:47 -07:00
parent 685197bd72
commit 4b51cf4081
8 changed files with 1108 additions and 11 deletions

View File

@ -1,4 +1,4 @@
FROM hunterlong/statup:base-v0.57
FROM hunterlong/statup:base-v0.59
MAINTAINER "Hunter Long (https://github.com/hunterlong)"
# Locked version of Statup for 'latest' Docker tag

View File

@ -1,4 +1,4 @@
VERSION=0.58
VERSION=0.59
BINARY_NAME=statup
GOPATH:=$(GOPATH)
GOCMD=go

View File

@ -54,7 +54,9 @@ func (u *User) Delete() error {
// Update will update the user's record in database
func (u *User) Update() error {
u.CreatedAt = time.Now()
u.Password = utils.HashPassword(u.Password)
u.ApiKey = utils.NewSHA1Hash(5)
u.ApiSecret = utils.NewSHA1Hash(10)
return usersDB().Update(u).Error
}

455
dev/postman.json Normal file
View File

@ -0,0 +1,455 @@
{
"info": {
"_postman_id": "d74ac4a3-8915-46e8-8ed2-5044ea4ce53b",
"name": "Statup",
"description": "Statup API Requests",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "Main",
"item": [
{
"name": "Statup Details",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_key}}",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {},
"url": {
"raw": "{{endpoint}}/api",
"host": [
"{{endpoint}}"
],
"path": [
"api"
]
}
},
"response": []
}
],
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_key}}",
"type": "string"
}
]
}
},
{
"name": "Services",
"item": [
{
"name": "View All Services",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_key}}",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {},
"url": {
"raw": "{{endpoint}}/api/services",
"host": [
"{{endpoint}}"
],
"path": [
"api",
"services"
]
}
},
"response": []
},
{
"name": "View Service",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_key}}",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {},
"url": {
"raw": "{{endpoint}}/api/services/1",
"host": [
"{{endpoint}}"
],
"path": [
"api",
"services",
"1"
]
}
},
"response": []
},
{
"name": "Create Service",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_key}}",
"type": "string"
}
]
},
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"name\": \"New Service\",\n \"domain\": \"https://google.com\",\n \"expected\": \"\",\n \"expected_status\": 200,\n \"check_interval\": 15,\n \"type\": \"http\",\n \"method\": \"GET\",\n \"post_data\": \"\",\n \"port\": 0,\n \"timeout\": 10,\n \"order_id\": 0\n}"
},
"url": {
"raw": "{{endpoint}}/api/services",
"host": [
"{{endpoint}}"
],
"path": [
"api",
"services"
]
}
},
"response": []
},
{
"name": "Update Service",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_key}}",
"type": "string"
}
]
},
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"name\": \"Updated Service\",\n \"domain\": \"https://google.com\",\n \"expected\": \"\",\n \"expected_status\": 200,\n \"check_interval\": 60,\n \"type\": \"http\",\n \"method\": \"GET\",\n \"post_data\": \"\",\n \"port\": 0,\n \"timeout\": 10,\n \"order_id\": 0\n}"
},
"url": {
"raw": "{{endpoint}}/api/services/19",
"host": [
"{{endpoint}}"
],
"path": [
"api",
"services",
"19"
]
}
},
"response": []
},
{
"name": "Delete Service",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_key}}",
"type": "string"
}
]
},
"method": "DELETE",
"header": [],
"body": {},
"url": {
"raw": "{{endpoint}}/api/services/1",
"host": [
"{{endpoint}}"
],
"path": [
"api",
"services",
"1"
]
}
},
"response": []
}
],
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_key}}",
"type": "string"
}
]
},
"event": [
{
"listen": "prerequest",
"script": {
"id": "4cd2ab82-e60d-45cd-9b74-cb4b5d893f4d",
"type": "text/javascript",
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"id": "c7cb2b6d-289a-4073-b291-202bbec8cb44",
"type": "text/javascript",
"exec": [
""
]
}
}
]
},
{
"name": "Users",
"item": [
{
"name": "View All Users",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_key}}",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {},
"url": {
"raw": "{{endpoint}}/api/users",
"host": [
"{{endpoint}}"
],
"path": [
"api",
"users"
]
}
},
"response": []
},
{
"name": "View User",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_key}}",
"type": "string"
}
]
},
"method": "GET",
"header": [],
"body": {},
"url": {
"raw": "{{endpoint}}/api/users/1",
"host": [
"{{endpoint}}"
],
"path": [
"api",
"users",
"1"
]
}
},
"response": []
},
{
"name": "Create User",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_key}}",
"type": "string"
}
]
},
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"username\": \"admin\",\n \"email\": \"info@email.com\",\n \"password\": \"password123\",\n \"admin\": true\n}"
},
"url": {
"raw": "{{endpoint}}/api/users",
"host": [
"{{endpoint}}"
],
"path": [
"api",
"users"
]
}
},
"response": []
},
{
"name": "Update User",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_key}}",
"type": "string"
}
]
},
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"username\": \"adminupdated\",\n \"email\": \"info@email.com\",\n \"password\": \"password123\",\n \"admin\": true\n}"
},
"url": {
"raw": "{{endpoint}}/api/users/4",
"host": [
"{{endpoint}}"
],
"path": [
"api",
"users",
"4"
]
}
},
"response": []
},
{
"name": "Delete User",
"request": {
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_key}}",
"type": "string"
}
]
},
"method": "DELETE",
"header": [],
"body": {},
"url": {
"raw": "{{endpoint}}/api/users/4",
"host": [
"{{endpoint}}"
],
"path": [
"api",
"users",
"4"
]
}
},
"response": []
}
],
"auth": {
"type": "bearer",
"bearer": [
{
"key": "token",
"value": "{{api_key}}",
"type": "string"
}
]
},
"event": [
{
"listen": "prerequest",
"script": {
"id": "9720db1a-bc4c-4e05-94ea-2782aaafb793",
"type": "text/javascript",
"exec": [
""
]
}
},
{
"listen": "test",
"script": {
"id": "c667ae2d-41f3-4dea-ab62-3b544e2bc8f9",
"type": "text/javascript",
"exec": [
""
]
}
}
]
}
]
}

611
dev/swagger.json Normal file
View File

@ -0,0 +1,611 @@
{
"swagger": "2.0",
"info": {
"version": "1.0",
"title": "Statup",
"description": "Statup API Requests"
},
"host": "example.com",
"basePath": "/",
"securityDefinitions": {
"auth": {
"type": "oauth2",
"flow": "implicit",
"authorizationUrl": "http://example.com",
"scopes": {}
}
},
"schemes": [
"http"
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"paths": {
"/api": {
"get": {
"description": "TODO: Add Description",
"summary": "Statup Details",
"tags": [
"Main"
],
"operationId": "ApiGet",
"produces": [
"application/json"
],
"parameters": [],
"responses": {
"200": {
"description": ""
}
},
"security": [
{
"auth": []
}
]
}
},
"/api/services": {
"get": {
"description": "TODO: Add Description",
"summary": "View All Services",
"tags": [
"Services"
],
"operationId": "ApiServicesGet",
"produces": [
"application/json"
],
"parameters": [],
"responses": {
"200": {
"description": ""
}
},
"security": [
{
"auth": []
}
]
},
"post": {
"description": "TODO: Add Description",
"summary": "Create Service",
"tags": [
"Services"
],
"operationId": "ApiServicesPost",
"produces": [
"application/json"
],
"parameters": [
{
"name": "Content-Type",
"in": "header",
"required": true,
"type": "string",
"description": ""
},
{
"name": "Body",
"in": "body",
"required": true,
"description": "",
"schema": {
"$ref": "#/definitions/CreateServicerequest"
}
}
],
"responses": {
"200": {
"description": ""
}
},
"security": [
{
"auth": []
}
]
}
},
"/api/services/1": {
"get": {
"description": "TODO: Add Description",
"summary": "View Service",
"tags": [
"Services"
],
"operationId": "ApiServices1Get",
"produces": [
"application/json"
],
"parameters": [],
"responses": {
"200": {
"description": ""
}
},
"security": [
{
"auth": []
}
]
},
"delete": {
"description": "TODO: Add Description",
"summary": "Delete Service",
"tags": [
"Services"
],
"operationId": "ApiServices1Delete",
"produces": [
"application/json"
],
"parameters": [],
"responses": {
"200": {
"description": ""
}
},
"security": [
{
"auth": []
}
]
}
},
"/api/services/19": {
"post": {
"description": "TODO: Add Description",
"summary": "Update Service",
"tags": [
"Services"
],
"operationId": "ApiServices19Post",
"produces": [
"application/json"
],
"parameters": [
{
"name": "Content-Type",
"in": "header",
"required": true,
"type": "string",
"description": ""
},
{
"name": "Body",
"in": "body",
"required": true,
"description": "",
"schema": {
"$ref": "#/definitions/UpdateServicerequest"
}
}
],
"responses": {
"200": {
"description": ""
}
},
"security": [
{
"auth": []
}
]
}
},
"/api/users": {
"get": {
"description": "TODO: Add Description",
"summary": "View All Users",
"tags": [
"Users"
],
"operationId": "ApiUsersGet",
"produces": [
"application/json"
],
"parameters": [],
"responses": {
"200": {
"description": ""
}
},
"security": [
{
"auth": []
}
]
},
"post": {
"description": "TODO: Add Description",
"summary": "Create User",
"tags": [
"Users"
],
"operationId": "ApiUsersPost",
"produces": [
"application/json"
],
"parameters": [
{
"name": "Content-Type",
"in": "header",
"required": true,
"type": "string",
"description": ""
},
{
"name": "Body",
"in": "body",
"required": true,
"description": "",
"schema": {
"$ref": "#/definitions/CreateUserrequest"
}
}
],
"responses": {
"200": {
"description": ""
}
},
"security": [
{
"auth": []
}
]
}
},
"/api/users/1": {
"get": {
"description": "TODO: Add Description",
"summary": "View User",
"tags": [
"Users"
],
"operationId": "ApiUsers1Get",
"produces": [
"application/json"
],
"parameters": [],
"responses": {
"200": {
"description": ""
}
},
"security": [
{
"auth": []
}
]
}
},
"/api/users/4": {
"post": {
"description": "TODO: Add Description",
"summary": "Update User",
"tags": [
"Users"
],
"operationId": "ApiUsers4Post",
"produces": [
"application/json"
],
"parameters": [
{
"name": "Content-Type",
"in": "header",
"required": true,
"type": "string",
"description": ""
},
{
"name": "Body",
"in": "body",
"required": true,
"description": "",
"schema": {
"$ref": "#/definitions/UpdateUserrequest"
}
}
],
"responses": {
"200": {
"description": ""
}
},
"security": [
{
"auth": []
}
]
},
"delete": {
"description": "TODO: Add Description",
"summary": "Delete User",
"tags": [
"Users"
],
"operationId": "ApiUsers4Delete",
"produces": [
"application/json"
],
"parameters": [],
"responses": {
"200": {
"description": ""
}
},
"security": [
{
"auth": []
}
]
}
}
},
"definitions": {
"CreateServicerequest": {
"title": "Create ServiceRequest",
"example": {
"name": "New Service",
"domain": "https://google.com",
"expected": "",
"expected_status": 200,
"check_interval": 15,
"type": "http",
"method": "GET",
"post_data": "",
"port": 0,
"timeout": 10,
"order_id": 0
},
"type": "object",
"properties": {
"name": {
"description": "",
"example": "New Service",
"type": "string"
},
"domain": {
"description": "",
"example": "https://google.com",
"type": "string"
},
"expected": {
"description": "",
"type": "string"
},
"expected_status": {
"description": "",
"example": 200,
"type": "integer",
"format": "int32"
},
"check_interval": {
"description": "",
"example": 15,
"type": "integer",
"format": "int32"
},
"type": {
"description": "",
"example": "http",
"type": "string"
},
"method": {
"description": "",
"example": "GET",
"type": "string"
},
"post_data": {
"description": "",
"type": "string"
},
"port": {
"description": "",
"example": 0,
"type": "integer",
"format": "int32"
},
"timeout": {
"description": "",
"example": 10,
"type": "integer",
"format": "int32"
},
"order_id": {
"description": "",
"example": 0,
"type": "integer",
"format": "int32"
}
},
"required": [
"name",
"domain",
"expected",
"expected_status",
"check_interval",
"type",
"method",
"post_data",
"port",
"timeout",
"order_id"
]
},
"UpdateServicerequest": {
"title": "Update ServiceRequest",
"example": {
"name": "Updated Service",
"domain": "https://google.com",
"expected": "",
"expected_status": 200,
"check_interval": 60,
"type": "http",
"method": "GET",
"post_data": "",
"port": 0,
"timeout": 10,
"order_id": 0
},
"type": "object",
"properties": {
"name": {
"description": "",
"example": "Updated Service",
"type": "string"
},
"domain": {
"description": "",
"example": "https://google.com",
"type": "string"
},
"expected": {
"description": "",
"type": "string"
},
"expected_status": {
"description": "",
"example": 200,
"type": "integer",
"format": "int32"
},
"check_interval": {
"description": "",
"example": 60,
"type": "integer",
"format": "int32"
},
"type": {
"description": "",
"example": "http",
"type": "string"
},
"method": {
"description": "",
"example": "GET",
"type": "string"
},
"post_data": {
"description": "",
"type": "string"
},
"port": {
"description": "",
"example": 0,
"type": "integer",
"format": "int32"
},
"timeout": {
"description": "",
"example": 10,
"type": "integer",
"format": "int32"
},
"order_id": {
"description": "",
"example": 0,
"type": "integer",
"format": "int32"
}
},
"required": [
"name",
"domain",
"expected",
"expected_status",
"check_interval",
"type",
"method",
"post_data",
"port",
"timeout",
"order_id"
]
},
"CreateUserrequest": {
"title": "Create UserRequest",
"example": {
"username": "admin",
"email": "info@email.com",
"password": "password123",
"admin": true
},
"type": "object",
"properties": {
"username": {
"description": "",
"example": "admin",
"type": "string"
},
"email": {
"description": "",
"example": "info@email.com",
"type": "string"
},
"password": {
"description": "",
"example": "password123",
"type": "string"
},
"admin": {
"description": "",
"example": true,
"type": "boolean"
}
},
"required": [
"username",
"email",
"password",
"admin"
]
},
"UpdateUserrequest": {
"title": "Update UserRequest",
"example": {
"username": "adminupdated",
"email": "info@email.com",
"password": "password123",
"admin": true
},
"type": "object",
"properties": {
"username": {
"description": "",
"example": "adminupdated",
"type": "string"
},
"email": {
"description": "",
"example": "info@email.com",
"type": "string"
},
"password": {
"description": "",
"example": "password123",
"type": "string"
},
"admin": {
"description": "",
"example": true,
"type": "boolean"
}
},
"required": [
"username",
"email",
"password",
"admin"
]
}
}
}

View File

@ -26,10 +26,10 @@ import (
)
type ApiResponse struct {
Object string `json:"type"`
Method string `json:"method"`
Id int64 `json:"id"`
Status string `json:"status"`
Object string `json:"type"`
Id int64 `json:"id"`
Method string `json:"method"`
}
func ApiIndexHandler(w http.ResponseWriter, r *http.Request) {
@ -37,7 +37,16 @@ func ApiIndexHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
out := core.CoreApp
var out core.Core
out = *core.CoreApp
var services []types.ServiceInterface
for _, s := range out.Services {
service := s.Select()
service.Failures = nil
services = append(services, core.ReturnService(service))
}
out.Services = services
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(out)
}
@ -79,6 +88,8 @@ func ApiServiceHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(service)
}
@ -100,6 +111,7 @@ func ApiCreateServiceHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(service)
}
@ -117,12 +129,15 @@ func ApiServiceUpdateHandler(w http.ResponseWriter, r *http.Request) {
var updatedService *types.Service
decoder := json.NewDecoder(r.Body)
decoder.Decode(&updatedService)
updatedService.Id = service.Id
service = core.ReturnService(updatedService)
err := service.Update(true)
if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
service.Check(true)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(service)
}
@ -148,6 +163,7 @@ func ApiServiceDeleteHandler(w http.ResponseWriter, r *http.Request) {
Id: service.Id,
Status: "success",
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(output)
}
@ -156,7 +172,14 @@ func ApiAllServicesHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
return
}
services := core.CoreApp.Services
allServices := core.CoreApp.Services
var services []types.ServiceInterface
for _, s := range allServices {
service := s.Select()
service.Failures = nil
services = append(services, core.ReturnService(service))
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(services)
}
@ -171,6 +194,7 @@ func ApiUserHandler(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(user)
}
@ -188,12 +212,14 @@ func ApiUserUpdateHandler(w http.ResponseWriter, r *http.Request) {
var updateUser *types.User
decoder := json.NewDecoder(r.Body)
decoder.Decode(&updateUser)
updateUser.Id = user.Id
user = core.ReturnUser(updateUser)
err = user.Update()
if err != nil {
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(user)
}
@ -219,6 +245,7 @@ func ApiUserDeleteHandler(w http.ResponseWriter, r *http.Request) {
Id: user.Id,
Status: "success",
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(output)
}
@ -228,6 +255,7 @@ func ApiAllUsersHandler(w http.ResponseWriter, r *http.Request) {
return
}
users, _ := core.SelectAllUsers()
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(users)
}
@ -255,6 +283,7 @@ func ApiCreateUsersHandler(w http.ResponseWriter, r *http.Request) {
Id: uId,
Status: "success",
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(output)
}

View File

@ -8,7 +8,7 @@ type Failure struct {
Id int64 `gorm:"primary_key;column:id" json:"id"`
Issue string `gorm:"column:issue" json:"issue"`
Method string `gorm:"column:method" json:"method,omitempty"`
Service int64 `gorm:"index;column:service" json:"service_id"`
Service int64 `gorm:"index;column:service" json:"-"`
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
FailureInterface `gorm:"-" json:"-"`
}

View File

@ -38,8 +38,6 @@ type Service struct {
Latency float64 `gorm:"-" json:"latency"`
Online24Hours float32 `gorm:"-" json:"24_hours_online"`
AvgResponse string `gorm:"-" json:"avg_response"`
Failures []interface{} `gorm:"-" json:"failures"`
Checkins []*Checkin `gorm:"-" json:"checkins"`
Running chan bool `gorm:"-" json:"-"`
Checkpoint time.Time `gorm:"-" json:"-"`
SleepDuration time.Duration `gorm:"-" json:"-"`
@ -47,6 +45,8 @@ type Service struct {
LastStatusCode int `gorm:"-" json:"status_code"`
LastOnline time.Time `gorm:"-" json:"last_online"`
DnsLookup float64 `gorm:"-" json:"dns_lookup_time"`
Failures []interface{} `gorm:"-" json:"failures,omitempty"`
Checkins []*Checkin `gorm:"-" json:"checkins,omitempty"`
}
type ServiceInterface interface {