diff --git a/README.md b/README.md index 53d17daff7..8b4918544f 100644 --- a/README.md +++ b/README.md @@ -461,6 +461,8 @@ To expose local packages in the Package Registry, build them first and boot up t For details on how to connect the service with the Elastic stack, see the [service command](https://github.com/elastic/elastic-package/blob/main/README.md#elastic-package-service). +You can customize your stack using profile settings, see [Elastic Package profiles](https://github.com/elastic/elastic-package/blob/main/README.md#elastic-package-profiles-1) section. These settings can be also overriden with the --parameter flag. Settings configured this way are not persisted. + ### `elastic-package stack update` _Context: global_ diff --git a/cmd/stack.go b/cmd/stack.go index 2eb110ae2c..fd52ed646f 100644 --- a/cmd/stack.go +++ b/cmd/stack.go @@ -44,7 +44,9 @@ Be aware that a common issue while trying to boot up the stack is that your Dock To expose local packages in the Package Registry, build them first and boot up the stack from inside of the Git repository containing the package (e.g. elastic/integrations). They will be copied to the development stack (~/.elastic-package/stack/development) and used to build a custom Docker image of the Package Registry. Starting with Elastic stack version >= 8.7.0, it is not mandatory to be available local packages in the Package Registry to run the tests. -For details on how to connect the service with the Elastic stack, see the [service command](https://github.com/elastic/elastic-package/blob/main/README.md#elastic-package-service).` +For details on how to connect the service with the Elastic stack, see the [service command](https://github.com/elastic/elastic-package/blob/main/README.md#elastic-package-service). + +You can customize your stack using profile settings, see [Elastic Package profiles](https://github.com/elastic/elastic-package/blob/main/README.md#elastic-package-profiles-1) section. These settings can be also overriden with the --parameter flag. Settings configured this way are not persisted.` func setupStackCommand() *cobraext.Command { upCommand := &cobra.Command{ @@ -86,6 +88,15 @@ func setupStackCommand() *cobraext.Command { return err } + // Parameters provided through the CLI are not persisted. + // Stack providers can get them with `profile.Config`, and they + // need to handle and store them if they need it. + userParameters, err := cobraext.GetStackUserParameterFlags(cmd) + if err != nil { + return err + } + profile.RuntimeOverrides(userParameters) + cmd.Printf("Using profile %s.\n", profile.ProfilePath) cmd.Println(`Remember to load stack environment variables using 'eval "$(elastic-package stack shellinit)"'.`) err = provider.BootUp(stack.Options{ @@ -108,6 +119,7 @@ func setupStackCommand() *cobraext.Command { fmt.Sprintf(cobraext.StackServicesFlagDescription, strings.Join(availableServicesAsList(), ","))) upCommand.Flags().StringP(cobraext.StackVersionFlagName, "", install.DefaultStackVersion, cobraext.StackVersionFlagDescription) upCommand.Flags().String(cobraext.StackProviderFlagName, "", fmt.Sprintf(cobraext.StackProviderFlagDescription, strings.Join(stack.SupportedProviders, ", "))) + upCommand.Flags().StringSliceP(cobraext.StackUserParameterFlagName, cobraext.StackUserParameterFlagShorthand, nil, cobraext.StackUserParameterDescription) downCommand := &cobra.Command{ Use: "down", diff --git a/internal/cobraext/flags.go b/internal/cobraext/flags.go index a7eb785eeb..3e7cde9d8d 100644 --- a/internal/cobraext/flags.go +++ b/internal/cobraext/flags.go @@ -166,6 +166,10 @@ const ( StackDumpOutputFlagName = "output" StackDumpOutputFlagDescription = "output location for the stack dump" + StackUserParameterFlagName = "parameter" + StackUserParameterFlagShorthand = "U" + StackUserParameterDescription = "optional parameter for the stack provider, as key=value" + StatusKibanaVersionFlagName = "kibana-version" StatusKibanaVersionFlagDescription = "show packages for the given kibana version" diff --git a/internal/cobraext/profiles.go b/internal/cobraext/profiles.go index bade86a9fe..2710c87273 100644 --- a/internal/cobraext/profiles.go +++ b/internal/cobraext/profiles.go @@ -90,3 +90,22 @@ func GetStackProviderFromProfile(cmd *cobra.Command, profile *profile.Profile, c return stack.BuildProvider(providerName, profile) } + +// GetStackUserParameterFlags returns the parameters defined by the user in the command line +func GetStackUserParameterFlags(cmd *cobra.Command) (map[string]string, error) { + parameters, err := cmd.Flags().GetStringSlice(StackUserParameterFlagName) + if err != nil { + return nil, FlagParsingError(err, StackUserParameterFlagName) + } + + values := make(map[string]string) + for _, p := range parameters { + k, v, valid := strings.Cut(p, "=") + if !valid { + return nil, fmt.Errorf("invalid format for user parameter, expected key=value, found %q", p) + } + values[k] = v + } + + return values, nil +} diff --git a/internal/profile/profile.go b/internal/profile/profile.go index 2501072899..ba5d8ea9a4 100644 --- a/internal/profile/profile.go +++ b/internal/profile/profile.go @@ -136,7 +136,8 @@ type Profile struct { ProfilePath string ProfileName string - config config + config config + overrides map[string]string } // Path returns an absolute path to the given file @@ -147,11 +148,22 @@ func (profile Profile) Path(names ...string) string { // Config returns a configuration setting, or its default if setting not found func (profile Profile) Config(name string, def string) string { - v, found := profile.config.get(name) - if !found { - return def + v, found := profile.overrides[name] + if found { + return v } - return v + + v, found = profile.config.get(name) + if found { + return v + } + + return def +} + +// RuntimeOverrides defines configuration overrides for the current session. +func (profile *Profile) RuntimeOverrides(overrides map[string]string) { + profile.overrides = overrides } // ErrNotAProfile is returned in cases where we don't have a valid profile directory