mirror of https://github.com/statping/statping
design changes, incidents
parent
2ab4fd97f3
commit
3e791c2c74
|
@ -1,3 +1,7 @@
|
||||||
|
# 0.90.23
|
||||||
|
- Added Incident Reporting
|
||||||
|
- Added Cypress tests
|
||||||
|
|
||||||
# 0.90.22
|
# 0.90.22
|
||||||
- Added range input types for integer form fields
|
- Added range input types for integer form fields
|
||||||
- Modified Sentry error logging details
|
- Modified Sentry error logging details
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
import "../support/commands"
|
||||||
|
|
||||||
|
context('Incidents Tests', () => {
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.restoreLocalStorageCache();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
cy.saveLocalStorageCache();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should Login', () => {
|
||||||
|
cy.visit('/login')
|
||||||
|
cy.get('#username').clear().type('admin')
|
||||||
|
cy.get('#password').clear().type('admin')
|
||||||
|
cy.get('button[type="submit"]').click()
|
||||||
|
|
||||||
|
cy.get('.navbar-brand').should('contain', 'Statping')
|
||||||
|
cy.getCookies()
|
||||||
|
|
||||||
|
cy.getCookies().should('have.length', 1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should create new incident', () => {
|
||||||
|
cy.visit('/dashboard')
|
||||||
|
cy.wait(3000)
|
||||||
|
cy.get('.service_block').eq(0).find(".incident").click()
|
||||||
|
cy.get('#title').clear().type('Downtime')
|
||||||
|
cy.get('#description').clear().type('Recently we found an issue with authentication')
|
||||||
|
cy.get('button[type="submit"]').click()
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
|
@ -26,35 +26,35 @@ context('Services Tests', () => {
|
||||||
|
|
||||||
it('should goto services', () => {
|
it('should goto services', () => {
|
||||||
cy.visit('/dashboard/services')
|
cy.visit('/dashboard/services')
|
||||||
cy.get(':nth-child(1) > .card-body > .table > tbody > tr').should('have.length', 5)
|
cy.get('#services_list > tr').should('have.length', 5)
|
||||||
cy.get('.sortable_groups > tr').should('have.length', 3)
|
cy.get('.sortable_groups > tr').should('have.length', 3)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should create new HTTP service', () => {
|
it('should create new HTTP service', () => {
|
||||||
cy.visit('/dashboard/create_service')
|
cy.visit('/dashboard/create_service')
|
||||||
cy.get(':nth-child(1) > .card-body > :nth-child(1) > .col-sm-8 > .form-control').clear().type('HTTP Service')
|
cy.get('#name').clear().type('HTTP Service')
|
||||||
cy.get('#service_type').select('http')
|
cy.get('#service_type').select('http')
|
||||||
cy.get('#service_url').clear().type('http://localhost:8888')
|
cy.get('#service_url').clear().type('http://localhost:8888')
|
||||||
cy.get('#service_response_code').clear().type('200')
|
cy.get('#service_response_code').clear().type('200')
|
||||||
cy.get('#service_interval').clear().type('30')
|
cy.get('#service_interval').invoke('val', 30).trigger('change')
|
||||||
cy.get(':nth-child(3) > .card-body > :nth-child(2) > .col-sm-8 > .form-control').clear().type('5')
|
cy.get('#timeout').invoke('val', 5).trigger('change')
|
||||||
cy.get('#permalink').clear().type('http_service')
|
cy.get('#permalink').clear().type('http_service')
|
||||||
|
|
||||||
cy.get('#notify_after').clear().type('3')
|
cy.get('#notify_after').invoke('val', 3).trigger('change')
|
||||||
|
|
||||||
cy.get('button[type="submit"]').click()
|
cy.get('button[type="submit"]').click()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should create new TCP service', () => {
|
it('should create new TCP service', () => {
|
||||||
cy.visit('/dashboard/create_service')
|
cy.visit('/dashboard/create_service')
|
||||||
cy.get(':nth-child(1) > .card-body > :nth-child(1) > .col-sm-8 > .form-control').clear().type('TCP Service')
|
cy.get('#name').clear().type('TCP Service')
|
||||||
cy.get('#service_type').select('tcp')
|
cy.get('#service_type').select('tcp')
|
||||||
cy.get('#service_url').clear().type('localhost')
|
cy.get('#service_url').clear().type('localhost')
|
||||||
cy.get('#service_port').clear().type('8888')
|
cy.get('#service_port').clear().type('8888')
|
||||||
|
|
||||||
cy.get('#service_interval').clear().type('30')
|
cy.get('#service_interval').invoke('val', 30).trigger('change')
|
||||||
cy.get(':nth-child(3) > .card-body > :nth-child(2) > .col-sm-8 > .form-control').clear().type('5')
|
cy.get('#timeout').invoke('val', 5).trigger('change')
|
||||||
cy.get('#notify_after').clear().type('3')
|
cy.get('#notify_after').invoke('val', 3).trigger('change')
|
||||||
|
|
||||||
cy.get('#permalink').clear().type('tcp_service')
|
cy.get('#permalink').clear().type('tcp_service')
|
||||||
|
|
||||||
|
@ -63,14 +63,14 @@ context('Services Tests', () => {
|
||||||
|
|
||||||
it('should create new UDP service', () => {
|
it('should create new UDP service', () => {
|
||||||
cy.visit('/dashboard/create_service')
|
cy.visit('/dashboard/create_service')
|
||||||
cy.get(':nth-child(1) > .card-body > :nth-child(1) > .col-sm-8 > .form-control').clear().type('UDP Service')
|
cy.get('#name').clear().type('UDP Service')
|
||||||
cy.get('#service_type').select('udp')
|
cy.get('#service_type').select('udp')
|
||||||
cy.get('#service_url').clear().type('8.8.8.8')
|
cy.get('#service_url').clear().type('8.8.8.8')
|
||||||
cy.get('#service_port').clear().type('53')
|
cy.get('#service_port').clear().type('53')
|
||||||
|
|
||||||
cy.get('#service_interval').clear().type('30')
|
cy.get('#service_interval').invoke('val', 30).trigger('change')
|
||||||
cy.get(':nth-child(3) > .card-body > :nth-child(2) > .col-sm-8 > .form-control').clear().type('5')
|
cy.get('#timeout').invoke('val', 5).trigger('change')
|
||||||
cy.get('#notify_after').clear().type('3')
|
cy.get('#notify_after').invoke('val', 3).trigger('change')
|
||||||
|
|
||||||
cy.get('#permalink').clear().type('udp_service')
|
cy.get('#permalink').clear().type('udp_service')
|
||||||
|
|
||||||
|
@ -79,12 +79,12 @@ context('Services Tests', () => {
|
||||||
|
|
||||||
it('should create new ICMP service', () => {
|
it('should create new ICMP service', () => {
|
||||||
cy.visit('/dashboard/create_service')
|
cy.visit('/dashboard/create_service')
|
||||||
cy.get(':nth-child(1) > .card-body > :nth-child(1) > .col-sm-8 > .form-control').clear().type('ICMP Service')
|
cy.get('#name').clear().type('ICMP Service')
|
||||||
cy.get('#service_type').select('icmp')
|
cy.get('#service_type').select('icmp')
|
||||||
cy.get('#service_url').clear().type('8.8.8.8')
|
cy.get('#service_url').clear().type('8.8.8.8')
|
||||||
|
|
||||||
cy.get('#service_interval').clear().type('30')
|
cy.get('#service_interval').invoke('val', 30).trigger('change')
|
||||||
cy.get('#notify_after').clear().type('3')
|
cy.get('#notify_after').invoke('val', 3).trigger('change')
|
||||||
|
|
||||||
cy.get('#permalink').clear().type('icmp_service')
|
cy.get('#permalink').clear().type('icmp_service')
|
||||||
|
|
||||||
|
@ -93,7 +93,16 @@ context('Services Tests', () => {
|
||||||
|
|
||||||
it('should confirm new services', () => {
|
it('should confirm new services', () => {
|
||||||
cy.visit('/dashboard/services')
|
cy.visit('/dashboard/services')
|
||||||
cy.get(':nth-child(1) > .card-body > .table > tbody > tr').should('have.length', 9)
|
cy.get('#services_list > tr').should('have.length', 9)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should delete new services', () => {
|
||||||
|
cy.visit('/dashboard/services')
|
||||||
|
cy.get('#services_list > tr').eq(0).find('.btn-danger').click()
|
||||||
|
cy.get('#services_list > tr').eq(0).find('.btn-danger').click()
|
||||||
|
cy.get('#services_list > tr').eq(0).find('.btn-danger').click()
|
||||||
|
cy.get('#services_list > tr').eq(0).find('.btn-danger').click()
|
||||||
|
cy.get('#services_list > tr').should('have.length', 4)
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, maximum-scale=1.0, user-scalable=0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, maximum-scale=1.0, user-scalable=0">
|
||||||
|
<base href="/">
|
||||||
<title>Statping</title>
|
<title>Statping</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-for="(service, index) in $store.getters.services" v-bind:key="index">
|
<div v-for="(service, index) in $store.getters.services" class="service_block" v-bind:key="index">
|
||||||
<ServiceInfo :service=service />
|
<ServiceInfo :service=service />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<th scope="col"></th>
|
<th scope="col"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<draggable tag="tbody" v-model="servicesList" handle=".drag_icon">
|
<draggable id="services_list" tag="tbody" v-model="servicesList" handle=".drag_icon">
|
||||||
<tr v-for="(service, index) in $store.getters.servicesInOrder" :key="service.id">
|
<tr v-for="(service, index) in $store.getters.servicesInOrder" :key="service.id">
|
||||||
<td>
|
<td>
|
||||||
<span v-if="$store.state.admin" class="drag_icon d-none d-md-inline">
|
<span v-if="$store.state.admin" class="drag_icon d-none d-md-inline">
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
<GroupServiceFailures :service="service"/>
|
<GroupServiceFailures :service="service"/>
|
||||||
|
|
||||||
|
<IncidentsBlock :service="service"/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -18,10 +19,12 @@
|
||||||
<script>
|
<script>
|
||||||
import Api from '../../API';
|
import Api from '../../API';
|
||||||
import GroupServiceFailures from './GroupServiceFailures';
|
import GroupServiceFailures from './GroupServiceFailures';
|
||||||
|
import IncidentsBlock from './IncidentsBlock';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Group',
|
name: 'Group',
|
||||||
components: {
|
components: {
|
||||||
|
IncidentsBlock,
|
||||||
GroupServiceFailures
|
GroupServiceFailures
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
<template>
|
||||||
|
<div class="row mt-4">
|
||||||
|
<div v-for="(incident, i) in incidents" class="col-12">
|
||||||
|
<h6><span class="badge badge-secondary">New</span>
|
||||||
|
{{incident.title}}
|
||||||
|
<span class="font-2">{{incident.created_at}}</span>
|
||||||
|
</h6>
|
||||||
|
{{incident.description}}
|
||||||
|
{{incident}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Api from '../../API';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'IncidentsBlock',
|
||||||
|
props: {
|
||||||
|
service: {
|
||||||
|
type: Object
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
incidents: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.getIncidents()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getIncidents() {
|
||||||
|
this.incidents = await Api.incidents_service(this.service)
|
||||||
|
},
|
||||||
|
async getIncidentsUpdates() {
|
||||||
|
this.incidents = await Api.incidents_service(this.service)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
|
@ -1,7 +1,8 @@
|
||||||
<template v-if="service">
|
<template v-if="service">
|
||||||
<div class="col-12 card mb-4" style="min-height: 280px;" :class="{'offline-card': !service.online}">
|
<div class="col-12 card mb-4" style="min-height: 280px;" :class="{'offline-card': !service.online}">
|
||||||
<div class="card-body p-3 p-md-1 pt-md-3 pb-md-1">
|
<div class="card-body p-3 p-md-1 pt-md-3 pb-md-1">
|
||||||
<h4 class="card-title mb-4"><router-link :to="serviceLink(service)">{{service.name}}</router-link>
|
<h4 class="card-title mb-4">
|
||||||
|
<router-link :to="serviceLink(service)">{{service.name}}</router-link>
|
||||||
<span class="badge float-right" :class="{'badge-success': service.online, 'badge-danger': !service.online}">
|
<span class="badge float-right" :class="{'badge-success': service.online, 'badge-danger': !service.online}">
|
||||||
{{service.online ? "ONLINE" : "OFFLINE"}}
|
{{service.online ? "ONLINE" : "OFFLINE"}}
|
||||||
</span>
|
</span>
|
||||||
|
@ -44,13 +45,13 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
<button @click.prevent="Tab('incident')" class="btn btn-block btn-outline-secondary" :class="{'text-white btn-secondary': openTab==='incident'}" >Create Incident</button>
|
<button @click.prevent="Tab('incident')" class="btn btn-block btn-outline-secondary incident" :class="{'text-white btn-secondary': openTab==='incident'}" >Incidents</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
<button @click.prevent="Tab('message')" class="btn btn-block btn-outline-secondary" :class="{'text-white btn-secondary': openTab==='message'}">Create Announcement</button>
|
<button @click.prevent="Tab('message')" class="btn btn-block btn-outline-secondary message" :class="{'text-white btn-secondary': openTab==='message'}">Announcements</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
<button @click.prevent="Tab('failures')" class="btn btn-block btn-outline-secondary" :disabled="service.stats.failures === 0" :class="{'text-white btn-secondary': openTab==='failures'}">
|
<button @click.prevent="Tab('failures')" class="btn btn-block btn-outline-secondary failures" :disabled="service.stats.failures === 0" :class="{'text-white btn-secondary': openTab==='failures'}">
|
||||||
Failures <span class="badge badge-danger float-right mt-1">{{service.stats.failures}}</span></button>
|
Failures <span class="badge badge-danger float-right mt-1">{{service.stats.failures}}</span></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
<div v-for="(incident, i) in incidents" class="card contain-card text-black-50 bg-white mb-4">
|
<div v-for="(incident, i) in incidents" class="card contain-card text-black-50 bg-white mb-4">
|
||||||
<div class="card-header">Incident: {{incident.title}}
|
<div class="card-header">Incident: {{incident.title}}
|
||||||
<button v-if="IsAdmin()" @click="deleteIncident(incident)" class="btn btn-sm btn-danger float-right">
|
<button @click="deleteIncident(incident)" class="btn btn-sm btn-danger float-right">
|
||||||
<font-awesome-icon icon="times" /> Delete
|
<font-awesome-icon icon="times" /> Delete
|
||||||
</button></div>
|
</button></div>
|
||||||
<div class="card-body bg-light pt-1">
|
<div class="card-body bg-light pt-1">
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div v-if="IsAdmin()" class="card contain-card text-black-50 bg-white mb-5">
|
<div class="card contain-card text-black-50 bg-white mb-5">
|
||||||
<div class="card-header">Create Incident for {{service.name}}</div>
|
<div class="card-header">Create Incident for {{service.name}}</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form @submit.prevent="createIncident">
|
<form @submit.prevent="createIncident">
|
||||||
|
@ -79,16 +79,16 @@
|
||||||
await this.loadIncidents()
|
await this.loadIncidents()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async loadIncidents() {
|
async loadIncidents() {
|
||||||
this.incidents = await Api.incidents_service(this.service)
|
this.incidents = await Api.incidents_service(this.service)
|
||||||
},
|
},
|
||||||
async createIncident() {
|
async createIncident() {
|
||||||
await Api.incident_create(this.service, this.incident)
|
await Api.incident_create(this.service, this.incident)
|
||||||
await this.loadIncidents()
|
await this.loadIncidents()
|
||||||
this.incident = {
|
this.incident = {
|
||||||
title: "",
|
title: "",
|
||||||
description: "",
|
description: "",
|
||||||
service: this.service.id,
|
service: this.service.id,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async deleteIncident(incident) {
|
async deleteIncident(incident) {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-sm-4 col-form-label">Service Name</label>
|
<label class="col-sm-4 col-form-label">Service Name</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<input v-model="service.name" @input="updatePermalink" type="text" name="name" class="form-control" placeholder="Server Name" required spellcheck="false" autocorrect="off">
|
<input v-model="service.name" @input="updatePermalink" id="name" type="text" name="name" class="form-control" placeholder="Server Name" required spellcheck="false" autocorrect="off">
|
||||||
<small class="form-text text-muted">Give your service a name you can recognize</small>
|
<small class="form-text text-muted">Give your service a name you can recognize</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -101,7 +101,7 @@
|
||||||
<label class="col-sm-4 col-form-label">Request Timeout</label>
|
<label class="col-sm-4 col-form-label">Request Timeout</label>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<span class="slider-info">{{secondsHumanize(service.timeout)}}</span>
|
<span class="slider-info">{{secondsHumanize(service.timeout)}}</span>
|
||||||
<input v-model="service.timeout" type="range" name="timeout" class="slider" min="1" max="180">
|
<input v-model="service.timeout" type="range" id="timeout" name="timeout" class="slider" min="1" max="180">
|
||||||
<small class="form-text text-muted">If the endpoint does not respond within this time it will be considered to be offline</small>
|
<small class="form-text text-muted">If the endpoint does not respond within this time it will be considered to be offline</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,7 +16,7 @@ func Samples() error {
|
||||||
|
|
||||||
group2 := &Group{
|
group2 := &Group{
|
||||||
Name: "Linked Services",
|
Name: "Linked Services",
|
||||||
Public: null.NewNullBool(false),
|
Public: null.NewNullBool(true),
|
||||||
Order: 1,
|
Order: 1,
|
||||||
}
|
}
|
||||||
if err := group2.Create(); err != nil {
|
if err := group2.Create(); err != nil {
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
package incidents
|
package incidents
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/statping/statping/utils"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
func Samples() error {
|
func Samples() error {
|
||||||
incident1 := &Incident{
|
incident1 := &Incident{
|
||||||
Title: "Github Downtime",
|
Title: "Github Downtime",
|
||||||
|
@ -10,30 +15,12 @@ func Samples() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
i1 := &IncidentUpdate{
|
incident2 := &Incident{
|
||||||
IncidentId: incident1.Id,
|
Title: "Recent Downtime",
|
||||||
Message: "Github's page for Statping seems to be sending a 501 error.",
|
Description: "We've noticed an issue with authentications and we're looking into it now.",
|
||||||
Type: "Investigating",
|
ServiceId: 4,
|
||||||
}
|
}
|
||||||
if err := i1.Create(); err != nil {
|
if err := incident2.Create(); err != nil {
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
i2 := &IncidentUpdate{
|
|
||||||
IncidentId: incident1.Id,
|
|
||||||
Message: "Problem is continuing and we are looking at the issues.",
|
|
||||||
Type: "Update",
|
|
||||||
}
|
|
||||||
if err := i2.Create(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
i3 := &IncidentUpdate{
|
|
||||||
IncidentId: incident1.Id,
|
|
||||||
Message: "Github is now back online and everything is working.",
|
|
||||||
Type: "Resolved",
|
|
||||||
}
|
|
||||||
if err := i3.Create(); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,13 +28,56 @@ func Samples() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func SamplesUpdates() error {
|
func SamplesUpdates() error {
|
||||||
u1 := &IncidentUpdate{
|
t := utils.Now()
|
||||||
|
|
||||||
|
i1 := &IncidentUpdate{
|
||||||
|
IncidentId: 1,
|
||||||
|
Message: "Github's page for Statping seems to be sending a 501 error.",
|
||||||
|
Type: "Investigating",
|
||||||
|
CreatedAt: t.Add(-60 * time.Minute),
|
||||||
|
}
|
||||||
|
if err := i1.Create(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
i2 := &IncidentUpdate{
|
||||||
|
IncidentId: 1,
|
||||||
|
Message: "Problem is continuing and we are looking at the issues.",
|
||||||
|
Type: "Update",
|
||||||
|
CreatedAt: t.Add(-30 * time.Minute),
|
||||||
|
}
|
||||||
|
if err := i2.Create(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
i3 := &IncidentUpdate{
|
||||||
IncidentId: 1,
|
IncidentId: 1,
|
||||||
Message: "Github is now back online and everything is working.",
|
Message: "Github is now back online and everything is working.",
|
||||||
Type: "Resolved",
|
Type: "Resolved",
|
||||||
|
CreatedAt: t.Add(-5 * time.Minute),
|
||||||
|
}
|
||||||
|
if err := i3.Create(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
u1 := &IncidentUpdate{
|
||||||
|
IncidentId: 2,
|
||||||
|
Message: "Github is now back online and everything is working.",
|
||||||
|
Type: "Resolved",
|
||||||
|
CreatedAt: t.Add(-120 * time.Minute),
|
||||||
}
|
}
|
||||||
if err := u1.Create(); err != nil {
|
if err := u1.Create(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u2 := &IncidentUpdate{
|
||||||
|
IncidentId: 2,
|
||||||
|
Message: "Github is now back online and everything is working.",
|
||||||
|
Type: "Resolved",
|
||||||
|
CreatedAt: t.Add(-60 * time.Minute),
|
||||||
|
}
|
||||||
|
if err := u2.Create(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
0.90.22
|
0.90.23
|
||||||
|
|
Loading…
Reference in New Issue