Skip to content

Commit

Permalink
feat(notification/teams): add endpoint and rule
Browse files Browse the repository at this point in the history
  • Loading branch information
sranka committed Oct 14, 2020
1 parent a171c4e commit c6e96ff
Show file tree
Hide file tree
Showing 7 changed files with 686 additions and 0 deletions.
2 changes: 2 additions & 0 deletions notification/endpoint/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ const (
PagerDutyType = "pagerduty"
HTTPType = "http"
TelegramType = "telegram"
TeamsType = "teams"
)

var typeToEndpoint = map[string]func() influxdb.NotificationEndpoint{
SlackType: func() influxdb.NotificationEndpoint { return &Slack{} },
PagerDutyType: func() influxdb.NotificationEndpoint { return &PagerDuty{} },
HTTPType: func() influxdb.NotificationEndpoint { return &HTTP{} },
TelegramType: func() influxdb.NotificationEndpoint { return &Telegram{} },
TeamsType: func() influxdb.NotificationEndpoint { return &Teams{} },
}

// UnmarshalJSON will convert the bytes to notification endpoint.
Expand Down
113 changes: 113 additions & 0 deletions notification/endpoint/endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,24 @@ func TestValidEndpoint(t *testing.T) {
},
err: nil,
},
{
name: "empty teams url",
src: &endpoint.Teams{
Base: goodBase,
},
err: &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "teams: empty URL",
},
},
{
name: "empty teams SecretURLSuffix",
src: &endpoint.Teams{
Base: goodBase,
URL: "http://localhost",
},
err: nil,
},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
Expand Down Expand Up @@ -305,6 +323,39 @@ func TestJSON(t *testing.T) {
Token: influxdb.SecretField{Key: "token-key-1"},
},
},
{
name: "teams with secretURLSuffix",
src: &endpoint.Teams{
Base: endpoint.Base{
ID: influxTesting.MustIDBase16Ptr(id1),
Name: "name1",
OrgID: influxTesting.MustIDBase16Ptr(id3),
Status: influxdb.Active,
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
URL: "https://outlook.office.com/webhook/",
SecretURLSuffix: influxdb.SecretField{Key: "token-key-1"},
},
},
{
name: "teams without secretURLSuffix",
src: &endpoint.Teams{
Base: endpoint.Base{
ID: influxTesting.MustIDBase16Ptr(id1),
Name: "name1",
OrgID: influxTesting.MustIDBase16Ptr(id3),
Status: influxdb.Active,
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
URL: "https://outlook.office.com/webhook/0acbc9c2-c262-11ea-b3de-0242ac130004",
},
},
}
for _, c := range cases {
b, err := json.Marshal(c.src)
Expand Down Expand Up @@ -478,6 +529,42 @@ func TestBackFill(t *testing.T) {
},
},
},
{
name: "simple Teams",
src: &endpoint.Teams{
Base: endpoint.Base{
ID: influxTesting.MustIDBase16Ptr(id1),
Name: "name1",
OrgID: influxTesting.MustIDBase16Ptr(id3),
Status: influxdb.Active,
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
URL: "https://outlook.office.com/webhook/",
SecretURLSuffix: influxdb.SecretField{
Value: strPtr("token-value"),
},
},
target: &endpoint.Teams{
Base: endpoint.Base{
ID: influxTesting.MustIDBase16Ptr(id1),
Name: "name1",
OrgID: influxTesting.MustIDBase16Ptr(id3),
Status: influxdb.Active,
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
URL: "https://outlook.office.com/webhook/",
SecretURLSuffix: influxdb.SecretField{
Key: id1 + "-token",
Value: strPtr("token-value"),
},
},
},
}
for _, c := range cases {
c.src.BackfillSecretKeys()
Expand Down Expand Up @@ -605,6 +692,32 @@ func TestSecretFields(t *testing.T) {
},
},
},
{
name: "simple Teams",
src: &endpoint.Teams{
Base: endpoint.Base{
ID: influxTesting.MustIDBase16Ptr(id1),
Name: "name1",
OrgID: influxTesting.MustIDBase16Ptr(id3),
Status: influxdb.Active,
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
URL: "https://outlook.office.com/webhook/",
SecretURLSuffix: influxdb.SecretField{
Key: id1 + "-token",
Value: strPtr("token-value"),
},
},
secrets: []influxdb.SecretField{
{
Key: id1 + "-token",
Value: strPtr("token-value"),
},
},
},
}
for _, c := range cases {
secretFields := c.src.SecretFields()
Expand Down
72 changes: 72 additions & 0 deletions notification/endpoint/teams.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package endpoint

import (
"encoding/json"

"github.com/influxdata/influxdb/v2"
)

var _ influxdb.NotificationEndpoint = &Teams{}

const teamsSecretSuffix = "-token"

// Teams is the notification endpoint config of Microdoft teams.
type Teams struct {
Base
// URL is the teams incoming webhook URL, see https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using#setting-up-a-custom-incoming-webhook ,
// for example: https://outlook.office.com/webhook/0acbc9c2-c262-11ea-b3de-0242ac130004
URL string `json:"url"`
// SecretURLSuffix is an optional secret suffix that is added to URL ,
// for example: 0acbc9c2-c262-11ea-b3de-0242ac130004 is the secret part that is added to https://outlook.office.com/webhook/
SecretURLSuffix influxdb.SecretField `json:"secretURLSuffix"`
}

// BackfillSecretKeys fill back the secret field key during the unmarshalling
// if value of that secret field is not nil.
func (s *Teams) BackfillSecretKeys() {
if s.SecretURLSuffix.Key == "" && s.SecretURLSuffix.Value != nil {
s.SecretURLSuffix.Key = s.idStr() + teamsSecretSuffix
}
}

// SecretFields return available secret fields.
func (s Teams) SecretFields() []influxdb.SecretField {
arr := []influxdb.SecretField{}
if s.SecretURLSuffix.Key != "" {
arr = append(arr, s.SecretURLSuffix)
}
return arr
}

// Valid returns error if some configuration is invalid
func (s Teams) Valid() error {
if err := s.Base.valid(); err != nil {
return err
}
if s.URL == "" {
return &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "teams: empty URL",
}
}
return nil
}

