From cd2bbb14bae4ce8c751e3e06cc82fc8e0f2817ea Mon Sep 17 00:00:00 2001 From: Johnny Steenbergen Date: Mon, 1 Jun 2020 17:11:41 -0700 Subject: [PATCH] feat(pkger): add export stack command to influx CLI closes: #18271 --- cmd/influx/pkg.go | 52 +++++++++++++++++++++++++++--- cmd/influxd/launcher/pkger_test.go | 1 + 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/cmd/influx/pkg.go b/cmd/influx/pkg.go index fdadb6a1a36..633786edb1a 100644 --- a/cmd/influx/pkg.go +++ b/cmd/influx/pkg.go @@ -202,7 +202,10 @@ func (b *cmdPkgBuilder) pkgApplyRunEFn(cmd *cobra.Command, args []string) error func (b *cmdPkgBuilder) cmdPkgExport() *cobra.Command { cmd := b.newCmd("export", b.pkgExportRunEFn, true) cmd.Short = "Export existing resources as a package" - cmd.AddCommand(b.cmdPkgExportAll()) + cmd.AddCommand( + b.cmdPkgExportAll(), + b.cmdPkgExportStack(), + ) cmd.Flags().StringVarP(&b.file, "file", "f", "", "output file for created pkg; defaults to std out if no file provided; the extension of provided file (.yml/.json) will dictate encoding") cmd.Flags().StringVar(&b.exportOpts.resourceType, "resource-type", "", "The resource type provided will be associated with all IDs via stdin.") @@ -250,7 +253,7 @@ func (b *cmdPkgBuilder) pkgExportRunEFn(cmd *cobra.Command, args []string) error } if b.exportOpts.resourceType == "" { - return b.writePkg(cmd.OutOrStdout(), pkgSVC, b.file, opts...) + return b.exportPkg(cmd.OutOrStdout(), pkgSVC, b.file, opts...) } kind := pkger.Kind(b.exportOpts.resourceType) @@ -270,7 +273,7 @@ func (b *cmdPkgBuilder) pkgExportRunEFn(cmd *cobra.Command, args []string) error return err } - return b.writePkg(cmd.OutOrStdout(), pkgSVC, b.file, append(opts, resTypeOpt)...) + return b.exportPkg(cmd.OutOrStdout(), pkgSVC, b.file, append(opts, resTypeOpt)...) } func (b *cmdPkgBuilder) cmdPkgExportAll() *cobra.Command { @@ -324,7 +327,42 @@ func (b *cmdPkgBuilder) pkgExportAllRunEFn(cmd *cobra.Command, args []string) er LabelNames: labelNames, ResourceKinds: resourceKinds, }) - return b.writePkg(cmd.OutOrStdout(), pkgSVC, b.file, orgOpt) + return b.exportPkg(cmd.OutOrStdout(), pkgSVC, b.file, orgOpt) +} + +func (b *cmdPkgBuilder) cmdPkgExportStack() *cobra.Command { + cmd := b.newCmd("stack $STACK_ID", b.pkgExportStackRunEFn, true) + cmd.Short = "Export all existing resources for an organization as a package" + cmd.Args = cobra.ExactValidArgs(1) + + cmd.Flags().StringVarP(&b.file, "file", "f", "", "output file for created pkg; defaults to std out if no file provided; the extension of provided file (.yml/.json) will dictate encoding") + b.org.register(cmd, false) + + return cmd +} + +func (b *cmdPkgBuilder) pkgExportStackRunEFn(cmd *cobra.Command, args []string) error { + pkgSVC, orgSVC, err := b.svcFn() + if err != nil { + return err + } + + stackID, err := influxdb.IDFromString(args[0]) + if err != nil { + return err + } + + orgID, err := b.org.getID(orgSVC) + if err != nil { + return err + } + + pkg, err := pkgSVC.ExportStack(context.Background(), orgID, *stackID) + if err != nil { + return err + } + + return b.writePkg(b.w, b.file, pkg) } func (b *cmdPkgBuilder) cmdPkgSummary() *cobra.Command { @@ -609,12 +647,16 @@ func (b *cmdPkgBuilder) registerPkgFileFlags(cmd *cobra.Command) { cmd.MarkFlagFilename("encoding", "yaml", "yml", "json", "jsonnet") } -func (b *cmdPkgBuilder) writePkg(w io.Writer, pkgSVC pkger.SVC, outPath string, opts ...pkger.CreatePkgSetFn) error { +func (b *cmdPkgBuilder) exportPkg(w io.Writer, pkgSVC pkger.SVC, outPath string, opts ...pkger.CreatePkgSetFn) error { pkg, err := pkgSVC.CreatePkg(context.Background(), opts...) if err != nil { return err } + return b.writePkg(w, outPath, pkg) +} + +func (b *cmdPkgBuilder) writePkg(w io.Writer, outPath string, pkg *pkger.Pkg) error { buf, err := createPkgBuf(pkg, outPath) if err != nil { return err diff --git a/cmd/influxd/launcher/pkger_test.go b/cmd/influxd/launcher/pkger_test.go index 9500f92df72..e7c4a15b4dd 100644 --- a/cmd/influxd/launcher/pkger_test.go +++ b/cmd/influxd/launcher/pkger_test.go @@ -1689,6 +1689,7 @@ func TestLauncher_Pkger(t *testing.T) { Name: "test-label-2", } require.NoError(t, l.kvService.CreateLabel(ctx, newLabel)) + defer resourceCheck.mustDeleteLabel(t, newLabel.ID) // TODO(jsteenb2): cannot figure out the issue with the http.LabelService returning // the bad HTTP method error :-(. Revisit this and replace with the