fix(notification/rule): remove authID requirement

pull/14679/head
Kelvin Wang 2019-08-15 19:24:22 -04:00
parent f4fb6a1753
commit f3dcdee504
9 changed files with 561 additions and 674 deletions

View File

@ -157,7 +157,7 @@ func TestNotificationRuleStore_FindNotificationRules(t *testing.T) {
OrgID: 10,
},
},
&rule.SMTP{
&rule.PagerDuty{
Base: rule.Base{
ID: 3,
OrgID: 11,
@ -189,7 +189,7 @@ func TestNotificationRuleStore_FindNotificationRules(t *testing.T) {
OrgID: 10,
},
},
&rule.SMTP{
&rule.PagerDuty{
Base: rule.Base{
ID: 3,
OrgID: 11,
@ -216,7 +216,7 @@ func TestNotificationRuleStore_FindNotificationRules(t *testing.T) {
OrgID: 10,
},
},
&rule.SMTP{
&rule.PagerDuty{
Base: rule.Base{
ID: 3,
OrgID: 11,

View File

@ -40,15 +40,15 @@ func Test_newNotificationRuleResponses(t *testing.T) {
Channel: "ch1",
MessageTemplate: "message 1{var1}",
Base: rule.Base{
ID: influxdb.ID(1),
OrgID: influxdb.ID(2),
AuthorizationID: influxdb.ID(3),
EndpointID: influxTesting.IDPtr(influxdb.ID(4)),
Name: "name1",
Description: "desc1",
Status: influxdb.Active,
Every: influxdb.Duration{Duration: time.Minute * 5},
Offset: influxdb.Duration{Duration: time.Second * 15},
ID: influxdb.ID(1),
OrgID: influxdb.ID(2),
OwnerID: influxdb.ID(3),
EndpointID: influxTesting.IDPtr(influxdb.ID(4)),
Name: "name1",
Description: "desc1",
Status: influxdb.Active,
Every: influxdb.Duration{Duration: time.Minute * 5},
Offset: influxdb.Duration{Duration: time.Second * 15},
TagRules: []notification.TagRule{
{
Tag: notification.Tag{Key: "k1", Value: "v1"},
@ -73,18 +73,16 @@ func Test_newNotificationRuleResponses(t *testing.T) {
},
},
},
&rule.SMTP{
To: "example@domain1.com, example@domain2.com",
SubjectTemp: "subject 2{var2}",
BodyTemp: "body 2{var2}",
&rule.PagerDuty{
MessageTemp: "body 2{var2}",
Base: rule.Base{
ID: influxdb.ID(11),
OrgID: influxdb.ID(2),
AuthorizationID: influxdb.ID(33),
EndpointID: influxTesting.IDPtr(influxdb.ID(44)),
Name: "name2",
Description: "desc2",
Status: influxdb.Inactive,
ID: influxdb.ID(11),
OrgID: influxdb.ID(2),
OwnerID: influxdb.ID(33),
EndpointID: influxTesting.IDPtr(influxdb.ID(44)),
Name: "name2",
Description: "desc2",
Status: influxdb.Inactive,
},
},
},
@ -95,7 +93,7 @@ func Test_newNotificationRuleResponses(t *testing.T) {
},
"notificationRules": [
{
"authorizationID": "0000000000000003",
"ownerID": "0000000000000003",
"channel": "ch1",
"createdAt": "0001-01-01T00:00:00Z",
"description": "desc1",
@ -151,8 +149,8 @@ func Test_newNotificationRuleResponses(t *testing.T) {
}
},
{
"authorizationID": "0000000000000021",
"bodyTemplate": "body 2{var2}",
"ownerID": "0000000000000021",
"messageTemplate": "body 2{var2}",
"createdAt": "0001-01-01T00:00:00Z",
"description": "desc2",
"endpointID": "000000000000002c",
@ -163,9 +161,7 @@ func Test_newNotificationRuleResponses(t *testing.T) {
"orgID": "0000000000000002",
"runbookLink": "",
"status": "inactive",
"subjectTemplate": "subject 2{var2}",
"to": "example@domain1.com, example@domain2.com",
"type": "smtp",
"type": "pagerduty",
"updatedAt": "0001-01-01T00:00:00Z",
"labels": [],
"links": {
@ -209,15 +205,15 @@ func Test_newNotificationRuleResponse(t *testing.T) {
Channel: "ch1",
MessageTemplate: "message 1{var1}",
Base: rule.Base{
ID: influxdb.ID(1),
OrgID: influxdb.ID(2),
AuthorizationID: influxdb.ID(3),
EndpointID: influxTesting.IDPtr(influxdb.ID(4)),
Name: "name1",
Description: "desc1",
Status: influxdb.Active,
Every: influxdb.Duration{Duration: time.Minute * 5},
Offset: influxdb.Duration{Duration: time.Second * 15},
ID: influxdb.ID(1),
OrgID: influxdb.ID(2),
OwnerID: influxdb.ID(3),
EndpointID: influxTesting.IDPtr(influxdb.ID(4)),
Name: "name1",
Description: "desc1",
Status: influxdb.Active,
Every: influxdb.Duration{Duration: time.Minute * 5},
Offset: influxdb.Duration{Duration: time.Second * 15},
TagRules: []notification.TagRule{
{
Tag: notification.Tag{Key: "k1", Value: "v1"},
@ -248,7 +244,7 @@ func Test_newNotificationRuleResponse(t *testing.T) {
"messageTemplate": "message 1{var1}",
"id": "0000000000000001",
"orgID": "0000000000000002",
"authorizationID": "0000000000000003",
"ownerID": "0000000000000003",
"endpointID": "0000000000000004",
"name": "name1",
"description": "desc1",

View File

@ -9057,8 +9057,8 @@ components:
orgID:
description: the ID of the organization that owns this notification rule.
type: string
authorizationID:
description: The ID of the authorization used to create this notification rule.
ownerID:
description: The ID of creator used to create this notification rule.
type: string
readOnly: true
createdAt:

View File

@ -75,6 +75,7 @@ func (s *Service) createNotificationRule(ctx context.Context, tx Tx, nr influxdb
id := s.IDGenerator.ID()
nr.SetID(id)
now := s.TimeGenerator.Now()
nr.SetOwnerID(userID)
nr.SetCreatedAt(now)
nr.SetUpdatedAt(now)
if err := s.putNotificationRule(ctx, tx, nr); err != nil {
@ -110,6 +111,7 @@ func (s *Service) updateNotificationRule(ctx context.Context, tx Tx, id influxdb
// ID and OrganizationID can not be updated
nr.SetID(current.GetID())
nr.SetOrgID(current.GetOrgID())
nr.SetOwnerID(current.GetOwnerID())
nr.SetCreatedAt(current.GetCRUDLog().CreatedAt)
nr.SetUpdatedAt(s.TimeGenerator.Now())
err = s.putNotificationRule(ctx, tx, nr)

View File

@ -36,6 +36,8 @@ type NotificationRule interface {
json.Marshaler
Updator
Getter
SetOwnerID(id ID)
GetOwnerID() ID
GetLimit() *Limit
}

View File

@ -9,9 +9,8 @@ import (
"github.com/influxdata/influxdb/notification"
)
var typToRule = map[string](func() influxdb.NotificationRule){
var typeToRule = map[string](func() influxdb.NotificationRule){
"slack": func() influxdb.NotificationRule { return &Slack{} },
"smtp": func() influxdb.NotificationRule { return &SMTP{} },
"pagerduty": func() influxdb.NotificationRule { return &PagerDuty{} },
}
@ -27,7 +26,7 @@ func UnmarshalJSON(b []byte) (influxdb.NotificationRule, error) {
Msg: "unable to detect the notification type from json",
}
}
convertedFunc, ok := typToRule[raw.Typ]
convertedFunc, ok := typeToRule[raw.Typ]
if !ok {
return nil, &influxdb.Error{
Msg: fmt.Sprintf("invalid notification type %s", raw.Typ),
@ -40,13 +39,13 @@ func UnmarshalJSON(b []byte) (influxdb.NotificationRule, error) {
// Base is the embed struct of every notification rule.
type Base struct {
ID influxdb.ID `json:"id,omitempty"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
EndpointID *influxdb.ID `json:"endpointID,omitempty"`
OrgID influxdb.ID `json:"orgID,omitempty"`
AuthorizationID influxdb.ID `json:"authorizationID,omitempty"`
Status influxdb.Status `json:"status"`
ID influxdb.ID `json:"id,omitempty"`
Name string `json:"name"`
Description string `json:"description,omitempty"`
EndpointID *influxdb.ID `json:"endpointID,omitempty"`
OrgID influxdb.ID `json:"orgID,omitempty"`
OwnerID influxdb.ID `json:"ownerID,omitempty"`
Status influxdb.Status `json:"status"`
// SleepUntil is an optional sleeptime to start a task.
SleepUntil *time.Time `json:"sleepUntil,omitempty"`
Cron string `json:"cron,omitempty"`
@ -74,10 +73,10 @@ func (b Base) valid() error {
Msg: "Notification Rule Name can't be empty",
}
}
if !b.AuthorizationID.Valid() {
if !b.OwnerID.Valid() {
return &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "Notification Rule AuthorizationID is invalid",
Msg: "Notification Rule OwnerID is invalid",
}
}
if !b.OrgID.Valid() {
@ -125,6 +124,11 @@ func (b Base) GetOrgID() influxdb.ID {
return b.OrgID
}
// GetOwnerID returns the owner id.
func (b Base) GetOwnerID() influxdb.ID {
return b.OwnerID
}
// GetCRUDLog implements influxdb.Getter interface.
func (b Base) GetCRUDLog() influxdb.CRUDLog {
return b.CRUDLog
@ -160,6 +164,11 @@ func (b *Base) SetOrgID(id influxdb.ID) {
b.OrgID = id
}
// SetOwnerID will set the owner id.
func (b *Base) SetOwnerID(id influxdb.ID) {
b.OwnerID = id
}
// SetName implements influxdb.Updator interface.
func (b *Base) SetName(name string) {
b.Name = name

View File

@ -22,11 +22,11 @@ const (
)
var goodBase = rule.Base{
ID: influxTesting.MustIDBase16(id1),
Name: "name1",
AuthorizationID: influxTesting.MustIDBase16(id2),
OrgID: influxTesting.MustIDBase16(id3),
Status: influxdb.Inactive,
ID: influxTesting.MustIDBase16(id1),
Name: "name1",
OwnerID: influxTesting.MustIDBase16(id2),
OrgID: influxTesting.MustIDBase16(id3),
Status: influxdb.Inactive,
}
func TestValidRule(t *testing.T) {
@ -45,7 +45,7 @@ func TestValidRule(t *testing.T) {
},
{
name: "empty name",
src: &rule.SMTP{
src: &rule.PagerDuty{
Base: rule.Base{
ID: influxTesting.MustIDBase16(id1),
},
@ -57,7 +57,7 @@ func TestValidRule(t *testing.T) {
},
{
name: "invalid auth id",
src: &rule.SMTP{
src: &rule.PagerDuty{
Base: rule.Base{
ID: influxTesting.MustIDBase16(id1),
Name: "name1",
@ -65,16 +65,16 @@ func TestValidRule(t *testing.T) {
},
err: &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "Notification Rule AuthorizationID is invalid",
Msg: "Notification Rule OwnerID is invalid",
},
},
{
name: "invalid org id",
src: &rule.PagerDuty{
Base: rule.Base{
ID: influxTesting.MustIDBase16(id1),
Name: "name1",
AuthorizationID: influxTesting.MustIDBase16(id2),
ID: influxTesting.MustIDBase16(id1),
Name: "name1",
OwnerID: influxTesting.MustIDBase16(id2),
},
},
err: &influxdb.Error{
@ -86,11 +86,11 @@ func TestValidRule(t *testing.T) {
name: "invalid org id",
src: &rule.Slack{
Base: rule.Base{
ID: influxTesting.MustIDBase16(id1),
Name: "name1",
AuthorizationID: influxTesting.MustIDBase16(id2),
OrgID: influxTesting.MustIDBase16(id3),
EndpointID: influxTesting.IDPtr(influxdb.InvalidID()),
ID: influxTesting.MustIDBase16(id1),
Name: "name1",
OwnerID: influxTesting.MustIDBase16(id2),
OrgID: influxTesting.MustIDBase16(id3),
EndpointID: influxTesting.IDPtr(influxdb.InvalidID()),
},
},
err: &influxdb.Error{
@ -102,10 +102,10 @@ func TestValidRule(t *testing.T) {
name: "invalid status",
src: &rule.Slack{
Base: rule.Base{
ID: influxTesting.MustIDBase16(id1),
Name: "name1",
AuthorizationID: influxTesting.MustIDBase16(id2),
OrgID: influxTesting.MustIDBase16(id3),
ID: influxTesting.MustIDBase16(id1),
Name: "name1",
OwnerID: influxTesting.MustIDBase16(id2),
OrgID: influxTesting.MustIDBase16(id3),
},
},
err: &influxdb.Error{
@ -124,38 +124,6 @@ func TestValidRule(t *testing.T) {
Msg: "slack msg template is empty",
},
},
{
name: "empty smtp email",
src: &rule.SMTP{
Base: goodBase,
},
err: &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "smtp email is empty",
},
},
{
name: "bad smtp email",
src: &rule.SMTP{
Base: goodBase,
To: "bad@@dfa.com,good@dfa.com",
},
err: &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "smtp invalid email address: bad@@dfa.com",
},
},
{
name: "bad smtp subject",
src: &rule.SMTP{
Base: goodBase,
To: "good1@dfa.com, good2@dfa.com",
},
err: &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "smtp empty subject template",
},
},
{
name: "empty pagerDuty message",
src: &rule.PagerDuty{
@ -168,13 +136,13 @@ func TestValidRule(t *testing.T) {
},
{
name: "bad tag rule",
src: &rule.SMTP{
src: &rule.PagerDuty{
Base: rule.Base{
ID: influxTesting.MustIDBase16(id1),
AuthorizationID: influxTesting.MustIDBase16(id2),
Name: "name1",
OrgID: influxTesting.MustIDBase16(id3),
Status: influxdb.Active,
ID: influxTesting.MustIDBase16(id1),
OwnerID: influxTesting.MustIDBase16(id2),
Name: "name1",
OrgID: influxTesting.MustIDBase16(id3),
Status: influxdb.Active,
TagRules: []notification.TagRule{
{
Tag: notification.Tag{
@ -185,9 +153,7 @@ func TestValidRule(t *testing.T) {
},
},
},
SubjectTemp: "subject 1 {var1}",
BodyTemp: "body {var2}",
To: "good1@dfa.com, good2@dfa.com",
MessageTemp: "body {var2}",
},
err: &influxdb.Error{
Code: influxdb.EInvalid,
@ -196,13 +162,13 @@ func TestValidRule(t *testing.T) {
},
{
name: "bad limit",
src: &rule.SMTP{
src: &rule.PagerDuty{
Base: rule.Base{
ID: influxTesting.MustIDBase16(id1),
AuthorizationID: influxTesting.MustIDBase16(id2),
OrgID: influxTesting.MustIDBase16(id3),
Name: "name1",
Status: influxdb.Active,
ID: influxTesting.MustIDBase16(id1),
OwnerID: influxTesting.MustIDBase16(id2),
OrgID: influxTesting.MustIDBase16(id3),
Name: "name1",
Status: influxdb.Active,
TagRules: []notification.TagRule{
{
Tag: notification.Tag{
@ -216,9 +182,7 @@ func TestValidRule(t *testing.T) {
Rate: 3,
},
},
SubjectTemp: "subject 1 {var1}",
BodyTemp: "body {var2}",
To: "good1@dfa.com, good2@dfa.com",
MessageTemp: "body {var2}",
},
err: &influxdb.Error{
Code: influxdb.EInvalid,
@ -245,14 +209,14 @@ func TestJSON(t *testing.T) {
name: "simple slack",
src: &rule.Slack{
Base: rule.Base{
ID: influxTesting.MustIDBase16(id1),
AuthorizationID: influxTesting.MustIDBase16(id2),
Name: "name1",
OrgID: influxTesting.MustIDBase16(id3),
Status: influxdb.Active,
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: influxdb.Duration{Duration: time.Hour},
ID: influxTesting.MustIDBase16(id1),
OwnerID: influxTesting.MustIDBase16(id2),
Name: "name1",
OrgID: influxTesting.MustIDBase16(id3),
Status: influxdb.Active,
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: influxdb.Duration{Duration: time.Hour},
TagRules: []notification.TagRule{
{
Tag: notification.Tag{
@ -280,16 +244,16 @@ func TestJSON(t *testing.T) {
},
{
name: "simple smtp",
src: &rule.SMTP{
src: &rule.PagerDuty{
Base: rule.Base{
ID: influxTesting.MustIDBase16(id1),
Name: "name1",
AuthorizationID: influxTesting.MustIDBase16(id2),
OrgID: influxTesting.MustIDBase16(id3),
Status: influxdb.Active,
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: influxdb.Duration{Duration: time.Hour},
ID: influxTesting.MustIDBase16(id1),
Name: "name1",
OwnerID: influxTesting.MustIDBase16(id2),
OrgID: influxTesting.MustIDBase16(id3),
Status: influxdb.Active,
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: influxdb.Duration{Duration: time.Hour},
TagRules: []notification.TagRule{
{
Tag: notification.Tag{
@ -311,23 +275,21 @@ func TestJSON(t *testing.T) {
UpdatedAt: timeGen2.Now(),
},
},
SubjectTemp: "subject1",
To: "example@host.com",
BodyTemp: "msg1",
MessageTemp: "msg1",
},
},
{
name: "simple pagerDuty",
src: &rule.PagerDuty{
Base: rule.Base{
ID: influxTesting.MustIDBase16(id1),
Name: "name1",
AuthorizationID: influxTesting.MustIDBase16(id2),
OrgID: influxTesting.MustIDBase16(id3),
Status: influxdb.Active,
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: influxdb.Duration{Duration: time.Hour},
ID: influxTesting.MustIDBase16(id1),
Name: "name1",
OwnerID: influxTesting.MustIDBase16(id2),
OrgID: influxTesting.MustIDBase16(id3),
Status: influxdb.Active,
RunbookLink: "runbooklink1",
SleepUntil: &time3,
Every: influxdb.Duration{Duration: time.Hour},
TagRules: []notification.TagRule{
{
Tag: notification.Tag{

View File

@ -1,68 +0,0 @@
package rule
import (
"encoding/json"
"regexp"
"strings"
"github.com/influxdata/influxdb"
)
// SMTP is the notification rule config of email.
type SMTP struct {
Base
SubjectTemp string `json:"subjectTemplate"`
BodyTemp string `json:"bodyTemplate"`
To string `json:"to"`
}
type smtpAlias SMTP
// MarshalJSON implement json.Marshaler interface.
func (c SMTP) MarshalJSON() ([]byte, error) {
return json.Marshal(
struct {
smtpAlias
Type string `json:"type"`
}{
smtpAlias: smtpAlias(c),
Type: c.Type(),
})
}
// Valid returns where the config is valid.
func (c SMTP) Valid() error {
if err := c.Base.valid(); err != nil {
return err
}
emails := strings.Split(c.To, ",")
for _, email := range emails {
email = strings.TrimSpace(email)
if email == "" {
return &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "smtp email is empty",
}
}
if !emailPattern.MatchString(email) {
return &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "smtp invalid email address: " + email,
}
}
}
if c.SubjectTemp == "" {
return &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "smtp empty subject template",
}
}
return nil
}
// Type returns the type of the rule config.
func (c SMTP) Type() string {
return "smtp"
}
var emailPattern = regexp.MustCompile(`[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}`)

File diff suppressed because it is too large Load Diff