Skip to content
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

Some fixes and refactors around profile and stack resources #1055

Closed
wants to merge 43 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
02a879e
Generate stack files
jsoriano May 3, 2022
97a3ce7
It builds
jsoriano May 3, 2022
935a90d
Fix docker compose file
jsoriano May 3, 2022
a1abf89
Merge remote-tracking branch 'origin/main' into profile-resources
jsoriano Nov 28, 2022
36af266
Fix profile creation
jsoriano Nov 29, 2022
6096b2d
Allow to select the current profile
jsoriano Nov 29, 2022
987028d
Move kibana healthcheck to stack
jsoriano Nov 29, 2022
8a8f8da
Remove code for service deployers from installation
jsoriano Nov 29, 2022
5fefa3c
Move service tokens and geoip to profile
jsoriano Nov 29, 2022
6a89b90
Fix tests
jsoriano Nov 29, 2022
ae24022
Unify code to load profiles in stack subcommands
jsoriano Nov 30, 2022
3d73ed7
Move stack files to stack package
jsoriano Nov 30, 2022
e164209
Add TODO
jsoriano Nov 30, 2022
01f754b
Use public go-resource
jsoriano Dec 1, 2022
dd40411
Merge remote-tracking branch 'origin/main' into profile-resources
jsoriano Dec 1, 2022
d22311c
Linting
jsoriano Dec 1, 2022
5c31959
Fix username and password
jsoriano Dec 1, 2022
200b4d7
Compose provider
jsoriano Dec 1, 2022
57c3e97
Persist stack configuration
jsoriano Dec 1, 2022
a24368c
Create a cluster
jsoriano Dec 1, 2022
ebf5d95
Cloud deployment creation
jsoriano Dec 2, 2022
592d610
Tear down and status
jsoriano Dec 2, 2022
118362e
Wait for cluster to be ready
jsoriano Dec 2, 2022
280b0ab
Print urls only when available
jsoriano Dec 2, 2022
092eeee
Get provider from profile, not from flag, except for stack up
jsoriano Dec 2, 2022
210a2f1
Return hard-coded shellinit default for backwards compatibility
jsoriano Dec 2, 2022
315dd92
Fix go mod
jsoriano Dec 5, 2022
7737fec
Linting
jsoriano Dec 5, 2022
1ef359b
Merge remote-tracking branch 'origin/main' into profile-resources
jsoriano Dec 14, 2022
8b8e82a
Merge remote-tracking branch 'origin/main' into profile-resources
jsoriano Dec 19, 2022
060b76f
Fix nil pointer dereference
jsoriano Dec 19, 2022
ed1e62b
Update go-resource
jsoriano Dec 19, 2022
aa10373
Merge remote-tracking branch 'origin/main' into profile-resources
jsoriano Dec 20, 2022
b5dbf6a
Update gobuffalo/packr
jsoriano Dec 20, 2022
d400e9d
Fix custom agent deployer
jsoriano Dec 21, 2022
a17fcdd
Add variant for Kibana >= 8.7.0 with Fleet experimental toggles enabl…
jsoriano Feb 1, 2023
d964ab5
Merge remote-tracking branch 'origin/main' into profile-resources
jsoriano Feb 3, 2023
12e4139
Fix terraform deployer
jsoriano Feb 9, 2023
3657f9f
Merge remote-tracking branch 'origin/main' into profile-resources
jsoriano Feb 9, 2023
1b9fb1e
Fix terraform deployer dockerfile
jsoriano Feb 9, 2023
77bc1d5
Remove unused kibana config
jsoriano Feb 9, 2023
0655713
Fix linting
jsoriano Feb 9, 2023
b5b5b26
Fix creation of parent directories
jsoriano Feb 9, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 51 additions & 17 deletions cmd/profiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (

"github.com/elastic/elastic-package/internal/cobraext"
"github.com/elastic/elastic-package/internal/configuration/locations"
"github.com/elastic/elastic-package/internal/environment"
"github.com/elastic/elastic-package/internal/install"
"github.com/elastic/elastic-package/internal/profile"
)

Expand All @@ -26,9 +26,6 @@ const jsonFormat = "json"
// tableFormat is the format for table output
const tableFormat = "table"

// profileNameEnvVar is the name of the environment variable to set the default profile
var profileNameEnvVar = environment.WithElasticPackagePrefix("PROFILE")

