@@ -66,7 +66,7 @@
-
+
{{group.name}} |
{{$store.getters.servicesInGroup(group.id).length}} |
@@ -121,23 +121,23 @@
value.forEach((s, k) => {
data.push({service: s.id, order: k+1})
});
- alert(JSON.stringify(data))
- const ord = await Api.services_reorder(data)
- alert(JSON.parse(ord))
+ await Api.services_reorder(data)
+ const services = await Api.services()
+ this.$store.commit('setServices', services)
}
},
groupsList: {
get() {
- return this.$store.state.groups
+ return this.$store.state.groupsInOrder
},
async set(value) {
let data = [];
value.forEach((s, k) => {
data.push({group: s.id, order: k+1})
});
- alert(JSON.stringify(data))
- const ord = await Api.services_reorder(data)
- alert(JSON.parse(ord))
+ await Api.groups_reorder(data)
+ const groups = await Api.groups()
+ this.$store.commit('setGroups', groups)
}
}
},
diff --git a/frontend/src/components/Dashboard/DashboardUsers.vue b/frontend/src/components/Dashboard/DashboardUsers.vue
index e8b92439..a2e0096b 100644
--- a/frontend/src/components/Dashboard/DashboardUsers.vue
+++ b/frontend/src/components/Dashboard/DashboardUsers.vue
@@ -5,6 +5,7 @@
Username |
+ Type |
|
@@ -12,6 +13,8 @@
|
{{user.username}} |
+ ADMIN |
+ USER |
Edit
diff --git a/frontend/src/forms/Group.vue b/frontend/src/forms/Group.vue
index 19f789f4..7cf527ac 100644
--- a/frontend/src/forms/Group.vue
+++ b/frontend/src/forms/Group.vue
@@ -25,8 +25,8 @@
@@ -52,6 +52,7 @@
},
data () {
return {
+ loading: false,
group: {
name: "",
public: true
@@ -70,13 +71,14 @@
},
async saveGroup(e) {
e.preventDefault();
+ this.loading = true
if (this.in_group) {
await this.updateGroup()
} else {
await this.createGroup()
}
+ this.loading = false
},
-
async createGroup() {
const g = this.group
const data = {name: g.name, public: g.public}
diff --git a/frontend/src/forms/Integration.vue b/frontend/src/forms/Integration.vue
new file mode 100644
index 00000000..2330bb67
--- /dev/null
+++ b/frontend/src/forms/Integration.vue
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
diff --git a/frontend/src/forms/Message.vue b/frontend/src/forms/Message.vue
index ea98727b..7370e9fd 100644
--- a/frontend/src/forms/Message.vue
+++ b/frontend/src/forms/Message.vue
@@ -74,7 +74,9 @@
-
diff --git a/frontend/src/forms/Notifier.vue b/frontend/src/forms/Notifier.vue
index e44cd3f2..e7d926db 100644
--- a/frontend/src/forms/Notifier.vue
+++ b/frontend/src/forms/Notifier.vue
@@ -1,7 +1,14 @@
@@ -72,8 +69,10 @@ export default {
},
data () {
return {
+ loading: false,
error: null,
saved: false,
+ ok: false,
}
},
mounted() {
@@ -82,6 +81,7 @@ export default {
methods: {
async saveNotifier(e) {
e.preventDefault();
+ this.loading = true
let form = {}
this.notifier.form.forEach((f) => {
form[f.field] = this.notifier[f.field]
@@ -93,12 +93,15 @@ export default {
const notifiers = await Api.notifiers()
this.$store.commit('setNotifiers', notifiers)
this.saved = true
+ this.loading = false
setTimeout(() => {
this.saved = false
}, 2000)
},
async testNotifier(e) {
e.preventDefault();
+ this.ok = false
+ this.loading = true
let form = {}
this.notifier.form.forEach((f) => {
form[f.field] = this.notifier[f.field]
@@ -106,13 +109,13 @@ export default {
form.enabled = this.notifier.enabled
form.limits = parseInt(this.notifier.limits)
form.method = this.notifier.method
- alert(JSON.stringify(form))
const tested = await Api.notifier_test(form)
- if (tested === "ok") {
- alert('This notifier seems to be working!')
+ if (tested === 'ok') {
+ this.ok = true
} else {
this.error = tested
}
+ this.loading = false
},
}
}
diff --git a/frontend/src/forms/Service.vue b/frontend/src/forms/Service.vue
index f5e76b4e..4269c5a8 100644
--- a/frontend/src/forms/Service.vue
+++ b/frontend/src/forms/Service.vue
@@ -168,6 +168,7 @@
name: 'FormService',
data () {
return {
+ loading: false,
service: {
name: "",
type: "http",
diff --git a/frontend/src/forms/User.vue b/frontend/src/forms/User.vue
index b5746966..0f015c64 100644
--- a/frontend/src/forms/User.vue
+++ b/frontend/src/forms/User.vue
@@ -11,7 +11,7 @@
@@ -101,149 +99,25 @@
-
- /api/services/7/data?start=1577937580&end=9999999999&group=hour |
- 13951 |
- 2020-01-15 20:00:10 -0800 -0800 |
+
+ {{cache.url}} |
+ {{cache.size}} |
+ {{cache.expiration}} |
- Clear Cache
+ Clear Cache
-
-
+
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -254,11 +128,13 @@
diff --git a/frontend/src/routes.js b/frontend/src/routes.js
index 4f22047f..529ae7c2 100644
--- a/frontend/src/routes.js
+++ b/frontend/src/routes.js
@@ -1,3 +1,4 @@
+import Help from './pages/Help';
import Index from "./pages/Index";
import Dashboard from "./pages/Dashboard";
import DashboardIndex from "./components/Dashboard/DashboardIndex";
@@ -5,12 +6,15 @@ import DashboardUsers from "./components/Dashboard/DashboardUsers";
import DashboardServices from "./components/Dashboard/DashboardServices";
import EditService from "./components/Dashboard/EditService";
import DashboardMessages from "./components/Dashboard/DashboardMessages";
+import Logs from './pages/Logs';
import Settings from "./pages/Settings";
import Login from "./pages/Login";
import Service from "./pages/Service";
import VueRouter from "vue-router";
import Setup from "./forms/Setup";
+import Api from "./components/API";
+
const routes = [
{
path: '/setup',
@@ -52,10 +56,10 @@ const routes = [
component: Settings
},{
path: 'logs',
- component: DashboardUsers
+ component: Logs
},{
path: 'help',
- component: DashboardUsers
+ component: Help
}]
},
{
@@ -79,15 +83,13 @@ const router = new VueRouter({
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
- const tk = localStorage.getItem("statping_user")
- if (tk !== null) {
- next()
- return
- }
- if (to.path !== '/login') {
+ const tk = Api.token()
+ if (to.path !== '/login' && !tk.token) {
next('/login')
return
}
+ next()
+ return
} else {
next()
}
diff --git a/frontend/src/store.js b/frontend/src/store.js
index a09e1617..c65bf122 100644
--- a/frontend/src/store.js
+++ b/frontend/src/store.js
@@ -25,7 +25,8 @@ export default new Vuex.Store({
groups: [],
messages: [],
users: [],
- notifiers: []
+ notifiers: [],
+ integrations: []
},
getters: {
hasAllData: state => state.hasAllData,
@@ -37,9 +38,10 @@ export default new Vuex.Store({
messages: state => state.messages,
users: state => state.users,
notifiers: state => state.notifiers,
+ integrations: state => state.integrations,
servicesInOrder: state => state.services.sort((a, b) => a.order_id - b.order_id),
- groupsCleaned: state => state.groups.filter(g => g.name !== ''),
+ groupsInOrder: state => state.groups.filter(g => g.name !== '').sort((a, b) => a.order_id - b.order_id),
serviceById: (state) => (id) => {
return state.services.find(s => s.id === id)
@@ -93,6 +95,9 @@ export default new Vuex.Store({
},
setNotifiers(state, notifiers) {
state.notifiers = notifiers
+ },
+ setIntegrations(state, integrations) {
+ state.integrations = integrations
}
},
actions: {
@@ -113,6 +118,8 @@ export default new Vuex.Store({
context.commit("setNotifiers", notifiers);
const users = await Api.users()
context.commit("setUsers", users);
+ const integrations = await Api.integrations()
+ context.commit("setIntegrations", integrations);
}
}
});
diff --git a/handlers/api.go b/handlers/api.go
index c98f8233..f9d94a77 100644
--- a/handlers/api.go
+++ b/handlers/api.go
@@ -86,9 +86,31 @@ func apiCoreHandler(w http.ResponseWriter, r *http.Request) {
returnJson(core.CoreApp, w, r)
}
+type cacheJson struct {
+ URL string `json:"url"`
+ Expiration int64 `json:"expiration"`
+ Size int `json:"size"`
+}
+
+func apiCacheHandler(w http.ResponseWriter, r *http.Request) {
+ cache := CacheStorage
+ var cacheList []cacheJson
+ for k, v := range cache.List() {
+ cacheList = append(cacheList, cacheJson{
+ URL: k,
+ Expiration: v.Expiration,
+ Size: len(v.Content),
+ })
+ }
+ returnJson(cacheList, w, r)
+}
+
func apiClearCacheHandler(w http.ResponseWriter, r *http.Request) {
CacheStorage = NewStorage()
- http.Redirect(w, r, basePath, http.StatusSeeOther)
+ output := apiResponse{
+ Status: "success",
+ }
+ returnJson(output, w, r)
}
func sendErrorJson(err error, w http.ResponseWriter, r *http.Request) {
diff --git a/handlers/dashboard.go b/handlers/dashboard.go
index d92e10c0..0a472d11 100644
--- a/handlers/dashboard.go
+++ b/handlers/dashboard.go
@@ -76,7 +76,7 @@ func logsHandler(w http.ResponseWriter, r *http.Request) {
logs = append(logs, utils.LastLines[i].FormatForHtml()+"\r\n")
}
utils.LockLines.Unlock()
- ExecuteResponse(w, r, "logs.gohtml", logs, nil)
+ returnJson(logs, w, r)
}
func logsLineHandler(w http.ResponseWriter, r *http.Request) {
diff --git a/handlers/handlers.go b/handlers/handlers.go
index 730e870d..a060ae0b 100644
--- a/handlers/handlers.go
+++ b/handlers/handlers.go
@@ -195,7 +195,6 @@ func IsAdmin(r *http.Request) bool {
if err != nil {
return false
}
- fmt.Println("user: ", claim.Username, claim.Admin)
return claim.Admin
}
diff --git a/handlers/incident.go b/handlers/incident.go
index 34a67e31..73365602 100644
--- a/handlers/incident.go
+++ b/handlers/incident.go
@@ -1,7 +1,11 @@
package handlers
import (
+ "encoding/json"
+ "github.com/gorilla/mux"
"github.com/hunterlong/statping/core"
+ "github.com/hunterlong/statping/types"
+ "github.com/hunterlong/statping/utils"
"net/http"
)
@@ -9,3 +13,58 @@ func apiAllIncidentsHandler(w http.ResponseWriter, r *http.Request) {
incidents := core.AllIncidents()
returnJson(incidents, w, r)
}
+
+func apiCreateIncidentHandler(w http.ResponseWriter, r *http.Request) {
+ var incident *types.Incident
+ decoder := json.NewDecoder(r.Body)
+ err := decoder.Decode(&incident)
+ if err != nil {
+ sendErrorJson(err, w, r)
+ return
+ }
+ newIncident := core.ReturnIncident(incident)
+ _, err = newIncident.Create()
+ if err != nil {
+ sendErrorJson(err, w, r)
+ return
+ }
+ sendJsonAction(newIncident, "create", w, r)
+}
+
+func apiIncidentUpdateHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ incident, err := core.SelectIncident(utils.ToInt(vars["id"]))
+ if err != nil {
+ sendErrorJson(err, w, r)
+ return
+ }
+
+ decoder := json.NewDecoder(r.Body)
+ err = decoder.Decode(&incident)
+ if err != nil {
+ sendErrorJson(err, w, r)
+ return
+ }
+
+ _, err = incident.Update()
+ if err != nil {
+ sendErrorJson(err, w, r)
+ return
+ }
+ sendJsonAction(incident, "update", w, r)
+}
+
+func apiDeleteIncidentHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ incident, err := core.SelectIncident(utils.ToInt(vars["id"]))
+ if err != nil {
+ sendErrorJson(err, w, r)
+ return
+ }
+ err = incident.Delete()
+ if err != nil {
+ sendErrorJson(err, w, r)
+ return
+ }
+ sendJsonAction(incident, "delete", w, r)
+}
diff --git a/handlers/integrations.go b/handlers/integrations.go
index 5275ca50..b65c07d1 100644
--- a/handlers/integrations.go
+++ b/handlers/integrations.go
@@ -1,8 +1,10 @@
package handlers
import (
+ "encoding/json"
"github.com/gorilla/mux"
"github.com/hunterlong/statping/core/integrations"
+ "github.com/hunterlong/statping/types"
"net/http"
)
@@ -11,20 +13,41 @@ func apiAllIntegrationsHandler(w http.ResponseWriter, r *http.Request) {
returnJson(integrations, w, r)
}
-func apiIntegrationHandler(w http.ResponseWriter, r *http.Request) {
+func apiIntegrationViewHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
- intg := vars["name"]
- r.ParseForm()
- for k, v := range r.PostForm {
- log.Info(k, v)
- }
-
- integration, err := integrations.Find(intg)
+ intgr, err := integrations.Find(vars["name"])
if err != nil {
sendErrorJson(err, w, r)
return
}
- list, err := integration.List()
+ returnJson(intgr.Get(), w, r)
+}
+
+func apiIntegrationHandler(w http.ResponseWriter, r *http.Request) {
+ vars := mux.Vars(r)
+ intgr, err := integrations.Find(vars["name"])
+ if err != nil {
+ sendErrorJson(err, w, r)
+ return
+ }
+
+ var intJson *types.Integration
+ decoder := json.NewDecoder(r.Body)
+ if err := decoder.Decode(&intJson); err != nil {
+ sendErrorJson(err, w, r)
+ return
+ }
+
+ integration := intgr.Get()
+ integration.Enabled = intJson.Enabled
+ integration.Fields = intJson.Fields
+
+ if err := integrations.Update(integration); err != nil {
+ sendErrorJson(err, w, r)
+ return
+ }
+
+ list, err := intgr.List()
if err != nil {
sendErrorJson(err, w, r)
return
diff --git a/handlers/middleware.go b/handlers/middleware.go
index be0ec8ba..62898529 100644
--- a/handlers/middleware.go
+++ b/handlers/middleware.go
@@ -65,7 +65,8 @@ func sendLog(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
t1 := utils.Now()
t2 := utils.Now().Sub(t1)
- if r.RequestURI == "/logs/line" {
+ if r.RequestURI == "/api/logs" || r.RequestURI == "/api/logs/last" {
+ next.ServeHTTP(w, r)
return
}
log.WithFields(utils.ToFields(w, r)).
diff --git a/handlers/routes.go b/handlers/routes.go
index d0cd2d9f..45664d6a 100644
--- a/handlers/routes.go
+++ b/handlers/routes.go
@@ -76,11 +76,15 @@ func Router() *mux.Router {
r.Handle("/api/setup", http.HandlerFunc(processSetupHandler)).Methods("POST")
r.Handle("/api/logout", http.HandlerFunc(logoutHandler))
r.Handle("/api/renew", authenticated(apiRenewHandler, false))
+ r.Handle("/api/cache", authenticated(apiCacheHandler, false)).Methods("GET")
r.Handle("/api/clear_cache", authenticated(apiClearCacheHandler, false))
r.Handle("/api/core", authenticated(apiCoreHandler, false)).Methods("POST")
+ r.Handle("/api/logs", authenticated(logsHandler, false)).Methods("GET")
+ r.Handle("/api/logs/last", authenticated(logsLineHandler, false)).Methods("GET")
+ // API INTEGRATIONS Routes
r.Handle("/api/integrations", authenticated(apiAllIntegrationsHandler, false)).Methods("GET")
- r.Handle("/api/integrations/{name}", authenticated(apiIntegrationHandler, false)).Methods("GET")
+ r.Handle("/api/integrations/{name}", authenticated(apiIntegrationViewHandler, false)).Methods("GET")
r.Handle("/api/integrations/{name}", authenticated(apiIntegrationHandler, false)).Methods("POST")
// API GROUPS Routes
@@ -109,6 +113,9 @@ func Router() *mux.Router {
// API INCIDENTS Routes
r.Handle("/api/incidents", readOnly(apiAllIncidentsHandler, false)).Methods("GET")
+ r.Handle("/api/incidents", authenticated(apiCreateIncidentHandler, false)).Methods("POST")
+ r.Handle("/api/incidents/:id", authenticated(apiIncidentUpdateHandler, false)).Methods("POST")
+ r.Handle("/api/incidents/:id", authenticated(apiDeleteIncidentHandler, false)).Methods("DELETE")
// API USER Routes
r.Handle("/api/users", authenticated(apiAllUsersHandler, false)).Methods("GET")
diff --git a/types/integrations.go b/types/integrations.go
index 534b76b5..4791134e 100644
--- a/types/integrations.go
+++ b/types/integrations.go
@@ -1,20 +1,20 @@
package types
type Integration struct {
- ShortName string `json:"name"`
- Name string `json:"full_name"`
- Icon string `json:"-"`
- Description string `json:"description"`
- Enabled bool `json:"enabled"`
- Fields []*IntegrationField `json:"fields"`
+ ShortName string `gorm:"column:name" json:"name"`
+ Name string `gorm:"-" json:"full_name,omitempty"`
+ Icon string `gorm:"-" json:"-"`
+ Description string `gorm:"-" json:"description,omitempty"`
+ Enabled bool `gorm:"column:enabled;default:false" json:"enabled"`
+ Fields []*IntegrationField `gorm:"column:fields" json:"fields"`
}
type IntegrationField struct {
- Name string `json:"name"`
- Value interface{} `json:"value"`
- Type string `json:"type"`
- Description string `json:"description,omitempty"`
- MimeType string `json:"mime_type,omitempty"`
+ Name string `gorm:"-" json:"name"`
+ Value interface{} `gorm:"-" json:"value"`
+ Type string `gorm:"-" json:"type"`
+ Description string `gorm:"-" json:"description,omitempty"`
+ MimeType string `gorm:"-" json:"mime_type,omitempty"`
}
type Integrator interface {
diff --git a/utils/utils.go b/utils/utils.go
index 1aa700f5..703e5e44 100644
--- a/utils/utils.go
+++ b/utils/utils.go
@@ -246,6 +246,13 @@ func CopyFile(src, dst string) error {
return out.Close()
}
+// IsType will return true if a variable can implement an interface
+func IsType(n interface{}, obj interface{}) bool {
+ one := reflect.TypeOf(n)
+ two := reflect.ValueOf(obj).Elem()
+ return one.Implements(two.Type())
+}
+
// Command will run a terminal command with 'sh -c COMMAND' and return stdout and errOut as strings
// in, out, err := Command("sass assets/scss assets/css/base.css")
func Command(cmd string) (string, string, error) {
| |