Skip to content

Commit

Permalink
feat(pkger): add export support for tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
jsteenb2 committed Dec 23, 2019
1 parent c9431bc commit 74801b3
Show file tree
Hide file tree
Showing 9 changed files with 269 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
1. [16320](https://github.com/influxdata/influxdb/pull/16320): Add support for tasks to pkger parser
1. [16322](https://github.com/influxdata/influxdb/pull/16322): Add support for tasks to pkger dry run functionality
1. [16323](https://github.com/influxdata/influxdb/pull/16323): Add support for tasks to pkger apply functionality
1. [16324](https://github.com/influxdata/influxdb/pull/16324): Add support for tasks to pkger export functionality

### Bug Fixes

Expand Down
3 changes: 3 additions & 0 deletions cmd/influx/pkg.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type cmdPkgBuilder struct {
endpoints string
labels string
rules string
tasks string
telegrafs string
variables string
}
Expand Down Expand Up @@ -231,6 +232,7 @@ func (b *cmdPkgBuilder) cmdPkgExport() *cobra.Command {
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.tasks, "tasks", "", "List of task 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 Down Expand Up @@ -258,6 +260,7 @@ func (b *cmdPkgBuilder) pkgExportRunEFn() func(*cobra.Command, []string) error {
{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.KindTask, idStrs: strings.Split(b.exportOpts.tasks, ",")},
{kind: pkger.KindTelegraf, idStrs: strings.Split(b.exportOpts.telegrafs, ",")},
{kind: pkger.KindVariable, idStrs: strings.Split(b.exportOpts.variables, ",")},
}
Expand Down
97 changes: 89 additions & 8 deletions cmd/influx/pkg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,10 @@ func Test_Pkg(t *testing.T) {
pkgFileArgs
bucketIDs []influxdb.ID
dashIDs []influxdb.ID
endpointIDs []influxdb.ID
labelIDs []influxdb.ID
ruleIDs []influxdb.ID
taskIDs []influxdb.ID
telegrafIDs []influxdb.ID
varIDs []influxdb.ID
expectedMeta pkger.Metadata
Expand Down Expand Up @@ -276,6 +279,24 @@ func Test_Pkg(t *testing.T) {
Version: "new version",
},
},
{
pkgFileArgs: pkgFileArgs{
name: "endpoints",
encoding: pkger.EncodingYAML,
filename: "pkg_0.yml",
flags: []flagArg{
{name: "name", val: "new name"},
{name: "description", val: "new desc"},
{name: "version", val: "new version"},
},
},
endpointIDs: []influxdb.ID{1, 2},
expectedMeta: pkger.Metadata{
Name: "new name",
Description: "new desc",
Version: "new version",
},
},
{
pkgFileArgs: pkgFileArgs{
name: "labels",
Expand All @@ -296,7 +317,7 @@ func Test_Pkg(t *testing.T) {
},
{
pkgFileArgs: pkgFileArgs{
name: "variables",
name: "rules",
encoding: pkger.EncodingYAML,
filename: "pkg_0.yml",
flags: []flagArg{
Expand All @@ -305,7 +326,25 @@ func Test_Pkg(t *testing.T) {
{name: "version", val: "new version"},
},
},
varIDs: []influxdb.ID{1, 2},
ruleIDs: []influxdb.ID{1, 2},
expectedMeta: pkger.Metadata{
Name: "new name",
Description: "new desc",
Version: "new version",
},
},
{
pkgFileArgs: pkgFileArgs{
name: "tasks",
encoding: pkger.EncodingYAML,
filename: "pkg_0.yml",
flags: []flagArg{
{name: "name", val: "new name"},
{name: "description", val: "new desc"},
{name: "version", val: "new version"},
},
},
taskIDs: []influxdb.ID{1, 2},
expectedMeta: pkger.Metadata{
Name: "new name",
Description: "new desc",
Expand All @@ -330,12 +369,30 @@ func Test_Pkg(t *testing.T) {
Version: "new version",
},
},
{
pkgFileArgs: pkgFileArgs{
name: "variables",
encoding: pkger.EncodingYAML,
filename: "pkg_0.yml",
flags: []flagArg{
{name: "name", val: "new name"},
{name: "description", val: "new desc"},
{name: "version", val: "new version"},
},
},
varIDs: []influxdb.ID{1, 2},
expectedMeta: pkger.Metadata{
Name: "new name",
Description: "new desc",
Version: "new version",
},
},
}

cmdFn := func() *cobra.Command {
pkgSVC := &fakePkgSVC{
createFn: func(_ context.Context, opts ...pkger.CreatePkgSetFn) (*pkger.Pkg, error) {
opt := pkger.CreateOpt{}
var opt pkger.CreateOpt
for _, o := range opts {
if err := o(&opt); err != nil {
return nil, err
Expand All @@ -348,6 +405,9 @@ func Test_Pkg(t *testing.T) {
Metadata: opt.Metadata,
}
for _, rc := range opt.Resources {
if rc.Kind == pkger.KindNotificationEndpoint {
rc.Kind = pkger.KindNotificationEndpointHTTP
}
name := rc.Kind.String() + strconv.Itoa(int(rc.ID))
pkg.Spec.Resources = append(pkg.Spec.Resources, pkger.Resource{
"kind": rc.Kind,
Expand All @@ -364,8 +424,12 @@ func Test_Pkg(t *testing.T) {
for _, tt := range tests {
tt.flags = append(tt.flags,
flagArg{"buckets", idsStr(tt.bucketIDs...)},
flagArg{"endpoints", idsStr(tt.endpointIDs...)},
flagArg{"dashboards", idsStr(tt.dashIDs...)},
flagArg{"labels", idsStr(tt.labelIDs...)},
flagArg{"rules", idsStr(tt.ruleIDs...)},
flagArg{"tasks", idsStr(tt.taskIDs...)},
flagArg{"telegraf-configs", idsStr(tt.telegrafIDs...)},
flagArg{"variables", idsStr(tt.varIDs...)},
)

Expand All @@ -386,11 +450,31 @@ func Test_Pkg(t *testing.T) {
actual := sum.Dashboards[i]
assert.Equal(t, "dashboard"+strconv.Itoa(int(id)), actual.Name)
}
require.Len(t, sum.NotificationEndpoints, len(tt.endpointIDs))
for i, id := range tt.endpointIDs {
actual := sum.NotificationEndpoints[i]
assert.Equal(t, "notification_endpoint_http"+strconv.Itoa(int(id)), actual.NotificationEndpoint.GetName())
}
require.Len(t, sum.Labels, len(tt.labelIDs))
for i, id := range tt.labelIDs {
actual := sum.Labels[i]
assert.Equal(t, "label"+strconv.Itoa(int(id)), actual.Name)
}
require.Len(t, sum.NotificationRules, len(tt.ruleIDs))
for i, id := range tt.ruleIDs {
actual := sum.NotificationRules[i]
assert.Equal(t, "notification_rule"+strconv.Itoa(int(id)), actual.Name)
}
require.Len(t, sum.Tasks, len(tt.taskIDs))
for i, id := range tt.taskIDs {
actual := sum.Tasks[i]
assert.Equal(t, "task"+strconv.Itoa(int(id)), actual.Name)
}
require.Len(t, sum.TelegrafConfigs, len(tt.telegrafIDs))
for i, id := range tt.telegrafIDs {
actual := sum.TelegrafConfigs[i]
assert.Equal(t, "telegraf"+strconv.Itoa(int(id)), actual.TelegrafConfig.Name)
}
require.Len(t, sum.Variables, len(tt.varIDs))
for i, id := range tt.varIDs {
actual := sum.Variables[i]
Expand Down Expand Up @@ -444,7 +528,6 @@ func testPkgWrites(t *testing.T, newCmdFn func() *cobra.Command, args pkgFileArg
return cmd
}

// we'll memoize the current env vars if defined in args.envVars, then set the env vars defined in each test
var initialEnvVars []struct{ key, val string }
for _, envVar := range args.envVars {
if k := os.Getenv(envVar.key); k != "" {
Expand All @@ -458,12 +541,10 @@ func testPkgWrites(t *testing.T, newCmdFn func() *cobra.Command, args pkgFileArg
}

defer func() {
// unset the env vars set by the test
for _, envVar := range args.envVars {
require.NoError(t, os.Unsetenv(envVar.key))
}

// set the test env vars back to the initial state
for _, envVar := range initialEnvVars {
require.NoError(t, os.Setenv(envVar.key, envVar.val))
}
Expand All @@ -489,7 +570,7 @@ func testPkgWritesFile(newCmdFn func() *cobra.Command, args pkgFileArgs, assertF

require.NoError(t, cmd.Execute())

pkg, err := pkger.Parse(args.encoding, pkger.FromFile(pathToFile), pkger.ValidWithoutResources())
pkg, err := pkger.Parse(args.encoding, pkger.FromFile(pathToFile), pkger.ValidWithoutResources(), pkger.ValidSkipParseError())
require.NoError(t, err)

require.Equal(t, pkger.KindPackage, pkg.Kind)
Expand All @@ -511,7 +592,7 @@ func testPkgWritesToBuffer(newCmdFn func() *cobra.Command, args pkgFileArgs, ass

require.NoError(t, cmd.Execute())

pkg, err := pkger.Parse(pkger.EncodingYAML, pkger.FromReader(&buf), pkger.ValidWithoutResources())
pkg, err := pkger.Parse(pkger.EncodingYAML, pkger.FromReader(&buf), pkger.ValidWithoutResources(), pkger.ValidSkipParseError())
require.NoError(t, err)

require.Equal(t, pkger.KindPackage, pkg.Kind)
Expand Down
14 changes: 14 additions & 0 deletions cmd/influxd/launcher/pkger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,10 @@ spec:
Kind: pkger.KindNotificationEndpoint,
ID: endpoints[0].NotificationEndpoint.GetID(),
},
{
Kind: pkger.KindTask,
ID: influxdb.ID(task.ID),
},
{
Kind: pkger.KindTelegraf,
ID: teles[0].TelegrafConfig.ID,
Expand Down Expand Up @@ -492,6 +496,16 @@ spec:
assert.Equal(t, rule.EndpointName, newRule.EndpointName)
hasLabelAssociations(t, newRule.LabelAssociations, 1, "label_1")

require.Len(t, newSum.Tasks, 1)
newTask := newSum.Tasks[0]
assert.Equal(t, task.Name, newTask.Name)
assert.Equal(t, task.Description, newTask.Description)
assert.Equal(t, task.Cron, newTask.Cron)
assert.Equal(t, task.Every, newTask.Every)
assert.Equal(t, task.Offset, newTask.Offset)
assert.Equal(t, task.Query, newTask.Query)
assert.Equal(t, task.Status, newTask.Status)

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
1 change: 1 addition & 0 deletions http/swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7157,6 +7157,7 @@ components:
- label
- notification_endpoint
- notification_rule
- task
- telegraf
- variable
name:
Expand Down
30 changes: 30 additions & 0 deletions pkger/clone_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package pkger

import (
"errors"
"regexp"
"sort"
"strings"

"github.com/influxdata/influxdb"
"github.com/influxdata/influxdb/notification"
Expand Down Expand Up @@ -499,6 +501,34 @@ func ruleToResource(iRule influxdb.NotificationRule, endpointName, name string)
return r
}

// regex used to rip out the hard coded task option stuffs
var taskFluxRegex = regexp.MustCompile(`option task = {(.|\n)*}`)

func taskToResource(t influxdb.Task, name string) Resource {
if name == "" {
name = t.Name
}

var query = t.Flux
groups := taskFluxRegex.Split(t.Flux, 2)
if len(groups) > 1 {
query = strings.TrimSpace(groups[1])
}

r := Resource{
fieldKind: KindTask.title(),
fieldName: name,
fieldQuery: query,
}
assignNonZeroStrings(r, map[string]string{
fieldTaskCron: t.Cron,
fieldDescription: t.Description,
fieldEvery: t.Every,
fieldOffset: durToStr(t.Offset),
})
return r
}

func telegrafToResource(t influxdb.TelegrafConfig, name string) Resource {
if name == "" {
name = t.Name
Expand Down
12 changes: 11 additions & 1 deletion pkger/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ func (p *Pkg) Summary() Summary {
type (
validateOpt struct {
minResources bool
skipValidate bool
}

// ValidateOptFn provides a means to disable desired validation checks.
Expand All @@ -213,6 +214,15 @@ func ValidWithoutResources() ValidateOptFn {
}
}

// ValidSkipParseError ignores the validation check from the of resources. This
// is useful for the service Create to ignore this and allow the creation of a
// pkg without resources.
func ValidSkipParseError() ValidateOptFn {
return func(opt *validateOpt) {
opt.skipValidate = true
}
}

// Validate will graph all resources and validate every thing is in a useful form.
func (p *Pkg) Validate(opts ...ValidateOptFn) error {
opt := &validateOpt{minResources: true}
Expand All @@ -238,7 +248,7 @@ func (p *Pkg) Validate(opts ...ValidateOptFn) error {
}
}

if len(pErr.Resources) > 0 {
if len(pErr.Resources) > 0 && !opt.skipValidate {
return &pErr
}

Expand Down
26 changes: 26 additions & 0 deletions pkger/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@ func (s *Service) cloneOrgResources(ctx context.Context, orgID influxdb.ID) ([]R
resType: KindNotificationRule.ResourceType(),
cloneFn: s.cloneOrgNotificationRules,
},
{
resType: KindTask.ResourceType(),
cloneFn: s.cloneOrgTasks,
},
{
resType: KindTelegraf.ResourceType(),
cloneFn: s.cloneOrgTelegrafs,
Expand Down Expand Up @@ -456,6 +460,22 @@ func (s *Service) cloneOrgNotificationRules(ctx context.Context, orgID influxdb.
return resources, nil
}

func (s *Service) cloneOrgTasks(ctx context.Context, orgID influxdb.ID) ([]ResourceToClone, error) {
teles, _, err := s.taskSVC.FindTasks(ctx, influxdb.TaskFilter{OrganizationID: &orgID})
if err != nil {
return nil, err
}

resources := make([]ResourceToClone, 0, len(teles))
for _, t := range teles {
resources = append(resources, ResourceToClone{
Kind: KindTask,
ID: t.ID,
})
}
return resources, nil
}

func (s *Service) cloneOrgTelegrafs(ctx context.Context, orgID influxdb.ID) ([]ResourceToClone, error) {
teles, _, err := s.teleSVC.FindTelegrafConfigs(ctx, influxdb.TelegrafConfigFilter{OrgID: &orgID})
if err != nil {
Expand Down Expand Up @@ -544,6 +564,12 @@ func (s *Service) resourceCloneToResource(ctx context.Context, r ResourceToClone
return nil, err
}
newResource, sidecarResources = ruleRes, append(sidecarResources, endpointRes)
case r.Kind.is(KindTask):
t, err := s.taskSVC.FindTaskByID(ctx, r.ID)
if err != nil {
return nil, err
}
newResource = taskToResource(*t, r.Name)
case r.Kind.is(KindTelegraf):
t, err := s.teleSVC.FindTelegrafConfigByID(ctx, r.ID)
if err != nil {
Expand Down
Loading

0 comments on commit 74801b3

Please sign in to comment.