Skip to content

Commit

Permalink
Merge pull request #23 from iLert/feature/notification-settings-2_0
Browse files Browse the repository at this point in the history
Feature/notification settings 2.0
  • Loading branch information
STLVRTX authored Mar 9, 2023
2 parents f850101 + c642e34 commit 1697a02
Show file tree
Hide file tree
Showing 64 changed files with 2,135 additions and 525 deletions.
22 changes: 17 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## 08.03.2023, Version 3.0.0 - API user preference migration: see [migration changes](https://docs.ilert.com/rest-api/api-version-history/api-user-preference-migration-2023#migrating-ilert-go-and-or-terraform) for a detailed migration guide

- removed notification settings fields from user resource
- add user contacts
- email
- phone number
- add user notification preferences
- alert (alert creation)
- duty (on-call)
- subscription (subscriber to incident, service, status page)
- update (alert update changes)

## 17.01.2023, Version 2.6.0

- add metrics
Expand Down Expand Up @@ -100,7 +112,7 @@

- fix internal version

## 30.06.2022, Version 2.0.0
## 30.06.2022, Version 2.0.0 - API Version upgrade

- add automation rules
- add incident templates
Expand Down Expand Up @@ -182,19 +194,19 @@
- add url option for create event
- add autotask types

## 9.11.2020, Version 1.1.3
## 09.11.2020, Version 1.1.3

- add integration url to alert source definition

## 8.11.2020, Version 1.1.2
## 08.11.2020, Version 1.1.2

- add jira alert source type

## 3.11.2020, Version 1.1.1
## 03.11.2020, Version 1.1.1

- add all connector types list

## 2.11.2020, Version 1.1.0
## 02.11.2020, Version 1.1.0

- add connections
- add connectors
Expand Down
4 changes: 2 additions & 2 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2021 iLert GmbH
Copyright 2023 iLert GmbH

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -198,4 +198,4 @@
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
limitations under the License.
39 changes: 22 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
# ilert-go

**The official iLert Go api bindings.**
**The official ilert Go api bindings.**

## Legacy API

> If you want to use the old client with v1 resources, please install it with the following command: `go get github.com/iLert/ilert-go`

## Create an incident (manually)
## Create an alert (manually)

```go
package main

import (
"log"
"github.com/iLert/ilert-go/v2"
"github.com/iLert/ilert-go/v3"
)

func main() {

// We strongly recommend to enable a retry logic if an error occurs
client := ilert.NewClient(ilert.WithRetry(10, 5*time.Second, 20*time.Second))
var apiToken = "your API token"
client := ilert.NewClient(ilert.WithRetry(10, 5*time.Second, 20*time.Second), ilert.WithAPIToken(apiToken))

var apiKey = "alert source API Key"
event := &ilert.Event{
Expand Down Expand Up @@ -48,24 +44,22 @@ package main

import (
"log"
"github.com/iLert/ilert-go/v2"
"github.com/iLert/ilert-go/v3"
)

func main() {

client := ilert.NewClient()

var apiKey = "heartbeat API Key"
var apiToken = "your API token"
client := ilert.NewClient(ilert.WithAPIToken(apiToken))

result, err := client.PingHeartbeat(&ilert.PingHeartbeatInput{
APIKey: ilert.String(apiKey),
Method: ilert.String(ilert.HeartbeatMethods.HEAD),
})

if err != nil {
log.Println(result)
log.Fatalln("ERROR:", err)
}

log.Println("Heartbeat is ok!")
}
```
Expand All @@ -77,15 +71,26 @@ package main

import (
"log"
"github.com/iLert/ilert-go/v2"
"github.com/iLert/ilert-go/v3"
)

