-
Notifications
You must be signed in to change notification settings - Fork 314
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Uptime Checks and Alerts Support (#593)
* Add uptime checks and alerts support * typo * Alert -> UptimeAlert, Fix "GetState" * GetUptimeCheckState -> GetState, Regions -> map[string]UptimeRegion
- Loading branch information
Showing
3 changed files
with
940 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,342 @@ | ||
package godo | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"net/http" | ||
"path" | ||
) | ||
|
||
const uptimeChecksBasePath = "/v2/uptime/checks" | ||
|
||
// UptimeChecksService is an interface for creating and managing Uptime checks with the DigitalOcean API. | ||
// See: https://docs.digitalocean.com/reference/api/api-reference/#tag/Uptime | ||
type UptimeChecksService interface { | ||
List(context.Context, *ListOptions) ([]UptimeCheck, *Response, error) | ||
Get(context.Context, string) (*UptimeCheck, *Response, error) | ||
GetState(context.Context, string) (*UptimeCheckState, *Response, error) | ||
Create(context.Context, *CreateUptimeCheckRequest) (*UptimeCheck, *Response, error) | ||
Update(context.Context, string, *UpdateUptimeCheckRequest) (*UptimeCheck, *Response, error) | ||
Delete(context.Context, string) (*Response, error) | ||
GetAlert(context.Context, string, string) (*UptimeAlert, *Response, error) | ||
ListAlerts(context.Context, string, *ListOptions) ([]UptimeAlert, *Response, error) | ||
CreateAlert(context.Context, string, *CreateUptimeAlertRequest) (*UptimeAlert, *Response, error) | ||
UpdateAlert(context.Context, string, string, *UpdateUptimeAlertRequest) (*UptimeAlert, *Response, error) | ||
DeleteAlert(context.Context, string, string) (*Response, error) | ||
} | ||
|
||
// UptimeChecksServiceOp handles communication with Uptime Check methods of the DigitalOcean API. | ||
type UptimeChecksServiceOp struct { | ||
client *Client | ||
} | ||
|
||
// UptimeCheck represents a DigitalOcean UptimeCheck configuration. | ||
type UptimeCheck struct { | ||
ID string `json:"id"` | ||
Name string `json:"name"` | ||
Type string `json:"type"` | ||
Target string `json:"target"` | ||
Regions []string `json:"regions"` | ||
Enabled bool `json:"enabled"` | ||
} | ||
|
||
// UptimeAlert represents a DigitalOcean Uptime Alert configuration. | ||
type UptimeAlert struct { | ||
ID string `json:"id"` | ||
Name string `json:"name"` | ||
Type string `json:"type"` | ||
Threshold int `json:"threshold"` | ||
Comparison string `json:"comparison"` | ||
Notifications *Notifications `json:"notifications"` | ||
Period string `json:"period"` | ||
} | ||
|
||
// Notifications represents a DigitalOcean Notifications configuration. | ||
type Notifications struct { | ||
Email []string `json:"email"` | ||
Slack []SlackDetails `json:"slack"` | ||
} | ||
|
||
// UptimeCheckState represents a DigitalOcean Uptime Check's state configuration. | ||
type UptimeCheckState struct { | ||
Regions map[string]UptimeRegion `json:"regions"` | ||
PreviousOutage UptimePreviousOutage `json:"previous_outage"` | ||
} | ||
|
||
type UptimeRegion struct { | ||
Status string `json:"status"` | ||
StatusChangedAt string `json:"status_changed_at"` | ||
ThirtyDayUptimePercentage float32 `json:"thirty_day_uptime_percentage"` | ||
} | ||
|
||
// UptimePreviousOutage represents a DigitalOcean Uptime Check's previous outage configuration. | ||
type UptimePreviousOutage struct { | ||
Region string `json:"region"` | ||
StartedAt string `json:"started_at"` | ||
EndedAt string `json:"ended_at"` | ||
DurationSeconds int `json:"duration_seconds"` | ||
} | ||
|
||
// CreateUptimeCheckRequest represents the request to create a new uptime check. | ||
type CreateUptimeCheckRequest struct { | ||
Name string `json:"name"` | ||
Type string `json:"type"` | ||
Target string `json:"target"` | ||
Regions []string `json:"regions"` | ||
Enabled bool `json:"enabled"` | ||
} | ||
|
||
// UpdateUptimeCheckRequest represents the request to update uptime check information. | ||
type UpdateUptimeCheckRequest struct { | ||
Name string `json:"name"` | ||
Type string `json:"type"` | ||
Target string `json:"target"` | ||
Regions []string `json:"regions"` | ||
Enabled bool `json:"enabled"` | ||
} | ||
|
||
// CreateUptimeUptimeAlertRequest represents the request to create a new Uptime Alert. | ||
type CreateUptimeAlertRequest struct { | ||
Name string `json:"name"` | ||
Type string `json:"type"` | ||
Threshold int `json:"threshold"` | ||
Comparison string `json:"comparison"` | ||
Notifications *Notifications `json:"notifications"` | ||
Period string `json:"period"` | ||
} | ||
|
||
// UpdateUptimeAlertRequest represents the request to create a new alert. | ||
type UpdateUptimeAlertRequest struct { | ||
Name string `json:"name"` | ||
Type string `json:"type"` | ||
Threshold int `json:"threshold"` | ||
Comparison string `json:"comparison"` | ||
Notifications *Notifications `json:"notifications"` | ||
Period string `json:"period"` | ||
} | ||
|
||
type uptimeChecksRoot struct { | ||
UptimeChecks []UptimeCheck `json:"checks"` | ||
Links *Links `json:"links"` | ||
Meta *Meta `json:"meta"` | ||
} | ||
|
||
type uptimeCheckStateRoot struct { | ||
UptimeCheckState UptimeCheckState `json:"state"` | ||
} | ||
|
||
type uptimeAlertsRoot struct { | ||
UptimeAlerts []UptimeAlert `json:"alerts"` | ||
Links *Links `json:"links"` | ||
Meta *Meta `json:"meta"` | ||
} | ||
|
||
type uptimeCheckRoot struct { | ||
UptimeCheck *UptimeCheck `json:"check"` | ||
} | ||
|
||
type uptimeAlertRoot struct { | ||
UptimeAlert *UptimeAlert `json:"alert"` | ||
} | ||
|
||
var _ UptimeChecksService = &UptimeChecksServiceOp{} | ||
|
||
// List Checks. | ||
func (p *UptimeChecksServiceOp) List(ctx context.Context, opts *ListOptions) ([]UptimeCheck, *Response, error) { | ||
path, err := addOptions(uptimeChecksBasePath, opts) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
req, err := p.client.NewRequest(ctx, http.MethodGet, path, nil) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
root := new(uptimeChecksRoot) | ||
resp, err := p.client.Do(ctx, req, root) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
if l := root.Links; l != nil { | ||
resp.Links = l | ||
} | ||
if m := root.Meta; m != nil { | ||
resp.Meta = m | ||
} | ||
|
||
return root.UptimeChecks, resp, err | ||
} | ||
|
||
// GetState of uptime check. | ||
func (p *UptimeChecksServiceOp) GetState(ctx context.Context, uptimeCheckID string) (*UptimeCheckState, *Response, error) { | ||
path := path.Join(uptimeChecksBasePath, uptimeCheckID, "/state") | ||
|
||
req, err := p.client.NewRequest(ctx, http.MethodGet, path, nil) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
root := new(uptimeCheckStateRoot) | ||
resp, err := p.client.Do(ctx, req, root) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
return &root.UptimeCheckState, resp, err | ||
} | ||
|
||
// Get retrieves a single uptime check by its ID. | ||
func (p *UptimeChecksServiceOp) Get(ctx context.Context, uptimeCheckID string) (*UptimeCheck, *Response, error) { | ||
path := path.Join(uptimeChecksBasePath, uptimeCheckID) | ||
|
||
req, err := p.client.NewRequest(ctx, http.MethodGet, path, nil) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
root := new(uptimeCheckRoot) | ||
resp, err := p.client.Do(ctx, req, root) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
return root.UptimeCheck, resp, err | ||
} | ||
|
||
// Create a new uptime check. | ||
func (p *UptimeChecksServiceOp) Create(ctx context.Context, cr *CreateUptimeCheckRequest) (*UptimeCheck, *Response, error) { | ||
req, err := p.client.NewRequest(ctx, http.MethodPost, uptimeChecksBasePath, cr) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
root := new(uptimeCheckRoot) | ||
resp, err := p.client.Do(ctx, req, root) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
return root.UptimeCheck, resp, err | ||
} | ||
|
||
// Update an uptime check. | ||
func (p *UptimeChecksServiceOp) Update(ctx context.Context, uptimeCheckID string, ur *UpdateUptimeCheckRequest) (*UptimeCheck, *Response, error) { | ||
path := path.Join(uptimeChecksBasePath, uptimeCheckID) | ||
req, err := p.client.NewRequest(ctx, http.MethodPut, path, ur) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
root := new(uptimeCheckRoot) | ||
resp, err := p.client.Do(ctx, req, root) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
return root.UptimeCheck, resp, err | ||
} | ||
|
||
// Delete an existing uptime check. | ||
func (p *UptimeChecksServiceOp) Delete(ctx context.Context, uptimeCheckID string) (*Response, error) { | ||
path := path.Join(uptimeChecksBasePath, uptimeCheckID) | ||
req, err := p.client.NewRequest(ctx, http.MethodDelete, path, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return p.client.Do(ctx, req, nil) | ||
} | ||
|
||
// alerts | ||
|
||
// ListAlerts lists alerts for a check. | ||
func (p *UptimeChecksServiceOp) ListAlerts(ctx context.Context, uptimeCheckID string, opts *ListOptions) ([]UptimeAlert, *Response, error) { | ||
fullPath := path.Join(uptimeChecksBasePath, uptimeCheckID, "/alerts") | ||
path, err := addOptions(fullPath, opts) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
req, err := p.client.NewRequest(ctx, http.MethodGet, path, nil) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
root := new(uptimeAlertsRoot) | ||
resp, err := p.client.Do(ctx, req, root) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
if l := root.Links; l != nil { | ||
resp.Links = l | ||
} | ||
if m := root.Meta; m != nil { | ||
resp.Meta = m | ||
} | ||
|
||
return root.UptimeAlerts, resp, err | ||
} | ||
|
||
// CreateAlert creates a new check alert. | ||
func (p *UptimeChecksServiceOp) CreateAlert(ctx context.Context, uptimeCheckID string, cr *CreateUptimeAlertRequest) (*UptimeAlert, *Response, error) { | ||
fullPath := path.Join(uptimeChecksBasePath, uptimeCheckID, "/alerts") | ||
req, err := p.client.NewRequest(ctx, http.MethodPost, fullPath, cr) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
root := new(uptimeAlertRoot) | ||
resp, err := p.client.Do(ctx, req, root) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
return root.UptimeAlert, resp, err | ||
} | ||
|
||
// GetAlert retrieves a single uptime check alert by its ID. | ||
func (p *UptimeChecksServiceOp) GetAlert(ctx context.Context, uptimeCheckID string, alertID string) (*UptimeAlert, *Response, error) { | ||
path := fmt.Sprintf("v2/uptime/checks/%s/alerts/%s", uptimeCheckID, alertID) | ||
|
||
req, err := p.client.NewRequest(ctx, http.MethodGet, path, nil) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
root := new(uptimeAlertRoot) | ||
resp, err := p.client.Do(ctx, req, root) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
return root.UptimeAlert, resp, err | ||
} | ||
|
||
// UpdateAlert updates an check's alert. | ||
func (p *UptimeChecksServiceOp) UpdateAlert(ctx context.Context, uptimeCheckID string, alertID string, ur *UpdateUptimeAlertRequest) (*UptimeAlert, *Response, error) { | ||
path := path.Join(uptimeChecksBasePath, uptimeCheckID, "/alerts/", alertID) | ||
req, err := p.client.NewRequest(ctx, http.MethodPut, path, ur) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
root := new(uptimeAlertRoot) | ||
resp, err := p.client.Do(ctx, req, root) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
return root.UptimeAlert, resp, err | ||
} | ||
|
||
// DeleteAlert deletes an existing check's alert. | ||
func (p *UptimeChecksServiceOp) DeleteAlert(ctx context.Context, uptimeCheckID string, alertID string) (*Response, error) { | ||
path := path.Join(uptimeChecksBasePath, uptimeCheckID, "/alerts/", alertID) | ||
req, err := p.client.NewRequest(ctx, http.MethodDelete, path, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return p.client.Do(ctx, req, nil) | ||
} |
Oops, something went wrong.