Skip to content

Commit

Permalink
feat(pkger): add export support for notification rules
Browse files Browse the repository at this point in the history
  • Loading branch information
jsteenb2 committed Dec 21, 2019
1 parent 08f523d commit af5b7fd
Show file tree
Hide file tree
Showing 9 changed files with 424 additions and 37 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
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
1. [16305](https://github.com/influxdata/influxdb/pull/16305): Add support for notification rule pkger apply functionality
1. [16312](https://github.com/influxdata/influxdb/pull/16312): Add support for notification rule pkger export functionality

### Bug Fixes

Expand Down
5 changes: 4 additions & 1 deletion cmd/influx/pkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type cmdPkgBuilder struct {
dashboards string
endpoints string
labels string
rules string
telegrafs string
variables string
}
Expand Down Expand Up @@ -229,6 +230,7 @@ func (b *cmdPkgBuilder) cmdPkgExport() *cobra.Command {
cmd.Flags().StringVar(&b.exportOpts.dashboards, "dashboards", "", "List of dashboard ids comma separated")
cmd.Flags().StringVar(&b.exportOpts.endpoints, "endpoints", "", "List of notification endpoint ids comma separated")
cmd.Flags().StringVar(&b.exportOpts.labels, "labels", "", "List of label ids comma separated")
cmd.Flags().StringVar(&b.exportOpts.rules, "rules", "", "List of notification rule ids comma separated")
cmd.Flags().StringVar(&b.exportOpts.telegrafs, "telegraf-configs", "", "List of telegraf config ids comma separated")
cmd.Flags().StringVar(&b.exportOpts.variables, "variables", "", "List of variable ids comma separated")

Expand All @@ -253,8 +255,9 @@ func (b *cmdPkgBuilder) pkgExportRunEFn() func(*cobra.Command, []string) error {
{kind: pkger.KindBucket, idStrs: strings.Split(b.exportOpts.buckets, ",")},
{kind: pkger.KindCheck, idStrs: strings.Split(b.exportOpts.checks, ",")},
{kind: pkger.KindDashboard, idStrs: strings.Split(b.exportOpts.dashboards, ",")},
{kind: pkger.KindNotificationEndpoint, idStrs: strings.Split(b.exportOpts.endpoints, ",")},
{kind: pkger.KindLabel, idStrs: strings.Split(b.exportOpts.labels, ",")},
{kind: pkger.KindNotificationEndpoint, idStrs: strings.Split(b.exportOpts.endpoints, ",")},
{kind: pkger.KindNotificationRule, idStrs: strings.Split(b.exportOpts.rules, ",")},
{kind: pkger.KindTelegraf, idStrs: strings.Split(b.exportOpts.telegrafs, ",")},
{kind: pkger.KindVariable, idStrs: strings.Split(b.exportOpts.variables, ",")},
}
Expand Down
22 changes: 22 additions & 0 deletions cmd/influxd/launcher/pkger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,11 @@ spec:
}

resWithNewName := []pkger.ResourceToClone{
{
Kind: pkger.KindNotificationRule,
Name: "new rule name",
ID: influxdb.ID(rule.ID),
},
{
Kind: pkger.KindVariable,
Name: "new name",
Expand Down Expand Up @@ -457,6 +462,13 @@ spec:
assert.Equal(t, endpoints[0].NotificationEndpoint.GetDescription(), newEndpoints[0].NotificationEndpoint.GetDescription())
hasLabelAssociations(t, newEndpoints[0].LabelAssociations, 1, "label_1")

require.Len(t, newSum.NotificationRules, 1)
newRule := newSum.NotificationRules[0]
assert.Equal(t, "new rule name", newRule.Name)
assert.Zero(t, newRule.EndpointID)
assert.Equal(t, rule.EndpointName, newRule.EndpointName)
hasLabelAssociations(t, newRule.LabelAssociations, 1, "label_1")

require.Len(t, newSum.TelegrafConfigs, 1)
assert.Equal(t, teles[0].TelegrafConfig.Name, newSum.TelegrafConfigs[0].TelegrafConfig.Name)
assert.Equal(t, teles[0].TelegrafConfig.Description, newSum.TelegrafConfigs[0].TelegrafConfig.Description)
Expand Down Expand Up @@ -636,6 +648,16 @@ spec:
level: INfO
min: 30.0
max: 45.0
- type: outside_range
level: WARN
min: 60.0
max: 70.0
- type: greater
level: CRIT
val: 80
- type: lesser
level: OK
val: 30
associations:
- kind: Label
name: label_1
Expand Down
1 change: 1 addition & 0 deletions http/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7156,6 +7156,7 @@ components:
- dashboard
- label
- notification_endpoint
- notification_rule
- telegraf
- variable
name:
Expand Down
112 changes: 95 additions & 17 deletions pkger/clone_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/influxdata/influxdb/notification"
icheck "github.com/influxdata/influxdb/notification/check"
"github.com/influxdata/influxdb/notification/endpoint"
"github.com/influxdata/influxdb/notification/rule"
)

// ResourceToClone is a resource that will be cloned.
Expand Down Expand Up @@ -79,18 +80,14 @@ func checkToResource(ch influxdb.Check, name string) Resource {
}
assignNonZeroStrings(r, map[string]string{fieldDescription: ch.GetDescription()})

assignFluxDur := func(field string, dur *notification.Duration) {
if dur == nil {
return
}
r[field] = dur.TimeDuration().String()
}

assignBase := func(base icheck.Base) {
r[fieldQuery] = base.Query.Text
r[fieldCheckStatusMessageTemplate] = base.StatusMessageTemplate
assignFluxDur(fieldEvery, base.Every)
assignFluxDur(fieldOffset, base.Offset)
assignNonZeroFluxDurs(r, map[string]*notification.Duration{
fieldEvery: base.Every,
fieldOffset: base.Offset,
})

var tags []Resource
for _, t := range base.Tags {
if t.Valid() != nil {
Expand All @@ -110,8 +107,10 @@ func checkToResource(ch influxdb.Check, name string) Resource {
case *icheck.Deadman:
r[fieldKind] = KindCheckDeadman.title()
assignBase(cT.Base)
assignFluxDur(fieldCheckTimeSince, cT.TimeSince)
assignFluxDur(fieldCheckStaleTime, cT.StaleTime)
assignNonZeroFluxDurs(r, map[string]*notification.Duration{
fieldCheckTimeSince: cT.TimeSince,
fieldCheckStaleTime: cT.StaleTime,
})
r[fieldLevel] = cT.Level.String()
assignNonZeroBools(r, map[string]bool{fieldCheckReportZero: cT.ReportZero})
case *icheck.Threshold:
Expand All @@ -129,15 +128,21 @@ func checkToResource(ch influxdb.Check, name string) Resource {
func convertThreshold(th icheck.ThresholdConfig) Resource {
r := Resource{fieldLevel: th.GetLevel().String()}

assignLesser := func(threshType thresholdType, allValues bool, val float64) {
r[fieldType] = string(threshType)
assignNonZeroBools(r, map[string]bool{fieldCheckAllValues: allValues})
r[fieldValue] = val
}

switch realType := th.(type) {
case icheck.Lesser:
r[fieldType] = string(thresholdTypeLesser)
assignNonZeroBools(r, map[string]bool{fieldCheckAllValues: realType.AllValues})
r[fieldValue] = realType.Value
assignLesser(thresholdTypeLesser, realType.AllValues, realType.Value)
case *icheck.Lesser:
assignLesser(thresholdTypeLesser, realType.AllValues, realType.Value)
case icheck.Greater:
r[fieldType] = string(thresholdTypeGreater)
assignNonZeroBools(r, map[string]bool{fieldCheckAllValues: realType.AllValues})
r[fieldValue] = realType.Value
assignLesser(thresholdTypeGreater, realType.AllValues, realType.Value)
case *icheck.Greater:
assignLesser(thresholdTypeGreater, realType.AllValues, realType.Value)
case icheck.Range:
assignRangeThreshold(r, realType)
case *icheck.Range:
Expand Down Expand Up @@ -433,6 +438,67 @@ func endpointToResource(e influxdb.NotificationEndpoint, name string) Resource {
return r
}

func ruleToResource(iRule influxdb.NotificationRule, endpointName, name string) Resource {
if name == "" {
name = iRule.GetName()
}
r := Resource{
fieldKind: KindNotificationRule.title(),
fieldName: name,
fieldNotificationRuleEndpointName: endpointName,
}
assignNonZeroStrings(r, map[string]string{
fieldDescription: iRule.GetDescription(),
})

assignBase := func(base rule.Base) {
assignNonZeroFluxDurs(r, map[string]*notification.Duration{
fieldEvery: base.Every,
fieldOffset: base.Offset,
})

var tagRes []Resource
for _, tRule := range base.TagRules {
tagRes = append(tagRes, Resource{
fieldKey: tRule.Key,
fieldValue: tRule.Value,
fieldOperator: tRule.Operator.String(),
})
}
if len(tagRes) > 0 {
r[fieldNotificationRuleTagRules] = tagRes
}

var statusRuleRes []Resource
for _, sRule := range base.StatusRules {
sRes := Resource{
fieldNotificationRuleCurrentLevel: sRule.CurrentLevel.String(),
}
if sRule.PreviousLevel != nil {
sRes[fieldNotificationRulePreviousLevel] = sRule.PreviousLevel.String()
}
statusRuleRes = append(statusRuleRes, sRes)
}
if len(statusRuleRes) > 0 {
r[fieldNotificationRuleStatusRules] = statusRuleRes
}
}

switch t := iRule.(type) {
case *rule.HTTP:
assignBase(t.Base)
case *rule.PagerDuty:
assignBase(t.Base)
r[fieldNotificationRuleMessageTemplate] = t.MessageTemplate
case *rule.Slack:
assignBase(t.Base)
r[fieldNotificationRuleMessageTemplate] = t.MessageTemplate
assignNonZeroStrings(r, map[string]string{fieldNotificationRuleChannel: t.Channel})
}

return r
}

func telegrafToResource(t influxdb.TelegrafConfig, name string) Resource {
if name == "" {
name = t.Name
Expand Down Expand Up @@ -487,6 +553,18 @@ func variableToResource(v influxdb.Variable, name string) Resource {
return r
}

func assignNonZeroFluxDurs(r Resource, m map[string]*notification.Duration) {
for field, dur := range m {
if dur == nil {
continue
}
if dur.TimeDuration() == 0 {
continue
}
r[field] = dur.TimeDuration().String()
}
}

func assignNonZeroBools(r Resource, m map[string]bool) {
for k, v := range m {
if v {
Expand Down
13 changes: 13 additions & 0 deletions pkger/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ var kinds = map[Kind]bool{
KindVariable: true,
}

var kindsUniqByName = map[Kind]bool{
KindBucket: true,
KindCheck: true,
KindCheckDeadman: true,
KindCheckThreshold: true,
KindLabel: true,
KindNotificationEndpoint: true,
KindNotificationEndpointHTTP: true,
KindNotificationEndpointPagerDuty: true,
KindNotificationEndpointSlack: true,
KindVariable: true,
}

// Kind is a resource kind.
type Kind string

Expand Down
26 changes: 18 additions & 8 deletions pkger/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -1274,7 +1274,13 @@ func uniqResources(resources []Resource) []Resource {
kind Kind
name string
}

// these 2 maps are used to eliminate duplicates that come
// from dependencies while keeping the Resource that has any
// associations. If there are no associations, then the resources
// are no different from one another.
m := make(map[key]bool)
res := make(map[key]Resource)

out := make([]Resource, 0, len(resources))
for _, r := range resources {
Expand All @@ -1285,18 +1291,22 @@ func uniqResources(resources []Resource) []Resource {
if err := k.OK(); err != nil {
continue
}
switch k {
// these 3 kinds are unique, have existing state identifiable by name
case KindBucket, KindLabel, KindVariable:

if kindsUniqByName[k] {
rKey := key{kind: k, name: r.Name()}
if m[rKey] {
if hasAssociations, ok := m[rKey]; ok && hasAssociations {
continue
}
m[rKey] = true
fallthrough
default:
out = append(out, r)
_, hasAssociations := r[fieldAssociations]
m[rKey] = hasAssociations
res[rKey] = r
continue
}
out = append(out, r)
}

for _, r := range res {
out = append(out, r)
}
return out
}
Expand Down
Loading

0 comments on commit af5b7fd

Please sign in to comment.