-
Notifications
You must be signed in to change notification settings - Fork 124
Add export ingest-pipelines command #2574
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
Merged
MichelLosier
merged 24 commits into
elastic:main
from
MichelLosier:add-export-pipelines-cmd
May 16, 2025
Merged
Changes from 6 commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
2b8dd4b
Move export dashboards cmd into own file
MichelLosier f1ffa7f
Add cmd interface for export ingest-pipelines and init es client
MichelLosier 5851641
Implement ingest pipeline list selection
MichelLosier dd5c688
Have ingest pipelines export fetch pipelines by IDs
MichelLosier f65865c
Refactor dump pipelines to share functionality with export
MichelLosier d33c88e
Get nested pipelines
MichelLosier ec296da
Filter out system pipelines for export selection
MichelLosier 6b8c718
Add GetProcessorPipelineNames method to RemotePipeline struct
MichelLosier a6e1c14
Add package root as export option, and implement PipelineWriteLocation
MichelLosier 721eba5
Write parent pipelines to yaml files
MichelLosier 748c597
Fix ingest_pipeline dir name
MichelLosier 5ec05c4
Write pipeline processor pipeline deps
MichelLosier 1ff73e5
Remove logging lines
MichelLosier 11a4494
Update installedobjects_test to handle bulk pipeline requests
MichelLosier d5a089c
Apply formatting
MichelLosier 5e8cbb0
Add triple-dash document start to pipeline yaml
MichelLosier db80e29
Remove log line
MichelLosier cb13e0d
Update readme
MichelLosier d9ddd09
Formatting and clean up
MichelLosier c69162a
Remove _meta and version fields from exported pipelines
MichelLosier b1925a3
Formatting
MichelLosier 2f2de41
Set pipeline yaml export with 2 space indent
MichelLosier 7969335
Add test for export.IngestPipelines
MichelLosier c741674
Add matcher to export ingest_pipelines test
MichelLosier File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file was extracted from |
||
// or more contributor license agreements. Licensed under the Elastic License; | ||
// you may not use this file except in compliance with the Elastic License. | ||
|
||
package cmd | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/AlecAivazis/survey/v2" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/elastic/elastic-package/internal/cobraext" | ||
"github.com/elastic/elastic-package/internal/common" | ||
"github.com/elastic/elastic-package/internal/export" | ||
"github.com/elastic/elastic-package/internal/kibana" | ||
"github.com/elastic/elastic-package/internal/stack" | ||
) | ||
|
||
const exportDashboardsLongDescription = `Use this command to export dashboards with referenced objects from the Kibana instance. | ||
|
||
Use this command to download selected dashboards and other associated saved objects from Kibana. This command adjusts the downloaded saved objects according to package naming conventions (prefixes, unique IDs) and writes them locally into folders corresponding to saved object types (dashboard, visualization, map, etc.).` | ||
|
||
func exportDashboardsCmd(cmd *cobra.Command, args []string) error { | ||
cmd.Println("Export Kibana dashboards") | ||
|
||
dashboardIDs, err := cmd.Flags().GetStringSlice(cobraext.DashboardIDsFlagName) | ||
if err != nil { | ||
return cobraext.FlagParsingError(err, cobraext.DashboardIDsFlagName) | ||
} | ||
|
||
common.TrimStringSlice(dashboardIDs) | ||
|
||
var opts []kibana.ClientOption | ||
tlsSkipVerify, _ := cmd.Flags().GetBool(cobraext.TLSSkipVerifyFlagName) | ||
if tlsSkipVerify { | ||
opts = append(opts, kibana.TLSSkipVerify()) | ||
} | ||
|
||
allowSnapshot, _ := cmd.Flags().GetBool(cobraext.AllowSnapshotFlagName) | ||
if err != nil { | ||
return cobraext.FlagParsingError(err, cobraext.AllowSnapshotFlagName) | ||
} | ||
|
||
profile, err := cobraext.GetProfileFlag(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
kibanaClient, err := stack.NewKibanaClientFromProfile(profile, opts...) | ||
if err != nil { | ||
return fmt.Errorf("can't create Kibana client: %w", err) | ||
} | ||
|
||
kibanaVersion, err := kibanaClient.Version() | ||
if err != nil { | ||
return fmt.Errorf("can't get Kibana status information: %w", err) | ||
} | ||
|
||
if kibanaVersion.IsSnapshot() { | ||
message := fmt.Sprintf("exporting dashboards from a SNAPSHOT version of Kibana (%s) is discouraged. It could lead to invalid dashboards (for example if they use features that are reverted or modified before the final release)", kibanaVersion.Version()) | ||
if !allowSnapshot { | ||
return fmt.Errorf("%s. --%s flag can be used to ignore this error", message, cobraext.AllowSnapshotFlagName) | ||
} | ||
fmt.Printf("Warning: %s\n", message) | ||
} | ||
|
||
if len(dashboardIDs) == 0 { | ||
dashboardIDs, err = promptDashboardIDs(cmd.Context(), kibanaClient) | ||
if err != nil { | ||
return fmt.Errorf("prompt for dashboard selection failed: %w", err) | ||
} | ||
|
||
if len(dashboardIDs) == 0 { | ||
fmt.Println("No dashboards were found in Kibana.") | ||
return nil | ||
} | ||
} | ||
|
||
err = export.Dashboards(cmd.Context(), kibanaClient, dashboardIDs) | ||
if err != nil { | ||
return fmt.Errorf("dashboards export failed: %w", err) | ||
} | ||
|
||
cmd.Println("Done") | ||
return nil | ||
} | ||
|
||
func promptDashboardIDs(ctx context.Context, kibanaClient *kibana.Client) ([]string, error) { | ||
savedDashboards, err := kibanaClient.FindDashboards(ctx) | ||
if err != nil { | ||
return nil, fmt.Errorf("finding dashboards failed: %w", err) | ||
} | ||
|
||
if len(savedDashboards) == 0 { | ||
return []string{}, nil | ||
} | ||
|
||
dashboardsPrompt := &survey.MultiSelect{ | ||
Message: "Which dashboards would you like to export?", | ||
Options: savedDashboards.Strings(), | ||
PageSize: 100, | ||
} | ||
|
||
var selectedOptions []string | ||
err = survey.AskOne(dashboardsPrompt, &selectedOptions, survey.WithValidator(survey.Required)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var selected []string | ||
for _, option := range selectedOptions { | ||
for _, sd := range savedDashboards { | ||
if sd.String() == option { | ||
selected = append(selected, sd.ID) | ||
} | ||
} | ||
} | ||
return selected, nil | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
// or more contributor license agreements. Licensed under the Elastic License; | ||
// you may not use this file except in compliance with the Elastic License. | ||
|
||
package cmd | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/AlecAivazis/survey/v2" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/elastic/elastic-package/internal/cobraext" | ||
"github.com/elastic/elastic-package/internal/common" | ||
"github.com/elastic/elastic-package/internal/elasticsearch" | ||
"github.com/elastic/elastic-package/internal/elasticsearch/ingest" | ||
"github.com/elastic/elastic-package/internal/export" | ||
"github.com/elastic/elastic-package/internal/stack" | ||
) | ||
|
||
|
||
const exportIngestPipelinesLongDescription = `Use this command to export ingest pipelines with referenced objects from the Elasticsearch instance. | ||
|
||
Use this command to download selected ingest pipelines and other associated saved objects from Elasticsearch. This command adjusts the downloaded saved objects according to package naming conventions (prefixes, unique IDs) and writes them locally into folders corresponding to saved object types (pipelines, etc.).` | ||
|
||
func exportIngestPipelinesCmd(cmd *cobra.Command, args []string) error { | ||
cmd.Println("Export Elasticsearch ingest pipelines") | ||
|
||
pipelineIDs, err := cmd.Flags().GetStringSlice(cobraext.IngestPipelineIDsFlagName) | ||
if err != nil { | ||
return cobraext.FlagParsingError(err, cobraext.IngestPipelineIDsFlagName) | ||
} | ||
|
||
common.TrimStringSlice(pipelineIDs) | ||
|
||
var opts []elasticsearch.ClientOption | ||
tlsSkipVerify, _ := cmd.Flags().GetBool(cobraext.TLSSkipVerifyFlagName) | ||
if tlsSkipVerify { | ||
opts = append(opts, elasticsearch.OptionWithSkipTLSVerify()) | ||
} | ||
|
||
profile, err := cobraext.GetProfileFlag(cmd) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
esClient, err := stack.NewElasticsearchClientFromProfile(profile, opts...) | ||
if err != nil { | ||
return fmt.Errorf("can't create Elasticsearch client: %w", err) | ||
} | ||
|
||
if len(pipelineIDs) == 0 { | ||
pipelineIDs, err = promptIngestPipelineIDs(cmd.Context(), esClient.API) | ||
|
||
if err != nil { | ||
return fmt.Errorf("prompt for ingest pipeline selection failed: %w", err) | ||
} | ||
|
||
if len(pipelineIDs) == 0 { | ||
cmd.Println("No ingest pipelines were found in Elasticsearch.") | ||
return nil | ||
} | ||
} | ||
|
||
err = export.IngestPipelines(cmd.Context(), esClient.API, pipelineIDs...) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
cmd.Println("Done") | ||
return nil | ||
} | ||
|
||
func promptIngestPipelineIDs(ctx context.Context, api *elasticsearch.API) ([]string, error) { | ||
ingestPipelineNames, err := ingest.GetRemotePipelineNames(ctx, api) | ||
if err != nil { | ||
return nil, fmt.Errorf("finding ingest pipelines failed: %w", err) | ||
} | ||
|
||
ingestPipelinesPrompt := &survey.MultiSelect{ | ||
Message: "Which ingest pipelines would you like to export?", | ||
Options: ingestPipelineNames, | ||
PageSize: 20, | ||
} | ||
|
||
var selectedOptions []string | ||
err = survey.AskOne(ingestPipelinesPrompt, &selectedOptions, survey.WithValidator(survey.Required)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return selectedOptions, nil | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moves export dashboards functionality into own file now that we are adding support for ingest-pipelines