alert.go raw

   1  package rest
   2  
   3  import (
   4  	"errors"
   5  	"fmt"
   6  	"net/http"
   7  
   8  	"gopkg.in/ns1/ns1-go.v2/rest/model/alerting"
   9  )
  10  
  11  // AlertsService handles 'alerting/v1/alerts' endpoint.
  12  type AlertsService service
  13  
  14  // The base for the alerting api relative to /v1
  15  // client.NewRequest will call ResolveReference and remove /v1/../
  16  const alertingRelativeBase = "../alerting/v1"
  17  
  18  type alertListResponse struct {
  19  	Limit        *int64            `json:"limit,omitempty"`
  20  	Next         *string           `json:"next,omitempty"`
  21  	Results      []*alerting.Alert `json:"results"`
  22  	TotalResults *int64            `json:"total_results,omitempty"`
  23  }
  24  
  25  // List returns all configured alerts.
  26  //
  27  // NS1 API docs: https://ns1.com/api/#alerts-get
  28  func (s *AlertsService) List() ([]*alerting.Alert, *http.Response, error) {
  29  	path := fmt.Sprintf("%s/%s", alertingRelativeBase, "alerts")
  30  	req, err := s.client.NewRequest("GET", path, nil)
  31  	if err != nil {
  32  		return nil, nil, err
  33  	}
  34  
  35  	alertListResp := alertListResponse{}
  36  	var resp *http.Response
  37  	if s.client.FollowPagination {
  38  		resp, err = s.client.DoWithPagination(req, &alertListResp, s.nextAlerts)
  39  	} else {
  40  		resp, err = s.client.Do(req, &alertListResp)
  41  	}
  42  	if err != nil {
  43  		return nil, resp, err
  44  	}
  45  	alerts := alertListResp.Results
  46  	return alerts, resp, nil
  47  }
  48  
  49  // nextAlerts is a pagination helper than gets and appends another list of alerts
  50  // to the passed alerts.
  51  func (s *AlertsService) nextAlerts(v *interface{}, uri string) (*http.Response, error) {
  52  	nextAlerts := &alertListResponse{}
  53  	resp, err := s.client.getURI(&nextAlerts, uri)
  54  	if err != nil {
  55  		return resp, err
  56  	}
  57  	alertListResp, ok := (*v).(*alertListResponse)
  58  	if !ok {
  59  		return nil, fmt.Errorf(
  60  			"incorrect value for v, expected value of type *[]*alerting.Alert, got: %T", v,
  61  		)
  62  	}
  63  	alertListResp.Results = append(alertListResp.Results, nextAlerts.Results...)
  64  	return resp, nil
  65  }
  66  
  67  // Get returns the details of a specific alert.
  68  //
  69  // NS1 API docs: https://ns1.com/api/#alert-alertid-get
  70  func (s *AlertsService) Get(alertID string) (*alerting.Alert, *http.Response, error) {
  71  	path := fmt.Sprintf("%s/%s/%s", alertingRelativeBase, "alerts", alertID)
  72  	req, err := s.client.NewRequest("GET", path, nil)
  73  	if err != nil {
  74  		return nil, nil, err
  75  	}
  76  
  77  	var alert alerting.Alert
  78  	resp, err := s.client.Do(req, &alert)
  79  	if err != nil {
  80  		switch err.(type) {
  81  		case *Error:
  82  			if resourceMissingMatch(err.(*Error).Message) {
  83  				return nil, resp, ErrAlertMissing
  84  			}
  85  		}
  86  		return nil, resp, err
  87  	}
  88  
  89  	return &alert, resp, nil
  90  }
  91  
  92  // Create takes a *alerting.Alert and creates a new alert.
  93  //
  94  // NS1 API docs: https://ns1.com/api/#alert-post
  95  func (s *AlertsService) Create(alert *alerting.Alert) (*http.Response, error) {
  96  	path := fmt.Sprintf("%s/%s", alertingRelativeBase, "alerts")
  97  	req, err := s.client.NewRequest("POST", path, &alert)
  98  	if err != nil {
  99  		return nil, err
 100  	}
 101  
 102  	// Update the alerts fields with data from api(ensure consistent)
 103  	resp, err := s.client.Do(req, &alert)
 104  	if err != nil {
 105  		switch err.(type) {
 106  		case *Error:
 107  			if err.(*Error).Resp.StatusCode == http.StatusConflict {
 108  				return resp, ErrAlertExists
 109  			}
 110  		}
 111  		return resp, err
 112  	}
 113  
 114  	return resp, nil
 115  }
 116  
 117  // Update updates the fields specified in the passed alert object.
 118  //
 119  // NS1 API docs: https://ns1.com/api/#alert-alertid-patch
 120  func (s *AlertsService) Update(alert *alerting.Alert) (*http.Response, error) {
 121  	alertID := ""
 122  	if alert != nil && alert.ID != nil {
 123  		alertID = *alert.ID
 124  	}
 125  	path := fmt.Sprintf("%s/%s/%s", alertingRelativeBase, "alerts", alertID)
 126  
 127  	req, err := s.client.NewRequest("PATCH", path, &alert)
 128  	if err != nil {
 129  		return nil, err
 130  	}
 131  
 132  	// Update the alerts fields with data from api(ensure consistent)
 133  	resp, err := s.client.Do(req, &alert)
 134  	if err != nil {
 135  		return resp, err
 136  	}
 137  
 138  	return resp, nil
 139  }
 140  
 141  // Replace replaces the values in an alert with the values in the passed object.
 142  //
 143  // NS1 API docs: https://ns1.com/api/#alert-alertid-put
 144  func (s *AlertsService) Replace(alert *alerting.Alert) (*http.Response, error) {
 145  	alertID := ""
 146  	if alert != nil && alert.ID != nil {
 147  		alertID = *alert.ID
 148  	}
 149  	path := fmt.Sprintf("%s/%s/%s", alertingRelativeBase, "alerts", alertID)
 150  
 151  	req, err := s.client.NewRequest("PUT", path, &alert)
 152  	if err != nil {
 153  		return nil, err
 154  	}
 155  
 156  	// Update the alerts fields with data from api (ensure consistent)
 157  	resp, err := s.client.Do(req, &alert)
 158  	if err != nil {
 159  		return resp, err
 160  	}
 161  
 162  	return resp, nil
 163  }
 164  
 165  // Delete deletes an existing alert.
 166  //
 167  // NS1 API docs: https://ns1.com/api/#alert-alertid-delete
 168  func (s *AlertsService) Delete(alertID string) (*http.Response, error) {
 169  	path := fmt.Sprintf("%s/%s/%s", alertingRelativeBase, "alerts", alertID)
 170  	req, err := s.client.NewRequest("DELETE", path, nil)
 171  	if err != nil {
 172  		return nil, err
 173  	}
 174  
 175  	resp, err := s.client.Do(req, nil)
 176  	if err != nil {
 177  		return resp, err
 178  	}
 179  
 180  	return resp, nil
 181  }
 182  
 183  // Test an existing alert, triggers notifications for the given alert id.
 184  //
 185  // NS1 API docs: https://ns1.com/api/#alert-alertid-test
 186  func (s *AlertsService) Test(alertID string) (*http.Response, error) {
 187  	path := fmt.Sprintf("%s/%s/%s/test", alertingRelativeBase, "alerts", alertID)
 188  	req, err := s.client.NewRequest("POST", path, nil)
 189  	if err != nil {
 190  		return nil, err
 191  	}
 192  
 193  	resp, err := s.client.Do(req, nil)
 194  	if err != nil {
 195  		return resp, err
 196  	}
 197  
 198  	return resp, nil
 199  }
 200  
 201  var (
 202  	// ErrAlertExists bundles POST create error.
 203  	ErrAlertExists = errors.New("alert already exists")
 204  
 205  	// ErrAlertMissing bundles GET/PUT/PATCH/DELETE error.
 206  	ErrAlertMissing = errors.New("alert does not exist")
 207  )
 208