Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pkger): add dry run functionality for notification rules #16298

Merged
merged 1 commit into from
Dec 20, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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

17 changes: 17 additions & 0 deletions cmd/influx/pkg.go
Original file line number Diff line number Diff line change
@@ -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 {
36 changes: 31 additions & 5 deletions cmd/influxd/launcher/pkger_test.go
Original file line number Diff line number Diff line change
@@ -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())
@@ -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)
@@ -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))
@@ -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
43 changes: 43 additions & 0 deletions http/swagger.yml
Original file line number Diff line number Diff line change
@@ -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:
125 changes: 86 additions & 39 deletions pkger/models.go
Original file line number Diff line number Diff line change
@@ -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"`
}
@@ -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"`
@@ -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
}
@@ -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 {
@@ -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,
@@ -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 {
@@ -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"
)
34 changes: 34 additions & 0 deletions pkger/service.go
Original file line number Diff line number Diff line change
@@ -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
@@ -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,
}
@@ -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 {
Loading