type teamsAlias Teams

// MarshalJSON implement json.Marshaler interface.
func (s Teams) MarshalJSON() ([]byte, error) {
return json.Marshal(
struct {
teamsAlias
Type string `json:"type"`
}{
teamsAlias: teamsAlias(s),
Type: s.Type(),
})
}

// Type returns the type.
func (s Teams) Type() string {
return TeamsType
}
1 change: 1 addition & 0 deletions notification/rule/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ var typeToRule = map[string](func() influxdb.NotificationRule){
"pagerduty": func() influxdb.NotificationRule { return &PagerDuty{} },
"http": func() influxdb.NotificationRule { return &HTTP{} },
"telegram": func() influxdb.NotificationRule { return &Telegram{} },
"teams": func() influxdb.NotificationRule { return &Teams{} },
}

// UnmarshalJSON will convert
Expand Down
36 changes: 36 additions & 0 deletions notification/rule/rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,42 @@ func TestJSON(t *testing.T) {
MessageTemplate: "blah",
},
},
{
name: "simple teams",
src: &rule.Teams{
Base: rule.Base{
ID: influxTesting.MustIDBase16(id1),
OwnerID: influxTesting.MustIDBase16(id2),
Name: "name1",
OrgID: influxTesting.MustIDBase16(id3),
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: mustDuration("1h"),
TagRules: []notification.TagRule{
{
Tag: influxdb.Tag{
Key: "k1",
Value: "v1",
},
Operator: influxdb.NotEqual,
},
{
Tag: influxdb.Tag{
Key: "k2",
Value: "v2",
},
Operator: influxdb.RegexEqual,
},
},
CRUDLog: influxdb.CRUDLog{
CreatedAt: timeGen1.Now(),
UpdatedAt: timeGen2.Now(),
},
},
Title: "my title",
MessageTemplate: "msg1",
},
},
}
for _, c := range cases {
b, err := json.Marshal(c.src)
Expand Down
Loading

0 comments on commit c6e96ff

Please sign in to comment.