From 95d84fa17dcf25ac2653924a39e732047e57c77c Mon Sep 17 00:00:00 2001 From: Teresa Romero Date: Mon, 15 Sep 2025 15:07:01 +0200 Subject: [PATCH 01/13] add support for version-based question prompts in data stream creation --- cmd/create_data_stream.go | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/cmd/create_data_stream.go b/cmd/create_data_stream.go index 62394e3ae..eb92a4c09 100644 --- a/cmd/create_data_stream.go +++ b/cmd/create_data_stream.go @@ -11,6 +11,7 @@ import ( "slices" "github.com/AlecAivazis/survey/v2" + "github.com/Masterminds/semver/v3" "github.com/spf13/cobra" @@ -19,6 +20,8 @@ import ( "github.com/elastic/elastic-package/internal/surveyext" ) +var semver3_2_0 = semver.MustParse("3.2.0") + const createDataStreamLongDescription = `Use this command to create a new data stream. The command can extend the package with a new data stream using embedded data stream template and wizard.` @@ -80,14 +83,21 @@ func createDataStreamCommandAction(cmd *cobra.Command, args []string) error { }, Validate: survey.Required, }, - { + } + + sv, err := semver.NewVersion(manifest.SpecVersion) + if err != nil { + return fmt.Errorf("failed to obtain spec version from package manifest in \"%s\"", packageRoot) + } + if !sv.LessThan(semver3_2_0) { + qs = append(qs, &survey.Question{ Name: "subobjects", Prompt: &survey.Confirm{ Message: "Enable creation of subobjects for fields with dots in their names?", Default: false, }, Validate: survey.Required, - }, + }) } var answers newDataStreamAnswers err = survey.Ask(qs, &answers) @@ -173,7 +183,7 @@ func createDataStreamCommandAction(cmd *cobra.Command, args []string) error { } } - descriptor := createDataStreamDescriptorFromAnswers(answers, packageRoot) + descriptor := createDataStreamDescriptorFromAnswers(answers, packageRoot, sv) err = archetype.CreateDataStream(descriptor) if err != nil { return fmt.Errorf("can't create new data stream: %w", err) @@ -183,14 +193,14 @@ func createDataStreamCommandAction(cmd *cobra.Command, args []string) error { return nil } -func createDataStreamDescriptorFromAnswers(answers newDataStreamAnswers, packageRoot string) archetype.DataStreamDescriptor { +func createDataStreamDescriptorFromAnswers(answers newDataStreamAnswers, packageRoot string, specVersion *semver.Version) archetype.DataStreamDescriptor { manifest := packages.DataStreamManifest{ Name: answers.Name, Title: answers.Title, Type: answers.Type, } - if !answers.Subobjects { + if !specVersion.LessThan(semver3_2_0) && !answers.Subobjects { manifest.Elasticsearch = &packages.Elasticsearch{ IndexTemplate: &packages.ManifestIndexTemplate{ Mappings: &packages.ManifestMappings{ From 092a91c075c418d4e361ee7a885bbeaf179376c4 Mon Sep 17 00:00:00 2001 From: Tere Date: Tue, 16 Sep 2025 09:53:46 +0200 Subject: [PATCH 02/13] Update cmd/create_data_stream.go Co-authored-by: Jaime Soriano Pastor --- cmd/create_data_stream.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/create_data_stream.go b/cmd/create_data_stream.go index eb92a4c09..83d811f8c 100644 --- a/cmd/create_data_stream.go +++ b/cmd/create_data_stream.go @@ -87,7 +87,7 @@ func createDataStreamCommandAction(cmd *cobra.Command, args []string) error { sv, err := semver.NewVersion(manifest.SpecVersion) if err != nil { - return fmt.Errorf("failed to obtain spec version from package manifest in \"%s\"", packageRoot) + return fmt.Errorf("failed to obtain spec version from package manifest in \"%s\": %w", packageRoot, err) } if !sv.LessThan(semver3_2_0) { qs = append(qs, &survey.Question{ From 6401c45b82896a8968ce68839f6678a6b1ede50f Mon Sep 17 00:00:00 2001 From: Teresa Romero Date: Tue, 16 Sep 2025 10:29:57 +0200 Subject: [PATCH 03/13] extract survey question logic into a separate function and add tests --- cmd/create_data_stream.go | 86 +++++++++++++++++++--------------- cmd/create_data_stream_test.go | 43 +++++++++++++++++ 2 files changed, 90 insertions(+), 39 deletions(-) create mode 100644 cmd/create_data_stream_test.go diff --git a/cmd/create_data_stream.go b/cmd/create_data_stream.go index 83d811f8c..8c400cd04 100644 --- a/cmd/create_data_stream.go +++ b/cmd/create_data_stream.go @@ -56,49 +56,13 @@ func createDataStreamCommandAction(cmd *cobra.Command, args []string) error { return fmt.Errorf("data-streams are not supported in input packages") } - validator := surveyext.Validator{Cwd: "."} - qs := []*survey.Question{ - { - Name: "name", - Prompt: &survey.Input{ - Message: "Data stream name:", - Default: "new_data_stream", - }, - Validate: survey.ComposeValidators(survey.Required, validator.DataStreamDoesNotExist, validator.DataStreamName), - }, - { - Name: "title", - Prompt: &survey.Input{ - Message: "Data stream title:", - Default: "New Data Stream", - }, - Validate: survey.Required, - }, - { - Name: "type", - Prompt: &survey.Select{ - Message: "Type:", - Options: []string{"logs", "metrics"}, - Default: "logs", - }, - Validate: survey.Required, - }, - } - sv, err := semver.NewVersion(manifest.SpecVersion) if err != nil { return fmt.Errorf("failed to obtain spec version from package manifest in \"%s\": %w", packageRoot, err) } - if !sv.LessThan(semver3_2_0) { - qs = append(qs, &survey.Question{ - Name: "subobjects", - Prompt: &survey.Confirm{ - Message: "Enable creation of subobjects for fields with dots in their names?", - Default: false, - }, - Validate: survey.Required, - }) - } + + qs := getInitialSurveyQuestionsForVersion(sv) + var answers newDataStreamAnswers err = survey.Ask(qs, &answers) if err != nil { @@ -241,3 +205,47 @@ func createDataStreamDescriptorFromAnswers(answers newDataStreamAnswers, package PackageRoot: packageRoot, } } + +func getInitialSurveyQuestionsForVersion(specVersion *semver.Version) []*survey.Question { + validator := surveyext.Validator{Cwd: "."} + qs := []*survey.Question{ + { + Name: "name", + Prompt: &survey.Input{ + Message: "Data stream name:", + Default: "new_data_stream", + }, + Validate: survey.ComposeValidators(survey.Required, validator.DataStreamDoesNotExist, validator.DataStreamName), + }, + { + Name: "title", + Prompt: &survey.Input{ + Message: "Data stream title:", + Default: "New Data Stream", + }, + Validate: survey.Required, + }, + { + Name: "type", + Prompt: &survey.Select{ + Message: "Type:", + Options: []string{"logs", "metrics"}, + Default: "logs", + }, + Validate: survey.Required, + }, + } + + if !specVersion.LessThan(semver3_2_0) { + qs = append(qs, &survey.Question{ + Name: "subobjects", + Prompt: &survey.Confirm{ + Message: "Enable creation of subobjects for fields with dots in their names?", + Default: false, + }, + Validate: survey.Required, + }) + } + + return qs +} diff --git a/cmd/create_data_stream_test.go b/cmd/create_data_stream_test.go new file mode 100644 index 000000000..7a27b5ae8 --- /dev/null +++ b/cmd/create_data_stream_test.go @@ -0,0 +1,43 @@ +package cmd + +import ( + "testing" + + "github.com/AlecAivazis/survey/v2" + "github.com/Masterminds/semver/v3" + "github.com/stretchr/testify/assert" +) + +func TestGetSurveyQuestionsForVersion_BelowSemver3_2_0(t *testing.T) { + version := semver.MustParse("3.1.9") + questions := getInitialSurveyQuestionsForVersion(version) + + assert.Len(t, questions, 3, "should return 3 questions for spec version < 3.2.0") + + assert.Equal(t, "name", questions[0].Name) + assert.IsType(t, &survey.Input{}, questions[0].Prompt) + assert.Equal(t, "title", questions[1].Name) + assert.IsType(t, &survey.Input{}, questions[1].Prompt) + assert.Equal(t, "type", questions[2].Name) + assert.IsType(t, &survey.Select{}, questions[2].Prompt) +} + +func TestGetSurveyQuestionsForVersion_EqualSemver3_2_0(t *testing.T) { + version := semver.MustParse("3.2.0") + questions := getInitialSurveyQuestionsForVersion(version) + + assert.Len(t, questions, 4, "should return 4 questions for spec version >= 3.2.0") + + assert.Equal(t, "subobjects", questions[3].Name) + assert.IsType(t, &survey.Confirm{}, questions[3].Prompt) +} + +func TestGetSurveyQuestionsForVersion_AboveSemver3_2_0(t *testing.T) { + version := semver.MustParse("3.3.0") + questions := getInitialSurveyQuestionsForVersion(version) + + assert.Len(t, questions, 4, "should return 4 questions for spec version > 3.2.0") + + assert.Equal(t, "subobjects", questions[3].Name) + assert.IsType(t, &survey.Confirm{}, questions[3].Prompt) +} From 4a0836c554e0120587fda4b7fffb9615c544987b Mon Sep 17 00:00:00 2001 From: Teresa Romero Date: Tue, 16 Sep 2025 10:36:59 +0200 Subject: [PATCH 04/13] add tests for createDataStreamDescriptorFromAnswers handling of Subobjects based on spec version --- cmd/create_data_stream_test.go | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/cmd/create_data_stream_test.go b/cmd/create_data_stream_test.go index 7a27b5ae8..90b1b0dae 100644 --- a/cmd/create_data_stream_test.go +++ b/cmd/create_data_stream_test.go @@ -41,3 +41,51 @@ func TestGetSurveyQuestionsForVersion_AboveSemver3_2_0(t *testing.T) { assert.Equal(t, "subobjects", questions[3].Name) assert.IsType(t, &survey.Confirm{}, questions[3].Prompt) } +func TestCreateDataStreamDescriptorFromAnswers_SubobjectsFalseForSpecVersionBelow3_2_0(t *testing.T) { + specVersion := semver.MustParse("3.1.0") + answers := newDataStreamAnswers{ + Name: "test_stream", + Title: "Test Stream", + Type: "logs", + Subobjects: false, + } + descriptor := createDataStreamDescriptorFromAnswers(answers, "/tmp/package", specVersion) + + assert.Equal(t, "test_stream", descriptor.Manifest.Name) + assert.Equal(t, "Test Stream", descriptor.Manifest.Title) + assert.Equal(t, "logs", descriptor.Manifest.Type) + assert.Equal(t, "/tmp/package", descriptor.PackageRoot) + assert.Nil(t, descriptor.Manifest.Elasticsearch) +} + +func TestCreateDataStreamDescriptorFromAnswers_SubobjectsFalseForSpecVersionGTE3_2_0(t *testing.T) { + specVersion := semver.MustParse("3.2.0") + answers := newDataStreamAnswers{ + Name: "test_stream", + Title: "Test Stream", + Type: "logs", + Subobjects: false, + } + descriptor := createDataStreamDescriptorFromAnswers(answers, "/tmp/package", specVersion) + + assert.NotNil(t, descriptor.Manifest.Elasticsearch) + assert.NotNil(t, descriptor.Manifest.Elasticsearch.IndexTemplate) + assert.NotNil(t, descriptor.Manifest.Elasticsearch.IndexTemplate.Mappings) + assert.False(t, descriptor.Manifest.Elasticsearch.IndexTemplate.Mappings.Subobjects) +} + +func TestCreateDataStreamDescriptorFromAnswers_SubobjectsTrueForSpecVersionGTE3_2_0(t *testing.T) { + specVersion := semver.MustParse("3.2.0") + answers := newDataStreamAnswers{ + Name: "test_stream", + Title: "Test Stream", + Type: "logs", + Subobjects: true, + } + descriptor := createDataStreamDescriptorFromAnswers(answers, "/tmp/package", specVersion) + + // Should not set Elasticsearch.IndexTemplate.Mappings.Subobjects + if descriptor.Manifest.Elasticsearch != nil && descriptor.Manifest.Elasticsearch.IndexTemplate != nil && descriptor.Manifest.Elasticsearch.IndexTemplate.Mappings != nil { + assert.NotEqual(t, false, descriptor.Manifest.Elasticsearch.IndexTemplate.Mappings.Subobjects) + } +} From b2d9ecc2ca8a63413a5a9b927cb6baf808a91c85 Mon Sep 17 00:00:00 2001 From: Teresa Romero Date: Tue, 16 Sep 2025 10:43:35 +0200 Subject: [PATCH 05/13] add copyright notice to create_data_stream_test.go --- cmd/create_data_stream_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/create_data_stream_test.go b/cmd/create_data_stream_test.go index 90b1b0dae..a8ccd17da 100644 --- a/cmd/create_data_stream_test.go +++ b/cmd/create_data_stream_test.go @@ -1,3 +1,7 @@ +// 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 ( From 4bcc8283811f5398c88cf09367a10f38daf8b981 Mon Sep 17 00:00:00 2001 From: Tere Date: Tue, 16 Sep 2025 13:52:57 +0200 Subject: [PATCH 06/13] Apply suggestion from @mrodm Co-authored-by: Mario Rodriguez Molins --- cmd/create_data_stream_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/create_data_stream_test.go b/cmd/create_data_stream_test.go index a8ccd17da..248c780cb 100644 --- a/cmd/create_data_stream_test.go +++ b/cmd/create_data_stream_test.go @@ -88,8 +88,8 @@ func TestCreateDataStreamDescriptorFromAnswers_SubobjectsTrueForSpecVersionGTE3_ } descriptor := createDataStreamDescriptorFromAnswers(answers, "/tmp/package", specVersion) - // Should not set Elasticsearch.IndexTemplate.Mappings.Subobjects - if descriptor.Manifest.Elasticsearch != nil && descriptor.Manifest.Elasticsearch.IndexTemplate != nil && descriptor.Manifest.Elasticsearch.IndexTemplate.Mappings != nil { - assert.NotEqual(t, false, descriptor.Manifest.Elasticsearch.IndexTemplate.Mappings.Subobjects) - } + require.NotNil(t, descriptor.Manifest.Elasticsearch) + require.NotNil(t, descriptor.Manifest.Elasticsearch.IndexTemplate) + require.NotNil(t, descriptor.Manifest.Elasticsearch.IndexTemplate.Mappings) + assert.False(t, descriptor.Manifest.Elasticsearch.IndexTemplate.Mappings.Subobjects) } From e4891f6811b2e17cc4892d0a20c3a4c179a64b0b Mon Sep 17 00:00:00 2001 From: Tere Date: Tue, 16 Sep 2025 13:53:11 +0200 Subject: [PATCH 07/13] Apply suggestion from @mrodm Co-authored-by: Mario Rodriguez Molins --- cmd/create_data_stream_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/create_data_stream_test.go b/cmd/create_data_stream_test.go index 248c780cb..8252827d5 100644 --- a/cmd/create_data_stream_test.go +++ b/cmd/create_data_stream_test.go @@ -72,9 +72,9 @@ func TestCreateDataStreamDescriptorFromAnswers_SubobjectsFalseForSpecVersionGTE3 } descriptor := createDataStreamDescriptorFromAnswers(answers, "/tmp/package", specVersion) - assert.NotNil(t, descriptor.Manifest.Elasticsearch) - assert.NotNil(t, descriptor.Manifest.Elasticsearch.IndexTemplate) - assert.NotNil(t, descriptor.Manifest.Elasticsearch.IndexTemplate.Mappings) + require.NotNil(t, descriptor.Manifest.Elasticsearch) + require.NotNil(t, descriptor.Manifest.Elasticsearch.IndexTemplate) + require.NotNil(t, descriptor.Manifest.Elasticsearch.IndexTemplate.Mappings) assert.False(t, descriptor.Manifest.Elasticsearch.IndexTemplate.Mappings.Subobjects) } From 3e68e2ea58610f54d341a539a851d07bba651d43 Mon Sep 17 00:00:00 2001 From: Tere Date: Tue, 16 Sep 2025 13:53:21 +0200 Subject: [PATCH 08/13] Apply suggestion from @mrodm Co-authored-by: Mario Rodriguez Molins --- cmd/create_data_stream_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/create_data_stream_test.go b/cmd/create_data_stream_test.go index 8252827d5..7ce4940b9 100644 --- a/cmd/create_data_stream_test.go +++ b/cmd/create_data_stream_test.go @@ -45,6 +45,7 @@ func TestGetSurveyQuestionsForVersion_AboveSemver3_2_0(t *testing.T) { assert.Equal(t, "subobjects", questions[3].Name) assert.IsType(t, &survey.Confirm{}, questions[3].Prompt) } + func TestCreateDataStreamDescriptorFromAnswers_SubobjectsFalseForSpecVersionBelow3_2_0(t *testing.T) { specVersion := semver.MustParse("3.1.0") answers := newDataStreamAnswers{ From a9a124fb36e22ba208fe4760dd452ec83494350f Mon Sep 17 00:00:00 2001 From: Tere Date: Tue, 16 Sep 2025 13:54:21 +0200 Subject: [PATCH 09/13] Apply suggestion from @mrodm Co-authored-by: Mario Rodriguez Molins --- cmd/create_data_stream_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/create_data_stream_test.go b/cmd/create_data_stream_test.go index 7ce4940b9..429004554 100644 --- a/cmd/create_data_stream_test.go +++ b/cmd/create_data_stream_test.go @@ -30,7 +30,7 @@ func TestGetSurveyQuestionsForVersion_EqualSemver3_2_0(t *testing.T) { version := semver.MustParse("3.2.0") questions := getInitialSurveyQuestionsForVersion(version) - assert.Len(t, questions, 4, "should return 4 questions for spec version >= 3.2.0") + require.Len(t, questions, 4, "should return 4 questions for spec version >= 3.2.0") assert.Equal(t, "subobjects", questions[3].Name) assert.IsType(t, &survey.Confirm{}, questions[3].Prompt) From 4621f9a344396d2ae3b742fe7b9005a88171ee77 Mon Sep 17 00:00:00 2001 From: Tere Date: Tue, 16 Sep 2025 13:54:36 +0200 Subject: [PATCH 10/13] Apply suggestion from @mrodm Co-authored-by: Mario Rodriguez Molins --- cmd/create_data_stream_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/create_data_stream_test.go b/cmd/create_data_stream_test.go index 429004554..c171f8a50 100644 --- a/cmd/create_data_stream_test.go +++ b/cmd/create_data_stream_test.go @@ -40,7 +40,7 @@ func TestGetSurveyQuestionsForVersion_AboveSemver3_2_0(t *testing.T) { version := semver.MustParse("3.3.0") questions := getInitialSurveyQuestionsForVersion(version) - assert.Len(t, questions, 4, "should return 4 questions for spec version > 3.2.0") + require.Len(t, questions, 4, "should return 4 questions for spec version > 3.2.0") assert.Equal(t, "subobjects", questions[3].Name) assert.IsType(t, &survey.Confirm{}, questions[3].Prompt) From 21a3eb4aaae560603af393a6dedeb99b399d17db Mon Sep 17 00:00:00 2001 From: Tere Date: Tue, 16 Sep 2025 13:55:06 +0200 Subject: [PATCH 11/13] Apply suggestion from @mrodm Co-authored-by: Mario Rodriguez Molins --- cmd/create_data_stream_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/create_data_stream_test.go b/cmd/create_data_stream_test.go index c171f8a50..bdb01e0ef 100644 --- a/cmd/create_data_stream_test.go +++ b/cmd/create_data_stream_test.go @@ -16,7 +16,7 @@ func TestGetSurveyQuestionsForVersion_BelowSemver3_2_0(t *testing.T) { version := semver.MustParse("3.1.9") questions := getInitialSurveyQuestionsForVersion(version) - assert.Len(t, questions, 3, "should return 3 questions for spec version < 3.2.0") + require.Len(t, questions, 3, "should return 3 questions for spec version < 3.2.0") assert.Equal(t, "name", questions[0].Name) assert.IsType(t, &survey.Input{}, questions[0].Prompt) From 2682da956c1baa4ba45133d94c37ec4786cbe500 Mon Sep 17 00:00:00 2001 From: Teresa Romero Date: Tue, 16 Sep 2025 14:53:08 +0200 Subject: [PATCH 12/13] Add missing require import in create_data_stream_test.go --- cmd/create_data_stream_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/create_data_stream_test.go b/cmd/create_data_stream_test.go index bdb01e0ef..0dd5ade86 100644 --- a/cmd/create_data_stream_test.go +++ b/cmd/create_data_stream_test.go @@ -10,6 +10,7 @@ import ( "github.com/AlecAivazis/survey/v2" "github.com/Masterminds/semver/v3" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestGetSurveyQuestionsForVersion_BelowSemver3_2_0(t *testing.T) { From b9ec1f0760e437d10647597aeba4ebcca60c1135 Mon Sep 17 00:00:00 2001 From: Teresa Romero Date: Wed, 17 Sep 2025 12:29:14 +0200 Subject: [PATCH 13/13] Fix assertion for subobjects true case --- cmd/create_data_stream_test.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cmd/create_data_stream_test.go b/cmd/create_data_stream_test.go index 0dd5ade86..8c25e12db 100644 --- a/cmd/create_data_stream_test.go +++ b/cmd/create_data_stream_test.go @@ -90,8 +90,5 @@ func TestCreateDataStreamDescriptorFromAnswers_SubobjectsTrueForSpecVersionGTE3_ } descriptor := createDataStreamDescriptorFromAnswers(answers, "/tmp/package", specVersion) - require.NotNil(t, descriptor.Manifest.Elasticsearch) - require.NotNil(t, descriptor.Manifest.Elasticsearch.IndexTemplate) - require.NotNil(t, descriptor.Manifest.Elasticsearch.IndexTemplate.Mappings) - assert.False(t, descriptor.Manifest.Elasticsearch.IndexTemplate.Mappings.Subobjects) + require.Nil(t, descriptor.Manifest.Elasticsearch) }