-
Notifications
You must be signed in to change notification settings - Fork 129
New stack provider for environment variables #2298
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
Merged
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit
Hold shift + click to select a range
b40cd78
Initial code, and removal of reset credentials
jsoriano 47532c3
Assume 410 status gone is ok for elasticsearch
jsoriano b9e112f
Refactor client tests so they don't try to use the configured client …
jsoriano a44469d
Merge remote-tracking branch 'origin/main' into api-key-support
jsoriano cd980a6
Refactor shellinit
jsoriano 5b41cd9
Use API key in stack clients
jsoriano 12aaebe
Ignore errors when getting logs from a non-local elasticsearch
jsoriano cce94bd
Share logic to start local services
jsoriano b3b1e76
Fix spaces in logstash config
jsoriano 3797d20
Prepare interfaces to create policies and getting enrollment tokens
jsoriano 04e22d2
Initial enrollment works
jsoriano 8f17940
Tear down
jsoriano 83beb64
Merge remote-tracking branch 'origin/main' into api-key-support
jsoriano 290c6d9
Fix tear down
jsoriano be6dd46
Fix system tests
jsoriano 6169e15
Get kibana host directly from the config?
jsoriano 2e12e02
Fix stack up with logstash
jsoriano f8d1cee
Fix logstash with api keys
jsoriano 9a24380
Better idempotence
jsoriano c4822eb
Remove unused variable
jsoriano 7295a2e
Revert change in initialization of kibana host
jsoriano 0ec34f2
Implement status for environment provider
jsoriano 5f000c5
Try to support local Fleet Server for remote stacks
jsoriano 0a188b4
Merge remote-tracking branch 'origin/main' into api-key-support
jsoriano 184209e
Fix certifictes on agent deployer
jsoriano d4d32ac
Fix fleet status when fleet server is locally managed
jsoriano 038549c
Reuse existing fleet server hosts
jsoriano 91f2b2d
Add options for API key in clients
jsoriano b854ca9
Merge remote-tracking branch 'origin/main' into api-key-support
jsoriano 0d1a1b2
Merge branch 'api-key-clients' into api-key-support
jsoriano 74f2049
Add host.docker.internal to the local services
jsoriano bbbc671
Merge remote-tracking branch 'origin/main' into api-key-support
jsoriano 0095a32
Polish status
jsoriano f60e15d
Add output id to stack config
jsoriano 0c407a0
Fix error formatting value
jsoriano f53325d
Merge remote-tracking branch 'origin/main' into api-key-support
jsoriano dcc5e0b
Merge remote-tracking branch 'origin/main' into api-key-support
jsoriano c65452b
Merge remote-tracking branch 'origin/main' into api-key-support
jsoriano ffeb24c
Remove unused API keys
jsoriano 1079df7
Fix issues after merge
jsoriano 699623e
Fix kubernetes agent deployer
jsoriano 699cb0f
Add tech preview warning
jsoriano 52ec637
Merge remote-tracking branch 'origin/main' into api-key-support
jsoriano aa71071
Merge remote-tracking branch 'origin/main' into api-key-support
jsoriano d728838
Pass context to call to get enrollment tokens
jsoriano 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
Share logic to start local services
- Loading branch information
commit cce94bd4630a452365cb008f9bde785576f92c23
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
File renamed without changes.
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
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
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,128 @@ | ||
| // 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 stack | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| "os" | ||
|
|
||
| "github.com/elastic/elastic-package/internal/elasticsearch" | ||
| "github.com/elastic/elastic-package/internal/kibana" | ||
| "github.com/elastic/elastic-package/internal/profile" | ||
| ) | ||
|
|
||
| type environmentProvider struct { | ||
| kibana *kibana.Client | ||
| elasticsearch *elasticsearch.Client | ||
| } | ||
|
|
||
| func newEnvironmentProvider(profile *profile.Profile) (*environmentProvider, error) { | ||
| return &environmentProvider{}, nil | ||
| } | ||
|
|
||
| // BootUp configures the profile to use as stack the one indicated using environment variables. | ||
| func (p *environmentProvider) BootUp(ctx context.Context, options Options) error { | ||
| config := Config{ | ||
| Provider: ProviderEnvironment, | ||
| ElasticsearchAPIKey: os.Getenv(ElasticsearchAPIKeyEnv), | ||
| ElasticsearchHost: os.Getenv(ElasticsearchHostEnv), | ||
| ElasticsearchUsername: os.Getenv(ElasticsearchUsernameEnv), | ||
| ElasticsearchPassword: os.Getenv(ElasticsearchPasswordEnv), | ||
| KibanaHost: os.Getenv(KibanaHostEnv), | ||
| CACertFile: os.Getenv(CACertificateEnv), | ||
|
|
||
| Parameters: make(map[string]string), | ||
| } | ||
| if err := requiredEnv(config.ElasticsearchHost, ElasticsearchHostEnv); err != nil { | ||
| return err | ||
| } | ||
| if err := requiredEnv(config.KibanaHost, KibanaHostEnv); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| err := p.initClients() | ||
| if err != nil { | ||
| return err | ||
| } | ||
| // TODO: Migrate from serverless variables. | ||
| config.Parameters[ParamServerlessFleetURL], err = p.kibana.DefaultFleetServerURL(ctx) | ||
| if err != nil { | ||
| return fmt.Errorf("cannot discover default fleet server URL: %w", err) | ||
| } | ||
|
|
||
| localServices := &localServicesManager{ | ||
| profile: options.Profile, | ||
| } | ||
| err = localServices.start(ctx, options, config) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to start local services: %w", err) | ||
| } | ||
|
|
||
| err = storeConfig(options.Profile, config) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to store config: %w", err) | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func requiredEnv(value string, envVarName string) error { | ||
| if value == "" { | ||
| return fmt.Errorf("environment variable %s required", envVarName) | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| func (p *environmentProvider) initClients() error { | ||
| kibana, err := NewKibanaClient() | ||
| if err != nil { | ||
| return fmt.Errorf("cannot create Kibana client: %w", err) | ||
| } | ||
| p.kibana = kibana | ||
|
|
||
| elasticsearch, err := NewElasticsearchClient() | ||
| if err != nil { | ||
| return fmt.Errorf("cannot create Elasticsearch client: %w", err) | ||
| } | ||
| p.elasticsearch = elasticsearch | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| // TearDown stops and/or removes a stack. | ||
| func (p *environmentProvider) TearDown(ctx context.Context, options Options) error { | ||
| localServices := &localServicesManager{ | ||
| profile: options.Profile, | ||
| } | ||
| err := localServices.destroy(ctx) | ||
| if err != nil { | ||
| return fmt.Errorf("failed ot destroy local services: %v", err) | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| // Update updates resources associated to a stack. | ||
| func (p *environmentProvider) Update(context.Context, Options) error { | ||
| return fmt.Errorf("not implemented") | ||
| } | ||
|
|
||
| // Dump dumps data for debug purpouses. | ||
| func (p *environmentProvider) Dump(ctx context.Context, options DumpOptions) ([]DumpResult, error) { | ||
| for _, service := range options.Services { | ||
| if service != "elastic-agent" { | ||
| return nil, &ErrNotImplemented{ | ||
| Operation: fmt.Sprintf("logs dump for service %s", service), | ||
| Provider: ProviderServerless, | ||
| } | ||
| } | ||
| } | ||
| return Dump(ctx, options) | ||
| } | ||
|
|
||
| // Status obtains status information of the stack. | ||
| func (p *environmentProvider) Status(context.Context, Options) ([]ServiceStatus, error) { | ||
| return nil, fmt.Errorf("not implemented") | ||
| } |
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
File renamed without changes.
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,117 @@ | ||
| // 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 stack | ||
|
|
||
| import ( | ||
| "context" | ||
| "errors" | ||
| "fmt" | ||
| "strings" | ||
|
|
||
| "github.com/elastic/elastic-package/internal/compose" | ||
| "github.com/elastic/elastic-package/internal/docker" | ||
| "github.com/elastic/elastic-package/internal/profile" | ||
| ) | ||
|
|
||
| type localServicesManager struct { | ||
| profile *profile.Profile | ||
| } | ||
|
|
||
| func (m *localServicesManager) start(ctx context.Context, options Options, config Config) error { | ||
| err := applyLocalResources(m.profile, options.StackVersion, config) | ||
| if err != nil { | ||
| return fmt.Errorf("could not initialize compose files for local services: %w", err) | ||
| } | ||
|
|
||
| project, err := m.composeProject() | ||
| if err != nil { | ||
| return fmt.Errorf("could not initialize local services compose project") | ||
| } | ||
|
|
||
| opts := compose.CommandOptions{ | ||
| ExtraArgs: []string{}, | ||
| } | ||
| err = project.Build(ctx, opts) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to build images for local services: %w", err) | ||
| } | ||
|
|
||
| if options.DaemonMode { | ||
| opts.ExtraArgs = append(opts.ExtraArgs, "-d") | ||
| } | ||
| if err := project.Up(ctx, opts); err != nil { | ||
| // At least starting on 8.6.0, fleet-server may be reconfigured or | ||
| // restarted after being healthy. If elastic-agent tries to enroll at | ||
| // this moment, it fails inmediately, stopping and making `docker-compose up` | ||
| // to fail too. | ||
| // As a workaround, try to give another chance to docker-compose if only | ||
| // elastic-agent failed. | ||
| if onlyElasticAgentFailed(ctx, options) && !errors.Is(err, context.Canceled) { | ||
| fmt.Println("Elastic Agent failed to start, trying again.") | ||
| if err := project.Up(ctx, opts); err != nil { | ||
| return fmt.Errorf("failed to start local services: %w", err) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func (m *localServicesManager) destroy(ctx context.Context) error { | ||
| project, err := m.composeProject() | ||
| if err != nil { | ||
| return fmt.Errorf("could not initialize local services compose project") | ||
| } | ||
|
|
||
| opts := compose.CommandOptions{ | ||
| // Remove associated volumes. | ||
| ExtraArgs: []string{"--volumes", "--remove-orphans"}, | ||
| } | ||
| err = project.Down(ctx, opts) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to destroy local services: %w", err) | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| func (m *localServicesManager) visitDescriptions(serviceFunc func(docker.ContainerDescription) error) error { | ||
| // query directly to docker to avoid load environment variables (e.g. STACK_VERSION_VARIANT) and profiles | ||
| project := m.composeProjectName() | ||
| containerIDs, err := docker.ContainerIDsWithLabel(projectLabelDockerCompose, project) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| if len(containerIDs) == 0 { | ||
| return nil | ||
| } | ||
|
|
||
| containerDescriptions, err := docker.InspectContainers(containerIDs...) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| for _, containerDescription := range containerDescriptions { | ||
| serviceName := containerDescription.Config.Labels.ComposeService | ||
| if strings.HasSuffix(serviceName, readyServicesSuffix) { | ||
| continue | ||
| } | ||
| err := serviceFunc(containerDescription) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| func (m *localServicesManager) composeProject() (*compose.Project, error) { | ||
| composeFile := m.profile.Path(ProfileStackPath, ComposeFile) | ||
| return compose.NewProject(m.composeProjectName(), composeFile) | ||
| } | ||
|
|
||
| func (m *localServicesManager) composeProjectName() string { | ||
| return DockerComposeProjectName(m.profile) | ||
| } |
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.
Uh oh!
There was an error while loading. Please reload this page.