mirror of https://github.com/statping/statping
UI updates, incident updates API changes
parent
dbe858c842
commit
6b9f0766a5
6
Makefile
6
Makefile
|
@ -29,6 +29,12 @@ go-build: clean
|
|||
tar -xvf source.tar.gz
|
||||
go build -a -ldflags "-s -w -extldflags -static -X main.VERSION=${VERSION}" -o statping --tags "netgo" ./cmd
|
||||
|
||||
lint:
|
||||
go fmt ./...
|
||||
golint ./...
|
||||
impi --local github.com/statping/statping/ --scheme stdLocalThirdParty ./...
|
||||
goimports ./...
|
||||
|
||||
up:
|
||||
docker-compose -f docker-compose.yml -f dev/docker-compose.full.yml up -d --remove-orphans
|
||||
make print_details
|
||||
|
|
|
@ -39,12 +39,15 @@ func systemctlCli(dir string, uninstall bool, port int64) error {
|
|||
location := "/etc/systemd/system/statping.service"
|
||||
|
||||
if uninstall {
|
||||
fmt.Println("systemctl stop statping")
|
||||
if _, _, err := utils.Command("systemctl", "stop", "statping"); err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
fmt.Println("systemctl disable statping")
|
||||
if _, _, err := utils.Command("systemctl", "disable", "statping"); err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
fmt.Println("Deleting systemctl: ", location)
|
||||
if err := utils.DeleteFile(location); err != nil {
|
||||
log.Errorln(err)
|
||||
}
|
||||
|
@ -79,20 +82,24 @@ WantedBy=multi-user.target"
|
|||
fmt.Println("Saving systemctl service to: ", location)
|
||||
fmt.Printf("Using directory %s for Statping data\n", dir)
|
||||
fmt.Printf("Running on port %d\n", port)
|
||||
fmt.Printf("\n\n%s\n\n", string(config))
|
||||
if err := utils.SaveFile(location, config); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("systemctl daemon-reload")
|
||||
if _, _, err := utils.Command("systemctl", "daemon-reload"); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("systemctl enable statping")
|
||||
if _, _, err := utils.Command("systemctl", "enable", "statping.service"); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("systemctl start statping")
|
||||
if _, _, err := utils.Command("systemctl", "start", "statping"); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Statping was will auto start on reboots")
|
||||
fmt.Println("systemctl service: /etc/systemd/system/statping.service")
|
||||
fmt.Println("systemctl service: ", location)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ var updateCmd = &cobra.Command{
|
|||
Short: "Update to the latest version",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
log.Infoln("Updating Statping to the latest version...")
|
||||
log.Infoln("curl -o- -L https://statping.com/install.sh | bash")
|
||||
curl, err := exec.LookPath("curl")
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 17 KiB |
|
@ -0,0 +1,82 @@
|
|||
<template>
|
||||
<div>
|
||||
<Loading :loading="!loaded"/>
|
||||
<div v-if="loaded && !service.online" class="bg-white shadow-sm mt-3 p-3 pr-4 pl-4 col-12">
|
||||
<font-awesome-icon icon="exclamation" class="mr-3" size="1x"/>
|
||||
Last failure was {{ago(service.last_error)}} ago.
|
||||
<code v-if="failure" class="d-block bg-light p-3 mt-3">
|
||||
{{failure.issue}}
|
||||
<span class="d-block text-dim float-right small mt-3 mb-1">Failure #{{failure.id}}</span>
|
||||
</code>
|
||||
</div>
|
||||
<div v-if="loaded" v-for="message in messages" class="bg-light shadow-sm p-3 pr-4 pl-4 col-12 mt-3">
|
||||
<font-awesome-icon icon="calendar" class="mr-3" size="1x"/> {{message.description}}
|
||||
<span class="d-block small text-muted mt-3">
|
||||
Starts at <strong>{{niceDate(message.start_on)}}</strong> till <strong>{{niceDate(message.end_on)}}</strong>
|
||||
({{dur(parseISO(message.start_on), parseISO(message.end_on))}})
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="loaded" v-for="incident in incidents" class="bg-light shadow-sm p-3 pr-4 pl-4 col-12 mt-3">
|
||||
<font-awesome-icon icon="calendar" class="mr-3" size="1x"/>
|
||||
{{incident.title}} - {{incident.description}}
|
||||
<div v-for="update in incident.updates" class="d-block small">
|
||||
<span class="font-weight-bold text-capitalize">{{update.type}}</span> - {{update.message}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Api from "../../API";
|
||||
import Loading from "@/components/Elements/Loading";
|
||||
|
||||
export default {
|
||||
name: "ServiceEvents",
|
||||
components: {
|
||||
Loading
|
||||
|
||||
},
|
||||
props: {
|
||||
service: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
messages: null,
|
||||
incidents: null,
|
||||
failure: null,
|
||||
loaded: false,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.load()
|
||||
},
|
||||
methods: {
|
||||
async load() {
|
||||
this.loaded = false
|
||||
if (!this.service.online) {
|
||||
await this.getFailure()
|
||||
}
|
||||
await this.getMessages()
|
||||
await this.getIncidents()
|
||||
this.loaded = true
|
||||
},
|
||||
async getMessages() {
|
||||
this.messages = await Api.messages()
|
||||
},
|
||||
async getFailure() {
|
||||
const f = await Api.service_failures(this.service.id, null, null, 1)
|
||||
this.failure = f[0]
|
||||
},
|
||||
async getIncidents() {
|
||||
this.incidents = await Api.incidents_service(this.service.id)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -9,60 +9,31 @@
|
|||
</h4>
|
||||
</div>
|
||||
|
||||
<div class="card-body p-3 p-md-1 pt-md-3 pb-md-1">
|
||||
<div class="card-body">
|
||||
<transition name="fade">
|
||||
<div v-if="loaded" class="col-12 pb-2">
|
||||
|
||||
<div v-if="false" class="row mb-4 align-content-center">
|
||||
|
||||
<div v-if="!service.online" class="col-3 text-left">
|
||||
<span css="text-danger font-5 font-weight-bold"></span>
|
||||
<span class="font-2 d-block">Current Downtime</span>
|
||||
</div>
|
||||
|
||||
<div v-if="service.online" class="col-3 text-left">
|
||||
<span class="text-success font-5 font-weight-bold">
|
||||
{{service.online_24_hours.toString()}} %
|
||||
</span>
|
||||
<span class="font-2 d-block">Total Uptime</span>
|
||||
</div>
|
||||
|
||||
<div v-if="service.online" class="col-3 text-left">
|
||||
<span class="text-success font-5 font-weight-bold">
|
||||
0
|
||||
</span>
|
||||
<span class="font-2 d-block">Downtime Today</span>
|
||||
</div>
|
||||
|
||||
<div v-if="service.online" class="col-3 text-left">
|
||||
<span class="text-success font-5 font-weight-bold">
|
||||
{{(uptime.uptime / 10000).toFixed(0).toString()}}
|
||||
</span>
|
||||
<span class="font-2 d-block">Uptime Duration</span>
|
||||
</div>
|
||||
|
||||
<div class="col-3 text-left">
|
||||
<span class="text-danger font-5 font-weight-bold">
|
||||
{{service.failures_24_hours}}
|
||||
</span>
|
||||
<span class="font-2 d-block">Failures last 24 hours</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div v-if="loaded" class="row pl-2 pr-2">
|
||||
<div class="col-md-6 col-sm-12 mt-2 mt-md-0 mb-3">
|
||||
<ServiceSparkLine :title="set2_name" subtitle="Latency Last 24 Hours" :series="set2"/>
|
||||
</div>
|
||||
<div class="col-md-6 col-sm-12 mt-4 mt-md-0 mb-3">
|
||||
<ServiceSparkLine :title="set1_name" subtitle="Latency Last 7 Days" :series="set1"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 mt-2 mt-md-0 mb-3">
|
||||
<ServiceEvents :service="service"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-else class="row mt-5 mb-5 pt-5 pb-5">
|
||||
<div class="col-6 text-center text-muted">
|
||||
<font-awesome-icon icon="circle-notch" size="3x" spin/>
|
||||
</div>
|
||||
<div class="col-6 text-center text-muted">
|
||||
<font-awesome-icon icon="circle-notch" size="3x" spin/>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
<div class="row">
|
||||
|
||||
|
@ -105,10 +76,12 @@
|
|||
import ServiceFailures from '../Service/ServiceFailures';
|
||||
import ServiceSparkLine from "./ServiceSparkLine";
|
||||
import Api from "../../API";
|
||||
import ServiceEvents from "@/components/Dashboard/ServiceEvents";
|
||||
|
||||
export default {
|
||||
name: 'ServiceInfo',
|
||||
components: {
|
||||
ServiceEvents,
|
||||
Checkin,
|
||||
ServiceFailures,
|
||||
FormIncident,
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<template>
|
||||
<div v-if="loading" class="row mt-3 mb-3">
|
||||
<div class="col-12 text-center text-muted">
|
||||
<font-awesome-icon icon="circle-notch" size="3x" spin/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Loading",
|
||||
props: {
|
||||
loading: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -28,7 +28,7 @@
|
|||
<label class="col-sm-4 col-form-label">Service</label>
|
||||
<div class="col-sm-8">
|
||||
<select v-model="message.service" name="service_id" class="form-control">
|
||||
<option :value="0">Global Announcement</option>
|
||||
<option v-bind:value="0">Global Announcement</option>
|
||||
<option v-for="service in $store.getters.services" :value="service.id" v-bind:key="service.id" >{{service.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
@ -48,7 +48,7 @@
|
|||
<label for="service_id" class="col-sm-4 col-form-label">Service</label>
|
||||
<div class="col-sm-8">
|
||||
<select v-model="message.service" class="form-control" name="service" id="service_id">
|
||||
<option :value="0">Global Message</option>
|
||||
<option v-bind:value="0">Global Message</option>
|
||||
<option v-for="service in $store.getters.services" :value="service.id" v-bind:key="service.id">{{service.name}}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
@ -130,6 +130,7 @@
|
|||
start_on: new Date(),
|
||||
end_on: new Date(),
|
||||
service_id: 0,
|
||||
service: 0,
|
||||
notify_method: "",
|
||||
notify: false,
|
||||
notify_before: 0,
|
||||
|
|
6
go.mod
6
go.mod
|
@ -17,6 +17,7 @@ require (
|
|||
github.com/hako/durafmt v0.0.0-20200605151348-3a43fc422dd9
|
||||
github.com/jinzhu/gorm v1.9.12
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible
|
||||
github.com/pavius/impi v0.0.3 // indirect
|
||||
github.com/pelletier/go-toml v1.7.0 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.1.0
|
||||
|
@ -29,11 +30,14 @@ require (
|
|||
github.com/spf13/viper v1.6.3
|
||||
github.com/stretchr/testify v1.5.1
|
||||
github.com/t-tiger/gorm-bulk-insert/v2 v2.0.1
|
||||
golang.org/x/crypto v0.0.0-20200420201142-3c4aac89819a
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d // indirect
|
||||
google.golang.org/grpc v1.28.1
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/mail.v2 v2.3.1 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
gopkg.in/yaml.v2 v2.2.8
|
||||
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect
|
||||
mvdan.cc/unindent v0.0.0-20170829200357-ff6a34147cea // indirect
|
||||
)
|
||||
|
|
19
go.sum
19
go.sum
|
@ -357,6 +357,7 @@ github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6i
|
|||
github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d h1:V5Rs9ztEWdp58oayPq/ulmlqJJZeJP6pP79uP3qjcao=
|
||||
github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.9.0 h1:GhthINjveNZAdFUD8QoQYfjxnOONZgztK/Yr6M23UTY=
|
||||
|
@ -469,6 +470,8 @@ github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014 h1:37VE5TYj2m/FLA9SNr4z
|
|||
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014/go.mod h1:joRatxRJaZBsY3JAOEMcoOp05CnZzsx4scTxi95DHyQ=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pavius/impi v0.0.3 h1:DND6MzU+BLABhOZXbELR3FU8b+zDgcq4dOCNLhiTYuI=
|
||||
github.com/pavius/impi v0.0.3/go.mod h1:x/hU0bfdWIhuOT1SKwiJg++yvkk6EuOtJk8WtDZqgr8=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.7.0 h1:7utD74fnzVc/cpcyy8sjrlFr5vYpypUixARcHIMIGuI=
|
||||
|
@ -606,6 +609,7 @@ github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FB
|
|||
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
|
||||
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
|
@ -641,6 +645,8 @@ golang.org/x/crypto v0.0.0-20200406173513-056763e48d71 h1:DOmugCavvUtnUD114C1Wh+
|
|||
golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200420201142-3c4aac89819a h1:y6sBfNd1b9Wy08a6K1Z1DZc4aXABUN5TKjkYhz7UKmo=
|
||||
golang.org/x/crypto v0.0.0-20200420201142-3c4aac89819a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
|
@ -662,6 +668,7 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl
|
|||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
|
@ -670,6 +677,8 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
|||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -704,6 +713,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -719,6 +730,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -808,7 +820,10 @@ golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapK
|
|||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4 h1:kDtqNkeBrZb8B+atrj50B5XLHpzXXqcCdZPP/ApQ5NY=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d h1:szSOL78iTCl0LF1AMjhSWJj8tIM0KixlUUnBtYXsmd8=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
|
@ -926,6 +941,10 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh
|
|||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo=
|
||||
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
|
||||
mvdan.cc/unindent v0.0.0-20170829200357-ff6a34147cea h1:M9wqFYtIbcU4ya22owATTPClIVAKkxqoYt2HAn02/JI=
|
||||
mvdan.cc/unindent v0.0.0-20170829200357-ff6a34147cea/go.mod h1:uK66ibKYZGgWb8OWRdHaAVsidCOAFXHXLpYh0P+WFgA=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
|
|
|
@ -119,8 +119,19 @@ func apiThemeCreateHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
if err := source.CompileSASS(); err != nil {
|
||||
source.CopyToPublic(source.TmplBox, "css", "main.css")
|
||||
source.CopyToPublic(source.TmplBox, "css", "base.css")
|
||||
if err := source.CopyToPublic(source.TmplBox, "css", "style.css"); err != nil {
|
||||
log.Errorln(err)
|
||||
sendErrorJson(err, w, r)
|
||||
return
|
||||
}
|
||||
jsFiles := []string{"bundle.js", "main.chunk.js", "polyfill.chunk.js", "style.chunk.js"}
|
||||
for _, f := range jsFiles {
|
||||
if err := source.CopyToPublic(source.TmplBox, "js", f); err != nil {
|
||||
log.Errorln(err)
|
||||
sendErrorJson(err, w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
log.Errorln("Default 'base.css' was inserted because SASS did not work.")
|
||||
}
|
||||
resetRouter()
|
||||
|
|
|
@ -45,7 +45,7 @@ func apiIncidentUpdatesHandler(w http.ResponseWriter, r *http.Request) {
|
|||
sendErrorJson(err, w, r)
|
||||
return
|
||||
}
|
||||
returnJson(incid.Updates(), w, r)
|
||||
returnJson(incid.Updates, w, r)
|
||||
}
|
||||
|
||||
func apiCreateIncidentUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -100,8 +100,7 @@ func apiIncidentUpdateHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
updates := incident.Updates()
|
||||
sendJsonAction(updates, "update", w, r)
|
||||
sendJsonAction(incident.Updates, "update", w, r)
|
||||
}
|
||||
|
||||
func apiDeleteIncidentHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.9 KiB |
|
@ -114,6 +114,11 @@ func TestInit(t *testing.T) {
|
|||
assert.Len(t, all, 1)
|
||||
})
|
||||
|
||||
t.Run("Test Samples", func(t *testing.T) {
|
||||
require.Nil(t, Samples())
|
||||
assert.Len(t, All(), 2)
|
||||
})
|
||||
|
||||
t.Run("Test Checkin", func(t *testing.T) {
|
||||
assert.Nil(t, db.Close())
|
||||
assert.Nil(t, dbHits.Close())
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package failures
|
||||
|
||||
import (
|
||||
"github.com/statping/statping/database"
|
||||
"github.com/statping/statping/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInit(t *testing.T) {
|
||||
t.Parallel()
|
||||
err := utils.InitLogs()
|
||||
require.Nil(t, err)
|
||||
db, err := database.OpenTester()
|
||||
require.Nil(t, err)
|
||||
SetDB(db)
|
||||
db.AutoMigrate(&Failure{})
|
||||
|
||||
t.Run("Test Samples", func(t *testing.T) {
|
||||
require.Nil(t, Samples())
|
||||
assert.Len(t, All(), 2)
|
||||
})
|
||||
}
|
|
@ -106,6 +106,11 @@ func TestDelete(t *testing.T) {
|
|||
assert.Len(t, all, 1)
|
||||
}
|
||||
|
||||
func TestSamples(t *testing.T) {
|
||||
require.Nil(t, Samples())
|
||||
assert.Len(t, All(), 4)
|
||||
}
|
||||
|
||||
func TestClose(t *testing.T) {
|
||||
assert.Nil(t, db.Close())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package hits
|
||||
|
||||
import (
|
||||
"github.com/statping/statping/database"
|
||||
"github.com/statping/statping/types/services"
|
||||
"github.com/statping/statping/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInit(t *testing.T) {
|
||||
err := utils.InitLogs()
|
||||
require.Nil(t, err)
|
||||
db, err := database.OpenTester()
|
||||
require.Nil(t, err)
|
||||
db.CreateTable(&Hit{}, &services.Service{})
|
||||
SetDB(db)
|
||||
services.SetDB(db)
|
||||
|
||||
for i := 0; i <= 5; i++ {
|
||||
s := services.Example(true)
|
||||
assert.Nil(t, s.Create())
|
||||
assert.Len(t, s.AllHits().List(), 2)
|
||||
}
|
||||
|
||||
require.Nil(t, Samples())
|
||||
}
|
|
@ -18,6 +18,7 @@ func SetDB(database database.Database) {
|
|||
}
|
||||
|
||||
func (i *Incident) AfterFind() {
|
||||
db.Model(i).Related(&i.Updates).Order("DESC")
|
||||
metrics.Query("incident", "find")
|
||||
}
|
||||
|
||||
|
@ -64,11 +65,6 @@ func Find(id int64) (*Incident, error) {
|
|||
func FindByService(id int64) []*Incident {
|
||||
var incidents []*Incident
|
||||
db.Where("service = ?", id).Find(&incidents)
|
||||
for _, i := range incidents {
|
||||
var updates []*IncidentUpdate
|
||||
dbUpdate.Where("incident = ?", id).Find(&updates)
|
||||
i.AllUpdates = updates
|
||||
}
|
||||
return incidents
|
||||
}
|
||||
|
||||
|
@ -87,7 +83,7 @@ func (i *Incident) Update() error {
|
|||
}
|
||||
|
||||
func (i *Incident) Delete() error {
|
||||
for _, u := range i.Updates() {
|
||||
for _, u := range i.Updates {
|
||||
if err := u.Delete(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
package incidents
|
||||
|
||||
func (i *Incident) Updates() []*IncidentUpdate {
|
||||
var updates []*IncidentUpdate
|
||||
dbUpdate.Where("incident = ?", i.Id).Find(&updates)
|
||||
i.AllUpdates = updates
|
||||
return updates
|
||||
}
|
||||
//func (i Incident) Updates() []*IncidentUpdate {
|
||||
// var updates []*IncidentUpdate
|
||||
// dbUpdate.Where("incident = ?", i.Id).Find(&updates)
|
||||
// return updates
|
||||
//}
|
||||
|
||||
func (i *IncidentUpdate) Create() error {
|
||||
q := dbUpdate.Create(i)
|
||||
|
|
|
@ -83,6 +83,11 @@ func TestDelete(t *testing.T) {
|
|||
assert.Len(t, all, 1)
|
||||
}
|
||||
|
||||
func TestSamples(t *testing.T) {
|
||||
require.Nil(t, Samples())
|
||||
assert.Len(t, All(), 3)
|
||||
}
|
||||
|
||||
func TestClose(t *testing.T) {
|
||||
assert.Nil(t, db.Close())
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ type Incident struct {
|
|||
ServiceId int64 `gorm:"index;column:service" json:"service"`
|
||||
CreatedAt time.Time `gorm:"column:created_at" json:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at" json:"updated_at"`
|
||||
AllUpdates []*IncidentUpdate `gorm:"-" json:"updates,omitempty"`
|
||||
Updates []*IncidentUpdate `gorm:"foreignkey:incident;association_foreignkey:id;association_autoupdate:false;association_autocreate:false" json:"updates,omitempty"`
|
||||
}
|
||||
|
||||
// IncidentUpdate contains updates based on a Incident
|
||||
|
|
|
@ -73,6 +73,11 @@ func TestDelete(t *testing.T) {
|
|||
assert.Len(t, all, 1)
|
||||
}
|
||||
|
||||
func TestSamples(t *testing.T) {
|
||||
require.Nil(t, Samples())
|
||||
assert.Len(t, All(), 2)
|
||||
}
|
||||
|
||||
func TestClose(t *testing.T) {
|
||||
assert.Nil(t, db.Close())
|
||||
}
|
||||
|
|
|
@ -1,10 +1,67 @@
|
|||
package null
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"gopkg.in/yaml.v2"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestJSONMarshal(t *testing.T) {
|
||||
tests := []struct {
|
||||
Input interface{}
|
||||
ExpectedJSON string
|
||||
}{
|
||||
{
|
||||
Input: NewNullBool(true),
|
||||
ExpectedJSON: `true`,
|
||||
},
|
||||
{
|
||||
Input: NewNullBool(false),
|
||||
ExpectedJSON: `false`,
|
||||
},
|
||||
{
|
||||
Input: NewNullFloat64(0.994),
|
||||
ExpectedJSON: `0.994`,
|
||||
},
|
||||
{
|
||||
Input: NewNullFloat64(0),
|
||||
ExpectedJSON: `0`,
|
||||
},
|
||||
{
|
||||
Input: NewNullInt64(42),
|
||||
ExpectedJSON: `42`,
|
||||
},
|
||||
{
|
||||
Input: NewNullInt64(0),
|
||||
ExpectedJSON: `0`,
|
||||
},
|
||||
{
|
||||
Input: NewNullString("test"),
|
||||
ExpectedJSON: `"test"`,
|
||||
},
|
||||
{
|
||||
Input: NewNullString(""),
|
||||
ExpectedJSON: `""`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
str, err := json.Marshal(test.Input)
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, test.ExpectedJSON, string(str))
|
||||
|
||||
str, err = yaml.Marshal(yamlStruct{test.Input})
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, test.ExpectedJSON, string(str))
|
||||
}
|
||||
}
|
||||
|
||||
type yamlStruct struct {
|
||||
Value interface{} `json:"value" yaml:"value"`
|
||||
}
|
||||
|
||||
func TestNewNullBool(t *testing.T) {
|
||||
val := NewNullBool(true)
|
||||
assert.True(t, val.Bool)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"github.com/statping/statping/types/null"
|
||||
"github.com/statping/statping/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
@ -251,6 +252,11 @@ func TestServiceNotifications(t *testing.T) {
|
|||
runNotifyTests(t, notif, tests...)
|
||||
})
|
||||
|
||||
t.Run("Test Samples", func(t *testing.T) {
|
||||
require.Nil(t, Samples())
|
||||
assert.Len(t, All(), 11)
|
||||
})
|
||||
|
||||
t.Run("Test Close", func(t *testing.T) {
|
||||
assert.Nil(t, db.Close())
|
||||
})
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
)
|
||||
|
||||
// AuthUser will return the User and a boolean if authentication was correct.
|
||||
// AuthUser accepts username, and password as a string
|
||||
// accepts username, and password as a string
|
||||
func AuthUser(username, password string) (*User, bool) {
|
||||
user, err := FindByUsername(username)
|
||||
if err != nil {
|
||||
|
|
|
@ -73,6 +73,16 @@ func TestUpdate(t *testing.T) {
|
|||
assert.Equal(t, "updated_user", item.Username)
|
||||
}
|
||||
|
||||
func TestAuthUser(t *testing.T) {
|
||||
u, err := AuthUser("updated_user", "admin")
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, "admin", u.Username)
|
||||
|
||||
u, err = AuthUser("updated_user", "wrongpass")
|
||||
assert.NotNil(t, err)
|
||||
assert.Nil(t, u)
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
all := All()
|
||||
assert.Len(t, all, 2)
|
||||
|
@ -87,6 +97,11 @@ func TestDelete(t *testing.T) {
|
|||
assert.Len(t, all, 1)
|
||||
}
|
||||
|
||||
func TestSamples(t *testing.T) {
|
||||
require.Nil(t, Samples())
|
||||
assert.Len(t, All(), 3)
|
||||
}
|
||||
|
||||
func TestClose(t *testing.T) {
|
||||
assert.Nil(t, db.Close())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue