Skip to content

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

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

MichelLosier
Copy link

@MichelLosier MichelLosier commented May 6, 2025

Resolves: #1722

  • Adds ingest pipeline export from elasticsearch to a package with the command elastic-package export ingest-pipelines
  • User is prompted with a multi-selection of pipelines to export
    • References to pipelines in a pipeline processor definitions will also be pulled automatically
  • User is prompted to select an existing data stream in the package, or the package root as destinations to export to.
    • Dependent pipeline references are not prompted for, they'll be written to the same destination as selected for the parent.
  • Pipelines are written to yaml files unchanged

Screenshot 2025-05-09 at 12 01 29 PM
Screenshot 2025-05-09 at 12 02 27 PM

cmd.PersistentFlags().StringP(cobraext.ProfileFlagName, "p", "", fmt.Sprintf(cobraext.ProfileFlagDescription, install.ProfileNameEnvVar))

return cobraext.NewCommand(cmd, cobraext.ContextPackage)
}

func exportDashboardsCmd(cmd *cobra.Command, args []string) error {
Copy link
Author

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

)

// IngestPipeline contains the information needed to export an ingest pipeline.
type IngestPipeline struct {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of this functionality was moved to the internal/elasticsearch package since it shares a lot of retrieval needs with the new export functionality

@@ -0,0 +1,122 @@
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file was extracted from cmd/export.go

@elasticmachine
Copy link
Collaborator

💚 Build Succeeded

History

@MichelLosier MichelLosier marked this pull request as ready for review May 9, 2025 19:09

ingestPipelineNames = slices.DeleteFunc(ingestPipelineNames, func(name string) bool {
// Filter out system pipelines that start with dot "." or global@
return strings.HasPrefix(name, ".") || strings.HasPrefix(name, "global@")
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any other pipeline types / patterns we should exclude here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine by now, we can modify this in the future if there is some feedback from package developers.

Copy link
Member

@jsoriano jsoriano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This is looking quite good, and works well. Added some comments.


ingestPipelineNames = slices.DeleteFunc(ingestPipelineNames, func(name string) bool {
// Filter out system pipelines that start with dot "." or global@
return strings.HasPrefix(name, ".") || strings.HasPrefix(name, "global@")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine by now, we can modify this in the future if there is some feedback from package developers.

}

func promptWriteLocations(pipelineNames []string, writeLocations []export.PipelineWriteLocation) (export.PipelineWriteAssignments, error) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit. Remove empty line.

Suggested change

Comment on lines +180 to +181
Description: func(value string, index int) string {
idx := slices.IndexFunc(writeLocations, func(p export.PipelineWriteLocation) bool { return p.Name == value })
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't be idx the same as index?

@@ -39,18 +43,20 @@ func TestDumpInstalledObjects(t *testing.T) {
&installedObjectsDumpSuite{
// To reproduce the scenario:
// - Start the stack with version 7.16.2.
// - Install apache package (1.3.4).
// - Install apache package (1.3.5).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit. Why did we need to regenerate the records? Doesn't it work the same for these cases?

Comment on lines +99 to +106
yamlBytes, err := yaml.Marshal(jsonPipeline)
if err != nil {
return fmt.Errorf("marshalling ingest pipeline json to yaml failed (ID: %s): %w", pipeline.Name(), err)
}

// requirement: https://github.com/elastic/package-spec/pull/54
documentStartDashes := []byte("---\n")
documentBytes := append(documentStartDashes, yamlBytes...)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit. To avoid appending, you can use a bytes buffer. Something like this:

Suggested change
yamlBytes, err := yaml.Marshal(jsonPipeline)
if err != nil {
return fmt.Errorf("marshalling ingest pipeline json to yaml failed (ID: %s): %w", pipeline.Name(), err)
}
// requirement: https://github.com/elastic/package-spec/pull/54
documentStartDashes := []byte("---\n")
documentBytes := append(documentStartDashes, yamlBytes...)
var documentBytes bytes.Buffer
// requirement: https://github.com/elastic/package-spec/pull/54
documentBytes.WriteString("---\n")
err := yaml.NewEncoder(&documentBytes).Encode(jsonPipeline)
if err != nil {
return fmt.Errorf("marshalling ingest pipeline json to yaml failed (ID: %s): %w", pipeline.Name(), err)
}


type PipelineWriteAssignments map[string]PipelineWriteLocation

func IngestPipelines(ctx context.Context, api *elasticsearch.API, writeAssignments PipelineWriteAssignments) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have a test case for this?

return fmt.Errorf("unmarshalling ingest pipeline failed (ID: %s): %w", pipeline.Name(), err)
}

yamlBytes, err := yaml.Marshal(jsonPipeline)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should do some formatting here. Some things:

  • Remove _meta, specially the managed* fields should not be needed here.
  • Remove version, I think this is not being used in packages.
  • Indentation. Looking to pipelines they use to be indented by two spaces, default marshalling seems to use four spaces.

Maybe we should make elastic-package format to automatically format these files too. But that is another story.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature] elastic-package export pipelines
3 participants