func main() {
client := ilert.NewClient(ilert.WithProxy("http://proxyserver:8888"))
var apiToken = "your API token"
client := ilert.NewClient(ilert.WithProxy("http://proxyserver:8888"), ilert.WithAPIToken(apiToken))
...
}
```

## Versions overview

If you want to use older legacy versions of ilert-go, you can access previous major versions using one of the commands below.

| Version | Description | Command |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- |
| > 3.0.0 | API user preference migration - [changes](https://docs.ilert.com/rest-api/api-version-history/api-user-preference-migration-2023) | `go get github.com/iLert/ilert-go/v3` |
| 2.0.0 - 2.6.0 | API versionless - [changes](https://docs.ilert.com/rest-api/api-version-history#renaming-incidents-to-alerts) | `go get github.com/iLert/ilert-go/v2` |
| 1.0.0 - 1.6.5 | API v1 - basic legacy resources | `go get github.com/iLert/ilert-go` |

## Getting help

We are happy to respond to [GitHub issues][issues] as well.
Expand Down
39 changes: 9 additions & 30 deletions alert.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,25 +154,6 @@ var AlertInclude = struct {
NextEscalationUser: "nextEscalationUser",
}

// // AlertAction definition
// type AlertAction struct {
// Name string `json:"name"`
// WebhookID string `json:"webhookId"`
// ExtensionID string `json:"extensionId"`
// IconURL string `json:"iconUrl"`
// History []AlertActionResult `json:"history"`
// }

// // AlertActionResult definition
// type AlertActionResult struct {
// ID string `json:"id"`
// AlertID int64 `json:"alertId"`
// WebhookID string `json:"webhookId"`
// ExtensionID string `json:"extensionId"`
// Actor User `json:"actor"`
// Success bool `json:"success"`
// }

// GetAlertInput represents the input of a GetAlert operation.
type GetAlertInput struct {
_ struct{}
Expand All @@ -194,7 +175,7 @@ func (c *Client) GetAlert(input *GetAlertInput) (*GetAlertOutput, error) {
return nil, errors.New("input is required")
}
if input.AlertID == nil {
return nil, errors.New("Alert id is required")
return nil, errors.New("alert id is required")
}

q := url.Values{}
Expand Down Expand Up @@ -256,7 +237,7 @@ type GetAlertsOutput struct {
Alerts []*Alert
}

// GetAlerts lists alerts. https://api.ilert.com/api-docs/#tag/Alerts/paths/~1alerts/get
// GetAlerts lists existing alerts. https://api.ilert.com/api-docs/#tag/Alerts/paths/~1alerts/get
func (c *Client) GetAlerts(input *GetAlertsInput) (*GetAlertsOutput, error) {
if input == nil {
input = &GetAlertsInput{}
Expand Down Expand Up @@ -320,10 +301,10 @@ type GetAlertsCountInput struct {
// state of the alert
States []*string

// alert source IDs of the alert's alert source
// alert source ids of the alert's alert source
AlertSources []*int64

// user IDs of the user that the alert is assigned to
// user ids of the user that the alert is assigned to
AssignedToUserIDs []*int64

// usernames of the user that the alert is assigned to
Expand Down Expand Up @@ -408,7 +389,7 @@ func (c *Client) GetAlertResponder(input *GetAlertResponderInput) (*GetAlertResp
return nil, errors.New("input is required")
}
if input.AlertID == nil {
return nil, errors.New("Alert id is required")
return nil, errors.New("alert id is required")
}

q := url.Values{}
Expand Down Expand Up @@ -459,7 +440,7 @@ func (c *Client) AssignAlert(input *AssignAlertInput) (*AssignAlertOutput, error
return nil, errors.New("input is required")
}
if input.AlertID == nil {
return nil, errors.New("Alert id is required")
return nil, errors.New("alert id is required")
}

if input.UserID == nil && input.Username == nil && input.EscalationPolicyID == nil && input.ScheduleID == nil {
Expand Down Expand Up @@ -515,7 +496,7 @@ func (c *Client) AcceptAlert(input *AcceptAlertInput) (*AcceptAlertOutput, error
return nil, errors.New("input is required")
}
if input.AlertID == nil {
return nil, errors.New("Alert id is required")
return nil, errors.New("alert id is required")
}

resp, err := c.httpClient.R().Put(fmt.Sprintf("%s/%d/accept", apiRoutes.alerts, *input.AlertID))
Expand Down Expand Up @@ -553,7 +534,7 @@ func (c *Client) ResolveAlert(input *ResolveAlertInput) (*ResolveAlertOutput, er
return nil, errors.New("input is required")
}
if input.AlertID == nil {
return nil, errors.New("Alert id is required")
return nil, errors.New("alert id is required")
}

resp, err := c.httpClient.R().Put(fmt.Sprintf("%s/%d/resolve", apiRoutes.alerts, *input.AlertID))
Expand Down Expand Up @@ -592,7 +573,7 @@ func (c *Client) GetAlertLogEntries(input *GetAlertLogEntriesInput) (*GetAlertLo
return nil, errors.New("input is required")
}
if input.AlertID == nil {
return nil, errors.New("Alert id is required")
return nil, errors.New("alert id is required")
}

q := url.Values{}
Expand Down Expand Up @@ -621,8 +602,6 @@ func (c *Client) GetAlertLogEntries(input *GetAlertLogEntriesInput) (*GetAlertLo
return &GetAlertLogEntriesOutput{LogEntries: alertLogEntries}, nil
}

// TODO https://api.ilert.com/api-docs/#tag/Alerts/paths/~1alerts~1{id}~1notifications/get

// TODO https://api.ilert.com/api-docs/#tag/Alert-Actions/paths/~1alerts~1{id}~1actions/get
// // GetAlertActionsInput represents the input of a GetAlertsAction operation.
// type GetAlertActionsInput struct {
Expand Down
4 changes: 2 additions & 2 deletions alertaction.go → alert_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ type CreateAlertActionOutput struct {
AlertAction *AlertActionOutput
}

// CreateAlertAction creates a new alert action https://api.ilert.com/api-docs/#tag/Alert-Actions/paths/~1alert-actions/post
// CreateAlertAction creates a new alert action. https://api.ilert.com/api-docs/#tag/Alert-Actions/paths/~1alert-actions/post
func (c *Client) CreateAlertAction(input *CreateAlertActionInput) (*CreateAlertActionOutput, error) {
if input == nil {
return nil, errors.New("input is required")
Expand Down Expand Up @@ -452,7 +452,7 @@ type GetAlertActionsOutput struct {
AlertActions []*AlertActionOutput
}

// GetAlertActions lists alert actions. https://api.ilert.com/api-docs/#tag/Alert-Actions/paths/~1alert-actions/get
// GetAlertActions lists existing alert actions. https://api.ilert.com/api-docs/#tag/Alert-Actions/paths/~1alert-actions/get
func (c *Client) GetAlertActions(input *GetAlertActionsInput) (*GetAlertActionsOutput, error) {
q := url.Values{}
if input.StartIndex != nil {
Expand Down
10 changes: 5 additions & 5 deletions alertsource.go → alert_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ func (c *Client) GetAlertSource(input *GetAlertSourceInput) (*GetAlertSourceOutp
return nil, errors.New("input is required")
}
if input.AlertSourceID == nil {
return nil, errors.New("AlertSource id is required")
return nil, errors.New("alert source id is required")
}

resp, err := c.httpClient.R().Get(fmt.Sprintf("%s/%d", apiRoutes.alertSources, *input.AlertSourceID))
Expand Down Expand Up @@ -489,7 +489,7 @@ type GetAlertSourcesOutput struct {
AlertSources []*AlertSource
}

// GetAlertSources lists alert sources. https://api.ilert.com/api-docs/#tag/Alert-Sources/paths/~1alert-sources/get
// GetAlertSources lists existing alert sources. https://api.ilert.com/api-docs/#tag/Alert-Sources/paths/~1alert-sources/get
func (c *Client) GetAlertSources(input *GetAlertSourcesInput) (*GetAlertSourcesOutput, error) {
q := url.Values{}
if input.StartIndex != nil {
Expand Down Expand Up @@ -528,7 +528,7 @@ type SearchAlertSourceOutput struct {
AlertSource *AlertSource
}

// SearchAlertSource gets the alertSource with specified name.
// SearchAlertSource gets the alert source with specified name.
func (c *Client) SearchAlertSource(input *SearchAlertSourceInput) (*SearchAlertSourceOutput, error) {
if input == nil {
return nil, errors.New("input is required")
Expand Down Expand Up @@ -573,7 +573,7 @@ func (c *Client) UpdateAlertSource(input *UpdateAlertSourceInput) (*UpdateAlertS
return nil, errors.New("input is required")
}
if input.AlertSource == nil {
return nil, errors.New("AlertSource input is required")
return nil, errors.New("alert source input is required")
}
if input.AlertSourceID == nil {
return nil, errors.New("alert source id is required")
Expand Down Expand Up @@ -634,7 +634,7 @@ func (c *Client) DeleteAlertSource(input *DeleteAlertSourceInput) (*DeleteAlertS
return nil, errors.New("input is required")
}
if input.AlertSourceID == nil {
return nil, errors.New("AlertSource id is required")
return nil, errors.New("alert source id is required")
}

resp, err := c.httpClient.R().Delete(fmt.Sprintf("%s/%d", apiRoutes.alertSources, *input.AlertSourceID))
Expand Down
File renamed without changes.
26 changes: 23 additions & 3 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,18 @@ func (aerr *NotFoundAPIError) Error() string {
return fmt.Sprintf("Not found: api respond with status code: %d, error code: %s, message: %s", aerr.Status, aerr.Code, aerr.Message)
}

// BadRequestAPIError describes not-found API response error e.g. resource deleted or never exists
type BadRequestAPIError struct {
error
Status int `json:"status"`
Message string `json:"message"`
Code string `json:"code"`
}

func (aerr *BadRequestAPIError) Error() string {
return fmt.Sprintf("Bad request: api respond with status code: %d, error code: %s, message: %s", aerr.Status, aerr.Code, aerr.Message)
}

// GenericCountResponse describes generic resources count response
type GenericCountResponse struct {
Count int `json:"count"`
Expand All @@ -75,7 +87,7 @@ func NewClient(options ...ClientOptions) *Client {
}

c.httpClient = resty.New()
c.httpClient.SetHostURL(apiEndpoint)
c.httpClient.SetBaseURL(apiEndpoint)
c.httpClient.SetTimeout(apiTimeoutMs * time.Millisecond)
c.httpClient.SetHeader("Accept", "application/json")
c.httpClient.SetHeader("Content-Type", "application/json")
Expand All @@ -88,7 +100,7 @@ func NewClient(options ...ClientOptions) *Client {

endpoint := getEnv("ILERT_ENDPOINT")
if endpoint != nil {
c.httpClient.SetHostURL(*endpoint)
c.httpClient.SetBaseURL(*endpoint)
}

apiToken := getEnv("ILERT_API_TOKEN")
Expand Down Expand Up @@ -130,7 +142,7 @@ func WithAPIToken(apiToken string) ClientOptions {
func WithAPIEndpoint(endpoint string) ClientOptions {
return func(c *Client) {
c.apiEndpoint = endpoint
c.httpClient.SetHostURL(endpoint)
c.httpClient.SetBaseURL(endpoint)
}
}

Expand Down Expand Up @@ -187,6 +199,14 @@ func getGenericAPIError(response *resty.Response, expectedStatusCode ...int) err
Message: out.Message,
}
}

if out.Status == http.StatusBadRequest {
return &BadRequestAPIError{
Status: out.Status,
Code: out.Code,
Message: out.Message,
}
}
if retryCondition(response, out) {
return &RetryableAPIError{
Status: out.Status,
Expand Down
Loading

0 comments on commit 1697a02

Please sign in to comment.