Skip to content

Commit

Permalink
feat(pkger): add dry run functionality for notification rules
Browse files Browse the repository at this point in the history
  • Loading branch information
jsteenb2 committed Dec 20, 2019
1 parent 3504ea2 commit 02aec6e
Show file tree
Hide file tree
Showing 7 changed files with 275 additions and 47 deletions.
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
1. [16234](https://github.com/influxdata/influxdb/pull/16234): Add support for notification endpoints to influx templates/pkgs.
2. [16242](https://github.com/influxdata/influxdb/pull/16242): Drop id prefix for secret key requirement for notification endpoints
3. [16259](https://github.com/influxdata/influxdb/pull/16259): Add support for check resource to pkger parser
4. [16262](https://github.com/influxdata/influxdb/pull/16262): Add support for check resource dry run functionality
5. [16275](https://github.com/influxdata/influxdb/pull/16275): Add support for check resource apply functionality
6. [16283](https://github.com/influxdata/influxdb/pull/16283): Add support for check resource export functionality
4. [16262](https://github.com/influxdata/influxdb/pull/16262): Add support for check resource pkger dry run functionality
5. [16275](https://github.com/influxdata/influxdb/pull/16275): Add support for check resource pkger apply functionality
6. [16283](https://github.com/influxdata/influxdb/pull/16283): Add support for check resource pkger export functionality
1. [16212](https://github.com/influxdata/influxdb/pull/16212): Add new kv.ForwardCursor interface
1. [16297](https://github.com/influxdata/influxdb/pull/16297): Add support for notification rule to pkger parser
1. [16298](https://github.com/influxdata/influxdb/pull/16298): Add support for notification rule pkger dry run functionality

### Bug Fixes

Expand Down
17 changes: 17 additions & 0 deletions cmd/influx/pkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,23 @@ func (b *cmdPkgBuilder) printPkgDiff(diff pkger.Diff) {
})
}

if rules := diff.NotificationRules; len(rules) > 0 {
headers := []string{"New", "Name", "Description", "Every", "Offset", "Endpoint Name", "Endpoint ID", "Endpoint Type"}
tablePrintFn("NOTIFICATION RULES", headers, len(rules), func(i int) []string {
v := rules[i]
return []string{
green(true),
v.Name,
v.Description,
v.Every,
v.Offset,
v.EndpointName,
v.EndpointID.String(),
v.EndpointType,
}
})
}

if teles := diff.Telegrafs; len(diff.Telegrafs) > 0 {
headers := []string{"New", "Name", "Description"}
tablePrintFn("TELEGRAF CONFIGS", headers, len(teles), func(i int) []string {
Expand Down
36 changes: 31 additions & 5 deletions cmd/influxd/launcher/pkger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ func TestLauncher_Pkger(t *testing.T) {
require.Len(t, diffBkts, 1)
assert.True(t, diffBkts[0].IsNew())

require.Len(t, diff.Checks, 2)
for _, ch := range diff.Checks {
assert.True(t, ch.IsNew())
}

diffLabels := diff.Labels
require.Len(t, diffLabels, 1)
assert.True(t, diffLabels[0].IsNew())
Expand All @@ -137,10 +142,9 @@ func TestLauncher_Pkger(t *testing.T) {
require.Len(t, diffVars, 1)
assert.True(t, diffVars[0].IsNew())

require.Len(t, diff.Checks, 2)
for _, ch := range diff.Checks {
assert.True(t, ch.IsNew())
}
require.Len(t, diff.NotificationRules, 1)
// the pkg being run here has a relationship with the rule and the endpoint within the pkg.
assert.Equal(t, "http", diff.NotificationRules[0].EndpointType)

require.Len(t, diff.Dashboards, 1)
require.Len(t, diff.NotificationEndpoints, 1)
Expand Down Expand Up @@ -266,7 +270,7 @@ func TestLauncher_Pkger(t *testing.T) {
}

mappings := sum1.LabelMappings
require.Len(t, mappings, 7)
require.Len(t, mappings, 8)
hasMapping(t, mappings, newSumMapping(bkts[0].ID, bkts[0].Name, influxdb.BucketsResourceType))
hasMapping(t, mappings, newSumMapping(dashs[0].ID, dashs[0].Name, influxdb.DashboardsResourceType))
hasMapping(t, mappings, newSumMapping(vars[0].ID, vars[0].Name, influxdb.VariablesResourceType))
Expand Down Expand Up @@ -638,6 +642,28 @@ spec:
associations:
- kind: Label
name: label_1
- kind: Notification_Rule
name: rule_0
description: desc_0
endpointName: http_none_auth_notification_endpoint
every: 10m
offset: 30s
messageTemplate: "Notification Rule: ${ r._notification_rule_name } triggered by check: ${ r._check_name }: ${ r._message }"
status: active
statusRules:
- currentLevel: WARN
- currentLevel: CRIT
previousLevel: OK
tagRules:
- key: k1
value: v2
operator: eQuAl
- key: k1
value: v1
operator: eQuAl
associations:
- kind: Label
name: label_1
`

const updatePkgYMLStr = `apiVersion: 0.1.0
Expand Down
43 changes: 43 additions & 0 deletions http/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7408,6 +7408,49 @@ components:
$ref: "#/components/schemas/NotificationEndpointDiscrimator"
old:
$ref: "#/components/schemas/NotificationEndpointDiscrimator"
notificationRules:
type: array
items:
type: object
properties:
name:
type: string
description:
type: string
endpointName:
type: string
endpointID:
type: string
endpointType:
type: string
every:
type: string
offset:
type: string
messageTemplate:
type: string
status:
type: string
statusRules:
type: array
items:
type: object
properties:
currentLevel:
type: string
previousLevel:
type: string
tagRules:
type: array
items:
type: object
properties:
key:
type: string
value:
type: string
operator:
type: string
telegrafConfigs:
type: array
items:
Expand Down
125 changes: 86 additions & 39 deletions pkger/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ type Diff struct {
Labels []DiffLabel `json:"labels"`
LabelMappings []DiffLabelMapping `json:"labelMappings"`
NotificationEndpoints []DiffNotificationEndpoint `json:"notificationEndpoints"`
NotificationRules []DiffNotificationRule `json:"notificationRules"`
Telegrafs []DiffTelegraf `json:"telegrafConfigs"`
Variables []DiffVariable `json:"variables"`
}
Expand Down Expand Up @@ -273,7 +274,7 @@ func (d DiffCheck) IsNew() bool {
return d.Old == nil
}

// DiffDashboard is a diff of an individual dashboard.
// DiffDashboard is a diff of an individual dashboard. This resource is always new.
type DiffDashboard struct {
Name string `json:"name"`
Desc string `json:"description"`
Expand Down Expand Up @@ -397,7 +398,45 @@ func (d DiffNotificationEndpoint) IsNew() bool {
return d.Old == nil
}

// DiffTelegraf is a diff of an individual telegraf.
// DiffNotificationRule is a diff of an individual notification rule. This resource is always new.
type DiffNotificationRule struct {
Name string `json:"name"`
Description string `json:"description"`

// All these fields represent the relationship of the rule to the endpoint.
EndpointName string `json:"endpointName"`
EndpointID SafeID `json:"endpointID"`
EndpointType string `json:"endpointType"`

Every string `json:"every"`
Offset string `json:"offset"`
MessageTemplate string `json:"messageTemplate"`
Status influxdb.Status `json:"status"`
StatusRules []SummaryStatusRule `json:"statusRules"`
TagRules []SummaryTagRule `json:"tagRules"`
}

func newDiffNotificationRule(r *notificationRule, iEndpoint influxdb.NotificationEndpoint) DiffNotificationRule {
sum := DiffNotificationRule{
Name: r.Name(),
Description: r.description,
EndpointName: r.endpointName,
Every: r.every.String(),
Offset: r.offset.String(),
MessageTemplate: r.msgTemplate,
Status: r.Status(),
StatusRules: toSummaryStatusRules(r.statusRules),
TagRules: toSummaryTagRules(r.tagRules),
}
if iEndpoint != nil {
sum.EndpointID = SafeID(iEndpoint.GetID())
sum.EndpointType = iEndpoint.Type()
}

return sum
}

// DiffTelegraf is a diff of an individual telegraf. This resource is always new.
type DiffTelegraf struct {
influxdb.TelegrafConfig
}
Expand Down Expand Up @@ -632,8 +671,8 @@ type (
}

SummaryStatusRule struct {
CurrentLevel string `json:"curLvl"`
PreviousLevel string `json:"prevLvl"`
CurrentLevel string `json:"currentLevel"`
PreviousLevel string `json:"previousLevel"`
}

SummaryTagRule struct {
Expand Down Expand Up @@ -1494,7 +1533,7 @@ func (r *notificationRule) Status() influxdb.Status {
}

func (r *notificationRule) summarize() SummaryNotificationRule {
sum := SummaryNotificationRule{
return SummaryNotificationRule{
Name: r.Name(),
EndpointName: r.endpointName,
Description: r.description,
Expand All @@ -1503,41 +1542,9 @@ func (r *notificationRule) summarize() SummaryNotificationRule {
Offset: r.offset.String(),
MessageTemplate: r.msgTemplate,
Status: r.Status(),
StatusRules: toSummaryStatusRules(r.statusRules),
TagRules: toSummaryTagRules(r.tagRules),
}

for _, sRule := range r.statusRules {
sum.StatusRules = append(sum.StatusRules, SummaryStatusRule{
CurrentLevel: sRule.curLvl,
PreviousLevel: sRule.prevLvl,
})
}
sort.Slice(sum.StatusRules, func(i, j int) bool {
si, sj := sum.StatusRules[i], sum.StatusRules[j]
if si.CurrentLevel == sj.CurrentLevel {
return si.PreviousLevel < sj.PreviousLevel
}
return si.CurrentLevel < sj.CurrentLevel
})

for _, tRule := range r.tagRules {
sum.TagRules = append(sum.TagRules, SummaryTagRule{
Key: tRule.k,
Value: tRule.v,
Operator: tRule.op,
})
}
sort.Slice(sum.TagRules, func(i, j int) bool {
ti, tj := sum.TagRules[i], sum.TagRules[j]
if ti.Key == tj.Key && ti.Value == tj.Value {
return ti.Operator < tj.Operator
}
if ti.Key == tj.Key {
return ti.Value < tj.Value
}
return ti.Key < tj.Key
})

return sum
}

func (r *notificationRule) valid() []validationErr {
Expand Down Expand Up @@ -1612,6 +1619,46 @@ func (r *notificationRule) valid() []validationErr {
return vErrs
}

func toSummaryStatusRules(statusRules []struct{ curLvl, prevLvl string }) []SummaryStatusRule {
out := make([]SummaryStatusRule, 0, len(statusRules))
for _, sRule := range statusRules {
out = append(out, SummaryStatusRule{
CurrentLevel: sRule.curLvl,
PreviousLevel: sRule.prevLvl,
})
}
sort.Slice(out, func(i, j int) bool {
si, sj := out[i], out[j]
if si.CurrentLevel == sj.CurrentLevel {
return si.PreviousLevel < sj.PreviousLevel
}
return si.CurrentLevel < sj.CurrentLevel
})
return out
}

func toSummaryTagRules(tagRules []struct{ k, v, op string }) []SummaryTagRule {
out := make([]SummaryTagRule, 0, len(tagRules))
for _, tRule := range tagRules {
out = append(out, SummaryTagRule{
Key: tRule.k,
Value: tRule.v,
Operator: tRule.op,
})
}
sort.Slice(out, func(i, j int) bool {
ti, tj := out[i], out[j]
if ti.Key == tj.Key && ti.Value == tj.Value {
return ti.Operator < tj.Operator
}
if ti.Key == tj.Key {
return ti.Value < tj.Value
}
return ti.Key < tj.Key
})
return out
}

const (
fieldTelegrafConfig = "config"
)
Expand Down
34 changes: 34 additions & 0 deletions pkger/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,11 @@ func (s *Service) DryRun(ctx context.Context, orgID, userID influxdb.ID, pkg *Pk
return Summary{}, Diff{}, err
}

diffRules, err := s.dryRunNotificationRules(ctx, orgID, pkg)
if err != nil {
return Summary{}, Diff{}, err
}

diffVars, err := s.dryRunVariables(ctx, orgID, pkg)
if err != nil {
return Summary{}, Diff{}, err
Expand All @@ -621,6 +626,7 @@ func (s *Service) DryRun(ctx context.Context, orgID, userID influxdb.ID, pkg *Pk
Labels: diffLabels,
LabelMappings: diffLabelMappings,
NotificationEndpoints: diffEndpoints,
NotificationRules: diffRules,
Telegrafs: s.dryRunTelegraf(pkg),
Variables: diffVars,
}
Expand Down Expand Up @@ -763,6 +769,34 @@ func (s *Service) dryRunNotificationEndpoints(ctx context.Context, orgID influxd
return diffs, nil
}

func (s *Service) dryRunNotificationRules(ctx context.Context, orgID influxdb.ID, pkg *Pkg) ([]DiffNotificationRule, error) {
iEndpoints, _, err := s.endpointSVC.FindNotificationEndpoints(ctx, influxdb.NotificationEndpointFilter{
OrgID: &orgID,
})
if err != nil {
return nil, err
}
mExisting := make(map[string]influxdb.NotificationEndpoint)
for _, e := range iEndpoints {
mExisting[e.GetName()] = e
}

var diffs []DiffNotificationRule
for _, r := range pkg.notificationRules() {
e, ok := mExisting[r.endpointName]
if !ok {
pkgerEndpoint, ok := pkg.mNotificationEndpoints[r.endpointName]
if !ok {
return nil, fmt.Errorf("failed to find endpoint by name: %q", r.endpointName)
}
e = pkgerEndpoint.summarize().NotificationEndpoint
}
diffs = append(diffs, newDiffNotificationRule(r, e))

}
return diffs, nil
}

func (s *Service) dryRunSecrets(ctx context.Context, orgID influxdb.ID, pkg *Pkg) error {
secrets := pkg.secrets()
if len(secrets) == 0 {
Expand Down
Loading

0 comments on commit 02aec6e

Please sign in to comment.