From 32623fa9cef259d815cf994b857efcd30e7731ef Mon Sep 17 00:00:00 2001 From: Kyle Brandt Date: Mon, 16 May 2016 12:23:45 -0400 Subject: [PATCH] cmd/scollector: fastly status.io monitoring and status.io lib (#1735) --- cmd/scollector/collectors/fastly.go | 92 +++++ cmd/scollector/conf/conf.go | 3 +- metadata/metadata.go | 1 + .../github.com/bosun-monitor/statusio/LICENSE | 21 ++ .../statusio/componentstatus_jsonenums.go | 62 ++++ .../statusio/incidentstatus_jsonenums.go | 65 ++++ .../statusio/maintenancestatus_jsonenums.go | 62 ++++ .../statusio/statusindicator_jsonenums.go | 62 ++++ .../bosun-monitor/statusio/statusio.go | 343 ++++++++++++++++++ vendor/vendor.json | 5 + 10 files changed, 715 insertions(+), 1 deletion(-) create mode 100644 vendor/github.com/bosun-monitor/statusio/LICENSE create mode 100644 vendor/github.com/bosun-monitor/statusio/componentstatus_jsonenums.go create mode 100644 vendor/github.com/bosun-monitor/statusio/incidentstatus_jsonenums.go create mode 100644 vendor/github.com/bosun-monitor/statusio/maintenancestatus_jsonenums.go create mode 100644 vendor/github.com/bosun-monitor/statusio/statusindicator_jsonenums.go create mode 100644 vendor/github.com/bosun-monitor/statusio/statusio.go diff --git a/cmd/scollector/collectors/fastly.go b/cmd/scollector/collectors/fastly.go index 420e3dc6b9..29a492458a 100644 --- a/cmd/scollector/collectors/fastly.go +++ b/cmd/scollector/collectors/fastly.go @@ -7,6 +7,7 @@ import ( "net/http" "net/url" "reflect" + "regexp" "strconv" "time" @@ -14,6 +15,7 @@ import ( "bosun.org/metadata" "bosun.org/opentsdb" "bosun.org/slog" + "github.com/bosun-monitor/statusio" ) func init() { @@ -34,6 +36,15 @@ func init() { name: "c_fastly_billing", Interval: time.Minute * 5, }) + if f.StatusBaseAddr != "" { + collectors = append(collectors, &IntervalCollector{ + F: func() (opentsdb.MultiDataPoint, error) { + return c_fastly_status(f.StatusBaseAddr) + }, + name: "c_fastly_status", + Interval: time.Minute * 1, + }) + } } }) } @@ -50,8 +61,89 @@ const ( fastlyBillingBeforeDiscountDesc = "The total incurred cost plus extras cost this month." fastlyBillingDiscountDesc = "The calculated discount rate this month." fastlyBillingCostDesc = "The final amount to be paid this month." + + fastlyStatusPrefix = "fastly.status." + fastlyComponentStatusDesc = "The current status of the %v. 0: Operational, 1: Degraded Performance, 2: Partial Outage, 3: Major Outage." // see iota for statusio.ComponentStatus + fastlyScheduledMaintDesc = "The number of currently scheduled maintenances. Does not include maintenance that is current active" + fastlyActiveScheduledMaintDesc = "The number of currently scheduled maintenances currently in progress. Includes the 'in_progress' and 'verifying'" + fastlyActiveIncidentDesc = "The number of currently active incidents. Includes the 'investingating', 'identified', and 'monitoring' states." +) + +var ( + fastlyStatusPopRegex = regexp.MustCompile(`(.*)\(([A-Z]{3})\)`) // i.e. Miami (MIA) ) +func c_fastly_status(baseAddr string) (opentsdb.MultiDataPoint, error) { + var md opentsdb.MultiDataPoint + c := statusio.NewClient(baseAddr) + summary, err := c.GetSummary() + if err != nil { + return md, err + } + + // Process Components (Pops, Support Systems) + for _, comp := range summary.Components { + match := fastlyStatusPopRegex.FindAllStringSubmatch(comp.Name, 1) + if len(match) != 0 && len(match[0]) == 3 { // We have a pop + //name := match[0][1] + code := match[0][2] + tagSet := opentsdb.TagSet{"code": code} + Add(&md, fastlyStatusPrefix+"pop", int(comp.Status), tagSet, metadata.Gauge, metadata.StatusCode, fmt.Sprintf(fastlyComponentStatusDesc, "pop")) + continue + } + // Must be service component + tagSet := opentsdb.TagSet{"service": comp.Name} + Add(&md, fastlyStatusPrefix+"service", int(comp.Status), tagSet, metadata.Gauge, metadata.StatusCode, fmt.Sprintf(fastlyComponentStatusDesc, "service")) + } + + // Scheduled Maintenance + scheduledMaintByImpact := make(map[statusio.StatusIndicator]int) + activeScheduledMaintByImpact := make(map[statusio.StatusIndicator]int) + // Make Maps + for _, si := range statusio.StatusIndicatorValues { + scheduledMaintByImpact[si] = 0 + activeScheduledMaintByImpact[si] = 0 + } + // Group by scheduled vs inprogress/verifying + for _, maint := range summary.ScheduledMaintenances { + switch maint.Status { + case statusio.Scheduled: + scheduledMaintByImpact[maint.Impact]++ + case statusio.InProgress, statusio.Verifying: + activeScheduledMaintByImpact[maint.Impact]++ + } + } + for impact, count := range scheduledMaintByImpact { + tagSet := opentsdb.TagSet{"impact": fmt.Sprint(impact)} + Add(&md, fastlyStatusPrefix+"scheduled_maint_count", count, tagSet, metadata.Gauge, metadata.Count, fastlyScheduledMaintDesc) + } + for impact, count := range activeScheduledMaintByImpact { + tagSet := opentsdb.TagSet{"impact": fmt.Sprint(impact)} + Add(&md, fastlyStatusPrefix+"in_progress_maint_count", count, tagSet, metadata.Gauge, metadata.Count, fastlyActiveScheduledMaintDesc) + } + + // Incidents + // Make Map + incidentsByImpact := make(map[statusio.StatusIndicator]int) + for _, si := range statusio.StatusIndicatorValues { + incidentsByImpact[si] = 0 + } + for _, incident := range summary.Incidents { + switch incident.Status { + case statusio.Investigating, statusio.Identified, statusio.Monitoring: + incidentsByImpact[incident.Impact]++ + default: + continue + } + } + for impact, count := range incidentsByImpact { + tagSet := opentsdb.TagSet{"impact": fmt.Sprint(impact)} + Add(&md, fastlyStatusPrefix+"active_incident_count", count, tagSet, metadata.Gauge, metadata.Incident, fastlyActiveIncidentDesc) + } + + return md, nil +} + func c_fastly_billing(c fastlyClient) (opentsdb.MultiDataPoint, error) { var md opentsdb.MultiDataPoint now := time.Now().UTC() diff --git a/cmd/scollector/conf/conf.go b/cmd/scollector/conf/conf.go index 39bee533f9..7389d5de31 100644 --- a/cmd/scollector/conf/conf.go +++ b/cmd/scollector/conf/conf.go @@ -101,7 +101,8 @@ type GoogleAnalytics struct { } type Fastly struct { - Key string + Key string + StatusBaseAddr string } type GoogleAnalyticsSite struct { diff --git a/metadata/metadata.go b/metadata/metadata.go index 60667bf8c5..e17fb9f492 100644 --- a/metadata/metadata.go +++ b/metadata/metadata.go @@ -71,6 +71,7 @@ const ( Fraction = "fraction" Get = "gets" GetExists = "get exists" + Incident = "incidents" Interupt = "interupts" InProgress = "in progress" Item = "items" diff --git a/vendor/github.com/bosun-monitor/statusio/LICENSE b/vendor/github.com/bosun-monitor/statusio/LICENSE new file mode 100644 index 0000000000..cb7f954921 --- /dev/null +++ b/vendor/github.com/bosun-monitor/statusio/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Stack Exchange + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/bosun-monitor/statusio/componentstatus_jsonenums.go b/vendor/github.com/bosun-monitor/statusio/componentstatus_jsonenums.go new file mode 100644 index 0000000000..7ab78a3d78 --- /dev/null +++ b/vendor/github.com/bosun-monitor/statusio/componentstatus_jsonenums.go @@ -0,0 +1,62 @@ +// generated by jsonenums -type=ComponentStatus; DO NOT EDIT + +package statusio + +import ( + "encoding/json" + "fmt" +) + +var ( + _ComponentStatusNameToValue = map[string]ComponentStatus{ + "Operational": Operational, + "DegradedPerformance": DegradedPerformance, + "PartialOutage": PartialOutage, + "MajorOutage": MajorOutage, + } + + _ComponentStatusValueToName = map[ComponentStatus]string{ + Operational: "Operational", + DegradedPerformance: "DegradedPerformance", + PartialOutage: "PartialOutage", + MajorOutage: "MajorOutage", + } +) + +func init() { + var v ComponentStatus + if _, ok := interface{}(v).(fmt.Stringer); ok { + _ComponentStatusNameToValue = map[string]ComponentStatus{ + interface{}(Operational).(fmt.Stringer).String(): Operational, + interface{}(DegradedPerformance).(fmt.Stringer).String(): DegradedPerformance, + interface{}(PartialOutage).(fmt.Stringer).String(): PartialOutage, + interface{}(MajorOutage).(fmt.Stringer).String(): MajorOutage, + } + } +} + +// MarshalJSON is generated so ComponentStatus satisfies json.Marshaler. +func (r ComponentStatus) MarshalJSON() ([]byte, error) { + if s, ok := interface{}(r).(fmt.Stringer); ok { + return json.Marshal(s.String()) + } + s, ok := _ComponentStatusValueToName[r] + if !ok { + return nil, fmt.Errorf("invalid ComponentStatus: %d", r) + } + return json.Marshal(s) +} + +// UnmarshalJSON is generated so ComponentStatus satisfies json.Unmarshaler. +func (r *ComponentStatus) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return fmt.Errorf("ComponentStatus should be a string, got %s", data) + } + v, ok := _ComponentStatusNameToValue[s] + if !ok { + return fmt.Errorf("invalid ComponentStatus %q", s) + } + *r = v + return nil +} diff --git a/vendor/github.com/bosun-monitor/statusio/incidentstatus_jsonenums.go b/vendor/github.com/bosun-monitor/statusio/incidentstatus_jsonenums.go new file mode 100644 index 0000000000..4b39ecbdd8 --- /dev/null +++ b/vendor/github.com/bosun-monitor/statusio/incidentstatus_jsonenums.go @@ -0,0 +1,65 @@ +// generated by jsonenums -type=IncidentStatus; DO NOT EDIT + +package statusio + +import ( + "encoding/json" + "fmt" +) + +var ( + _IncidentStatusNameToValue = map[string]IncidentStatus{ + "Investigating": Investigating, + "Identified": Identified, + "Monitoring": Monitoring, + "Resolved": Resolved, + "PostMortem": PostMortem, + } + + _IncidentStatusValueToName = map[IncidentStatus]string{ + Investigating: "Investigating", + Identified: "Identified", + Monitoring: "Monitoring", + Resolved: "Resolved", + PostMortem: "PostMortem", + } +) + +func init() { + var v IncidentStatus + if _, ok := interface{}(v).(fmt.Stringer); ok { + _IncidentStatusNameToValue = map[string]IncidentStatus{ + interface{}(Investigating).(fmt.Stringer).String(): Investigating, + interface{}(Identified).(fmt.Stringer).String(): Identified, + interface{}(Monitoring).(fmt.Stringer).String(): Monitoring, + interface{}(Resolved).(fmt.Stringer).String(): Resolved, + interface{}(PostMortem).(fmt.Stringer).String(): PostMortem, + } + } +} + +// MarshalJSON is generated so IncidentStatus satisfies json.Marshaler. +func (r IncidentStatus) MarshalJSON() ([]byte, error) { + if s, ok := interface{}(r).(fmt.Stringer); ok { + return json.Marshal(s.String()) + } + s, ok := _IncidentStatusValueToName[r] + if !ok { + return nil, fmt.Errorf("invalid IncidentStatus: %d", r) + } + return json.Marshal(s) +} + +// UnmarshalJSON is generated so IncidentStatus satisfies json.Unmarshaler. +func (r *IncidentStatus) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return fmt.Errorf("IncidentStatus should be a string, got %s", data) + } + v, ok := _IncidentStatusNameToValue[s] + if !ok { + return fmt.Errorf("invalid IncidentStatus %q", s) + } + *r = v + return nil +} diff --git a/vendor/github.com/bosun-monitor/statusio/maintenancestatus_jsonenums.go b/vendor/github.com/bosun-monitor/statusio/maintenancestatus_jsonenums.go new file mode 100644 index 0000000000..ca16501966 --- /dev/null +++ b/vendor/github.com/bosun-monitor/statusio/maintenancestatus_jsonenums.go @@ -0,0 +1,62 @@ +// generated by jsonenums -type=MaintenanceStatus; DO NOT EDIT + +package statusio + +import ( + "encoding/json" + "fmt" +) + +var ( + _MaintenanceStatusNameToValue = map[string]MaintenanceStatus{ + "Scheduled": Scheduled, + "InProgress": InProgress, + "Verifying": Verifying, + "Completed": Completed, + } + + _MaintenanceStatusValueToName = map[MaintenanceStatus]string{ + Scheduled: "Scheduled", + InProgress: "InProgress", + Verifying: "Verifying", + Completed: "Completed", + } +) + +func init() { + var v MaintenanceStatus + if _, ok := interface{}(v).(fmt.Stringer); ok { + _MaintenanceStatusNameToValue = map[string]MaintenanceStatus{ + interface{}(Scheduled).(fmt.Stringer).String(): Scheduled, + interface{}(InProgress).(fmt.Stringer).String(): InProgress, + interface{}(Verifying).(fmt.Stringer).String(): Verifying, + interface{}(Completed).(fmt.Stringer).String(): Completed, + } + } +} + +// MarshalJSON is generated so MaintenanceStatus satisfies json.Marshaler. +func (r MaintenanceStatus) MarshalJSON() ([]byte, error) { + if s, ok := interface{}(r).(fmt.Stringer); ok { + return json.Marshal(s.String()) + } + s, ok := _MaintenanceStatusValueToName[r] + if !ok { + return nil, fmt.Errorf("invalid MaintenanceStatus: %d", r) + } + return json.Marshal(s) +} + +// UnmarshalJSON is generated so MaintenanceStatus satisfies json.Unmarshaler. +func (r *MaintenanceStatus) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return fmt.Errorf("MaintenanceStatus should be a string, got %s", data) + } + v, ok := _MaintenanceStatusNameToValue[s] + if !ok { + return fmt.Errorf("invalid MaintenanceStatus %q", s) + } + *r = v + return nil +} diff --git a/vendor/github.com/bosun-monitor/statusio/statusindicator_jsonenums.go b/vendor/github.com/bosun-monitor/statusio/statusindicator_jsonenums.go new file mode 100644 index 0000000000..6caf157313 --- /dev/null +++ b/vendor/github.com/bosun-monitor/statusio/statusindicator_jsonenums.go @@ -0,0 +1,62 @@ +// generated by jsonenums -type=StatusIndicator; DO NOT EDIT + +package statusio + +import ( + "encoding/json" + "fmt" +) + +var ( + _StatusIndicatorNameToValue = map[string]StatusIndicator{ + "None": None, + "Minor": Minor, + "Major": Major, + "Critical": Critical, + } + + _StatusIndicatorValueToName = map[StatusIndicator]string{ + None: "None", + Minor: "Minor", + Major: "Major", + Critical: "Critical", + } +) + +func init() { + var v StatusIndicator + if _, ok := interface{}(v).(fmt.Stringer); ok { + _StatusIndicatorNameToValue = map[string]StatusIndicator{ + interface{}(None).(fmt.Stringer).String(): None, + interface{}(Minor).(fmt.Stringer).String(): Minor, + interface{}(Major).(fmt.Stringer).String(): Major, + interface{}(Critical).(fmt.Stringer).String(): Critical, + } + } +} + +// MarshalJSON is generated so StatusIndicator satisfies json.Marshaler. +func (r StatusIndicator) MarshalJSON() ([]byte, error) { + if s, ok := interface{}(r).(fmt.Stringer); ok { + return json.Marshal(s.String()) + } + s, ok := _StatusIndicatorValueToName[r] + if !ok { + return nil, fmt.Errorf("invalid StatusIndicator: %d", r) + } + return json.Marshal(s) +} + +// UnmarshalJSON is generated so StatusIndicator satisfies json.Unmarshaler. +func (r *StatusIndicator) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return fmt.Errorf("StatusIndicator should be a string, got %s", data) + } + v, ok := _StatusIndicatorNameToValue[s] + if !ok { + return fmt.Errorf("invalid StatusIndicator %q", s) + } + *r = v + return nil +} diff --git a/vendor/github.com/bosun-monitor/statusio/statusio.go b/vendor/github.com/bosun-monitor/statusio/statusio.go new file mode 100644 index 0000000000..3882d8e5cc --- /dev/null +++ b/vendor/github.com/bosun-monitor/statusio/statusio.go @@ -0,0 +1,343 @@ +// Package statusio provides a client for the public v2 api of pages powered by statusio +package statusio + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "time" + + "bosun.org/slog" +) + +type Client struct { + baseAddr string + client *http.Client +} + +// NewClient creates a new statusio client for the *public api*. +// baseAddr is i.e. status.example.copm/api/v2/ +func NewClient(baseAddr string) *Client { + return &Client{ + baseAddr: baseAddr, + client: &http.Client{}, + } +} + +type SummaryResponse struct { + Components []Component `json:"components"` + Incidents []Incident `json:"incidents"` + Page Page `json:"page"` + ScheduledMaintenances []ScheduledMaintenance `json:"scheduled_maintenances"` + Status struct { + Description string `json:"description"` + StatusIndicator string `json:"indicator"` + } `json:"status"` +} + +// GetSummary returns a summary of the status page, including a status indicator, component statuses, unresolved incidents, and any upcoming or in-progress scheduled maintenances. +func (c *Client) GetSummary() (SummaryResponse, error) { + s := SummaryResponse{} + err := c.request("api/v2/summary.json", &s) + return s, err +} + +type StatusResponse struct { + Page Page `json:"page"` + Status struct { + Description string `json:"description"` + Indicator StatusIndicator `json:"indicator"` + } `json:"status"` +} + +// GetStatus returns rollup for the whole page. This endpoint includes an indicator - one of none, minor, major, or critical, as well as a human description of the blended component status. +// Examples of the blended status include "All Systems Operational", "Partial System Outage", and "Major Service Outage". +func (c *Client) GetStatus() (StatusResponse, error) { + s := StatusResponse{} + err := c.request("api/v2/status.json", &s) + return s, err +} + +type ComponentsResponse struct { + Components []Component `json:"components"` + Page Page `json:"page"` +} + +// GetComponents gets the components for the page. Each component is listed along with its status - one of operational, degraded_performance, partial_outage, or major_outage. +func (c *Client) GetComponents() (ComponentsResponse, error) { + comp := ComponentsResponse{} + err := c.request("api/v2/components.json", &comp) + return comp, err +} + +type IncidentsResponse struct { + Incidents []Incident `json:"incidents"` + Page Page `json:"page"` +} + +// GetUnresolvedIncidents gets a list of any unresolved incidents. +// This endpoint will only return incidents in the Investigating, Identified, or Monitoring state. +func (c *Client) GetUnresolvedIncidents() (IncidentsResponse, error) { + i := IncidentsResponse{} + err := c.request("api/v2/incidents/unresolved.json", &i) + return i, err +} + +// GetIncidents returns a list of the 50 most recent incidents. +// This includes all unresolved incidents returned in GetUnresolvedIncidents, as well as those in the Resolved and Postmortem state. +func (c *Client) GetIncidents() (IncidentsResponse, error) { + i := IncidentsResponse{} + err := c.request("api/v2/incidents.json", &i) + return i, err +} + +type ScheduledMaintenancesResponse struct { + Page Page `json:"page"` + ScheduledMaintenances []ScheduledMaintenance `json:"scheduled_maintenances"` +} + +// GetUpcomingScheduledMaintenances gets a list of any upcoming maintenances. +// This endpoint will only return scheduled maintenances still in the Scheduled state. +func (c *Client) GetUpcomingScheduledMaintenances() (ScheduledMaintenancesResponse, error) { + s := ScheduledMaintenancesResponse{} + err := c.request("api/v2/scheduled-maintenances/upcoming.json", &s) + return s, err +} + +// GetActiveScheduledMaintenances gets a list of any upcoming maintenances. // This endpoint will only return scheduled maintenances in the In Progress or Verifying state. +func (c *Client) GetActiveScheduledMaintenances() (ScheduledMaintenancesResponse, error) { + s := ScheduledMaintenancesResponse{} + err := c.request("api/v2/scheduled-maintenances/active.json", &s) + return s, err +} + +// GetAllScheduledMaintenances gets a list of the 50 most recent scheduled maintenances. +// This includes scheduled maintenances as described in the above two endpoints, as well as those in the Completed state. +func (c *Client) GetAllScheduledMaintenances() (ScheduledMaintenancesResponse, error) { + s := ScheduledMaintenancesResponse{} + err := c.request("api/v2/scheduled-maintenances.json", &s) + return s, err +} + +type NotImplemented bool + +// GetPageSubscribers is not implemented +func (c *Client) GetPageSubscribers() NotImplemented { + return true +} + +// GetIncidentSubscribers is not implemented +func (c *Client) GetIncidentSubscribers() NotImplemented { + return true +} + +// RemoveSubscription is not implemented +func (c *Client) RemoveSubscription() NotImplemented { + return true +} + +func (c *Client) request(path string, s interface{}) error { + u := &url.URL{ + Scheme: "https", + Host: c.baseAddr, + Path: path, + } + req, err := http.NewRequest("GET", u.String(), nil) + if err != nil { + slog.Error(err) + return err + } + req.Header.Set("Accept", "application/json") + resp, err := c.client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + if resp.StatusCode != 200 { + b, _ := ioutil.ReadAll(resp.Body) + return fmt.Errorf("%v: %v: %v", req.URL, resp.Status, string(b)) + } + d := json.NewDecoder(resp.Body) + if err := d.Decode(&s); err != nil { + return err + } + return nil +} + +// Page is part of all status.io public api responses. +type Page struct { + ID string `json:"id"` + Name string `json:"name"` + UpdatedAt *time.Time `json:"updated_at"` + URL string `json:"url"` +} + +type Component struct { + CreatedAt *time.Time `json:"created_at"` + Description interface{} `json:"description"` + Group bool `json:"group"` + GroupID interface{} `json:"group_id"` + ID string `json:"id"` + Name string `json:"name"` + OnlyShowIfDegraded bool `json:"only_show_if_degraded"` + PageID string `json:"page_id"` + Position int `json:"position"` + Status ComponentStatus `json:"status"` + UpdatedAt *time.Time `json:"updated_at"` +} + +type Incident struct { + CreatedAt *time.Time `json:"created_at"` + ID string `json:"id"` + Impact StatusIndicator `json:"impact"` + IncidentUpdates []IncidentUpdate `json:"incident_updates"` + MonitoringAt *time.Time `json:"monitoring_at"` + Name string `json:"name"` + PageID string `json:"page_id"` + ResolvedAt *time.Time `json:"resolved_at"` + Shortlink string `json:"shortlink"` + Status IncidentStatus `json:"status"` + UpdatedAt *time.Time `json:"updated_at"` +} + +type IncidentUpdate struct { + Body string `json:"body"` + CreatedAt *time.Time `json:"created_at"` + DisplayAt *time.Time `json:"display_at"` + ID string `json:"id"` + IncidentID string `json:"incident_id"` + Status string `json:"status"` + UpdatedAt *time.Time `json:"updated_at"` +} + +type ScheduledMaintenance struct { + CreatedAt *time.Time `json:"created_at"` + ID string `json:"id"` + Impact StatusIndicator `json:"impact"` + IncidentUpdates []IncidentUpdate `json:"incident_updates"` + MonitoringAt *time.Time `json:"monitoring_at"` + Name string `json:"name"` + PageID string `json:"page_id"` + ResolvedAt *time.Time `json:"resolved_at"` + ScheduledFor *time.Time `json:"scheduled_for"` + ScheduledUntil *time.Time `json:"scheduled_until"` + Shortlink string `json:"shortlink"` + Status MaintenanceStatus `json:"status"` + UpdatedAt *time.Time `json:"updated_at"` +} + +type ComponentStatus int + +func (c ComponentStatus) String() string { + switch c { + case 0: + return "operational" + case 1: + return "degraded_performance" + case 2: + return "partial_outage" + case 3: + return "major_outage" + } + return "UnexpectedComponentStatus" +} + +// Comments are the JSON representation +const ( + Operational ComponentStatus = iota // operational + DegradedPerformance // degraded_performance + PartialOutage // partial_outage + MajorOutage // major_outage +) + +// ComponentStatusValues represents all the possible values of the ComponetStatus iota +var ComponentStatusValues = []ComponentStatus{Operational, DegradedPerformance, PartialOutage, MajorOutage} + +// StatusIndicator is an enum used for general status and impact fields +type StatusIndicator int // ScheduledMaintenance Impact field seems to use the same enum + +func (s StatusIndicator) String() string { + switch s { + case 0: + return "none" + case 1: + return "minor" + case 2: + return "major" + case 3: + return "critical" + } + return "UnexpectedStatusIndicator" +} + +// Comments are the JSON representation +const ( + None StatusIndicator = iota // none + Minor // minor + Major // major + Critical // critical +) + +// StatusIndicatorValues represents all the possible values of the StatusIndicator iota +var StatusIndicatorValues = []StatusIndicator{None, Minor, Major, Critical} + +// IncidentStatus represents the status of an incident +type IncidentStatus int + +func (i IncidentStatus) String() string { + switch i { + case 0: + return "investigating" + case 1: + return "identified" + case 2: + return "monitoring" + case 3: + return "resolved" + case 4: + return "post_mortem" + } + return "UnexpectedIncidentStatus" +} + +// Comments are the JSON representation +const ( + Investigating IncidentStatus = iota // investigating + Identified // identified + Monitoring // monitoring + Resolved // resolved + PostMortem // post_mortem (?) Guessing, the documentation doesn't use the literals for this enum +) + +// IncidentStatusValues represents all the possible values of an incident status +var IncidenStatusValues = []IncidentStatus{Investigating, Identified, Monitoring, Resolved, PostMortem} + +// MaintenanceStatus represents the status of a maintenance operation +type MaintenanceStatus int + +func (m MaintenanceStatus) String() string { + switch m { + case 0: + return "scheduled" + case 1: + return "in_progress" + case 2: + return "verifying" + case 3: + return "completed" + } + return "UnexpectedMaintenanceStatus" +} + +// Comments are the JSON representation +const ( + Scheduled MaintenanceStatus = iota // scheduled + InProgress // in_progress (?) Guessing, the documentation doesn't use the literals for this enum + Verifying // verifying + Completed // completed +) + +// MaitenanceStatusValues represents all the possible values of the MaintenanceStatus enum +var MaintenanceStatusValues = []MaintenanceStatus{Scheduled, InProgress, Verifying, Completed} diff --git a/vendor/vendor.json b/vendor/vendor.json index 62c142a487..231f7c163a 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -205,6 +205,11 @@ "revision": "68b0a4165b545e37b87b3b4b8baca55156ac9119", "revisionTime": "2016-04-29T11:34:44-04:00" }, + { + "path": "github.com/bosun-monitor/statusio", + "revision": "ab1583139762a47425d3c189a7cb6344c3220d95", + "revisionTime": "2016-05-16T12:08:16-04:00" + }, { "path": "github.com/bradfitz/slice", "revision": "a665b5dbaad5fc7474c1193c67ed138df1e1b0e7",