func setupProfilesCommand() *cobraext.Command {
profilesLongDescription := `Use this command to add, remove, and manage multiple config profiles.

Expand Down Expand Up @@ -65,12 +62,16 @@ User profiles are not overwritten on upgrade of elastic-stack, and can be freely
return errors.Wrapf(err, "error creating profile %s from profile %s", newProfileName, fromName)
}

fmt.Printf("Created profile %s from %s.\n", newProfileName, fromName)
if fromName == "" {
fmt.Printf("Created profile %s.\n", newProfileName)
} else {
fmt.Printf("Created profile %s from %s.\n", newProfileName, fromName)
}

return nil
},
}
profileNewCommand.Flags().String(cobraext.ProfileFromFlagName, "default", cobraext.ProfileFromFlagDescription)
profileNewCommand.Flags().String(cobraext.ProfileFromFlagName, "", cobraext.ProfileFromFlagDescription)

profileDeleteCommand := &cobra.Command{
Use: "delete",
Expand Down Expand Up @@ -104,10 +105,14 @@ User profiles are not overwritten on upgrade of elastic-stack, and can be freely
if err != nil {
return errors.Wrap(err, "error listing all profiles")
}
if len(profileList) == 0 {
fmt.Println("There are no profiles yet.")
return nil
}

format, err := cmd.Flags().GetString(cobraext.ProfileFormatFlagName)
if err != nil {
return cobraext.FlagParsingError(err, cobraext.ProfileFromFlagName)
return cobraext.FlagParsingError(err, cobraext.ProfileFormatFlagName)
}

switch format {
Expand All @@ -122,7 +127,45 @@ User profiles are not overwritten on upgrade of elastic-stack, and can be freely
}
profileListCommand.Flags().String(cobraext.ProfileFormatFlagName, tableFormat, cobraext.ProfileFormatFlagDescription)

profileCommand.AddCommand(profileNewCommand, profileDeleteCommand, profileListCommand)
profileUseCommand := &cobra.Command{
Use: "use",
Short: "Sets the profile to use when no other is specified",
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return errors.New("use requires an argument")
}
profileName := args[0]

_, err := profile.LoadProfile(profileName)
if err != nil {
return fmt.Errorf("cannot use profile %q: %v", profileName, err)
}

location, err := locations.NewLocationManager()
if err != nil {
return fmt.Errorf("error fetching profile: %w", err)
}

config, err := install.Configuration()
if err != nil {
return fmt.Errorf("failed to load current configuration: %w", err)
}
config.SetCurrentProfile(profileName)

err = install.WriteConfigFile(location, config)
if err != nil {
return fmt.Errorf("failed to store configuration: %w", err)
}
return nil
},
}

profileCommand.AddCommand(
profileNewCommand,
profileDeleteCommand,
profileListCommand,
profileUseCommand,
)

return cobraext.NewCommand(profileCommand, cobraext.ContextGlobal)
}
Expand Down Expand Up @@ -175,15 +218,6 @@ func profileToList(profiles []profile.Metadata) [][]string {
return profileList
}

func lookupEnv() string {
env := os.Getenv(profileNameEnvVar)
if env == "" {
return profile.DefaultProfile
}
return env

}

func availableProfilesAsAList() ([]string, error) {
loc, err := locations.NewLocationManager()
if err != nil {
Expand Down
166 changes: 99 additions & 67 deletions cmd/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ By default the latest released version of the stack is spun up but it is possibl

Be aware that a common issue while trying to boot up the stack is that your Docker environments settings are too low in terms of memory threshold.

To ęxpose 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.
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.

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).`

Expand Down Expand Up @@ -73,37 +73,24 @@ func setupStackCommand() *cobraext.Command {
return cobraext.FlagParsingError(err, cobraext.StackVersionFlagName)
}

profileName, err := cmd.Flags().GetString(cobraext.ProfileFlagName)
profile, err := getProfileFlag(cmd)
if err != nil {
return cobraext.FlagParsingError(err, cobraext.ProfileFlagName)
}

userProfile, err := profile.LoadProfile(profileName)
if errors.Is(err, profile.ErrNotAProfile) {
pList, err := availableProfilesAsAList()
if err != nil {
return errors.Wrap(err, "error listing known profiles")
}
return fmt.Errorf("%s is not a valid profile, known profiles are: %s", profileName, pList)
}
if err != nil {
return errors.Wrap(err, "error loading profile")
return err
}

// Print information before starting the stack, for cases where
// this is executed in the foreground, without daemon mode.
cmd.Printf("Using profile %s.\n", userProfile.ProfilePath)
cmd.Println(`Remember to load stack environment variables using 'eval "$(elastic-package stack shellinit)"'.`)
err = printInitConfig(cmd, userProfile)
provider, err := getProviderFromProfile(cmd, profile, true)
if err != nil {
return err
}

err = stack.BootUp(stack.Options{
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{
DaemonMode: daemonMode,
StackVersion: stackVersion,
Services: services,
Profile: userProfile,
Profile: profile,
Printer: cmd,
})
if err != nil {
return errors.Wrap(err, "booting up the stack failed")
Expand All @@ -117,33 +104,27 @@ func setupStackCommand() *cobraext.Command {
upCommand.Flags().StringSliceP(cobraext.StackServicesFlagName, "s", nil,
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, ", ")))

downCommand := &cobra.Command{
Use: "down",
Short: "Take down the stack",
RunE: func(cmd *cobra.Command, args []string) error {
cmd.Println("Take down the Elastic stack")

profileName, err := cmd.Flags().GetString(cobraext.ProfileFlagName)
profile, err := getProfileFlag(cmd)
if err != nil {
return cobraext.FlagParsingError(err, cobraext.ProfileFlagName)
}

userProfile, err := profile.LoadProfile(profileName)
if errors.Is(err, profile.ErrNotAProfile) {
pList, err := availableProfilesAsAList()
if err != nil {
return errors.Wrap(err, "error listing known profiles")
}
return fmt.Errorf("%s is not a valid profile, known profiles are: %s", profileName, pList)
return err
}

provider, err := getProviderFromProfile(cmd, profile, false)
if err != nil {
return errors.Wrap(err, "error loading profile")
return err
}

err = stack.TearDown(stack.Options{
Profile: userProfile,
err = provider.TearDown(stack.Options{
Profile: profile,
Printer: cmd,
})
if err != nil {
return errors.Wrap(err, "tearing down the stack failed")
Expand All @@ -160,24 +141,25 @@ func setupStackCommand() *cobraext.Command {
RunE: func(cmd *cobra.Command, args []string) error {
cmd.Println("Update the Elastic stack")

profileName, err := cmd.Flags().GetString(cobraext.ProfileFlagName)
profile, err := getProfileFlag(cmd)
if err != nil {
return cobraext.FlagParsingError(err, cobraext.ProfileFlagName)
return err
}

profile, err := profile.LoadProfile(profileName)
provider, err := getProviderFromProfile(cmd, profile, false)
if err != nil {
return errors.Wrap(err, "error loading profile")
return err
}

stackVersion, err := cmd.Flags().GetString(cobraext.StackVersionFlagName)
if err != nil {
return cobraext.FlagParsingError(err, cobraext.StackVersionFlagName)
}

err = stack.Update(stack.Options{
err = provider.Update(stack.Options{
StackVersion: stackVersion,
Profile: profile,
Printer: cmd,
})
if err != nil {
return errors.Wrap(err, "failed updating the stack images")
Expand All @@ -193,11 +175,6 @@ func setupStackCommand() *cobraext.Command {
Use: "shellinit",
Short: "Export environment variables",
RunE: func(cmd *cobra.Command, args []string) error {
profileName, err := cmd.Flags().GetString(cobraext.ProfileFlagName)
if err != nil {
return cobraext.FlagParsingError(err, cobraext.ProfileFlagName)
}

shellName, err := cmd.Flags().GetString(cobraext.ShellInitShellFlagName)
if err != nil {
return cobraext.FlagParsingError(err, cobraext.ShellInitShellFlagName)
Expand All @@ -207,9 +184,9 @@ func setupStackCommand() *cobraext.Command {
fmt.Fprintf(cmd.OutOrStderr(), "Detected shell: %s\n", shellName)
}

profile, err := profile.LoadProfile(profileName)
profile, err := getProfileFlag(cmd)
if err != nil {
return errors.Wrap(err, "error loading profile")
return err
}

shellCode, err := stack.ShellInit(profile, shellName)
Expand All @@ -232,17 +209,17 @@ func setupStackCommand() *cobraext.Command {
return cobraext.FlagParsingError(err, cobraext.StackDumpOutputFlagName)
}

profileName, err := cmd.Flags().GetString(cobraext.ProfileFlagName)
profile, err := getProfileFlag(cmd)
if err != nil {
return cobraext.FlagParsingError(err, cobraext.ProfileFlagName)
return err
}

profile, err := profile.LoadProfile(profileName)
provider, err := getProviderFromProfile(cmd, profile, false)
if err != nil {
return errors.Wrap(err, "error loading profile")
return err
}

target, err := stack.Dump(stack.DumpOptions{
target, err := provider.Dump(stack.DumpOptions{
Output: output,
Profile: profile,
})
Expand All @@ -262,7 +239,20 @@ func setupStackCommand() *cobraext.Command {
Use: "status",
Short: "Show status of the stack services",
RunE: func(cmd *cobra.Command, args []string) error {
servicesStatus, err := stack.Status()
profile, err := getProfileFlag(cmd)
if err != nil {
return err
}

provider, err := getProviderFromProfile(cmd, profile, false)
if err != nil {
return err
}

servicesStatus, err := provider.Status(stack.Options{
Profile: profile,
Printer: cmd,
})
if err != nil {
return errors.Wrap(err, "failed getting stack status")
}
Expand All @@ -278,7 +268,7 @@ func setupStackCommand() *cobraext.Command {
Short: "Manage the Elastic stack",
Long: stackLongDescription,
}
cmd.PersistentFlags().StringP(cobraext.ProfileFlagName, "p", lookupEnv(), fmt.Sprintf(cobraext.ProfileFlagDescription, profileNameEnvVar))
cmd.PersistentFlags().StringP(cobraext.ProfileFlagName, "p", "", fmt.Sprintf(cobraext.ProfileFlagDescription, install.ProfileNameEnvVar))
cmd.AddCommand(
upCommand,
downCommand,
Expand Down Expand Up @@ -317,18 +307,6 @@ func validateServicesFlag(services []string) error {
return nil
}

func printInitConfig(cmd *cobra.Command, profile *profile.Profile) error {
initConfig, err := stack.StackInitConfig(profile)
if err != nil {
return nil
}
cmd.Printf("Elasticsearch host: %s\n", initConfig.ElasticsearchHostPort)
cmd.Printf("Kibana host: %s\n", initConfig.KibanaHostPort)
cmd.Printf("Username: %s\n", initConfig.ElasticsearchUsername)
cmd.Printf("Password: %s\n", initConfig.ElasticsearchPassword)
return nil
}

func printStatus(cmd *cobra.Command, servicesStatus []stack.ServiceStatus) {
if len(servicesStatus) == 0 {
cmd.Printf(" - No service running\n")
Expand All @@ -343,3 +321,57 @@ func printStatus(cmd *cobra.Command, servicesStatus []stack.ServiceStatus) {
t.SetStyle(table.StyleRounded)
cmd.Println(t.Render())
}

func getProfileFlag(cmd *cobra.Command) (*profile.Profile, error) {
profileName, err := cmd.Flags().GetString(cobraext.ProfileFlagName)
if err != nil {
return nil, cobraext.FlagParsingError(err, cobraext.ProfileFlagName)
}
if profileName == "" {
config, err := install.Configuration()
if err != nil {
return nil, fmt.Errorf("cannot read configuration: %w", err)
}
profileName = config.CurrentProfile()
}

p, err := profile.LoadProfile(profileName)
if errors.Is(err, profile.ErrNotAProfile) {
list, err := availableProfilesAsAList()
if err != nil {
return nil, errors.Wrap(err, "error listing known profiles")
}
if len(list) == 0 {
return nil, fmt.Errorf("%s is not a valid profile", profileName)
}
return nil, fmt.Errorf("%s is not a valid profile, known profiles are: %s", profileName, strings.Join(list, ", "))
}
if err != nil {
return nil, errors.Wrap(err, "error loading profile")
}

return p, nil
}

func getProviderFromProfile(cmd *cobra.Command, profile *profile.Profile, checkFlag bool) (stack.Provider, error) {
var providerName = stack.DefaultProvider
stackConfig, err := stack.LoadConfig(profile)
if err != nil {
return nil, err
}
if stackConfig.Provider != "" {
providerName = stackConfig.Provider
}

if checkFlag {
providerFlag, err := cmd.Flags().GetString(cobraext.StackProviderFlagName)
if err != nil {
return nil, cobraext.FlagParsingError(err, cobraext.StackProviderFlagName)
}
if providerFlag != "" {
providerName = providerFlag
}
}

return stack.BuildProvider(providerName, profile)
}
Loading